@intutic/cli 2.0.0 → 2.2.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/dist/cli.js +131 -130
- package/dist/cli.js.map +1 -1
- package/dist/commands/attenuate.d.ts.map +1 -1
- package/dist/commands/attenuate.js +4 -2
- package/dist/commands/attenuate.js.map +1 -1
- package/dist/commands/budget.d.ts.map +1 -1
- package/dist/commands/budget.js +2 -2
- package/dist/commands/budget.js.map +1 -1
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +138 -49
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/disconnect.d.ts +25 -0
- package/dist/commands/disconnect.d.ts.map +1 -0
- package/dist/commands/disconnect.js +252 -0
- package/dist/commands/disconnect.js.map +1 -0
- package/dist/commands/doctor.d.ts +19 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +33 -41
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/enforce.d.ts +10 -0
- package/dist/commands/enforce.d.ts.map +1 -1
- package/dist/commands/enforce.js +36 -0
- package/dist/commands/enforce.js.map +1 -1
- package/dist/commands/env.d.ts +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +2 -7
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/exec.d.ts +7 -8
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/exec.js +59 -60
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/gateway.d.ts +2 -0
- package/dist/commands/gateway.d.ts.map +1 -1
- package/dist/commands/gateway.js +16 -3
- package/dist/commands/gateway.js.map +1 -1
- package/dist/commands/guardrails.d.ts.map +1 -1
- package/dist/commands/guardrails.js +18 -1
- package/dist/commands/guardrails.js.map +1 -1
- package/dist/commands/init.d.ts +5 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +38 -22
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install-daemon.d.ts +1 -1
- package/dist/commands/install-daemon.d.ts.map +1 -1
- package/dist/commands/install-daemon.js +5 -3
- package/dist/commands/install-daemon.js.map +1 -1
- package/dist/commands/integrity.d.ts +31 -2
- package/dist/commands/integrity.d.ts.map +1 -1
- package/dist/commands/integrity.js +116 -3
- package/dist/commands/integrity.js.map +1 -1
- package/dist/commands/judge.d.ts +8 -4
- package/dist/commands/judge.d.ts.map +1 -1
- package/dist/commands/judge.js +41 -21
- package/dist/commands/judge.js.map +1 -1
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +16 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/predict-cost.d.ts +1 -2
- package/dist/commands/predict-cost.d.ts.map +1 -1
- package/dist/commands/predict-cost.js +1 -4
- package/dist/commands/predict-cost.js.map +1 -1
- package/dist/commands/setup.d.ts +1 -2
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +11 -68
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/skill.d.ts +1 -0
- package/dist/commands/skill.d.ts.map +1 -1
- package/dist/commands/skill.js +17 -3
- package/dist/commands/skill.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +5 -1
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/syncContext.d.ts.map +1 -1
- package/dist/commands/syncContext.js +15 -5
- package/dist/commands/syncContext.js.map +1 -1
- package/dist/config/paths.d.ts +25 -3
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +47 -7
- package/dist/config/paths.js.map +1 -1
- package/dist/harness/agentFramework.d.ts +25 -0
- package/dist/harness/agentFramework.d.ts.map +1 -0
- package/dist/harness/agentFramework.js +37 -0
- package/dist/harness/agentFramework.js.map +1 -0
- package/dist/harness/agentcore.d.ts +6 -3
- package/dist/harness/agentcore.d.ts.map +1 -1
- package/dist/harness/agentcore.js +7 -4
- package/dist/harness/agentcore.js.map +1 -1
- package/dist/harness/agenticOrchestrator.d.ts +3 -5
- package/dist/harness/agenticOrchestrator.d.ts.map +1 -1
- package/dist/harness/agenticOrchestrator.js +3 -5
- package/dist/harness/agenticOrchestrator.js.map +1 -1
- package/dist/harness/aiSdkHarness.d.ts +1 -1
- package/dist/harness/aiSdkHarness.js +1 -1
- package/dist/harness/aiSdkWorkflow.d.ts +1 -1
- package/dist/harness/aiSdkWorkflow.d.ts.map +1 -1
- package/dist/harness/aiSdkWorkflow.js +5 -3
- package/dist/harness/aiSdkWorkflow.js.map +1 -1
- package/dist/harness/aider.d.ts +4 -3
- package/dist/harness/aider.d.ts.map +1 -1
- package/dist/harness/aider.js +7 -6
- package/dist/harness/aider.js.map +1 -1
- package/dist/harness/antigravity.d.ts +4 -2
- package/dist/harness/antigravity.d.ts.map +1 -1
- package/dist/harness/antigravity.js +15 -12
- package/dist/harness/antigravity.js.map +1 -1
- package/dist/harness/base.d.ts +5 -1
- package/dist/harness/base.d.ts.map +1 -1
- package/dist/harness/base.js +9 -8
- package/dist/harness/base.js.map +1 -1
- package/dist/harness/cline.d.ts +10 -4
- package/dist/harness/cline.d.ts.map +1 -1
- package/dist/harness/cline.js +40 -32
- package/dist/harness/cline.js.map +1 -1
- package/dist/harness/codex.d.ts +10 -4
- package/dist/harness/codex.d.ts.map +1 -1
- package/dist/harness/codex.js +30 -32
- package/dist/harness/codex.js.map +1 -1
- package/dist/harness/continue.d.ts +8 -5
- package/dist/harness/continue.d.ts.map +1 -1
- package/dist/harness/continue.js +27 -63
- package/dist/harness/continue.js.map +1 -1
- package/dist/harness/cursor.d.ts.map +1 -1
- package/dist/harness/cursor.js +2 -6
- package/dist/harness/cursor.js.map +1 -1
- package/dist/harness/detector.d.ts +1 -1
- package/dist/harness/detector.d.ts.map +1 -1
- package/dist/harness/detector.js +3 -1
- package/dist/harness/detector.js.map +1 -1
- package/dist/harness/dsh.d.ts +2 -2
- package/dist/harness/dsh.js +3 -3
- package/dist/harness/dsh.js.map +1 -1
- package/dist/harness/eve.d.ts +1 -1
- package/dist/harness/eve.js +1 -1
- package/dist/harness/githubCopilot.d.ts +4 -2
- package/dist/harness/githubCopilot.d.ts.map +1 -1
- package/dist/harness/githubCopilot.js +13 -8
- package/dist/harness/githubCopilot.js.map +1 -1
- package/dist/harness/grok.d.ts.map +1 -1
- package/dist/harness/grok.js +4 -6
- package/dist/harness/grok.js.map +1 -1
- package/dist/harness/jsSdkGatedAdapter.d.ts.map +1 -1
- package/dist/harness/jsSdkGatedAdapter.js +8 -9
- package/dist/harness/jsSdkGatedAdapter.js.map +1 -1
- package/dist/harness/langgraph.d.ts.map +1 -1
- package/dist/harness/langgraph.js +8 -10
- package/dist/harness/langgraph.js.map +1 -1
- package/dist/harness/muse.d.ts.map +1 -1
- package/dist/harness/muse.js +4 -6
- package/dist/harness/muse.js.map +1 -1
- package/dist/harness/n8n.d.ts +12 -2
- package/dist/harness/n8n.d.ts.map +1 -1
- package/dist/harness/n8n.js +66 -3
- package/dist/harness/n8n.js.map +1 -1
- package/dist/harness/openWebUI.d.ts +7 -2
- package/dist/harness/openWebUI.d.ts.map +1 -1
- package/dist/harness/openWebUI.js +15 -4
- package/dist/harness/openWebUI.js.map +1 -1
- package/dist/harness/openaiAgents.d.ts.map +1 -1
- package/dist/harness/openaiAgents.js +4 -1
- package/dist/harness/openaiAgents.js.map +1 -1
- package/dist/harness/opencode.d.ts +3 -2
- package/dist/harness/opencode.d.ts.map +1 -1
- package/dist/harness/opencode.js +7 -8
- package/dist/harness/opencode.js.map +1 -1
- package/dist/harness/openhands.d.ts +3 -2
- package/dist/harness/openhands.d.ts.map +1 -1
- package/dist/harness/openhands.js +40 -27
- package/dist/harness/openhands.js.map +1 -1
- package/dist/harness/rooCode.d.ts +6 -5
- package/dist/harness/rooCode.d.ts.map +1 -1
- package/dist/harness/rooCode.js +13 -18
- package/dist/harness/rooCode.js.map +1 -1
- package/dist/harness/sdkGatedAdapter.d.ts.map +1 -1
- package/dist/harness/sdkGatedAdapter.js +8 -9
- package/dist/harness/sdkGatedAdapter.js.map +1 -1
- package/dist/harness/trueforge.js +2 -2
- package/dist/harness/trueforge.js.map +1 -1
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js +4 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/windsurf.d.ts +4 -2
- package/dist/harness/windsurf.d.ts.map +1 -1
- package/dist/harness/windsurf.js +14 -11
- package/dist/harness/windsurf.js.map +1 -1
- package/dist/harness/xirp.d.ts +5 -7
- package/dist/harness/xirp.d.ts.map +1 -1
- package/dist/harness/xirp.js +5 -7
- package/dist/harness/xirp.js.map +1 -1
- package/dist/lib/envInjector.d.ts +16 -6
- package/dist/lib/envInjector.d.ts.map +1 -1
- package/dist/lib/envInjector.js +99 -88
- package/dist/lib/envInjector.js.map +1 -1
- package/dist/lib/localProxy.d.ts +19 -0
- package/dist/lib/localProxy.d.ts.map +1 -0
- package/dist/lib/localProxy.js +33 -0
- package/dist/lib/localProxy.js.map +1 -0
- package/dist/lib/onboarding.d.ts +1 -1
- package/dist/lib/onboarding.d.ts.map +1 -1
- package/dist/lib/onboarding.js +21 -27
- package/dist/lib/onboarding.js.map +1 -1
- package/dist/lib/otelPropagation.d.ts +1 -1
- package/dist/lib/otelPropagation.js +1 -1
- package/dist/lib/policySnapshot.d.ts +2 -1
- package/dist/lib/policySnapshot.d.ts.map +1 -1
- package/dist/lib/policySnapshot.js +11 -4
- package/dist/lib/policySnapshot.js.map +1 -1
- package/dist/lib/sandbox/image.d.ts +27 -0
- package/dist/lib/sandbox/image.d.ts.map +1 -0
- package/dist/lib/sandbox/image.js +54 -0
- package/dist/lib/sandbox/image.js.map +1 -0
- package/dist/lib/sandbox/oci.d.ts +1 -0
- package/dist/lib/sandbox/oci.d.ts.map +1 -1
- package/dist/lib/sandbox/oci.js +4 -0
- package/dist/lib/sandbox/oci.js.map +1 -1
- package/dist/lib/sandbox/types.d.ts +5 -0
- package/dist/lib/sandbox/types.d.ts.map +1 -1
- package/package.json +6 -5
- package/resources/sandbox/Dockerfile +30 -0
- package/resources/sandbox/entrypoint.sh +108 -0
- package/resources/sandbox/firecracker-launch.sh +120 -0
- package/dist/harness/vscodeSettingsWriter.d.ts +0 -40
- package/dist/harness/vscodeSettingsWriter.d.ts.map +0 -1
- package/dist/harness/vscodeSettingsWriter.js +0 -116
- package/dist/harness/vscodeSettingsWriter.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { Command } from 'commander';
|
|
14
14
|
import { createRequire } from 'node:module';
|
|
15
|
+
import { DEFAULT_SANDBOX_IMAGE } from './lib/sandbox/image.js';
|
|
15
16
|
// Read the version from package.json rather than repeating it here. The literal
|
|
16
17
|
// that used to live below said 1.6.0 for three releases running, so
|
|
17
18
|
// `intutic --version` reported a version the user did not have — and any check
|
|
@@ -20,14 +21,22 @@ import { createRequire } from 'node:module';
|
|
|
20
21
|
// but JSON imports still need an assertion on older runtimes.
|
|
21
22
|
const { version } = createRequire(import.meta.url)('../package.json');
|
|
22
23
|
const program = new Command();
|
|
24
|
+
// Positional options: `--version` and `--help` belong to the program only when
|
|
25
|
+
// they come before a subcommand. Without this, commander matches program
|
|
26
|
+
// options anywhere on the line, so `intutic policy rollback <id> --version 2`
|
|
27
|
+
// printed the CLI version and exited before `policy rollback` ever saw its own
|
|
28
|
+
// required `--version`.
|
|
23
29
|
program
|
|
24
30
|
.name('intutic')
|
|
25
31
|
.description('Intutic CLI — AI governance control plane for developer workspaces')
|
|
26
|
-
.version(version)
|
|
32
|
+
.version(version)
|
|
33
|
+
.enablePositionalOptions();
|
|
27
34
|
program
|
|
28
35
|
.command('init')
|
|
29
|
-
.description('Initialize workspace — detect harnesses
|
|
36
|
+
.description('Initialize workspace — detect harnesses and record them in ~/.intutic/config.json')
|
|
30
37
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
38
|
+
.option('--git-hooks', 'Install the Intutic Git hooks without asking')
|
|
39
|
+
.option('--no-git-hooks', 'Skip the Git hooks without asking (the default when stdin is not a terminal)')
|
|
31
40
|
.action(async (opts) => {
|
|
32
41
|
const { runInit } = await import('./commands/init.js');
|
|
33
42
|
await runInit(opts);
|
|
@@ -35,7 +44,7 @@ program
|
|
|
35
44
|
// ── Cohort setup wizard (LLD #70) ────────────────────────────────────────
|
|
36
45
|
program
|
|
37
46
|
.command('setup')
|
|
38
|
-
.description('Guided setup: detect harnesses, configure a provider credential, verify it
|
|
47
|
+
.description('Guided setup: detect harnesses, configure a provider credential, and verify it')
|
|
39
48
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
40
49
|
.action(async (opts) => {
|
|
41
50
|
const { runSetup } = await import('./commands/setup.js');
|
|
@@ -46,7 +55,7 @@ const judgeCmd = program
|
|
|
46
55
|
.description('Configure the LLM-as-judge path');
|
|
47
56
|
judgeCmd
|
|
48
57
|
.command('configure')
|
|
49
|
-
.description('Generate local artifacts (litellm_config.yaml, env, Helm values) for an on-prem judge — never a remote API call')
|
|
58
|
+
.description('Generate local artifacts (litellm_config.yaml, env, Helm values) for an on-prem judge on a self-hosted model — never a remote API call')
|
|
50
59
|
.option('--out <path>', 'Where to write litellm_config.yaml', './litellm_config.yaml')
|
|
51
60
|
.action(async (opts) => {
|
|
52
61
|
const { runJudgeConfigure } = await import('./commands/judge.js');
|
|
@@ -56,11 +65,22 @@ program
|
|
|
56
65
|
.command('login')
|
|
57
66
|
.description('Authenticate with the Intutic control plane')
|
|
58
67
|
.option('--api-key <key>', 'Authenticate with an API key (vk_*)')
|
|
68
|
+
.option('--control-plane-url <url>', 'Control plane to log in to (e.g. a self-hosted one); saved for every later command')
|
|
59
69
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
60
70
|
.action(async (opts) => {
|
|
61
71
|
const { runLogin } = await import('./commands/login.js');
|
|
62
72
|
await runLogin(opts);
|
|
63
73
|
});
|
|
74
|
+
program
|
|
75
|
+
.command('disconnect')
|
|
76
|
+
.description('Undo intutic connect: restore every harness config it changed, remove its services, and log out')
|
|
77
|
+
.option('--harness <id>', 'Disconnect one harness only (credentials and services stay)')
|
|
78
|
+
.option('--dry-run', 'Print exactly what would change, and change nothing')
|
|
79
|
+
.option('--keep-login', 'Keep the stored credentials')
|
|
80
|
+
.action(async (opts) => {
|
|
81
|
+
const { runDisconnect } = await import('./commands/disconnect.js');
|
|
82
|
+
await runDisconnect({ harness: opts.harness, dryRun: opts.dryRun, keepLogin: opts.keepLogin });
|
|
83
|
+
});
|
|
64
84
|
program
|
|
65
85
|
.command('logout')
|
|
66
86
|
.description('Clear stored credentials')
|
|
@@ -108,11 +128,10 @@ program
|
|
|
108
128
|
});
|
|
109
129
|
program
|
|
110
130
|
.command('predict-cost')
|
|
111
|
-
.description('Pre-flight cost estimate for a prompt/task before it runs (
|
|
112
|
-
|
|
113
|
-
'every other cost figure
|
|
131
|
+
.description('Pre-flight cost estimate for a prompt/task before it runs (requires `intutic login`). ' +
|
|
132
|
+
"Estimates output tokens from the workspace's recorded usage and prices them with the same " +
|
|
133
|
+
'rate table as every other cost figure the control plane reports.')
|
|
114
134
|
.requiredOption('--model <model>', 'Model to estimate against (e.g. claude-sonnet-4-5)')
|
|
115
|
-
.option('--task-type <type>', 'Task type used to pick the baseline bucket', 'coding')
|
|
116
135
|
.option('--tokens <n>', 'Input token count (mutually exclusive with --file)')
|
|
117
136
|
.option('--file <path>', 'File whose contents size the input (mutually exclusive with --tokens)')
|
|
118
137
|
.option('--json', 'Output as JSON instead of a report')
|
|
@@ -128,7 +147,7 @@ sopsCmd
|
|
|
128
147
|
.command('push <name>')
|
|
129
148
|
.description('Push a local offline SOP folder to the central workspace')
|
|
130
149
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
131
|
-
.option('--org', "Push as an org-wide floor
|
|
150
|
+
.option('--org', "Push as an org-wide floor instead of a workspace SOP -- applies to every workspace under the caller's org, in addition to that workspace's own SOPs")
|
|
132
151
|
.action(async (name, opts) => {
|
|
133
152
|
const { runSopsPush } = await import('./commands/sops.js');
|
|
134
153
|
await runSopsPush(name, opts);
|
|
@@ -152,7 +171,7 @@ sopsCmd
|
|
|
152
171
|
});
|
|
153
172
|
sopsCmd
|
|
154
173
|
.command('org-list')
|
|
155
|
-
.description("List org-wide SOP floors for the caller's own org
|
|
174
|
+
.description("List org-wide SOP floors for the caller's own org")
|
|
156
175
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
157
176
|
.action(async (opts) => {
|
|
158
177
|
const { runSopsOrgList } = await import('./commands/sops.js');
|
|
@@ -349,7 +368,7 @@ guardrailsCmd
|
|
|
349
368
|
.command('list')
|
|
350
369
|
.description('List guardrails with their status and shadow evidence')
|
|
351
370
|
.option('--status <status>', 'PROPOSED | SHADOW | ENFORCING | REJECTED | RETIRED')
|
|
352
|
-
.option('--target <target>', 'hook_rule | sop_front_matter | wasm_rule')
|
|
371
|
+
.option('--target <target>', 'hook_rule | sop_front_matter | wasm_rule | workspace_setting')
|
|
353
372
|
.option('--doc <docId>', 'Only guardrails cited from this document')
|
|
354
373
|
.option('--limit <n>', 'Max rows (default 50, capped at 200)')
|
|
355
374
|
.option('--json', 'Output as JSON')
|
|
@@ -378,8 +397,8 @@ guardrailsCmd
|
|
|
378
397
|
});
|
|
379
398
|
guardrailsCmd
|
|
380
399
|
.command('promote <guardrailId>')
|
|
381
|
-
.description('Promote a shadow guardrail to enforcing once the server says it is ready')
|
|
382
|
-
.option('--acknowledge-no-traffic', 'Promote a rule that no observed traffic exercised')
|
|
400
|
+
.description('Promote a shadow guardrail to enforcing once the server says it is ready (an egress allow list is applied from proposed)')
|
|
401
|
+
.option('--acknowledge-no-traffic', 'Promote a rule that no observed traffic exercised, or apply an egress allow list, which has no shadow evidence')
|
|
383
402
|
.option('--json', 'Output as JSON')
|
|
384
403
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
385
404
|
.action(async (guardrailId, opts) => {
|
|
@@ -475,7 +494,7 @@ program
|
|
|
475
494
|
program
|
|
476
495
|
.command('start')
|
|
477
496
|
.description('Start the proxy standalone — no account or control plane needed')
|
|
478
|
-
.option('--port <port>', 'Proxy port
|
|
497
|
+
.option('--port <port>', 'Proxy port (default: the port of $INTUTIC_PROXY_URL, else 4000)')
|
|
479
498
|
.option('--valkey-port <port>', 'Valkey port', '6379')
|
|
480
499
|
.option('--upstream-url <url>', 'Upstream LLM provider base URL')
|
|
481
500
|
.action(async (opts) => {
|
|
@@ -531,7 +550,7 @@ enterpriseCmd
|
|
|
531
550
|
.option('--mdm-output-dir <dir>', 'Directory to write generated MDM manifests to', './intutic-mdm')
|
|
532
551
|
.option('--skip-ca', 'Skip system-wide CA trust installation')
|
|
533
552
|
.option('--skip-hooks', 'Skip system-level Cursor hooks installation')
|
|
534
|
-
.option('--dev', '
|
|
553
|
+
.option('--dev', 'Send the device enforcement report to the local control plane (http://localhost:3001)')
|
|
535
554
|
.option('--cli-binary-path <path>', 'Absolute path to the intutic CLI binary on TARGET machines, embedded in the firewall-deployment manifests (default: /usr/local/bin/intutic — override if your fleet installs elsewhere)')
|
|
536
555
|
.action(async (opts) => {
|
|
537
556
|
const { runEnterpriseInstall } = await import('./commands/enterprise.js');
|
|
@@ -542,7 +561,7 @@ const envCmd = program
|
|
|
542
561
|
.description('Persist or clear the proxy base-URL environment variables');
|
|
543
562
|
envCmd
|
|
544
563
|
.command('persist')
|
|
545
|
-
.description('Write ANTHROPIC_BASE_URL / OPENAI_BASE_URL at the OS level so
|
|
564
|
+
.description('Write ANTHROPIC_BASE_URL / OPENAI_BASE_URL at the OS level so new shells and apps pick them up.\n' +
|
|
546
565
|
' macOS: launchctl setenv Linux: ~/.bashrc Windows: setx\n' +
|
|
547
566
|
'\n' +
|
|
548
567
|
' Opt-in on purpose: on macOS this reaches every GUI app you launch afterwards.\n' +
|
|
@@ -573,8 +592,8 @@ program
|
|
|
573
592
|
});
|
|
574
593
|
program
|
|
575
594
|
.command('sync-context')
|
|
576
|
-
.description('
|
|
577
|
-
.option('--git', '
|
|
595
|
+
.description('Record the Git branch and commit in .intutic/git-context.json, which a running `intutic connect` reports')
|
|
596
|
+
.option('--git', 'Read the branch and commit from the repository (for any not given below)')
|
|
578
597
|
.option('--branch <name>', 'Current Git branch name')
|
|
579
598
|
.option('--commit <hash>', 'Current Git commit SHA')
|
|
580
599
|
.action(async (opts) => {
|
|
@@ -585,7 +604,7 @@ program
|
|
|
585
604
|
.command('decisions-log-refresh')
|
|
586
605
|
.description('One-shot refresh of the governed decisions log (.intutic/DECISIONS.md + the claude-code ' +
|
|
587
606
|
'harness config section) — no-ops if decisionsLogEnabled is off. Invoked by the optional ' +
|
|
588
|
-
'post-merge hook
|
|
607
|
+
'post-merge Git hook `intutic init` installs; safe to run manually.')
|
|
589
608
|
.action(async () => {
|
|
590
609
|
const { refreshDecisionsLog } = await import('./lib/decisionsLogRefresh.js');
|
|
591
610
|
const result = await refreshDecisionsLog(process.cwd());
|
|
@@ -602,7 +621,7 @@ program
|
|
|
602
621
|
// (LLD #63 §6): cap-drop, no-new-privileges, read-only rootfs, resource caps,
|
|
603
622
|
// and a default-deny egress firewall the agent cannot undo.
|
|
604
623
|
.option('--sandbox [kind]', 'Run the agent in an isolated sandbox (kind: oci | firecracker; default oci)')
|
|
605
|
-
.option('--sandbox-image <image>', 'Sandbox image (must contain the agent + nftables + capsh)',
|
|
624
|
+
.option('--sandbox-image <image>', 'Sandbox image (must contain the agent + nftables + capsh); the default is built locally on first use', DEFAULT_SANDBOX_IMAGE)
|
|
606
625
|
.option('--sandbox-memory <size>', 'Sandbox memory cap (e.g. 2g)', '2g')
|
|
607
626
|
.option('--sandbox-cpus <n>', 'Sandbox CPU cap', '2')
|
|
608
627
|
.option('--sandbox-pids <n>', 'Sandbox max process count', '512')
|
|
@@ -658,7 +677,7 @@ const findings = program
|
|
|
658
677
|
findings
|
|
659
678
|
.command('list')
|
|
660
679
|
.description('List detector findings for the workspace')
|
|
661
|
-
.option('--unadjudicated',
|
|
680
|
+
.option('--unadjudicated', 'Only show findings nobody has ruled on yet (default: all findings)')
|
|
662
681
|
.option('--detector <id>', 'Filter by detector_id (e.g. response_injection:override-instructions)')
|
|
663
682
|
.option('--limit <n>', 'Max rows to return (default: 100, max: 500)')
|
|
664
683
|
.option('--json', 'Output as JSON instead of table')
|
|
@@ -690,8 +709,8 @@ findings
|
|
|
690
709
|
findings
|
|
691
710
|
.command('echo-report')
|
|
692
711
|
.description('Response-injection echo measurement report — per-pattern false-positive rate')
|
|
693
|
-
.option('--since <date>', 'ISO date — window start (
|
|
694
|
-
.option('--until <date>', 'ISO date — window end (
|
|
712
|
+
.option('--since <date>', 'ISO date — window start (default: 7 days before --until)')
|
|
713
|
+
.option('--until <date>', 'ISO date — window end (default: now)')
|
|
695
714
|
.option('--json', 'Output as JSON instead of table')
|
|
696
715
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
697
716
|
.action(async (opts) => {
|
|
@@ -715,6 +734,7 @@ integrity
|
|
|
715
734
|
integrity
|
|
716
735
|
.command('verify <root_id>')
|
|
717
736
|
.description('Re-derive a root from the live traces and check its signature (exit 1 on mismatch)')
|
|
737
|
+
.option('--against <file>', 'Also compare with the copy of this root mirrored to your own bucket (BYOC)')
|
|
718
738
|
.option('--json', 'Output as JSON instead of a report')
|
|
719
739
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
720
740
|
.action(async (rootId, opts) => {
|
|
@@ -747,7 +767,7 @@ const routing = program
|
|
|
747
767
|
routing
|
|
748
768
|
.command('adoption-report')
|
|
749
769
|
.description('Mirror-test adoption report for one candidate model — win/loss/tie, fault-rate delta, ' +
|
|
750
|
-
'cost delta, latency delta
|
|
770
|
+
'cost delta, latency delta. ' +
|
|
751
771
|
'A reported signal for human review, not an automatic gate.')
|
|
752
772
|
.requiredOption('--candidate-model <model>', 'The mirror-tested candidate model to report on')
|
|
753
773
|
.option('--json', 'Output as JSON instead of a report')
|
|
@@ -760,80 +780,93 @@ routing
|
|
|
760
780
|
const daemon = program
|
|
761
781
|
.command('daemon')
|
|
762
782
|
.description('Manage the Intutic sync-daemon, MCP daemon and standalone proxy system services (LaunchAgent / systemd)');
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
783
|
+
// `install` and `uninstall` are also reachable as the top-level shortcuts
|
|
784
|
+
// `intutic install-daemon` / `intutic uninstall-daemon`. A commander alias only
|
|
785
|
+
// renames a command within its own parent, so each verb is defined once here
|
|
786
|
+
// and registered in both places. The shortcuts used to be separate copies, and
|
|
787
|
+
// they drifted: `install-daemon` had no --mcp, --proxy or proxy options and
|
|
788
|
+
// demanded a workspace and key even for the standalone proxy, while the docs
|
|
789
|
+
// called it a shortcut for `daemon install`.
|
|
790
|
+
function defineDaemonInstall(cmd) {
|
|
791
|
+
return cmd
|
|
792
|
+
.description('Install sync-daemon as a system service (auto-starts on login, restarts on any exit).\n' +
|
|
793
|
+
' macOS: ~/Library/LaunchAgents/ai.intutic.sync-daemon.plist (KeepAlive: true)\n' +
|
|
794
|
+
' Linux: ~/.config/systemd/user/intutic-sync-daemon.service (Restart=always)\n' +
|
|
795
|
+
'\n' +
|
|
796
|
+
' --proxy installs the standalone intutic-proxy binary instead (no workspace or key needed):\n' +
|
|
797
|
+
' macOS: ~/Library/LaunchAgents/ai.intutic.proxy.plist\n' +
|
|
798
|
+
' Linux: ~/.config/systemd/user/intutic-proxy.service\n' +
|
|
799
|
+
'\n' +
|
|
800
|
+
' The service restarts whenever its process exits, so killing the process does not stop it.\n' +
|
|
801
|
+
' Use \'intutic daemon stop\' or \'intutic daemon uninstall\'.')
|
|
802
|
+
.option('--workspace-id <id>', 'Workspace ID (e.g. wk_xxxx) — required unless --proxy')
|
|
803
|
+
.option('--api-key <key>', 'Workspace API key (e.g. vk_xxxx) — required unless --proxy')
|
|
804
|
+
.option('--control-plane-url <url>', 'Control plane the daemon connects to (default: $INTUTIC_CONTROL_PLANE_URL, then the URL saved by `intutic login`, then https://api.intutic.ai)')
|
|
805
|
+
.option('--binary-path <path>', 'Path to intutic CLI binary (defaults to current process); with --proxy, absolute path to intutic-proxy')
|
|
806
|
+
.option('--dry-run', 'Print what would be done without writing files')
|
|
807
|
+
.option('--system', 'Install as a system-level service (LaunchDaemon on macOS, systemd system unit on Linux)')
|
|
808
|
+
.option('--mcp', 'Install the MCP proxy daemon instead of the sync-daemon')
|
|
809
|
+
.option('--proxy', 'Install the standalone intutic-proxy binary as a service')
|
|
810
|
+
.option('--port <port>', 'With --proxy: proxy listen port (default: the port of $INTUTIC_PROXY_URL, else 4000)')
|
|
811
|
+
.option('--valkey-url <url>', 'With --proxy: Valkey URL to attach to; omit to run standalone (INTUTIC_STANDALONE=1)')
|
|
812
|
+
.option('--upstream-url <url>', 'With --proxy: upstream LLM provider base URL')
|
|
813
|
+
.action(async (opts, cmd) => {
|
|
814
|
+
if (opts.proxy) {
|
|
815
|
+
// The standalone proxy has no control plane, so no workspace or key.
|
|
816
|
+
// Its unit carries the same environment `intutic start` sets, fixed at
|
|
817
|
+
// install time rather than probed at launch.
|
|
818
|
+
const { installProxyService } = await import('./commands/install-daemon.js');
|
|
819
|
+
await installProxyService({
|
|
820
|
+
port: opts.port,
|
|
821
|
+
valkeyUrl: opts.valkeyUrl,
|
|
822
|
+
upstreamUrl: opts.upstreamUrl,
|
|
823
|
+
binaryPath: opts.binaryPath,
|
|
824
|
+
dryRun: opts.dryRun,
|
|
825
|
+
system: opts.system,
|
|
826
|
+
});
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
// Required for the two daemons; commander's `requiredOption` cannot express
|
|
830
|
+
// "unless --proxy", so the check lives here with the same wording.
|
|
831
|
+
if (!opts.workspaceId)
|
|
832
|
+
cmd.error("error: required option '--workspace-id <id>' not specified");
|
|
833
|
+
if (!opts.apiKey)
|
|
834
|
+
cmd.error("error: required option '--api-key <key>' not specified");
|
|
835
|
+
// `installMcpDaemon` and `buildMcpPlist` were written, tested and exported,
|
|
836
|
+
// and then nothing called them: every route into install-daemon.ts landed
|
|
837
|
+
// on `installDaemon`, so the MCP proxy daemon could not be installed by any
|
|
838
|
+
// command the CLI offered. This flag is that missing route.
|
|
839
|
+
const { installDaemon, installMcpDaemon } = await import('./commands/install-daemon.js');
|
|
840
|
+
const install = opts.mcp ? installMcpDaemon : installDaemon;
|
|
841
|
+
await install({
|
|
842
|
+
workspaceId: opts.workspaceId,
|
|
843
|
+
apiKey: opts.apiKey,
|
|
844
|
+
controlPlaneUrl: opts.controlPlaneUrl,
|
|
797
845
|
binaryPath: opts.binaryPath,
|
|
798
846
|
dryRun: opts.dryRun,
|
|
799
847
|
system: opts.system,
|
|
800
848
|
});
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
// Required for the two daemons; commander's `requiredOption` cannot express
|
|
804
|
-
// "unless --proxy", so the check lives here with the same wording.
|
|
805
|
-
if (!opts.workspaceId)
|
|
806
|
-
cmd.error("error: required option '--workspace-id <id>' not specified");
|
|
807
|
-
if (!opts.apiKey)
|
|
808
|
-
cmd.error("error: required option '--api-key <key>' not specified");
|
|
809
|
-
// `installMcpDaemon` and `buildMcpPlist` were written, tested and exported,
|
|
810
|
-
// and then nothing called them: every route into install-daemon.ts landed
|
|
811
|
-
// on `installDaemon`, so the MCP proxy daemon could not be installed by any
|
|
812
|
-
// command the CLI offered (TD-153). This flag is that missing route.
|
|
813
|
-
const { installDaemon, installMcpDaemon } = await import('./commands/install-daemon.js');
|
|
814
|
-
const install = opts.mcp ? installMcpDaemon : installDaemon;
|
|
815
|
-
await install({
|
|
816
|
-
workspaceId: opts.workspaceId,
|
|
817
|
-
apiKey: opts.apiKey,
|
|
818
|
-
controlPlaneUrl: opts.controlPlaneUrl,
|
|
819
|
-
binaryPath: opts.binaryPath,
|
|
820
|
-
dryRun: opts.dryRun,
|
|
821
|
-
system: opts.system,
|
|
822
849
|
});
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
}
|
|
850
|
+
}
|
|
851
|
+
function defineDaemonUninstall(cmd) {
|
|
852
|
+
return cmd
|
|
853
|
+
.description('Remove the sync-daemon system service and stop it permanently.')
|
|
854
|
+
.option('--dry-run', 'Print what would be done without writing files')
|
|
855
|
+
.option('--system', 'Uninstall the system-level service')
|
|
856
|
+
.option('--mcp', 'Uninstall the MCP proxy daemon instead of the sync-daemon')
|
|
857
|
+
.option('--proxy', 'Uninstall the standalone intutic-proxy service instead of the sync-daemon')
|
|
858
|
+
.action(async (opts) => {
|
|
859
|
+
const { uninstallDaemon, uninstallMcpDaemon, uninstallProxyService } = await import('./commands/install-daemon.js');
|
|
860
|
+
const uninstall = opts.proxy ? uninstallProxyService : opts.mcp ? uninstallMcpDaemon : uninstallDaemon;
|
|
861
|
+
await uninstall({ dryRun: opts.dryRun, system: opts.system });
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
defineDaemonInstall(daemon.command('install'));
|
|
865
|
+
defineDaemonUninstall(daemon.command('uninstall'));
|
|
866
|
+
defineDaemonInstall(program.command('install-daemon'))
|
|
867
|
+
.summary("Shortcut for 'intutic daemon install'");
|
|
868
|
+
defineDaemonUninstall(program.command('uninstall-daemon'))
|
|
869
|
+
.summary("Shortcut for 'intutic daemon uninstall'");
|
|
837
870
|
daemon
|
|
838
871
|
.command('status')
|
|
839
872
|
.description('Show sync-daemon system service status (or the standalone proxy service with --proxy).')
|
|
@@ -870,39 +903,6 @@ daemon
|
|
|
870
903
|
const { daemonStart, proxyServiceStart, mcpDaemonStart } = await import('./commands/install-daemon.js');
|
|
871
904
|
await (opts.proxy ? proxyServiceStart() : opts.mcp ? mcpDaemonStart() : daemonStart());
|
|
872
905
|
});
|
|
873
|
-
// Top-level shortcuts (for discoverability)
|
|
874
|
-
program
|
|
875
|
-
.command('install-daemon', { hidden: false })
|
|
876
|
-
.description('Shortcut for \'intutic daemon install\' — install sync-daemon as system service')
|
|
877
|
-
.requiredOption('--workspace-id <id>', 'Workspace ID')
|
|
878
|
-
.requiredOption('--api-key <key>', 'Workspace API key')
|
|
879
|
-
.option('--control-plane-url <url>', 'Control plane URL', 'https://api.intutic.ai')
|
|
880
|
-
.option('--binary-path <path>', 'Path to intutic CLI binary')
|
|
881
|
-
.option('--dry-run', 'Print what would be done without writing files')
|
|
882
|
-
.option('--system', 'Install as a system-level service')
|
|
883
|
-
.action(async (opts) => {
|
|
884
|
-
const { installDaemon } = await import('./commands/install-daemon.js');
|
|
885
|
-
await installDaemon({
|
|
886
|
-
workspaceId: opts.workspaceId,
|
|
887
|
-
apiKey: opts.apiKey,
|
|
888
|
-
controlPlaneUrl: opts.controlPlaneUrl,
|
|
889
|
-
binaryPath: opts.binaryPath,
|
|
890
|
-
dryRun: opts.dryRun,
|
|
891
|
-
system: opts.system,
|
|
892
|
-
});
|
|
893
|
-
});
|
|
894
|
-
program
|
|
895
|
-
.command('uninstall-daemon', { hidden: false })
|
|
896
|
-
.description('Shortcut for \'intutic daemon uninstall\'')
|
|
897
|
-
.option('--dry-run', 'Print what would be done without writing files')
|
|
898
|
-
.option('--system', 'Uninstall the system-level service')
|
|
899
|
-
.option('--mcp', 'Uninstall the MCP proxy daemon instead of the sync-daemon')
|
|
900
|
-
.option('--proxy', 'Uninstall the standalone intutic-proxy service instead of the sync-daemon')
|
|
901
|
-
.action(async (opts) => {
|
|
902
|
-
const { uninstallDaemon, uninstallMcpDaemon, uninstallProxyService } = await import('./commands/install-daemon.js');
|
|
903
|
-
const uninstall = opts.proxy ? uninstallProxyService : opts.mcp ? uninstallMcpDaemon : uninstallDaemon;
|
|
904
|
-
await uninstall({ dryRun: opts.dryRun, system: opts.system });
|
|
905
|
-
});
|
|
906
906
|
// ── Skill commands ─────────────────────────────────────────────────────────
|
|
907
907
|
const skillCmd = program
|
|
908
908
|
.command('skill')
|
|
@@ -920,9 +920,10 @@ skillCmd
|
|
|
920
920
|
.option('--sarif', 'Output findings as a SARIF 2.1.0 document (for GitHub Code Scanning / CI interop) instead of the human-readable report')
|
|
921
921
|
.option('--engine <engine>', "Scanning engine: 'native' (default, always runs) or 'cisco' to also run the opt-in Cisco " +
|
|
922
922
|
"skill-scanner integration (requires the 'skill-scanner' binary on PATH — pipx install cisco-ai-skill-scanner)", 'native')
|
|
923
|
+
.option('--exit-zero', 'Exit 0 even when there are findings (by default findings exit 1)')
|
|
923
924
|
.action(async (opts) => {
|
|
924
925
|
const { runSkillAudit } = await import('./commands/skill.js');
|
|
925
|
-
await runSkillAudit({ sarif: opts.sarif, engine: opts.engine });
|
|
926
|
+
await runSkillAudit({ sarif: opts.sarif, engine: opts.engine, exitZero: opts.exitZero });
|
|
926
927
|
});
|
|
927
928
|
skillCmd
|
|
928
929
|
.command('scan-staged')
|
|
@@ -969,7 +970,7 @@ loopCmd
|
|
|
969
970
|
.option('--approve', 'Release the hold; the run resumes')
|
|
970
971
|
.option('--reject', 'Refuse the hold; the run is killed')
|
|
971
972
|
.option('--note <note>', 'Why, recorded against the run')
|
|
972
|
-
.option('--dev', '
|
|
973
|
+
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
973
974
|
.action(async (loopRunId, opts) => {
|
|
974
975
|
const { runLoopReview } = await import('./commands/skill.js');
|
|
975
976
|
await runLoopReview(loopRunId, opts);
|
|
@@ -1028,7 +1029,7 @@ decisionCmd
|
|
|
1028
1029
|
// see commands/gateway.ts's module doc.
|
|
1029
1030
|
const gatewayCmd = program
|
|
1030
1031
|
.command('gateway')
|
|
1031
|
-
.description('Manage self-hosted gateway registrations (Docker / Kubernetes / bare
|
|
1032
|
+
.description('Manage self-hosted gateway registrations (Docker / Kubernetes / bare metal)');
|
|
1032
1033
|
gatewayCmd
|
|
1033
1034
|
.command('register')
|
|
1034
1035
|
.description('Register a new self-hosted gateway and print its one-time gwk_ token')
|
|
@@ -1154,7 +1155,7 @@ const attenuateCmd = program
|
|
|
1154
1155
|
.description('Attenuate an API key to a narrower child key (capability subset + optional TTL)')
|
|
1155
1156
|
.option('--parent-key <keyId>', 'Parent API key ID to attenuate')
|
|
1156
1157
|
.option('--caps <caps>', 'Comma-separated capability subset to grant the child key')
|
|
1157
|
-
.option('--ttl <seconds>', 'Child key TTL in seconds (
|
|
1158
|
+
.option('--ttl <seconds>', 'Child key TTL in whole seconds, 60 to 86400 (default 14400)')
|
|
1158
1159
|
.option('--dev', 'Use local control plane (http://localhost:3001)')
|
|
1159
1160
|
.action(async (opts) => {
|
|
1160
1161
|
const { runAttenuate } = await import('./commands/attenuate.js');
|