refactor: migrate issue provider logic to task manager interface and implement GitHub/GitLab providers
This commit is contained in:
@@ -14,12 +14,12 @@ import { writeFile, unlink } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import {
|
||||
type IssueProvider,
|
||||
type TaskManager,
|
||||
type Issue,
|
||||
type StateLabel,
|
||||
STATE_LABELS,
|
||||
LABEL_COLORS,
|
||||
} from "../issue-provider.js";
|
||||
} from "./task-manager.js";
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
@@ -48,7 +48,7 @@ function toIssue(gh: GhIssue): Issue {
|
||||
};
|
||||
}
|
||||
|
||||
export class GitHubProvider implements IssueProvider {
|
||||
export class GitHubProvider implements TaskManager {
|
||||
private repoPath: string;
|
||||
|
||||
constructor(opts: GitHubProviderOptions) {
|
||||
@@ -10,12 +10,12 @@ import { writeFile, unlink } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import {
|
||||
type IssueProvider,
|
||||
type TaskManager,
|
||||
type Issue,
|
||||
type StateLabel,
|
||||
STATE_LABELS,
|
||||
LABEL_COLORS,
|
||||
} from "../issue-provider.js";
|
||||
} from "./task-manager.js";
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
@@ -23,7 +23,7 @@ export type GitLabProviderOptions = {
|
||||
repoPath: string;
|
||||
};
|
||||
|
||||
export class GitLabProvider implements IssueProvider {
|
||||
export class GitLabProvider implements TaskManager {
|
||||
private repoPath: string;
|
||||
|
||||
constructor(opts: GitLabProviderOptions) {
|
||||
@@ -8,7 +8,7 @@
|
||||
* Can be overridden with explicit `provider` option.
|
||||
*/
|
||||
import { execFileSync } from "node:child_process";
|
||||
import type { IssueProvider } from "../issue-provider.js";
|
||||
import type { TaskManager } from "./task-manager.js";
|
||||
import { GitLabProvider } from "./gitlab.js";
|
||||
import { GitHubProvider } from "./github.js";
|
||||
import { resolveRepoPath } from "../utils.js";
|
||||
@@ -34,7 +34,7 @@ function detectProvider(repoPath: string): "gitlab" | "github" {
|
||||
}
|
||||
|
||||
export type ProviderWithType = {
|
||||
provider: IssueProvider;
|
||||
provider: TaskManager;
|
||||
type: "github" | "gitlab";
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* IssueProvider — Abstract interface for issue tracker operations.
|
||||
* TaskManager — Abstract interface for issue tracker operations.
|
||||
*
|
||||
* GitLab is the first implementation (via glab CLI).
|
||||
* Future providers: GitHub (via gh CLI), Jira (via API).
|
||||
* GitHub (via gh CLI) and GitLab (via glab CLI) are the current implementations.
|
||||
* Future providers: Jira (via API).
|
||||
*
|
||||
* All DevClaw tools operate through this interface, making it possible
|
||||
* to swap issue trackers without changing tool logic.
|
||||
@@ -41,7 +41,7 @@ export type Issue = {
|
||||
web_url: string;
|
||||
};
|
||||
|
||||
export interface IssueProvider {
|
||||
export interface TaskManager {
|
||||
/** Create a label if it doesn't exist (idempotent). */
|
||||
ensureLabel(name: string, color: string): Promise<void>;
|
||||
|
||||
@@ -75,6 +75,12 @@ export interface IssueProvider {
|
||||
/** Check if any merged MR/PR exists for a specific issue. */
|
||||
hasMergedMR(issueId: number): Promise<boolean>;
|
||||
|
||||
/** Verify the provider is working (CLI available, auth valid, repo accessible). */
|
||||
/** Verify the task manager is working (CLI available, auth valid, repo accessible). */
|
||||
healthCheck(): Promise<boolean>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compatibility alias for backward compatibility.
|
||||
* @deprecated Use TaskManager instead.
|
||||
*/
|
||||
export type IssueProvider = TaskManager;
|
||||
@@ -13,7 +13,7 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { readProjects, writeProjects, emptyWorkerState } from "../projects.js";
|
||||
import { resolveRepoPath } from "../utils.js";
|
||||
import { createProvider } from "../providers/index.js";
|
||||
import { createProvider } from "../task-managers/index.js";
|
||||
import { log as auditLog } from "../audit.js";
|
||||
import { DEV_TIERS, QA_TIERS } from "../tiers.js";
|
||||
import { DEFAULT_DEV_INSTRUCTIONS, DEFAULT_QA_INSTRUCTIONS } from "../templates.js";
|
||||
|
||||
@@ -7,8 +7,8 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||
import { jsonResult } from "openclaw/plugin-sdk";
|
||||
import type { ToolContext } from "../types.js";
|
||||
import { readProjects, getProject } from "../projects.js";
|
||||
import { type StateLabel } from "../issue-provider.js";
|
||||
import { createProvider } from "../providers/index.js";
|
||||
import { type StateLabel } from "../task-managers/task-manager.js";
|
||||
import { createProvider } from "../task-managers/index.js";
|
||||
import { log as auditLog } from "../audit.js";
|
||||
import { detectContext, generateGuardrails } from "../context-guard.js";
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||
import { jsonResult } from "openclaw/plugin-sdk";
|
||||
import type { ToolContext } from "../types.js";
|
||||
import { readProjects, updateWorker, getSessionForModel } from "../projects.js";
|
||||
import { type StateLabel } from "../issue-provider.js";
|
||||
import { createProvider } from "../providers/index.js";
|
||||
import { type StateLabel } from "../task-managers/task-manager.js";
|
||||
import { createProvider } from "../task-managers/index.js";
|
||||
import { log as auditLog } from "../audit.js";
|
||||
|
||||
export function createSessionHealthTool(api: OpenClawPluginApi) {
|
||||
|
||||
@@ -14,8 +14,8 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||
import { jsonResult } from "openclaw/plugin-sdk";
|
||||
import { log as auditLog } from "../audit.js";
|
||||
import { dispatchTask } from "../dispatch.js";
|
||||
import { type StateLabel } from "../issue-provider.js";
|
||||
import { createProvider } from "../providers/index.js";
|
||||
import { type StateLabel } from "../task-managers/task-manager.js";
|
||||
import { createProvider } from "../task-managers/index.js";
|
||||
import { resolveRepoPath } from "../utils.js";
|
||||
import {
|
||||
deactivateWorker,
|
||||
|
||||
@@ -13,9 +13,9 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||
import { jsonResult } from "openclaw/plugin-sdk";
|
||||
import type { ToolContext } from "../types.js";
|
||||
import { readProjects } from "../projects.js";
|
||||
import { createProvider } from "../providers/index.js";
|
||||
import { createProvider } from "../task-managers/index.js";
|
||||
import { log as auditLog } from "../audit.js";
|
||||
import type { StateLabel } from "../issue-provider.js";
|
||||
import type { StateLabel } from "../task-managers/task-manager.js";
|
||||
|
||||
const STATE_LABELS: StateLabel[] = [
|
||||
"Planning",
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||
import { jsonResult } from "openclaw/plugin-sdk";
|
||||
import { dispatchTask } from "../dispatch.js";
|
||||
import { type StateLabel } from "../issue-provider.js";
|
||||
import { createProvider } from "../providers/index.js";
|
||||
import { type StateLabel } from "../task-managers/task-manager.js";
|
||||
import { createProvider } from "../task-managers/index.js";
|
||||
import { selectModel } from "../model-selector.js";
|
||||
import { getProject, getWorker, readProjects } from "../projects.js";
|
||||
import type { ToolContext } from "../types.js";
|
||||
|
||||
Reference in New Issue
Block a user