@shield-agent/kya 0.22.0 → 0.23.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.
Files changed (239) hide show
  1. package/.mcp.json +1 -1
  2. package/README.md +72 -30
  3. package/amp/settings.example.json +1 -1
  4. package/claude/claude_desktop_config.example.json +1 -1
  5. package/cline/cline_mcp_settings.example.json +1 -1
  6. package/copilot/mcp-config.example.json +1 -1
  7. package/dist/certify/attest.js +5 -5
  8. package/dist/certify/catalog.d.ts +1 -1
  9. package/dist/certify/catalog.js +3 -3
  10. package/dist/certify/context.js +1 -1
  11. package/dist/certify/evaluate.d.ts +2 -2
  12. package/dist/certify/evaluate.js +12 -12
  13. package/dist/certify/live.js +2 -2
  14. package/dist/certify/render.d.ts +1 -1
  15. package/dist/certify/render.js +10 -10
  16. package/dist/cli.d.ts +2 -2
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +49 -16
  19. package/dist/cli.js.map +1 -1
  20. package/dist/commands/certify.d.ts +1 -1
  21. package/dist/commands/certify.js +3 -3
  22. package/dist/commands/connect.d.ts +2 -2
  23. package/dist/commands/connect.js +22 -22
  24. package/dist/commands/dash.js +4 -4
  25. package/dist/commands/gate-serve.js +3 -3
  26. package/dist/commands/gate.d.ts +1 -1
  27. package/dist/commands/gate.js +16 -16
  28. package/dist/commands/hook.d.ts +1 -1
  29. package/dist/commands/hook.d.ts.map +1 -1
  30. package/dist/commands/hook.js +55 -18
  31. package/dist/commands/hook.js.map +1 -1
  32. package/dist/commands/import-traces.d.ts +16 -0
  33. package/dist/commands/import-traces.d.ts.map +1 -0
  34. package/dist/commands/import-traces.js +18 -0
  35. package/dist/commands/import-traces.js.map +1 -0
  36. package/dist/commands/init.js +1 -1
  37. package/dist/commands/investigate.d.ts +13 -0
  38. package/dist/commands/investigate.d.ts.map +1 -0
  39. package/dist/commands/investigate.js +22 -0
  40. package/dist/commands/investigate.js.map +1 -0
  41. package/dist/commands/notify-flush.d.ts +2 -0
  42. package/dist/commands/notify-flush.d.ts.map +1 -0
  43. package/dist/commands/notify-flush.js +47 -0
  44. package/dist/commands/notify-flush.js.map +1 -0
  45. package/dist/commands/orr.d.ts +3 -3
  46. package/dist/commands/orr.js +5 -5
  47. package/dist/commands/receipt-serve.d.ts +1 -1
  48. package/dist/commands/receipt-serve.js +1 -1
  49. package/dist/commands/serve-mcp.js +1 -1
  50. package/dist/commands/start.d.ts +2 -2
  51. package/dist/commands/start.js +20 -20
  52. package/dist/commands/stop.d.ts +1 -1
  53. package/dist/commands/stop.js +6 -6
  54. package/dist/commands/update.d.ts +19 -0
  55. package/dist/commands/update.d.ts.map +1 -0
  56. package/dist/commands/update.js +96 -0
  57. package/dist/commands/update.js.map +1 -0
  58. package/dist/commands/wire-hooks.d.ts +1 -1
  59. package/dist/commands/wire-hooks.js +14 -14
  60. package/dist/commands/wrap.d.ts.map +1 -1
  61. package/dist/commands/wrap.js +12 -7
  62. package/dist/commands/wrap.js.map +1 -1
  63. package/dist/config.d.ts +4 -4
  64. package/dist/config.js +5 -5
  65. package/dist/dash/dash.d.ts +1 -1
  66. package/dist/dash/dash.js +3 -3
  67. package/dist/dash/entitlement.d.ts +1 -1
  68. package/dist/dash/entitlement.js +1 -1
  69. package/dist/dash/render.js +2 -2
  70. package/dist/dash/screens/enterprise.js +9 -9
  71. package/dist/dash/screens/free.js +5 -5
  72. package/dist/diff-preview.d.ts +1 -1
  73. package/dist/diff-preview.js +2 -2
  74. package/dist/errors.d.ts +1 -1
  75. package/dist/errors.js +1 -1
  76. package/dist/fs-atomic.d.ts +1 -1
  77. package/dist/fs-atomic.js +2 -2
  78. package/dist/gate/binary.js +4 -4
  79. package/dist/gate/config-gen.d.ts +1 -1
  80. package/dist/gate/config-gen.js +7 -7
  81. package/dist/gate/config.d.ts +2 -2
  82. package/dist/gate/config.js +6 -6
  83. package/dist/gate/daemon.js +1 -1
  84. package/dist/gate/discover.d.ts +2 -2
  85. package/dist/gate/discover.js +7 -7
  86. package/dist/gate/hosted-sync.js +1 -1
  87. package/dist/gate/otlp-decode.d.ts +2 -2
  88. package/dist/gate/otlp-decode.js +2 -2
  89. package/dist/gate/otlp-receiver.d.ts +1 -1
  90. package/dist/gate/otlp-receiver.js +3 -3
  91. package/dist/host-reload.js +11 -11
  92. package/dist/host-tools.d.ts +1 -1
  93. package/dist/host-tools.js +1 -1
  94. package/dist/importers/formats.d.ts +26 -0
  95. package/dist/importers/formats.d.ts.map +1 -0
  96. package/dist/importers/formats.js +281 -0
  97. package/dist/importers/formats.js.map +1 -0
  98. package/dist/importers/index.d.ts +26 -0
  99. package/dist/importers/index.d.ts.map +1 -0
  100. package/dist/importers/index.js +122 -0
  101. package/dist/importers/index.js.map +1 -0
  102. package/dist/index.d.ts +1 -1
  103. package/dist/index.js +1 -1
  104. package/dist/investigate/detectors.d.ts +35 -0
  105. package/dist/investigate/detectors.d.ts.map +1 -0
  106. package/dist/investigate/detectors.js +277 -0
  107. package/dist/investigate/detectors.js.map +1 -0
  108. package/dist/investigate/fix-brief.d.ts +3 -0
  109. package/dist/investigate/fix-brief.d.ts.map +1 -0
  110. package/dist/investigate/fix-brief.js +88 -0
  111. package/dist/investigate/fix-brief.js.map +1 -0
  112. package/dist/investigate/incidents.d.ts +19 -0
  113. package/dist/investigate/incidents.d.ts.map +1 -0
  114. package/dist/investigate/incidents.js +84 -0
  115. package/dist/investigate/incidents.js.map +1 -0
  116. package/dist/investigate/index.d.ts +25 -0
  117. package/dist/investigate/index.d.ts.map +1 -0
  118. package/dist/investigate/index.js +46 -0
  119. package/dist/investigate/index.js.map +1 -0
  120. package/dist/mcp/protocol.d.ts +2 -2
  121. package/dist/mcp/protocol.d.ts.map +1 -1
  122. package/dist/mcp/protocol.js +39 -8
  123. package/dist/mcp/protocol.js.map +1 -1
  124. package/dist/mcp/stdio.d.ts +1 -1
  125. package/dist/mcp/stdio.js +2 -2
  126. package/dist/mcp-servers.d.ts +2 -2
  127. package/dist/mcp-servers.js +2 -2
  128. package/dist/node-upgrade.d.ts +2 -2
  129. package/dist/node-upgrade.js +9 -9
  130. package/dist/notify/dispatch.d.ts +20 -0
  131. package/dist/notify/dispatch.d.ts.map +1 -0
  132. package/dist/notify/dispatch.js +52 -0
  133. package/dist/notify/dispatch.js.map +1 -0
  134. package/dist/notify/index.d.ts +39 -0
  135. package/dist/notify/index.d.ts.map +1 -0
  136. package/dist/notify/index.js +119 -0
  137. package/dist/notify/index.js.map +1 -0
  138. package/dist/notify/sender.d.ts +56 -0
  139. package/dist/notify/sender.d.ts.map +1 -0
  140. package/dist/notify/sender.js +139 -0
  141. package/dist/notify/sender.js.map +1 -0
  142. package/dist/notify/templates.d.ts +33 -0
  143. package/dist/notify/templates.d.ts.map +1 -0
  144. package/dist/notify/templates.js +119 -0
  145. package/dist/notify/templates.js.map +1 -0
  146. package/dist/offline-evaluate.d.ts +2 -2
  147. package/dist/offline-evaluate.js +3 -3
  148. package/dist/orr/agentshield.d.ts +2 -2
  149. package/dist/orr/agentshield.js +4 -4
  150. package/dist/orr/scorecard.d.ts +1 -1
  151. package/dist/orr/scorecard.js +3 -3
  152. package/dist/otel/exporter.d.ts +64 -0
  153. package/dist/otel/exporter.d.ts.map +1 -0
  154. package/dist/otel/exporter.js +243 -0
  155. package/dist/otel/exporter.js.map +1 -0
  156. package/dist/parse-args.d.ts +1 -1
  157. package/dist/parse-args.js +1 -1
  158. package/dist/receipt/auto-open.d.ts +1 -1
  159. package/dist/receipt/auto-open.js +1 -1
  160. package/dist/receipt/daemon.d.ts +6 -6
  161. package/dist/receipt/daemon.js +15 -15
  162. package/dist/receipt/dashboard.d.ts +1 -1
  163. package/dist/receipt/dashboard.js +2 -2
  164. package/dist/receipt/embeddings.d.ts +15 -4
  165. package/dist/receipt/embeddings.d.ts.map +1 -1
  166. package/dist/receipt/embeddings.js +116 -35
  167. package/dist/receipt/embeddings.js.map +1 -1
  168. package/dist/receipt/enrich.d.ts +2 -2
  169. package/dist/receipt/enrich.js +5 -5
  170. package/dist/receipt/gate-card.d.ts +2 -2
  171. package/dist/receipt/gate-card.d.ts.map +1 -1
  172. package/dist/receipt/gate-card.js +3 -3
  173. package/dist/receipt/live-server.d.ts.map +1 -1
  174. package/dist/receipt/live-server.js +22 -8
  175. package/dist/receipt/live-server.js.map +1 -1
  176. package/dist/receipt/receipt-css.d.ts +1 -1
  177. package/dist/receipt/receipt-css.d.ts.map +1 -1
  178. package/dist/receipt/receipt-css.js +72 -11
  179. package/dist/receipt/receipt-css.js.map +1 -1
  180. package/dist/receipt/render-receipt.d.ts +1 -1
  181. package/dist/receipt/render-receipt.d.ts.map +1 -1
  182. package/dist/receipt/render-receipt.js +138 -87
  183. package/dist/receipt/render-receipt.js.map +1 -1
  184. package/dist/receipt/share.d.ts +2 -2
  185. package/dist/receipt/share.js +5 -5
  186. package/dist/sample-tools.d.ts +1 -1
  187. package/dist/sample-tools.js +1 -1
  188. package/dist/sandbox/mock-driver.d.ts +1 -1
  189. package/dist/sandbox/mock-driver.js +1 -1
  190. package/dist/sdk/a2a.d.ts +2 -2
  191. package/dist/sdk/a2a.js +1 -1
  192. package/dist/sdk/adapters/claude-agent.d.ts +1 -1
  193. package/dist/sdk/adapters/claude-agent.js +1 -1
  194. package/dist/sdk/adapters/langgraph.d.ts +1 -1
  195. package/dist/sdk/adapters/langgraph.js +1 -1
  196. package/dist/sdk/adapters/mastra.d.ts +1 -1
  197. package/dist/sdk/adapters/mastra.js +1 -1
  198. package/dist/sdk/adapters/openai-agents.d.ts +1 -1
  199. package/dist/sdk/adapters/openai-agents.js +1 -1
  200. package/dist/sdk/adapters/vercel-ai.d.ts +2 -2
  201. package/dist/sdk/adapters/vercel-ai.js +1 -1
  202. package/dist/sdk/govern.d.ts +2 -2
  203. package/dist/sdk/govern.js +3 -3
  204. package/dist/sdk/index.d.ts +1 -1
  205. package/dist/sdk/index.js +1 -1
  206. package/dist/showback/trail-usage.d.ts +30 -0
  207. package/dist/showback/trail-usage.d.ts.map +1 -0
  208. package/dist/showback/trail-usage.js +50 -0
  209. package/dist/showback/trail-usage.js.map +1 -0
  210. package/dist/sign/evidence-bundle.d.ts +6 -6
  211. package/dist/sign/evidence-bundle.js +5 -5
  212. package/dist/star-cta.d.ts +1 -1
  213. package/dist/star-cta.d.ts.map +1 -1
  214. package/dist/star-cta.js +3 -3
  215. package/dist/trail-summary.d.ts +1 -1
  216. package/dist/trail-summary.js +3 -3
  217. package/dist/trail.d.ts +8 -2
  218. package/dist/trail.d.ts.map +1 -1
  219. package/dist/trail.js +18 -5
  220. package/dist/trail.js.map +1 -1
  221. package/dist/update-check.d.ts +17 -0
  222. package/dist/update-check.d.ts.map +1 -0
  223. package/dist/update-check.js +134 -0
  224. package/dist/update-check.js.map +1 -0
  225. package/droid/README.md +1 -1
  226. package/droid/mcp.example.json +1 -1
  227. package/gemini/settings.example.json +1 -1
  228. package/grok/README.md +1 -1
  229. package/kilo/kilo.example.json +1 -1
  230. package/kimi/mcp.example.json +1 -1
  231. package/kiro/mcp.example.json +1 -1
  232. package/manifest.json +1 -1
  233. package/mastracode/mcp.example.json +1 -1
  234. package/mcp.json +1 -1
  235. package/openai/codex.config.example.toml +1 -1
  236. package/opencode/opencode.example.json +1 -1
  237. package/package.json +2 -2
  238. package/qwen/settings.example.json +1 -1
  239. package/server.json +2 -2
package/dist/dash/dash.js CHANGED
@@ -191,7 +191,7 @@ async function loadCases(client) {
191
191
  if (!Array.isArray(rows)) {
192
192
  return [
193
193
  "Cases list is not available on this plane.",
194
- "Use the web console /app/kya/cases (observational — not a PEP).",
194
+ "Use the web console /app/kya/cases (observational - not a PEP).",
195
195
  ];
196
196
  }
197
197
  return casesBody(rows);
@@ -199,7 +199,7 @@ async function loadCases(client) {
199
199
  catch {
200
200
  return [
201
201
  "GET /api/v1/kya/cases is not on this plane yet.",
202
- "Use the web console /app/kya/cases. Observational only — does not approve submit.",
202
+ "Use the web console /app/kya/cases. Observational only - does not approve submit.",
203
203
  ];
204
204
  }
205
205
  }
@@ -220,7 +220,7 @@ async function loadEdge(client) {
220
220
  return { error: "edge status unavailable" };
221
221
  }
222
222
  }
223
- /** Offline sample used by tests — production PEP is HTTP. */
223
+ /** Offline sample used by tests - production PEP is HTTP. */
224
224
  export function offlinePolicyPair() {
225
225
  return {
226
226
  deny: evaluateOffline({
@@ -25,7 +25,7 @@ export interface ResolveEntitlementInput {
25
25
  readonly now?: Date;
26
26
  readonly licensePublicKeyPem?: string;
27
27
  }
28
- /** Placeholder verify key — real issuers replace via KYA_LICENSE_PUBKEY. */
28
+ /** Placeholder verify key - real issuers replace via KYA_LICENSE_PUBKEY. */
29
29
  export declare const DEFAULT_LICENSE_PUBKEY_PEM = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA//////////////////////////////////////////8=\n-----END PUBLIC KEY-----\n";
30
30
  export declare function isEnterprisePane(pane: string): pane is EnterprisePane;
31
31
  export declare function paneAllowed(ent: Entitlement, pane: DashPane): boolean;
@@ -16,7 +16,7 @@ export const FREE_PANES = [
16
16
  "mcp",
17
17
  "sandbox",
18
18
  ];
19
- /** Placeholder verify key — real issuers replace via KYA_LICENSE_PUBKEY. */
19
+ /** Placeholder verify key - real issuers replace via KYA_LICENSE_PUBKEY. */
20
20
  export const DEFAULT_LICENSE_PUBKEY_PEM = `-----BEGIN PUBLIC KEY-----
21
21
  MCowBQYDK2VwAyEA//////////////////////////////////////////8=
22
22
  -----END PUBLIC KEY-----
@@ -42,7 +42,7 @@ export function enterpriseNavLine(ent, active) {
42
42
  .map((p) => (p === active ? `[${p.toUpperCase()}]` : p))
43
43
  .join(" ")}`);
44
44
  }
45
- return clip("ent: (hidden on FREE — set KYA_DASH_PLAN=enterprise to unlock)");
45
+ return clip("ent: (hidden on FREE - set KYA_DASH_PLAN=enterprise to unlock)");
46
46
  }
47
47
  export function lockedPane(pane) {
48
48
  return [
@@ -91,7 +91,7 @@ export function assertNoSecrets(text, extra) {
91
91
  /\bsession=[^\s;&"']{8,}/i,
92
92
  /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/i,
93
93
  /-----END [A-Z0-9 ]*PRIVATE KEY-----/i,
94
- // Keyword assignments require a realistically long value — short benign
94
+ // Keyword assignments require a realistically long value - short benign
95
95
  // mentions ("refreshed token: ab12cd34") must not DoS every render.
96
96
  /\b(password|passwd|secret|token|api[_-]?key)\s*[:=]\s*(?!\[redacted\])[^\s#"']{16,}/i,
97
97
  /\bxox[baprs]-[A-Za-z0-9-]{10,}/i,
@@ -5,12 +5,12 @@ export function dashboardBody(k) {
5
5
  "",
6
6
  ...table(["kpi", "value"], [
7
7
  ["pending approvals", String(k.pendingApprovals)],
8
- ["agents registered", Number.isFinite(k.agentCount) ? String(k.agentCount) : "—"],
9
- ["observed sessions", String(k.sessionCount ?? "—")],
10
- ["high-risk sessions", String(k.highRiskSessions ?? "—")],
11
- ["policy denies", String(k.policyDeny ?? "—")],
12
- ["approve required", String(k.approveRequired ?? "—")],
13
- ["approve granted", String(k.approveGranted ?? "—")],
8
+ ["agents registered", Number.isFinite(k.agentCount) ? String(k.agentCount) : "-"],
9
+ ["observed sessions", String(k.sessionCount ?? "-")],
10
+ ["high-risk sessions", String(k.highRiskSessions ?? "-")],
11
+ ["policy denies", String(k.policyDeny ?? "-")],
12
+ ["approve required", String(k.approveRequired ?? "-")],
13
+ ["approve granted", String(k.approveGranted ?? "-")],
14
14
  ]),
15
15
  "",
16
16
  "Actions that change production still wait for a person.",
@@ -18,7 +18,7 @@ export function dashboardBody(k) {
18
18
  }
19
19
  export function casesBody(rows) {
20
20
  return [
21
- "Evidence & cases (optional disputes pack). Observational — does not approve submit.",
21
+ "Evidence & cases (optional disputes pack). Observational - does not approve submit.",
22
22
  "",
23
23
  ...table(["id", "status", "amount"], rows.map((c) => [c.id, c.status ?? "", c.amount ?? ""])),
24
24
  ];
@@ -32,14 +32,14 @@ export function metricsBody(m) {
32
32
  }
33
33
  export function edgeBody(flags) {
34
34
  return [
35
- "Edge / Gatekeeper (read-only). Complement — not a second PEP.",
35
+ "Edge / Gatekeeper (read-only). Complement - not a second PEP.",
36
36
  "",
37
37
  ...table(["flag", "value"], Object.entries(flags).map(([k, v]) => [k, String(v)])),
38
38
  ];
39
39
  }
40
40
  export function settingsBody(lines) {
41
41
  return [
42
- "Settings (licensed). Team / SSO / keys / billing — same surfaces as the web console.",
42
+ "Settings (licensed). Team / SSO / keys / billing - same surfaces as the web console.",
43
43
  "",
44
44
  ...(lines.length ? lines : ["Connect a plane to load tenant settings."]),
45
45
  ];
@@ -10,7 +10,7 @@ export function homeBody(input) {
10
10
  `offline ${input.offline ? "yes (sample tools, not production PEP)" : "no"}`,
11
11
  `api key ${input.hasApiKey ? "set" : "empty (fail-closed on live panes)"}`,
12
12
  `plane ${input.offline ? "offline" : input.baseUrl}`,
13
- `agentId ${input.agentId ?? "(none — kya register-agent)"}`,
13
+ `agentId ${input.agentId ?? "(none - kya register-agent)"}`,
14
14
  "",
15
15
  "2 policy (e force-eval / w wrap) 3 agents (k kill, confirm y)",
16
16
  "4 approvals (i invoke) 5 sessions (b/R shrink, confirm y)",
@@ -34,7 +34,7 @@ export function policyOfflineBody() {
34
34
  env: { host: "ide" },
35
35
  });
36
36
  return [
37
- "Policy playground (offline sample — not the production PEP).",
37
+ "Policy playground (offline sample - not the production PEP).",
38
38
  "Sole PEP in production is Shield HTTP evaluate.",
39
39
  "",
40
40
  ...table(["tool", "verdict", "reason"], [
@@ -84,7 +84,7 @@ export function agentsLiveBody(rows, cursor = 0) {
84
84
  export function sandboxBody(input) {
85
85
  const lines = [
86
86
  "Sandbox (opt-in Firecracker wrap). Not MCP. Never auto-exec.",
87
- `KYA_SANDBOX ${input.backend || "(unset — set mock|firecracker)"}`,
87
+ `KYA_SANDBOX ${input.backend || "(unset - set mock|firecracker)"}`,
88
88
  "Spawn/exec go through evaluate first. DENY / Hold block side effects.",
89
89
  "",
90
90
  ];
@@ -137,7 +137,7 @@ export function sessionsLiveBody(rows, cursor = 0) {
137
137
  }
138
138
  export function orrBody(summary) {
139
139
  return [
140
- "ORR board (reporting only — not a second PEP).",
140
+ "ORR board (reporting only - not a second PEP).",
141
141
  "Scanners are evidence. Sole PEP remains Shield KYA.",
142
142
  "",
143
143
  summary
@@ -152,7 +152,7 @@ export function mcpBody(input) {
152
152
  " kya serve-mcp --port 13920",
153
153
  " tools: kya.policy_evaluate | kya.session_ingest | kya.request_approval",
154
154
  `host ${input.host}`,
155
- `api key ${input.hasApiKey ? "set" : "empty — serve-mcp will fail-closed"}`,
155
+ `api key ${input.hasApiKey ? "set" : "empty - serve-mcp will fail-closed"}`,
156
156
  "Dash will not start the server (it would steal this TTY).",
157
157
  ];
158
158
  }
@@ -18,7 +18,7 @@ export interface WireChangeFields {
18
18
  }
19
19
  /**
20
20
  * The three change fields the hosted plane persists on the tool event.
21
- * Undefined when opted out or when nothing safe/useful was derivable —
21
+ * Undefined when opted out or when nothing safe/useful was derivable -
22
22
  * evaluate still happens, the fields are simply omitted from the body.
23
23
  */
24
24
  export declare function deriveWireChangeFields(toolId: string, args?: unknown, env?: NodeJS.ProcessEnv): WireChangeFields | undefined;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Clipped, redacted change preview for the activity receipt.
3
- * Never persists full patches — hard caps + redaction only.
3
+ * Never persists full patches - hard caps + redaction only.
4
4
  */
5
5
  import { deriveTargetPath, deriveTrailSummary, redactTrailText } from "./trail-summary.js";
6
6
  import { assertNoSecrets } from "./dash/render.js";
@@ -203,7 +203,7 @@ export function sendPreviewsEnabled(env = process.env) {
203
203
  }
204
204
  /**
205
205
  * The three change fields the hosted plane persists on the tool event.
206
- * Undefined when opted out or when nothing safe/useful was derivable —
206
+ * Undefined when opted out or when nothing safe/useful was derivable -
207
207
  * evaluate still happens, the fields are simply omitted from the body.
208
208
  */
209
209
  export function deriveWireChangeFields(toolId, args, env = process.env) {
package/dist/errors.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- /** Fail-closed CLI / client errors — never silent allow-all. */
1
+ /** Fail-closed CLI / client errors - never silent allow-all. */
2
2
  export declare class KyaError extends Error {
3
3
  readonly code: string;
4
4
  readonly exitCode: number;
package/dist/errors.js CHANGED
@@ -1,4 +1,4 @@
1
- /** Fail-closed CLI / client errors — never silent allow-all. */
1
+ /** Fail-closed CLI / client errors - never silent allow-all. */
2
2
  export class KyaError extends Error {
3
3
  code;
4
4
  exitCode;
@@ -2,7 +2,7 @@
2
2
  * Crash-safe write: tmp file in the same directory, then rename onto the
3
3
  * target (atomic on POSIX and win32 within one volume). A mid-write crash
4
4
  * leaves the original config intact; the tmp file is removed best-effort.
5
- * An existing target's file mode is carried over — a rename would otherwise
5
+ * An existing target's file mode is carried over - a rename would otherwise
6
6
  * turn a 0600 config into the umask default.
7
7
  */
8
8
  export declare function atomicWriteSync(target: string, content: string): void;
package/dist/fs-atomic.js CHANGED
@@ -7,7 +7,7 @@ import { chmodSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs"
7
7
  * Crash-safe write: tmp file in the same directory, then rename onto the
8
8
  * target (atomic on POSIX and win32 within one volume). A mid-write crash
9
9
  * leaves the original config intact; the tmp file is removed best-effort.
10
- * An existing target's file mode is carried over — a rename would otherwise
10
+ * An existing target's file mode is carried over - a rename would otherwise
11
11
  * turn a 0600 config into the umask default.
12
12
  */
13
13
  export function atomicWriteSync(target, content) {
@@ -18,7 +18,7 @@ export function atomicWriteSync(target, content) {
18
18
  mode = statSync(target).mode;
19
19
  }
20
20
  catch {
21
- /* new file — keep default mode */
21
+ /* new file - keep default mode */
22
22
  }
23
23
  writeFileSync(tmp, content, "utf8");
24
24
  if (mode !== undefined) {
@@ -25,7 +25,7 @@ export function resolveGatePlatform(platform = process.platform, arch = process.
25
25
  const os = platform === "darwin" ? "darwin" : platform === "win32" ? "windows" : platform === "linux" ? "linux" : undefined;
26
26
  const a = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : undefined;
27
27
  if (!os || !a) {
28
- throw new KyaError(`no gateway build for ${platform}/${arch} — supported: linux, darwin, windows × amd64, arm64`, "GATE_UNSUPPORTED_PLATFORM");
28
+ throw new KyaError(`no gateway build for ${platform}/${arch} - supported: linux, darwin, windows × amd64, arm64`, "GATE_UNSUPPORTED_PLATFORM");
29
29
  }
30
30
  return { os, arch: a };
31
31
  }
@@ -99,20 +99,20 @@ export async function ensureGateBinary(deps = {}) {
99
99
  try {
100
100
  const [tgzRes, sumRes] = [await fetchFn(base), await fetchFn(`${base}.sha256`)];
101
101
  if (!tgzRes.ok || !sumRes.ok) {
102
- throw new KyaError(`gateway artifact ${name} not available (HTTP ${!tgzRes.ok ? tgzRes.status : sumRes.status}) — gateway binaries are published by the kya release pipeline (see legal/THIRD-PARTY.md); check the release tag gate-v${GATE_VERSION}`, "GATE_DOWNLOAD_FAILED");
102
+ throw new KyaError(`gateway artifact ${name} not available (HTTP ${!tgzRes.ok ? tgzRes.status : sumRes.status}) - gateway binaries are published by the kya release pipeline (see legal/THIRD-PARTY.md); check the release tag gate-v${GATE_VERSION}`, "GATE_DOWNLOAD_FAILED");
103
103
  }
104
104
  const tgz = Buffer.from(await tgzRes.arrayBuffer());
105
105
  const expected = parseSha256File(await sumRes.text());
106
106
  const actual = sha256Hex(tgz);
107
107
  if (actual !== expected) {
108
- throw new KyaError(`gateway artifact checksum mismatch (expected ${expected}, got ${actual}) — refusing to install`, "GATE_CHECKSUM_MISMATCH");
108
+ throw new KyaError(`gateway artifact checksum mismatch (expected ${expected}, got ${actual}) - refusing to install`, "GATE_CHECKSUM_MISMATCH");
109
109
  }
110
110
  const tgzPath = join(stage, name);
111
111
  writeFileSync(tgzPath, tgz);
112
112
  (deps.extract ?? defaultExtract)(tgzPath, stage);
113
113
  const extracted = join(stage, platform === "win32" ? "kya-gate.exe" : "kya-gate");
114
114
  if (!existsSync(extracted)) {
115
- throw new KyaError(`gateway artifact ${name} did not contain a kya-gate binary — corrupt repack?`, "GATE_ARTIFACT_INVALID");
115
+ throw new KyaError(`gateway artifact ${name} did not contain a kya-gate binary - corrupt repack?`, "GATE_ARTIFACT_INVALID");
116
116
  }
117
117
  // Atomic install: stage beside the target, then rename over it.
118
118
  const tmpTarget = join(binDir, `.kya-gate.${process.pid}.tmp`);
@@ -7,7 +7,7 @@ export declare const LOOPBACK_RULE = "cidr(\"127.0.0.0/8\").containsIP(source.ad
7
7
  export declare function denyPatternsFor(serverId: string): readonly string[];
8
8
  /**
9
9
  * Whether an unmatched tool on this server is allowed: the registry
10
- * defaultTier — READ and WRITE both map to allow (WRITE is observed, not
10
+ * defaultTier - READ and WRITE both map to allow (WRITE is observed, not
11
11
  * blocked); an ADMIN default would deny. Unknown servers allow (local
12
12
  * observe gateway), subject to the destructive deny.
13
13
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Generate the gateway YAML from `.kya/gateways.json` + the MCP server
3
3
  * registry tiers. The CEL authorization rules are always derived from the
4
- * registry — never hand-written:
4
+ * registry - never hand-written:
5
5
  *
6
6
  * - destructive names (drop|truncate|purge|transfer, word-boundary anchored
7
7
  * so `dropdown_select` is untouched) are denied for every server, and
@@ -9,7 +9,7 @@
9
9
  * "allow … AND NOT matches(deny)");
10
10
  * - the server's ADMIN-tier registry patterns join the deny set;
11
11
  * - everything else on the target is allowed: READ → allow, WRITE → allow
12
- * (observe mode — allowed calls are audited, not blocked), and unmatched
12
+ * (observe mode - allowed calls are audited, not blocked), and unmatched
13
13
  * tools follow the server's defaultTier, which for every registered
14
14
  * server resolves to one of those two allows;
15
15
  * - unknown servers get the destructive-name deny only.
@@ -18,8 +18,8 @@
18
18
  * denies the call (and filters it from tools/list).
19
19
  *
20
20
  * Listener hardening: the binary binds UNSPECIFIED with no config knob, so
21
- * exposure is cut at L4 — a frontend networkAuthorization allowlist permits
22
- * only loopback sources (127.0.0.0/8, ::1) — and the stats/readiness/admin
21
+ * exposure is cut at L4 - a frontend networkAuthorization allowlist permits
22
+ * only loopback sources (127.0.0.0/8, ::1) - and the stats/readiness/admin
23
23
  * listeners are turned off entirely. Logging is pinned to warn so module
24
24
  * noise (and upstream build strings) stays out of gate.log.
25
25
  */
@@ -35,7 +35,7 @@ export function denyPatternsFor(serverId) {
35
35
  }
36
36
  /**
37
37
  * Whether an unmatched tool on this server is allowed: the registry
38
- * defaultTier — READ and WRITE both map to allow (WRITE is observed, not
38
+ * defaultTier - READ and WRITE both map to allow (WRITE is observed, not
39
39
  * blocked); an ADMIN default would deny. Unknown servers allow (local
40
40
  * observe gateway), subject to the destructive deny.
41
41
  */
@@ -50,7 +50,7 @@ export function celAllowRule(server) {
50
50
  const target = `mcp.tool.target == ${celString(server.id)}`;
51
51
  const deny = denyPatternsFor(server.id).join("|");
52
52
  if (!unmatchedAllowed(server.id)) {
53
- // ADMIN defaultTier: only explicitly non-denied, non-admin tools may run —
53
+ // ADMIN defaultTier: only explicitly non-denied, non-admin tools may run -
54
54
  // allow nothing unmatched (no registered server has this today).
55
55
  return `${target} && false`;
56
56
  }
@@ -102,7 +102,7 @@ function targetYaml(server) {
102
102
  */
103
103
  export function generateGatewayYaml(config) {
104
104
  const lines = [
105
- "# Generated by kya gate — regenerate with `kya gate run` (do not edit).",
105
+ "# Generated by kya gate - regenerate with `kya gate run` (do not edit).",
106
106
  "config:",
107
107
  ' statsAddr: "off"',
108
108
  ' readinessAddr: "off"',
@@ -20,7 +20,7 @@ export interface GatewaysConfig {
20
20
  /**
21
21
  * Gateway behavior when a target fails to initialize: failOpen serves the
22
22
  * healthy targets (default, better local UX); failClosed takes the whole
23
- * gateway down (strict — a silently missing server is impossible).
23
+ * gateway down (strict - a silently missing server is impossible).
24
24
  */
25
25
  readonly failureMode: GateFailureMode;
26
26
  readonly servers: readonly GatewayServer[];
@@ -33,7 +33,7 @@ export declare function validateGateways(raw: unknown): GatewaysConfig;
33
33
  export declare function readGateways(env?: NodeJS.ProcessEnv): GatewaysConfig;
34
34
  /**
35
35
  * Scaffold `.kya/gateways.json`: an empty active `servers` list plus the
36
- * `recipes` catalog — move a recipe object into `servers` and fill its
36
+ * `recipes` catalog - move a recipe object into `servers` and fill its
37
37
  * placeholders to enable it. Idempotent: an existing file is left alone.
38
38
  */
39
39
  export declare function scaffoldGateways(env?: NodeJS.ProcessEnv): {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `.kya/gateways.json` — the upstream MCP servers the local kya gateway
2
+ * `.kya/gateways.json` - the upstream MCP servers the local kya gateway
3
3
  * federates. Strict JSON (hand-editable, merge-safe); `kya gate init` seeds
4
4
  * it with a `recipes` catalog of ready-to-move entries for the well-known
5
5
  * servers from the MCP server registry.
@@ -77,7 +77,7 @@ function parseServer(raw, index) {
77
77
  }
78
78
  if (transport === "http" && env) {
79
79
  // The gateway's http targets have no env concept; auth travels as headers.
80
- throw new UsageError(`${where}: transport "http" does not support "env" — use "headers" (e.g. {"authorization": "Bearer …"})`);
80
+ throw new UsageError(`${where}: transport "http" does not support "env" - use "headers" (e.g. {"authorization": "Bearer …"})`);
81
81
  }
82
82
  if (transport === "stdio" && headers) {
83
83
  throw new UsageError(`${where}: "headers" only applies to transport "http"`);
@@ -157,13 +157,13 @@ export function readGateways(env = process.env) {
157
157
  raw = JSON.parse(readFileSync(path, "utf8"));
158
158
  }
159
159
  catch {
160
- throw new UsageError(`${path} is not valid JSON — fix it by hand, then re-run kya gate run`);
160
+ throw new UsageError(`${path} is not valid JSON - fix it by hand, then re-run kya gate run`);
161
161
  }
162
162
  return persistInstanceId(path, raw, randomUUID());
163
163
  }
164
164
  const RECIPES = [
165
165
  { id: "playwright", transport: "stdio", cmd: ["npx", "-y", "@playwright/mcp@latest"], note: "Browser automation" },
166
- { id: "github", transport: "http", url: "https://api.githubcopilot.com/mcp/", headers: { authorization: "Bearer <github-pat>" }, note: "GitHub (remote; auth travels as a header — the gateway's http targets have no env)" },
166
+ { id: "github", transport: "http", url: "https://api.githubcopilot.com/mcp/", headers: { authorization: "Bearer <github-pat>" }, note: "GitHub (remote; auth travels as a header - the gateway's http targets have no env)" },
167
167
  { id: "slack", transport: "stdio", cmd: ["npx", "-y", "@modelcontextprotocol/server-slack"], env: { SLACK_BOT_TOKEN: "<xoxb-…>", SLACK_TEAM_ID: "<T…>" }, note: "Slack workspace" },
168
168
  { id: "postgresql", transport: "stdio", cmd: ["npx", "-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"], note: "PostgreSQL (pass the connection string as the last arg)" },
169
169
  { id: "filesystem", transport: "stdio", cmd: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."], note: "Local filesystem (scope = last args)" },
@@ -185,7 +185,7 @@ const RECIPES = [
185
185
  ];
186
186
  /**
187
187
  * Scaffold `.kya/gateways.json`: an empty active `servers` list plus the
188
- * `recipes` catalog — move a recipe object into `servers` and fill its
188
+ * `recipes` catalog - move a recipe object into `servers` and fill its
189
189
  * placeholders to enable it. Idempotent: an existing file is left alone.
190
190
  */
191
191
  export function scaffoldGateways(env = process.env) {
@@ -196,7 +196,7 @@ export function scaffoldGateways(env = process.env) {
196
196
  const doc = {
197
197
  port: GATE_DEFAULT_PORT,
198
198
  // failOpen: one broken target never takes the gateway down (a missing
199
- // server then fails silently — its tools just vanish). failClosed is the
199
+ // server then fails silently - its tools just vanish). failClosed is the
200
200
  // strict choice: any broken target stops the whole gateway.
201
201
  failureMode: "failOpen",
202
202
  instanceId: randomUUID(),
@@ -40,7 +40,7 @@ export function readGateState(env = process.env) {
40
40
  }
41
41
  }
42
42
  catch {
43
- /* corrupt state — treat as absent */
43
+ /* corrupt state - treat as absent */
44
44
  }
45
45
  return undefined;
46
46
  }
@@ -29,7 +29,7 @@ export interface GateImportResult {
29
29
  /**
30
30
  * Merge discovered candidates into gateways.json `servers`. Hand-configured
31
31
  * entries and other top-level keys (recipes) are preserved; ids already
32
- * present are skipped — an already-imported entry only unions new source
32
+ * present are skipped - an already-imported entry only unions new source
33
33
  * hosts into its `importedFrom`, a hand-configured entry is left byte-identical.
34
34
  */
35
35
  export declare function importGateCandidates(candidates: readonly GateCandidate[], env?: NodeJS.ProcessEnv): GateImportResult;
@@ -42,7 +42,7 @@ export interface HostEntryRemoval {
42
42
  /**
43
43
  * Remove the given server ids from a host's user-level config, after copying
44
44
  * the full original under <global .kya>/backups. Only the listed ids are
45
- * touched — shield-kya entries and every other setting survive. Returns
45
+ * touched - shield-kya entries and every other setting survive. Returns
46
46
  * undefined (and writes nothing) when the file is missing, unparseable, or
47
47
  * carries none of the ids.
48
48
  */
@@ -114,7 +114,7 @@ function tomlStringArray(body, key) {
114
114
  return v;
115
115
  }
116
116
  catch {
117
- /* single-quoted TOML strings etc. — no args */
117
+ /* single-quoted TOML strings etc. - no args */
118
118
  }
119
119
  return undefined;
120
120
  }
@@ -191,7 +191,7 @@ export function discoverGateServers(home) {
191
191
  : candidatesFromJson(text, spec.rootKey);
192
192
  }
193
193
  catch {
194
- continue; // unparseable host config — skip the host, keep the rest
194
+ continue; // unparseable host config - skip the host, keep the rest
195
195
  }
196
196
  for (const [rawKey, core] of entries) {
197
197
  const id = sanitizeServerId(rawKey);
@@ -212,7 +212,7 @@ export function discoverGateServers(home) {
212
212
  /**
213
213
  * Merge discovered candidates into gateways.json `servers`. Hand-configured
214
214
  * entries and other top-level keys (recipes) are preserved; ids already
215
- * present are skipped — an already-imported entry only unions new source
215
+ * present are skipped - an already-imported entry only unions new source
216
216
  * hosts into its `importedFrom`, a hand-configured entry is left byte-identical.
217
217
  */
218
218
  export function importGateCandidates(candidates, env = process.env) {
@@ -226,15 +226,15 @@ export function importGateCandidates(candidates, env = process.env) {
226
226
  parsed = JSON.parse(readFileSync(path, "utf8"));
227
227
  }
228
228
  catch {
229
- throw new UsageError(`${path} is not valid JSON — fix it by hand, then re-run kya start`);
229
+ throw new UsageError(`${path} is not valid JSON - fix it by hand, then re-run kya start`);
230
230
  }
231
231
  if (!isPlainObject(parsed)) {
232
- throw new UsageError(`${path} must be a JSON object — fix it by hand, then re-run kya start`);
232
+ throw new UsageError(`${path} must be a JSON object - fix it by hand, then re-run kya start`);
233
233
  }
234
234
  raw = parsed;
235
235
  }
236
236
  if (raw["servers"] !== undefined && !Array.isArray(raw["servers"])) {
237
- throw new UsageError(`${path}: "servers" must be an array — fix it by hand, then re-run kya start`);
237
+ throw new UsageError(`${path}: "servers" must be an array - fix it by hand, then re-run kya start`);
238
238
  }
239
239
  const servers = Array.isArray(raw["servers"]) ? [...raw["servers"]] : [];
240
240
  const imported = [];
@@ -320,7 +320,7 @@ function removeTomlTables(text, ids) {
320
320
  /**
321
321
  * Remove the given server ids from a host's user-level config, after copying
322
322
  * the full original under <global .kya>/backups. Only the listed ids are
323
- * touched — shield-kya entries and every other setting survive. Returns
323
+ * touched - shield-kya entries and every other setting survive. Returns
324
324
  * undefined (and writes nothing) when the file is missing, unparseable, or
325
325
  * carries none of the ids.
326
326
  */
@@ -132,7 +132,7 @@ export function triggerHostedSyncFromEnv(input) {
132
132
  });
133
133
  }
134
134
  catch {
135
- /* best-effort — sync must never break gate commands */
135
+ /* best-effort - sync must never break gate commands */
136
136
  }
137
137
  }
138
138
  //# sourceMappingURL=hosted-sync.js.map
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Minimal OTLP wire decode for ExportTraceServiceRequest — protobuf (OTLP/HTTP
2
+ * Minimal OTLP wire decode for ExportTraceServiceRequest - protobuf (OTLP/HTTP
3
3
  * default) and OTLP/JSON. Only the fields the gate consumes are read (span
4
4
  * name, string/int/bool attributes, status); every other field is skipped by
5
- * wire type. Tool arguments are never extracted — the whitelist lives in
5
+ * wire type. Tool arguments are never extracted - the whitelist lives in
6
6
  * otlp-receiver.ts.
7
7
  */
8
8
  export interface DecodedSpan {
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Minimal OTLP wire decode for ExportTraceServiceRequest — protobuf (OTLP/HTTP
2
+ * Minimal OTLP wire decode for ExportTraceServiceRequest - protobuf (OTLP/HTTP
3
3
  * default) and OTLP/JSON. Only the fields the gate consumes are read (span
4
4
  * name, string/int/bool attributes, status); every other field is skipped by
5
- * wire type. Tool arguments are never extracted — the whitelist lives in
5
+ * wire type. Tool arguments are never extracted - the whitelist lives in
6
6
  * otlp-receiver.ts.
7
7
  */
8
8
  const WIRE_VARINT = 0;
@@ -28,7 +28,7 @@ export interface OtlpReceiverOptions {
28
28
  }
29
29
  /**
30
30
  * Accept OTLP trace exports on 127.0.0.1 and append tools/call spans to the
31
- * trail. Malformed payloads get a 400 and are dropped — the receiver never
31
+ * trail. Malformed payloads get a 400 and are dropped - the receiver never
32
32
  * dies on bad input (the gateway keeps exporting).
33
33
  */
34
34
  export declare function startOtlpReceiver(opts: OtlpReceiverOptions): Promise<OtlpReceiver>;
@@ -8,7 +8,7 @@
8
8
  * name, session id). Tool arguments are never extracted, and the persisted
9
9
  * fields pass through the secret scanner before hitting the trail.
10
10
  *
11
- * Known limitation: the receiver is unauthenticated — any local process can
11
+ * Known limitation: the receiver is unauthenticated - any local process can
12
12
  * POST spans and inject trail events. That is the same trust boundary as the
13
13
  * user-writable trail file itself (any local process can append to
14
14
  * ~/.kya/trail.jsonl), so no new privilege is granted; remote injection is
@@ -25,7 +25,7 @@ const TWIN_TTL_MS = 30_000;
25
25
  // refused as `-32602 Unknown tool` over HTTP 400; the span carries ERROR
26
26
  // status and an "Unknown tool" error message. Downstream API denials (a
27
27
  // tool's own 403/"forbidden" result) are NOT policy denials and must not
28
- // match this signal — they classify as TOOL_ERROR.
28
+ // match this signal - they classify as TOOL_ERROR.
29
29
  const DENIAL_SIGNAL = /\bunknown tool\b/i;
30
30
  function attr(span, key) {
31
31
  const v = span.attributes[key];
@@ -88,7 +88,7 @@ function readBody(req) {
88
88
  }
89
89
  /**
90
90
  * Accept OTLP trace exports on 127.0.0.1 and append tools/call spans to the
91
- * trail. Malformed payloads get a 400 and are dropped — the receiver never
91
+ * trail. Malformed payloads get a 400 and are dropped - the receiver never
92
92
  * dies on bad input (the gateway keeps exporting).
93
93
  */
94
94
  export async function startOtlpReceiver(opts) {
@@ -1,15 +1,15 @@
1
1
  /**
2
- * Per-host MCP reload behavior — researched against official docs, 2026-09.
2
+ * Per-host MCP reload behavior - researched against official docs, 2026-09.
3
3
  * The blanket "restart your host" instruction was wrong for most hosts: many
4
4
  * watch their config file (or offer an in-session reload) and pick up a new
5
5
  * server with no restart at all. Messaging in `connect` / `start` is built
6
6
  * from this table, and docs/hosts/<id>.md pages mirror it.
7
7
  *
8
8
  * Classes:
9
- * auto — new server is picked up in the running host (file watcher or
9
+ * auto - new server is picked up in the running host (file watcher or
10
10
  * in-session refresh; detail says which)
11
- * session — loads in the next session/conversation; app stays open
12
- * restart — process must be relaunched (resumeTip preserves context if any)
11
+ * session - loads in the next session/conversation; app stays open
12
+ * restart - process must be relaunched (resumeTip preserves context if any)
13
13
  */
14
14
  import { execFileSync } from "node:child_process";
15
15
  export const HOST_RELOAD = {
@@ -22,7 +22,7 @@ export const HOST_RELOAD = {
22
22
  kiro: {
23
23
  id: "kiro",
24
24
  reload: "auto",
25
- detail: "Kiro hot-reloads mcp.json on save — only the new server starts",
25
+ detail: "Kiro hot-reloads mcp.json on save - only the new server starts",
26
26
  processNames: ["kiro", "kiro-cli"],
27
27
  },
28
28
  qwen: {
@@ -64,7 +64,7 @@ export const HOST_RELOAD = {
64
64
  kimi: {
65
65
  id: "kimi",
66
66
  reload: "session",
67
- detail: "Kimi Code registers MCP servers at session start — a new session is enough",
67
+ detail: "Kimi Code registers MCP servers at session start - a new session is enough",
68
68
  processNames: ["kimi"],
69
69
  },
70
70
  claude: {
@@ -141,15 +141,15 @@ export function hostRunning(info, procs) {
141
141
  export function reloadMessage(info, label, running) {
142
142
  switch (info.reload) {
143
143
  case "auto":
144
- return `No restart needed — ${info.detail}.`;
144
+ return `No restart needed - ${info.detail}.`;
145
145
  case "session":
146
146
  return running
147
- ? `${label} is running — start a new session to load shield-kya (${info.detail}). No app restart.`
148
- : `shield-kya loads in your next ${label} session — no restart needed.`;
147
+ ? `${label} is running - start a new session to load shield-kya (${info.detail}). No app restart.`
148
+ : `shield-kya loads in your next ${label} session - no restart needed.`;
149
149
  case "restart":
150
150
  return running
151
- ? `${label} is running — relaunch it to load shield-kya (${info.detail}${info.resumeTip ? `; ${info.resumeTip}` : ""}).`
152
- : `shield-kya loads when you next start ${label} — it is not running, so nothing to restart.`;
151
+ ? `${label} is running - relaunch it to load shield-kya (${info.detail}${info.resumeTip ? `; ${info.resumeTip}` : ""}).`
152
+ : `shield-kya loads when you next start ${label} - it is not running, so nothing to restart.`;
153
153
  }
154
154
  }
155
155
  //# sourceMappingURL=host-reload.js.map
@@ -3,6 +3,6 @@
3
3
  * Advisory only: production authorization stays with the control plane.
4
4
  */
5
5
  export type HostToolTier = "READ" | "WRITE" | "SHELL";
6
- /** Lookup is case-insensitive; only `__`-qualified names (mcp__*, server__tool) stay unknown — a bare `read_file` from an MCP filesystem server still matches READ, which is deliberate: reads are reads in this advisory vocabulary. */
6
+ /** Lookup is case-insensitive; only `__`-qualified names (mcp__*, server__tool) stay unknown - a bare `read_file` from an MCP filesystem server still matches READ, which is deliberate: reads are reads in this advisory vocabulary. */
7
7
  export declare function findHostToolTier(toolId: string): HostToolTier | undefined;
8
8
  //# sourceMappingURL=host-tools.d.ts.map
@@ -13,7 +13,7 @@ const HOST_TOOLS = {
13
13
  // shell / exec
14
14
  bash: "SHELL", run_terminal_command: "SHELL",
15
15
  };
16
- /** Lookup is case-insensitive; only `__`-qualified names (mcp__*, server__tool) stay unknown — a bare `read_file` from an MCP filesystem server still matches READ, which is deliberate: reads are reads in this advisory vocabulary. */
16
+ /** Lookup is case-insensitive; only `__`-qualified names (mcp__*, server__tool) stay unknown - a bare `read_file` from an MCP filesystem server still matches READ, which is deliberate: reads are reads in this advisory vocabulary. */
17
17
  export function findHostToolTier(toolId) {
18
18
  const id = toolId.trim().toLowerCase();
19
19
  if (!id || id.includes("__"))