@interf/compiler 0.13.0 → 0.16.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.
- package/README.md +40 -0
- package/agent-skills/interf-actions/SKILL.md +51 -5
- package/agent-skills/interf-actions/references/cli.md +82 -82
- package/dist/cli/commands/agents.d.ts +2 -0
- package/dist/cli/commands/agents.js +213 -0
- package/dist/cli/commands/compile.js +10 -1
- package/dist/cli/commands/doctor.js +1 -1
- package/dist/cli/commands/login.js +1 -1
- package/dist/cli/commands/logout.js +1 -1
- package/dist/cli/commands/mcp.d.ts +42 -0
- package/dist/cli/commands/mcp.js +239 -0
- package/dist/cli/commands/method.js +1 -1
- package/dist/cli/commands/prep.js +23 -5
- package/dist/cli/commands/reset.js +1 -1
- package/dist/cli/commands/runs.js +1 -1
- package/dist/cli/commands/status.js +1 -1
- package/dist/cli/commands/verify.d.ts +8 -0
- package/dist/cli/commands/{test.js → verify.js} +24 -18
- package/dist/cli/commands/web.js +71 -18
- package/dist/cli/commands/wizard.js +373 -126
- package/dist/cli/index.d.ts +4 -2
- package/dist/cli/index.js +7 -3
- package/dist/compiler-ui/404.html +1 -1
- package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
- package/dist/compiler-ui/__next._full.txt +3 -3
- package/dist/compiler-ui/__next._head.txt +1 -1
- package/dist/compiler-ui/__next._index.txt +2 -2
- package/dist/compiler-ui/__next._tree.txt +2 -2
- package/dist/compiler-ui/_next/static/chunks/{17t-lulmyawg5.js → 0jipmpez3_ehh.js} +16 -16
- package/dist/compiler-ui/_next/static/chunks/{045gole2ojo3g.css → 13awzu4tooflw.css} +1 -1
- package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
- package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
- package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
- package/dist/compiler-ui/_not-found.html +1 -1
- package/dist/compiler-ui/_not-found.txt +2 -2
- package/dist/compiler-ui/index.html +1 -1
- package/dist/compiler-ui/index.txt +3 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/packages/contracts/index.d.ts +2 -1
- package/dist/packages/contracts/index.js +1 -0
- package/dist/packages/contracts/lib/schema.d.ts +102 -8
- package/dist/packages/contracts/lib/schema.js +102 -2
- package/dist/packages/{local-service → engine}/action-definitions.js +8 -1
- package/dist/packages/{local-service → engine}/action-planner.d.ts +1 -1
- package/dist/packages/{local-service → engine}/action-planner.js +1 -1
- package/dist/packages/{agents → engine/agents}/index.d.ts +3 -0
- package/dist/packages/{agents → engine/agents}/index.js +3 -0
- package/dist/packages/{agents → engine/agents}/lib/compiled-bootstrap.js +2 -2
- package/dist/packages/engine/agents/lib/detection.d.ts +13 -0
- package/dist/packages/{agents → engine/agents}/lib/detection.js +11 -0
- package/dist/packages/{agents → engine/agents}/lib/executors.d.ts +2 -2
- package/dist/packages/{agents → engine/agents}/lib/shells.d.ts +4 -4
- package/dist/packages/{agents → engine/agents}/lib/shells.js +8 -8
- package/dist/packages/{agents → engine/agents}/lib/user-config.js +2 -2
- package/dist/packages/engine/agents/registry.d.ts +91 -0
- package/dist/packages/engine/agents/registry.js +321 -0
- package/dist/packages/engine/agents/role-executors.d.ts +35 -0
- package/dist/packages/engine/agents/role-executors.js +88 -0
- package/dist/packages/engine/agents/role-router.d.ts +66 -0
- package/dist/packages/engine/agents/role-router.js +73 -0
- package/dist/packages/{local-service → engine}/client.d.ts +9 -9
- package/dist/packages/{local-service → engine}/client.js +11 -11
- package/dist/packages/{compiler → engine/compile}/artifact-counts.js +1 -1
- package/dist/packages/{compiler → engine/compile}/compiled-pipeline.d.ts +12 -1
- package/dist/packages/{compiler → engine/compile}/compiled-pipeline.js +16 -6
- package/dist/packages/{compiler → engine/compile}/compiled-schema.d.ts +2 -2
- package/dist/packages/{compiler → engine/compile}/compiled-schema.js +4 -4
- package/dist/packages/{compiler → engine/compile}/compiled-stage-plan.d.ts +1 -1
- package/dist/packages/{compiler → engine/compile}/compiled-stage-plan.js +4 -4
- package/dist/packages/{compiler → engine/compile}/compiled-stage-runner.d.ts +1 -1
- package/dist/packages/{compiler → engine/compile}/compiled-stage-runner.js +3 -3
- package/dist/packages/{compiler → engine/compile}/compiled-target.d.ts +2 -2
- package/dist/packages/{compiler → engine/compile}/compiled-target.js +2 -2
- package/dist/packages/{compiler → engine/compile}/discovery.js +1 -1
- package/dist/packages/{compiler → engine/compile}/lib/schema.d.ts +4 -4
- package/dist/packages/{compiler → engine/compile}/lib/schema.js +2 -2
- package/dist/packages/{compiler → engine/compile}/method-runs.d.ts +3 -3
- package/dist/packages/{compiler → engine/compile}/method-runs.js +3 -3
- package/dist/packages/{compiler → engine/compile}/runtime-acceptance.js +17 -14
- package/dist/packages/{compiler → engine/compile}/runtime-reconcile.d.ts +1 -1
- package/dist/packages/{compiler → engine/compile}/runtime-reconcile.js +12 -10
- package/dist/packages/{compiler → engine/compile}/runtime-runs.d.ts +1 -2
- package/dist/packages/{compiler → engine/compile}/runtime-runs.js +3 -43
- package/dist/packages/{compiler → engine/compile}/runtime-types.d.ts +1 -5
- package/dist/packages/{compiler → engine/compile}/runtime.d.ts +2 -2
- package/dist/packages/{compiler → engine/compile}/runtime.js +1 -1
- package/dist/packages/{compiler → engine/compile}/source-files.d.ts +1 -1
- package/dist/packages/{compiler → engine/compile}/source-files.js +3 -3
- package/dist/packages/{compiler → engine/compile}/state-health.js +2 -2
- package/dist/packages/{compiler → engine/compile}/state-io.js +2 -2
- package/dist/packages/{compiler → engine/compile}/state-view.js +2 -2
- package/dist/packages/{compiler → engine/compile}/validate-compiled.js +2 -2
- package/dist/packages/{compiler → engine/compile}/validate.d.ts +1 -1
- package/dist/packages/{compiler → engine/compile}/validate.js +3 -3
- package/dist/packages/{execution → engine/execution}/lib/schema.d.ts +2 -22
- package/dist/packages/{execution → engine/execution}/lib/schema.js +2 -2
- package/dist/packages/{local-service → engine}/index.d.ts +4 -4
- package/dist/packages/{local-service → engine}/index.js +2 -2
- package/dist/packages/{local-service → engine}/lib/schema.d.ts +85 -209
- package/dist/packages/{local-service → engine}/lib/schema.js +58 -54
- package/dist/packages/{local-service → engine}/native-run-handlers.d.ts +7 -5
- package/dist/packages/{local-service → engine}/native-run-handlers.js +69 -25
- package/dist/packages/{local-service → engine}/preparation-store.d.ts +16 -4
- package/dist/packages/{local-service → engine}/preparation-store.js +48 -25
- package/dist/packages/{local-service → engine}/readiness-check-draft.d.ts +2 -2
- package/dist/packages/{local-service → engine}/routes.d.ts +30 -1
- package/dist/packages/{local-service → engine}/routes.js +32 -1
- package/dist/packages/{local-service → engine}/run-observability.d.ts +3 -3
- package/dist/packages/{local-service → engine}/run-observability.js +14 -13
- package/dist/packages/{local-service → engine}/runtime-event-applier.d.ts +1 -1
- package/dist/packages/{local-service → engine}/runtime-persistence.d.ts +6 -6
- package/dist/packages/{local-service → engine}/runtime-persistence.js +9 -9
- package/dist/packages/{local-service → engine}/runtime-proposal-helpers.d.ts +1 -1
- package/dist/packages/{local-service → engine}/runtime-proposal-helpers.js +5 -5
- package/dist/packages/{local-service → engine}/runtime-resource-builders.d.ts +6 -6
- package/dist/packages/{local-service → engine}/runtime-resource-builders.js +1 -1
- package/dist/packages/{local-service → engine}/runtime.d.ts +80 -49
- package/dist/packages/{local-service → engine}/runtime.js +177 -179
- package/dist/packages/{local-service → engine}/server.js +276 -14
- package/dist/packages/{testing → engine/verify}/lib/schema.d.ts +1 -1
- package/dist/packages/{testing → engine/verify}/lib/schema.js +1 -1
- package/dist/packages/{testing → engine/verify}/readiness-check-run.d.ts +6 -13
- package/dist/packages/{testing → engine/verify}/readiness-check-run.js +25 -81
- package/dist/packages/{testing → engine/verify}/test-paths.js +2 -2
- package/dist/packages/{testing → engine/verify}/test-sandbox.js +6 -6
- package/dist/packages/{testing → engine/verify}/test-specs.js +1 -1
- package/dist/packages/{testing → engine/verify}/test-targets.js +3 -3
- package/dist/packages/{method-authoring → methods/authoring}/method-authoring.d.ts +11 -3
- package/dist/packages/{method-authoring → methods/authoring}/method-authoring.js +68 -5
- package/dist/packages/{method-authoring → methods/authoring}/method-edit-session.d.ts +2 -2
- package/dist/packages/{method-authoring → methods/authoring}/method-improvement.d.ts +4 -4
- package/dist/packages/{method-authoring → methods/authoring}/method-improvement.js +15 -9
- package/dist/packages/{method-package → methods/package}/builtin-compiled-method.d.ts +1 -1
- package/dist/packages/{method-package → methods/package}/builtin-compiled-method.js +2 -2
- package/dist/packages/{method-package → methods/package}/context-interface.d.ts +1 -1
- package/dist/packages/{method-package → methods/package}/context-interface.js +3 -3
- package/dist/packages/{method-package → methods/package}/interf-method-package.js +3 -2
- package/dist/packages/{method-package → methods/package}/lib/package-root.js +2 -2
- package/dist/packages/{method-package → methods/package}/local-methods.d.ts +8 -2
- package/dist/packages/{method-package → methods/package}/local-methods.js +8 -7
- package/dist/packages/{method-package → methods/package}/method-definitions.d.ts +8 -2
- package/dist/packages/{method-package → methods/package}/method-definitions.js +5 -4
- package/dist/packages/{method-package → methods/package}/method-helpers.d.ts +1 -1
- package/dist/packages/{method-package → methods/package}/method-helpers.js +4 -4
- package/dist/packages/{method-package → methods/package}/method-review-paths.d.ts +1 -1
- package/dist/packages/{method-package → methods/package}/method-review-paths.js +1 -1
- package/dist/packages/{method-package → methods/package}/method-stage-runner.d.ts +4 -9
- package/dist/packages/{method-package → methods/package}/method-stage-runner.js +1 -29
- package/dist/packages/{method-package → methods/package}/user-methods.js +2 -2
- package/dist/packages/{project-model → project}/interf-bootstrap.d.ts +1 -1
- package/dist/packages/{project-model → project}/interf-bootstrap.js +1 -1
- package/dist/packages/{project-model → project}/interf-detect.js +4 -4
- package/dist/packages/{project-model → project}/interf-scaffold.js +7 -7
- package/dist/packages/{project-model → project}/lib/schema.d.ts +2 -2
- package/dist/packages/{project-model → project}/lib/schema.js +1 -1
- package/dist/packages/{project-model → project}/source-config.d.ts +1 -1
- package/dist/packages/{project-model → project}/source-config.js +7 -7
- package/dist/packages/{project-model → project}/source-folders.js +2 -2
- package/package.json +6 -5
- package/dist/cli/commands/test.d.ts +0 -9
- package/dist/packages/agents/lib/detection.d.ts +0 -7
- /package/dist/compiler-ui/_next/static/{C6vVfy3aeYuIO3d2AoNvC → a3UiUF0DiMEbfWy_0gihg}/_buildManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{C6vVfy3aeYuIO3d2AoNvC → a3UiUF0DiMEbfWy_0gihg}/_clientMiddlewareManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{C6vVfy3aeYuIO3d2AoNvC → a3UiUF0DiMEbfWy_0gihg}/_ssgManifest.js +0 -0
- /package/dist/packages/{shared → contracts/utils}/file-types.d.ts +0 -0
- /package/dist/packages/{shared → contracts/utils}/file-types.js +0 -0
- /package/dist/packages/{shared → contracts/utils}/filesystem.d.ts +0 -0
- /package/dist/packages/{shared → contracts/utils}/filesystem.js +0 -0
- /package/dist/packages/{shared → contracts/utils}/logger.d.ts +0 -0
- /package/dist/packages/{shared → contracts/utils}/logger.js +0 -0
- /package/dist/packages/{shared → contracts/utils}/naming.d.ts +0 -0
- /package/dist/packages/{shared → contracts/utils}/naming.js +0 -0
- /package/dist/packages/{shared → contracts/utils}/parse.d.ts +0 -0
- /package/dist/packages/{shared → contracts/utils}/parse.js +0 -0
- /package/dist/packages/{shared → contracts/utils}/path-guards.d.ts +0 -0
- /package/dist/packages/{shared → contracts/utils}/path-guards.js +0 -0
- /package/dist/packages/{local-service → engine}/action-definitions.d.ts +0 -0
- /package/dist/packages/{local-service → engine}/action-values.d.ts +0 -0
- /package/dist/packages/{local-service → engine}/action-values.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/agents.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/agents.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/args.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/args.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/chart-guidance.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/chart-guidance.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/compiled-bootstrap.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/constants.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/constants.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/execution-profile.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/execution-profile.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/execution.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/execution.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/executors.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/logs.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/logs.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/preflight.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/preflight.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/render.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/render.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/schema.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/schema.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/status.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/status.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/types.d.ts +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/types.js +0 -0
- /package/dist/packages/{agents → engine/agents}/lib/user-config.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/artifact-counts.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/compiled-compile.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/compiled-compile.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/compiled-paths.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/compiled-paths.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/discovery.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/index.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/index.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/method-primitives.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/method-primitives.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/reset.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/reset.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-acceptance.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-contracts.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-contracts.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-inventory.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-inventory.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-paths.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-paths.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-prompt.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-prompt.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/runtime-types.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/state-artifacts.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/state-artifacts.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/state-health.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/state-io.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/state-paths.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/state-paths.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/state-view.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/state.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/state.js +0 -0
- /package/dist/packages/{compiler → engine/compile}/validate-compiled.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/validate-helpers.d.ts +0 -0
- /package/dist/packages/{compiler → engine/compile}/validate-helpers.js +0 -0
- /package/dist/packages/{local-service → engine}/connection-config.d.ts +0 -0
- /package/dist/packages/{local-service → engine}/connection-config.js +0 -0
- /package/dist/packages/{execution → engine/execution}/adapters.d.ts +0 -0
- /package/dist/packages/{execution → engine/execution}/adapters.js +0 -0
- /package/dist/packages/{execution → engine/execution}/events.d.ts +0 -0
- /package/dist/packages/{execution → engine/execution}/events.js +0 -0
- /package/dist/packages/{execution → engine/execution}/index.d.ts +0 -0
- /package/dist/packages/{execution → engine/execution}/index.js +0 -0
- /package/dist/packages/{local-service → engine}/instance-paths.d.ts +0 -0
- /package/dist/packages/{local-service → engine}/instance-paths.js +0 -0
- /package/dist/packages/{local-service → engine}/readiness-check-draft.js +0 -0
- /package/dist/packages/{local-service → engine}/runtime-caches.d.ts +0 -0
- /package/dist/packages/{local-service → engine}/runtime-caches.js +0 -0
- /package/dist/packages/{local-service → engine}/runtime-event-applier.js +0 -0
- /package/dist/packages/{local-service → engine}/server.d.ts +0 -0
- /package/dist/packages/{local-service → engine}/service-registry.d.ts +0 -0
- /package/dist/packages/{local-service → engine}/service-registry.js +0 -0
- /package/dist/packages/{testing → engine/verify}/index.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/index.js +0 -0
- /package/dist/packages/{testing → engine/verify}/test-execution.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/test-execution.js +0 -0
- /package/dist/packages/{testing → engine/verify}/test-paths.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/test-profile-presets.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/test-profile-presets.js +0 -0
- /package/dist/packages/{testing → engine/verify}/test-sandbox.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/test-specs.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/test-targets.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/test-types.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/test-types.js +0 -0
- /package/dist/packages/{testing → engine/verify}/test.d.ts +0 -0
- /package/dist/packages/{testing → engine/verify}/test.js +0 -0
- /package/dist/packages/{method-authoring → methods/authoring}/index.d.ts +0 -0
- /package/dist/packages/{method-authoring → methods/authoring}/index.js +0 -0
- /package/dist/packages/{method-authoring → methods/authoring}/lib/method-edit-utils.d.ts +0 -0
- /package/dist/packages/{method-authoring → methods/authoring}/lib/method-edit-utils.js +0 -0
- /package/dist/packages/{method-authoring → methods/authoring}/method-edit-session.js +0 -0
- /package/dist/packages/{method-package → methods/package}/interf-method-package.d.ts +0 -0
- /package/dist/packages/{method-package → methods/package}/lib/package-root.d.ts +0 -0
- /package/dist/packages/{method-package → methods/package}/user-methods.d.ts +0 -0
- /package/dist/packages/{project-model → project}/index.d.ts +0 -0
- /package/dist/packages/{project-model → project}/index.js +0 -0
- /package/dist/packages/{project-model → project}/interf-detect.d.ts +0 -0
- /package/dist/packages/{project-model → project}/interf-scaffold.d.ts +0 -0
- /package/dist/packages/{project-model → project}/interf.d.ts +0 -0
- /package/dist/packages/{project-model → project}/interf.js +0 -0
- /package/dist/packages/{project-model → project}/preparation-entries.d.ts +0 -0
- /package/dist/packages/{project-model → project}/preparation-entries.js +0 -0
- /package/dist/packages/{project-model → project}/source-folders.d.ts +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Agent } from "./types.js";
|
|
2
|
+
export declare function detectAgents(): Agent[];
|
|
3
|
+
/**
|
|
4
|
+
* Whether the executable named in an agent's `command` field resolves on
|
|
5
|
+
* PATH. Custom agents may register commands like `"opencode --prompt"`,
|
|
6
|
+
* so we only check the first whitespace-separated token.
|
|
7
|
+
*/
|
|
8
|
+
export declare function agentCommandAvailable(command: string): boolean;
|
|
9
|
+
export declare function supportsAutomatedRuns(agent: Agent): boolean;
|
|
10
|
+
export declare function resolveAgent(): {
|
|
11
|
+
agent: Agent | null;
|
|
12
|
+
error?: string;
|
|
13
|
+
};
|
|
@@ -19,6 +19,17 @@ function commandExists(command) {
|
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Whether the executable named in an agent's `command` field resolves on
|
|
24
|
+
* PATH. Custom agents may register commands like `"opencode --prompt"`,
|
|
25
|
+
* so we only check the first whitespace-separated token.
|
|
26
|
+
*/
|
|
27
|
+
export function agentCommandAvailable(command) {
|
|
28
|
+
const firstToken = command.trim().split(/\s+/)[0];
|
|
29
|
+
if (!firstToken)
|
|
30
|
+
return false;
|
|
31
|
+
return commandExists(firstToken);
|
|
32
|
+
}
|
|
22
33
|
export function supportsAutomatedRuns(agent) {
|
|
23
34
|
return agent.name === "claude-code" || agent.name === "codex";
|
|
24
35
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RuntimeExecutorInfo } from "
|
|
1
|
+
import type { RuntimeExecutorInfo } from "../../../contracts/lib/schema.js";
|
|
2
2
|
import type { Agent } from "./types.js";
|
|
3
3
|
export type MethodExecutorKind = "local-agent" | "connected-provider" | "managed";
|
|
4
4
|
export interface MethodExecutionProfile {
|
|
@@ -21,7 +21,7 @@ export interface MethodExecutor {
|
|
|
21
21
|
executionProfile?: MethodExecutionProfile;
|
|
22
22
|
execute(rootPath: string, prompt: string, options?: MethodExecuteOptions): Promise<number>;
|
|
23
23
|
}
|
|
24
|
-
export type { RuntimeExecutorInfo } from "
|
|
24
|
+
export type { RuntimeExecutorInfo } from "../../../contracts/lib/schema.js";
|
|
25
25
|
export declare function buildRuntimeExecutorInfo(executor: MethodExecutor): RuntimeExecutorInfo;
|
|
26
26
|
export declare function createLocalAgentExecutor(agent: Agent, executionProfile?: MethodExecutionProfile): MethodExecutor;
|
|
27
27
|
export declare function resolveLocalExecutor(options?: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { MethodImprovementContext } from "../../
|
|
2
|
-
import type { RuntimeContractType } from "
|
|
3
|
-
import type { SourceReadinessCheck } from "
|
|
4
|
-
import { type ContextInterfaceZoneId as MethodZoneId } from "
|
|
1
|
+
import type { MethodImprovementContext } from "../../compile/lib/schema.js";
|
|
2
|
+
import type { RuntimeContractType } from "../../../contracts/lib/schema.js";
|
|
3
|
+
import type { SourceReadinessCheck } from "../../../project/lib/schema.js";
|
|
4
|
+
import { type ContextInterfaceZoneId as MethodZoneId } from "../../../methods/package/context-interface.js";
|
|
5
5
|
export interface NativeStageDefinition {
|
|
6
6
|
id: string;
|
|
7
7
|
label: string;
|
|
@@ -2,13 +2,13 @@ import { cpSync, copyFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, re
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { basename, dirname, join, relative, sep as pathSep } from "node:path";
|
|
4
4
|
import { CHART_APPROXIMATION_NOTES } from "./chart-guidance.js";
|
|
5
|
-
import { buildCompiledSourceFiles } from "../../
|
|
6
|
-
import { METHOD_PACKAGE_DIR } from "
|
|
7
|
-
import { CONTEXT_INTERFACE_FILE as METHOD_SCHEMA_FILE, contextInterfaceZoneAbsolutePath as compiledZoneAbsolutePath, readContextInterface as readCompiledSchemaFile, resolveContextInterfacePath as resolveMethodSchemaPath, } from "
|
|
8
|
-
import { stageExecutionShellsRoot, methodImprovementLoopRoot, methodPackagePathForCompiled, compiledInterfConfigPath, compiledRuntimeRoot, compiledRuntimeSourceSnapshotPath, compiledRuntimeStageInputsPath, } from "../../
|
|
9
|
-
import { ensureCompiledZoneTargets } from "../../
|
|
10
|
-
import { listFilesRecursive } from "
|
|
11
|
-
import { resolveMethodImprovementReviewSourcePaths } from "
|
|
5
|
+
import { buildCompiledSourceFiles } from "../../compile/source-files.js";
|
|
6
|
+
import { METHOD_PACKAGE_DIR } from "../../../project/interf-detect.js";
|
|
7
|
+
import { CONTEXT_INTERFACE_FILE as METHOD_SCHEMA_FILE, contextInterfaceZoneAbsolutePath as compiledZoneAbsolutePath, readContextInterface as readCompiledSchemaFile, resolveContextInterfacePath as resolveMethodSchemaPath, } from "../../../methods/package/context-interface.js";
|
|
8
|
+
import { stageExecutionShellsRoot, methodImprovementLoopRoot, methodPackagePathForCompiled, compiledInterfConfigPath, compiledRuntimeRoot, compiledRuntimeSourceSnapshotPath, compiledRuntimeStageInputsPath, } from "../../compile/compiled-paths.js";
|
|
9
|
+
import { ensureCompiledZoneTargets } from "../../compile/compiled-schema.js";
|
|
10
|
+
import { listFilesRecursive } from "../../../contracts/utils/filesystem.js";
|
|
11
|
+
import { resolveMethodImprovementReviewSourcePaths } from "../../../methods/package/method-review-paths.js";
|
|
12
12
|
const LOCAL_SKILL_ROOTS = [
|
|
13
13
|
".claude/skills",
|
|
14
14
|
".codex/skills",
|
|
@@ -90,7 +90,7 @@ export function renderCompiledAgents(compiledPath, name, methodId, about, option
|
|
|
90
90
|
"",
|
|
91
91
|
"```",
|
|
92
92
|
"interf compile build this portable context",
|
|
93
|
-
"interf
|
|
93
|
+
"interf verify run checks against this portable context",
|
|
94
94
|
"interf status show deterministic health",
|
|
95
95
|
"```",
|
|
96
96
|
"",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { readJsonFileWithSchema } from "
|
|
4
|
-
import { interfHomeRoot } from "
|
|
3
|
+
import { readJsonFileWithSchema } from "../../../contracts/utils/parse.js";
|
|
4
|
+
import { interfHomeRoot } from "../../../contracts/lib/preparation-paths.js";
|
|
5
5
|
import { InterfUserConfigSchema } from "./schema.js";
|
|
6
6
|
/** `~/.interf/` (overridable via `INTERF_USER_HOME`). */
|
|
7
7
|
export function interfHome() {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type AgentRecord, type AgentsRegistry, type RoleMap } from "../../contracts/lib/schema.js";
|
|
2
|
+
export declare const AGENTS_REGISTRY_FILENAME = "agents.json";
|
|
3
|
+
/** `~/.interf/agents.json` — persisted custom agents + role-map. */
|
|
4
|
+
export declare function agentsRegistryPath(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Load just the persisted on-disk part of the registry. Built-in agents
|
|
7
|
+
* are NOT included — call `loadAgentsRegistry()` for the merged view.
|
|
8
|
+
*
|
|
9
|
+
* Returns `{ agents: [], role_map: {} }` when the file is missing or
|
|
10
|
+
* unreadable; persisted custom agents always have `source: "user"`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadPersistedRegistry(): AgentsRegistry;
|
|
13
|
+
/** Persist the on-disk part of the registry (custom agents + role-map). */
|
|
14
|
+
export declare function savePersistedRegistry(registry: AgentsRegistry): void;
|
|
15
|
+
/**
|
|
16
|
+
* Detect built-in agents present on this machine. Filtered to agents
|
|
17
|
+
* whose marker home directory exists; we do NOT require the command
|
|
18
|
+
* to be on PATH at registry read time — that's a runtime concern.
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectBuiltinAgentRecords(): AgentRecord[];
|
|
21
|
+
/**
|
|
22
|
+
* Same as `detectBuiltinAgentRecords()` but only includes agents the
|
|
23
|
+
* current Interf build can fully drive (Claude Code, Codex). Used by
|
|
24
|
+
* the role-router and the CLI / UI listing as the "available agents"
|
|
25
|
+
* set.
|
|
26
|
+
*/
|
|
27
|
+
export declare function detectAutomatableBuiltinAgentRecords(): AgentRecord[];
|
|
28
|
+
/**
|
|
29
|
+
* Full advertisement set — all built-in agents Interf knows about,
|
|
30
|
+
* regardless of whether they are installed locally. Used by the
|
|
31
|
+
* "install cards" zero-state surface so the UI / wizard can offer
|
|
32
|
+
* the user choices to install.
|
|
33
|
+
*/
|
|
34
|
+
export declare function listKnownBuiltinAgents(): AgentRecord[];
|
|
35
|
+
export interface ResolvedRegistry {
|
|
36
|
+
/** All currently usable agents — built-in detected + persisted custom. */
|
|
37
|
+
agents: AgentRecord[];
|
|
38
|
+
/** Role → agent-name. Includes any persisted user edits. */
|
|
39
|
+
roleMap: RoleMap;
|
|
40
|
+
/**
|
|
41
|
+
* The "active" / default agent. This is whatever the role-map's
|
|
42
|
+
* `general` row points at, falling back to the first available
|
|
43
|
+
* agent when `general` is unset or maps to something that no longer
|
|
44
|
+
* exists in `agents`.
|
|
45
|
+
*/
|
|
46
|
+
activeAgent: AgentRecord | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Public entry point — read the persisted registry, merge with detected
|
|
50
|
+
* built-ins, and seed the default role-map on first read if needed.
|
|
51
|
+
*
|
|
52
|
+
* Does NOT write back to disk. Callers that mutate the registry should
|
|
53
|
+
* call `savePersistedRegistry()` explicitly with the persisted slice.
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadAgentsRegistry(): ResolvedRegistry;
|
|
56
|
+
/** Pure helper — like `loadAgentsRegistry()` but works off in-memory data. */
|
|
57
|
+
export declare function resolveRegistry(persisted: AgentsRegistry, builtinDetected: AgentRecord[]): ResolvedRegistry;
|
|
58
|
+
/**
|
|
59
|
+
* Update the role-map (full replace). Returns the persisted slice that
|
|
60
|
+
* was written.
|
|
61
|
+
*/
|
|
62
|
+
export declare function updateRoleMap(nextRoleMap: RoleMap): AgentsRegistry;
|
|
63
|
+
/**
|
|
64
|
+
* Patch the role-map with a partial update. Empty-string values clear
|
|
65
|
+
* the role (it falls back to `general` / active agent at run time).
|
|
66
|
+
*/
|
|
67
|
+
export declare function patchRoleMap(patch: Record<string, string>): AgentsRegistry;
|
|
68
|
+
/**
|
|
69
|
+
* Register a new custom agent. Throws if `name` collides with a known
|
|
70
|
+
* built-in or with an already-persisted custom agent.
|
|
71
|
+
*/
|
|
72
|
+
export declare function registerCustomAgent(input: {
|
|
73
|
+
name: string;
|
|
74
|
+
display_name: string;
|
|
75
|
+
command: string;
|
|
76
|
+
}): AgentsRegistry;
|
|
77
|
+
/**
|
|
78
|
+
* Unregister a custom agent. Throws if `name` matches a built-in or no
|
|
79
|
+
* custom record exists. Removes any role-map entry pointing at the
|
|
80
|
+
* removed agent.
|
|
81
|
+
*/
|
|
82
|
+
export declare function unregisterCustomAgent(name: string): AgentsRegistry;
|
|
83
|
+
/**
|
|
84
|
+
* Set the "active" agent — i.e. the agent the role-map's `general` row
|
|
85
|
+
* points at. Also updates any role still pointing at the previous
|
|
86
|
+
* active agent so existing single-active-agent setups don't need
|
|
87
|
+
* per-role edits when switching agents.
|
|
88
|
+
*
|
|
89
|
+
* Throws if `name` is not in the merged agents list.
|
|
90
|
+
*/
|
|
91
|
+
export declare function setActiveAgent(name: string): AgentsRegistry;
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agents registry — `~/.interf/agents.json`.
|
|
3
|
+
*
|
|
4
|
+
* Reads / writes the persisted user-registered agents and the role-map.
|
|
5
|
+
* Built-in agents (Claude Code, Codex, Cursor) are NOT persisted; they
|
|
6
|
+
* are detected dynamically at read time and merged with the persisted
|
|
7
|
+
* custom agents. The role-map IS persisted.
|
|
8
|
+
*
|
|
9
|
+
* 0.15 contract:
|
|
10
|
+
* {
|
|
11
|
+
* "agents": [
|
|
12
|
+
* { "name": "opencode", "display_name": "OpenCode", "command": "opencode --prompt", "source": "user" }
|
|
13
|
+
* ],
|
|
14
|
+
* "role_map": {
|
|
15
|
+
* "extractor": "claude-code",
|
|
16
|
+
* "summarizer": "claude-code",
|
|
17
|
+
* "structurer": "claude-code",
|
|
18
|
+
* "verifier": "claude-code",
|
|
19
|
+
* "general": "claude-code"
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
*/
|
|
23
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
24
|
+
import { join } from "node:path";
|
|
25
|
+
import { AgentRecordSchema, AgentsRegistrySchema, CANONICAL_ROLES, } from "../../contracts/lib/schema.js";
|
|
26
|
+
import { readJsonFileWithSchema } from "../../contracts/utils/parse.js";
|
|
27
|
+
import { interfHomeRoot } from "../instance-paths.js";
|
|
28
|
+
import { agentCommandAvailable, detectAgents, supportsAutomatedRuns } from "./lib/detection.js";
|
|
29
|
+
import { AGENTS } from "./lib/constants.js";
|
|
30
|
+
export const AGENTS_REGISTRY_FILENAME = "agents.json";
|
|
31
|
+
/** `~/.interf/agents.json` — persisted custom agents + role-map. */
|
|
32
|
+
export function agentsRegistryPath() {
|
|
33
|
+
return join(interfHomeRoot(), AGENTS_REGISTRY_FILENAME);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load just the persisted on-disk part of the registry. Built-in agents
|
|
37
|
+
* are NOT included — call `loadAgentsRegistry()` for the merged view.
|
|
38
|
+
*
|
|
39
|
+
* Returns `{ agents: [], role_map: {} }` when the file is missing or
|
|
40
|
+
* unreadable; persisted custom agents always have `source: "user"`.
|
|
41
|
+
*/
|
|
42
|
+
export function loadPersistedRegistry() {
|
|
43
|
+
const path = agentsRegistryPath();
|
|
44
|
+
if (!existsSync(path)) {
|
|
45
|
+
return AgentsRegistrySchema.parse({});
|
|
46
|
+
}
|
|
47
|
+
const value = readJsonFileWithSchema(path, "agents registry", AgentsRegistrySchema);
|
|
48
|
+
return value ?? AgentsRegistrySchema.parse({});
|
|
49
|
+
}
|
|
50
|
+
/** Persist the on-disk part of the registry (custom agents + role-map). */
|
|
51
|
+
export function savePersistedRegistry(registry) {
|
|
52
|
+
const home = interfHomeRoot();
|
|
53
|
+
mkdirSync(home, { recursive: true });
|
|
54
|
+
const sanitized = {
|
|
55
|
+
agents: registry.agents.map(({ available: _available, ...agent }) => AgentRecordSchema.parse({ ...agent, source: "user" })),
|
|
56
|
+
role_map: { ...registry.role_map },
|
|
57
|
+
};
|
|
58
|
+
writeFileSync(agentsRegistryPath(), `${JSON.stringify(sanitized, null, 2)}\n`);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Detect built-in agents present on this machine. Filtered to agents
|
|
62
|
+
* whose marker home directory exists; we do NOT require the command
|
|
63
|
+
* to be on PATH at registry read time — that's a runtime concern.
|
|
64
|
+
*/
|
|
65
|
+
export function detectBuiltinAgentRecords() {
|
|
66
|
+
return detectAgents().map((agent) => AgentRecordSchema.parse({
|
|
67
|
+
name: agent.name,
|
|
68
|
+
display_name: agent.displayName,
|
|
69
|
+
command: agent.command,
|
|
70
|
+
source: "builtin",
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Same as `detectBuiltinAgentRecords()` but only includes agents the
|
|
75
|
+
* current Interf build can fully drive (Claude Code, Codex). Used by
|
|
76
|
+
* the role-router and the CLI / UI listing as the "available agents"
|
|
77
|
+
* set.
|
|
78
|
+
*/
|
|
79
|
+
export function detectAutomatableBuiltinAgentRecords() {
|
|
80
|
+
return detectAgents()
|
|
81
|
+
.filter(supportsAutomatedRuns)
|
|
82
|
+
.map((agent) => AgentRecordSchema.parse({
|
|
83
|
+
name: agent.name,
|
|
84
|
+
display_name: agent.displayName,
|
|
85
|
+
command: agent.command,
|
|
86
|
+
source: "builtin",
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Full advertisement set — all built-in agents Interf knows about,
|
|
91
|
+
* regardless of whether they are installed locally. Used by the
|
|
92
|
+
* "install cards" zero-state surface so the UI / wizard can offer
|
|
93
|
+
* the user choices to install.
|
|
94
|
+
*/
|
|
95
|
+
export function listKnownBuiltinAgents() {
|
|
96
|
+
return AGENTS.map((agent) => AgentRecordSchema.parse({
|
|
97
|
+
name: agent.name,
|
|
98
|
+
display_name: agent.displayName,
|
|
99
|
+
command: agent.command,
|
|
100
|
+
source: "builtin",
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Merge persisted custom agents with the built-in agents currently
|
|
105
|
+
* detected on this machine. Detected built-ins are listed first; any
|
|
106
|
+
* persisted custom entry whose name collides with a built-in is
|
|
107
|
+
* dropped (built-ins are immutable / cannot be overridden).
|
|
108
|
+
*
|
|
109
|
+
* Each merged record carries an `available` flag — true when the
|
|
110
|
+
* agent's command resolves on PATH. Built-ins are detected by their
|
|
111
|
+
* marker directory and assumed available; custom agents are checked
|
|
112
|
+
* against `which` so a stale `~/.interf/agents.json` entry does not
|
|
113
|
+
* appear as a usable choice.
|
|
114
|
+
*/
|
|
115
|
+
function mergeAgents(builtin, persisted) {
|
|
116
|
+
const seen = new Set(builtin.map((agent) => agent.name));
|
|
117
|
+
const merged = builtin.map((agent) => ({ ...agent, available: true }));
|
|
118
|
+
for (const agent of persisted) {
|
|
119
|
+
if (seen.has(agent.name))
|
|
120
|
+
continue;
|
|
121
|
+
seen.add(agent.name);
|
|
122
|
+
merged.push({
|
|
123
|
+
...agent,
|
|
124
|
+
source: "user",
|
|
125
|
+
available: agentCommandAvailable(agent.command),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return merged;
|
|
129
|
+
}
|
|
130
|
+
function pickActiveAgent(agents, roleMap) {
|
|
131
|
+
const generalName = roleMap["general"];
|
|
132
|
+
const generalAgent = generalName
|
|
133
|
+
? agents.find((agent) => agent.name === generalName)
|
|
134
|
+
: null;
|
|
135
|
+
if (generalAgent && generalAgent.available !== false)
|
|
136
|
+
return generalAgent;
|
|
137
|
+
return agents.find((agent) => agent.available !== false) ?? null;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Default role-map for a fresh install: every canonical role maps to
|
|
141
|
+
* the first available agent. If nothing is detected, returns an empty
|
|
142
|
+
* object (callers must handle "no agents available" upstream).
|
|
143
|
+
*/
|
|
144
|
+
function buildDefaultRoleMap(agents) {
|
|
145
|
+
const first = agents.find((agent) => agent.available !== false) ?? agents[0];
|
|
146
|
+
if (!first)
|
|
147
|
+
return {};
|
|
148
|
+
const map = {};
|
|
149
|
+
for (const role of CANONICAL_ROLES) {
|
|
150
|
+
map[role] = first.name;
|
|
151
|
+
}
|
|
152
|
+
return map;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Public entry point — read the persisted registry, merge with detected
|
|
156
|
+
* built-ins, and seed the default role-map on first read if needed.
|
|
157
|
+
*
|
|
158
|
+
* Does NOT write back to disk. Callers that mutate the registry should
|
|
159
|
+
* call `savePersistedRegistry()` explicitly with the persisted slice.
|
|
160
|
+
*/
|
|
161
|
+
export function loadAgentsRegistry() {
|
|
162
|
+
const persisted = loadPersistedRegistry();
|
|
163
|
+
const builtinDetected = detectAutomatableBuiltinAgentRecords();
|
|
164
|
+
const agents = mergeAgents(builtinDetected, persisted.agents);
|
|
165
|
+
// Seed the default role-map on first read when the persisted file
|
|
166
|
+
// has no role-map entries AND we have at least one detectable agent.
|
|
167
|
+
// (We do not write to disk yet; the seeded map is computed on the
|
|
168
|
+
// fly for each reader so a fresh install behaves identically before
|
|
169
|
+
// and after the first user edit.)
|
|
170
|
+
const persistedRoleMap = persisted.role_map;
|
|
171
|
+
const hasPersistedEntries = Object.keys(persistedRoleMap).length > 0;
|
|
172
|
+
const roleMap = hasPersistedEntries
|
|
173
|
+
? { ...persistedRoleMap }
|
|
174
|
+
: buildDefaultRoleMap(agents);
|
|
175
|
+
// Derive the "active" agent: role-map's `general` entry, falling
|
|
176
|
+
// back to the first available agent. Skips the general entry if it
|
|
177
|
+
// points at an agent whose command is no longer on PATH.
|
|
178
|
+
const activeAgent = pickActiveAgent(agents, roleMap);
|
|
179
|
+
return { agents, roleMap, activeAgent };
|
|
180
|
+
}
|
|
181
|
+
/** Pure helper — like `loadAgentsRegistry()` but works off in-memory data. */
|
|
182
|
+
export function resolveRegistry(persisted, builtinDetected) {
|
|
183
|
+
const agents = mergeAgents(builtinDetected, persisted.agents);
|
|
184
|
+
const hasPersistedEntries = Object.keys(persisted.role_map).length > 0;
|
|
185
|
+
const roleMap = hasPersistedEntries
|
|
186
|
+
? { ...persisted.role_map }
|
|
187
|
+
: buildDefaultRoleMap(agents);
|
|
188
|
+
const activeAgent = pickActiveAgent(agents, roleMap);
|
|
189
|
+
return { agents, roleMap, activeAgent };
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Update the role-map (full replace). Returns the persisted slice that
|
|
193
|
+
* was written.
|
|
194
|
+
*/
|
|
195
|
+
export function updateRoleMap(nextRoleMap) {
|
|
196
|
+
const current = loadPersistedRegistry();
|
|
197
|
+
const next = {
|
|
198
|
+
agents: current.agents,
|
|
199
|
+
role_map: { ...nextRoleMap },
|
|
200
|
+
};
|
|
201
|
+
savePersistedRegistry(next);
|
|
202
|
+
return next;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Patch the role-map with a partial update. Empty-string values clear
|
|
206
|
+
* the role (it falls back to `general` / active agent at run time).
|
|
207
|
+
*/
|
|
208
|
+
export function patchRoleMap(patch) {
|
|
209
|
+
const current = loadPersistedRegistry();
|
|
210
|
+
const next = { ...current.role_map };
|
|
211
|
+
for (const [role, agentName] of Object.entries(patch)) {
|
|
212
|
+
if (typeof agentName !== "string" || agentName.trim().length === 0) {
|
|
213
|
+
delete next[role];
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
next[role] = agentName.trim();
|
|
217
|
+
}
|
|
218
|
+
const updated = {
|
|
219
|
+
agents: current.agents,
|
|
220
|
+
role_map: next,
|
|
221
|
+
};
|
|
222
|
+
savePersistedRegistry(updated);
|
|
223
|
+
return updated;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Register a new custom agent. Throws if `name` collides with a known
|
|
227
|
+
* built-in or with an already-persisted custom agent.
|
|
228
|
+
*/
|
|
229
|
+
export function registerCustomAgent(input) {
|
|
230
|
+
const trimmedName = input.name.trim();
|
|
231
|
+
const trimmedDisplayName = input.display_name.trim();
|
|
232
|
+
const trimmedCommand = input.command.trim();
|
|
233
|
+
if (!trimmedName)
|
|
234
|
+
throw new Error("Agent name is required.");
|
|
235
|
+
if (!trimmedDisplayName)
|
|
236
|
+
throw new Error("Agent display name is required.");
|
|
237
|
+
if (!trimmedCommand)
|
|
238
|
+
throw new Error("Agent command is required.");
|
|
239
|
+
if (AGENTS.some((agent) => agent.name === trimmedName)) {
|
|
240
|
+
throw new Error(`Cannot register custom agent "${trimmedName}": that name is reserved for a built-in agent.`);
|
|
241
|
+
}
|
|
242
|
+
const current = loadPersistedRegistry();
|
|
243
|
+
if (current.agents.some((agent) => agent.name === trimmedName)) {
|
|
244
|
+
throw new Error(`Custom agent "${trimmedName}" is already registered.`);
|
|
245
|
+
}
|
|
246
|
+
const record = AgentRecordSchema.parse({
|
|
247
|
+
name: trimmedName,
|
|
248
|
+
display_name: trimmedDisplayName,
|
|
249
|
+
command: trimmedCommand,
|
|
250
|
+
source: "user",
|
|
251
|
+
});
|
|
252
|
+
const next = {
|
|
253
|
+
agents: [...current.agents, record],
|
|
254
|
+
role_map: { ...current.role_map },
|
|
255
|
+
};
|
|
256
|
+
savePersistedRegistry(next);
|
|
257
|
+
return next;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Unregister a custom agent. Throws if `name` matches a built-in or no
|
|
261
|
+
* custom record exists. Removes any role-map entry pointing at the
|
|
262
|
+
* removed agent.
|
|
263
|
+
*/
|
|
264
|
+
export function unregisterCustomAgent(name) {
|
|
265
|
+
const trimmedName = name.trim();
|
|
266
|
+
if (AGENTS.some((agent) => agent.name === trimmedName)) {
|
|
267
|
+
throw new Error(`Cannot unregister built-in agent "${trimmedName}". Built-in agents are detected dynamically.`);
|
|
268
|
+
}
|
|
269
|
+
const current = loadPersistedRegistry();
|
|
270
|
+
const remaining = current.agents.filter((agent) => agent.name !== trimmedName);
|
|
271
|
+
if (remaining.length === current.agents.length) {
|
|
272
|
+
throw new Error(`Custom agent "${trimmedName}" is not registered.`);
|
|
273
|
+
}
|
|
274
|
+
const trimmedRoleMap = {};
|
|
275
|
+
for (const [role, agentName] of Object.entries(current.role_map)) {
|
|
276
|
+
if (agentName === trimmedName)
|
|
277
|
+
continue;
|
|
278
|
+
trimmedRoleMap[role] = agentName;
|
|
279
|
+
}
|
|
280
|
+
const next = {
|
|
281
|
+
agents: remaining,
|
|
282
|
+
role_map: trimmedRoleMap,
|
|
283
|
+
};
|
|
284
|
+
savePersistedRegistry(next);
|
|
285
|
+
return next;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Set the "active" agent — i.e. the agent the role-map's `general` row
|
|
289
|
+
* points at. Also updates any role still pointing at the previous
|
|
290
|
+
* active agent so existing single-active-agent setups don't need
|
|
291
|
+
* per-role edits when switching agents.
|
|
292
|
+
*
|
|
293
|
+
* Throws if `name` is not in the merged agents list.
|
|
294
|
+
*/
|
|
295
|
+
export function setActiveAgent(name) {
|
|
296
|
+
const trimmedName = name.trim();
|
|
297
|
+
if (!trimmedName)
|
|
298
|
+
throw new Error("Agent name is required.");
|
|
299
|
+
const persisted = loadPersistedRegistry();
|
|
300
|
+
const builtinDetected = detectAutomatableBuiltinAgentRecords();
|
|
301
|
+
const agents = mergeAgents(builtinDetected, persisted.agents);
|
|
302
|
+
if (!agents.some((agent) => agent.name === trimmedName)) {
|
|
303
|
+
throw new Error(`Agent "${trimmedName}" is not detected or registered. Install or register it before making it active.`);
|
|
304
|
+
}
|
|
305
|
+
// The previous active is whatever `general` currently maps to (or the
|
|
306
|
+
// first agent in the merged list when `general` is unset).
|
|
307
|
+
const previousActive = persisted.role_map["general"] ?? agents[0]?.name ?? null;
|
|
308
|
+
const nextRoleMap = { ...persisted.role_map };
|
|
309
|
+
for (const [role, currentName] of Object.entries(nextRoleMap)) {
|
|
310
|
+
if (currentName === previousActive) {
|
|
311
|
+
nextRoleMap[role] = trimmedName;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
nextRoleMap["general"] = trimmedName;
|
|
315
|
+
const next = {
|
|
316
|
+
agents: persisted.agents,
|
|
317
|
+
role_map: nextRoleMap,
|
|
318
|
+
};
|
|
319
|
+
savePersistedRegistry(next);
|
|
320
|
+
return next;
|
|
321
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AgentRecord, RoleMap } from "../../contracts/lib/schema.js";
|
|
2
|
+
import type { MethodExecutionProfile, MethodExecutor } from "./lib/executors.js";
|
|
3
|
+
import { type ResolvedAgent, type RoleResolutionContext } from "./role-router.js";
|
|
4
|
+
export interface RoleExecutorBundle {
|
|
5
|
+
/** Map agent name → method executor. */
|
|
6
|
+
executors: Map<string, MethodExecutor>;
|
|
7
|
+
/** Default fallback executor — usually the active agent. */
|
|
8
|
+
defaultExecutor: MethodExecutor;
|
|
9
|
+
/** The registry context we built this bundle from. */
|
|
10
|
+
context: RoleResolutionContext;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a stage's role to an executor + provenance. Falls back
|
|
13
|
+
* through `general` and the default executor before raising.
|
|
14
|
+
*/
|
|
15
|
+
resolveExecutorForRole(role: string): {
|
|
16
|
+
executor: MethodExecutor;
|
|
17
|
+
resolved: ResolvedAgent;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface BuildRoleExecutorBundleInput {
|
|
21
|
+
agents: AgentRecord[];
|
|
22
|
+
roleMap: RoleMap;
|
|
23
|
+
/** The agent the role-map's `general` row points at, or fallback. */
|
|
24
|
+
activeAgent: AgentRecord | null;
|
|
25
|
+
/** The fallback executor — used when role resolution yields the active. */
|
|
26
|
+
defaultExecutor: MethodExecutor;
|
|
27
|
+
executionProfile?: MethodExecutionProfile;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build a per-role executor bundle from a registry snapshot. The
|
|
31
|
+
* `defaultExecutor` is what the pipeline already passes for the
|
|
32
|
+
* single-active-agent case (so role lookups that fall through to
|
|
33
|
+
* `fallback-active` resolve to the same executor).
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildRoleExecutorBundle(input: BuildRoleExecutorBundleInput): RoleExecutorBundle;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role-aware executor factory.
|
|
3
|
+
*
|
|
4
|
+
* Bridges the registry layer (`AgentRecord` / `RoleMap`) to the runtime
|
|
5
|
+
* layer (`MethodExecutor`). Builds a per-agent-name `MethodExecutor`
|
|
6
|
+
* map up front and exposes a `resolveExecutorForRole(role)` helper that
|
|
7
|
+
* the compile / verify pipelines can call per-stage.
|
|
8
|
+
*
|
|
9
|
+
* Falls back gracefully: when a role isn't mapped, or the mapped agent
|
|
10
|
+
* is missing, we fall through to `general` and ultimately to the
|
|
11
|
+
* default executor (the active agent at job start).
|
|
12
|
+
*/
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { homedir } from "node:os";
|
|
15
|
+
import { createLocalAgentExecutor } from "./lib/executors.js";
|
|
16
|
+
import { AGENTS } from "./lib/constants.js";
|
|
17
|
+
import { resolveAgentForRole, } from "./role-router.js";
|
|
18
|
+
/**
|
|
19
|
+
* Hydrate an `AgentRecord` (registry shape) into an `Agent` (runtime
|
|
20
|
+
* shape with `skillsDir`). For built-in agents we copy the canonical
|
|
21
|
+
* `skillsDir`; for custom user agents we synthesize a path under
|
|
22
|
+
* `~/.<name>` so any future skill loader has somewhere to look.
|
|
23
|
+
*/
|
|
24
|
+
function agentRecordToAgent(record) {
|
|
25
|
+
const builtin = AGENTS.find((agent) => agent.name === record.name);
|
|
26
|
+
if (builtin)
|
|
27
|
+
return { ...builtin };
|
|
28
|
+
return {
|
|
29
|
+
name: record.name,
|
|
30
|
+
displayName: record.display_name,
|
|
31
|
+
skillsDir: join(homedir(), `.${record.name}`),
|
|
32
|
+
command: record.command,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build a per-role executor bundle from a registry snapshot. The
|
|
37
|
+
* `defaultExecutor` is what the pipeline already passes for the
|
|
38
|
+
* single-active-agent case (so role lookups that fall through to
|
|
39
|
+
* `fallback-active` resolve to the same executor).
|
|
40
|
+
*/
|
|
41
|
+
export function buildRoleExecutorBundle(input) {
|
|
42
|
+
const executors = new Map();
|
|
43
|
+
for (const record of input.agents) {
|
|
44
|
+
const agent = agentRecordToAgent(record);
|
|
45
|
+
executors.set(record.name, createLocalAgentExecutor(agent, input.executionProfile));
|
|
46
|
+
}
|
|
47
|
+
// Make sure the active / default executor is reachable by name
|
|
48
|
+
// even when the active agent isn't formally in the registry yet
|
|
49
|
+
// (e.g. legacy single-active setups during the 0.14 → 0.15 transition).
|
|
50
|
+
if (input.activeAgent && !executors.has(input.activeAgent.name)) {
|
|
51
|
+
executors.set(input.activeAgent.name, input.defaultExecutor);
|
|
52
|
+
}
|
|
53
|
+
const context = {
|
|
54
|
+
roleMap: input.roleMap,
|
|
55
|
+
agents: input.agents,
|
|
56
|
+
activeAgent: input.activeAgent,
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
executors,
|
|
60
|
+
defaultExecutor: input.defaultExecutor,
|
|
61
|
+
context,
|
|
62
|
+
resolveExecutorForRole(role) {
|
|
63
|
+
const result = resolveAgentForRole(role, context);
|
|
64
|
+
if ("error" in result) {
|
|
65
|
+
// Role-router refused — fall back to the default executor and
|
|
66
|
+
// synthesize a `fallback-active` resolution. This keeps prepare
|
|
67
|
+
// runs alive when the registry is empty / mid-edit.
|
|
68
|
+
const synthetic = {
|
|
69
|
+
agent: input.activeAgent
|
|
70
|
+
?? {
|
|
71
|
+
name: input.defaultExecutor.name,
|
|
72
|
+
display_name: input.defaultExecutor.displayName,
|
|
73
|
+
command: input.defaultExecutor.command ?? input.defaultExecutor.name,
|
|
74
|
+
source: "user",
|
|
75
|
+
},
|
|
76
|
+
role,
|
|
77
|
+
source: "fallback-active",
|
|
78
|
+
};
|
|
79
|
+
return {
|
|
80
|
+
executor: input.defaultExecutor,
|
|
81
|
+
resolved: synthetic,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const executor = executors.get(result.agent.name) ?? input.defaultExecutor;
|
|
85
|
+
return { executor, resolved: result };
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|