@co0ontty/wand 4.82.0 → 4.83.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.
Files changed (91) hide show
  1. package/README.md +47 -9
  2. package/dist/agent-dispatch.d.ts +3 -2
  3. package/dist/agent-dispatch.js +19 -3
  4. package/dist/ai-team-delivery-types.d.ts +40 -0
  5. package/dist/ai-team-delivery-types.js +1 -0
  6. package/dist/ai-team-delivery.d.ts +13 -0
  7. package/dist/ai-team-delivery.js +89 -0
  8. package/dist/ai-team-employee-binding.d.ts +16 -0
  9. package/dist/ai-team-employee-binding.js +77 -0
  10. package/dist/ai-team-prompts.js +5 -0
  11. package/dist/ai-team-runner.d.ts +9 -2
  12. package/dist/ai-team-runner.js +52 -7
  13. package/dist/ai-team-types.d.ts +17 -3
  14. package/dist/ai-team-types.js +43 -3
  15. package/dist/build-info.json +3 -3
  16. package/dist/cli.js +36 -0
  17. package/dist/config.d.ts +18 -10
  18. package/dist/config.js +63 -105
  19. package/dist/decision-client.d.ts +4 -0
  20. package/dist/decision-client.js +91 -0
  21. package/dist/decision-runner.d.ts +9 -0
  22. package/dist/decision-runner.js +36 -0
  23. package/dist/decision-service.d.ts +46 -0
  24. package/dist/decision-service.js +230 -0
  25. package/dist/decision-skill.d.ts +6 -0
  26. package/dist/decision-skill.js +70 -0
  27. package/dist/decision-tool.d.ts +21 -0
  28. package/dist/decision-tool.js +346 -0
  29. package/dist/decision-types.d.ts +36 -0
  30. package/dist/decision-types.js +123 -0
  31. package/dist/decision-worker.py +86 -0
  32. package/dist/default-employee.d.ts +4 -1
  33. package/dist/default-employee.js +11 -1
  34. package/dist/env-utils.js +3 -0
  35. package/dist/git-quick-commit.js +7 -1
  36. package/dist/message-truncator.d.ts +1 -1
  37. package/dist/message-truncator.js +29 -22
  38. package/dist/models.d.ts +1 -0
  39. package/dist/models.js +31 -4
  40. package/dist/process-manager.d.ts +39 -1
  41. package/dist/process-manager.js +112 -8
  42. package/dist/provider-catalog.d.ts +47 -0
  43. package/dist/provider-catalog.js +138 -0
  44. package/dist/provider-cli-updater.d.ts +1 -1
  45. package/dist/pty-foreground.d.ts +37 -0
  46. package/dist/pty-foreground.js +56 -0
  47. package/dist/pty-turn-activity.d.ts +6 -5
  48. package/dist/pty-turn-activity.js +6 -5
  49. package/dist/retention.d.ts +29 -0
  50. package/dist/retention.js +142 -0
  51. package/dist/server-ai-team-routes.d.ts +2 -1
  52. package/dist/server-ai-team-routes.js +27 -9
  53. package/dist/server-decision-routes.d.ts +10 -0
  54. package/dist/server-decision-routes.js +52 -0
  55. package/dist/server-employee-routes.js +9 -1
  56. package/dist/server-session-routes.d.ts +2 -2
  57. package/dist/server-session-routes.js +97 -1
  58. package/dist/server-settings-routes.js +10 -36
  59. package/dist/server-update-routes.js +2 -1
  60. package/dist/server-workspace-routes.js +8 -0
  61. package/dist/server.js +37 -5
  62. package/dist/session-completion-state.d.ts +26 -0
  63. package/dist/session-completion-state.js +30 -0
  64. package/dist/session-completion.d.ts +12 -0
  65. package/dist/session-completion.js +62 -0
  66. package/dist/session-provider.d.ts +1 -15
  67. package/dist/session-provider.js +4 -54
  68. package/dist/session-registry.d.ts +5 -0
  69. package/dist/session-registry.js +19 -1
  70. package/dist/session-transport.js +2 -0
  71. package/dist/storage.d.ts +12 -0
  72. package/dist/storage.js +119 -16
  73. package/dist/structured-client-protocol.js +36 -1
  74. package/dist/structured-provider-common.js +3 -3
  75. package/dist/structured-session-manager.d.ts +13 -1
  76. package/dist/structured-session-manager.js +196 -27
  77. package/dist/system-employee.js +1 -0
  78. package/dist/task-types.d.ts +4 -2
  79. package/dist/tool-preview.d.ts +8 -0
  80. package/dist/tool-preview.js +158 -0
  81. package/dist/types.d.ts +35 -2
  82. package/dist/web-ui/content/ai-teams.js +13 -13
  83. package/dist/web-ui/content/scripts.js +66 -64
  84. package/dist/web-ui/content/styles.css +1 -1
  85. package/dist/web-ui/content/tailwind.css +3 -0
  86. package/dist/web-ui/embedded-assets.js +3 -3
  87. package/dist/web-ui/provider-identity.d.ts +7 -13
  88. package/dist/web-ui/provider-identity.js +8 -71
  89. package/package.json +3 -2
  90. package/skills/wand-decision/SKILL.md +61 -0
  91. package/skills/wand-decision/scripts/decide.mjs +16 -0
@@ -1,17 +1,11 @@
1
- export declare const PROVIDER_IDS: readonly ["claude", "codex", "opencode", "grok", "qoder", "pi", "gemini"];
2
- export type ProviderId = (typeof PROVIDER_IDS)[number];
3
- /** Normalizes a persisted provider id or provider-runner alias. */
4
- export declare function normalizeProviderId(value: unknown): ProviderId | null;
5
- /**
6
- * Infers old sessions from the command's executable only. Arguments and parent
7
- * directory names must not be allowed to impersonate a different provider.
8
- */
9
- export declare function inferProviderIdFromCommand(value: unknown): ProviderId | null;
10
- /** provider 对应的 CLI 可执行文件名(Qoder 的 CLI 叫 qodercli)。 */
11
- export declare function providerCliCommand(provider: string): string;
12
- /** 严格判断:只接受 6 个 provider 字面量,不做别名 / 大小写归一。 */
1
+ import { SESSION_PROVIDERS as PROVIDER_IDS, inferProviderFromCommand, normalizeProviderId, type SessionProvider } from "../provider-catalog.js";
2
+ export { inferProviderFromCommand, providerCliCommand, providerDisplayName, isNativeThinkingEffort, NATIVE_THINKING_EFFORT_PATTERN, PROVIDER_LABELS, } from "../provider-catalog.js";
3
+ export { PROVIDER_IDS, normalizeProviderId };
4
+ export type ProviderId = SessionProvider;
5
+ /** 兼容旧名:浏览器层的调用点叫 inferProviderIdFromCommand。 */
6
+ export declare const inferProviderIdFromCommand: typeof inferProviderFromCommand;
7
+ /** 严格判断:只接受 7 个 provider 字面量,不做别名 / 大小写归一。 */
13
8
  export declare function isProviderId(value: unknown): value is ProviderId;
14
- export declare function providerDisplayName(value: unknown): string;
15
9
  export declare const CLAUDE_BRAND_COLOR = "#D97757";
16
10
  export declare const CLAUDE_LOGO_PATH = "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z";
17
11
  export declare const CODEX_LOGO_PATH = "M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z";
@@ -1,78 +1,15 @@
1
- export const PROVIDER_IDS = ["claude", "codex", "opencode", "grok", "qoder", "pi", "gemini"];
1
+ // Provider 的列表 / 别名 / 展示名 / 推断规则统一在 src/provider-catalog.ts(服务端共用)。
2
+ // 这里只补充浏览器层特有的品牌 logo 与 HTML 渲染。
3
+ import { SESSION_PROVIDERS as PROVIDER_IDS, inferProviderFromCommand, normalizeProviderId, } from "../provider-catalog.js";
4
+ export { inferProviderFromCommand, providerCliCommand, providerDisplayName, isNativeThinkingEffort, NATIVE_THINKING_EFFORT_PATTERN, PROVIDER_LABELS, } from "../provider-catalog.js";
5
+ export { PROVIDER_IDS, normalizeProviderId };
6
+ /** 兼容旧名:浏览器层的调用点叫 inferProviderIdFromCommand。 */
7
+ export const inferProviderIdFromCommand = inferProviderFromCommand;
2
8
  const PROVIDER_ID_SET = new Set(PROVIDER_IDS);
3
- const PROVIDER_LABELS = {
4
- claude: "Claude",
5
- codex: "Codex",
6
- opencode: "OpenCode",
7
- grok: "Grok",
8
- qoder: "Qoder",
9
- pi: "Pi",
10
- gemini: "Gemini",
11
- };
12
- const PROVIDER_ALIASES = {
13
- anthropic: "claude",
14
- claude: "claude",
15
- "claude-cli": "claude",
16
- "claude-cli-print": "claude",
17
- codex: "codex",
18
- "codex-cli": "codex",
19
- "codex-cli-exec": "codex",
20
- grok: "grok",
21
- "grok-cli": "grok",
22
- "grok-cli-headless": "grok",
23
- "open-code": "opencode",
24
- open_code: "opencode",
25
- opencode: "opencode",
26
- "opencode-cli-run": "opencode",
27
- qoder: "qoder",
28
- "qoder-cli": "qoder",
29
- "qoder-cli-print": "qoder",
30
- qodercli: "qoder",
31
- pi: "pi",
32
- "pi-cli": "pi",
33
- "pi-cli-json": "pi",
34
- gemini: "gemini",
35
- "gemini-cli": "gemini",
36
- "gemini-cli-json": "gemini",
37
- };
38
- /** Normalizes a persisted provider id or provider-runner alias. */
39
- export function normalizeProviderId(value) {
40
- if (typeof value !== "string")
41
- return null;
42
- const normalized = value.trim().toLowerCase();
43
- return normalized ? PROVIDER_ALIASES[normalized] ?? null : null;
44
- }
45
- /**
46
- * Infers old sessions from the command's executable only. Arguments and parent
47
- * directory names must not be allowed to impersonate a different provider.
48
- */
49
- export function inferProviderIdFromCommand(value) {
50
- if (typeof value !== "string")
51
- return null;
52
- const command = value.trim();
53
- if (!command)
54
- return null;
55
- const match = command.match(/^(?:"([^"]+)"|'([^']+)'|(\S+))/);
56
- const executablePath = match?.[1] ?? match?.[2] ?? match?.[3] ?? "";
57
- const executable = executablePath.split(/[\\/]/).pop()?.replace(/\.(?:cmd|exe)$/i, "") ?? "";
58
- return normalizeProviderId(executable);
59
- }
60
- /** provider 对应的 CLI 可执行文件名(Qoder 的 CLI 叫 qodercli)。 */
61
- export function providerCliCommand(provider) {
62
- return provider === "qoder" ? "qodercli" : provider;
63
- }
64
- /** 严格判断:只接受 6 个 provider 字面量,不做别名 / 大小写归一。 */
9
+ /** 严格判断:只接受 7 个 provider 字面量,不做别名 / 大小写归一。 */
65
10
  export function isProviderId(value) {
66
11
  return typeof value === "string" && PROVIDER_ID_SET.has(value);
67
12
  }
68
- export function providerDisplayName(value) {
69
- if (typeof value === "string" && value.trim().toLowerCase() === "terminal")
70
- return "终端";
71
- const provider = normalizeProviderId(value);
72
- if (provider)
73
- return PROVIDER_LABELS[provider];
74
- return typeof value === "string" && value.trim() ? value.trim() : "AI";
75
- }
76
13
  // Claude/Codex paths match the existing Android BrandLogos source (simple-icons,
77
14
  // CC0). Grok uses xAI's mark path already shipped by the Web new-session view.
78
15
  // Claude keeps the official Anthropic orange instead of inheriting Wand accent.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "4.82.0",
3
+ "version": "4.83.1",
4
4
  "description": "A web console for Claude Code, Codex, OpenCode, and other local CLI tools.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,6 +13,7 @@
13
13
  },
14
14
  "files": [
15
15
  "dist",
16
+ "skills/wand-decision",
16
17
  "browser-extension",
17
18
  "scripts/install-render-binary.js",
18
19
  "scripts/stage-render-binaries.js"
@@ -21,7 +22,7 @@
21
22
  "scripts": {
22
23
  "generate:web-assets": "node scripts/generate-web-assets.js",
23
24
  "build": "node scripts/check-node-version.js && rm -rf dist && node scripts/bundle-tailwind.js && node scripts/bundle-xterm.js && node scripts/bundle-qrcode.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc -p tsconfig.json && npm run build:copy-content && node scripts/check-bundle-budget.js && (npm run build:render-bin || echo '[wand] WARNING: build:render-bin failed; dist/native/ has no wand-render (run: npm run build:render-bin)' >&2) && node scripts/stamp-build-info.js && node scripts/fix-dist-permissions.js",
24
- "build:copy-content": "cp -r src/web-ui/content dist/web-ui/ && node scripts/minify-dist-content.js",
25
+ "build:copy-content": "cp -r src/web-ui/content dist/web-ui/ && cp src/decision-worker.py dist/decision-worker.py && node scripts/minify-dist-content.js",
25
26
  "build:render-bin": "node scripts/stage-render-binaries.js --all",
26
27
  "build:render-native": "cargo build --release --manifest-path render/Cargo.toml -p wand-renderd",
27
28
  "build:structured-render-native": "cargo build --release --manifest-path render/Cargo.toml -p wand-structured-renderd",
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: wand-decision
3
+ description: Use Wand's local, offline decision model for bounded classification, candidate selection, rubric scoring, or yes/no judgments over supplied evidence. Useful for quick semantic checks and small repeated judgments, not open-ended reasoning, execution authorization, or authoritative verification.
4
+ license: Apache-2.0
5
+ compatibility: Wand-managed structured CLI session with command execution permission, Node.js, and an enabled local decision runtime.
6
+ ---
7
+
8
+ # Wand local decisions
9
+
10
+ This is an optional inference tool, not a replacement for your main model. Only call it when a small typed judgment helps the user's task. Do not force it into every turn. Its decision quality is experimental: a local Chinese routing evaluation scored 24/44 and some wrong answers had near-1 probabilities. High probability is not correctness or permission.
11
+
12
+ ## Call the shared HTTP service
13
+
14
+ Use the bundled `scripts/decide.mjs`, resolved relative to this skill directory:
15
+
16
+ ```sh
17
+ node /absolute/path/to/this/skill/scripts/decide.mjs --stdin <<'JSON'
18
+ {
19
+ "state": "The customer was billed twice and requests a refund.",
20
+ "questions": {
21
+ "department": {
22
+ "type": "choice",
23
+ "instructions": "Which department handles this request?",
24
+ "criteria": {
25
+ "billing": "Payments, invoices and refunds",
26
+ "technical": "Software faults and outages",
27
+ "none": "No matching department or insufficient information"
28
+ }
29
+ }
30
+ }
31
+ }
32
+ JSON
33
+ ```
34
+
35
+ Replace the example skill path with the actual installed path. `--status` checks whether the shared service is enabled and ready without loading the model. The helper calls `wand decide` through the current session's bound executable and uses HTTP; it does not load Python or model weights in the CLI process.
36
+
37
+ Do not print, copy, persist, or inspect `WAND_DECISION_*` credential values. Never place a token in command arguments, SKILL.md, generated code, or the chat. The runtime binds the service and a short-lived inference-only capability; no caller-selected employee/config overrides are accepted. If unbound, ask to run through an enabled Wand structured session; never read admin passwords or another session's credentials. Installing this skill does not grant shell/MCP/network permissions: when command execution is disallowed, do not bypass that restriction.
38
+
39
+ ## Contract
40
+
41
+ Input is a JSON object with exactly `state` and `questions`:
42
+
43
+ - `state`: relevant text, JSON object, or list. Supply evidence, not a demand for a predetermined answer. No automatic access to files, private employee knowledge, history, or external facts.
44
+ - `questions`: 1–8 named questions. Each has `type`, `instructions` (nonempty, at most500 characters), and the appropriate `criteria`.
45
+ - `choice`: 2–8 unique labels mapped to short descriptions, or a list of labels. Labels at most80 characters, descriptions at most300. Prefer meaningful labels; map them back to stable IDs in your own code. Include an explicit no-match option when appropriate.
46
+ - `score`: 2–8 ordered, concrete rubric descriptions. The result is an expected zero-based level, not a newly generated rating scale.
47
+ - `noul`: a yes/no proposition, with optional `criteria` keyed only `false`/`true`. Returns P(true); a value near0.5 is uncertainty, not medium intensity.
48
+
49
+ One request can ask independent questions together; they do not see one another's answers. Maximum body32KiB. The multilingual model's **1024-token limit includes state, instructions and options per question**; character limits do not guarantee token fit. Keep inputs much shorter than a chat transcript. Overlength state, instructions/options that would be truncated, or indistinguishable options are rejected rather than silently used.
50
+
51
+ Output includes `answers`, per-option probabilities where applicable, `usage`, `runtime`, and `experimental: true`. It does not generate prose, rationales, code, arbitrary strings, or new candidate values. Do not invent an explanation the model did not return. Confidence summarizes a distribution and is not necessarily calibrated for your task or compatible with Jev's formula.
52
+
53
+ ## Use the result safely
54
+
55
+ - Validate that answers belong to the supplied options and make sense against the actual evidence.
56
+ - Do not use this model to approve permissions, destructive commands, credentials, payments, release/publish actions, or automatic task dispatch. Existing user authorization and project rules remain authoritative.
57
+ - Hard facts, exact comparisons and eligibility checks belong in ordinary code. Complex planning, ambiguous requests and unsupported topics belong with the main model or the user.
58
+ - Do not automatically supply another employee's private knowledge, whole files or unneeded sensitive data. Only provide the minimum evidence you are already authorized to use.
59
+ - For `CONTEXT_LIMIT`, `QUESTION_LIMIT` or `OPTIONS_COLLAPSED`, reduce the input while retaining the relevant constraints. Do not drop negations or the actual requested action just to fit.
60
+ - For `UNAVAILABLE`, `UNBOUND`, authorization failures, `BUSY`, rate limits or timeouts, state the limitation and continue without this auxiliary judgment or ask the user. No endless retries and no cloud fallback.
61
+ - To claim the service was used, require an actual successful tool response. Skill discovery alone is not a successful inference.
@@ -0,0 +1,16 @@
1
+ import { spawn } from "node:child_process";
2
+ import { isAbsolute } from "node:path";
3
+
4
+ const cli = process.env.WAND_DECISION_CLI;
5
+ const node = process.env.WAND_DECISION_NODE;
6
+ const args = process.argv.slice(2);
7
+ if (!cli || !node || !isAbsolute(cli) || !isAbsolute(node)
8
+ || !process.env.WAND_DECISION_TOKEN || args.length !== 1 || !["--stdin", "--status"].includes(args[0])) {
9
+ process.stderr.write("wand-decision: call --stdin or --status inside an enabled Wand structured session; no admin credential fallback.\n");
10
+ process.exitCode = 1;
11
+ } else {
12
+ const child = spawn(node, [...(cli.endsWith(".ts") ? ["--import", "tsx"] : []), cli, "decide", ...args], { stdio: "inherit" });
13
+ child.on("error", () => { process.stderr.write("wand-decision: client could not start.\n"); process.exitCode = 1; });
14
+ child.on("exit", (code) => { process.exitCode = code ?? 1; });
15
+ for (const signal of ["SIGINT", "SIGTERM"]) process.on(signal, () => child.kill(signal));
16
+ }