@oxagen/cli 0.6.0 → 0.6.1
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/dist/agent/__tests__/judge.test.js +11 -6
- package/dist/agent/__tests__/judge.test.js.map +1 -1
- package/dist/agent/__tests__/loop-errors.test.js +32 -1
- package/dist/agent/__tests__/loop-errors.test.js.map +1 -1
- package/dist/agent/__tests__/loop-gating.test.d.ts +2 -0
- package/dist/agent/__tests__/loop-gating.test.d.ts.map +1 -0
- package/dist/agent/__tests__/loop-gating.test.js +94 -0
- package/dist/agent/__tests__/loop-gating.test.js.map +1 -0
- package/dist/agent/__tests__/model-router.test.js +16 -0
- package/dist/agent/__tests__/model-router.test.js.map +1 -1
- package/dist/agent/__tests__/permissions.test.d.ts +2 -0
- package/dist/agent/__tests__/permissions.test.d.ts.map +1 -0
- package/dist/agent/__tests__/permissions.test.js +206 -0
- package/dist/agent/__tests__/permissions.test.js.map +1 -0
- package/dist/agent/__tests__/pipeline-telemetry.test.d.ts +2 -0
- package/dist/agent/__tests__/pipeline-telemetry.test.d.ts.map +1 -0
- package/dist/agent/__tests__/pipeline-telemetry.test.js +158 -0
- package/dist/agent/__tests__/pipeline-telemetry.test.js.map +1 -0
- package/dist/agent/__tests__/pipeline.test.js +12 -3
- package/dist/agent/__tests__/pipeline.test.js.map +1 -1
- package/dist/agent/__tests__/rate-card.test.d.ts +2 -0
- package/dist/agent/__tests__/rate-card.test.d.ts.map +1 -0
- package/dist/agent/__tests__/rate-card.test.js +69 -0
- package/dist/agent/__tests__/rate-card.test.js.map +1 -0
- package/dist/agent/__tests__/system-prompt.test.d.ts +2 -0
- package/dist/agent/__tests__/system-prompt.test.d.ts.map +1 -0
- package/dist/agent/__tests__/system-prompt.test.js +29 -0
- package/dist/agent/__tests__/system-prompt.test.js.map +1 -0
- package/dist/agent/__tests__/trace-format-verbose.test.d.ts +2 -0
- package/dist/agent/__tests__/trace-format-verbose.test.d.ts.map +1 -0
- package/dist/agent/__tests__/trace-format-verbose.test.js +93 -0
- package/dist/agent/__tests__/trace-format-verbose.test.js.map +1 -0
- package/dist/agent/__tests__/verbose-log.test.d.ts +2 -0
- package/dist/agent/__tests__/verbose-log.test.d.ts.map +1 -0
- package/dist/agent/__tests__/verbose-log.test.js +69 -0
- package/dist/agent/__tests__/verbose-log.test.js.map +1 -0
- package/dist/agent/evaluator.d.ts.map +1 -1
- package/dist/agent/evaluator.js +8 -4
- package/dist/agent/evaluator.js.map +1 -1
- package/dist/agent/fleet/orchestrator.d.ts +5 -0
- package/dist/agent/fleet/orchestrator.d.ts.map +1 -1
- package/dist/agent/fleet/orchestrator.js +3 -0
- package/dist/agent/fleet/orchestrator.js.map +1 -1
- package/dist/agent/fleet/types.d.ts +2 -0
- package/dist/agent/fleet/types.d.ts.map +1 -1
- package/dist/agent/judge.d.ts +11 -3
- package/dist/agent/judge.d.ts.map +1 -1
- package/dist/agent/judge.js +15 -3
- package/dist/agent/judge.js.map +1 -1
- package/dist/agent/loop.d.ts +35 -0
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +147 -48
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/model-router.d.ts +5 -19
- package/dist/agent/model-router.d.ts.map +1 -1
- package/dist/agent/model-router.js +19 -42
- package/dist/agent/model-router.js.map +1 -1
- package/dist/agent/permissions.d.ts +103 -0
- package/dist/agent/permissions.d.ts.map +1 -0
- package/dist/agent/permissions.js +245 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/agent/pipeline.d.ts +13 -3
- package/dist/agent/pipeline.d.ts.map +1 -1
- package/dist/agent/pipeline.js +66 -15
- package/dist/agent/pipeline.js.map +1 -1
- package/dist/agent/planner.d.ts +3 -0
- package/dist/agent/planner.d.ts.map +1 -1
- package/dist/agent/planner.js +14 -1
- package/dist/agent/planner.js.map +1 -1
- package/dist/agent/prompt-enhancer.d.ts +9 -0
- package/dist/agent/prompt-enhancer.d.ts.map +1 -1
- package/dist/agent/prompt-enhancer.js +23 -1
- package/dist/agent/prompt-enhancer.js.map +1 -1
- package/dist/agent/rate-card.d.ts +77 -0
- package/dist/agent/rate-card.d.ts.map +1 -0
- package/dist/agent/rate-card.js +99 -0
- package/dist/agent/rate-card.js.map +1 -0
- package/dist/agent/system-prompt.d.ts +5 -0
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +13 -4
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/tools.d.ts +8 -4
- package/dist/agent/tools.d.ts.map +1 -1
- package/dist/agent/tools.js +35 -4
- package/dist/agent/tools.js.map +1 -1
- package/dist/agent/trace-format.d.ts +7 -0
- package/dist/agent/trace-format.d.ts.map +1 -1
- package/dist/agent/trace-format.js +114 -0
- package/dist/agent/trace-format.js.map +1 -1
- package/dist/agent/trace.d.ts +59 -0
- package/dist/agent/trace.d.ts.map +1 -1
- package/dist/agent/verbose-log.d.ts +8 -0
- package/dist/agent/verbose-log.d.ts.map +1 -0
- package/dist/agent/verbose-log.js +53 -0
- package/dist/agent/verbose-log.js.map +1 -0
- package/dist/agents/__tests__/loader.test.d.ts +2 -0
- package/dist/agents/__tests__/loader.test.d.ts.map +1 -0
- package/dist/agents/__tests__/loader.test.js +88 -0
- package/dist/agents/__tests__/loader.test.js.map +1 -0
- package/dist/agents/__tests__/tools.test.d.ts +2 -0
- package/dist/agents/__tests__/tools.test.d.ts.map +1 -0
- package/dist/agents/__tests__/tools.test.js +40 -0
- package/dist/agents/__tests__/tools.test.js.map +1 -0
- package/dist/agents/index.d.ts +12 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +4 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/loader.d.ts +25 -0
- package/dist/agents/loader.d.ts.map +1 -0
- package/dist/agents/loader.js +133 -0
- package/dist/agents/loader.js.map +1 -0
- package/dist/agents/tools.d.ts +14 -0
- package/dist/agents/tools.d.ts.map +1 -0
- package/dist/agents/tools.js +21 -0
- package/dist/agents/tools.js.map +1 -0
- package/dist/agents/types.d.ts +27 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +11 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/agents/write.d.ts +10 -0
- package/dist/agents/write.d.ts.map +1 -0
- package/dist/agents/write.js +28 -0
- package/dist/agents/write.js.map +1 -0
- package/dist/commands/__tests__/agent.test.d.ts +2 -0
- package/dist/commands/__tests__/agent.test.d.ts.map +1 -0
- package/dist/commands/__tests__/agent.test.js +82 -0
- package/dist/commands/__tests__/agent.test.js.map +1 -0
- package/dist/commands/__tests__/command.test.d.ts +2 -0
- package/dist/commands/__tests__/command.test.d.ts.map +1 -0
- package/dist/commands/__tests__/command.test.js +73 -0
- package/dist/commands/__tests__/command.test.js.map +1 -0
- package/dist/commands/__tests__/cost.test.d.ts +2 -0
- package/dist/commands/__tests__/cost.test.d.ts.map +1 -0
- package/dist/commands/__tests__/cost.test.js +139 -0
- package/dist/commands/__tests__/cost.test.js.map +1 -0
- package/dist/commands/__tests__/graph.pull.test.d.ts +2 -0
- package/dist/commands/__tests__/graph.pull.test.d.ts.map +1 -0
- package/dist/commands/__tests__/graph.pull.test.js +259 -0
- package/dist/commands/__tests__/graph.pull.test.js.map +1 -0
- package/dist/commands/__tests__/mcp.test.d.ts +2 -0
- package/dist/commands/__tests__/mcp.test.d.ts.map +1 -0
- package/dist/commands/__tests__/mcp.test.js +88 -0
- package/dist/commands/__tests__/mcp.test.js.map +1 -0
- package/dist/commands/__tests__/rules.test.d.ts +2 -0
- package/dist/commands/__tests__/rules.test.d.ts.map +1 -0
- package/dist/commands/__tests__/rules.test.js +95 -0
- package/dist/commands/__tests__/rules.test.js.map +1 -0
- package/dist/commands/__tests__/settings.test.d.ts +2 -0
- package/dist/commands/__tests__/settings.test.d.ts.map +1 -0
- package/dist/commands/__tests__/settings.test.js +83 -0
- package/dist/commands/__tests__/settings.test.js.map +1 -0
- package/dist/commands/agent.d.ts +15 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +58 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/command.d.ts +17 -0
- package/dist/commands/command.d.ts.map +1 -0
- package/dist/commands/command.js +74 -0
- package/dist/commands/command.js.map +1 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/cost.d.ts +10 -0
- package/dist/commands/cost.d.ts.map +1 -0
- package/dist/commands/cost.js +140 -0
- package/dist/commands/cost.js.map +1 -0
- package/dist/commands/graph.pull.d.ts +15 -0
- package/dist/commands/graph.pull.d.ts.map +1 -0
- package/dist/commands/graph.pull.js +137 -0
- package/dist/commands/graph.pull.js.map +1 -0
- package/dist/commands/graph.status.d.ts +10 -0
- package/dist/commands/graph.status.d.ts.map +1 -0
- package/dist/commands/graph.status.js +75 -0
- package/dist/commands/graph.status.js.map +1 -0
- package/dist/commands/mcp.d.ts +18 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +183 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/rules.d.ts +19 -0
- package/dist/commands/rules.d.ts.map +1 -0
- package/dist/commands/rules.js +96 -0
- package/dist/commands/rules.js.map +1 -0
- package/dist/commands/settings.d.ts +10 -0
- package/dist/commands/settings.d.ts.map +1 -0
- package/dist/commands/settings.js +117 -0
- package/dist/commands/settings.js.map +1 -0
- package/dist/index.js +297 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +2 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/mcp/__tests__/client.test.d.ts +2 -0
- package/dist/mcp/__tests__/client.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/client.test.js +101 -0
- package/dist/mcp/__tests__/client.test.js.map +1 -0
- package/dist/mcp/client.d.ts +89 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +201 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/repl/__tests__/components.test.js +50 -1
- package/dist/repl/__tests__/components.test.js.map +1 -1
- package/dist/repl/components.d.ts +18 -1
- package/dist/repl/components.d.ts.map +1 -1
- package/dist/repl/components.js +32 -2
- package/dist/repl/components.js.map +1 -1
- package/dist/repl/interactive.d.ts +5 -0
- package/dist/repl/interactive.d.ts.map +1 -1
- package/dist/repl/interactive.js +124 -11
- package/dist/repl/interactive.js.map +1 -1
- package/dist/repl/one-shot.d.ts +16 -0
- package/dist/repl/one-shot.d.ts.map +1 -1
- package/dist/repl/one-shot.js +71 -1
- package/dist/repl/one-shot.js.map +1 -1
- package/dist/rules/__tests__/enforce.test.d.ts +2 -0
- package/dist/rules/__tests__/enforce.test.d.ts.map +1 -0
- package/dist/rules/__tests__/enforce.test.js +58 -0
- package/dist/rules/__tests__/enforce.test.js.map +1 -0
- package/dist/rules/__tests__/loader.test.d.ts +2 -0
- package/dist/rules/__tests__/loader.test.d.ts.map +1 -0
- package/dist/rules/__tests__/loader.test.js +54 -0
- package/dist/rules/__tests__/loader.test.js.map +1 -0
- package/dist/rules/enforce.d.ts +23 -0
- package/dist/rules/enforce.d.ts.map +1 -0
- package/dist/rules/enforce.js +36 -0
- package/dist/rules/enforce.js.map +1 -0
- package/dist/rules/index.d.ts +10 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +4 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/loader.d.ts +10 -0
- package/dist/rules/loader.d.ts.map +1 -0
- package/dist/rules/loader.js +77 -0
- package/dist/rules/loader.js.map +1 -0
- package/dist/rules/types.d.ts +39 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +16 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/write.d.ts +10 -0
- package/dist/rules/write.d.ts.map +1 -0
- package/dist/rules/write.js +28 -0
- package/dist/rules/write.js.map +1 -0
- package/dist/settings/__tests__/gate.test.d.ts +2 -0
- package/dist/settings/__tests__/gate.test.d.ts.map +1 -0
- package/dist/settings/__tests__/gate.test.js +137 -0
- package/dist/settings/__tests__/gate.test.js.map +1 -0
- package/dist/settings/__tests__/hooks.test.d.ts +2 -0
- package/dist/settings/__tests__/hooks.test.d.ts.map +1 -0
- package/dist/settings/__tests__/hooks.test.js +103 -0
- package/dist/settings/__tests__/hooks.test.js.map +1 -0
- package/dist/settings/__tests__/mcp-write.test.d.ts +2 -0
- package/dist/settings/__tests__/mcp-write.test.d.ts.map +1 -0
- package/dist/settings/__tests__/mcp-write.test.js +77 -0
- package/dist/settings/__tests__/mcp-write.test.js.map +1 -0
- package/dist/settings/__tests__/permissions-gate.test.d.ts +2 -0
- package/dist/settings/__tests__/permissions-gate.test.d.ts.map +1 -0
- package/dist/settings/__tests__/permissions-gate.test.js +75 -0
- package/dist/settings/__tests__/permissions-gate.test.js.map +1 -0
- package/dist/settings/__tests__/resolve.test.d.ts +2 -0
- package/dist/settings/__tests__/resolve.test.d.ts.map +1 -0
- package/dist/settings/__tests__/resolve.test.js +109 -0
- package/dist/settings/__tests__/resolve.test.js.map +1 -0
- package/dist/settings/__tests__/runtime.test.d.ts +2 -0
- package/dist/settings/__tests__/runtime.test.d.ts.map +1 -0
- package/dist/settings/__tests__/runtime.test.js +72 -0
- package/dist/settings/__tests__/runtime.test.js.map +1 -0
- package/dist/settings/__tests__/schema.test.d.ts +2 -0
- package/dist/settings/__tests__/schema.test.d.ts.map +1 -0
- package/dist/settings/__tests__/schema.test.js +55 -0
- package/dist/settings/__tests__/schema.test.js.map +1 -0
- package/dist/settings/__tests__/write.test.d.ts +2 -0
- package/dist/settings/__tests__/write.test.d.ts.map +1 -0
- package/dist/settings/__tests__/write.test.js +61 -0
- package/dist/settings/__tests__/write.test.js.map +1 -0
- package/dist/settings/gate.d.ts +34 -0
- package/dist/settings/gate.d.ts.map +1 -0
- package/dist/settings/gate.js +50 -0
- package/dist/settings/gate.js.map +1 -0
- package/dist/settings/hooks.d.ts +26 -0
- package/dist/settings/hooks.d.ts.map +1 -0
- package/dist/settings/hooks.js +115 -0
- package/dist/settings/hooks.js.map +1 -0
- package/dist/settings/index.d.ts +23 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +23 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/mcp-write.d.ts +41 -0
- package/dist/settings/mcp-write.d.ts.map +1 -0
- package/dist/settings/mcp-write.js +61 -0
- package/dist/settings/mcp-write.js.map +1 -0
- package/dist/settings/permissions-gate.d.ts +19 -0
- package/dist/settings/permissions-gate.d.ts.map +1 -0
- package/dist/settings/permissions-gate.js +103 -0
- package/dist/settings/permissions-gate.js.map +1 -0
- package/dist/settings/resolve.d.ts +37 -0
- package/dist/settings/resolve.d.ts.map +1 -0
- package/dist/settings/resolve.js +169 -0
- package/dist/settings/resolve.js.map +1 -0
- package/dist/settings/runtime.d.ts +28 -0
- package/dist/settings/runtime.d.ts.map +1 -0
- package/dist/settings/runtime.js +45 -0
- package/dist/settings/runtime.js.map +1 -0
- package/dist/settings/schema.d.ts +1387 -0
- package/dist/settings/schema.d.ts.map +1 -0
- package/dist/settings/schema.js +146 -0
- package/dist/settings/schema.js.map +1 -0
- package/dist/settings/write.d.ts +37 -0
- package/dist/settings/write.d.ts.map +1 -0
- package/dist/settings/write.js +85 -0
- package/dist/settings/write.js.map +1 -0
- package/dist/slash/__tests__/expand.test.d.ts +2 -0
- package/dist/slash/__tests__/expand.test.d.ts.map +1 -0
- package/dist/slash/__tests__/expand.test.js +44 -0
- package/dist/slash/__tests__/expand.test.js.map +1 -0
- package/dist/slash/__tests__/loader.test.d.ts +2 -0
- package/dist/slash/__tests__/loader.test.d.ts.map +1 -0
- package/dist/slash/__tests__/loader.test.js +48 -0
- package/dist/slash/__tests__/loader.test.js.map +1 -0
- package/dist/slash/expand.d.ts +32 -0
- package/dist/slash/expand.d.ts.map +1 -0
- package/dist/slash/expand.js +48 -0
- package/dist/slash/expand.js.map +1 -0
- package/dist/slash/index.d.ts +11 -0
- package/dist/slash/index.d.ts.map +1 -0
- package/dist/slash/index.js +4 -0
- package/dist/slash/index.js.map +1 -0
- package/dist/slash/loader.d.ts +10 -0
- package/dist/slash/loader.d.ts.map +1 -0
- package/dist/slash/loader.js +64 -0
- package/dist/slash/loader.js.map +1 -0
- package/dist/slash/types.d.ts +24 -0
- package/dist/slash/types.d.ts.map +1 -0
- package/dist/slash/types.js +11 -0
- package/dist/slash/types.js.map +1 -0
- package/dist/slash/write.d.ts +10 -0
- package/dist/slash/write.d.ts.map +1 -0
- package/dist/slash/write.js +26 -0
- package/dist/slash/write.js.map +1 -0
- package/dist/tui/fleet-view/index.d.ts.map +1 -1
- package/dist/tui/fleet-view/index.js +5 -1
- package/dist/tui/fleet-view/index.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rules command — manage and test workspace rules.
|
|
3
|
+
*
|
|
4
|
+
* oxagen rules list List rules and which are hard-enforced
|
|
5
|
+
* oxagen rules show <name> Show a rule's text + guard
|
|
6
|
+
* oxagen rules new <name> Scaffold .oxagen/rules/<name>.md
|
|
7
|
+
* oxagen rules check <tool> <subject> Dry-run a tool call against the guards
|
|
8
|
+
*
|
|
9
|
+
* Rules are injected into the agent's system prompt every turn and their guards
|
|
10
|
+
* are hard-enforced at the tool gate.
|
|
11
|
+
*/
|
|
12
|
+
import { type LoadRulesOptions } from "../rules/index.js";
|
|
13
|
+
export type RulesCmdCtx = Pick<LoadRulesOptions, "cwd" | "userRulesDir">;
|
|
14
|
+
export declare function rulesList(ctx?: RulesCmdCtx): void;
|
|
15
|
+
export declare function rulesShow(name: string, ctx?: RulesCmdCtx): void;
|
|
16
|
+
export declare function rulesNew(name: string, ctx?: RulesCmdCtx): void;
|
|
17
|
+
/** Dry-run a proposed tool call against the rule guards (no model, no side effect). */
|
|
18
|
+
export declare function rulesCheck(tool: string, subject: string, ctx?: RulesCmdCtx): void;
|
|
19
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/commands/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAyC,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGjG,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,cAAc,CAAC,CAAC;AAUzE,wBAAgB,SAAS,CAAC,GAAG,GAAE,WAAgB,GAAG,IAAI,CAWrD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAuBnE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAalE;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAkBrF"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rules command — manage and test workspace rules.
|
|
3
|
+
*
|
|
4
|
+
* oxagen rules list List rules and which are hard-enforced
|
|
5
|
+
* oxagen rules show <name> Show a rule's text + guard
|
|
6
|
+
* oxagen rules new <name> Scaffold .oxagen/rules/<name>.md
|
|
7
|
+
* oxagen rules check <tool> <subject> Dry-run a tool call against the guards
|
|
8
|
+
*
|
|
9
|
+
* Rules are injected into the agent's system prompt every turn and their guards
|
|
10
|
+
* are hard-enforced at the tool gate.
|
|
11
|
+
*/
|
|
12
|
+
import { loadRules, guardsToDeny, scaffoldRule } from "../rules/index.js";
|
|
13
|
+
import { evaluateLocalPermission } from "../settings/permissions-gate.js";
|
|
14
|
+
/** Map the friendly `check` tool arg to a CLI tool id + the input field. */
|
|
15
|
+
const TOOL_ALIAS = {
|
|
16
|
+
bash: { tool: "bash", field: "command" },
|
|
17
|
+
edit: { tool: "edit_file", field: "path" },
|
|
18
|
+
write: { tool: "write_file", field: "path" },
|
|
19
|
+
read: { tool: "read_file", field: "path" },
|
|
20
|
+
};
|
|
21
|
+
export function rulesList(ctx = {}) {
|
|
22
|
+
const rules = loadRules(ctx).sort((a, b) => a.id.localeCompare(b.id));
|
|
23
|
+
if (rules.length === 0) {
|
|
24
|
+
console.log("No rules defined. Create one with `oxagen rules new <name>`.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
console.log("Workspace rules:\n");
|
|
28
|
+
for (const r of rules) {
|
|
29
|
+
console.log(` ${r.id}${r.guard ? " [enforced]" : ""}`);
|
|
30
|
+
if (r.description)
|
|
31
|
+
console.log(` ${r.description}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function rulesShow(name, ctx = {}) {
|
|
35
|
+
const rule = loadRules(ctx).find((r) => r.id === name);
|
|
36
|
+
if (!rule) {
|
|
37
|
+
console.error(`Unknown rule "${name}". Run \`oxagen rules list\`.`);
|
|
38
|
+
process.exitCode = 1;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
console.log(`# ${rule.id}`);
|
|
42
|
+
if (rule.description)
|
|
43
|
+
console.log(rule.description);
|
|
44
|
+
console.log(`\nsource: ${rule.source}`);
|
|
45
|
+
if (rule.guard) {
|
|
46
|
+
const g = rule.guard;
|
|
47
|
+
const parts = [
|
|
48
|
+
g.tool ? `tool=${g.tool}` : "",
|
|
49
|
+
g.denyPathGlob ? `denyPath=${g.denyPathGlob}` : "",
|
|
50
|
+
g.denyCommandGlob ? `denyCommand=${g.denyCommandGlob}` : "",
|
|
51
|
+
].filter(Boolean);
|
|
52
|
+
console.log(`guard: ${parts.join(" ")} (hard-enforced)`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.log("guard: (none — prompt-only)");
|
|
56
|
+
}
|
|
57
|
+
console.log("\n--- rule ---\n");
|
|
58
|
+
console.log(rule.text);
|
|
59
|
+
}
|
|
60
|
+
export function rulesNew(name, ctx = {}) {
|
|
61
|
+
if (!/^[A-Za-z0-9][\w-]*$/.test(name)) {
|
|
62
|
+
console.error(`Invalid rule name "${name}". Use letters, digits, dashes, underscores.`);
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { path, created } = scaffoldRule({ name, cwd: ctx.cwd });
|
|
67
|
+
if (created) {
|
|
68
|
+
console.log(`✓ Created rule ${path}`);
|
|
69
|
+
console.log(" Add a guard (guard-tool / guard-deny-path / guard-deny-command) to hard-enforce it.");
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
console.log(`${path} already exists — left untouched.`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Dry-run a proposed tool call against the rule guards (no model, no side effect). */
|
|
76
|
+
export function rulesCheck(tool, subject, ctx = {}) {
|
|
77
|
+
const alias = TOOL_ALIAS[tool.toLowerCase()];
|
|
78
|
+
if (!alias) {
|
|
79
|
+
console.error(`Unknown tool "${tool}". Use one of: ${Object.keys(TOOL_ALIAS).join(", ")}`);
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const { deny, reasons } = guardsToDeny(loadRules(ctx));
|
|
84
|
+
const input = { [alias.field]: subject };
|
|
85
|
+
const result = evaluateLocalPermission(alias.tool, input, { deny });
|
|
86
|
+
if (result.decision === "deny") {
|
|
87
|
+
const why = result.rule ? reasons[result.rule] ?? result.reason : result.reason;
|
|
88
|
+
console.log(`⛔ BLOCKED: ${tool} ${subject}`);
|
|
89
|
+
console.log(` ${why}`);
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.log(`✓ allowed: ${tool} ${subject} (no guard matched)`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/commands/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ResolveSettingsOptions } from "../settings/index.js";
|
|
2
|
+
/** Resolution context shared by every handler (paths come from here in tests). */
|
|
3
|
+
export type SettingsCtx = Pick<ResolveSettingsOptions, "cwd" | "userSettingsPath" | "projectDirName">;
|
|
4
|
+
export declare function settingsShow(ctx?: SettingsCtx): void;
|
|
5
|
+
export declare function settingsPath(ctx?: SettingsCtx): void;
|
|
6
|
+
export declare function settingsGet(key: string, ctx?: SettingsCtx): void;
|
|
7
|
+
export declare function settingsSet(key: string, value: string, scopeArg?: string, ctx?: SettingsCtx): void;
|
|
8
|
+
export declare function settingsValidate(ctx?: SettingsCtx): void;
|
|
9
|
+
export declare function settingsInit(scopeArg?: string, ctx?: SettingsCtx): void;
|
|
10
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/commands/settings.ts"],"names":[],"mappings":"AAiBA,OAAO,EAOL,KAAK,sBAAsB,EAC5B,MAAM,sBAAsB,CAAC;AAI9B,kFAAkF;AAClF,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,EAAE,KAAK,GAAG,kBAAkB,GAAG,gBAAgB,CAAC,CAAC;AAgBtG,wBAAgB,YAAY,CAAC,GAAG,GAAE,WAAgB,GAAG,IAAI,CAaxD;AAED,wBAAgB,YAAY,CAAC,GAAG,GAAE,WAAgB,GAAG,IAAI,CAOxD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAQpE;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,GAAG,GAAE,WAAgB,GACpB,IAAI,CAcN;AAED,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,WAAgB,GAAG,IAAI,CAgB5D;AAED,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAc3E"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* settings command — inspect and edit the unified `settings.json`.
|
|
3
|
+
*
|
|
4
|
+
* oxagen settings Show the merged settings + where each scope lives
|
|
5
|
+
* oxagen settings path List the three scope files and their status
|
|
6
|
+
* oxagen settings get <key> Print a value (dotted, e.g. permissions.defaultMode)
|
|
7
|
+
* oxagen settings set <key> <val> Write a value (model | apiUrl | env.NAME)
|
|
8
|
+
* oxagen settings validate Validate every scope file against the schema
|
|
9
|
+
* oxagen settings init Write a documented starter file (project scope)
|
|
10
|
+
*
|
|
11
|
+
* `set` / `init` target a single scope (default: project) so the user/project/
|
|
12
|
+
* local layering stays meaningful.
|
|
13
|
+
*
|
|
14
|
+
* Every handler accepts an optional resolution context (cwd / userSettingsPath)
|
|
15
|
+
* so the command is exercisable in tests without touching the real `~/.config`.
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync } from "node:fs";
|
|
18
|
+
import { loadSettings, getScopePaths, writeSettingsValue, writeStarterSettings, } from "../settings/index.js";
|
|
19
|
+
const SCOPES = ["user", "project", "local"];
|
|
20
|
+
function isScope(value) {
|
|
21
|
+
return SCOPES.includes(value);
|
|
22
|
+
}
|
|
23
|
+
/** Navigate a dotted path (e.g. "permissions.defaultMode") into the settings. */
|
|
24
|
+
function getByPath(settings, key) {
|
|
25
|
+
let cur = settings;
|
|
26
|
+
for (const part of key.split(".")) {
|
|
27
|
+
if (cur === null || typeof cur !== "object")
|
|
28
|
+
return undefined;
|
|
29
|
+
cur = cur[part];
|
|
30
|
+
}
|
|
31
|
+
return cur;
|
|
32
|
+
}
|
|
33
|
+
export function settingsShow(ctx = {}) {
|
|
34
|
+
const { settings, scopes } = loadSettings({ ...ctx, noCache: true });
|
|
35
|
+
console.log("Effective settings (merged user → project → local):\n");
|
|
36
|
+
console.log(JSON.stringify(settings, null, 2));
|
|
37
|
+
const present = scopes.filter((s) => s.settings || s.error);
|
|
38
|
+
console.log("\nScopes:");
|
|
39
|
+
if (present.length === 0) {
|
|
40
|
+
console.log(" (no settings files found — run `oxagen settings init`)");
|
|
41
|
+
}
|
|
42
|
+
for (const s of present) {
|
|
43
|
+
const status = s.error ? `⚠ ${s.error}` : "ok";
|
|
44
|
+
console.log(` ${s.scope.padEnd(8)} ${s.path} [${status}]`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function settingsPath(ctx = {}) {
|
|
48
|
+
const paths = getScopePaths(ctx);
|
|
49
|
+
console.log("Settings scope files (lowest → highest precedence):\n");
|
|
50
|
+
for (const scope of SCOPES) {
|
|
51
|
+
const path = paths[scope];
|
|
52
|
+
console.log(` ${scope.padEnd(8)} ${path} ${existsSync(path) ? "(exists)" : "(absent)"}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function settingsGet(key, ctx = {}) {
|
|
56
|
+
const { settings } = loadSettings({ ...ctx, noCache: true });
|
|
57
|
+
const value = getByPath(settings, key);
|
|
58
|
+
if (value === undefined) {
|
|
59
|
+
console.log(`${key}: (not set)`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
console.log(`${key}: ${typeof value === "string" ? value : JSON.stringify(value)}`);
|
|
63
|
+
}
|
|
64
|
+
export function settingsSet(key, value, scopeArg, ctx = {}) {
|
|
65
|
+
const scope = scopeArg ?? "project";
|
|
66
|
+
if (!isScope(scope)) {
|
|
67
|
+
console.error(`Unknown scope "${scope}". Use one of: ${SCOPES.join(", ")}`);
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const path = writeSettingsValue({ ...ctx, scope, key, value });
|
|
73
|
+
console.log(`✓ ${key} = ${value} (${scope}: ${path})`);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export function settingsValidate(ctx = {}) {
|
|
81
|
+
const { scopes } = loadSettings({ ...ctx, noCache: true });
|
|
82
|
+
let ok = true;
|
|
83
|
+
let checked = 0;
|
|
84
|
+
for (const s of scopes) {
|
|
85
|
+
if (!s.settings && !s.error)
|
|
86
|
+
continue; // absent file — nothing to validate
|
|
87
|
+
checked++;
|
|
88
|
+
if (s.error) {
|
|
89
|
+
ok = false;
|
|
90
|
+
console.error(`✗ ${s.scope} (${s.path}): ${s.error}`);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.log(`✓ ${s.scope} (${s.path})`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (checked === 0)
|
|
97
|
+
console.log("No settings files found.");
|
|
98
|
+
if (!ok)
|
|
99
|
+
process.exitCode = 1;
|
|
100
|
+
}
|
|
101
|
+
export function settingsInit(scopeArg, ctx = {}) {
|
|
102
|
+
const scope = scopeArg ?? "project";
|
|
103
|
+
if (!isScope(scope)) {
|
|
104
|
+
console.error(`Unknown scope "${scope}". Use one of: ${SCOPES.join(", ")}`);
|
|
105
|
+
process.exitCode = 1;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const { path, created } = writeStarterSettings({ ...ctx, scope });
|
|
109
|
+
if (created) {
|
|
110
|
+
console.log(`✓ Wrote starter settings to ${path}`);
|
|
111
|
+
console.log(" Edit it to add permissions, hooks, env, and MCP servers.");
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.log(`${path} already exists — left untouched.`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/commands/settings.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import { Command } from "commander";
|
|
15
15
|
import pkg from "../package.json" with { type: "json" };
|
|
16
|
+
import { parseModeArg } from "./agent/permissions.js";
|
|
16
17
|
// The Oxagen context engine pulls in DuckDB, a native CommonJS dependency that
|
|
17
18
|
// references a bare `require`. Under pure-ESM execution that global is absent, so
|
|
18
19
|
// loading the store throws "require is not defined". Provide the shim before any
|
|
@@ -30,15 +31,40 @@ program
|
|
|
30
31
|
.version(version)
|
|
31
32
|
.argument("[prompt...]", "One-shot prompt (runs and exits)")
|
|
32
33
|
.option("-m, --model <slug>", "Gateway model slug (overrides config/default)")
|
|
34
|
+
.option("--agent <name>", "Run the one-shot prompt as a named agent definition")
|
|
33
35
|
.option("--readonly", "Read-only mode: read/search/explain only — no file edits or commands", false)
|
|
36
|
+
.option("--mode <mode>", "Permission mode: ask | accept-edits | bypass | readonly (REPL default: ask; one-shot ungated unless set)")
|
|
34
37
|
.option("--no-pipeline", "Skip prompt evaluation, context injection, and completeness judging")
|
|
38
|
+
.option("--verbose", "Capture + emit full per-turn telemetry (per-phase timing, model+token+cost, tool results)", false)
|
|
35
39
|
.action(async (promptWords, opts) => {
|
|
36
40
|
const prompt = promptWords.join(" ").trim();
|
|
41
|
+
let mode;
|
|
42
|
+
if (opts.mode) {
|
|
43
|
+
mode = parseModeArg(opts.mode);
|
|
44
|
+
if (!mode) {
|
|
45
|
+
process.stderr.write(`Error: invalid --mode "${opts.mode}". Use ask, accept-edits, bypass, or readonly.\n`);
|
|
46
|
+
process.exitCode = 1;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
37
50
|
const runOpts = {
|
|
38
51
|
model: opts.model,
|
|
39
52
|
readOnly: opts.readonly,
|
|
53
|
+
mode,
|
|
40
54
|
bare: opts.pipeline === false,
|
|
55
|
+
verbose: opts.verbose,
|
|
41
56
|
};
|
|
57
|
+
// --agent: run the prompt as a named agent (its prompt, tools, model).
|
|
58
|
+
if (opts.agent) {
|
|
59
|
+
if (!prompt) {
|
|
60
|
+
process.stderr.write("Error: --agent requires a prompt, e.g. `oxagen --agent reviewer \"…\"`.\n");
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const { runAgentOneShot } = await import("./repl/one-shot.js");
|
|
65
|
+
await runAgentOneShot(prompt, opts.agent, runOpts);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
42
68
|
if (prompt) {
|
|
43
69
|
// One-shot mode: run prompt, stream response, exit
|
|
44
70
|
const { runOneShot } = await import("./repl/one-shot.js");
|
|
@@ -117,7 +143,23 @@ program
|
|
|
117
143
|
const { handleReplay } = await import("./commands/replay.js");
|
|
118
144
|
await handleReplay(turn, opts);
|
|
119
145
|
});
|
|
120
|
-
// ──
|
|
146
|
+
// ── cost: project + report model cost from the baked-in rate card ─────────────
|
|
147
|
+
program
|
|
148
|
+
.command("cost")
|
|
149
|
+
// The root's global `-m, --model` is reused (commander binds it to the parent),
|
|
150
|
+
// so the action reads merged opts via optsWithGlobals() to see --model here.
|
|
151
|
+
.description("Project model cost from the baked-in rate card, or roll up this project's spend")
|
|
152
|
+
.option("--in <tokens>", "Input token count to price", (v) => parseInt(v, 10))
|
|
153
|
+
.option("--out <tokens>", "Output token count to price", (v) => parseInt(v, 10))
|
|
154
|
+
.option("--rates", "Print the baked-in rate card", false)
|
|
155
|
+
.option("--session", "Roll up what this project's recorded turns actually cost, by model", false)
|
|
156
|
+
.option("--json", "Output JSON", false)
|
|
157
|
+
.action(async (_opts, command) => {
|
|
158
|
+
const merged = command.optsWithGlobals();
|
|
159
|
+
const { handleCost } = await import("./commands/cost.js");
|
|
160
|
+
await handleCost(merged);
|
|
161
|
+
});
|
|
162
|
+
// ── graph: knowledge-graph search + pull + status ─────────────────────────────
|
|
121
163
|
const graph = program.command("graph").description("Query the knowledge graph");
|
|
122
164
|
graph
|
|
123
165
|
.command("search")
|
|
@@ -132,6 +174,30 @@ graph
|
|
|
132
174
|
const { handleGraphSearch } = await import("./commands/graph.search.js");
|
|
133
175
|
await handleGraphSearch(opts);
|
|
134
176
|
});
|
|
177
|
+
graph
|
|
178
|
+
.command("pull")
|
|
179
|
+
.description("Download an incremental snapshot of the workspace graph into a local DuckDB replica")
|
|
180
|
+
.option("--full", "Ignore the saved cursor and re-pull the entire graph", false)
|
|
181
|
+
.option("-l, --labels <csv>", "Comma-separated domain labels to filter (e.g. Person,SourceFile)")
|
|
182
|
+
.option("--no-system", "Exclude product-owned (system) nodes")
|
|
183
|
+
.option("--json", "Output summary as JSON")
|
|
184
|
+
.action(async (opts) => {
|
|
185
|
+
const { handleGraphPull } = await import("./commands/graph.pull.js");
|
|
186
|
+
await handleGraphPull({
|
|
187
|
+
full: opts.full,
|
|
188
|
+
labels: opts.labels,
|
|
189
|
+
noSystem: opts.system === false,
|
|
190
|
+
json: opts.json,
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
graph
|
|
194
|
+
.command("status")
|
|
195
|
+
.description("Show the state of the local workspace-graph replica")
|
|
196
|
+
.option("--json", "Output as JSON")
|
|
197
|
+
.action(async (opts) => {
|
|
198
|
+
const { handleGraphStatus } = await import("./commands/graph.status.js");
|
|
199
|
+
await handleGraphStatus(opts);
|
|
200
|
+
});
|
|
135
201
|
// ── config: local configuration ───────────────────────────────────────────────
|
|
136
202
|
program
|
|
137
203
|
.command("config")
|
|
@@ -142,6 +208,232 @@ program
|
|
|
142
208
|
const { handleConfig } = await import("./commands/config.js");
|
|
143
209
|
await handleConfig(key, value);
|
|
144
210
|
});
|
|
211
|
+
// ── settings: the unified settings.json driver ────────────────────────────────
|
|
212
|
+
const settings = program
|
|
213
|
+
.command("settings")
|
|
214
|
+
.description("Inspect and edit the unified settings.json (model, env, permissions, hooks, MCP)")
|
|
215
|
+
.action(async () => {
|
|
216
|
+
const { settingsShow } = await import("./commands/settings.js");
|
|
217
|
+
settingsShow();
|
|
218
|
+
});
|
|
219
|
+
settings
|
|
220
|
+
.command("show")
|
|
221
|
+
.description("Show the merged settings and which scope each file lives in")
|
|
222
|
+
.action(async () => {
|
|
223
|
+
const { settingsShow } = await import("./commands/settings.js");
|
|
224
|
+
settingsShow();
|
|
225
|
+
});
|
|
226
|
+
settings
|
|
227
|
+
.command("path")
|
|
228
|
+
.description("List the three scope files (user / project / local) and their status")
|
|
229
|
+
.action(async () => {
|
|
230
|
+
const { settingsPath } = await import("./commands/settings.js");
|
|
231
|
+
settingsPath();
|
|
232
|
+
});
|
|
233
|
+
settings
|
|
234
|
+
.command("get")
|
|
235
|
+
.description("Print a value by dotted key (e.g. permissions.defaultMode)")
|
|
236
|
+
.argument("<key>", "Dotted settings key")
|
|
237
|
+
.action(async (key) => {
|
|
238
|
+
const { settingsGet } = await import("./commands/settings.js");
|
|
239
|
+
settingsGet(key);
|
|
240
|
+
});
|
|
241
|
+
settings
|
|
242
|
+
.command("set")
|
|
243
|
+
.description("Set a value (model | apiUrl | env.NAME) in a scope")
|
|
244
|
+
.argument("<key>", "model, apiUrl, or env.NAME")
|
|
245
|
+
.argument("<value>", "Value to write")
|
|
246
|
+
.option("--scope <scope>", "user | project | local (default: project)")
|
|
247
|
+
.action(async (key, value, opts) => {
|
|
248
|
+
const { settingsSet } = await import("./commands/settings.js");
|
|
249
|
+
settingsSet(key, value, opts.scope);
|
|
250
|
+
});
|
|
251
|
+
settings
|
|
252
|
+
.command("validate")
|
|
253
|
+
.description("Validate every scope file against the settings schema")
|
|
254
|
+
.action(async () => {
|
|
255
|
+
const { settingsValidate } = await import("./commands/settings.js");
|
|
256
|
+
settingsValidate();
|
|
257
|
+
});
|
|
258
|
+
settings
|
|
259
|
+
.command("init")
|
|
260
|
+
.description("Write a documented starter settings.json (default: project scope)")
|
|
261
|
+
.option("--scope <scope>", "user | project | local (default: project)")
|
|
262
|
+
.action(async (opts) => {
|
|
263
|
+
const { settingsInit } = await import("./commands/settings.js");
|
|
264
|
+
settingsInit(opts.scope);
|
|
265
|
+
});
|
|
266
|
+
// ── agent: named agent definitions ────────────────────────────────────────────
|
|
267
|
+
const agent = program
|
|
268
|
+
.command("agent")
|
|
269
|
+
.description("Manage named agent definitions (run one with `oxagen --agent <name> \"…\"`)");
|
|
270
|
+
agent
|
|
271
|
+
.command("list")
|
|
272
|
+
.description("List available agents")
|
|
273
|
+
.action(async () => {
|
|
274
|
+
const { agentList } = await import("./commands/agent.js");
|
|
275
|
+
agentList();
|
|
276
|
+
});
|
|
277
|
+
agent
|
|
278
|
+
.command("show")
|
|
279
|
+
.description("Show an agent's definition and system prompt")
|
|
280
|
+
.argument("<name>", "Agent name")
|
|
281
|
+
.action(async (name) => {
|
|
282
|
+
const { agentShow } = await import("./commands/agent.js");
|
|
283
|
+
agentShow(name);
|
|
284
|
+
});
|
|
285
|
+
agent
|
|
286
|
+
.command("new")
|
|
287
|
+
.description("Scaffold a new agent at .oxagen/agents/<name>.md")
|
|
288
|
+
.argument("<name>", "Agent name")
|
|
289
|
+
.action(async (name) => {
|
|
290
|
+
const { agentNew } = await import("./commands/agent.js");
|
|
291
|
+
agentNew(name);
|
|
292
|
+
});
|
|
293
|
+
// ── command: user-defined slash commands ──────────────────────────────────────
|
|
294
|
+
const command = program
|
|
295
|
+
.command("command")
|
|
296
|
+
.description("Manage user-defined slash commands (invoke as `/name` in the REPL)");
|
|
297
|
+
command
|
|
298
|
+
.command("list")
|
|
299
|
+
.description("List available slash commands")
|
|
300
|
+
.action(async () => {
|
|
301
|
+
const { commandList } = await import("./commands/command.js");
|
|
302
|
+
commandList();
|
|
303
|
+
});
|
|
304
|
+
command
|
|
305
|
+
.command("show")
|
|
306
|
+
.description("Show a slash command's template")
|
|
307
|
+
.argument("<name>", "Command name")
|
|
308
|
+
.action(async (name) => {
|
|
309
|
+
const { commandShow } = await import("./commands/command.js");
|
|
310
|
+
commandShow(name);
|
|
311
|
+
});
|
|
312
|
+
command
|
|
313
|
+
.command("new")
|
|
314
|
+
.description("Scaffold a new slash command at .oxagen/commands/<name>.md")
|
|
315
|
+
.argument("<name>", "Command name")
|
|
316
|
+
.action(async (name) => {
|
|
317
|
+
const { commandNew } = await import("./commands/command.js");
|
|
318
|
+
commandNew(name);
|
|
319
|
+
});
|
|
320
|
+
command
|
|
321
|
+
.command("run")
|
|
322
|
+
.description("Expand a slash command's template with args and run it as a turn")
|
|
323
|
+
.argument("<name>", "Command name")
|
|
324
|
+
.argument("[args...]", "Arguments substituted into the template")
|
|
325
|
+
.action(async (name, args) => {
|
|
326
|
+
const { commandRun } = await import("./commands/command.js");
|
|
327
|
+
await commandRun(name, args ?? []);
|
|
328
|
+
});
|
|
329
|
+
// ── rules: workspace rules the agent must follow ──────────────────────────────
|
|
330
|
+
const rules = program
|
|
331
|
+
.command("rules")
|
|
332
|
+
.description("Manage workspace rules the agent is told about and hard-blocked from violating");
|
|
333
|
+
rules
|
|
334
|
+
.command("list")
|
|
335
|
+
.description("List rules (and which are hard-enforced)")
|
|
336
|
+
.action(async () => {
|
|
337
|
+
const { rulesList } = await import("./commands/rules.js");
|
|
338
|
+
rulesList();
|
|
339
|
+
});
|
|
340
|
+
rules
|
|
341
|
+
.command("show")
|
|
342
|
+
.description("Show a rule's text and guard")
|
|
343
|
+
.argument("<name>", "Rule name")
|
|
344
|
+
.action(async (name) => {
|
|
345
|
+
const { rulesShow } = await import("./commands/rules.js");
|
|
346
|
+
rulesShow(name);
|
|
347
|
+
});
|
|
348
|
+
rules
|
|
349
|
+
.command("new")
|
|
350
|
+
.description("Scaffold a new rule at .oxagen/rules/<name>.md")
|
|
351
|
+
.argument("<name>", "Rule name")
|
|
352
|
+
.action(async (name) => {
|
|
353
|
+
const { rulesNew } = await import("./commands/rules.js");
|
|
354
|
+
rulesNew(name);
|
|
355
|
+
});
|
|
356
|
+
rules
|
|
357
|
+
.command("check")
|
|
358
|
+
.description("Dry-run a proposed tool call against the guards (bash|edit|write|read)")
|
|
359
|
+
.argument("<tool>", "bash | edit | write | read")
|
|
360
|
+
.argument("<subject>", "The command (bash) or path (edit/write/read) to test")
|
|
361
|
+
.action(async (tool, subject) => {
|
|
362
|
+
const { rulesCheck } = await import("./commands/rules.js");
|
|
363
|
+
rulesCheck(tool, subject);
|
|
364
|
+
});
|
|
365
|
+
// ── mcp: external MCP servers ─────────────────────────────────────────────────
|
|
366
|
+
const collect = (val, prev) => prev.concat([val]);
|
|
367
|
+
const mcp = program
|
|
368
|
+
.command("mcp")
|
|
369
|
+
.description("Manage external MCP servers the agent loop connects to");
|
|
370
|
+
mcp
|
|
371
|
+
.command("add")
|
|
372
|
+
.description("Add an MCP server (stdio via --command, or http/sse/websocket via --url)")
|
|
373
|
+
.argument("<name>", "Server name (used in tool names: mcp__<name>__<tool>)")
|
|
374
|
+
.option("--command <command>", "stdio: the command to spawn (e.g. npx)")
|
|
375
|
+
.option("--arg <arg>", "stdio: a command argument (repeatable)", collect, [])
|
|
376
|
+
.option("--url <url>", "http/sse/websocket: the server URL")
|
|
377
|
+
.option("--transport <transport>", "streamable-http | sse | websocket (default streamable-http)")
|
|
378
|
+
.option("--auth <auth>", "none | bearer | header (default none)")
|
|
379
|
+
.option("--env-token <VAR>", "Env var holding the bearer token")
|
|
380
|
+
.option("--header <KEY=VALUE>", "Static header for header auth (repeatable)", collect, [])
|
|
381
|
+
.option("--scope <scope>", "user | project | local (default project)")
|
|
382
|
+
.action(async (name, opts) => {
|
|
383
|
+
const { mcpAdd } = await import("./commands/mcp.js");
|
|
384
|
+
mcpAdd(name, {
|
|
385
|
+
command: opts["command"],
|
|
386
|
+
arg: opts["arg"],
|
|
387
|
+
url: opts["url"],
|
|
388
|
+
transport: opts["transport"],
|
|
389
|
+
auth: opts["auth"],
|
|
390
|
+
envToken: opts["envToken"],
|
|
391
|
+
header: opts["header"],
|
|
392
|
+
scope: opts["scope"],
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
mcp
|
|
396
|
+
.command("list")
|
|
397
|
+
.description("List configured MCP servers")
|
|
398
|
+
.action(async () => {
|
|
399
|
+
const { mcpList } = await import("./commands/mcp.js");
|
|
400
|
+
mcpList();
|
|
401
|
+
});
|
|
402
|
+
mcp
|
|
403
|
+
.command("remove")
|
|
404
|
+
.description("Remove an MCP server")
|
|
405
|
+
.argument("<name>", "Server name")
|
|
406
|
+
.option("--scope <scope>", "Limit to a scope (default: auto-detect)")
|
|
407
|
+
.action(async (name, opts) => {
|
|
408
|
+
const { mcpRemove } = await import("./commands/mcp.js");
|
|
409
|
+
mcpRemove(name, opts.scope);
|
|
410
|
+
});
|
|
411
|
+
mcp
|
|
412
|
+
.command("enable")
|
|
413
|
+
.description("Enable a disabled MCP server")
|
|
414
|
+
.argument("<name>", "Server name")
|
|
415
|
+
.option("--scope <scope>", "Limit to a scope (default: auto-detect)")
|
|
416
|
+
.action(async (name, opts) => {
|
|
417
|
+
const { mcpSetEnabled } = await import("./commands/mcp.js");
|
|
418
|
+
mcpSetEnabled(name, true, opts.scope);
|
|
419
|
+
});
|
|
420
|
+
mcp
|
|
421
|
+
.command("disable")
|
|
422
|
+
.description("Disable an MCP server without removing it")
|
|
423
|
+
.argument("<name>", "Server name")
|
|
424
|
+
.option("--scope <scope>", "Limit to a scope (default: auto-detect)")
|
|
425
|
+
.action(async (name, opts) => {
|
|
426
|
+
const { mcpSetEnabled } = await import("./commands/mcp.js");
|
|
427
|
+
mcpSetEnabled(name, false, opts.scope);
|
|
428
|
+
});
|
|
429
|
+
mcp
|
|
430
|
+
.command("check")
|
|
431
|
+
.description("Connect to a server (or all enabled) and preview the tools it exposes")
|
|
432
|
+
.argument("[name]", "Server name (omit to check all enabled)")
|
|
433
|
+
.action(async (name) => {
|
|
434
|
+
const { mcpCheck } = await import("./commands/mcp.js");
|
|
435
|
+
await mcpCheck(name);
|
|
436
|
+
});
|
|
145
437
|
// ── env: workspace environments ───────────────────────────────────────────────
|
|
146
438
|
const env = program.command("env").description("Manage workspace environments");
|
|
147
439
|
env
|
|
@@ -264,6 +556,10 @@ secret
|
|
|
264
556
|
await handleSecretExport(opts);
|
|
265
557
|
});
|
|
266
558
|
async function main() {
|
|
559
|
+
// Project settings.json (env, apiUrl, model) into the environment before any
|
|
560
|
+
// command runs — filling only unset vars, so the shell always wins.
|
|
561
|
+
const { applySettingsToEnv } = await import("./settings/runtime.js");
|
|
562
|
+
applySettingsToEnv();
|
|
267
563
|
await program.parseAsync(process.argv);
|
|
268
564
|
}
|
|
269
565
|
void main();
|