@elie-laloum/outpost 1.1.4 → 2.0.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 (76) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +12 -6
  3. package/dist/cli/image.js +1 -1
  4. package/dist/cli/image.js.map +1 -1
  5. package/dist/cli/init-command.js +4 -3
  6. package/dist/cli/init-command.js.map +1 -1
  7. package/dist/cli/main.constants.d.ts +4 -10
  8. package/dist/cli/main.constants.js +4 -7
  9. package/dist/cli/main.constants.js.map +1 -1
  10. package/dist/cli/project-settings.js +8 -2
  11. package/dist/cli/project-settings.js.map +1 -1
  12. package/dist/cli/scaffold-files.d.ts +1 -1
  13. package/dist/cli/scaffold-files.js +26 -20
  14. package/dist/cli/scaffold-files.js.map +1 -1
  15. package/dist/cli/scaffold-validation.js +2 -5
  16. package/dist/cli/scaffold-validation.js.map +1 -1
  17. package/dist/cli/scaffold.constants.d.ts +0 -2
  18. package/dist/cli/scaffold.constants.js +1 -13
  19. package/dist/cli/scaffold.constants.js.map +1 -1
  20. package/dist/cli/scaffold.d.ts +1 -1
  21. package/dist/cli/scaffold.js +37 -29
  22. package/dist/cli/scaffold.js.map +1 -1
  23. package/dist/cli/scaffold.types.d.ts +3 -5
  24. package/dist/cli/scaffold.types.js.map +1 -1
  25. package/dist/cli/starters.d.ts +1 -2
  26. package/dist/cli/starters.js +42 -30
  27. package/dist/cli/starters.js.map +1 -1
  28. package/dist/index.d.ts +0 -5
  29. package/dist/index.js +0 -2
  30. package/dist/index.js.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/adapters/backlogs/backlog.constants.d.ts +0 -4
  33. package/dist/adapters/backlogs/backlog.constants.js +0 -5
  34. package/dist/adapters/backlogs/backlog.constants.js.map +0 -1
  35. package/dist/adapters/backlogs/beads-adapter.d.ts +0 -4
  36. package/dist/adapters/backlogs/beads-adapter.js +0 -31
  37. package/dist/adapters/backlogs/beads-adapter.js.map +0 -1
  38. package/dist/adapters/backlogs/cli.d.ts +0 -3
  39. package/dist/adapters/backlogs/cli.js +0 -20
  40. package/dist/adapters/backlogs/cli.js.map +0 -1
  41. package/dist/adapters/backlogs/github-adapter.d.ts +0 -4
  42. package/dist/adapters/backlogs/github-adapter.js +0 -28
  43. package/dist/adapters/backlogs/github-adapter.js.map +0 -1
  44. package/dist/adapters/backlogs/issue.d.ts +0 -2
  45. package/dist/adapters/backlogs/issue.js +0 -13
  46. package/dist/adapters/backlogs/issue.js.map +0 -1
  47. package/dist/adapters/backlogs/settings.types.d.ts +0 -5
  48. package/dist/adapters/backlogs/settings.types.js +0 -2
  49. package/dist/adapters/backlogs/settings.types.js.map +0 -1
  50. package/dist/application/campaign-integration.d.ts +0 -2
  51. package/dist/application/campaign-integration.js +0 -44
  52. package/dist/application/campaign-integration.js.map +0 -1
  53. package/dist/application/campaign-planner.d.ts +0 -3
  54. package/dist/application/campaign-planner.js +0 -35
  55. package/dist/application/campaign-planner.js.map +0 -1
  56. package/dist/application/campaign-worker.d.ts +0 -3
  57. package/dist/application/campaign-worker.js +0 -54
  58. package/dist/application/campaign-worker.js.map +0 -1
  59. package/dist/application/campaign.constants.d.ts +0 -7
  60. package/dist/application/campaign.constants.js +0 -8
  61. package/dist/application/campaign.constants.js.map +0 -1
  62. package/dist/application/campaign.d.ts +0 -3
  63. package/dist/application/campaign.js +0 -96
  64. package/dist/application/campaign.js.map +0 -1
  65. package/dist/application/campaign.types.d.ts +0 -43
  66. package/dist/application/campaign.types.js +0 -2
  67. package/dist/application/campaign.types.js.map +0 -1
  68. package/dist/domain/backlog.d.ts +0 -3
  69. package/dist/domain/backlog.js +0 -23
  70. package/dist/domain/backlog.js.map +0 -1
  71. package/dist/domain/backlog.types.d.ts +0 -15
  72. package/dist/domain/backlog.types.js +0 -2
  73. package/dist/domain/backlog.types.js.map +0 -1
  74. package/dist/providers/backlogs.d.ts +0 -3
  75. package/dist/providers/backlogs.js +0 -3
  76. package/dist/providers/backlogs.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/cli/scaffold.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, mkdir, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { invariant, OutpostError } from \"../domain/errors.ts\";\nimport { requireSuccess } from \"../infrastructure/process.ts\";\nimport type { Executor } from \"../infrastructure/process.types.ts\";\nimport { manageImage } from \"./image.ts\";\nimport { projectSettings } from \"./project-settings.ts\";\nimport { scaffoldFiles } from \"./scaffold-files.ts\";\nimport { validateInitialization } from \"./scaffold-validation.ts\";\nimport { providerPackages } from \"./scaffold.constants.ts\";\nimport type { InitOptions, ScaffoldResult } from \"./scaffold.types.ts\";\n\nexport { manageImage } from \"./image.ts\";\nexport { imageRecipe } from \"./scaffold.constants.ts\";\nexport type { InitOptions, Template } from \"./scaffold.types.ts\";\n\nexport async function initialize(\n options: InitOptions = {},\n executor?: Executor,\n): Promise<ScaffoldResult> {\n const root = resolve(options.directory ?? process.cwd()),\n folder = join(root, \".outpost\");\n const provider = options.provider ?? \"docker\";\n validateInitialization(options);\n const { extension, manager } = await projectSettings(root, options);\n const files = scaffoldFiles(options, extension);\n for (const name of Object.keys(files))\n if (\n await access(join(folder, name))\n .then(() => true)\n .catch(() => false)\n )\n throw new OutpostError(\n \"configuration\",\n `Initialization would overwrite .outpost/${name}`,\n );\n await mkdir(folder, { recursive: true });\n for (const [name, content] of Object.entries(files))\n await writeFile(join(folder, name), content, { flag: \"wx\" });\n if (options.install) {\n const packages = [\"@elie-laloum/outpost\", ...providerPackages[provider]];\n const args =\n manager === \"npm\"\n ? [\"install\", \"--save-dev\", ...packages]\n : [\"add\", \"--dev\", ...packages];\n await requireSuccess(\n process.platform === \"win32\"\n ? {\n executable: \"cmd.exe\",\n arguments: [\"/d\", \"/c\", [manager, ...args].join(\" \")],\n directory: root,\n }\n : { executable: manager, arguments: args, directory: root },\n executor,\n );\n }\n if (options.label) {\n invariant(\n options.tracker === \"github\",\n \"Labels require the GitHub tracker\",\n );\n await requireSuccess(\n {\n executable: \"gh\",\n arguments: [\n \"label\",\n \"create\",\n options.label,\n \"--color\",\n \"4969ED\",\n \"--description\",\n \"Ready for Outpost\",\n \"--force\",\n ],\n directory: root,\n },\n executor,\n );\n }\n if (options.build && (provider === \"docker\" || provider === \"podman\"))\n await manageImage(\n \"build\",\n {\n directory: root,\n engine: provider,\n ...(options.image ? { image: options.image } : {}),\n },\n executor,\n );\n return {\n files: Object.keys(files).map((name) => join(folder, name)),\n run: `node .outpost/run.${extension}`,\n };\n}\n"]}
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/cli/scaffold.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n appendFile,\n lstat,\n mkdir,\n readFile,\n writeFile,\n} from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport { requireSuccess } from \"../infrastructure/process.ts\";\nimport type { Executor } from \"../infrastructure/process.types.ts\";\nimport { imageName } from \"../providers/container.ts\";\nimport { manageImage } from \"./image.ts\";\nimport { projectSettings } from \"./project-settings.ts\";\nimport { scaffoldFiles } from \"./scaffold-files.ts\";\nimport { validateInitialization } from \"./scaffold-validation.ts\";\nimport { providerPackages } from \"./scaffold.constants.ts\";\nimport type { InitOptions, ScaffoldResult } from \"./scaffold.types.ts\";\n\nexport { manageImage } from \"./image.ts\";\nexport { imageRecipe } from \"./scaffold.constants.ts\";\nexport type { InitOptions } from \"./scaffold.types.ts\";\n\nexport async function initialize(\n options: InitOptions = {},\n executor?: Executor,\n): Promise<ScaffoldResult> {\n const root = resolve(options.directory ?? process.cwd());\n const provider = options.provider ?? \"docker\";\n validateInitialization(options);\n const { hasPackage, manager, extension } = await projectSettings(\n root,\n options,\n );\n const files = await scaffoldFiles(\n { ...options, image: options.image ?? imageName(root) },\n hasPackage,\n extension,\n );\n const existingIgnore = await readFile(join(root, \".gitignore\"), \"utf8\").catch(\n (error) => {\n if (error.code === \"ENOENT\") return undefined;\n throw error;\n },\n );\n const ignore = files[\".gitignore\"]!;\n if (existingIgnore !== undefined) delete files[\".gitignore\"];\n for (const name of Object.keys(files))\n if (\n await lstat(join(root, name))\n .then(() => true)\n .catch((error) => {\n if (error.code === \"ENOENT\") return false;\n throw error;\n })\n )\n throw new OutpostError(\n \"configuration\",\n `Initialization would overwrite ${name}`,\n );\n await mkdir(root, { recursive: true });\n for (const [name, content] of Object.entries(files))\n await writeFile(join(root, name), content, { flag: \"wx\" });\n if (existingIgnore !== undefined) {\n const rules = new Set(existingIgnore.split(/\\r?\\n/));\n const additions = ignore\n .trimEnd()\n .split(\"\\n\")\n .filter((rule) => !rules.has(rule));\n if (additions.length) {\n const suffix = `${existingIgnore && !existingIgnore.endsWith(\"\\n\") ? \"\\n\" : \"\"}${additions.join(\"\\n\")}\\n`;\n await appendFile(join(root, \".gitignore\"), suffix);\n files[\".gitignore\"] = existingIgnore + suffix;\n }\n }\n if (options.install) {\n const packages = [\"@elie-laloum/outpost\", ...providerPackages[provider]];\n const args =\n manager === \"npm\"\n ? [\"install\", \"--save-dev\", ...packages]\n : [\"add\", \"--dev\", ...packages];\n await requireSuccess(\n process.platform === \"win32\"\n ? {\n executable: \"cmd.exe\",\n arguments: [\"/d\", \"/c\", [manager, ...args].join(\" \")],\n directory: root,\n }\n : { executable: manager, arguments: args, directory: root },\n executor,\n );\n }\n if (options.build && (provider === \"docker\" || provider === \"podman\"))\n await manageImage(\n \"build\",\n {\n directory: root,\n engine: provider,\n ...(options.image ? { image: options.image } : {}),\n },\n executor,\n );\n return {\n files: Object.keys(files).map((name) => join(root, name)),\n run: `node run.${extension}`,\n };\n}\n"]}
@@ -1,14 +1,11 @@
1
- export type Template = "blank" | "iterate" | "review" | "plan" | "plan-review";
2
1
  export interface InitOptions {
3
2
  readonly directory?: string;
3
+ readonly repository?: string;
4
4
  readonly agent?: "claude" | "codex";
5
5
  readonly provider?: "docker" | "podman" | "vercel" | "daytona" | "local";
6
- readonly template?: Template;
7
- readonly tracker?: "github" | "beads" | "custom";
8
6
  readonly manager?: "npm" | "pnpm" | "yarn" | "bun";
9
7
  readonly model?: string;
10
8
  readonly install?: boolean;
11
- readonly label?: string;
12
9
  readonly build?: boolean;
13
10
  readonly image?: string;
14
11
  }
@@ -17,7 +14,8 @@ export interface PackageManifest {
17
14
  readonly packageManager?: string;
18
15
  }
19
16
  export interface ProjectSettings {
20
- readonly extension: string;
17
+ readonly extension: "ts" | "mts";
18
+ readonly hasPackage: boolean;
21
19
  readonly manager: string;
22
20
  }
23
21
  export interface ScaffoldResult {
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.types.js","sourceRoot":"","sources":["../../src/cli/scaffold.types.ts"],"names":[],"mappings":"","sourcesContent":["export type Template = \"blank\" | \"iterate\" | \"review\" | \"plan\" | \"plan-review\";\n\nexport interface InitOptions {\n readonly directory?: string;\n readonly agent?: \"claude\" | \"codex\";\n readonly provider?: \"docker\" | \"podman\" | \"vercel\" | \"daytona\" | \"local\";\n readonly template?: Template;\n readonly tracker?: \"github\" | \"beads\" | \"custom\";\n readonly manager?: \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n readonly model?: string;\n readonly install?: boolean;\n readonly label?: string;\n readonly build?: boolean;\n readonly image?: string;\n}\n\nexport interface PackageManifest {\n readonly type?: string;\n readonly packageManager?: string;\n}\nexport interface ProjectSettings {\n readonly extension: string;\n readonly manager: string;\n}\nexport interface ScaffoldResult {\n files: readonly string[];\n run: string;\n}\n"]}
1
+ {"version":3,"file":"scaffold.types.js","sourceRoot":"","sources":["../../src/cli/scaffold.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface InitOptions {\n readonly directory?: string;\n readonly repository?: string;\n readonly agent?: \"claude\" | \"codex\";\n readonly provider?: \"docker\" | \"podman\" | \"vercel\" | \"daytona\" | \"local\";\n readonly manager?: \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n readonly model?: string;\n readonly install?: boolean;\n readonly build?: boolean;\n readonly image?: string;\n}\n\nexport interface PackageManifest {\n readonly type?: string;\n readonly packageManager?: string;\n}\nexport interface ProjectSettings {\n readonly extension: \"ts\" | \"mts\";\n readonly hasPackage: boolean;\n readonly manager: string;\n}\nexport interface ScaffoldResult {\n files: readonly string[];\n run: string;\n}\n"]}
@@ -1,3 +1,2 @@
1
1
  import type { InitOptions } from "./scaffold.types.ts";
2
- export declare function starter(options: InitOptions, extension: string): string;
3
- export declare function tracker(kind: NonNullable<InitOptions["tracker"]>, label?: string): string;
2
+ export declare function starter(options: InitOptions): string;
@@ -1,34 +1,46 @@
1
- export function starter(options, extension) {
2
- const agent = options.agent ?? "codex", provider = options.provider ?? "docker", template = options.template ?? "blank";
3
- const planning = template === "plan" || template === "plan-review";
4
- const reviewing = template === "review" || template === "plan-review";
5
- const imports = `import { campaign, dispatch, ${agent} } from "@elie-laloum/outpost";\nimport type { Backlog } from "@elie-laloum/outpost";\nimport { ${provider} } from "@elie-laloum/outpost/providers/${provider}";\nimport { readFile } from "node:fs/promises";\n${options.tracker ? `import { backlog } from "./tickets.${extension}";\n` : ""}`;
6
- const config = `const runtime = { agent: ${agent}(${options.model ? `{ model: ${JSON.stringify(options.model)} }` : ""}), provider: ${provider}(${options.image && (provider === "docker" || provider === "podman") ? `{ image: ${JSON.stringify(options.image)} }` : ""}) };\nconst objective = process.argv.slice(2).join(" ") || "Inspect this repository and implement one useful improvement.";\n`;
7
- if (template === "blank")
8
- return `${imports}\n${config}\nconst result = await dispatch({ ...runtime, branch: { mode: "integrate" }, brief: { file: ".outpost/brief.md", values: { OBJECTIVE: objective } } });\nconsole.log({ branch: result.branch, commits: result.commits, conversation: result.conversation });\n`;
9
- const backlog = options.tracker
10
- ? ""
11
- : `let pending = true;\nconst requested = { id: "objective", title: objective };\nconst backlog: Backlog = {\n async list() { return pending ? [requested] : []; },\n async get() { return requested; },\n async close() { pending = false; },\n};\n`;
12
- return `${imports}\n${config}\n${backlog}\nconst result = await campaign({\n ...runtime, backlog,\n cycles: 10, concurrency: ${planning ? 3 : 1},\n implementationPasses: ${planning ? 100 : 1}, reviewPasses: 1,\n planner: ${planning ? "runtime.agent" : "false"}, reviewer: ${reviewing ? "runtime.agent" : "false"},\n copies: ["node_modules"],\n standards: await readFile(new URL("./STANDARDS.md", import.meta.url), "utf8"),\n observe: event => console.log(\`[cycle \${event.cycle}] \${event.phase}\${event.issue ? " " + event.issue : ""}\`),\n});\nconsole.log(result);\nif (result.issues.some(issue => issue.state === "failed")) process.exitCode = 1;\n`;
13
- }
14
- export function tracker(kind, label) {
15
- if (kind !== "custom") {
16
- const factory = kind === "github" ? "githubBacklog" : "beadsBacklog";
17
- return `import { ${factory} } from "@elie-laloum/outpost";\nexport const backlog = ${factory}(${label ? `{ label: ${JSON.stringify(label)} }` : ""});\n`;
18
- }
19
- return `import type { Backlog, Issue } from "@elie-laloum/outpost";
20
- async function request(path: string, method = "GET", signal?: AbortSignal) {
21
- const base = process.env.OUTPOST_TRACKER_URL;
22
- if (!base) throw new Error("Set OUTPOST_TRACKER_URL");
23
- const reply = await fetch(new URL(path, base.endsWith("/") ? base : base + "/"), { method, signal });
24
- if (!reply.ok) throw new Error(\`Tracker returned \${reply.status}\`);
25
- return reply;
26
- }
27
- export const backlog: Backlog = {
28
- async list(signal) { return await (await request("issues?state=open", "GET", signal)).json() as Issue[]; },
29
- async get(id, signal) { return await (await request("issues/" + encodeURIComponent(id), "GET", signal)).json() as Issue; },
30
- async close(id, signal) { await request("issues/" + encodeURIComponent(id) + "/close", "POST", signal); },
1
+ export function starter(options) {
2
+ const agent = options.agent ?? "codex", provider = options.provider ?? "docker";
3
+ const model = options.model ? `model: ${JSON.stringify(options.model)}` : "";
4
+ const image = options.image && (provider === "docker" || provider === "podman")
5
+ ? `image: ${JSON.stringify(options.image)}, `
6
+ : "";
7
+ return `import { readFile } from "node:fs/promises";
8
+ import { resolve } from "node:path";
9
+ import { parseEnv } from "node:util";
10
+ import { dispatch, ${agent}, OutpostError, reporter } from "@elie-laloum/outpost";
11
+ import { ${provider} } from "@elie-laloum/outpost/providers/${provider}";
12
+
13
+ // Paths are relative to this workflow, regardless of where Node is launched.
14
+ const repository = resolve(import.meta.dirname, ${JSON.stringify(options.repository ?? ".")});
15
+ const environment = await readFile(new URL(".env", import.meta.url), "utf8").catch((error) => {
16
+ if (error.code === "ENOENT") return "";
17
+ throw error;
18
+ });
19
+ const variables = Object.fromEntries(
20
+ Object.entries(parseEnv(environment)).map(([key, value]) => [key, value || process.env[key] || ""]),
21
+ );
22
+ const runtime = {
23
+ agent: ${agent}({ ${model} }),
24
+ provider: ${provider}({ ${image}variables }),
31
25
  };
26
+ const objective = process.argv.slice(2).join(" ") || "Inspect this repository and implement one useful improvement.";
27
+
28
+ console.error("[outpost] Preparing sandbox...");
29
+ try {
30
+ const result = await dispatch({
31
+ ...runtime,
32
+ repository,
33
+ branch: { mode: "integrate" },
34
+ brief: { file: resolve(import.meta.dirname, "brief.md"), values: { OBJECTIVE: objective } },
35
+ observe: reporter(),
36
+ warn: (message) => console.error(message),
37
+ });
38
+ console.log({ branch: result.branch, commits: result.commits, conversation: result.conversation });
39
+ } catch (error) {
40
+ if (!(error instanceof OutpostError) || error.code !== "aborted") throw error;
41
+ process.exitCode ||= 130;
42
+ console.error("[outpost] Cancelled. Recovery details:", error.recovery);
43
+ }
32
44
  `;
33
45
  }
34
46
  //# sourceMappingURL=starters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"starters.js","sourceRoot":"","sources":["../../src/cli/starters.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,OAAO,CAAC,OAAoB,EAAE,SAAiB;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,EACpC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,EACvC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC;IACzC,MAAM,QAAQ,GAAG,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,aAAa,CAAC;IACnE,MAAM,SAAS,GAAG,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,aAAa,CAAC;IACtE,MAAM,OAAO,GAAG,gCAAgC,KAAK,mGAAmG,QAAQ,2CAA2C,QAAQ,qDAAqD,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,sCAAsC,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACvV,MAAM,MAAM,GAAG,4BAA4B,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAgB,QAAQ,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,+HAA+H,CAAC;IACxY,IAAI,QAAQ,KAAK,OAAO;QACtB,OAAO,GAAG,OAAO,KAAK,MAAM,gQAAgQ,CAAC;IAC/R,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;QAC7B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,sPAAsP,CAAC;IAC3P,OAAO,GAAG,OAAO,KAAK,MAAM,KAAK,OAAO,yFAAyF,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,8BAA8B,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kCAAkC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,eAAe,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,wVAAwV,CAAC;AACtpB,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,IAAyC,EACzC,KAAc;IAEd,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC;QACrE,OAAO,YAAY,OAAO,2DAA2D,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IAC3J,CAAC;IACD,OAAO;;;;;;;;;;;;;CAaR,CAAC;AACF,CAAC","sourcesContent":["import type { InitOptions } from \"./scaffold.types.ts\";\n\nexport function starter(options: InitOptions, extension: string): string {\n const agent = options.agent ?? \"codex\",\n provider = options.provider ?? \"docker\",\n template = options.template ?? \"blank\";\n const planning = template === \"plan\" || template === \"plan-review\";\n const reviewing = template === \"review\" || template === \"plan-review\";\n const imports = `import { campaign, dispatch, ${agent} } from \"@elie-laloum/outpost\";\\nimport type { Backlog } from \"@elie-laloum/outpost\";\\nimport { ${provider} } from \"@elie-laloum/outpost/providers/${provider}\";\\nimport { readFile } from \"node:fs/promises\";\\n${options.tracker ? `import { backlog } from \"./tickets.${extension}\";\\n` : \"\"}`;\n const config = `const runtime = { agent: ${agent}(${options.model ? `{ model: ${JSON.stringify(options.model)} }` : \"\"}), provider: ${provider}(${options.image && (provider === \"docker\" || provider === \"podman\") ? `{ image: ${JSON.stringify(options.image)} }` : \"\"}) };\\nconst objective = process.argv.slice(2).join(\" \") || \"Inspect this repository and implement one useful improvement.\";\\n`;\n if (template === \"blank\")\n return `${imports}\\n${config}\\nconst result = await dispatch({ ...runtime, branch: { mode: \"integrate\" }, brief: { file: \".outpost/brief.md\", values: { OBJECTIVE: objective } } });\\nconsole.log({ branch: result.branch, commits: result.commits, conversation: result.conversation });\\n`;\n const backlog = options.tracker\n ? \"\"\n : `let pending = true;\\nconst requested = { id: \"objective\", title: objective };\\nconst backlog: Backlog = {\\n async list() { return pending ? [requested] : []; },\\n async get() { return requested; },\\n async close() { pending = false; },\\n};\\n`;\n return `${imports}\\n${config}\\n${backlog}\\nconst result = await campaign({\\n ...runtime, backlog,\\n cycles: 10, concurrency: ${planning ? 3 : 1},\\n implementationPasses: ${planning ? 100 : 1}, reviewPasses: 1,\\n planner: ${planning ? \"runtime.agent\" : \"false\"}, reviewer: ${reviewing ? \"runtime.agent\" : \"false\"},\\n copies: [\"node_modules\"],\\n standards: await readFile(new URL(\"./STANDARDS.md\", import.meta.url), \"utf8\"),\\n observe: event => console.log(\\`[cycle \\${event.cycle}] \\${event.phase}\\${event.issue ? \" \" + event.issue : \"\"}\\`),\\n});\\nconsole.log(result);\\nif (result.issues.some(issue => issue.state === \"failed\")) process.exitCode = 1;\\n`;\n}\n\nexport function tracker(\n kind: NonNullable<InitOptions[\"tracker\"]>,\n label?: string,\n): string {\n if (kind !== \"custom\") {\n const factory = kind === \"github\" ? \"githubBacklog\" : \"beadsBacklog\";\n return `import { ${factory} } from \"@elie-laloum/outpost\";\\nexport const backlog = ${factory}(${label ? `{ label: ${JSON.stringify(label)} }` : \"\"});\\n`;\n }\n return `import type { Backlog, Issue } from \"@elie-laloum/outpost\";\nasync function request(path: string, method = \"GET\", signal?: AbortSignal) {\n const base = process.env.OUTPOST_TRACKER_URL;\n if (!base) throw new Error(\"Set OUTPOST_TRACKER_URL\");\n const reply = await fetch(new URL(path, base.endsWith(\"/\") ? base : base + \"/\"), { method, signal });\n if (!reply.ok) throw new Error(\\`Tracker returned \\${reply.status}\\`);\n return reply;\n}\nexport const backlog: Backlog = {\n async list(signal) { return await (await request(\"issues?state=open\", \"GET\", signal)).json() as Issue[]; },\n async get(id, signal) { return await (await request(\"issues/\" + encodeURIComponent(id), \"GET\", signal)).json() as Issue; },\n async close(id, signal) { await request(\"issues/\" + encodeURIComponent(id) + \"/close\", \"POST\", signal); },\n};\n`;\n}\n"]}
1
+ {"version":3,"file":"starters.js","sourceRoot":"","sources":["../../src/cli/starters.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,OAAO,CAAC,OAAoB;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,EACpC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,MAAM,KAAK,GACT,OAAO,CAAC,KAAK,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ,CAAC;QAC/D,CAAC,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI;QAC7C,CAAC,CAAC,EAAE,CAAC;IACT,OAAO;;;qBAGY,KAAK;WACf,QAAQ,2CAA2C,QAAQ;;;kDAGpB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC;;;;;;;;;WAShF,KAAK,MAAM,KAAK;cACb,QAAQ,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;CAoBhC,CAAC;AACF,CAAC","sourcesContent":["import type { InitOptions } from \"./scaffold.types.ts\";\n\nexport function starter(options: InitOptions): string {\n const agent = options.agent ?? \"codex\",\n provider = options.provider ?? \"docker\";\n const model = options.model ? `model: ${JSON.stringify(options.model)}` : \"\";\n const image =\n options.image && (provider === \"docker\" || provider === \"podman\")\n ? `image: ${JSON.stringify(options.image)}, `\n : \"\";\n return `import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { parseEnv } from \"node:util\";\nimport { dispatch, ${agent}, OutpostError, reporter } from \"@elie-laloum/outpost\";\nimport { ${provider} } from \"@elie-laloum/outpost/providers/${provider}\";\n\n// Paths are relative to this workflow, regardless of where Node is launched.\nconst repository = resolve(import.meta.dirname, ${JSON.stringify(options.repository ?? \".\")});\nconst environment = await readFile(new URL(\".env\", import.meta.url), \"utf8\").catch((error) => {\n if (error.code === \"ENOENT\") return \"\";\n throw error;\n});\nconst variables = Object.fromEntries(\n Object.entries(parseEnv(environment)).map(([key, value]) => [key, value || process.env[key] || \"\"]),\n);\nconst runtime = {\n agent: ${agent}({ ${model} }),\n provider: ${provider}({ ${image}variables }),\n};\nconst objective = process.argv.slice(2).join(\" \") || \"Inspect this repository and implement one useful improvement.\";\n\nconsole.error(\"[outpost] Preparing sandbox...\");\ntry {\n const result = await dispatch({\n ...runtime,\n repository,\n branch: { mode: \"integrate\" },\n brief: { file: resolve(import.meta.dirname, \"brief.md\"), values: { OBJECTIVE: objective } },\n observe: reporter(),\n warn: (message) => console.error(message),\n });\n console.log({ branch: result.branch, commits: result.commits, conversation: result.conversation });\n} catch (error) {\n if (!(error instanceof OutpostError) || error.code !== \"aborted\") throw error;\n process.exitCode ||= 130;\n console.error(\"[outpost] Cancelled. Recovery details:\", error.recovery);\n}\n`;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -4,11 +4,6 @@ export type { DispatchOptions, Execution, Turn, } from "./application/execution.
4
4
  export { WorkflowFailure, task, workflow } from "./domain/workflow.ts";
5
5
  export type { Retry, Task, TaskContext, TaskOptions, TaskRecord, TaskStatus, Workflow, WorkflowEvent, WorkflowOptions, WorkflowResult, } from "./domain/workflow.ts";
6
6
  export { agentTask, commandTask, isolatedTask } from "./application/tasks.ts";
7
- export { campaign } from "./application/campaign.ts";
8
- export type { CampaignEvent, CampaignOptions, CampaignResult, IssueOutcome, } from "./application/campaign.ts";
9
- export type { Assignment, Backlog, Issue } from "./domain/backlog.ts";
10
- export { beadsBacklog, githubBacklog } from "./providers/backlogs.ts";
11
- export type { BacklogSettings } from "./providers/backlogs.ts";
12
7
  export { claude, codex } from "./providers/agents.ts";
13
8
  export { agentVersions } from "./providers/versions.ts";
14
9
  export { conversations } from "./infrastructure/conversations.ts";
package/dist/index.js CHANGED
@@ -1,8 +1,6 @@
1
1
  export { attach, createSandbox, dispatch, openWorkspace, } from "./application/outpost.js";
2
2
  export { WorkflowFailure, task, workflow } from "./domain/workflow.js";
3
3
  export { agentTask, commandTask, isolatedTask } from "./application/tasks.js";
4
- export { campaign } from "./application/campaign.js";
5
- export { beadsBacklog, githubBacklog } from "./providers/backlogs.js";
6
4
  export { claude, codex } from "./providers/agents.js";
7
5
  export { agentVersions } from "./providers/versions.js";
8
6
  export { conversations } from "./infrastructure/conversations.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,aAAa,EACb,QAAQ,EACR,aAAa,GACd,MAAM,0BAA0B,CAAC;AAoBlC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAevE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAWrD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAItE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AASlE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE3E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAI/D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAkCnE,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["export {\n attach,\n createSandbox,\n dispatch,\n openWorkspace,\n} from \"./application/outpost.ts\";\n\nexport type {\n AttachOptions,\n AttachResult,\n ContinuationOptions,\n DispatchResult,\n Sandbox,\n SandboxOptions,\n WarmDispatchResult,\n Workspace,\n WorkspaceOptions,\n} from \"./application/outpost.ts\";\n\nexport type {\n DispatchOptions,\n Execution,\n Turn,\n} from \"./application/execution.ts\";\n\nexport { WorkflowFailure, task, workflow } from \"./domain/workflow.ts\";\n\nexport type {\n Retry,\n Task,\n TaskContext,\n TaskOptions,\n TaskRecord,\n TaskStatus,\n Workflow,\n WorkflowEvent,\n WorkflowOptions,\n WorkflowResult,\n} from \"./domain/workflow.ts\";\n\nexport { agentTask, commandTask, isolatedTask } from \"./application/tasks.ts\";\n\nexport { campaign } from \"./application/campaign.ts\";\n\nexport type {\n CampaignEvent,\n CampaignOptions,\n CampaignResult,\n IssueOutcome,\n} from \"./application/campaign.ts\";\n\nexport type { Assignment, Backlog, Issue } from \"./domain/backlog.ts\";\n\nexport { beadsBacklog, githubBacklog } from \"./providers/backlogs.ts\";\n\nexport type { BacklogSettings } from \"./providers/backlogs.ts\";\n\nexport { claude, codex } from \"./providers/agents.ts\";\n\nexport { agentVersions } from \"./providers/versions.ts\";\n\nexport { conversations } from \"./infrastructure/conversations.ts\";\n\nexport type {\n ConversationFormat,\n ConversationLocation,\n} from \"./infrastructure/conversations.ts\";\n\nexport type { ClaudeSettings, CodexSettings } from \"./providers/agents.ts\";\n\nexport { mountedProvider, remoteProvider } from \"./providers/factories.ts\";\n\nexport { ResponseError, response } from \"./domain/response.ts\";\n\nexport type { ResponseSpec, StandardValidator } from \"./domain/response.ts\";\n\nexport { OutpostError, recoveryDetails } from \"./domain/errors.ts\";\n\nexport type { FaultCode } from \"./domain/errors.ts\";\n\nexport type {\n AgentAdapter,\n AgentEvent,\n AgentInput,\n AgentObservation,\n BranchPolicy,\n Channel,\n Command,\n CommandResult,\n Commit,\n ConversationContext,\n ConversationRecord,\n ConversationStore,\n Disposal,\n LifecycleHooks,\n SandboxContext,\n SandboxLease,\n SandboxProvider,\n StageLimits,\n TransferOptions,\n Usage,\n Variables,\n Volume,\n WorkspaceRecord,\n} from \"./domain/ports.ts\";\n\nexport type { Brief, PromptVariables } from \"./domain/prompts.ts\";\n\nexport type { Logging } from \"./infrastructure/journal.ts\";\n\nexport { reporter } from \"./infrastructure/reporter.ts\";\n\nexport type { ReporterOptions } from \"./infrastructure/reporter.ts\";\n\nexport type { VariableQuestion } from \"./application/interactive-brief.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,aAAa,EACb,QAAQ,EACR,aAAa,GACd,MAAM,0BAA0B,CAAC;AAoBlC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAevE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AASlE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE3E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAI/D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAkCnE,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["export {\n attach,\n createSandbox,\n dispatch,\n openWorkspace,\n} from \"./application/outpost.ts\";\n\nexport type {\n AttachOptions,\n AttachResult,\n ContinuationOptions,\n DispatchResult,\n Sandbox,\n SandboxOptions,\n WarmDispatchResult,\n Workspace,\n WorkspaceOptions,\n} from \"./application/outpost.ts\";\n\nexport type {\n DispatchOptions,\n Execution,\n Turn,\n} from \"./application/execution.ts\";\n\nexport { WorkflowFailure, task, workflow } from \"./domain/workflow.ts\";\n\nexport type {\n Retry,\n Task,\n TaskContext,\n TaskOptions,\n TaskRecord,\n TaskStatus,\n Workflow,\n WorkflowEvent,\n WorkflowOptions,\n WorkflowResult,\n} from \"./domain/workflow.ts\";\n\nexport { agentTask, commandTask, isolatedTask } from \"./application/tasks.ts\";\n\nexport { claude, codex } from \"./providers/agents.ts\";\n\nexport { agentVersions } from \"./providers/versions.ts\";\n\nexport { conversations } from \"./infrastructure/conversations.ts\";\n\nexport type {\n ConversationFormat,\n ConversationLocation,\n} from \"./infrastructure/conversations.ts\";\n\nexport type { ClaudeSettings, CodexSettings } from \"./providers/agents.ts\";\n\nexport { mountedProvider, remoteProvider } from \"./providers/factories.ts\";\n\nexport { ResponseError, response } from \"./domain/response.ts\";\n\nexport type { ResponseSpec, StandardValidator } from \"./domain/response.ts\";\n\nexport { OutpostError, recoveryDetails } from \"./domain/errors.ts\";\n\nexport type { FaultCode } from \"./domain/errors.ts\";\n\nexport type {\n AgentAdapter,\n AgentEvent,\n AgentInput,\n AgentObservation,\n BranchPolicy,\n Channel,\n Command,\n CommandResult,\n Commit,\n ConversationContext,\n ConversationRecord,\n ConversationStore,\n Disposal,\n LifecycleHooks,\n SandboxContext,\n SandboxLease,\n SandboxProvider,\n StageLimits,\n TransferOptions,\n Usage,\n Variables,\n Volume,\n WorkspaceRecord,\n} from \"./domain/ports.ts\";\n\nexport type { Brief, PromptVariables } from \"./domain/prompts.ts\";\n\nexport type { Logging } from \"./infrastructure/journal.ts\";\n\nexport { reporter } from \"./infrastructure/reporter.ts\";\n\nexport type { ReporterOptions } from \"./infrastructure/reporter.ts\";\n\nexport type { VariableQuestion } from \"./application/interactive-brief.ts\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elie-laloum/outpost",
3
- "version": "1.1.4",
3
+ "version": "2.0.0",
4
4
  "description": "Programmable sandboxes, coding agents and typed workflows.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,4 +0,0 @@
1
- export declare const backlogDefaults: Readonly<{
2
- deadlineMs: 60000;
3
- retainBytes: 16777216;
4
- }>;
@@ -1,5 +0,0 @@
1
- export const backlogDefaults = Object.freeze({
2
- deadlineMs: 60_000,
3
- retainBytes: 16_777_216,
4
- });
5
- //# sourceMappingURL=backlog.constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"backlog.constants.js","sourceRoot":"","sources":["../../../src/adapters/backlogs/backlog.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,UAAU;CACxB,CAAC,CAAC","sourcesContent":["export const backlogDefaults = Object.freeze({\n deadlineMs: 60_000,\n retainBytes: 16_777_216,\n});\n"]}
@@ -1,4 +0,0 @@
1
- import type { Backlog } from "../../domain/backlog.types.ts";
2
- import type { Executor } from "../../infrastructure/process.types.ts";
3
- import type { BacklogSettings } from "./settings.types.ts";
4
- export declare function beadsBacklog(settings?: BacklogSettings, executor?: Executor): Backlog;
@@ -1,31 +0,0 @@
1
- import { invariant } from "../../domain/errors.js";
2
- import { cli } from "./cli.js";
3
- import { issue } from "./issue.js";
4
- export function beadsBacklog(settings = {}, executor) {
5
- const run = cli("bd", settings, executor);
6
- const identifier = (id) => {
7
- invariant(/^[\w][\w.-]*$/.test(id), "Invalid Beads issue id");
8
- return id;
9
- };
10
- return {
11
- async list(signal) {
12
- const data = JSON.parse(await run([
13
- "ready",
14
- "--json",
15
- "--limit",
16
- "0",
17
- ...(settings.label ? ["--label", settings.label] : []),
18
- ], signal));
19
- invariant(Array.isArray(data), "Invalid Beads backlog");
20
- return data.map(issue);
21
- },
22
- async get(id, signal) {
23
- const data = JSON.parse(await run(["show", identifier(id), "--json"], signal));
24
- return issue(Array.isArray(data) ? data[0] : data);
25
- },
26
- async close(id, signal) {
27
- await run(["close", identifier(id)], signal);
28
- },
29
- };
30
- }
31
- //# sourceMappingURL=beads-adapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"beads-adapter.js","sourceRoot":"","sources":["../../../src/adapters/backlogs/beads-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,MAAM,UAAU,YAAY,CAC1B,WAA4B,EAAE,EAC9B,QAAmB;IAEnB,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,CAAC,EAAU,EAAE,EAAE;QAChC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAC9D,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IACF,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,MAAM;YACf,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAC9B,MAAM,GAAG,CACP;gBACE,OAAO;gBACP,QAAQ;gBACR,SAAS;gBACT,GAAG;gBACH,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aACvD,EACD,MAAM,CACP,CACF,CAAC;YACF,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,uBAAuB,CAAC,CAAC;YACxD,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM;YAClB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CACrB,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CACtD,CAAC;YACF,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM;YACpB,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Backlog } from \"../../domain/backlog.types.ts\";\nimport { invariant } from \"../../domain/errors.ts\";\nimport type { Executor } from \"../../infrastructure/process.types.ts\";\nimport { cli } from \"./cli.ts\";\nimport { issue } from \"./issue.ts\";\nimport type { BacklogSettings } from \"./settings.types.ts\";\n\nexport function beadsBacklog(\n settings: BacklogSettings = {},\n executor?: Executor,\n): Backlog {\n const run = cli(\"bd\", settings, executor);\n const identifier = (id: string) => {\n invariant(/^[\\w][\\w.-]*$/.test(id), \"Invalid Beads issue id\");\n return id;\n };\n return {\n async list(signal) {\n const data: unknown = JSON.parse(\n await run(\n [\n \"ready\",\n \"--json\",\n \"--limit\",\n \"0\",\n ...(settings.label ? [\"--label\", settings.label] : []),\n ],\n signal,\n ),\n );\n invariant(Array.isArray(data), \"Invalid Beads backlog\");\n return data.map(issue);\n },\n async get(id, signal) {\n const data = JSON.parse(\n await run([\"show\", identifier(id), \"--json\"], signal),\n );\n return issue(Array.isArray(data) ? data[0] : data);\n },\n async close(id, signal) {\n await run([\"close\", identifier(id)], signal);\n },\n };\n}\n"]}
@@ -1,3 +0,0 @@
1
- import type { Executor } from "../../infrastructure/process.types.ts";
2
- import type { BacklogSettings } from "./settings.types.ts";
3
- export declare function cli(program: string, settings: BacklogSettings, executor?: Executor): (args: readonly string[], signal?: AbortSignal) => Promise<string>;
@@ -1,20 +0,0 @@
1
- import { requireSuccess } from "../../infrastructure/process.js";
2
- import { resolveVariables } from "../../infrastructure/settings.js";
3
- import { backlogDefaults } from "./backlog.constants.js";
4
- export function cli(program, settings, executor) {
5
- const directory = settings.directory ?? process.cwd();
6
- return async (args, signal) => {
7
- signal?.throwIfAborted();
8
- const variables = await resolveVariables(directory);
9
- return (await requireSuccess({
10
- executable: program,
11
- arguments: args,
12
- directory,
13
- variables,
14
- deadlineMs: settings.deadlineMs ?? backlogDefaults.deadlineMs,
15
- retain: backlogDefaults.retainBytes,
16
- ...(signal ? { signal } : {}),
17
- }, executor)).stdout;
18
- };
19
- }
20
- //# sourceMappingURL=cli.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/adapters/backlogs/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,MAAM,UAAU,GAAG,CACjB,OAAe,EACf,QAAyB,EACzB,QAAmB;IAEnB,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtD,OAAO,KAAK,EAAE,IAAuB,EAAE,MAAoB,EAAE,EAAE;QAC7D,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACpD,OAAO,CACL,MAAM,cAAc,CAClB;YACE,UAAU,EAAE,OAAO;YACnB,SAAS,EAAE,IAAI;YACf,SAAS;YACT,SAAS;YACT,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,eAAe,CAAC,UAAU;YAC7D,MAAM,EAAE,eAAe,CAAC,WAAW;YACnC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,EACD,QAAQ,CACT,CACF,CAAC,MAAM,CAAC;IACX,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { requireSuccess } from \"../../infrastructure/process.ts\";\nimport type { Executor } from \"../../infrastructure/process.types.ts\";\nimport { resolveVariables } from \"../../infrastructure/settings.ts\";\nimport { backlogDefaults } from \"./backlog.constants.ts\";\nimport type { BacklogSettings } from \"./settings.types.ts\";\n\nexport function cli(\n program: string,\n settings: BacklogSettings,\n executor?: Executor,\n) {\n const directory = settings.directory ?? process.cwd();\n return async (args: readonly string[], signal?: AbortSignal) => {\n signal?.throwIfAborted();\n const variables = await resolveVariables(directory);\n return (\n await requireSuccess(\n {\n executable: program,\n arguments: args,\n directory,\n variables,\n deadlineMs: settings.deadlineMs ?? backlogDefaults.deadlineMs,\n retain: backlogDefaults.retainBytes,\n ...(signal ? { signal } : {}),\n },\n executor,\n )\n ).stdout;\n };\n}\n"]}
@@ -1,4 +0,0 @@
1
- import type { Backlog } from "../../domain/backlog.types.ts";
2
- import type { Executor } from "../../infrastructure/process.types.ts";
3
- import type { BacklogSettings } from "./settings.types.ts";
4
- export declare function githubBacklog(settings?: BacklogSettings, executor?: Executor): Backlog;
@@ -1,28 +0,0 @@
1
- import { invariant } from "../../domain/errors.js";
2
- import { cli } from "./cli.js";
3
- import { issue } from "./issue.js";
4
- export function githubBacklog(settings = {}, executor) {
5
- const run = cli("gh", settings, executor);
6
- const identifier = (id) => {
7
- invariant(/^[1-9]\d*$/.test(id), "GitHub issue id must be a positive number");
8
- return id;
9
- };
10
- return {
11
- async list(signal) {
12
- const endpoint = `repos/{owner}/{repo}/issues?state=open&per_page=100${settings.label ? `&labels=${encodeURIComponent(settings.label)}` : ""}`;
13
- const pages = JSON.parse(await run(["api", endpoint, "--paginate", "--slurp"], signal));
14
- invariant(Array.isArray(pages) && pages.every(Array.isArray), "Invalid GitHub issue pages");
15
- return pages
16
- .flat()
17
- .filter((item) => !item.pull_request)
18
- .map(issue);
19
- },
20
- async get(id, signal) {
21
- return issue(JSON.parse(await run(["issue", "view", identifier(id), "--json", "number,title,body"], signal)));
22
- },
23
- async close(id, signal) {
24
- await run(["issue", "close", identifier(id), "--reason", "completed"], signal);
25
- },
26
- };
27
- }
28
- //# sourceMappingURL=github-adapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"github-adapter.js","sourceRoot":"","sources":["../../../src/adapters/backlogs/github-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,MAAM,UAAU,aAAa,CAC3B,WAA4B,EAAE,EAC9B,QAAmB;IAEnB,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,CAAC,EAAU,EAAE,EAAE;QAChC,SAAS,CACP,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EACrB,2CAA2C,CAC5C,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IACF,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,MAAM;YACf,MAAM,QAAQ,GAAG,sDAAsD,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC/I,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAC/B,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAC9D,CAAC;YACF,SAAS,CACP,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAClD,4BAA4B,CAC7B,CAAC;YACF,OAAO,KAAK;iBACT,IAAI,EAAE;iBACN,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;iBACpC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM;YAClB,OAAO,KAAK,CACV,IAAI,CAAC,KAAK,CACR,MAAM,GAAG,CACP,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,EAChE,MAAM,CACP,CACF,CACF,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM;YACpB,MAAM,GAAG,CACP,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,EAC3D,MAAM,CACP,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Backlog } from \"../../domain/backlog.types.ts\";\nimport { invariant } from \"../../domain/errors.ts\";\nimport type { Executor } from \"../../infrastructure/process.types.ts\";\nimport { cli } from \"./cli.ts\";\nimport { issue } from \"./issue.ts\";\nimport type { BacklogSettings } from \"./settings.types.ts\";\n\nexport function githubBacklog(\n settings: BacklogSettings = {},\n executor?: Executor,\n): Backlog {\n const run = cli(\"gh\", settings, executor);\n const identifier = (id: string) => {\n invariant(\n /^[1-9]\\d*$/.test(id),\n \"GitHub issue id must be a positive number\",\n );\n return id;\n };\n return {\n async list(signal) {\n const endpoint = `repos/{owner}/{repo}/issues?state=open&per_page=100${settings.label ? `&labels=${encodeURIComponent(settings.label)}` : \"\"}`;\n const pages: unknown = JSON.parse(\n await run([\"api\", endpoint, \"--paginate\", \"--slurp\"], signal),\n );\n invariant(\n Array.isArray(pages) && pages.every(Array.isArray),\n \"Invalid GitHub issue pages\",\n );\n return pages\n .flat()\n .filter((item) => !item.pull_request)\n .map(issue);\n },\n async get(id, signal) {\n return issue(\n JSON.parse(\n await run(\n [\"issue\", \"view\", identifier(id), \"--json\", \"number,title,body\"],\n signal,\n ),\n ),\n );\n },\n async close(id, signal) {\n await run(\n [\"issue\", \"close\", identifier(id), \"--reason\", \"completed\"],\n signal,\n );\n },\n };\n}\n"]}
@@ -1,2 +0,0 @@
1
- import type { Issue } from "../../domain/backlog.types.ts";
2
- export declare function issue(input: unknown): Issue;
@@ -1,13 +0,0 @@
1
- import { invariant } from "../../domain/errors.js";
2
- export function issue(input) {
3
- invariant(!!input && typeof input === "object", "Tracker returned an invalid issue");
4
- const item = input;
5
- invariant((typeof item.id === "string" || typeof item.number === "number") &&
6
- typeof item.title === "string", "Tracker issue needs an id and a title");
7
- return {
8
- id: String(item.number ?? item.id),
9
- title: item.title,
10
- body: String(item.body ?? item.description ?? ""),
11
- };
12
- }
13
- //# sourceMappingURL=issue.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"issue.js","sourceRoot":"","sources":["../../../src/adapters/backlogs/issue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,UAAU,KAAK,CAAC,KAAc;IAClC,SAAS,CACP,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EACpC,mCAAmC,CACpC,CAAC;IACF,MAAM,IAAI,GAAG,KAAgC,CAAC;IAC9C,SAAS,CACP,CAAC,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC;QAC9D,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAChC,uCAAuC,CACxC,CAAC;IACF,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC;QAClC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC","sourcesContent":["import type { Issue } from \"../../domain/backlog.types.ts\";\nimport { invariant } from \"../../domain/errors.ts\";\n\nexport function issue(input: unknown): Issue {\n invariant(\n !!input && typeof input === \"object\",\n \"Tracker returned an invalid issue\",\n );\n const item = input as Record<string, unknown>;\n invariant(\n (typeof item.id === \"string\" || typeof item.number === \"number\") &&\n typeof item.title === \"string\",\n \"Tracker issue needs an id and a title\",\n );\n return {\n id: String(item.number ?? item.id),\n title: item.title,\n body: String(item.body ?? item.description ?? \"\"),\n };\n}\n"]}
@@ -1,5 +0,0 @@
1
- export interface BacklogSettings {
2
- readonly directory?: string;
3
- readonly label?: string;
4
- readonly deadlineMs?: number;
5
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=settings.types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"settings.types.js","sourceRoot":"","sources":["../../../src/adapters/backlogs/settings.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface BacklogSettings {\n readonly directory?: string;\n readonly label?: string;\n readonly deadlineMs?: number;\n}\n"]}
@@ -1,2 +0,0 @@
1
- import type { CampaignContext, CompletedIssue } from "./campaign.types.ts";
2
- export declare function integrateIssues(context: CampaignContext, completed: readonly CompletedIssue[]): Promise<void>;
@@ -1,44 +0,0 @@
1
- import { invariant, OutpostError } from "../domain/errors.js";
2
- import { createSandbox } from "./sandbox.js";
3
- export async function integrateIssues(context, completed) {
4
- const { runtime, standards, options: { merger }, } = context;
5
- const integration = await createSandbox({
6
- ...runtime,
7
- agent: merger ?? runtime.agent,
8
- branch: { mode: "integrate" },
9
- });
10
- let integrated = false;
11
- try {
12
- for (const item of completed) {
13
- const merged = await integration.command({
14
- executable: "git",
15
- arguments: ["merge", "--no-edit", item.head],
16
- ...(runtime.signal ? { signal: runtime.signal } : {}),
17
- });
18
- await integration.dispatch({
19
- agent: merger ?? runtime.agent,
20
- ...(runtime.signal ? { signal: runtime.signal } : {}),
21
- brief: {
22
- text: `Validate integration of issue ${item.id} from commit ${item.head}. ${merged.status ? "Resolve the current Git merge conflict and finish the merge." : "The commits have been merged."} Run relevant tests, fix integration defects and commit any changes. ${standards} Do not close issues. When complete, write <outpost>done</outpost>.`,
23
- },
24
- });
25
- const verified = await integration.command({
26
- executable: "git",
27
- arguments: ["merge-base", "--is-ancestor", item.head, "HEAD"],
28
- });
29
- if (verified.status)
30
- throw new OutpostError("conflict", "Merge did not include the issue commits", { issue: item.id, branch: item.branch });
31
- }
32
- const clean = await integration.command({
33
- executable: "git",
34
- arguments: ["status", "--porcelain"],
35
- });
36
- invariant(clean.status === 0 && !clean.stdout.trim(), "Integration has uncommitted changes");
37
- await integration.workspace.integrate();
38
- integrated = true;
39
- }
40
- finally {
41
- await integration.close({ preserve: !integrated });
42
- }
43
- }
44
- //# sourceMappingURL=campaign-integration.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"campaign-integration.js","sourceRoot":"","sources":["../../src/application/campaign-integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAwB,EACxB,SAAoC;IAEpC,MAAM,EACJ,OAAO,EACP,SAAS,EACT,OAAO,EAAE,EAAE,MAAM,EAAE,GACpB,GAAG,OAAO,CAAC;IACZ,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC;QACtC,GAAG,OAAO;QACV,KAAK,EAAE,MAAM,IAAI,OAAO,CAAC,KAAK;QAC9B,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;KAC9B,CAAC,CAAC;IACH,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,CAAC;QACH,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC;gBACvC,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC;gBAC5C,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtD,CAAC,CAAC;YACH,MAAM,WAAW,CAAC,QAAQ,CAAC;gBACzB,KAAK,EAAE,MAAM,IAAI,OAAO,CAAC,KAAK;gBAC9B,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,KAAK,EAAE;oBACL,IAAI,EAAE,iCAAiC,IAAI,CAAC,EAAE,gBAAgB,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,8DAA8D,CAAC,CAAC,CAAC,+BAA+B,wEAAwE,SAAS,qEAAqE;iBACnV;aACF,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC;gBACzC,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,CAAC,YAAY,EAAE,eAAe,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;aAC9D,CAAC,CAAC;YACH,IAAI,QAAQ,CAAC,MAAM;gBACjB,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,yCAAyC,EACzC,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CACxC,CAAC;QACN,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC;YACtC,UAAU,EAAE,KAAK;YACjB,SAAS,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC;SACrC,CAAC,CAAC;QACH,SAAS,CACP,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAC1C,qCAAqC,CACtC,CAAC;QACF,MAAM,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;QACxC,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,MAAM,WAAW,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC","sourcesContent":["import { invariant, OutpostError } from \"../domain/errors.ts\";\nimport type { CampaignContext, CompletedIssue } from \"./campaign.types.ts\";\nimport { createSandbox } from \"./sandbox.ts\";\n\nexport async function integrateIssues(\n context: CampaignContext,\n completed: readonly CompletedIssue[],\n): Promise<void> {\n const {\n runtime,\n standards,\n options: { merger },\n } = context;\n const integration = await createSandbox({\n ...runtime,\n agent: merger ?? runtime.agent,\n branch: { mode: \"integrate\" },\n });\n let integrated = false;\n try {\n for (const item of completed) {\n const merged = await integration.command({\n executable: \"git\",\n arguments: [\"merge\", \"--no-edit\", item.head],\n ...(runtime.signal ? { signal: runtime.signal } : {}),\n });\n await integration.dispatch({\n agent: merger ?? runtime.agent,\n ...(runtime.signal ? { signal: runtime.signal } : {}),\n brief: {\n text: `Validate integration of issue ${item.id} from commit ${item.head}. ${merged.status ? \"Resolve the current Git merge conflict and finish the merge.\" : \"The commits have been merged.\"} Run relevant tests, fix integration defects and commit any changes. ${standards} Do not close issues. When complete, write <outpost>done</outpost>.`,\n },\n });\n const verified = await integration.command({\n executable: \"git\",\n arguments: [\"merge-base\", \"--is-ancestor\", item.head, \"HEAD\"],\n });\n if (verified.status)\n throw new OutpostError(\n \"conflict\",\n \"Merge did not include the issue commits\",\n { issue: item.id, branch: item.branch },\n );\n }\n const clean = await integration.command({\n executable: \"git\",\n arguments: [\"status\", \"--porcelain\"],\n });\n invariant(\n clean.status === 0 && !clean.stdout.trim(),\n \"Integration has uncommitted changes\",\n );\n await integration.workspace.integrate();\n integrated = true;\n } finally {\n await integration.close({ preserve: !integrated });\n }\n}\n"]}
@@ -1,3 +0,0 @@
1
- import type { Assignment, Issue } from "../domain/backlog.types.ts";
2
- import type { CampaignContext } from "./campaign.types.ts";
3
- export declare function planIssues(context: CampaignContext, ready: readonly Issue[], concurrency: number): Promise<readonly Assignment[]>;
@@ -1,35 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { readPlan } from "../domain/backlog.js";
3
- import { invariant } from "../domain/errors.js";
4
- import { response } from "../domain/response.js";
5
- import { dispatch } from "./dispatch.js";
6
- export async function planIssues(context, ready, concurrency) {
7
- const { runtime, emit, options: { planner }, } = context;
8
- const prefix = `outpost/batch-${randomUUID().slice(0, 8)}`;
9
- let assignments;
10
- if (planner !== false) {
11
- emit("plan");
12
- const plan = await dispatch({
13
- ...runtime,
14
- agent: planner ?? runtime.agent,
15
- branch: { mode: "named", name: `${prefix}-planning` },
16
- brief: {
17
- text: `Select independent, unblocked issues from this backlog. Read the repository without editing files. Return <assignments>{"issues":[{"id":"an existing id","branch":"${prefix}-short-name"}]}</assignments>. Return an empty array when blocked.\n${JSON.stringify(ready)}`,
18
- },
19
- response: response.json({
20
- tag: "assignments",
21
- schema: readPlan,
22
- repairs: 1,
23
- }),
24
- });
25
- invariant(!plan.commits.length && !plan.retainedDirectory, "Planner changed its workspace; inspect the planning branch before continuing");
26
- assignments = plan.value;
27
- }
28
- else
29
- assignments = ready.slice(0, concurrency).map((issue, index) => ({
30
- id: issue.id,
31
- branch: `${prefix}-${index + 1}`,
32
- }));
33
- return assignments;
34
- }
35
- //# sourceMappingURL=campaign-planner.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"campaign-planner.js","sourceRoot":"","sources":["../../src/application/campaign-planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAwB,EACxB,KAAuB,EACvB,WAAmB;IAEnB,MAAM,EACJ,OAAO,EACP,IAAI,EACJ,OAAO,EAAE,EAAE,OAAO,EAAE,GACrB,GAAG,OAAO,CAAC;IACZ,MAAM,MAAM,GAAG,iBAAiB,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC3D,IAAI,WAAkC,CAAC;IACvC,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC;YAC1B,GAAG,OAAO;YACV,KAAK,EAAE,OAAO,IAAI,OAAO,CAAC,KAAK;YAC/B,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,WAAW,EAAE;YACrD,KAAK,EAAE;gBACL,IAAI,EAAE,sKAAsK,MAAM,uEAAuE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;aACjR;YACD,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;gBACtB,GAAG,EAAE,aAAa;gBAClB,MAAM,EAAE,QAAQ;gBAChB,OAAO,EAAE,CAAC;aACX,CAAC;SACH,CAAC,CAAC;QACH,SAAS,CACP,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAC/C,8EAA8E,CAC/E,CAAC;QACF,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;IAC3B,CAAC;;QACC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YAC/D,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,MAAM,EAAE,GAAG,MAAM,IAAI,KAAK,GAAG,CAAC,EAAE;SACjC,CAAC,CAAC,CAAC;IAEN,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { readPlan } from \"../domain/backlog.ts\";\nimport type { Assignment, Issue } from \"../domain/backlog.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport { response } from \"../domain/response.ts\";\nimport type { CampaignContext } from \"./campaign.types.ts\";\nimport { dispatch } from \"./dispatch.ts\";\n\nexport async function planIssues(\n context: CampaignContext,\n ready: readonly Issue[],\n concurrency: number,\n): Promise<readonly Assignment[]> {\n const {\n runtime,\n emit,\n options: { planner },\n } = context;\n const prefix = `outpost/batch-${randomUUID().slice(0, 8)}`;\n let assignments: readonly Assignment[];\n if (planner !== false) {\n emit(\"plan\");\n const plan = await dispatch({\n ...runtime,\n agent: planner ?? runtime.agent,\n branch: { mode: \"named\", name: `${prefix}-planning` },\n brief: {\n text: `Select independent, unblocked issues from this backlog. Read the repository without editing files. Return <assignments>{\"issues\":[{\"id\":\"an existing id\",\"branch\":\"${prefix}-short-name\"}]}</assignments>. Return an empty array when blocked.\\n${JSON.stringify(ready)}`,\n },\n response: response.json({\n tag: \"assignments\",\n schema: readPlan,\n repairs: 1,\n }),\n });\n invariant(\n !plan.commits.length && !plan.retainedDirectory,\n \"Planner changed its workspace; inspect the planning branch before continuing\",\n );\n assignments = plan.value;\n } else\n assignments = ready.slice(0, concurrency).map((issue, index) => ({\n id: issue.id,\n branch: `${prefix}-${index + 1}`,\n }));\n\n return assignments;\n}\n"]}
@@ -1,3 +0,0 @@
1
- import type { Assignment } from "../domain/backlog.types.ts";
2
- import type { CampaignContext, CompletedIssue } from "./campaign.types.ts";
3
- export declare function implementIssue(context: CampaignContext, assignment: Assignment, baseline: string, signal: AbortSignal): Promise<CompletedIssue | undefined>;