@stigmer/cli 3.12.8 → 3.13.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 (106) hide show
  1. package/commands/agent-exec-flags.d.ts +1 -0
  2. package/commands/agent-exec-flags.d.ts.map +1 -1
  3. package/commands/agent-exec-flags.js +3 -1
  4. package/commands/agent-exec-flags.js.map +1 -1
  5. package/commands/run.js +3 -0
  6. package/commands/run.js.map +1 -1
  7. package/commands/up.d.ts.map +1 -1
  8. package/commands/up.js +22 -6
  9. package/commands/up.js.map +1 -1
  10. package/config/resolve.d.ts +5 -2
  11. package/config/resolve.d.ts.map +1 -1
  12. package/config/resolve.js +7 -4
  13. package/config/resolve.js.map +1 -1
  14. package/local/constants.d.ts +8 -3
  15. package/local/constants.d.ts.map +1 -1
  16. package/local/constants.js +8 -3
  17. package/local/constants.js.map +1 -1
  18. package/local/daemon/components.d.ts.map +1 -1
  19. package/local/daemon/components.js +4 -2
  20. package/local/daemon/components.js.map +1 -1
  21. package/local/daemon/env.d.ts +16 -3
  22. package/local/daemon/env.d.ts.map +1 -1
  23. package/local/daemon/env.js +16 -3
  24. package/local/daemon/env.js.map +1 -1
  25. package/local/daemon/launch.d.ts.map +1 -1
  26. package/local/daemon/launch.js +5 -4
  27. package/local/daemon/launch.js.map +1 -1
  28. package/local/daemon/process.d.ts.map +1 -1
  29. package/local/daemon/process.js +8 -5
  30. package/local/daemon/process.js.map +1 -1
  31. package/local/runtime/index.d.ts +2 -2
  32. package/local/runtime/index.d.ts.map +1 -1
  33. package/local/runtime/index.js +4 -2
  34. package/local/runtime/index.js.map +1 -1
  35. package/local/runtime/node.d.ts +8 -0
  36. package/local/runtime/node.d.ts.map +1 -1
  37. package/local/runtime/node.js +74 -23
  38. package/local/runtime/node.js.map +1 -1
  39. package/local/runtime/runner.d.ts +2 -1
  40. package/local/runtime/runner.d.ts.map +1 -1
  41. package/local/runtime/runner.js +4 -31
  42. package/local/runtime/runner.js.map +1 -1
  43. package/local/runtime/runtimes-install.d.ts +13 -0
  44. package/local/runtime/runtimes-install.d.ts.map +1 -0
  45. package/local/runtime/runtimes-install.js +60 -0
  46. package/local/runtime/runtimes-install.js.map +1 -0
  47. package/local/runtime/server.d.ts +26 -30
  48. package/local/runtime/server.d.ts.map +1 -1
  49. package/local/runtime/server.js +106 -108
  50. package/local/runtime/server.js.map +1 -1
  51. package/local/status.d.ts.map +1 -1
  52. package/local/status.js +4 -2
  53. package/local/status.js.map +1 -1
  54. package/local/webconsole/index.d.ts +2 -3
  55. package/local/webconsole/index.d.ts.map +1 -1
  56. package/local/webconsole/index.js +24 -10
  57. package/local/webconsole/index.js.map +1 -1
  58. package/package.json +5 -5
  59. package/resources/run/agent-exec.d.ts.map +1 -1
  60. package/resources/run/agent-exec.js +2 -0
  61. package/resources/run/agent-exec.js.map +1 -1
  62. package/resources/run/create.d.ts +2 -1
  63. package/resources/run/create.d.ts.map +1 -1
  64. package/resources/run/create.js +21 -3
  65. package/resources/run/create.js.map +1 -1
  66. package/resources/run/header.d.ts +9 -1
  67. package/resources/run/header.d.ts.map +1 -1
  68. package/resources/run/header.js +3 -0
  69. package/resources/run/header.js.map +1 -1
  70. package/resources/run/prepare.d.ts +41 -3
  71. package/resources/run/prepare.d.ts.map +1 -1
  72. package/resources/run/prepare.js +53 -16
  73. package/resources/run/prepare.js.map +1 -1
  74. package/src/commands/agent-exec-flags.ts +5 -2
  75. package/src/commands/run.ts +3 -0
  76. package/src/commands/up.ts +24 -6
  77. package/src/config/resolve.test.ts +1 -1
  78. package/src/config/resolve.ts +7 -4
  79. package/src/local/constants.ts +8 -4
  80. package/src/local/daemon/components.test.ts +9 -1
  81. package/src/local/daemon/components.ts +4 -2
  82. package/src/local/daemon/daemon.integration.test.ts +1 -1
  83. package/src/local/daemon/env.test.ts +15 -4
  84. package/src/local/daemon/env.ts +33 -5
  85. package/src/local/daemon/launch.ts +5 -4
  86. package/src/local/daemon/process.ts +7 -4
  87. package/src/local/runtime/index.ts +6 -5
  88. package/src/local/runtime/node.ts +99 -23
  89. package/src/local/runtime/runner.ts +5 -36
  90. package/src/local/runtime/runtime.test.ts +58 -14
  91. package/src/local/runtime/runtimes-install.test.ts +56 -0
  92. package/src/local/runtime/runtimes-install.ts +72 -0
  93. package/src/local/runtime/server.test.ts +178 -114
  94. package/src/local/runtime/server.ts +149 -129
  95. package/src/local/status.ts +4 -2
  96. package/src/local/webconsole/index.ts +27 -10
  97. package/src/resources/connect/oauth.test.ts +1 -1
  98. package/src/resources/run/agent-exec.test.ts +25 -0
  99. package/src/resources/run/agent-exec.ts +2 -0
  100. package/src/resources/run/create.test.ts +92 -1
  101. package/src/resources/run/create.ts +25 -6
  102. package/src/resources/run/header.test.ts +18 -0
  103. package/src/resources/run/header.ts +11 -1
  104. package/src/resources/run/prepare.test.ts +247 -5
  105. package/src/resources/run/prepare.ts +99 -21
  106. package/src/resources/share.test.ts +2 -2
@@ -27,6 +27,9 @@ export function renderSessionHeader(out, info) {
27
27
  lines.push(row(s, "Subject", info.subject ?? ""));
28
28
  if (info.model !== "")
29
29
  lines.push(row(s, "Model", info.model));
30
+ // Only "cursor" is surfaced; native/"" is the default and stays implicit.
31
+ if (info.harness === "cursor")
32
+ lines.push(row(s, "Harness", "Cursor"));
30
33
  // Only "plan" is surfaced; "agent"/"" is the default and stays implicit.
31
34
  if (info.mode === "plan")
32
35
  lines.push(row(s, "Mode", "Plan (read-only)"));
@@ -1 +1 @@
1
- {"version":3,"file":"header.js","sourceRoot":"","sources":["../../../src/resources/run/header.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,qEAAqE;AACrE,EAAE;AACF,4EAA4E;AAC5E,wEAAwE;AACxE,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,+EAA+E;AAC/E,4EAA4E;AAG5E,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAa/D,8EAA8E;AAC9E,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAuD,EAAE,IAAuB;IAClH,MAAM,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,IAAI,CAAC,SAAS,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACvE,IAAI,IAAI,CAAC,SAAS,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACnF,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,yEAAyE;IACzE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACzE,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACvC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,GAAG,CAAC,CAA4B,EAAE,KAAa,EAAE,KAAa;IACrE,MAAM,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAAC,OAAkC;IAC/D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"header.js","sourceRoot":"","sources":["../../../src/resources/run/header.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,qEAAqE;AACrE,EAAE;AACF,4EAA4E;AAC5E,wEAAwE;AACxE,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,+EAA+E;AAC/E,4EAA4E;AAG5E,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAqB/D,8EAA8E;AAC9E,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAuD,EAAE,IAAuB;IAClH,MAAM,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,IAAI,CAAC,SAAS,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACvE,IAAI,IAAI,CAAC,SAAS,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACnF,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,0EAA0E;IAC1E,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvE,yEAAyE;IACzE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACzE,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACvC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,GAAG,CAAC,CAA4B,EAAE,KAAa,EAAE,KAAa;IACrE,MAAM,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAAC,OAAkC;IAC/D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC"}
@@ -17,6 +17,14 @@ export type ServiceTierFlag = "" | "standard" | "fast";
17
17
  * unset — distinct from an explicit "disabled" for the same ledger reason.
18
18
  */
19
19
  export type ThinkingFlag = "" | "disabled" | "enabled";
20
+ /**
21
+ * The `--harness` flag's value space (oss#293): empty means unset — the
22
+ * account preference may fill it (see {@link prepareAgentExec}), and when
23
+ * nothing resolves the server defaults the session to native. Deliberately
24
+ * only the two shipped engines, mirroring the proto validation on
25
+ * `IdentityAccountPreferences.default_harness`.
26
+ */
27
+ export type HarnessFlag = "" | "native" | "cursor";
20
28
  /** Raw agent-execution flags shared by `run` and `draft` (Go's agentExecFlags). */
21
29
  export interface AgentExecFlags {
22
30
  readonly message: string;
@@ -36,6 +44,7 @@ export interface AgentExecFlags {
36
44
  readonly mode: RunMode;
37
45
  readonly serviceTier: ServiceTierFlag;
38
46
  readonly thinking: ThinkingFlag;
47
+ readonly harness: HarnessFlag;
39
48
  }
40
49
  /**
41
50
  * The validated, resolved inputs ready for create + stream. Mirrors Go's
@@ -55,17 +64,37 @@ export interface PreparedRun {
55
64
  readonly mode: RunMode;
56
65
  readonly serviceTier: ServiceTierFlag;
57
66
  readonly thinking: ThinkingFlag;
67
+ /**
68
+ * The RESOLVED harness for the new session: the explicit flag, else the
69
+ * account preference (when the caller opted in), else "" — which stays off
70
+ * the wire so the server default (native) applies. Also drives the header's
71
+ * visibility row: a cursor session is never entered silently.
72
+ */
73
+ readonly harness: HarnessFlag;
58
74
  }
59
75
  /** Optional behavior switches for {@link prepareAgentExec}. */
60
76
  export interface PrepareAgentExecOptions {
61
77
  /**
62
78
  * When `true` (the caller's backend is Stigmer Cloud) and `--model` is
63
79
  * omitted, the model is filled from the caller's account preference
64
- * (`IdentityAccountPreferences.default_native_model`) via `whoAmI()`.
65
- * Local mode has no IdentityAccount, so callers pass `false` there and
66
- * the omitted model keeps resolving to the platform default.
80
+ * (`IdentityAccountPreferences.default_*_model` for the resolved harness)
81
+ * via `whoAmI()`. Local mode has no IdentityAccount, so callers pass
82
+ * `false` there and the omitted model keeps resolving to the platform
83
+ * default.
67
84
  */
68
85
  readonly cloudBackend?: boolean;
86
+ /**
87
+ * When `true` and `--harness` is omitted, the harness is filled from the
88
+ * caller's account preference (`IdentityAccountPreferences.default_harness`)
89
+ * on cloud. `run` opts in; `draft` deliberately does not: draft executes the
90
+ * seedpack's system creator agents (a utility flow, not the user's own
91
+ * conversation), which are built and exercised on the native harness —
92
+ * silently rerouting them onto the cursor engine (different toolset,
93
+ * premium billing tier) would fail the least-surprise test. An explicit
94
+ * `--harness` on draft still wins; only the silent preference fill is
95
+ * scoped out. Owner-ratified (D5, 2026-08-23).
96
+ */
97
+ readonly applyAccountHarnessDefault?: boolean;
69
98
  }
70
99
  /**
71
100
  * Validate flags and resolve all execution inputs. The `org` is used to inject
@@ -98,4 +127,13 @@ export declare function validateServiceTier(tier: string): asserts tier is Servi
98
127
  * before a network round trip.
99
128
  */
100
129
  export declare function validateThinking(mode: string): asserts mode is ThinkingFlag;
130
+ /**
131
+ * Validate the `--harness` flag. Empty means "use default": the account
132
+ * preference when the caller opted in, else the platform default (native).
133
+ * Only the shipped engines are accepted — other harness names that appear in
134
+ * UI metadata (copilot, codex, ...) have no proto mapping yet, so rejecting
135
+ * them here is honest, and this check catches spelling errors before a
136
+ * network round trip.
137
+ */
138
+ export declare function validateHarness(harness: string): asserts harness is HarnessFlag;
101
139
  //# sourceMappingURL=prepare.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../../../src/resources/run/prepare.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../../../src/resources/run/prepare.ts"],"names":[],"mappings":"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"}
@@ -20,13 +20,25 @@ export async function prepareAgentExec(flags, client, org, progress, options) {
20
20
  validateMode(flags.mode);
21
21
  validateServiceTier(flags.serviceTier);
22
22
  validateThinking(flags.thinking);
23
- // Layered model seed (oss#293 Phase 1.5): an explicit --model always wins;
24
- // an omitted one fills from the account preference on cloud. `run` and
25
- // `draft` always create a NEW session (threading lives in `resume`, which
26
- // does not pass through here), so the fill never injects a native model
27
- // into an existing cursor-harness session.
28
- const model = flags.model === "" && options?.cloudBackend === true
29
- ? await resolveModelFromAccountPreference(client)
23
+ validateHarness(flags.harness);
24
+ // Layered seeds (oss#293, DD-003): explicit flag > account preference
25
+ // (cloud only) > platform default. Harness resolves first because the model
26
+ // fill is harness-aware: a cursor session fills from default_cursor_model,
27
+ // everything else from default_native_model. `run` and `draft` always
28
+ // create a NEW session (threading lives in `resume`, which does not pass
29
+ // through here), so neither fill can ever contradict an existing session's
30
+ // immutable harness. One whoAmI round trip serves both fills, and it is
31
+ // skipped entirely when explicit flags leave nothing to fill.
32
+ const wantsHarnessFill = flags.harness === "" && options?.applyAccountHarnessDefault === true;
33
+ const wantsModelFill = flags.model === "";
34
+ const accountDefaults = options?.cloudBackend === true && (wantsHarnessFill || wantsModelFill)
35
+ ? await resolveAccountExecutionDefaults(client)
36
+ : NO_ACCOUNT_DEFAULTS;
37
+ const harness = flags.harness !== "" ? flags.harness : wantsHarnessFill ? accountDefaults.harness : "";
38
+ const model = wantsModelFill
39
+ ? harness === "cursor"
40
+ ? accountDefaults.cursorModel
41
+ : accountDefaults.nativeModel
30
42
  : flags.model;
31
43
  const workspaceEntries = parseWorkspaceEntries(flags.workspace, flags.branch, flags.commit);
32
44
  const runtimeEnv = loadAndMergeEnv({
@@ -53,23 +65,35 @@ export async function prepareAgentExec(flags, client, org, progress, options) {
53
65
  mode: flags.mode,
54
66
  serviceTier: flags.serviceTier,
55
67
  thinking: flags.thinking,
68
+ harness,
56
69
  };
57
70
  }
71
+ const NO_ACCOUNT_DEFAULTS = { harness: "", nativeModel: "", cursorModel: "" };
58
72
  /**
59
- * Best-effort read of the caller's default model for native-harness runs
60
- * (CLI sessions are native — there is no --harness flag yet, so the cursor
61
- * default is deliberately not consulted). Any failure — network, auth, a
62
- * backend without IdentityAccount — resolves to "" and the run proceeds
63
- * exactly as an unfilled --model does today: a missing preference must
64
- * never fail a run.
73
+ * Best-effort read of the caller's execution defaults
74
+ * (`IdentityAccountPreferences.default_harness` / `default_*_model`) in one
75
+ * whoAmI round trip. Any failure — network, auth, a backend without
76
+ * IdentityAccount — resolves to no defaults and the run proceeds exactly as
77
+ * unfilled flags do today: a missing preference must never fail a run.
78
+ *
79
+ * The persisted harness value is allowlist-guarded to the shipped engines
80
+ * (the same guard the web launcher's useAccountExecutionDefaults applies):
81
+ * a client must not trust stored data it did not write, so anything outside
82
+ * native/cursor is treated as undeclared rather than stamped on the wire.
65
83
  */
66
- async function resolveModelFromAccountPreference(client) {
84
+ async function resolveAccountExecutionDefaults(client) {
67
85
  try {
68
86
  const account = await client.identityAccount.whoAmI();
69
- return account.spec?.preferences?.defaultNativeModel ?? "";
87
+ const prefs = account.spec?.preferences;
88
+ const declared = prefs?.defaultHarness;
89
+ return {
90
+ harness: declared === "native" || declared === "cursor" ? declared : "",
91
+ nativeModel: prefs?.defaultNativeModel ?? "",
92
+ cursorModel: prefs?.defaultCursorModel ?? "",
93
+ };
70
94
  }
71
95
  catch {
72
- return "";
96
+ return NO_ACCOUNT_DEFAULTS;
73
97
  }
74
98
  }
75
99
  /**
@@ -127,4 +151,17 @@ export function validateThinking(mode) {
127
151
  throw new UsageError(`invalid --thinking value "${mode}": must be "disabled" or "enabled"`);
128
152
  }
129
153
  }
154
+ /**
155
+ * Validate the `--harness` flag. Empty means "use default": the account
156
+ * preference when the caller opted in, else the platform default (native).
157
+ * Only the shipped engines are accepted — other harness names that appear in
158
+ * UI metadata (copilot, codex, ...) have no proto mapping yet, so rejecting
159
+ * them here is honest, and this check catches spelling errors before a
160
+ * network round trip.
161
+ */
162
+ export function validateHarness(harness) {
163
+ if (harness !== "" && harness !== "native" && harness !== "cursor") {
164
+ throw new UsageError(`invalid --harness value "${harness}": must be "native" or "cursor"`);
165
+ }
166
+ }
130
167
  //# sourceMappingURL=prepare.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.js","sourceRoot":"","sources":["../../../src/resources/run/prepare.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prepare.js","sourceRoot":"","sources":["../../../src/resources/run/prepare.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  // execution flag is added here once and both surfaces pick it up.
4
4
 
5
5
  import type { Command } from "commander";
6
- import type { AgentExecFlags, RunMode, ServiceTierFlag, ThinkingFlag } from "../resources/run/prepare.js";
6
+ import type { AgentExecFlags, HarnessFlag, RunMode, ServiceTierFlag, ThinkingFlag } from "../resources/run/prepare.js";
7
7
 
8
8
  /** Commander collector for repeatable string options. */
9
9
  export const collect = (value: string, previous: string[]): string[] => [...previous, value];
@@ -27,6 +27,7 @@ export interface AgentExecOptions {
27
27
  mode?: string;
28
28
  serviceTier?: string;
29
29
  thinking?: string;
30
+ harness?: string;
30
31
  }
31
32
 
32
33
  /**
@@ -54,7 +55,8 @@ export function addAgentExecFlags(command: Command, requireMessage = false): Com
54
55
  .option("--auto-approve", "automatically approve all tool executions")
55
56
  .option("--mode <mode>", 'interaction mode: "agent" (default) or "plan" (read-only)')
56
57
  .option("--service-tier <tier>", 'model service tier: "standard" (default) or "fast" (requires --model naming a model with a fast tier; billed at fast rates)')
57
- .option("--thinking <mode>", 'extended reasoning: "disabled" (default) or "enabled" (requires --model naming a thinking-capable model; billed at base rates, uses more output tokens)');
58
+ .option("--thinking <mode>", 'extended reasoning: "disabled" (default) or "enabled" (requires --model naming a thinking-capable model; billed at base rates, uses more output tokens)')
59
+ .option("--harness <harness>", 'execution harness for the new session: "native" (default) or "cursor"');
58
60
  }
59
61
 
60
62
  /** Map parsed commander options onto the shared {@link AgentExecFlags} shape. */
@@ -77,5 +79,6 @@ export function toAgentExecFlags(options: AgentExecOptions): AgentExecFlags {
77
79
  mode: (options.mode ?? "") as RunMode,
78
80
  serviceTier: (options.serviceTier ?? "") as ServiceTierFlag,
79
81
  thinking: (options.thinking ?? "") as ThinkingFlag,
82
+ harness: (options.harness ?? "") as HarnessFlag,
80
83
  };
81
84
  }
@@ -173,6 +173,9 @@ async function runResolvedAgent(
173
173
 
174
174
  const prepared = await prepareAgentExec(toAgentExecFlags(options), client.stigmer, org, stderrProgress(), {
175
175
  cloudBackend: isCloudMode(client.config),
176
+ // run opts into the account default_harness fill; draft deliberately
177
+ // does not (see the option's doc comment for the D5 rationale).
178
+ applyAccountHarnessDefault: true,
176
179
  });
177
180
  await executeResolvedAgent({
178
181
  agent,
@@ -6,9 +6,11 @@
6
6
  // outcome. The launcher (and the heavy resolvers it pulls in) load lazily so
7
7
  // `--help` stays fast (DD-001).
8
8
 
9
+ import { homedir } from "node:os";
10
+ import { join } from "node:path";
9
11
  import type { Command } from "commander";
10
12
  import { CommandResult, type OutputFlags, renderResult } from "../output/index.js";
11
- import { SERVER_PORT } from "../local/constants.js";
13
+ import { HEALTH_STATE_FILE, SERVER_PORT } from "../local/constants.js";
12
14
  import { addResultFlags, resultFormat } from "./shared.js";
13
15
 
14
16
  interface UpFlags extends OutputFlags {
@@ -16,15 +18,17 @@ interface UpFlags extends OutputFlags {
16
18
  web?: boolean; // false when --no-web is passed
17
19
  }
18
20
 
21
+ // The server serves the web console from its unified port (DD-012); the
22
+ // flag suppresses probing/reporting it, not the serving itself (one
23
+ // process, one origin — there is no separate console to not-start).
24
+ const NO_WEB_HELP = "don't report the web console URL";
25
+
19
26
  export function registerUp(program: Command): void {
20
27
  const up = program
21
28
  .command("up")
22
29
  .description("start the local Stigmer stack (server, runner, Temporal)")
23
30
  .option("--server-only", "start only the control plane (no runners)")
24
- // Accepted for compatibility with the Go CLI; this CLI does not bundle a
25
- // local web console, so the stack is headless either way (use the cloud
26
- // console at app.stigmer.ai for a UI).
27
- .option("--no-web", "no-op: this CLI does not serve a local web console")
31
+ .option("--no-web", NO_WEB_HELP)
28
32
  .action((options: UpFlags) =>
29
33
  runUp({ serverOnly: options.serverOnly === true, noWeb: options.web === false }, options),
30
34
  );
@@ -33,7 +37,7 @@ export function registerUp(program: Command): void {
33
37
  const server = up
34
38
  .command("server")
35
39
  .description("start only the control plane (no runners)")
36
- .option("--no-web", "no-op: this CLI does not serve a local web console")
40
+ .option("--no-web", NO_WEB_HELP)
37
41
  .action((options: UpFlags) => runUp({ serverOnly: true, noWeb: options.web === false }, options));
38
42
  addResultFlags(server);
39
43
  }
@@ -46,6 +50,20 @@ async function runUp(opts: { serverOnly: boolean; noWeb: boolean }, flags: Outpu
46
50
  const result = CommandResult.success(opts.serverOnly ? "Stigmer control plane is up" : "Stigmer local stack is up");
47
51
  const section = result.addSection("Endpoints");
48
52
  section.field("server", `http://localhost:${SERVER_PORT}`);
53
+ if (await consoleReported()) {
54
+ // Same origin as the API: the server serves the console (DD-012). Only
55
+ // printed when the daemon's probe found a bundled export — a dev-tree
56
+ // server without one must not advertise a dead URL.
57
+ section.field("console", `http://localhost:${SERVER_PORT}`);
58
+ }
49
59
  result.hint("Check status with: stigmer status").hint("Stop it with: stigmer down");
50
60
  renderResult(result, resultFormat(flags));
51
61
  }
62
+
63
+ /** Whether the daemon recorded the web console as running (its own probe). */
64
+ async function consoleReported(): Promise<boolean> {
65
+ const { dataDir } = await import("../local/paths.js");
66
+ const { loadHealthState } = await import("../local/state/health-state.js");
67
+ const health = loadHealthState(join(dataDir(homedir()), HEALTH_STATE_FILE));
68
+ return health?.components["web-console"]?.state === "running";
69
+ }
@@ -109,7 +109,7 @@ describe("resolveConsoleURL", () => {
109
109
  });
110
110
 
111
111
  it("uses the local web-console port for the local backend", () => {
112
- expect(resolveConsoleURL("local", {} as NodeJS.ProcessEnv)).toBe("http://localhost:8234");
112
+ expect(resolveConsoleURL("local", {} as NodeJS.ProcessEnv)).toBe("http://localhost:7234");
113
113
  });
114
114
 
115
115
  it("uses the cloud console URL for the cloud backend", () => {
@@ -3,7 +3,7 @@
3
3
  // precedence keeps every call site consistent (mirrors the Go CLI's Resolve*).
4
4
 
5
5
  import { CliExitError, ExitCode } from "../errors/index.js";
6
- import { WEB_CONSOLE_PORT } from "../local/constants.js";
6
+ import { SERVER_PORT } from "../local/constants.js";
7
7
  import { type BackendType, type Config, isCloudMode } from "./config.js";
8
8
 
9
9
  const DEFAULT_CLOUD_ENDPOINT = "api.stigmer.ai:443";
@@ -76,17 +76,20 @@ export function resolveOrganization(config: Config, flagOrg?: string): string {
76
76
  /**
77
77
  * Resolve the web console URL:
78
78
  * 1. `STIGMER_CONSOLE_URL` (explicit override)
79
- * 2. local backend → `http://localhost:{WEB_CONSOLE_PORT}`
79
+ * 2. local backend → `http://localhost:{SERVER_PORT}` — the server's own
80
+ * unified port serves the console since DD-012 (one origin for UI and
81
+ * API; the Go-era separate 8234 listener is retired)
80
82
  * 3. cloud backend → {@link DEFAULT_CLOUD_CONSOLE_URL}
81
83
  *
82
84
  * The console origin is also the app origin that serves the hosted chat
83
85
  * page (`/chat/<org>/<slug>`) and the embed loader (`/embed.js`), so
84
- * share-link builders use this same resolver.
86
+ * share-link builders use this same resolver — both routes live in the
87
+ * same static export the server serves.
85
88
  */
86
89
  export function resolveConsoleURL(backendType: BackendType, env: NodeJS.ProcessEnv = process.env): string {
87
90
  const override = env.STIGMER_CONSOLE_URL;
88
91
  if (override !== undefined && override !== "") return override;
89
- if (backendType === "local") return `http://localhost:${WEB_CONSOLE_PORT}`;
92
+ if (backendType === "local") return `http://localhost:${SERVER_PORT}`;
90
93
  return DEFAULT_CLOUD_CONSOLE_URL;
91
94
  }
92
95
 
@@ -7,12 +7,16 @@
7
7
  // runner-poll can never drift (see the T05 plan's "Critical correctness
8
8
  // finding").
9
9
 
10
- /** Port `stigmer-server` listens on (gRPC). Matches the Go CLI's `DaemonPort`. */
10
+ /**
11
+ * Port `stigmer-server` listens on (gRPC). Matches the Go CLI's `DaemonPort`.
12
+ *
13
+ * This is also the web console's origin: since DD-012 the server serves the
14
+ * console's static export on this same unified port (lane 4), so the Go-era
15
+ * WEB_CONSOLE_PORT (8234, a separate CLI-embedded listener) is retired —
16
+ * one process, one origin, no CORS hop.
17
+ */
11
18
  export const SERVER_PORT = 7234;
12
19
 
13
- /** Port the embedded web console is served on (7xxx=API, 8xxx=UI convention). */
14
- export const WEB_CONSOLE_PORT = 8234;
15
-
16
20
  /** Temporal frontend gRPC port (dev server default). */
17
21
  export const TEMPORAL_PORT = 7233;
18
22
 
@@ -11,7 +11,7 @@ const config: DaemonConfig = {
11
11
  temporalAddress: "127.0.0.1:7233",
12
12
  serverOnly: false,
13
13
  noWeb: false,
14
- serverBin: "/bin/stigmer-server",
14
+ server: { nodeBin: "/bin/node", entryPath: "/repo/server/dist/main.js", appDir: "/repo/server" },
15
15
  runner: { nodeBin: "/bin/node", entryPath: "/repo/runner/dist/main.js", appDir: "/repo/runner" },
16
16
  };
17
17
 
@@ -133,6 +133,14 @@ describe("buildComponents", () => {
133
133
  expect(runner.resolve().args).toEqual(["/repo/runner/dist/main.js"]);
134
134
  });
135
135
 
136
+ // The TS server child is `node <entry>` — the runner's launch shape.
137
+ it("spawns the node-shape server as node + entry", () => {
138
+ const [server] = buildComponents(config, {});
139
+ const spawn = server.resolve();
140
+ expect(spawn.command).toBe("/bin/node");
141
+ expect(spawn.args).toEqual(["/repo/server/dist/main.js"]);
142
+ });
143
+
136
144
  it("omits the runner in server-only mode", () => {
137
145
  const components = buildComponents({ ...config, serverOnly: true }, {});
138
146
  expect(components.map((c) => c.name)).toEqual(["stigmer-server"]);
@@ -91,9 +91,11 @@ export function buildComponents(config: DaemonConfig, base: NodeJS.ProcessEnv =
91
91
  name: "stigmer-server",
92
92
  pidFile: join(config.dataDir, SERVER_PID_FILE),
93
93
  critical: true,
94
+ // The server is `node <entry>` — the runner's launch shape, one child
95
+ // contract for both components.
94
96
  resolve: () => ({
95
- command: config.serverBin,
96
- args: [],
97
+ command: config.server.nodeBin,
98
+ args: [config.server.entryPath],
97
99
  env: buildServerEnv(config, base),
98
100
  logFile: join(config.logDir, "stigmer-server.log"),
99
101
  }),
@@ -128,7 +128,7 @@ describe("runInternalDaemon (full body with fakes)", () => {
128
128
  temporalAddress: "127.0.0.1:7233",
129
129
  serverOnly: false,
130
130
  noWeb: true,
131
- serverBin: "server-cmd",
131
+ server: { nodeBin: "node-cmd", entryPath: join(data, "server-entry.js"), appDir: data },
132
132
  runner: { nodeBin: "node-cmd", entryPath: join(data, "entry.js"), appDir: data },
133
133
  };
134
134
 
@@ -8,7 +8,11 @@ const baseInputs: DaemonEnvInputs = {
8
8
  temporalAddress: "127.0.0.1:7233",
9
9
  serverOnly: false,
10
10
  noWeb: false,
11
- serverBin: "/usr/local/bin/stigmer-server",
11
+ server: {
12
+ nodeBin: "/usr/bin/node",
13
+ entryPath: "/repo/server/dist/main.js",
14
+ appDir: "/repo/server",
15
+ },
12
16
  runner: { nodeBin: "/usr/bin/node", entryPath: "/repo/runner/dist/main.js", appDir: "/repo/runner" },
13
17
  };
14
18
 
@@ -23,7 +27,11 @@ describe("buildDaemonEnv + readDaemonConfig", () => {
23
27
  temporalAddress: "127.0.0.1:7233",
24
28
  serverOnly: false,
25
29
  noWeb: false,
26
- serverBin: "/usr/local/bin/stigmer-server",
30
+ server: {
31
+ nodeBin: "/usr/bin/node",
32
+ entryPath: "/repo/server/dist/main.js",
33
+ appDir: "/repo/server",
34
+ },
27
35
  runner: { nodeBin: "/usr/bin/node", entryPath: "/repo/runner/dist/main.js", appDir: "/repo/runner" },
28
36
  cursorApiKey: undefined,
29
37
  anthropicApiKey: undefined,
@@ -90,8 +98,11 @@ describe("buildDaemonEnv + readDaemonConfig", () => {
90
98
  expect(readDaemonConfig(env)).not.toHaveProperty("openaiApiKey");
91
99
  });
92
100
 
93
- it("requires the data dir and server binary", () => {
101
+ it("requires the data dir and the full server launch triple", () => {
94
102
  expect(() => readDaemonConfig({})).toThrow(/STIGMER_DATA_DIR/);
95
- expect(() => readDaemonConfig({ STIGMER_DATA_DIR: "/x" })).toThrow(/STIGMER_SERVER_BIN/);
103
+ expect(() => readDaemonConfig({ STIGMER_DATA_DIR: "/x" })).toThrow(/STIGMER_SERVER_NODE_BIN/);
104
+ expect(() => readDaemonConfig({ STIGMER_DATA_DIR: "/x", STIGMER_SERVER_NODE_BIN: "/usr/bin/node" })).toThrow(
105
+ /STIGMER_SERVER_ENTRY/,
106
+ );
96
107
  });
97
108
  });
@@ -12,7 +12,9 @@ export const DaemonEnvVar = {
12
12
  TemporalAddress: "TEMPORAL_SERVICE_ADDRESS",
13
13
  ServerOnly: "STIGMER_SERVER_ONLY",
14
14
  NoWeb: "STIGMER_NO_WEB",
15
- ServerBin: "STIGMER_SERVER_BIN",
15
+ ServerNodeBin: "STIGMER_SERVER_NODE_BIN",
16
+ ServerEntry: "STIGMER_SERVER_ENTRY",
17
+ ServerAppDir: "STIGMER_SERVER_APP_DIR",
16
18
  RunnerNodeBin: "STIGMER_RUNNER_NODE_BIN",
17
19
  RunnerEntry: "STIGMER_RUNNER_ENTRY",
18
20
  RunnerAppDir: "STIGMER_RUNNER_APP_DIR",
@@ -30,6 +32,18 @@ export interface RunnerLaunch {
30
32
  appDir: string;
31
33
  }
32
34
 
35
+ /**
36
+ * Resolved server launch coordinates: a node binary + bundled entry — the
37
+ * same launch shape as the runner. (Until #25 go-server-retirement this was
38
+ * a discriminated union whose "binary" variant carried the Go rollback
39
+ * executable.)
40
+ */
41
+ export interface ServerLaunch {
42
+ nodeBin: string;
43
+ entryPath: string;
44
+ appDir: string;
45
+ }
46
+
33
47
  /** The daemon's resolved configuration, parsed from the environment. */
34
48
  export interface DaemonConfig {
35
49
  dataDir: string;
@@ -38,7 +52,7 @@ export interface DaemonConfig {
38
52
  temporalAddress: string;
39
53
  serverOnly: boolean;
40
54
  noWeb: boolean;
41
- serverBin: string;
55
+ server: ServerLaunch;
42
56
  runner?: RunnerLaunch;
43
57
  cursorApiKey?: string;
44
58
  anthropicApiKey?: string;
@@ -55,7 +69,7 @@ export interface DaemonEnvInputs {
55
69
  temporalAddress: string;
56
70
  serverOnly: boolean;
57
71
  noWeb: boolean;
58
- serverBin: string;
72
+ server: ServerLaunch;
59
73
  runner?: RunnerLaunch;
60
74
  // Anthropic API key resolved by the launcher (env > config file). Must be
61
75
  // written into the daemon env explicitly: unlike a shell-exported key, a key
@@ -83,7 +97,9 @@ export function buildDaemonEnv(inputs: DaemonEnvInputs, base: NodeJS.ProcessEnv
83
97
  env[DaemonEnvVar.LogDir] = inputs.logDir;
84
98
  env[DaemonEnvVar.TemporalManaged] = String(inputs.temporalManaged);
85
99
  env[DaemonEnvVar.TemporalAddress] = inputs.temporalAddress;
86
- env[DaemonEnvVar.ServerBin] = inputs.serverBin;
100
+ env[DaemonEnvVar.ServerNodeBin] = inputs.server.nodeBin;
101
+ env[DaemonEnvVar.ServerEntry] = inputs.server.entryPath;
102
+ env[DaemonEnvVar.ServerAppDir] = inputs.server.appDir;
87
103
  if (inputs.serverOnly) env[DaemonEnvVar.ServerOnly] = "true";
88
104
  if (inputs.noWeb) env[DaemonEnvVar.NoWeb] = "1";
89
105
  if (inputs.runner !== undefined && !inputs.serverOnly) {
@@ -112,7 +128,7 @@ export function readDaemonConfig(env: NodeJS.ProcessEnv = process.env): DaemonCo
112
128
  temporalAddress: env[DaemonEnvVar.TemporalAddress] ?? "127.0.0.1:7233",
113
129
  serverOnly,
114
130
  noWeb: env[DaemonEnvVar.NoWeb] === "1",
115
- serverBin: required(env, DaemonEnvVar.ServerBin),
131
+ server: readServer(env),
116
132
  runner: serverOnly ? undefined : runner,
117
133
  cursorApiKey: nonEmpty(env[DaemonEnvVar.CursorApiKey]),
118
134
  anthropicApiKey: nonEmpty(env[DaemonEnvVar.AnthropicApiKey]),
@@ -122,6 +138,18 @@ export function readDaemonConfig(env: NodeJS.ProcessEnv = process.env): DaemonCo
122
138
  };
123
139
  }
124
140
 
141
+ function readServer(env: NodeJS.ProcessEnv): ServerLaunch {
142
+ const nodeBin = env[DaemonEnvVar.ServerNodeBin];
143
+ const entryPath = env[DaemonEnvVar.ServerEntry];
144
+ const appDir = env[DaemonEnvVar.ServerAppDir];
145
+ if (!nodeBin || !entryPath || !appDir) {
146
+ throw new Error(
147
+ `the ${DaemonEnvVar.ServerNodeBin}/${DaemonEnvVar.ServerEntry}/${DaemonEnvVar.ServerAppDir} triple is required for the daemon process`,
148
+ );
149
+ }
150
+ return { nodeBin, entryPath, appDir };
151
+ }
152
+
125
153
  function readRunner(env: NodeJS.ProcessEnv): RunnerLaunch | undefined {
126
154
  const nodeBin = env[DaemonEnvVar.RunnerNodeBin];
127
155
  const entryPath = env[DaemonEnvVar.RunnerEntry];
@@ -2,7 +2,7 @@
2
2
  // `down` (signal + wait + safety-net cleanup), and a liveness check.
3
3
  //
4
4
  // `up` resolves every heavy dependency in the foreground (Temporal binary,
5
- // server binary, runner entry) so failures surface with a clear message before
5
+ // server launch, runner entry) so failures surface with a clear message before
6
6
  // a detached daemon is spawned, then re-execs this same CLI as the hidden
7
7
  // `internal-daemon` and waits until the server's gRPC port answers.
8
8
 
@@ -24,7 +24,7 @@ import { rotateLogs } from "../state/log-rotation.js";
24
24
  import { resolveApiKey, resolveProvider } from "../llm-config.js";
25
25
  import { resolveOperatorIdentity } from "../operator-config.js";
26
26
  import { ensureRunner } from "../runtime/runner.js";
27
- import { ensureServerBinary } from "../runtime/server.js";
27
+ import { ensureServer } from "../runtime/server.js";
28
28
  import { TemporalManager } from "../temporal/manager.js";
29
29
  import { buildDaemonEnv, type DaemonEnvInputs } from "./env.js";
30
30
 
@@ -64,7 +64,8 @@ export async function up(options: UpOptions = {}, home: string = homedir()): Pro
64
64
  await temporal.ensureInstalled();
65
65
  }
66
66
 
67
- const serverBin = await ensureServerBinary({ home });
67
+ // Resolves the server (repo tree or the acquired @stigmer/server-slim).
68
+ const server = ensureServer({ home });
68
69
  const runner = options.serverOnly === true ? undefined : ensureRunner({ home });
69
70
 
70
71
  const env = buildDaemonEnv(
@@ -75,7 +76,7 @@ export async function up(options: UpOptions = {}, home: string = homedir()): Pro
75
76
  temporalAddress: temporal.address,
76
77
  serverOnly: options.serverOnly === true,
77
78
  noWeb: options.noWeb === true,
78
- serverBin,
79
+ server,
79
80
  runner,
80
81
  ...resolveLlmKeyInputs(config),
81
82
  ...resolveOperatorIdentityInputs(config),