agentplane 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +19 -0
  3. package/assets/AGENTS.md +274 -0
  4. package/assets/agents/CODER.json +28 -0
  5. package/assets/agents/CREATOR.json +25 -0
  6. package/assets/agents/DOCS.json +25 -0
  7. package/assets/agents/INTEGRATOR.json +27 -0
  8. package/assets/agents/ORCHESTRATOR.json +31 -0
  9. package/assets/agents/PLANNER.json +28 -0
  10. package/assets/agents/REDMINE.json +26 -0
  11. package/assets/agents/REVIEWER.json +22 -0
  12. package/assets/agents/TESTER.json +27 -0
  13. package/assets/agents/UPDATER.json +23 -0
  14. package/assets/agents/UPGRADER.json +27 -0
  15. package/bin/agentplane.js +2 -0
  16. package/dist/agents-template.d.ts +10 -0
  17. package/dist/agents-template.d.ts.map +1 -0
  18. package/dist/agents-template.js +66 -0
  19. package/dist/bundled-recipes.d.ts +13 -0
  20. package/dist/bundled-recipes.d.ts.map +1 -0
  21. package/dist/bundled-recipes.js +4 -0
  22. package/dist/cli/fs-utils.d.ts +4 -0
  23. package/dist/cli/fs-utils.d.ts.map +1 -0
  24. package/dist/cli/fs-utils.js +28 -0
  25. package/dist/cli/prompts.d.ts +4 -0
  26. package/dist/cli/prompts.d.ts.map +1 -0
  27. package/dist/cli/prompts.js +31 -0
  28. package/dist/cli/recipes-bundled.d.ts +9 -0
  29. package/dist/cli/recipes-bundled.d.ts.map +1 -0
  30. package/dist/cli/recipes-bundled.js +33 -0
  31. package/dist/cli.d.ts +3 -0
  32. package/dist/cli.d.ts.map +1 -0
  33. package/dist/cli.js +5 -0
  34. package/dist/command-guide.d.ts +4 -0
  35. package/dist/command-guide.d.ts.map +1 -0
  36. package/dist/command-guide.js +244 -0
  37. package/dist/comment-format.d.ts +8 -0
  38. package/dist/comment-format.d.ts.map +1 -0
  39. package/dist/comment-format.js +80 -0
  40. package/dist/env.d.ts +3 -0
  41. package/dist/env.d.ts.map +1 -0
  42. package/dist/env.js +49 -0
  43. package/dist/errors.d.ts +16 -0
  44. package/dist/errors.d.ts.map +1 -0
  45. package/dist/errors.js +22 -0
  46. package/dist/help.d.ts +2 -0
  47. package/dist/help.d.ts.map +1 -0
  48. package/dist/help.js +124 -0
  49. package/dist/run-cli.d.ts +2 -0
  50. package/dist/run-cli.d.ts.map +1 -0
  51. package/dist/run-cli.js +8412 -0
  52. package/dist/run-cli.test-helpers.d.ts +44 -0
  53. package/dist/run-cli.test-helpers.d.ts.map +1 -0
  54. package/dist/run-cli.test-helpers.js +280 -0
  55. package/dist/task-backend.d.ts +175 -0
  56. package/dist/task-backend.d.ts.map +1 -0
  57. package/dist/task-backend.js +1235 -0
  58. package/dist/version.d.ts +2 -0
  59. package/dist/version.d.ts.map +1 -0
  60. package/dist/version.js +3 -0
  61. package/package.json +59 -0
@@ -0,0 +1,44 @@
1
+ import { defaultConfig } from "@agentplane/core";
2
+ export declare function registerAgentplaneHome(): void;
3
+ export declare function getAgentplaneHome(): string | null;
4
+ export declare function captureStdIO(): {
5
+ readonly stdout: string;
6
+ readonly stderr: string;
7
+ restore(): void;
8
+ };
9
+ export declare function mkGitRepoRoot(): Promise<string>;
10
+ export declare function mkTempDir(): Promise<string>;
11
+ export declare function writeDefaultConfig(root: string): Promise<void>;
12
+ export declare function writeConfig(root: string, config: ReturnType<typeof defaultConfig>): Promise<void>;
13
+ export declare function resetAgentplaneHomeRecipes(): Promise<void>;
14
+ export declare function createRecipeArchive(opts?: {
15
+ id?: string;
16
+ version?: string;
17
+ name?: string;
18
+ summary?: string;
19
+ description?: string;
20
+ tags?: string[];
21
+ format?: "tar" | "zip";
22
+ wrapDir?: boolean;
23
+ }): Promise<{
24
+ archivePath: string;
25
+ manifest: Record<string, unknown>;
26
+ }>;
27
+ export declare function createRecipeArchiveWithManifest(opts: {
28
+ manifest: Record<string, unknown>;
29
+ files?: Record<string, string>;
30
+ format?: "tar" | "zip";
31
+ wrapDir?: boolean;
32
+ }): Promise<string>;
33
+ export declare function createUpgradeBundle(files: Record<string, string>): Promise<{
34
+ bundlePath: string;
35
+ checksumPath: string;
36
+ }>;
37
+ export declare function mkGitRepoRootWithBranch(branch: string): Promise<string>;
38
+ export declare function configureGitUser(root: string): Promise<void>;
39
+ export declare function cleanGitEnv(): NodeJS.ProcessEnv;
40
+ export declare function pathExists(filePath: string): Promise<boolean>;
41
+ export declare function gitBranchExists(root: string, branch: string): Promise<boolean>;
42
+ export declare function commitAll(root: string, message: string): Promise<void>;
43
+ export declare function stageGitignoreIfPresent(root: string): Promise<void>;
44
+ //# sourceMappingURL=run-cli.test-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-cli.test-helpers.d.ts","sourceRoot":"","sources":["../src/run-cli.test-helpers.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAiCjD,wBAAgB,sBAAsB,IAAI,IAAI,CAgB7C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAEjD;AAED,wBAAgB,YAAY;;;;EAgC3B;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAKrD;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAEjD;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpE;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC,CAKhE;AAED,wBAAsB,mBAAmB,CAAC,IAAI,CAAC,EAAE;IAC/C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CA+FtE;AAED,wBAAsB,+BAA+B,CAAC,IAAI,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAiBD;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI7E;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlE;AAED,wBAAgB,WAAW,IAAI,MAAM,CAAC,UAAU,CAS/C;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYpF;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzE"}
@@ -0,0 +1,280 @@
1
+ import { execFile } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import { access, cp, mkdir, mkdtemp, readdir, readFile, rm, writeFile } from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { promisify } from "node:util";
7
+ import { afterAll, beforeAll } from "vitest";
8
+ import { defaultConfig } from "@agentplane/core";
9
+ const execFileAsync = promisify(execFile);
10
+ let agentplaneHome = null;
11
+ const originalAgentplaneHome = process.env.AGENTPLANE_HOME;
12
+ const recipeArchiveCache = new Map();
13
+ let gitTemplateRoot = null;
14
+ let gitTemplatePromise = null;
15
+ async function ensureGitTemplateRoot() {
16
+ if (gitTemplateRoot)
17
+ return gitTemplateRoot;
18
+ gitTemplatePromise ??= (async () => {
19
+ const root = await mkdtemp(path.join(os.tmpdir(), "agentplane-git-template-"));
20
+ await execFileAsync("git", ["init", "-q"], { cwd: root });
21
+ return root;
22
+ })();
23
+ gitTemplateRoot = await gitTemplatePromise;
24
+ return gitTemplateRoot;
25
+ }
26
+ async function copyDirContents(src, dest) {
27
+ const entries = await readdir(src, { withFileTypes: true });
28
+ await Promise.all(entries.map((entry) => cp(path.join(src, entry.name), path.join(dest, entry.name), { recursive: true })));
29
+ }
30
+ export function registerAgentplaneHome() {
31
+ beforeAll(async () => {
32
+ agentplaneHome = await mkdtemp(path.join(os.tmpdir(), "agentplane-home-"));
33
+ process.env.AGENTPLANE_HOME = agentplaneHome;
34
+ });
35
+ afterAll(async () => {
36
+ if (agentplaneHome) {
37
+ await rm(agentplaneHome, { recursive: true, force: true });
38
+ }
39
+ if (originalAgentplaneHome === undefined) {
40
+ delete process.env.AGENTPLANE_HOME;
41
+ }
42
+ else {
43
+ process.env.AGENTPLANE_HOME = originalAgentplaneHome;
44
+ }
45
+ });
46
+ }
47
+ export function getAgentplaneHome() {
48
+ return agentplaneHome;
49
+ }
50
+ export function captureStdIO() {
51
+ let stdout = "";
52
+ let stderr = "";
53
+ const origStdoutWrite = process.stdout.write.bind(process.stdout);
54
+ const origStderrWrite = process.stderr.write.bind(process.stderr);
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ process.stdout.write = (chunk) => {
57
+ stdout += String(chunk);
58
+ return true;
59
+ };
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ process.stderr.write = (chunk) => {
62
+ stderr += String(chunk);
63
+ return true;
64
+ };
65
+ return {
66
+ get stdout() {
67
+ return stdout;
68
+ },
69
+ get stderr() {
70
+ return stderr;
71
+ },
72
+ restore() {
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
+ process.stdout.write = origStdoutWrite;
75
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
+ process.stderr.write = origStderrWrite;
77
+ },
78
+ };
79
+ }
80
+ export async function mkGitRepoRoot() {
81
+ const template = await ensureGitTemplateRoot();
82
+ const root = await mkdtemp(path.join(os.tmpdir(), "agentplane-cli-test-"));
83
+ await copyDirContents(template, root);
84
+ return root;
85
+ }
86
+ export async function mkTempDir() {
87
+ return await mkdtemp(path.join(os.tmpdir(), "agentplane-cli-test-"));
88
+ }
89
+ export async function writeDefaultConfig(root) {
90
+ const agentplaneDir = path.join(root, ".agentplane");
91
+ await mkdir(agentplaneDir, { recursive: true });
92
+ const configPath = path.join(agentplaneDir, "config.json");
93
+ await writeFile(configPath, JSON.stringify(defaultConfig(), null, 2), "utf8");
94
+ }
95
+ export async function writeConfig(root, config) {
96
+ const agentplaneDir = path.join(root, ".agentplane");
97
+ await mkdir(agentplaneDir, { recursive: true });
98
+ const configPath = path.join(agentplaneDir, "config.json");
99
+ await writeFile(configPath, JSON.stringify(config, null, 2), "utf8");
100
+ }
101
+ export async function resetAgentplaneHomeRecipes() {
102
+ if (!agentplaneHome)
103
+ return;
104
+ await rm(path.join(agentplaneHome, "recipes"), { recursive: true, force: true });
105
+ await rm(path.join(agentplaneHome, "recipes.json"), { force: true });
106
+ await rm(path.join(agentplaneHome, "recipes-index.json"), { force: true });
107
+ }
108
+ export async function createRecipeArchive(opts) {
109
+ const normalizedTags = opts?.tags ? [...opts.tags].toSorted() : undefined;
110
+ const cacheKey = JSON.stringify({
111
+ id: opts?.id ?? "viewer",
112
+ version: opts?.version ?? "1.2.3",
113
+ name: opts?.name ?? "Viewer",
114
+ summary: opts?.summary ?? "Preview task artifacts",
115
+ description: opts?.description ?? "Provides a local viewer for task artifacts.",
116
+ tags: normalizedTags,
117
+ format: opts?.format ?? "tar",
118
+ wrapDir: opts?.wrapDir ?? false,
119
+ });
120
+ const cached = recipeArchiveCache.get(cacheKey);
121
+ if (cached)
122
+ return cached;
123
+ const baseDir = await mkdtemp(path.join(os.tmpdir(), "agentplane-recipe-"));
124
+ const recipeDir = path.join(baseDir, opts?.wrapDir ? "bundle" : "recipe");
125
+ await mkdir(recipeDir, { recursive: true });
126
+ const manifest = {
127
+ schema_version: "1",
128
+ id: opts?.id ?? "viewer",
129
+ version: opts?.version ?? "1.2.3",
130
+ name: opts?.name ?? "Viewer",
131
+ summary: opts?.summary ?? "Preview task artifacts",
132
+ description: opts?.description ?? "Provides a local viewer for task artifacts.",
133
+ agents: [{ id: "RECIPE_AGENT", summary: "Recipe agent", file: "agents/recipe.json" }],
134
+ tools: [
135
+ { id: "RECIPE_TOOL", summary: "Recipe tool", runtime: "bash", entrypoint: "tools/run.sh" },
136
+ ],
137
+ scenarios: [{ id: "RECIPE_SCENARIO", summary: "Recipe scenario" }],
138
+ };
139
+ if (normalizedTags) {
140
+ manifest.tags = normalizedTags;
141
+ }
142
+ await writeFile(path.join(recipeDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
143
+ const agentsDir = path.join(recipeDir, "agents");
144
+ await mkdir(agentsDir, { recursive: true });
145
+ await writeFile(path.join(agentsDir, "recipe.json"), JSON.stringify({
146
+ id: "RECIPE_AGENT",
147
+ role: "Recipe agent",
148
+ description: "Example agent installed from a recipe.",
149
+ }, null, 2), "utf8");
150
+ const toolsDir = path.join(recipeDir, "tools");
151
+ await mkdir(toolsDir, { recursive: true });
152
+ await writeFile(path.join(toolsDir, "run.sh"), [
153
+ "#!/usr/bin/env bash",
154
+ "set -euo pipefail",
155
+ 'echo "ok" > "$AGENTPLANE_RUN_DIR/artifact.txt"',
156
+ ].join("\n"), "utf8");
157
+ const scenariosDir = path.join(recipeDir, "scenarios");
158
+ await mkdir(scenariosDir, { recursive: true });
159
+ await writeFile(path.join(scenariosDir, "recipe-scenario.json"), JSON.stringify({
160
+ schema_version: "1",
161
+ id: "RECIPE_SCENARIO",
162
+ summary: "Recipe scenario",
163
+ goal: "Preview installed tasks.",
164
+ inputs: [{ name: "task_id", type: "string" }],
165
+ outputs: [{ name: "report", type: "html" }],
166
+ steps: [{ tool: "RECIPE_TOOL" }],
167
+ }, null, 2), "utf8");
168
+ const format = opts?.format ?? "tar";
169
+ const archivePath = format === "zip" ? path.join(baseDir, "recipe.zip") : path.join(baseDir, "recipe.tar.gz");
170
+ if (format === "zip") {
171
+ await (opts?.wrapDir
172
+ ? execFileAsync("zip", ["-qr", archivePath, path.basename(recipeDir)], { cwd: baseDir })
173
+ : execFileAsync("zip", ["-qr", archivePath, "."], { cwd: recipeDir }));
174
+ }
175
+ else {
176
+ await (opts?.wrapDir
177
+ ? execFileAsync("tar", ["-czf", archivePath, "-C", baseDir, path.basename(recipeDir)])
178
+ : execFileAsync("tar", ["-czf", archivePath, "-C", recipeDir, "."]));
179
+ }
180
+ const payload = { archivePath, manifest };
181
+ recipeArchiveCache.set(cacheKey, payload);
182
+ return payload;
183
+ }
184
+ export async function createRecipeArchiveWithManifest(opts) {
185
+ const baseDir = await mkdtemp(path.join(os.tmpdir(), "agentplane-recipe-bad-"));
186
+ const recipeDir = path.join(baseDir, opts.wrapDir ? "bundle" : "recipe");
187
+ await mkdir(recipeDir, { recursive: true });
188
+ await writeFile(path.join(recipeDir, "manifest.json"), JSON.stringify(opts.manifest, null, 2));
189
+ if (opts.files) {
190
+ for (const [relPath, content] of Object.entries(opts.files)) {
191
+ const fullPath = path.join(recipeDir, relPath);
192
+ await mkdir(path.dirname(fullPath), { recursive: true });
193
+ await writeFile(fullPath, content, "utf8");
194
+ }
195
+ }
196
+ const format = opts.format ?? "tar";
197
+ const archivePath = format === "zip" ? path.join(baseDir, "recipe.zip") : path.join(baseDir, "recipe.tar.gz");
198
+ if (format === "zip") {
199
+ await (opts.wrapDir
200
+ ? execFileAsync("zip", ["-qr", archivePath, path.basename(recipeDir)], { cwd: baseDir })
201
+ : execFileAsync("zip", ["-qr", archivePath, "."], { cwd: recipeDir }));
202
+ }
203
+ else {
204
+ await (opts.wrapDir
205
+ ? execFileAsync("tar", ["-czf", archivePath, "-C", baseDir, path.basename(recipeDir)])
206
+ : execFileAsync("tar", ["-czf", archivePath, "-C", recipeDir, "."]));
207
+ }
208
+ return archivePath;
209
+ }
210
+ export async function createUpgradeBundle(files) {
211
+ const baseDir = await mkdtemp(path.join(os.tmpdir(), "agentplane-upgrade-bundle-"));
212
+ const bundleDir = path.join(baseDir, "bundle");
213
+ await mkdir(bundleDir, { recursive: true });
214
+ for (const [relPath, content] of Object.entries(files)) {
215
+ const fullPath = path.join(bundleDir, relPath);
216
+ await mkdir(path.dirname(fullPath), { recursive: true });
217
+ await writeFile(fullPath, content, "utf8");
218
+ }
219
+ const bundlePath = path.join(baseDir, "agentplane-upgrade.tar.gz");
220
+ await execFileAsync("tar", ["-czf", bundlePath, "-C", bundleDir, "."]);
221
+ const checksum = createHash("sha256")
222
+ .update(await readFile(bundlePath))
223
+ .digest("hex");
224
+ const checksumPath = `${bundlePath}.sha256`;
225
+ await writeFile(checksumPath, `${checksum} agentplane-upgrade.tar.gz\n`, "utf8");
226
+ return { bundlePath, checksumPath };
227
+ }
228
+ export async function mkGitRepoRootWithBranch(branch) {
229
+ const root = await mkGitRepoRoot();
230
+ await execFileAsync("git", ["checkout", "-b", branch], { cwd: root });
231
+ return root;
232
+ }
233
+ export async function configureGitUser(root) {
234
+ await execFileAsync("git", ["config", "user.email", "test@example.com"], { cwd: root });
235
+ await execFileAsync("git", ["config", "user.name", "Test User"], { cwd: root });
236
+ }
237
+ export function cleanGitEnv() {
238
+ const env = { ...process.env };
239
+ delete env.GIT_DIR;
240
+ delete env.GIT_WORK_TREE;
241
+ delete env.GIT_COMMON_DIR;
242
+ delete env.GIT_INDEX_FILE;
243
+ delete env.GIT_OBJECT_DIRECTORY;
244
+ delete env.GIT_ALTERNATE_OBJECT_DIRECTORIES;
245
+ return env;
246
+ }
247
+ export async function pathExists(filePath) {
248
+ try {
249
+ await access(filePath);
250
+ return true;
251
+ }
252
+ catch {
253
+ return false;
254
+ }
255
+ }
256
+ export async function gitBranchExists(root, branch) {
257
+ try {
258
+ await execFileAsync("git", ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`], {
259
+ cwd: root,
260
+ env: cleanGitEnv(),
261
+ });
262
+ return true;
263
+ }
264
+ catch (err) {
265
+ const code = err?.code;
266
+ if (code === 1)
267
+ return false;
268
+ throw err;
269
+ }
270
+ }
271
+ export async function commitAll(root, message) {
272
+ await execFileAsync("git", ["add", "."], { cwd: root });
273
+ await execFileAsync("git", ["commit", "-m", message], { cwd: root });
274
+ }
275
+ export async function stageGitignoreIfPresent(root) {
276
+ const gitignorePath = path.join(root, ".gitignore");
277
+ if (!(await pathExists(gitignorePath)))
278
+ return;
279
+ await execFileAsync("git", ["add", ".gitignore"], { cwd: root });
280
+ }
@@ -0,0 +1,175 @@
1
+ import { type AgentplaneConfig, type ResolvedProject, type TaskRecord } from "@agentplane/core";
2
+ export declare function extractTaskDoc(body: string): string;
3
+ export declare function mergeTaskDoc(body: string, doc: string): string;
4
+ export type TaskData = {
5
+ id: string;
6
+ title: string;
7
+ description: string;
8
+ status: string;
9
+ priority: string | number;
10
+ owner: string;
11
+ depends_on: string[];
12
+ tags: string[];
13
+ verify: string[];
14
+ commit?: {
15
+ hash: string;
16
+ message: string;
17
+ } | null;
18
+ comments?: {
19
+ author: string;
20
+ body: string;
21
+ }[];
22
+ doc?: string;
23
+ doc_version?: number;
24
+ doc_updated_at?: string;
25
+ doc_updated_by?: string;
26
+ dirty?: boolean;
27
+ id_source?: string;
28
+ };
29
+ export type TaskBackend = {
30
+ id: string;
31
+ listTasks(): Promise<TaskData[]>;
32
+ getTask(taskId: string): Promise<TaskData | null>;
33
+ writeTask(task: TaskData): Promise<void>;
34
+ writeTasks?(tasks: TaskData[]): Promise<void>;
35
+ exportTasksJson?(outputPath: string): Promise<void>;
36
+ getTaskDoc?(taskId: string): Promise<string>;
37
+ setTaskDoc?(taskId: string, doc: string, updatedBy?: string): Promise<void>;
38
+ touchTaskDocMetadata?(taskId: string, updatedBy?: string): Promise<void>;
39
+ sync?(opts: {
40
+ direction: "push" | "pull";
41
+ conflict: "diff" | "prefer-local" | "prefer-remote" | "fail";
42
+ quiet: boolean;
43
+ confirm: boolean;
44
+ }): Promise<void>;
45
+ generateTaskId?(opts: {
46
+ length: number;
47
+ attempts: number;
48
+ }): Promise<string>;
49
+ };
50
+ export declare class BackendError extends Error {
51
+ code: "E_BACKEND" | "E_NETWORK";
52
+ constructor(message: string, code: "E_BACKEND" | "E_NETWORK");
53
+ }
54
+ export declare class RedmineUnavailable extends BackendError {
55
+ constructor(message: string);
56
+ }
57
+ export declare function taskRecordToData(record: TaskRecord): TaskData;
58
+ export declare function buildTasksExportSnapshotFromTasks(tasks: TaskData[]): {
59
+ tasks: TaskData[];
60
+ meta: {
61
+ schema_version: 1;
62
+ managed_by: string;
63
+ checksum_algo: "sha256";
64
+ checksum: string;
65
+ };
66
+ };
67
+ export declare function writeTasksExportFromTasks(opts: {
68
+ outputPath: string;
69
+ tasks: TaskData[];
70
+ }): Promise<void>;
71
+ export declare class LocalBackend implements TaskBackend {
72
+ id: string;
73
+ root: string;
74
+ updatedBy: string;
75
+ constructor(settings?: {
76
+ dir?: string;
77
+ updatedBy?: string;
78
+ });
79
+ generateTaskId(opts: {
80
+ length: number;
81
+ attempts: number;
82
+ }): Promise<string>;
83
+ listTasks(): Promise<TaskData[]>;
84
+ getTask(taskId: string): Promise<TaskData | null>;
85
+ getTaskDoc(taskId: string): Promise<string>;
86
+ writeTask(task: TaskData): Promise<void>;
87
+ setTaskDoc(taskId: string, doc: string, updatedBy?: string): Promise<void>;
88
+ touchTaskDocMetadata(taskId: string, updatedBy?: string): Promise<void>;
89
+ writeTasks(tasks: TaskData[]): Promise<void>;
90
+ exportTasksJson(outputPath: string): Promise<void>;
91
+ }
92
+ type RedmineSettings = {
93
+ url?: string;
94
+ api_key?: string;
95
+ project_id?: string;
96
+ status_map?: Record<string, unknown>;
97
+ custom_fields?: Record<string, unknown>;
98
+ batch_size?: number;
99
+ batch_pause?: number;
100
+ owner_agent?: string;
101
+ cache_dir?: string;
102
+ };
103
+ export declare class RedmineBackend implements TaskBackend {
104
+ id: string;
105
+ baseUrl: string;
106
+ apiKey: string;
107
+ projectId: string;
108
+ assigneeId: number | null;
109
+ ownerAgent: string;
110
+ statusMap: Record<string, unknown>;
111
+ customFields: Record<string, unknown>;
112
+ batchSize: number;
113
+ batchPause: number;
114
+ cache: LocalBackend | null;
115
+ issueCache: Map<string, Record<string, unknown>>;
116
+ reverseStatus: Map<number, string>;
117
+ constructor(settings: RedmineSettings, opts: {
118
+ cache?: LocalBackend | null;
119
+ });
120
+ generateTaskId(opts: {
121
+ length: number;
122
+ attempts: number;
123
+ }): Promise<string>;
124
+ listTasks(): Promise<TaskData[]>;
125
+ exportTasksJson(outputPath: string): Promise<void>;
126
+ getTask(taskId: string): Promise<TaskData | null>;
127
+ getTaskDoc(taskId: string): Promise<string>;
128
+ setTaskDoc(taskId: string, doc: string, updatedBy?: string): Promise<void>;
129
+ touchTaskDocMetadata(taskId: string, updatedBy?: string): Promise<void>;
130
+ writeTask(task: TaskData): Promise<void>;
131
+ writeTasks(tasks: TaskData[]): Promise<void>;
132
+ sync(opts: {
133
+ direction: "push" | "pull";
134
+ conflict: "diff" | "prefer-local" | "prefer-remote" | "fail";
135
+ quiet: boolean;
136
+ confirm: boolean;
137
+ }): Promise<void>;
138
+ private ensureDocMetadata;
139
+ private syncPush;
140
+ private syncPull;
141
+ private handleConflict;
142
+ private diffTasks;
143
+ private tasksDiffer;
144
+ private cacheTask;
145
+ private taskIdFieldId;
146
+ private setIssueCustomFieldValue;
147
+ private listTasksRemote;
148
+ private issueFromPayload;
149
+ private findIssueByTaskId;
150
+ private issueToTask;
151
+ private taskToIssuePayload;
152
+ private appendCustomField;
153
+ private normalizeComments;
154
+ private commentsToPairs;
155
+ private formatCommentNote;
156
+ private appendCommentNotes;
157
+ private startDateFromTaskId;
158
+ private doneRatioForStatus;
159
+ private customFieldValue;
160
+ private maybeParseJson;
161
+ private coerceDocVersion;
162
+ private requestJson;
163
+ }
164
+ export declare function loadTaskBackend(opts: {
165
+ cwd: string;
166
+ rootOverride?: string | null;
167
+ }): Promise<{
168
+ backend: TaskBackend;
169
+ backendId: string;
170
+ resolved: ResolvedProject;
171
+ config: AgentplaneConfig;
172
+ backendConfigPath: string;
173
+ }>;
174
+ export {};
175
+ //# sourceMappingURL=task-backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-backend.d.ts","sourceRoot":"","sources":["../src/task-backend.ts"],"names":[],"mappings":"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"}