@shield-agent/kya 0.32.7 → 0.33.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/.cursor-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/LIMITATIONS.md +2 -2
- package/README.md +232 -17
- package/amp/settings.example.json +1 -1
- package/claude/claude_desktop_config.example.json +1 -1
- package/cline/cline_mcp_settings.example.json +1 -1
- package/copilot/mcp-config.example.json +1 -1
- package/data/iocs.json +17 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +237 -53
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/commands/connect.d.ts +1 -1
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +11 -3
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/dash.d.ts.map +1 -1
- package/dist/commands/dash.js +25 -1
- package/dist/commands/dash.js.map +1 -1
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +26 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/eval-tool.d.ts +3 -0
- package/dist/commands/eval-tool.d.ts.map +1 -1
- package/dist/commands/eval-tool.js +2 -1
- package/dist/commands/eval-tool.js.map +1 -1
- package/dist/commands/export.d.ts +33 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +121 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/hook.d.ts.map +1 -1
- package/dist/commands/hook.js +135 -26
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/hosted-hook.d.ts +8 -1
- package/dist/commands/hosted-hook.d.ts.map +1 -1
- package/dist/commands/hosted-hook.js +15 -5
- package/dist/commands/hosted-hook.js.map +1 -1
- package/dist/commands/login.d.ts +34 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +74 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/map.d.ts +21 -0
- package/dist/commands/map.d.ts.map +1 -0
- package/dist/commands/map.js +76 -0
- package/dist/commands/map.js.map +1 -0
- package/dist/commands/notify-flush.d.ts.map +1 -1
- package/dist/commands/notify-flush.js +7 -1
- package/dist/commands/notify-flush.js.map +1 -1
- package/dist/commands/posture.d.ts +21 -0
- package/dist/commands/posture.d.ts.map +1 -0
- package/dist/commands/posture.js +177 -0
- package/dist/commands/posture.js.map +1 -0
- package/dist/commands/receipt-serve.d.ts +7 -0
- package/dist/commands/receipt-serve.d.ts.map +1 -1
- package/dist/commands/receipt-serve.js +50 -0
- package/dist/commands/receipt-serve.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/team.d.ts.map +1 -1
- package/dist/commands/team.js +30 -11
- package/dist/commands/team.js.map +1 -1
- package/dist/commands/wire-hooks.d.ts +5 -1
- package/dist/commands/wire-hooks.d.ts.map +1 -1
- package/dist/commands/wire-hooks.js +23 -8
- package/dist/commands/wire-hooks.js.map +1 -1
- package/dist/commands/wrap.d.ts +38 -1
- package/dist/commands/wrap.d.ts.map +1 -1
- package/dist/commands/wrap.js +82 -6
- package/dist/commands/wrap.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/cta.d.ts +23 -0
- package/dist/cta.d.ts.map +1 -0
- package/dist/cta.js +86 -0
- package/dist/cta.js.map +1 -0
- package/dist/daily-slot.d.ts +2 -0
- package/dist/daily-slot.d.ts.map +1 -0
- package/dist/daily-slot.js +29 -0
- package/dist/daily-slot.js.map +1 -0
- package/dist/dash/dash.d.ts.map +1 -1
- package/dist/dash/dash.js +10 -0
- package/dist/dash/dash.js.map +1 -1
- package/dist/dash/entitlement.d.ts +1 -1
- package/dist/dash/entitlement.d.ts.map +1 -1
- package/dist/dash/entitlement.js +1 -0
- package/dist/dash/entitlement.js.map +1 -1
- package/dist/dash/input.d.ts +1 -1
- package/dist/dash/input.d.ts.map +1 -1
- package/dist/dash/input.js +3 -0
- package/dist/dash/input.js.map +1 -1
- package/dist/dash/render.js +1 -1
- package/dist/dash/render.js.map +1 -1
- package/dist/dash/screens/free.js +1 -1
- package/dist/dash/screens/free.js.map +1 -1
- package/dist/device-id.d.ts +5 -0
- package/dist/device-id.d.ts.map +1 -0
- package/dist/device-id.js +78 -0
- package/dist/device-id.js.map +1 -0
- package/dist/fs-atomic.d.ts +15 -3
- package/dist/fs-atomic.d.ts.map +1 -1
- package/dist/fs-atomic.js +31 -14
- package/dist/fs-atomic.js.map +1 -1
- package/dist/gate/config-gen.d.ts +26 -2
- package/dist/gate/config-gen.d.ts.map +1 -1
- package/dist/gate/config-gen.js +53 -4
- package/dist/gate/config-gen.js.map +1 -1
- package/dist/gate/otlp-receiver.d.ts.map +1 -1
- package/dist/gate/otlp-receiver.js +3 -1
- package/dist/gate/otlp-receiver.js.map +1 -1
- package/dist/guard-pack.d.ts +58 -0
- package/dist/guard-pack.d.ts.map +1 -0
- package/dist/guard-pack.js +753 -0
- package/dist/guard-pack.js.map +1 -0
- package/dist/ioc/exec.d.ts +19 -0
- package/dist/ioc/exec.d.ts.map +1 -0
- package/dist/ioc/exec.js +49 -0
- package/dist/ioc/exec.js.map +1 -0
- package/dist/ioc/format.d.ts +4 -0
- package/dist/ioc/format.d.ts.map +1 -0
- package/dist/ioc/format.js +23 -0
- package/dist/ioc/format.js.map +1 -0
- package/dist/ioc/list.d.ts +29 -0
- package/dist/ioc/list.d.ts.map +1 -0
- package/dist/ioc/list.js +25 -0
- package/dist/ioc/list.js.map +1 -0
- package/dist/ioc/result.d.ts +18 -0
- package/dist/ioc/result.d.ts.map +1 -0
- package/dist/ioc/result.js +26 -0
- package/dist/ioc/result.js.map +1 -0
- package/dist/ioc/scan.d.ts +21 -0
- package/dist/ioc/scan.d.ts.map +1 -0
- package/dist/ioc/scan.js +247 -0
- package/dist/ioc/scan.js.map +1 -0
- package/dist/ioc/spawn.d.ts +26 -0
- package/dist/ioc/spawn.d.ts.map +1 -0
- package/dist/ioc/spawn.js +52 -0
- package/dist/ioc/spawn.js.map +1 -0
- package/dist/login/credentials.d.ts +17 -0
- package/dist/login/credentials.d.ts.map +1 -0
- package/dist/login/credentials.js +64 -0
- package/dist/login/credentials.js.map +1 -0
- package/dist/login/device-flow.d.ts +44 -0
- package/dist/login/device-flow.d.ts.map +1 -0
- package/dist/login/device-flow.js +205 -0
- package/dist/login/device-flow.js.map +1 -0
- package/dist/map/build.d.ts +58 -0
- package/dist/map/build.d.ts.map +1 -0
- package/dist/map/build.js +439 -0
- package/dist/map/build.js.map +1 -0
- package/dist/map/heat.d.ts +44 -0
- package/dist/map/heat.d.ts.map +1 -0
- package/dist/map/heat.js +96 -0
- package/dist/map/heat.js.map +1 -0
- package/dist/map/load.d.ts +38 -0
- package/dist/map/load.d.ts.map +1 -0
- package/dist/map/load.js +38 -0
- package/dist/map/load.js.map +1 -0
- package/dist/map/page.d.ts +90 -0
- package/dist/map/page.d.ts.map +1 -0
- package/dist/map/page.js +374 -0
- package/dist/map/page.js.map +1 -0
- package/dist/map/target-class.d.ts +22 -0
- package/dist/map/target-class.d.ts.map +1 -0
- package/dist/map/target-class.js +151 -0
- package/dist/map/target-class.js.map +1 -0
- package/dist/map/types.d.ts +102 -0
- package/dist/map/types.d.ts.map +1 -0
- package/dist/map/types.js +3 -0
- package/dist/map/types.js.map +1 -0
- package/dist/mcp/protocol.d.ts.map +1 -1
- package/dist/mcp/protocol.js +16 -5
- package/dist/mcp/protocol.js.map +1 -1
- package/dist/never-code.d.ts +7 -0
- package/dist/never-code.d.ts.map +1 -0
- package/dist/never-code.js +9 -0
- package/dist/never-code.js.map +1 -0
- package/dist/never-list-input.d.ts +92 -0
- package/dist/never-list-input.d.ts.map +1 -0
- package/dist/never-list-input.js +1889 -0
- package/dist/never-list-input.js.map +1 -0
- package/dist/notify/dispatch.d.ts +4 -0
- package/dist/notify/dispatch.d.ts.map +1 -1
- package/dist/notify/dispatch.js +3 -1
- package/dist/notify/dispatch.js.map +1 -1
- package/dist/offline-evaluate.d.ts +42 -5
- package/dist/offline-evaluate.d.ts.map +1 -1
- package/dist/offline-evaluate.js +96 -9
- package/dist/offline-evaluate.js.map +1 -1
- package/dist/otel/exporter.d.ts +15 -2
- package/dist/otel/exporter.d.ts.map +1 -1
- package/dist/otel/exporter.js +52 -6
- package/dist/otel/exporter.js.map +1 -1
- package/dist/otel/map-attrs-optin.d.ts +39 -0
- package/dist/otel/map-attrs-optin.d.ts.map +1 -0
- package/dist/otel/map-attrs-optin.js +109 -0
- package/dist/otel/map-attrs-optin.js.map +1 -0
- package/dist/otel.d.ts +8 -2
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +32 -16
- package/dist/otel.js.map +1 -1
- package/dist/parse-args.d.ts +2 -0
- package/dist/parse-args.d.ts.map +1 -1
- package/dist/parse-args.js +4 -2
- package/dist/parse-args.js.map +1 -1
- package/dist/posture/card.d.ts +26 -0
- package/dist/posture/card.d.ts.map +1 -0
- package/dist/posture/card.js +46 -0
- package/dist/posture/card.js.map +1 -0
- package/dist/posture/collect.d.ts +19 -0
- package/dist/posture/collect.d.ts.map +1 -0
- package/dist/posture/collect.js +182 -0
- package/dist/posture/collect.js.map +1 -0
- package/dist/posture/send.d.ts +24 -0
- package/dist/posture/send.d.ts.map +1 -0
- package/dist/posture/send.js +162 -0
- package/dist/posture/send.js.map +1 -0
- package/dist/posture/spawn.d.ts +20 -0
- package/dist/posture/spawn.d.ts.map +1 -0
- package/dist/posture/spawn.js +33 -0
- package/dist/posture/spawn.js.map +1 -0
- package/dist/posture/store.d.ts +34 -0
- package/dist/posture/store.d.ts.map +1 -0
- package/dist/posture/store.js +107 -0
- package/dist/posture/store.js.map +1 -0
- package/dist/posture/validate.d.ts +33 -0
- package/dist/posture/validate.d.ts.map +1 -0
- package/dist/posture/validate.js +232 -0
- package/dist/posture/validate.js.map +1 -0
- package/dist/project-policy.d.ts +23 -0
- package/dist/project-policy.d.ts.map +1 -0
- package/dist/project-policy.js +95 -0
- package/dist/project-policy.js.map +1 -0
- package/dist/receipt/daemon.d.ts +9 -9
- package/dist/receipt/daemon.d.ts.map +1 -1
- package/dist/receipt/daemon.js +26 -11
- package/dist/receipt/daemon.js.map +1 -1
- package/dist/receipt/embeddings.d.ts +29 -7
- package/dist/receipt/embeddings.d.ts.map +1 -1
- package/dist/receipt/embeddings.js +282 -33
- package/dist/receipt/embeddings.js.map +1 -1
- package/dist/receipt/gate-page.d.ts.map +1 -1
- package/dist/receipt/gate-page.js +5 -22
- package/dist/receipt/gate-page.js.map +1 -1
- package/dist/receipt/live-server.d.ts +8 -0
- package/dist/receipt/live-server.d.ts.map +1 -1
- package/dist/receipt/live-server.js +136 -4
- package/dist/receipt/live-server.js.map +1 -1
- package/dist/receipt/render-receipt.d.ts +7 -1
- package/dist/receipt/render-receipt.d.ts.map +1 -1
- package/dist/receipt/render-receipt.js +101 -13
- package/dist/receipt/render-receipt.js.map +1 -1
- package/dist/receipt/search.d.ts +5 -0
- package/dist/receipt/search.d.ts.map +1 -1
- package/dist/receipt/search.js +23 -2
- package/dist/receipt/search.js.map +1 -1
- package/dist/receipt/semantic-setup.d.ts +21 -0
- package/dist/receipt/semantic-setup.d.ts.map +1 -0
- package/dist/receipt/semantic-setup.js +111 -0
- package/dist/receipt/semantic-setup.js.map +1 -0
- package/dist/receipt/semantic-status.d.ts +7 -0
- package/dist/receipt/semantic-status.d.ts.map +1 -0
- package/dist/receipt/semantic-status.js +26 -0
- package/dist/receipt/semantic-status.js.map +1 -0
- package/dist/sdk/govern.d.ts.map +1 -1
- package/dist/sdk/govern.js +7 -3
- package/dist/sdk/govern.js.map +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +3 -23
- package/dist/telemetry.js.map +1 -1
- package/dist/trail-map-fields.d.ts +10 -0
- package/dist/trail-map-fields.d.ts.map +1 -0
- package/dist/trail-map-fields.js +53 -0
- package/dist/trail-map-fields.js.map +1 -0
- package/dist/trail-summary.d.ts.map +1 -1
- package/dist/trail-summary.js +11 -3
- package/dist/trail-summary.js.map +1 -1
- package/dist/trail.d.ts +13 -1
- package/dist/trail.d.ts.map +1 -1
- package/dist/trail.js +38 -1
- package/dist/trail.js.map +1 -1
- package/droid/README.md +1 -1
- package/droid/mcp.example.json +1 -1
- package/gemini/settings.example.json +1 -1
- package/grok/README.md +1 -1
- package/kilo/kilo.example.json +1 -1
- package/kimi/mcp.example.json +1 -1
- package/kiro/mcp.example.json +1 -1
- package/manifest.json +1 -1
- package/mastracode/mcp.example.json +1 -1
- package/mcp.json +1 -1
- package/openai/codex.config.example.toml +1 -1
- package/opencode/opencode.example.json +1 -1
- package/package.json +8 -7
- package/qwen/settings.example.json +1 -1
- package/server.json +2 -2
- package/vendor/cytoscape/LICENSE +19 -0
- package/vendor/cytoscape/README.md +7 -0
- package/vendor/cytoscape/cytoscape.min.js +31 -0
package/dist/cli.js
CHANGED
|
@@ -10,45 +10,12 @@
|
|
|
10
10
|
import { realpathSync, writeSync } from "node:fs";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { resolveConfig } from "./config.js";
|
|
13
|
-
import { KyaError } from "./errors.js";
|
|
13
|
+
import { AuthRequiredError, KyaError } from "./errors.js";
|
|
14
14
|
import { flagBool, flagString, parseArgs } from "./parse-args.js";
|
|
15
|
-
import { initFromArgs } from "./commands/init.js";
|
|
16
|
-
import { registerAgentInputFromArgs, runRegisterAgent, } from "./commands/register-agent.js";
|
|
17
|
-
import { evalToolInputFromArgs, formatEvalHuman, runEvalTool, } from "./commands/eval-tool.js";
|
|
18
|
-
import { runServeMcp, serveMcpOptionsFromArgs, } from "./commands/serve-mcp.js";
|
|
19
|
-
import { orrRunOptionsFromArgs, runOrr, } from "./commands/orr.js";
|
|
20
|
-
import { certifyOptionsFromArgs, formatCertifySummary, runCertify, } from "./commands/certify.js";
|
|
21
|
-
import { runDash } from "./commands/dash.js";
|
|
22
|
-
import { formatAgentTable, formatApprovalTable, formatSessionTable, requireId, runGetAgent, runGetPassport, runKillAgent, runListAgents, runListApprovals, runListSessions, runShrinkSession, shrinkToFromArgs, } from "./commands/ops.js";
|
|
23
|
-
import { formatWrapHuman, runWrap, verdictExitCode, wrapExitCode, wrapInputFromArgs, } from "./commands/wrap.js";
|
|
24
|
-
import { formatReceiptHuman, openPath, receiptInputFromArgs, runReceipt, runReceiptShare, } from "./commands/receipt.js";
|
|
25
|
-
import { formatShareLine, SHARE_HOSTED_HINT } from "./receipt/share.js";
|
|
26
|
-
import { formatStartHuman, runStart } from "./commands/start.js";
|
|
27
|
-
import { connectableHosts, formatConnectHuman, runConnect, } from "./commands/connect.js";
|
|
28
|
-
import { appendTrail, defaultSessionId } from "./trail.js";
|
|
29
|
-
import { deriveTargetPath } from "./trail-summary.js";
|
|
30
|
-
import { decideIdFromArgs, runDecide } from "./commands/decide.js";
|
|
31
|
-
import { formatInvokeHuman, invokeInputFromArgs, runInvoke, } from "./commands/invoke.js";
|
|
32
|
-
import { runSandboxCommand } from "./commands/sandbox.js";
|
|
33
|
-
import { runHook } from "./commands/hook.js";
|
|
34
|
-
import { crashDecision, guardStream, hostedCrashHandler, planeBudgetMs } from "./commands/hosted-hook.js";
|
|
35
|
-
import { importOptionsFromArgs, runImport } from "./commands/import-traces.js";
|
|
36
|
-
import { investigateOptionsFromArgs, runInvestigate, } from "./commands/investigate.js";
|
|
37
|
-
import { discoverOptionsFromArgs, runDiscover, } from "./commands/discover.js";
|
|
38
|
-
import { runNotifyFlush } from "./commands/notify-flush.js";
|
|
39
|
-
import { formatStopHuman, runStop } from "./commands/stop.js";
|
|
40
|
-
import { runReceiptServe } from "./commands/receipt-serve.js";
|
|
41
|
-
import { maybePrintStarCta } from "./star-cta.js";
|
|
42
|
-
import { formatGateDoctorHuman, gateMcpUrl, gateSubcommand, runGateDoctor, runGateInit, runGateRun, runGateSetup, runGateStop, } from "./commands/gate.js";
|
|
43
|
-
import { triggerHostedSyncFromEnv } from "./gate/hosted-sync.js";
|
|
44
|
-
import { runGateServe } from "./commands/gate-serve.js";
|
|
45
15
|
import { ensureSupportedNode } from "./node-upgrade.js";
|
|
46
16
|
import { CLI_VERSION } from "./version.js";
|
|
47
|
-
import {
|
|
48
|
-
|
|
49
|
-
import { formatTeamInitHuman, managedSettings, runTeamInit } from "./commands/team.js";
|
|
50
|
-
import { maybePromptConsent, maybeSpawnHookPing, runTelemetryCommand, startSessionBeacon, } from "./telemetry.js";
|
|
51
|
-
const HELP = `Shield KYA light CLI - Know Your Agent (provider-agnostic)
|
|
17
|
+
import { isNeverCode } from "./never-code.js";
|
|
18
|
+
const helpFor = (hosts) => `Shield KYA light CLI - Know Your Agent (provider-agnostic)
|
|
52
19
|
|
|
53
20
|
Usage:
|
|
54
21
|
kya <command> [options]
|
|
@@ -63,9 +30,9 @@ Commands:
|
|
|
63
30
|
(--all also stops orphaned report daemons from other
|
|
64
31
|
directories or older installs)
|
|
65
32
|
connect <host> Wire KYA MCP into a coding host config
|
|
66
|
-
(${
|
|
33
|
+
(${hosts}; --project for project scope, --force to overwrite)
|
|
67
34
|
--hooks also wires the host's PreToolUse hook (claude|grok|kimi)
|
|
68
|
-
--hooks --hosted --plane-config <abs path> wires the hosted hook (claude,
|
|
35
|
+
--hooks --hosted --plane-config <abs path> wires the hosted hook (claude, preview)
|
|
69
36
|
--gate points the host at the local kya gateway (kya gate run)
|
|
70
37
|
gate Local MCP gateway: govern + audit tool calls to any MCP server
|
|
71
38
|
(init | setup | doctor | status | run | stop)
|
|
@@ -74,11 +41,16 @@ Commands:
|
|
|
74
41
|
merges a tag-pinned marketplace + enabledPlugins into the project's
|
|
75
42
|
.claude/settings.json (--dry-run shows the change, writes nothing)
|
|
76
43
|
team managed-settings Print the managed-settings JSON an admin deploys
|
|
44
|
+
login Link this machine to the hosted console (device code). Saves a 0600
|
|
45
|
+
key in ~/.kya/hosted-credentials.json. --base-url <url> or KYA_BASE_URL
|
|
46
|
+
logout Delete the saved hosted key (the key stays active until you revoke it)
|
|
77
47
|
update Self-update to the latest npm version (kya start warns when
|
|
78
48
|
a newer release exists; --no-update-check / KYA_UPDATE_CHECK=0 opts out)
|
|
79
49
|
register-agent POST /api/v1/kya/agents (human mint; server applies allow/break-glass/approve)
|
|
80
50
|
eval-tool Policy evaluate (HTTP plane or --offline sample)
|
|
81
|
-
wrap Evaluate + record trail.
|
|
51
|
+
wrap Evaluate + record trail. With --tool-id it never executes.
|
|
52
|
+
wrap [--offline] -- <cmd...>: gate the command as a shell call, run it
|
|
53
|
+
only if allowed (exit = the command's; 1 denied, 4 Hold pending).
|
|
82
54
|
Default observe: no Hold ticket (no second approve). --hold / KYA_HOLD=1 for org Hold.
|
|
83
55
|
hook PreToolUse interception for native-hook hosts (claude|grok|kimi|…)
|
|
84
56
|
Reads the hook payload from stdin; exit 2 blocks. --strict denies advisory.
|
|
@@ -87,12 +59,26 @@ Commands:
|
|
|
87
59
|
timeout needs onFailure=block in the plugin hooks.json.
|
|
88
60
|
Records once per tool_use_id (dual-hook safe). Never-list DENY
|
|
89
61
|
blocks in both modes.
|
|
90
|
-
|
|
62
|
+
Guard pack (local, default on, exit 2, rule id in the message):
|
|
63
|
+
NEVER_SHELL rm of home/root, terraform destroy, SQL drops, force
|
|
64
|
+
push, delete main, docker volumes, kubectl delete ns,
|
|
65
|
+
cloud deletes, git hard reset plus git clean
|
|
66
|
+
NEVER_SECRET_READ ssh/cloud/kube/docker/railway credentials, .env
|
|
67
|
+
NEVER_SECRET_WRITE AWS/GitHub/Slack/Stripe keys, private key headers
|
|
68
|
+
NEVER_EXFIL env or credential files sent to a non-loopback host
|
|
69
|
+
Config in ~/.kya/config.json only: shellNeverList, secretsGuard,
|
|
70
|
+
exfilGuard (default true), guardAllow [{rule, path|command}].
|
|
71
|
+
A project .kya/config.json cannot lift a deny. docs/guard-pack.md.
|
|
72
|
+
--plane-config <abs path> (preview): evaluate on the hosted plane,
|
|
91
73
|
fail closed; key/URL/agent come only from that 0600 file.
|
|
92
74
|
--plane-shadow records hosted verdicts without blocking;
|
|
93
75
|
--plane-budget-ms <n> total plane budget (default 3000, max 4000).
|
|
94
76
|
receipt Activity report HTML/JSON/MD (default: last 3 days, all tools; --open)
|
|
95
77
|
--q pre-fills feed search · --share publishes a redacted summary (see --share-url)
|
|
78
|
+
map Map of agent actions: device, agent, tool and target graph with KYA verdicts (local only)
|
|
79
|
+
--days <n> window (default 3) · --json · --html <file> · --session <id>
|
|
80
|
+
export Local trail as an agent-flow JSONL event log (classes only, no args; local only)
|
|
81
|
+
--format agent-flow · --days <n> (default 3) · --session <id> · --out <file>
|
|
96
82
|
invoke Authorize on the plane after Allow or APPROVED. Never runs the write here.
|
|
97
83
|
approve Human APPROVE an approval id (kya.approve scope)
|
|
98
84
|
reject Human REJECT an approval id (kya.approve scope)
|
|
@@ -109,6 +95,12 @@ Commands:
|
|
|
109
95
|
orr run Read-only ORR board (reporting only - not a second PEP)
|
|
110
96
|
Optional: --producer harness.agentshield [--agentshield-json <file>]
|
|
111
97
|
dash Terminal desk (FREE panes; actions on a TTY, --once for CI)
|
|
98
|
+
doctor Local checks. doctor --iocs scans this machine now for known supply-chain
|
|
99
|
+
indicators (advisory; read-only, offline). --json for scripts. Last result: kya dash/receipt
|
|
100
|
+
Background daily scan (from kya hook) is off with KYA_IOC=0 or ioc.enabled=false in ~/.kya/config.json
|
|
101
|
+
posture Developer posture report, OFF by default. status | on [--yes] | off |
|
|
102
|
+
send [--dry-run --json] | label NAME. "on" prints the exact report first.
|
|
103
|
+
Sent once a day only when the local toggle AND the workspace allow it.
|
|
112
104
|
sandbox Opt-in Firecracker wrap (spawn|exec|kill|status). Not MCP.
|
|
113
105
|
Requires KYA_SANDBOX=mock|firecracker. MCP still never execs.
|
|
114
106
|
certify Agent Trust Baseline gap report from local evidence
|
|
@@ -183,14 +175,21 @@ Examples:
|
|
|
183
175
|
Docs: https://shield-agent.com/install · docs/guides/kya-light-install.md
|
|
184
176
|
Doctrine: sole PEP is Shield; DENY is hard; missing APPROVED ⇒ no irreversible side effect.
|
|
185
177
|
`;
|
|
178
|
+
/** Help text. The host list comes from the connect registry, loaded on demand so `kya hook` stays light. */
|
|
179
|
+
async function helpText() {
|
|
180
|
+
const { connectableHosts } = await import("./commands/connect.js");
|
|
181
|
+
return helpFor(connectableHosts().join("|"));
|
|
182
|
+
}
|
|
186
183
|
const defaultIo = {
|
|
187
184
|
log: (m) => console.log(m),
|
|
188
185
|
error: (m) => console.error(m),
|
|
189
186
|
exit: (c) => process.exit(c),
|
|
190
187
|
};
|
|
191
|
-
/**
|
|
188
|
+
/** The hook decides on the bytes it has after this long when the host never closes stdin. */
|
|
189
|
+
const HOOK_STDIN_TIMEOUT_MS = 10_000;
|
|
190
|
+
/** Set by the hook command: the CLI entry exits right after the answer is flushed. */
|
|
192
191
|
let exitWhenDone = false;
|
|
193
|
-
/** Whether the CLI entry will exit right after the hook answer
|
|
192
|
+
/** Whether the CLI entry will exit right after the hook answer. Exposed for tests. */
|
|
194
193
|
export function hostedExitPending() {
|
|
195
194
|
return exitWhenDone;
|
|
196
195
|
}
|
|
@@ -210,7 +209,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
210
209
|
parsed.command === "help" ||
|
|
211
210
|
parsed.flags["help"] === true ||
|
|
212
211
|
parsed.flags["h"] === true) {
|
|
213
|
-
io.log(
|
|
212
|
+
io.log(await helpText());
|
|
214
213
|
return 0;
|
|
215
214
|
}
|
|
216
215
|
try {
|
|
@@ -219,6 +218,10 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
219
218
|
return nodeHandoff;
|
|
220
219
|
switch (parsed.command) {
|
|
221
220
|
case "start": {
|
|
221
|
+
const { formatStartHuman, runStart } = await import("./commands/start.js");
|
|
222
|
+
const { maybePrintStarCta } = await import("./star-cta.js");
|
|
223
|
+
const { checkForUpdate, formatUpdateBanner, shouldSkipUpdateCheck } = await import("./update-check.js");
|
|
224
|
+
const { maybePromptConsent } = await import("./telemetry.js");
|
|
222
225
|
const config = resolveConfig({
|
|
223
226
|
cwd,
|
|
224
227
|
env,
|
|
@@ -232,6 +235,11 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
232
235
|
const noGate = parsed.flags["no-gate"] === true || parsed.flags["no-gate"] === "true";
|
|
233
236
|
if (!config.json)
|
|
234
237
|
await maybePromptConsent(io, env);
|
|
238
|
+
// Before the report server starts, so the first search already sees the runtime. Never fails start.
|
|
239
|
+
if (!config.json) {
|
|
240
|
+
const { maybeOfferSemanticSearch } = await import("./receipt/semantic-setup.js");
|
|
241
|
+
await maybeOfferSemanticSearch(io, env).catch(() => undefined);
|
|
242
|
+
}
|
|
235
243
|
const result = await runStart(config, { force, open: !noOpen, gate: !noGate });
|
|
236
244
|
if (config.json) {
|
|
237
245
|
io.log(JSON.stringify(result, null, 2));
|
|
@@ -249,10 +257,26 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
249
257
|
}
|
|
250
258
|
return 0;
|
|
251
259
|
}
|
|
260
|
+
case "login": {
|
|
261
|
+
const { loginBrowserOpener, runLogin } = await import("./commands/login.js");
|
|
262
|
+
const { openPath } = await import("./commands/receipt.js");
|
|
263
|
+
return await runLogin({
|
|
264
|
+
io,
|
|
265
|
+
env,
|
|
266
|
+
baseUrl: flagString(parsed.flags, "base-url"),
|
|
267
|
+
open: loginBrowserOpener(env, io.isTty ?? Boolean(process.stdout.isTTY), (url) => openPath(url)),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
case "logout": {
|
|
271
|
+
const { runLogout } = await import("./commands/login.js");
|
|
272
|
+
return runLogout({ io, env });
|
|
273
|
+
}
|
|
252
274
|
case "update": {
|
|
275
|
+
const { runUpdate } = await import("./commands/update.js");
|
|
253
276
|
return await runUpdate();
|
|
254
277
|
}
|
|
255
278
|
case "stop": {
|
|
279
|
+
const { formatStopHuman, runStop } = await import("./commands/stop.js");
|
|
256
280
|
const result = await runStop(cwd, { all: flagBool(parsed.flags, "all") });
|
|
257
281
|
if (parsed.flags["json"] === true || parsed.flags["json"] === "true") {
|
|
258
282
|
io.log(JSON.stringify(result, null, 2));
|
|
@@ -263,6 +287,9 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
263
287
|
return 0;
|
|
264
288
|
}
|
|
265
289
|
case "receipt-serve": {
|
|
290
|
+
const { receiptInputFromArgs } = await import("./commands/receipt.js");
|
|
291
|
+
const { runReceiptServe } = await import("./commands/receipt-serve.js");
|
|
292
|
+
const { startSessionBeacon } = await import("./telemetry.js");
|
|
266
293
|
// Internal: detached child of `kya start` / `kya receipt --open`.
|
|
267
294
|
const config = resolveConfig({
|
|
268
295
|
cwd,
|
|
@@ -283,9 +310,15 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
283
310
|
finally {
|
|
284
311
|
await beacon.stop();
|
|
285
312
|
}
|
|
313
|
+
// The server is closed (signal, idle, folder gone, memory ceiling). A running search warm-up or
|
|
314
|
+
// another handle must not keep this process alive after its state file is gone.
|
|
315
|
+
exitWhenDone = true;
|
|
286
316
|
return 0;
|
|
287
317
|
}
|
|
288
318
|
case "connect": {
|
|
319
|
+
const { formatConnectHuman, runConnect } = await import("./commands/connect.js");
|
|
320
|
+
const { gateMcpUrl } = await import("./commands/gate.js");
|
|
321
|
+
const { maybePromptConsent } = await import("./telemetry.js");
|
|
289
322
|
if (parsed.flags["plane-config"] !== undefined && !flagBool(parsed.flags, "hosted")) {
|
|
290
323
|
// Without --hosted this would quietly wire the local, fail-open hook.
|
|
291
324
|
io.error("--plane-config needs --hosted (kya connect claude --hooks --hosted --plane-config <absolute path>)");
|
|
@@ -293,6 +326,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
293
326
|
}
|
|
294
327
|
const host = parsed.positionals[0];
|
|
295
328
|
if (!host) {
|
|
329
|
+
const { connectableHosts } = await import("./commands/connect.js");
|
|
296
330
|
io.error(`Usage: kya connect <host> (${connectableHosts().join("|")})`);
|
|
297
331
|
return 2;
|
|
298
332
|
}
|
|
@@ -329,6 +363,8 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
329
363
|
return 0;
|
|
330
364
|
}
|
|
331
365
|
case "gate": {
|
|
366
|
+
const { formatGateDoctorHuman, gateSubcommand, runGateDoctor, runGateInit, runGateRun, runGateSetup, runGateStop } = await import("./commands/gate.js");
|
|
367
|
+
const { triggerHostedSyncFromEnv } = await import("./gate/hosted-sync.js");
|
|
332
368
|
const sub = gateSubcommand(parsed);
|
|
333
369
|
if (sub === "init") {
|
|
334
370
|
const result = runGateInit(env);
|
|
@@ -399,6 +435,8 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
399
435
|
return 0;
|
|
400
436
|
}
|
|
401
437
|
case "gate-serve": {
|
|
438
|
+
const { runGateServe } = await import("./commands/gate-serve.js");
|
|
439
|
+
const { startSessionBeacon } = await import("./telemetry.js");
|
|
402
440
|
// Internal: detached supervisor child of `kya gate run`.
|
|
403
441
|
const beacon = startSessionBeacon("gateway", { env, cwd });
|
|
404
442
|
try {
|
|
@@ -410,6 +448,8 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
410
448
|
return 0;
|
|
411
449
|
}
|
|
412
450
|
case "init": {
|
|
451
|
+
const { initFromArgs } = await import("./commands/init.js");
|
|
452
|
+
const { maybePromptConsent } = await import("./telemetry.js");
|
|
413
453
|
if (!flagBool(parsed.flags, "json"))
|
|
414
454
|
await maybePromptConsent(io, env);
|
|
415
455
|
const result = initFromArgs(parsed, cwd);
|
|
@@ -427,6 +467,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
427
467
|
return 0;
|
|
428
468
|
}
|
|
429
469
|
case "team": {
|
|
470
|
+
const { formatTeamInitHuman, managedSettings, runTeamInit } = await import("./commands/team.js");
|
|
430
471
|
const sub = parsed.positionals[0];
|
|
431
472
|
if (sub === "managed-settings") {
|
|
432
473
|
io.log(JSON.stringify(managedSettings(), null, 2));
|
|
@@ -444,6 +485,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
444
485
|
return 0;
|
|
445
486
|
}
|
|
446
487
|
case "register-agent": {
|
|
488
|
+
const { registerAgentInputFromArgs, runRegisterAgent } = await import("./commands/register-agent.js");
|
|
447
489
|
const config = resolveConfig({
|
|
448
490
|
cwd,
|
|
449
491
|
env,
|
|
@@ -463,6 +505,11 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
463
505
|
return 0;
|
|
464
506
|
}
|
|
465
507
|
case "eval-tool": {
|
|
508
|
+
const { evalToolInputFromArgs, formatEvalHuman, runEvalTool } = await import("./commands/eval-tool.js");
|
|
509
|
+
const { verdictExitCode } = await import("./commands/wrap.js");
|
|
510
|
+
const { appendTrail, defaultSessionId } = await import("./trail.js");
|
|
511
|
+
const { deriveTargetPath } = await import("./trail-summary.js");
|
|
512
|
+
const { trailMapFields } = await import("./trail-map-fields.js");
|
|
466
513
|
const input = evalToolInputFromArgs(parsed);
|
|
467
514
|
const config = resolveConfig({
|
|
468
515
|
cwd,
|
|
@@ -481,8 +528,9 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
481
528
|
verdict: result.response.verdict,
|
|
482
529
|
reasonCode: result.response.reasonCode ?? "",
|
|
483
530
|
mode: result.offline ? "offline" : config.holdEnabled ? "hold" : "observe",
|
|
484
|
-
neverEvent: result.response.reasonCode
|
|
531
|
+
neverEvent: isNeverCode(result.response.reasonCode),
|
|
485
532
|
argsHash: result.argsHash,
|
|
533
|
+
...trailMapFields(result.response.toolId ?? input.toolId, input.args, config.cwd, env),
|
|
486
534
|
...(targetPath ? { targetPath } : {}),
|
|
487
535
|
}, env);
|
|
488
536
|
if (config.json) {
|
|
@@ -494,6 +542,9 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
494
542
|
return verdictExitCode(result.response.verdict);
|
|
495
543
|
}
|
|
496
544
|
case "receipt": {
|
|
545
|
+
const { formatReceiptHuman, receiptInputFromArgs, runReceipt, runReceiptShare } = await import("./commands/receipt.js");
|
|
546
|
+
const { SHARE_HOSTED_HINT, formatShareLine } = await import("./receipt/share.js");
|
|
547
|
+
const { maybePrintStarCta } = await import("./star-cta.js");
|
|
497
548
|
const config = resolveConfig({
|
|
498
549
|
cwd,
|
|
499
550
|
env,
|
|
@@ -531,10 +582,60 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
531
582
|
io.log(formatReceiptHuman(result));
|
|
532
583
|
if (result.liveUrl)
|
|
533
584
|
maybePrintStarCta(cwd, result.days, io.log);
|
|
585
|
+
// One CTA per day at most: the truncation pitch wins over the --share hint.
|
|
586
|
+
const { maybeCta } = await import("./cta.js");
|
|
587
|
+
const { trailTruncated } = await import("./trail.js");
|
|
588
|
+
maybeCta(trailTruncated(cwd, env) ? "receipt-truncated" : "receipt-share", { env, cwd, isTty: io.isTty ?? Boolean(process.stdout.isTTY) }, io.log);
|
|
534
589
|
}
|
|
535
590
|
return 0;
|
|
536
591
|
}
|
|
592
|
+
case "map": {
|
|
593
|
+
const { mapOptionsFromArgs, runMap } = await import("./commands/map.js");
|
|
594
|
+
return await runMap(mapOptionsFromArgs(parsed), io, cwd, env);
|
|
595
|
+
}
|
|
596
|
+
case "export": {
|
|
597
|
+
const { exportOptionsFromArgs, runExport } = await import("./commands/export.js");
|
|
598
|
+
return await runExport(exportOptionsFromArgs(parsed), io, cwd, env);
|
|
599
|
+
}
|
|
537
600
|
case "wrap": {
|
|
601
|
+
const { formatWrapHuman, runWrap, runWrapCommand, spawnWrapped, wrapCommandFromArgs, wrapCommandInputFromArgs, wrapExitCode, wrapInputFromArgs } = await import("./commands/wrap.js");
|
|
602
|
+
const argv = wrapCommandFromArgs(parsed);
|
|
603
|
+
if (argv) {
|
|
604
|
+
// Command form: verdict lines go to stderr so the child's stdout stays clean.
|
|
605
|
+
const cmdInput = wrapCommandInputFromArgs(parsed);
|
|
606
|
+
// No key and no --offline: gate with the local sample policy (never-list included) instead of refusing to run.
|
|
607
|
+
const cmdBase = { cwd, env, flags: parsed.flags };
|
|
608
|
+
const cmdConfig = (() => {
|
|
609
|
+
if (cmdInput.offline)
|
|
610
|
+
return resolveConfig({ ...cmdBase, requireApiKey: false, offline: true });
|
|
611
|
+
try {
|
|
612
|
+
return resolveConfig({ ...cmdBase, requireApiKey: true });
|
|
613
|
+
}
|
|
614
|
+
catch (e) {
|
|
615
|
+
if (!(e instanceof AuthRequiredError))
|
|
616
|
+
throw e;
|
|
617
|
+
return resolveConfig({ ...cmdBase, requireApiKey: false, offline: true });
|
|
618
|
+
}
|
|
619
|
+
})();
|
|
620
|
+
const { exitCode } = await runWrapCommand(cmdConfig, argv, cmdInput, {
|
|
621
|
+
run: (a) => spawnWrapped(a, io.error),
|
|
622
|
+
onEvaluated: async (w) => {
|
|
623
|
+
io.error(cmdConfig.json ? JSON.stringify(w, null, 2) : formatWrapHuman(w));
|
|
624
|
+
try {
|
|
625
|
+
const { autoOpenReceiptAfterWrap } = await import("./receipt/auto-open.js");
|
|
626
|
+
const force = w.eval.response.verdict.toUpperCase() === "DENY" ||
|
|
627
|
+
w.eval.response.reasonCode === "NEVER_EVENT";
|
|
628
|
+
const auto = await autoOpenReceiptAfterWrap(cmdConfig, { force, env });
|
|
629
|
+
if (!cmdConfig.json && auto.hint)
|
|
630
|
+
io.error(auto.hint);
|
|
631
|
+
}
|
|
632
|
+
catch {
|
|
633
|
+
/* receipt open is best-effort */
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
});
|
|
637
|
+
return exitCode;
|
|
638
|
+
}
|
|
538
639
|
const input = wrapInputFromArgs(parsed);
|
|
539
640
|
const config = resolveConfig({
|
|
540
641
|
cwd,
|
|
@@ -554,7 +655,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
554
655
|
try {
|
|
555
656
|
const { autoOpenReceiptAfterWrap } = await import("./receipt/auto-open.js");
|
|
556
657
|
const force = result.eval.response.verdict.toUpperCase() === "DENY" ||
|
|
557
|
-
result.eval.response.reasonCode
|
|
658
|
+
isNeverCode(result.eval.response.reasonCode);
|
|
558
659
|
const auto = await autoOpenReceiptAfterWrap(config, { force, env });
|
|
559
660
|
if (!config.json && auto.hint)
|
|
560
661
|
io.log(auto.hint);
|
|
@@ -565,6 +666,8 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
565
666
|
return wrapExitCode(result);
|
|
566
667
|
}
|
|
567
668
|
case "invoke": {
|
|
669
|
+
const { verdictExitCode } = await import("./commands/wrap.js");
|
|
670
|
+
const { formatInvokeHuman, invokeInputFromArgs, runInvoke } = await import("./commands/invoke.js");
|
|
568
671
|
const input = invokeInputFromArgs(parsed);
|
|
569
672
|
const config = resolveConfig({
|
|
570
673
|
cwd,
|
|
@@ -583,6 +686,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
583
686
|
}
|
|
584
687
|
case "approve":
|
|
585
688
|
case "reject": {
|
|
689
|
+
const { decideIdFromArgs, runDecide } = await import("./commands/decide.js");
|
|
586
690
|
const id = decideIdFromArgs(parsed, parsed.command);
|
|
587
691
|
const config = resolveConfig({
|
|
588
692
|
cwd,
|
|
@@ -603,6 +707,8 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
603
707
|
return 0;
|
|
604
708
|
}
|
|
605
709
|
case "serve-mcp": {
|
|
710
|
+
const { runServeMcp, serveMcpOptionsFromArgs } = await import("./commands/serve-mcp.js");
|
|
711
|
+
const { startSessionBeacon } = await import("./telemetry.js");
|
|
606
712
|
const config = resolveConfig({
|
|
607
713
|
cwd,
|
|
608
714
|
env,
|
|
@@ -642,6 +748,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
642
748
|
return 0;
|
|
643
749
|
}
|
|
644
750
|
case "orr": {
|
|
751
|
+
const { orrRunOptionsFromArgs, runOrr } = await import("./commands/orr.js");
|
|
645
752
|
const sub = parsed.positionals[0];
|
|
646
753
|
if (sub !== "run") {
|
|
647
754
|
io.error('Usage: kya orr run --path <dir> [options]');
|
|
@@ -661,6 +768,8 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
661
768
|
return result.exitCode;
|
|
662
769
|
}
|
|
663
770
|
case "certify": {
|
|
771
|
+
const { certifyOptionsFromArgs, formatCertifySummary, runCertify } = await import("./commands/certify.js");
|
|
772
|
+
const { openPath } = await import("./commands/receipt.js");
|
|
664
773
|
// Local-first, evidence-only: no resolveConfig, no API key, no network.
|
|
665
774
|
const opts = certifyOptionsFromArgs(parsed);
|
|
666
775
|
const result = runCertify({ ...opts, cwd, env });
|
|
@@ -675,6 +784,11 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
675
784
|
io.log(` wrote ${p}`);
|
|
676
785
|
}
|
|
677
786
|
io.log("(evidence only - sole PEP remains Shield KYA; certify never allows or blocks)");
|
|
787
|
+
if (result.report.overall.result === "gap") {
|
|
788
|
+
// One-line CTA, silent in CI, non-TTY, quiet, opt-out and within 24 h of the last one. Never changes exit code.
|
|
789
|
+
const { maybeCta } = await import("./cta.js");
|
|
790
|
+
maybeCta("certify-gaps", { env, cwd, isTty: io.isTty ?? Boolean(process.stdout.isTTY), json: jsonOut, quiet: opts.quiet }, io.log);
|
|
791
|
+
}
|
|
678
792
|
}
|
|
679
793
|
// Attestation confirmation is safety-relevant (proof the attest write
|
|
680
794
|
// happened): it prints even under --quiet, like the key notice;
|
|
@@ -703,6 +817,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
703
817
|
return result.exitCode;
|
|
704
818
|
}
|
|
705
819
|
case "agents": {
|
|
820
|
+
const { formatAgentTable, runListAgents } = await import("./commands/ops.js");
|
|
706
821
|
const config = resolveConfig({
|
|
707
822
|
cwd,
|
|
708
823
|
env,
|
|
@@ -714,6 +829,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
714
829
|
return 0;
|
|
715
830
|
}
|
|
716
831
|
case "agent": {
|
|
832
|
+
const { formatAgentTable, requireId, runGetAgent } = await import("./commands/ops.js");
|
|
717
833
|
const id = requireId(parsed, "agent");
|
|
718
834
|
const config = resolveConfig({
|
|
719
835
|
cwd,
|
|
@@ -726,6 +842,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
726
842
|
return 0;
|
|
727
843
|
}
|
|
728
844
|
case "passport": {
|
|
845
|
+
const { requireId, runGetPassport } = await import("./commands/ops.js");
|
|
729
846
|
const id = requireId(parsed, "passport");
|
|
730
847
|
const config = resolveConfig({
|
|
731
848
|
cwd,
|
|
@@ -738,6 +855,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
738
855
|
return 0;
|
|
739
856
|
}
|
|
740
857
|
case "kill": {
|
|
858
|
+
const { requireId, runKillAgent } = await import("./commands/ops.js");
|
|
741
859
|
const id = requireId(parsed, "kill");
|
|
742
860
|
const config = resolveConfig({
|
|
743
861
|
cwd,
|
|
@@ -753,6 +871,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
753
871
|
return 0;
|
|
754
872
|
}
|
|
755
873
|
case "approvals": {
|
|
874
|
+
const { formatApprovalTable, runListApprovals } = await import("./commands/ops.js");
|
|
756
875
|
const config = resolveConfig({
|
|
757
876
|
cwd,
|
|
758
877
|
env,
|
|
@@ -764,6 +883,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
764
883
|
return 0;
|
|
765
884
|
}
|
|
766
885
|
case "sessions": {
|
|
886
|
+
const { formatSessionTable, runListSessions } = await import("./commands/ops.js");
|
|
767
887
|
const config = resolveConfig({
|
|
768
888
|
cwd,
|
|
769
889
|
env,
|
|
@@ -775,6 +895,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
775
895
|
return 0;
|
|
776
896
|
}
|
|
777
897
|
case "shrink": {
|
|
898
|
+
const { requireId, runShrinkSession, shrinkToFromArgs } = await import("./commands/ops.js");
|
|
778
899
|
const id = requireId(parsed, "shrink");
|
|
779
900
|
const to = shrinkToFromArgs(parsed);
|
|
780
901
|
const config = resolveConfig({
|
|
@@ -791,6 +912,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
791
912
|
return 0;
|
|
792
913
|
}
|
|
793
914
|
case "dash": {
|
|
915
|
+
const { runDash } = await import("./commands/dash.js");
|
|
794
916
|
const config = resolveConfig({
|
|
795
917
|
cwd,
|
|
796
918
|
env,
|
|
@@ -802,9 +924,11 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
802
924
|
return await runDash(config, parsed, io, env);
|
|
803
925
|
}
|
|
804
926
|
case "sandbox": {
|
|
927
|
+
const { runSandboxCommand } = await import("./commands/sandbox.js");
|
|
805
928
|
return await runSandboxCommand(parsed);
|
|
806
929
|
}
|
|
807
930
|
case "telemetry": {
|
|
931
|
+
const { runTelemetryCommand } = await import("./telemetry.js");
|
|
808
932
|
return runTelemetryCommand({
|
|
809
933
|
sub: parsed.positionals[0],
|
|
810
934
|
purge: flagBool(parsed.flags, "purge"),
|
|
@@ -812,6 +936,9 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
812
936
|
}, io, env, cwd);
|
|
813
937
|
}
|
|
814
938
|
case "hook": {
|
|
939
|
+
const { runHook } = await import("./commands/hook.js");
|
|
940
|
+
const { crashDecision, guardStream, hostedCrashHandler, planeBudgetMs } = await import("./commands/hosted-hook.js");
|
|
941
|
+
const { maybeSpawnHookPing } = await import("./telemetry.js");
|
|
815
942
|
const host = flagString(parsed.flags, "host") ?? "other";
|
|
816
943
|
const strict = flagBool(parsed.flags, "strict");
|
|
817
944
|
// Strict boolean: parseArgs would otherwise swallow a following word
|
|
@@ -819,7 +946,7 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
819
946
|
// Present means on, except an explicit false/0.
|
|
820
947
|
const fcFlag = parsed.flags["fail-closed"];
|
|
821
948
|
const failClosed = fcFlag !== undefined && fcFlag !== false && !/^(false|0)$/i.test(String(fcFlag));
|
|
822
|
-
// Hosted plane (
|
|
949
|
+
// Hosted plane (preview): argv only. Missing or empty path still means hosted (it denies PLANE_CONFIG).
|
|
823
950
|
const planeFlag = parsed.flags["plane-config"];
|
|
824
951
|
const plane = planeFlag === undefined
|
|
825
952
|
? undefined
|
|
@@ -842,16 +969,29 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
842
969
|
process.on("uncaughtException", crash);
|
|
843
970
|
process.on("unhandledRejection", crash);
|
|
844
971
|
}
|
|
972
|
+
// A host that closed its end of stdout must not turn the answer into a crash (EPIPE).
|
|
973
|
+
if (isCliEntry()) {
|
|
974
|
+
process.stdout.on("error", () => undefined);
|
|
975
|
+
process.stderr.on("error", () => undefined);
|
|
976
|
+
}
|
|
845
977
|
let stdinText = "";
|
|
846
978
|
if (!process.stdin.isTTY) {
|
|
847
979
|
stdinText = await new Promise((res) => {
|
|
848
980
|
// Buffer chunks, not string concat - a multibyte UTF-8 char can
|
|
849
981
|
// straddle a chunk boundary.
|
|
850
982
|
const chunks = [];
|
|
983
|
+
const done = () => {
|
|
984
|
+
clearTimeout(timer);
|
|
985
|
+
res(Buffer.concat(chunks).toString("utf8"));
|
|
986
|
+
};
|
|
987
|
+
// A host that never closes stdin would hold the hook for days: decide on what arrived.
|
|
988
|
+
// Fixed on purpose: an env value (a repo can set it in committed settings) must not shorten it
|
|
989
|
+
// and so turn a slow payload into an empty one that the OSS hook allows.
|
|
990
|
+
const timer = setTimeout(done, HOOK_STDIN_TIMEOUT_MS);
|
|
851
991
|
process.stdin.on("data", (c) => chunks.push(c));
|
|
852
992
|
// Pipe errors must not hang the hook - resolve with what arrived.
|
|
853
|
-
process.stdin.on("error",
|
|
854
|
-
process.stdin.on("end",
|
|
993
|
+
process.stdin.on("error", done);
|
|
994
|
+
process.stdin.on("end", done);
|
|
855
995
|
});
|
|
856
996
|
}
|
|
857
997
|
let r;
|
|
@@ -871,36 +1011,80 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
871
1011
|
}
|
|
872
1012
|
return d.code;
|
|
873
1013
|
}
|
|
874
|
-
// Await the write callbacks: pipes can be async, and
|
|
1014
|
+
// Await the write callbacks: pipes can be async, and the exit below must not cut them off.
|
|
875
1015
|
if (r.stdout)
|
|
876
1016
|
await new Promise((ok) => process.stdout.write(r.stdout, () => ok()));
|
|
877
1017
|
if (r.stderr)
|
|
878
1018
|
await new Promise((ok) => process.stderr.write(r.stderr, () => ok()));
|
|
879
|
-
//
|
|
880
|
-
|
|
881
|
-
|
|
1019
|
+
// Exit with the same code once the answer is out and the spawns below are issued. Detached
|
|
1020
|
+
// children (ping, IoC, posture, notify) are unref'd and keep running; no other handle may hold a hook.
|
|
1021
|
+
exitWhenDone = true;
|
|
882
1022
|
// After the answer is out. Opt-in, at most daily, detached: the hook never waits on the network.
|
|
883
1023
|
// Skipped when another hook copy already handled this tool_use_id.
|
|
884
1024
|
if (r.firstSeen !== false)
|
|
885
1025
|
maybeSpawnHookPing({ env, cwd, host });
|
|
1026
|
+
// Daily IoC scan: detached, at most once per 24 h, never awaited. Fail open.
|
|
1027
|
+
const { maybeSpawnIocScan } = await import("./ioc/spawn.js");
|
|
1028
|
+
maybeSpawnIocScan({ env });
|
|
1029
|
+
// Daily posture send: only when the local toggle is on. Detached, at most once per 24 h, never awaited.
|
|
1030
|
+
const { maybeSpawnPostureSend } = await import("./posture/spawn.js");
|
|
1031
|
+
maybeSpawnPostureSend({ env });
|
|
886
1032
|
return r.exitCode;
|
|
887
1033
|
}
|
|
1034
|
+
case "posture": {
|
|
1035
|
+
const { runPosture } = await import("./commands/posture.js");
|
|
1036
|
+
const [sub, ...rest] = parsed.positionals;
|
|
1037
|
+
return await runPosture({
|
|
1038
|
+
io: { log: (line) => io.log(line), error: (line) => io.error(line) },
|
|
1039
|
+
env,
|
|
1040
|
+
sub: parsed.command === "posture" ? sub : undefined,
|
|
1041
|
+
args: rest,
|
|
1042
|
+
flags: parsed.flags,
|
|
1043
|
+
isTty: io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
case "posture-send": {
|
|
1047
|
+
// Internal: detached daily posture send started by the hook (posture/spawn.ts). Not in help.
|
|
1048
|
+
const { runPostureSendDetached } = await import("./commands/posture.js");
|
|
1049
|
+
await runPostureSendDetached(env);
|
|
1050
|
+
return 0;
|
|
1051
|
+
}
|
|
1052
|
+
case "doctor": {
|
|
1053
|
+
const { runDoctor } = await import("./commands/doctor.js");
|
|
1054
|
+
return await runDoctor((line) => io.log(line), {
|
|
1055
|
+
env,
|
|
1056
|
+
iocs: flagBool(parsed.flags, "iocs"),
|
|
1057
|
+
json: flagBool(parsed.flags, "json"),
|
|
1058
|
+
cwd,
|
|
1059
|
+
warn: (line) => io.error(line),
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
case "ioc-scan": {
|
|
1063
|
+
// Internal: detached daily IoC scan started by kya hook (ioc/spawn.ts). Not in help.
|
|
1064
|
+
const { runDetachedIocScan } = await import("./ioc/scan.js");
|
|
1065
|
+
await runDetachedIocScan(env);
|
|
1066
|
+
return 0;
|
|
1067
|
+
}
|
|
888
1068
|
case "import": {
|
|
1069
|
+
const { importOptionsFromArgs, runImport } = await import("./commands/import-traces.js");
|
|
889
1070
|
return await runImport(importOptionsFromArgs(parsed), io, cwd, env);
|
|
890
1071
|
}
|
|
891
1072
|
case "investigate": {
|
|
1073
|
+
const { investigateOptionsFromArgs, runInvestigate } = await import("./commands/investigate.js");
|
|
892
1074
|
return await runInvestigate(investigateOptionsFromArgs(parsed), io, cwd, env);
|
|
893
1075
|
}
|
|
894
1076
|
case "discover": {
|
|
1077
|
+
const { discoverOptionsFromArgs, runDiscover } = await import("./commands/discover.js");
|
|
895
1078
|
return await runDiscover(discoverOptionsFromArgs(parsed), io, cwd, env);
|
|
896
1079
|
}
|
|
897
1080
|
case "notify-flush": {
|
|
1081
|
+
const { runNotifyFlush } = await import("./commands/notify-flush.js");
|
|
898
1082
|
// Internal: spawned detached by hook/wrap (src/notify/dispatch.ts).
|
|
899
1083
|
return await runNotifyFlush(env, cwd);
|
|
900
1084
|
}
|
|
901
1085
|
default:
|
|
902
1086
|
io.error(`Unknown command: ${parsed.command}`);
|
|
903
|
-
io.log(
|
|
1087
|
+
io.log(await helpText());
|
|
904
1088
|
return 2;
|
|
905
1089
|
}
|
|
906
1090
|
}
|