forgeos 0.1.0-alpha.65 → 0.1.0-alpha.67

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 (284) hide show
  1. package/.npmignore +19 -19
  2. package/AGENTS.md +1 -1
  3. package/CHANGELOG.md +24 -0
  4. package/LICENSE +21 -21
  5. package/README.md +525 -525
  6. package/adapters/java/README.md +68 -68
  7. package/adapters/java/pom.xml +47 -47
  8. package/adapters/java/src/main/java/dev/forgeos/adapter/Auth.java +20 -20
  9. package/adapters/java/src/main/java/dev/forgeos/adapter/Diagnostic.java +16 -16
  10. package/adapters/java/src/main/java/dev/forgeos/adapter/Entry.java +38 -38
  11. package/adapters/java/src/main/java/dev/forgeos/adapter/EntryKind.java +16 -16
  12. package/adapters/java/src/main/java/dev/forgeos/adapter/ErrorInfo.java +4 -4
  13. package/adapters/java/src/main/java/dev/forgeos/adapter/Forge.java +94 -94
  14. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeCall.java +12 -12
  15. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeContext.java +11 -11
  16. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHandler.java +8 -8
  17. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeHttpHandler.java +179 -179
  18. package/adapters/java/src/main/java/dev/forgeos/adapter/ForgeRegistry.java +121 -121
  19. package/adapters/java/src/main/java/dev/forgeos/adapter/Json.java +14 -14
  20. package/adapters/java/src/main/java/dev/forgeos/adapter/Manifest.java +14 -14
  21. package/adapters/java/src/main/java/dev/forgeos/adapter/RequestEnvelope.java +6 -6
  22. package/adapters/java/src/main/java/dev/forgeos/adapter/ResponseEnvelope.java +25 -25
  23. package/adapters/java/src/main/java/dev/forgeos/adapter/Risk.java +18 -18
  24. package/adapters/java/src/main/java/dev/forgeos/adapter/Schemas.java +36 -36
  25. package/adapters/java/src/main/java/dev/forgeos/adapter/Service.java +65 -65
  26. package/adapters/java/src/main/java/dev/forgeos/adapter/TransactionMode.java +18 -18
  27. package/adapters/java/src/main/java/dev/forgeos/adapter/TypedForgeHandler.java +6 -6
  28. package/adapters/java-spring-boot-starter/README.md +32 -32
  29. package/adapters/java-spring-boot-starter/pom.xml +49 -49
  30. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeCommand.java +22 -22
  31. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeExternalService.java +15 -15
  32. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeQuery.java +16 -16
  33. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeServiceBeanCondition.java +18 -18
  34. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringAutoConfiguration.java +16 -16
  35. package/adapters/java-spring-boot-starter/src/main/java/dev/forgeos/adapter/spring/ForgeSpringRuntime.java +104 -104
  36. package/adapters/java-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +1 -1
  37. package/bin/forge.mjs +38 -38
  38. package/docs/agent-fabric.md +131 -0
  39. package/examples/java-billing/pom.xml +60 -60
  40. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/CreateInvoiceInput.java +4 -4
  41. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Invoice.java +11 -11
  42. package/examples/java-billing/src/main/java/dev/forgeos/examples/billing/Main.java +127 -127
  43. package/package.json +5 -4
  44. package/packages/eslint-plugin-forge/index.ts +15 -15
  45. package/packages/eslint-plugin-forge/package.json +10 -10
  46. package/packages/eslint-plugin-forge/src/check-source.ts +95 -95
  47. package/packages/eslint-plugin-forge/src/load-artifacts.ts +24 -24
  48. package/packages/eslint-plugin-forge/src/rule-no-forge-guard-violation.ts +93 -93
  49. package/schemas/agent-fabric/v0.1/control-event.schema.json +281 -281
  50. package/scripts/field-test-forgeos.mjs +1021 -1021
  51. package/src/forge/_generated/releaseManifest.json +1 -1
  52. package/src/forge/_generated/releaseManifest.ts +3 -3
  53. package/src/forge/agent-adapters/index.ts +7 -3
  54. package/src/forge/agent-adapters/types.ts +1 -0
  55. package/src/forge/agent-fabric/attached-snapshot.ts +55 -0
  56. package/src/forge/agent-fabric/attached-task-contract.ts +105 -0
  57. package/src/forge/agent-fabric/attached-task-service.ts +127 -0
  58. package/src/forge/agent-fabric/attached-task-store.ts +109 -0
  59. package/src/forge/agent-fabric/codex-adversarial-review.ts +229 -0
  60. package/src/forge/agent-fabric/codex-sdk-worker.ts +163 -0
  61. package/src/forge/agent-fabric/index.ts +19 -0
  62. package/src/forge/agent-fabric/local-adaptive-digest-worker.mjs +26 -26
  63. package/src/forge/agent-fabric/local-change-review-service.ts +374 -0
  64. package/src/forge/agent-fabric/local-task-server.ts +324 -249
  65. package/src/forge/agent-fabric/managed-environment.ts +205 -0
  66. package/src/forge/agent-fabric/managed-run-contract.ts +102 -0
  67. package/src/forge/agent-fabric/managed-run-service.ts +392 -0
  68. package/src/forge/agent-fabric/managed-run-store.ts +135 -0
  69. package/src/forge/agent-fabric/managed-workspace.ts +214 -0
  70. package/src/forge/agent-fabric/readiness.ts +26 -0
  71. package/src/forge/agent-fabric/workflow-engine.ts +218 -0
  72. package/src/forge/agent-fabric/workflow-task-actions.ts +104 -0
  73. package/src/forge/agent-fabric/workflow-templates.ts +11 -0
  74. package/src/forge/agent-memory/bridge.ts +309 -47
  75. package/src/forge/agent-memory/context-pack.ts +8 -1
  76. package/src/forge/agent-memory/hook-runner.ts +38 -19
  77. package/src/forge/agent-memory/mcp.ts +500 -286
  78. package/src/forge/agent-memory/sources/codex-hook-runner.mjs +343 -234
  79. package/src/forge/agent-memory/sources/codex.ts +49 -7
  80. package/src/forge/agent-memory/types.ts +11 -0
  81. package/src/forge/bench.ts +154 -154
  82. package/src/forge/cair/action-journal.ts +61 -61
  83. package/src/forge/cair/action-parser.ts +314 -314
  84. package/src/forge/cair/action-validator.ts +40 -40
  85. package/src/forge/cair/actions.ts +1818 -1818
  86. package/src/forge/cair/format.ts +77 -77
  87. package/src/forge/cair/index.ts +106 -106
  88. package/src/forge/cair/query.ts +478 -478
  89. package/src/forge/cair/snapshot.ts +315 -315
  90. package/src/forge/cair/types.ts +248 -248
  91. package/src/forge/cli/ai.ts +816 -816
  92. package/src/forge/cli/codex-app-server.ts +877 -877
  93. package/src/forge/cli/fabric.ts +205 -131
  94. package/src/forge/cli/index.ts +26 -26
  95. package/src/forge/cli/main.ts +259 -245
  96. package/src/forge/cli/next-actions.ts +23 -23
  97. package/src/forge/cli/parse.ts +3574 -3542
  98. package/src/forge/cli/release.ts +309 -309
  99. package/src/forge/cli/self-host.ts +510 -510
  100. package/src/forge/compiler/ai-registry/parse.ts +219 -219
  101. package/src/forge/compiler/app-graph/classify.ts +10 -10
  102. package/src/forge/compiler/app-graph/dup-symbol.ts +29 -29
  103. package/src/forge/compiler/app-graph/extract.ts +231 -231
  104. package/src/forge/compiler/app-graph/forge-apis.ts +25 -25
  105. package/src/forge/compiler/app-graph/index.ts +11 -11
  106. package/src/forge/compiler/app-graph/module-graph.ts +151 -151
  107. package/src/forge/compiler/app-graph/parser.ts +71 -71
  108. package/src/forge/compiler/app-graph/symbols.ts +48 -48
  109. package/src/forge/compiler/app-graph/types.ts +43 -43
  110. package/src/forge/compiler/app-graph/versions.ts +14 -14
  111. package/src/forge/compiler/cache/index.ts +17 -17
  112. package/src/forge/compiler/cache/key.ts +46 -46
  113. package/src/forge/compiler/cache/scheduler.ts +72 -72
  114. package/src/forge/compiler/cache/store.ts +78 -78
  115. package/src/forge/compiler/classifier/capabilities.ts +64 -64
  116. package/src/forge/compiler/classifier/classify.ts +76 -76
  117. package/src/forge/compiler/classifier/contexts.ts +188 -188
  118. package/src/forge/compiler/classifier/index.ts +18 -18
  119. package/src/forge/compiler/classifier/runtime-matrix.ts +45 -45
  120. package/src/forge/compiler/classifier/secrets.ts +31 -31
  121. package/src/forge/compiler/classifier/signals.ts +95 -95
  122. package/src/forge/compiler/client-sdk/build-manifest.ts +210 -210
  123. package/src/forge/compiler/data-graph/sql/serialize.ts +89 -89
  124. package/src/forge/compiler/data-graph/sql/types.ts +38 -38
  125. package/src/forge/compiler/diagnostics/index.ts +57 -57
  126. package/src/forge/compiler/emitter/artifact-kind.ts +14 -14
  127. package/src/forge/compiler/emitter/barrel.ts +47 -47
  128. package/src/forge/compiler/emitter/constants.ts +7 -7
  129. package/src/forge/compiler/emitter/emit.ts +223 -223
  130. package/src/forge/compiler/emitter/index.ts +24 -24
  131. package/src/forge/compiler/emitter/lock.ts +61 -61
  132. package/src/forge/compiler/external-manifest/registry.ts +205 -205
  133. package/src/forge/compiler/external-manifest/types.ts +91 -91
  134. package/src/forge/compiler/external-manifest/validate.ts +373 -373
  135. package/src/forge/compiler/frontend-graph/build.ts +623 -623
  136. package/src/forge/compiler/guards/artifacts.ts +96 -96
  137. package/src/forge/compiler/guards/check-import-guards.ts +106 -106
  138. package/src/forge/compiler/guards/index.ts +11 -11
  139. package/src/forge/compiler/guards/propagate-contexts.ts +57 -57
  140. package/src/forge/compiler/index.ts +17 -17
  141. package/src/forge/compiler/integration/index.ts +17 -17
  142. package/src/forge/compiler/integration/snapshot.ts +54 -54
  143. package/src/forge/compiler/integration/templates/convex.ts +70 -70
  144. package/src/forge/compiler/orchestrator/discover.ts +214 -214
  145. package/src/forge/compiler/orchestrator/guards.ts +5 -5
  146. package/src/forge/compiler/orchestrator/index.ts +27 -27
  147. package/src/forge/compiler/orchestrator/orphans.ts +51 -51
  148. package/src/forge/compiler/orchestrator/profile.ts +23 -23
  149. package/src/forge/compiler/orchestrator/serialize.ts +979 -979
  150. package/src/forge/compiler/orchestrator/verify.ts +35 -35
  151. package/src/forge/compiler/package-graph/capabilities-stub.ts +33 -33
  152. package/src/forge/compiler/package-graph/checksum.ts +107 -107
  153. package/src/forge/compiler/package-graph/exports-discovery.ts +91 -91
  154. package/src/forge/compiler/package-graph/extract-dts.ts +32 -32
  155. package/src/forge/compiler/package-graph/index.ts +24 -24
  156. package/src/forge/compiler/package-graph/jsdoc.ts +50 -50
  157. package/src/forge/compiler/package-graph/oracle.ts +326 -326
  158. package/src/forge/compiler/package-graph/read-file.ts +21 -21
  159. package/src/forge/compiler/package-graph/resolve.ts +131 -131
  160. package/src/forge/compiler/package-manager/adapter.ts +240 -240
  161. package/src/forge/compiler/package-manager/commands.ts +51 -51
  162. package/src/forge/compiler/package-manager/detect.ts +65 -65
  163. package/src/forge/compiler/package-manager/executor.ts +146 -146
  164. package/src/forge/compiler/package-manager/index.ts +22 -22
  165. package/src/forge/compiler/package-manager/parse-spec.ts +16 -16
  166. package/src/forge/compiler/primitives/compare.ts +26 -26
  167. package/src/forge/compiler/primitives/hash.ts +29 -29
  168. package/src/forge/compiler/primitives/header.ts +43 -43
  169. package/src/forge/compiler/primitives/index.ts +45 -45
  170. package/src/forge/compiler/primitives/paths.ts +24 -24
  171. package/src/forge/compiler/primitives/serialize.ts +66 -66
  172. package/src/forge/compiler/primitives/sort.ts +87 -87
  173. package/src/forge/compiler/recipes/helpers.ts +37 -37
  174. package/src/forge/compiler/sandbox/artifact-sanitize.ts +26 -26
  175. package/src/forge/compiler/sandbox/backends/child.ts +123 -123
  176. package/src/forge/compiler/sandbox/backends/docker.ts +173 -173
  177. package/src/forge/compiler/sandbox/index.ts +51 -51
  178. package/src/forge/compiler/sandbox/inspect.ts +143 -143
  179. package/src/forge/compiler/sandbox/inspector-entry.ts +115 -115
  180. package/src/forge/compiler/sandbox/limits.ts +31 -31
  181. package/src/forge/compiler/sandbox/scrub-env.ts +60 -60
  182. package/src/forge/compiler/sandbox/secret-scan.ts +54 -54
  183. package/src/forge/compiler/sandbox/serialize.ts +106 -106
  184. package/src/forge/compiler/sandbox/types.ts +7 -7
  185. package/src/forge/compiler/test-graph/build.ts +285 -285
  186. package/src/forge/compiler/types/app-graph.ts +87 -87
  187. package/src/forge/compiler/types/capability.ts +29 -29
  188. package/src/forge/compiler/types/classification.ts +9 -9
  189. package/src/forge/compiler/types/diagnostic.ts +2 -2
  190. package/src/forge/compiler/types/frontend-graph.ts +81 -81
  191. package/src/forge/compiler/types/import-guards.ts +19 -19
  192. package/src/forge/compiler/types/index.ts +98 -98
  193. package/src/forge/compiler/types/json.ts +3 -3
  194. package/src/forge/compiler/types/lock.ts +37 -37
  195. package/src/forge/compiler/types/runtime-matrix.ts +16 -16
  196. package/src/forge/compiler/types/runtime.ts +30 -30
  197. package/src/forge/compiler/types/sandbox.ts +24 -24
  198. package/src/forge/delta/broker-runner.mjs +5 -0
  199. package/src/forge/delta/broker.ts +429 -0
  200. package/src/forge/delta/classifier.ts +52 -52
  201. package/src/forge/delta/explain.ts +238 -238
  202. package/src/forge/delta/git-observer.ts +24 -0
  203. package/src/forge/delta/ids.ts +40 -40
  204. package/src/forge/delta/index.ts +25 -25
  205. package/src/forge/delta/process-identity.ts +31 -0
  206. package/src/forge/delta/queue-status.ts +190 -0
  207. package/src/forge/delta/redaction.ts +50 -50
  208. package/src/forge/delta/schema.ts +135 -135
  209. package/src/forge/delta/session.ts +142 -142
  210. package/src/forge/delta/status.ts +82 -145
  211. package/src/forge/delta/store.ts +77 -32
  212. package/src/forge/delta/timeline.ts +178 -178
  213. package/src/forge/dev/types.ts +63 -63
  214. package/src/forge/dev/watch.ts +119 -119
  215. package/src/forge/intent/index.ts +509 -509
  216. package/src/forge/make/types.ts +153 -153
  217. package/src/forge/refactor/index.ts +1937 -1937
  218. package/src/forge/refactor/runtime-rename.ts +598 -598
  219. package/src/forge/repair/rules/index.ts +476 -476
  220. package/src/forge/review/types.ts +211 -211
  221. package/src/forge/runtime/db/generated-client.ts +305 -305
  222. package/src/forge/runtime/db/pglite-adapter.ts +33 -11
  223. package/src/forge/runtime/runner/run-entry.ts +236 -236
  224. package/src/forge/version.ts +1 -1
  225. package/templates/agent-workroom/AGENTS.md +29 -29
  226. package/templates/agent-workroom/README.md +34 -34
  227. package/templates/agent-workroom/forge.config.ts +3 -3
  228. package/templates/agent-workroom/package.json +34 -34
  229. package/templates/agent-workroom/pnpm-workspace.yaml +2 -2
  230. package/templates/agent-workroom/src/actions/indexAgentSignal.ts +10 -10
  231. package/templates/agent-workroom/src/commands/openWorkroom.ts +61 -61
  232. package/templates/agent-workroom/src/commands/recordAgentSignal.ts +119 -119
  233. package/templates/agent-workroom/src/commands/recordCheckRun.ts +52 -52
  234. package/templates/agent-workroom/src/forge/schema.ts +54 -54
  235. package/templates/agent-workroom/src/policies.ts +6 -6
  236. package/templates/agent-workroom/src/queries/listWorkrooms.ts +11 -11
  237. package/templates/agent-workroom/src/queries/liveWorkroom.ts +63 -63
  238. package/templates/agent-workroom/tsconfig.json +16 -16
  239. package/templates/agent-workroom/web/index.html +13 -13
  240. package/templates/agent-workroom/web/package.json +21 -21
  241. package/templates/agent-workroom/web/src/App.tsx +345 -345
  242. package/templates/agent-workroom/web/src/main.tsx +13 -13
  243. package/templates/agent-workroom/web/src/styles.css +545 -545
  244. package/templates/agent-workroom/web/tsconfig.json +27 -27
  245. package/templates/b2b-support-web/package.json +37 -37
  246. package/templates/b2b-support-web/pnpm-workspace.yaml +2 -2
  247. package/templates/b2b-support-web/web/package.json +21 -21
  248. package/templates/minimal-web/package.json +34 -34
  249. package/templates/minimal-web/pnpm-workspace.yaml +2 -2
  250. package/templates/minimal-web/web/index.html +13 -13
  251. package/templates/minimal-web/web/src/styles.css +190 -190
  252. package/templates/nuxt-web/.vscode/settings.json +14 -14
  253. package/templates/nuxt-web/.yarnrc.yml +1 -1
  254. package/templates/nuxt-web/README.md +30 -30
  255. package/templates/nuxt-web/forge.config.ts +3 -3
  256. package/templates/nuxt-web/package.json +34 -34
  257. package/templates/nuxt-web/pnpm-workspace.yaml +2 -2
  258. package/templates/nuxt-web/src/actions/logNoteCreated.ts +11 -11
  259. package/templates/nuxt-web/src/commands/createNote.ts +26 -26
  260. package/templates/nuxt-web/src/forge/schema.ts +12 -12
  261. package/templates/nuxt-web/src/policies.ts +6 -6
  262. package/templates/nuxt-web/src/queries/listNotes.ts +8 -8
  263. package/templates/nuxt-web/src/queries/liveNotes.ts +8 -8
  264. package/templates/nuxt-web/tsconfig.json +17 -17
  265. package/templates/nuxt-web/web/app.vue +67 -67
  266. package/templates/nuxt-web/web/components/LiveNotes.vue +89 -89
  267. package/templates/nuxt-web/web/components/NoteComposer.vue +100 -100
  268. package/templates/nuxt-web/web/composables/forge.ts +13 -13
  269. package/templates/nuxt-web/web/composables/useNotes.ts +24 -24
  270. package/templates/nuxt-web/web/nuxt.config.ts +11 -11
  271. package/templates/nuxt-web/web/package.json +19 -19
  272. package/templates/nuxt-web/web/plugins/forge.client.ts +10 -10
  273. package/templates/nuxt-web/web/plugins/forge.server.ts +10 -10
  274. package/templates/nuxt-web/web/server/api/forge-health.get.ts +7 -7
  275. package/templates/nuxt-web/web/tsconfig.json +6 -6
  276. package/templates/vendor-access/.vscode/settings.json +14 -14
  277. package/templates/vendor-access/README.md +30 -30
  278. package/templates/vendor-access/package.json +35 -35
  279. package/templates/vendor-access/pnpm-workspace.yaml +2 -2
  280. package/templates/vendor-access/tsconfig.json +17 -17
  281. package/templates/vendor-access/web/index.html +13 -13
  282. package/templates/vendor-access/web/package.json +21 -21
  283. package/templates/vendor-access/web/src/styles.css +682 -682
  284. package/templates/vendor-access/web/tsconfig.json +18 -18
@@ -1,131 +1,205 @@
1
- import { readFileSync, realpathSync, statSync } from "node:fs";
2
- import { isAbsolute, relative, resolve } from "node:path";
3
- import { LocalTaskService } from "../agent-fabric/local-task-service.ts";
4
- import { LOCAL_CODING_MODEL, LOCAL_CODING_TARGET } from "../agent-fabric/local-task-contract.ts";
5
- import { requestLocalMemory, requestLocalTask, serveLocalTasks, type LocalMemoryAction, type LocalTaskAction } from "../agent-fabric/local-task-server.ts";
6
- import { runAdaptiveCommand, type AdaptiveCliOptions } from "./adaptive.ts";
7
-
8
- export interface FabricCliOptions {
9
- subcommand: "capabilities" | "propose" | "status" | "evidence" | "review" | "run" | "cancel" | "reconcile" | "verify" | "recover-verification" | "review-result" | "serve" | "memory-add" | "memory-list" | "memory-delete" | AdaptiveCliOptions["subcommand"];
10
- workspaceRoot: string;
11
- json: boolean;
12
- file?: string;
13
- taskId?: string;
14
- channel?: "canary" | "stable";
15
- }
16
-
17
- export async function runFabricCommand(options: FabricCliOptions): Promise<number> {
18
- if (options.subcommand.startsWith("adaptive-")) return runAdaptiveCommand(options as AdaptiveCliOptions);
19
- if (options.subcommand === "capabilities") {
20
- const result = {
21
- ok: true, schemaVersion: 1, runtime: "local-pilot",
22
- proposal: true, ownerReview: true, durableStatus: true,
23
- codingWorker: true, ownerServer: true,
24
- codingWorkerModel: { targetId: LOCAL_CODING_TARGET, modelId: LOCAL_CODING_MODEL,
25
- proposalField: "requestedModelId" },
26
- sandboxVerification: { supported: true, localReadiness: "not_checked" },
27
- cancellation: { supported: true, concurrentRequestsRequireOwnerServer: true,
28
- activeModelStopIsBestEffort: true },
29
- consequentialEffects: false,
30
- privateMemory: "owner_cli_only",
31
- adaptiveHarness: { twoProcessDataOnly: true, ownerReview: true, durableReadback: true,
32
- selectedDataProfile: "optional_canary_or_stable" },
33
- mcpTaskMutation: "proposal_only", mcpEvidence: true,
34
- nativeCodexHookProofRequired: true,
35
- };
36
- process.stdout.write(options.json ? `${JSON.stringify(result, null, 2)}\n` :
37
- "Agent Fabric local pilot: proposal, owner review, bounded Ollama coding, and durable status are available.\n");
38
- return 0;
39
- }
40
-
41
- let service: LocalTaskService | undefined;
42
- try {
43
- const repositoryRoot = realpathSync(options.workspaceRoot);
44
- if (options.subcommand === "serve") {
45
- const owner = await serveLocalTasks(repositoryRoot);
46
- process.stdout.write(options.json ? `${JSON.stringify({ ok: true, repositoryRoot: owner.repositoryRoot, port: owner.port, pid: process.pid })}\n` :
47
- `Agent Fabric owner running for ${owner.repositoryRoot} on local port ${owner.port}. Press Ctrl+C to stop.\n`);
48
- try {
49
- await new Promise<void>((resolve) => {
50
- process.once("SIGINT", resolve);
51
- process.once("SIGTERM", resolve);
52
- });
53
- } finally {
54
- await owner.close();
55
- }
56
- return 0;
57
- }
58
- let proposal: unknown;
59
- if (options.subcommand === "propose" || options.subcommand === "memory-add" || options.subcommand === "memory-list") {
60
- if (!options.file) throw new Error("A request file is required");
61
- const file = realpathSync(resolve(repositoryRoot, options.file));
62
- const relation = relative(repositoryRoot, file);
63
- if (options.subcommand === "propose" && (!relation || relation.startsWith("..") || isAbsolute(relation))) {
64
- throw new Error("Proposal file must be inside the current repository");
65
- }
66
- if (statSync(file).size > (options.subcommand === "propose" ? 32 * 1024 : 4 * 1024)) throw new Error("Request file exceeds byte limit");
67
- proposal = JSON.parse(readFileSync(file, "utf8")) as unknown;
68
- }
69
- if (options.subcommand.startsWith("memory-")) {
70
- const action = options.subcommand as LocalMemoryAction;
71
- const body = action === "memory-delete" ? { id: options.taskId ?? "" } : proposal as Record<string, unknown>;
72
- const remote = await requestLocalMemory(repositoryRoot, action, body);
73
- if (remote === null) {
74
- service = await LocalTaskService.open(repositoryRoot);
75
- }
76
- const memory = remote ?? (action === "memory-add" ? service!.rememberMemory(body)
77
- : action === "memory-list" ? service!.listMemory(body)
78
- : { deleted: service!.forgetMemory(body.id) });
79
- process.stdout.write(options.json ? `${JSON.stringify({ ok: true, memory }, null, 2)}\n` :
80
- `${JSON.stringify(memory, null, 2)}\n`);
81
- return 0;
82
- }
83
- const action = options.subcommand as LocalTaskAction;
84
- const body = action === "propose" ? { proposal } : { taskId: options.taskId ?? "" };
85
- const remote = await requestLocalTask(repositoryRoot, action, body);
86
- if (remote) {
87
- process.stdout.write(options.json ? `${JSON.stringify({ ok: true, status: remote }, null, 2)}\n` :
88
- `${remote.taskId}: ${remote.state}; execution ${remote.canStart ? "available" : "not available"}\n`);
89
- return 0;
90
- }
91
- try { service = await LocalTaskService.open(repositoryRoot); }
92
- catch (error) {
93
- if (options.subcommand === "cancel") {
94
- throw new Error("Cannot reach the active local task owner. Start forge fabric serve before run to cancel an in-flight model call", { cause: error });
95
- }
96
- throw error;
97
- }
98
- if (options.subcommand === "cancel" &&
99
- (await service.status(options.taskId ?? "")).state === "model_uncertain") {
100
- throw new Error("An in-flight model call can only be cancelled through its running forge fabric serve owner");
101
- }
102
- const status = options.subcommand === "propose"
103
- ? await service.propose(proposal)
104
- : options.subcommand === "evidence"
105
- ? await service.evidence(options.taskId ?? "")
106
- : options.subcommand === "review"
107
- ? await service.review(options.taskId ?? "")
108
- : options.subcommand === "run"
109
- ? await service.run(options.taskId ?? "")
110
- : options.subcommand === "cancel"
111
- ? await service.cancel(options.taskId ?? "")
112
- : options.subcommand === "reconcile"
113
- ? await service.reconcile(options.taskId ?? "")
114
- : options.subcommand === "verify"
115
- ? await service.verify(options.taskId ?? "")
116
- : options.subcommand === "recover-verification"
117
- ? await service.recoverVerification(options.taskId ?? "")
118
- : options.subcommand === "review-result"
119
- ? await service.reviewResult(options.taskId ?? "")
120
- : await service.status(options.taskId ?? "");
121
- process.stdout.write(options.json ? `${JSON.stringify({ ok: true, status }, null, 2)}\n` :
122
- `${status.taskId}: ${status.state}; execution ${status.canStart ? "available" : "not available"}\n`);
123
- return 0;
124
- } catch (error) {
125
- const message = error instanceof Error ? error.message : String(error);
126
- process.stdout.write(options.json ? `${JSON.stringify({ ok: false, error: message }, null, 2)}\n` : `error: ${message}\n`);
127
- return 1;
128
- } finally {
129
- await service?.close();
130
- }
131
- }
1
+ import { readFileSync, realpathSync, statSync } from "node:fs";
2
+ import { isAbsolute, relative, resolve } from "node:path";
3
+ import { LocalTaskService } from "../agent-fabric/local-task-service.ts";
4
+ import { LocalChangeReviewService } from "../agent-fabric/local-change-review-service.ts";
5
+ import { LOCAL_CODING_MODEL, LOCAL_CODING_TARGET } from "../agent-fabric/local-task-contract.ts";
6
+ import { isManagedRunAction, requestManagedRun, type ManagedRunAction, isAttachedTaskAction, isAttachedTaskRead, requestAttachedTask, type AttachedTaskAction, requestLocalMemory, requestLocalTask, serveLocalTasks, type LocalMemoryAction, type LocalTaskAction } from "../agent-fabric/local-task-server.ts";
7
+ import { runAdaptiveCommand, type AdaptiveCliOptions } from "./adaptive.ts";
8
+
9
+ export interface FabricCliOptions {
10
+ subcommand: ManagedRunAction | AttachedTaskAction | "capabilities" | "propose" | "status" | "evidence" | "review" | "run" | "cancel" | "reconcile" | "verify" | "recover-verification" | "review-result" | "serve" | "memory-add" | "memory-list" | "memory-delete" | "change-propose" | "change-status" | "change-review" | "change-evidence" | AdaptiveCliOptions["subcommand"];
11
+ workspaceRoot: string;
12
+ json: boolean;
13
+ file?: string;
14
+ taskId?: string;
15
+ runId?: string;
16
+ channel?: "canary" | "stable";
17
+ }
18
+
19
+ export async function runFabricCommand(options: FabricCliOptions): Promise<number> {
20
+ if (options.subcommand.startsWith("adaptive-")) return runAdaptiveCommand(options as AdaptiveCliOptions);
21
+ if (options.subcommand === "capabilities") {
22
+ const result = {
23
+ ok: true, schemaVersion: 1, runtime: "local-pilot",
24
+ proposal: true, ownerReview: true, durableStatus: true,
25
+ codingWorker: true, ownerServer: true,
26
+ codingWorkerModel: { targetId: LOCAL_CODING_TARGET, modelId: LOCAL_CODING_MODEL,
27
+ proposalField: "requestedModelId" },
28
+ sandboxVerification: { supported: true, localReadiness: "not_checked" },
29
+ cancellation: { supported: true, concurrentRequestsRequireOwnerServer: true,
30
+ activeModelStopIsBestEffort: true },
31
+ accompaniedTasks: { supported: true, runningOwnerRequired: true, nativeSessionAssociation: true,
32
+ evidenceProvenance: "agent_reported", automaticDispatch: false, managedWorkers: false, workflowExecution: "caller_driven" },
33
+ managedExecution: { supported: true, runningOwnerRequired: true, scheduler: "owner_managed",
34
+ executors: ["codex", "command"], startDispatchesWork: true, boundedEventWaitMs: 30_000,
35
+ codexMayConsumeCredits: true, controls: ["steer", "pause", "resume", "cancel", "reconcile"],
36
+ environment: { automaticPreparation: true, isolatedDependencies: true, cacheReuse: "verified_copy", ignoreScriptsDefault: true } },
37
+ consequentialEffects: true,
38
+ effectsByMode: { legacy: "owner_reviewed_local_pilot", accompanied: "caller_driven_records",
39
+ managed: "process_execution_and_optional_local_publication" },
40
+ privateMemory: "owner_cli_only",
41
+ adaptiveHarness: { twoProcessDataOnly: true, ownerReview: true, durableReadback: true,
42
+ selectedDataProfile: "optional_canary_or_stable" },
43
+ adversarialChangeReview: { propose: true, status: true, evidence: true,
44
+ reviewer: "codex_cli_owner_command_only", automaticPaidReview: false },
45
+ mcpTaskMutation: "mode_specific", mcpDispatch: { legacy: "proposal_only",
46
+ accompanied: "caller_driven_records", managed: "run_start_dispatches_work" }, mcpEvidence: true,
47
+ nativeCodexHookProofRequired: true,
48
+ };
49
+ process.stdout.write(options.json ? `${JSON.stringify(result, null, 2)}\n` :
50
+ "Agent Fabric local pilot: proposal, owner review, bounded Ollama coding, and durable status are available.\n");
51
+ return 0;
52
+ }
53
+
54
+ let service: LocalTaskService | undefined;
55
+ let changeService: LocalChangeReviewService | undefined;
56
+ try {
57
+ const repositoryRoot = realpathSync(options.workspaceRoot);
58
+ if (isManagedRunAction(options.subcommand)) {
59
+ let body: Record<string, unknown>;
60
+ if (options.subcommand === "run-status") body = { runId: options.runId ?? "" };
61
+ else {
62
+ if (!options.file) throw new Error("A request file is required");
63
+ const file = realpathSync(resolve(repositoryRoot, options.file));
64
+ const relation = relative(repositoryRoot, file);
65
+ if (!relation || relation.startsWith("..") || isAbsolute(relation)) throw new Error("Request file must be inside the current repository");
66
+ if (statSync(file).size > 40 * 1024) throw new Error("Request file exceeds 40 KiB");
67
+ const value: unknown = JSON.parse(readFileSync(file, "utf8"));
68
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Request file must contain an object");
69
+ body = value as Record<string, unknown>;
70
+ }
71
+ const status = await requestManagedRun(repositoryRoot, options.subcommand, body);
72
+ process.stdout.write(`${JSON.stringify({ ok: true, status }, null, 2)}\n`);
73
+ return 0;
74
+ }
75
+ if (isAttachedTaskAction(options.subcommand)) {
76
+ let body: Record<string, unknown>;
77
+ if (isAttachedTaskRead(options.subcommand)) body = { taskId: options.taskId ?? "" };
78
+ else {
79
+ if (!options.file) throw new Error("A request file is required");
80
+ const file = realpathSync(resolve(repositoryRoot, options.file));
81
+ const relation = relative(repositoryRoot, file);
82
+ if (!relation || relation.startsWith("..") || isAbsolute(relation)) throw new Error("Request file must be inside the current repository");
83
+ if (statSync(file).size > 40 * 1024) throw new Error("Request file exceeds 40 KiB");
84
+ const value: unknown = JSON.parse(readFileSync(file, "utf8"));
85
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Request file must contain an object");
86
+ body = value as Record<string, unknown>;
87
+ }
88
+ const status = await requestAttachedTask(repositoryRoot, options.subcommand, body);
89
+ process.stdout.write(`${JSON.stringify({ ok: true, status }, null, 2)}\n`);
90
+ return 0;
91
+ }
92
+ if (options.subcommand === "serve") {
93
+ const owner = await serveLocalTasks(repositoryRoot);
94
+ process.stdout.write(options.json ? `${JSON.stringify({ ok: true, repositoryRoot: owner.repositoryRoot, port: owner.port, pid: process.pid })}\n` :
95
+ `Agent Fabric owner running for ${owner.repositoryRoot} on local port ${owner.port}. Press Ctrl+C to stop.\n`);
96
+ try {
97
+ await new Promise<void>((resolve) => {
98
+ process.once("SIGINT", resolve);
99
+ process.once("SIGTERM", resolve);
100
+ });
101
+ } finally {
102
+ await owner.close();
103
+ }
104
+ return 0;
105
+ }
106
+ if (options.subcommand === "change-propose" || options.subcommand === "change-status" ||
107
+ options.subcommand === "change-review" || options.subcommand === "change-evidence") {
108
+ let request: unknown;
109
+ if (options.subcommand === "change-propose") {
110
+ if (!options.file) throw new Error("A change request file is required");
111
+ const file = realpathSync(resolve(repositoryRoot, options.file));
112
+ const relation = relative(repositoryRoot, file);
113
+ if (!relation || relation.startsWith("..") || isAbsolute(relation)) {
114
+ throw new Error("Change request file must be inside the current repository");
115
+ }
116
+ if (statSync(file).size > 32 * 1024) throw new Error("Change request file exceeds byte limit");
117
+ request = JSON.parse(readFileSync(file, "utf8")) as unknown;
118
+ }
119
+ changeService = await LocalChangeReviewService.open(repositoryRoot);
120
+ const changeId = options.taskId ?? "";
121
+ const status = options.subcommand === "change-propose"
122
+ ? await changeService.propose(request as Parameters<LocalChangeReviewService["propose"]>[0])
123
+ : options.subcommand === "change-status"
124
+ ? await changeService.status(changeId)
125
+ : options.subcommand === "change-evidence"
126
+ ? await changeService.evidence(changeId)
127
+ : await changeService.review(changeId);
128
+ process.stdout.write(`${JSON.stringify({ ok: true, status }, null, 2)}\n`);
129
+ return 0;
130
+ }
131
+ let proposal: unknown;
132
+ if (options.subcommand === "propose" || options.subcommand === "memory-add" || options.subcommand === "memory-list") {
133
+ if (!options.file) throw new Error("A request file is required");
134
+ const file = realpathSync(resolve(repositoryRoot, options.file));
135
+ const relation = relative(repositoryRoot, file);
136
+ if (options.subcommand === "propose" && (!relation || relation.startsWith("..") || isAbsolute(relation))) {
137
+ throw new Error("Proposal file must be inside the current repository");
138
+ }
139
+ if (statSync(file).size > (options.subcommand === "propose" ? 32 * 1024 : 4 * 1024)) throw new Error("Request file exceeds byte limit");
140
+ proposal = JSON.parse(readFileSync(file, "utf8")) as unknown;
141
+ }
142
+ if (options.subcommand.startsWith("memory-")) {
143
+ const action = options.subcommand as LocalMemoryAction;
144
+ const body = action === "memory-delete" ? { id: options.taskId ?? "" } : proposal as Record<string, unknown>;
145
+ const remote = await requestLocalMemory(repositoryRoot, action, body);
146
+ if (remote === null) {
147
+ service = await LocalTaskService.open(repositoryRoot);
148
+ }
149
+ const memory = remote ?? (action === "memory-add" ? service!.rememberMemory(body)
150
+ : action === "memory-list" ? service!.listMemory(body)
151
+ : { deleted: service!.forgetMemory(body.id) });
152
+ process.stdout.write(options.json ? `${JSON.stringify({ ok: true, memory }, null, 2)}\n` :
153
+ `${JSON.stringify(memory, null, 2)}\n`);
154
+ return 0;
155
+ }
156
+ const action = options.subcommand as LocalTaskAction;
157
+ const body = action === "propose" ? { proposal } : { taskId: options.taskId ?? "" };
158
+ const remote = await requestLocalTask(repositoryRoot, action, body);
159
+ if (remote) {
160
+ process.stdout.write(options.json ? `${JSON.stringify({ ok: true, status: remote }, null, 2)}\n` :
161
+ `${remote.taskId}: ${remote.state}; execution ${remote.canStart ? "available" : "not available"}\n`);
162
+ return 0;
163
+ }
164
+ try { service = await LocalTaskService.open(repositoryRoot); }
165
+ catch (error) {
166
+ if (options.subcommand === "cancel") {
167
+ throw new Error("Cannot reach the active local task owner. Start forge fabric serve before run to cancel an in-flight model call", { cause: error });
168
+ }
169
+ throw error;
170
+ }
171
+ if (options.subcommand === "cancel" &&
172
+ (await service.status(options.taskId ?? "")).state === "model_uncertain") {
173
+ throw new Error("An in-flight model call can only be cancelled through its running forge fabric serve owner");
174
+ }
175
+ const status = options.subcommand === "propose"
176
+ ? await service.propose(proposal)
177
+ : options.subcommand === "evidence"
178
+ ? await service.evidence(options.taskId ?? "")
179
+ : options.subcommand === "review"
180
+ ? await service.review(options.taskId ?? "")
181
+ : options.subcommand === "run"
182
+ ? await service.run(options.taskId ?? "")
183
+ : options.subcommand === "cancel"
184
+ ? await service.cancel(options.taskId ?? "")
185
+ : options.subcommand === "reconcile"
186
+ ? await service.reconcile(options.taskId ?? "")
187
+ : options.subcommand === "verify"
188
+ ? await service.verify(options.taskId ?? "")
189
+ : options.subcommand === "recover-verification"
190
+ ? await service.recoverVerification(options.taskId ?? "")
191
+ : options.subcommand === "review-result"
192
+ ? await service.reviewResult(options.taskId ?? "")
193
+ : await service.status(options.taskId ?? "");
194
+ process.stdout.write(options.json ? `${JSON.stringify({ ok: true, status }, null, 2)}\n` :
195
+ `${status.taskId}: ${status.state}; execution ${status.canStart ? "available" : "not available"}\n`);
196
+ return 0;
197
+ } catch (error) {
198
+ const message = error instanceof Error ? error.message : String(error);
199
+ process.stdout.write(options.json ? `${JSON.stringify({ ok: false, error: message }, null, 2)}\n` : `error: ${message}\n`);
200
+ return 1;
201
+ } finally {
202
+ await service?.close();
203
+ await changeService?.close();
204
+ }
205
+ }
@@ -1,26 +1,26 @@
1
- export { CLI_VERSION } from "./version.ts";
2
- export { parseCli, hasUnknownOption, type ParsedCli, type ForgeCommand } from "./parse.ts";
3
- export { runNewCommand, type NewCommandOptions, type NewCommandResult } from "./new.ts";
4
- export { runSelfHostCommand, type SelfHostCommandOptions } from "./self-host.ts";
5
- export { runDocsCheckCommand, type DocsCheckResult } from "./docs.ts";
6
- export { runBuildCommand, type BuildCommandOptions } from "./build.ts";
7
- export { runServeCommand, type ServeCommandOptions } from "./serve.ts";
8
- export { runWorkerCommand, type WorkerCommandOptions } from "./worker.ts";
9
- export {
10
- runAgentContractPrint,
11
- type AgentContractCommandOptions,
12
- type AgentContractSubcommand,
13
- } from "./agent-contract.ts";
14
- export {
15
- runDoctorCommand,
16
- type DoctorCheck,
17
- type DoctorResult,
18
- } from "./doctor.ts";
19
- export {
20
- executeCommand,
21
- runGenerateCommand,
22
- runAddCommand,
23
- runCheckCommand,
24
- runInspectCommand,
25
- } from "./commands.ts";
26
- export { main } from "./main.ts";
1
+ export { CLI_VERSION } from "./version.ts";
2
+ export { parseCli, hasUnknownOption, type ParsedCli, type ForgeCommand } from "./parse.ts";
3
+ export { runNewCommand, type NewCommandOptions, type NewCommandResult } from "./new.ts";
4
+ export { runSelfHostCommand, type SelfHostCommandOptions } from "./self-host.ts";
5
+ export { runDocsCheckCommand, type DocsCheckResult } from "./docs.ts";
6
+ export { runBuildCommand, type BuildCommandOptions } from "./build.ts";
7
+ export { runServeCommand, type ServeCommandOptions } from "./serve.ts";
8
+ export { runWorkerCommand, type WorkerCommandOptions } from "./worker.ts";
9
+ export {
10
+ runAgentContractPrint,
11
+ type AgentContractCommandOptions,
12
+ type AgentContractSubcommand,
13
+ } from "./agent-contract.ts";
14
+ export {
15
+ runDoctorCommand,
16
+ type DoctorCheck,
17
+ type DoctorResult,
18
+ } from "./doctor.ts";
19
+ export {
20
+ executeCommand,
21
+ runGenerateCommand,
22
+ runAddCommand,
23
+ runCheckCommand,
24
+ runInspectCommand,
25
+ } from "./commands.ts";
26
+ export { main } from "./main.ts";