forgeos 0.1.0-alpha.67 → 0.1.0-alpha.68

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.
@@ -1,23 +1,55 @@
1
- import { readFileSync, realpathSync, statSync } from "node:fs";
1
+ import { readFileSync, realpathSync, statSync } from "node:fs";
2
+ import { execFile } from "node:child_process";
3
+ import { fileURLToPath } from "node:url";
4
+ import { promisify } from "node:util";
2
5
  import { isAbsolute, relative, resolve } from "node:path";
3
6
  import { LocalTaskService } from "../agent-fabric/local-task-service.ts";
4
7
  import { LocalChangeReviewService } from "../agent-fabric/local-change-review-service.ts";
5
8
  import { LOCAL_CODING_MODEL, LOCAL_CODING_TARGET } from "../agent-fabric/local-task-contract.ts";
6
9
  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";
10
+ import { runAdaptiveCommand, type AdaptiveCliOptions } from "./adaptive.ts";
11
+ import { listFabricProjects, registerFabricProject, resolveFabricRoot } from "../agent-fabric/project-registry.ts";
12
+ import { ensureFabricOwner, fabricProjectDoctor } from "../agent-fabric/project-runtime.ts";
8
13
 
9
14
  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"];
15
+ subcommand: ManagedRunAction | AttachedTaskAction | "install-skill" | "doctor" | "ensure-owner" | "project-register" | "project-list" | "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
16
  workspaceRoot: string;
12
17
  json: boolean;
13
18
  file?: string;
14
19
  taskId?: string;
15
- runId?: string;
20
+ runId?: string;
21
+ projectId?: string;
22
+ dryRun?: boolean;
16
23
  channel?: "canary" | "stable";
17
24
  }
18
25
 
19
- export async function runFabricCommand(options: FabricCliOptions): Promise<number> {
20
- if (options.subcommand.startsWith("adaptive-")) return runAdaptiveCommand(options as AdaptiveCliOptions);
26
+ export async function runFabricCommand(options: FabricCliOptions): Promise<number> {
27
+ if (options.subcommand.startsWith("adaptive-")) return runAdaptiveCommand(options as AdaptiveCliOptions);
28
+ if (options.subcommand === "install-skill") {
29
+ try {
30
+ const installer = fileURLToPath(new URL("../../../scripts/install-agent-fabric-skill.mjs", import.meta.url));
31
+ const { stdout } = await promisify(execFile)(process.execPath, [installer, ...(options.dryRun ? ["--dry-run"] : [])], { windowsHide: true, timeout: 30_000 });
32
+ process.stdout.write(stdout);
33
+ return 0;
34
+ } catch (error) {
35
+ process.stdout.write(`${JSON.stringify({ ok: false, error: error instanceof Error ? error.message : "Skill installation failed" })}\n`);
36
+ return 1;
37
+ }
38
+ }
39
+ if (["doctor", "ensure-owner", "project-register", "project-list"].includes(options.subcommand)) {
40
+ try {
41
+ const status = options.subcommand === "project-list" ? await listFabricProjects()
42
+ : options.subcommand === "project-register" ? await registerFabricProject(options.workspaceRoot, { id: options.projectId })
43
+ : options.subcommand === "doctor" ? await fabricProjectDoctor(options.workspaceRoot)
44
+ : await ensureFabricOwner(options.workspaceRoot);
45
+ const ok = !(options.subcommand === "doctor" && "ok" in status && !status.ok);
46
+ process.stdout.write(`${JSON.stringify({ ok, status }, null, 2)}\n`);
47
+ return ok ? 0 : 1;
48
+ } catch (error) {
49
+ process.stdout.write(`${JSON.stringify({ ok: false, error: error instanceof Error ? error.message : "Agent Fabric project operation failed" })}\n`);
50
+ return 1;
51
+ }
52
+ }
21
53
  if (options.subcommand === "capabilities") {
22
54
  const result = {
23
55
  ok: true, schemaVersion: 1, runtime: "local-pilot",
@@ -30,10 +62,11 @@ export async function runFabricCommand(options: FabricCliOptions): Promise<numbe
30
62
  activeModelStopIsBestEffort: true },
31
63
  accompaniedTasks: { supported: true, runningOwnerRequired: true, nativeSessionAssociation: true,
32
64
  evidenceProvenance: "agent_reported", automaticDispatch: false, managedWorkers: false, workflowExecution: "caller_driven" },
33
- managedExecution: { supported: true, runningOwnerRequired: true, scheduler: "owner_managed",
65
+ managedExecution: { supported: true, runningOwnerRequired: true, scheduler: "owner_managed",
34
66
  executors: ["codex", "command"], startDispatchesWork: true, boundedEventWaitMs: 30_000,
35
67
  codexMayConsumeCredits: true, controls: ["steer", "pause", "resume", "cancel", "reconcile"],
36
68
  environment: { automaticPreparation: true, isolatedDependencies: true, cacheReuse: "verified_copy", ignoreScriptsDefault: true } },
69
+ portableProjects: { supported: true, rootResolution: "git_toplevel", ownerPerRepository: true, optionalProfile: ".forge/fabric.json", mcpProjectRouting: "registered_project_id" },
37
70
  consequentialEffects: true,
38
71
  effectsByMode: { legacy: "owner_reviewed_local_pilot", accompanied: "caller_driven_records",
39
72
  managed: "process_execution_and_optional_local_publication" },
@@ -54,7 +87,8 @@ export async function runFabricCommand(options: FabricCliOptions): Promise<numbe
54
87
  let service: LocalTaskService | undefined;
55
88
  let changeService: LocalChangeReviewService | undefined;
56
89
  try {
57
- const repositoryRoot = realpathSync(options.workspaceRoot);
90
+ const repositoryRoot = isManagedRunAction(options.subcommand) || isAttachedTaskAction(options.subcommand) || options.subcommand === "serve"
91
+ ? await resolveFabricRoot(options.workspaceRoot) : realpathSync(options.workspaceRoot);
58
92
  if (isManagedRunAction(options.subcommand)) {
59
93
  let body: Record<string, unknown>;
60
94
  if (options.subcommand === "run-status") body = { runId: options.runId ?? "" };