@tt-a1i/hive 1.4.4 → 1.6.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 (180) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.en.md +21 -0
  3. package/README.md +16 -0
  4. package/assets/qq-group.jpg +0 -0
  5. package/dist/bin/team.cmd +1 -0
  6. package/dist/src/cli/hive-update.d.ts +45 -17
  7. package/dist/src/cli/hive-update.js +63 -25
  8. package/dist/src/cli/hive.d.ts +25 -0
  9. package/dist/src/cli/hive.js +41 -3
  10. package/dist/src/cli/team.d.ts +1 -0
  11. package/dist/src/cli/team.js +216 -3
  12. package/dist/src/server/agent-command-resolver.js +3 -19
  13. package/dist/src/server/agent-manager-support.d.ts +2 -2
  14. package/dist/src/server/agent-manager-support.js +98 -24
  15. package/dist/src/server/agent-run-starter.d.ts +6 -1
  16. package/dist/src/server/agent-run-starter.js +9 -2
  17. package/dist/src/server/agent-run-store.d.ts +1 -1
  18. package/dist/src/server/agent-runtime-close.d.ts +1 -0
  19. package/dist/src/server/agent-runtime-close.js +25 -1
  20. package/dist/src/server/agent-runtime-contract.d.ts +12 -1
  21. package/dist/src/server/agent-runtime-stop-run.d.ts +1 -1
  22. package/dist/src/server/agent-runtime-stop-run.js +4 -1
  23. package/dist/src/server/agent-runtime.d.ts +2 -1
  24. package/dist/src/server/agent-runtime.js +14 -3
  25. package/dist/src/server/agent-startup-instructions.d.ts +7 -1
  26. package/dist/src/server/agent-startup-instructions.js +17 -9
  27. package/dist/src/server/agent-stdin-dispatcher.d.ts +25 -5
  28. package/dist/src/server/agent-stdin-dispatcher.js +141 -40
  29. package/dist/src/server/cron-util.d.ts +7 -0
  30. package/dist/src/server/cron-util.js +19 -0
  31. package/dist/src/server/dispatch-ledger-store.d.ts +22 -0
  32. package/dist/src/server/dispatch-ledger-store.js +51 -3
  33. package/dist/src/server/env-sync-message.js +9 -9
  34. package/dist/src/server/feature-flags.d.ts +42 -0
  35. package/dist/src/server/feature-flags.js +24 -0
  36. package/dist/src/server/fs-pick-folder.js +4 -0
  37. package/dist/src/server/fs-sandbox.js +36 -7
  38. package/dist/src/server/hive-team-guidance.d.ts +12 -6
  39. package/dist/src/server/hive-team-guidance.js +253 -71
  40. package/dist/src/server/live-run-registry.d.ts +1 -0
  41. package/dist/src/server/live-run-registry.js +1 -1
  42. package/dist/src/server/open-target-commands.js +5 -6
  43. package/dist/src/server/orchestrator-autostart.d.ts +12 -0
  44. package/dist/src/server/orchestrator-autostart.js +15 -13
  45. package/dist/src/server/path-canonicalization.d.ts +3 -0
  46. package/dist/src/server/path-canonicalization.js +29 -0
  47. package/dist/src/server/platform-path.d.ts +3 -0
  48. package/dist/src/server/platform-path.js +13 -0
  49. package/dist/src/server/post-start-input-writer.d.ts +1 -1
  50. package/dist/src/server/post-start-input-writer.js +110 -13
  51. package/dist/src/server/preset-launch-support.d.ts +1 -1
  52. package/dist/src/server/preset-launch-support.js +33 -2
  53. package/dist/src/server/recovery-summary.d.ts +5 -1
  54. package/dist/src/server/recovery-summary.js +18 -17
  55. package/dist/src/server/report-outbox-store.d.ts +36 -0
  56. package/dist/src/server/report-outbox-store.js +33 -0
  57. package/dist/src/server/restart-policy-support.d.ts +5 -1
  58. package/dist/src/server/restart-policy-support.js +9 -1
  59. package/dist/src/server/restart-policy.d.ts +6 -2
  60. package/dist/src/server/restart-policy.js +51 -31
  61. package/dist/src/server/role-template-store.d.ts +1 -0
  62. package/dist/src/server/role-template-store.js +11 -1
  63. package/dist/src/server/route-types.d.ts +43 -0
  64. package/dist/src/server/routes-runtime.js +2 -1
  65. package/dist/src/server/routes-settings.js +76 -0
  66. package/dist/src/server/routes-tasks.js +23 -0
  67. package/dist/src/server/routes-team.js +211 -1
  68. package/dist/src/server/routes-workflow-schedules.d.ts +2 -0
  69. package/dist/src/server/routes-workflow-schedules.js +58 -0
  70. package/dist/src/server/routes-workflows.d.ts +2 -0
  71. package/dist/src/server/routes-workflows.js +83 -0
  72. package/dist/src/server/routes-workspaces.js +5 -0
  73. package/dist/src/server/routes.js +4 -0
  74. package/dist/src/server/runtime-restart-policy.d.ts +3 -1
  75. package/dist/src/server/runtime-restart-policy.js +2 -1
  76. package/dist/src/server/runtime-store-contract.d.ts +125 -0
  77. package/dist/src/server/runtime-store-contract.js +1 -0
  78. package/dist/src/server/runtime-store-helpers.d.ts +11 -0
  79. package/dist/src/server/runtime-store-helpers.js +106 -2
  80. package/dist/src/server/runtime-store-workflows.d.ts +6 -0
  81. package/dist/src/server/runtime-store-workflows.js +108 -0
  82. package/dist/src/server/runtime-store.d.ts +3 -72
  83. package/dist/src/server/runtime-store.js +71 -4
  84. package/dist/src/server/session-capture-codex.d.ts +3 -3
  85. package/dist/src/server/session-capture-codex.js +9 -7
  86. package/dist/src/server/session-capture-gemini.d.ts +1 -1
  87. package/dist/src/server/session-capture-gemini.js +6 -3
  88. package/dist/src/server/settings-store.d.ts +3 -0
  89. package/dist/src/server/settings-store.js +1 -0
  90. package/dist/src/server/sqlite-schema-v19.d.ts +2 -0
  91. package/dist/src/server/sqlite-schema-v19.js +17 -0
  92. package/dist/src/server/sqlite-schema-v20.d.ts +2 -0
  93. package/dist/src/server/sqlite-schema-v20.js +20 -0
  94. package/dist/src/server/sqlite-schema-v21.d.ts +2 -0
  95. package/dist/src/server/sqlite-schema-v21.js +20 -0
  96. package/dist/src/server/sqlite-schema.d.ts +1 -1
  97. package/dist/src/server/sqlite-schema.js +110 -1
  98. package/dist/src/server/system-message.d.ts +7 -0
  99. package/dist/src/server/system-message.js +8 -1
  100. package/dist/src/server/task-deps.d.ts +32 -0
  101. package/dist/src/server/task-deps.js +40 -0
  102. package/dist/src/server/tasks-file-watcher.d.ts +12 -1
  103. package/dist/src/server/tasks-file-watcher.js +128 -23
  104. package/dist/src/server/tasks-file.d.ts +3 -1
  105. package/dist/src/server/tasks-file.js +33 -9
  106. package/dist/src/server/tasks-websocket-server.js +13 -14
  107. package/dist/src/server/team-authz.d.ts +1 -1
  108. package/dist/src/server/team-authz.js +10 -1
  109. package/dist/src/server/team-autostaff.d.ts +16 -0
  110. package/dist/src/server/team-autostaff.js +16 -0
  111. package/dist/src/server/team-list-serializer.d.ts +1 -1
  112. package/dist/src/server/team-list-serializer.js +3 -1
  113. package/dist/src/server/team-operations.d.ts +21 -1
  114. package/dist/src/server/team-operations.js +183 -16
  115. package/dist/src/server/terminal-protocol.js +9 -3
  116. package/dist/src/server/terminal-stream-hub.js +16 -10
  117. package/dist/src/server/terminal-ws-server.js +10 -8
  118. package/dist/src/server/webhook-notifier.d.ts +34 -0
  119. package/dist/src/server/webhook-notifier.js +47 -0
  120. package/dist/src/server/websocket-upgrade-safety.d.ts +10 -0
  121. package/dist/src/server/websocket-upgrade-safety.js +35 -0
  122. package/dist/src/server/windows-command-line.d.ts +3 -0
  123. package/dist/src/server/windows-command-line.js +9 -0
  124. package/dist/src/server/windows-filename.d.ts +2 -0
  125. package/dist/src/server/windows-filename.js +33 -0
  126. package/dist/src/server/workflow-cli-policy.d.ts +60 -0
  127. package/dist/src/server/workflow-cli-policy.js +110 -0
  128. package/dist/src/server/workflow-dispatch-awaiter.d.ts +12 -0
  129. package/dist/src/server/workflow-dispatch-awaiter.js +80 -0
  130. package/dist/src/server/workflow-feature.d.ts +15 -0
  131. package/dist/src/server/workflow-feature.js +15 -0
  132. package/dist/src/server/workflow-http-serializers.d.ts +64 -0
  133. package/dist/src/server/workflow-http-serializers.js +58 -0
  134. package/dist/src/server/workflow-output-schema.d.ts +18 -0
  135. package/dist/src/server/workflow-output-schema.js +41 -0
  136. package/dist/src/server/workflow-run-log-store.d.ts +19 -0
  137. package/dist/src/server/workflow-run-log-store.js +45 -0
  138. package/dist/src/server/workflow-run-store.d.ts +50 -0
  139. package/dist/src/server/workflow-run-store.js +103 -0
  140. package/dist/src/server/workflow-runner.d.ts +147 -0
  141. package/dist/src/server/workflow-runner.js +411 -0
  142. package/dist/src/server/workflow-schedule-create.d.ts +14 -0
  143. package/dist/src/server/workflow-schedule-create.js +41 -0
  144. package/dist/src/server/workflow-schedule-store.d.ts +43 -0
  145. package/dist/src/server/workflow-schedule-store.js +112 -0
  146. package/dist/src/server/workflow-scheduler.d.ts +36 -0
  147. package/dist/src/server/workflow-scheduler.js +97 -0
  148. package/dist/src/server/workflow-script-loader.d.ts +34 -0
  149. package/dist/src/server/workflow-script-loader.js +106 -0
  150. package/dist/src/server/workspace-path-validation.js +16 -4
  151. package/dist/src/server/workspace-shell-runtime.d.ts +5 -0
  152. package/dist/src/server/workspace-shell-runtime.js +24 -2
  153. package/dist/src/server/workspace-store-contract.d.ts +4 -1
  154. package/dist/src/server/workspace-store-hydration.js +23 -7
  155. package/dist/src/server/workspace-store-mutations.js +2 -5
  156. package/dist/src/server/workspace-store-support.d.ts +4 -0
  157. package/dist/src/server/workspace-store-support.js +13 -1
  158. package/dist/src/server/workspace-store.js +38 -4
  159. package/dist/src/shared/types.d.ts +16 -1
  160. package/package.json +4 -2
  161. package/web/dist/assets/{AddWorkerDialog-DeZhTQLi.js → AddWorkerDialog-CGbaxu0T.js} +2 -2
  162. package/web/dist/assets/AddWorkspaceDialog-CNgExu6b.js +1 -0
  163. package/web/dist/assets/{FirstRunWizard-B5wLcat5.js → FirstRunWizard-DxGApUNc.js} +1 -1
  164. package/web/dist/assets/{MarketplaceDrawer-BC0eBOEW.js → MarketplaceDrawer-Bk6cpukn.js} +1 -1
  165. package/web/dist/assets/WhatsNewDialog-CSGzk-2U.js +1 -0
  166. package/web/dist/assets/WorkerModal-i2F3n3nZ.js +1 -0
  167. package/web/dist/assets/WorkspaceTaskDrawer-C_Ta_K13.js +1 -0
  168. package/web/dist/assets/WorkspaceTerminalPanels-VdDxtrQF.js +1 -0
  169. package/web/dist/assets/index-5zh61jMg.css +1 -0
  170. package/web/dist/assets/index-CAgGM6nb.js +75 -0
  171. package/web/dist/assets/path-join-7MR1s7b1.js +1 -0
  172. package/web/dist/index.html +2 -2
  173. package/web/dist/sw.js +1 -1
  174. package/web/dist/assets/AddWorkspaceDialog-DDpXNEKf.js +0 -1
  175. package/web/dist/assets/WorkerModal-BwMHq-Bi.js +0 -1
  176. package/web/dist/assets/WorkspaceTaskDrawer-CxvT4nqs.js +0 -1
  177. package/web/dist/assets/WorkspaceTerminalPanels-CvibsPSd.js +0 -1
  178. package/web/dist/assets/index-BEsTmfrO.css +0 -1
  179. package/web/dist/assets/index-Ddb7bDN5.js +0 -75
  180. package/web/dist/assets/path-join-S7qkXQtP.js +0 -1
@@ -18,13 +18,17 @@ const toRecord = (row) => ({
18
18
  deliveredAt: row.delivered_at,
19
19
  fromAgentId: row.from_agent_id,
20
20
  id: row.id,
21
+ label: row.label ?? null,
22
+ phase: row.phase ?? null,
21
23
  reportedAt: row.reported_at,
22
24
  reportText: row.report_text,
23
25
  sequence: row.sequence,
24
26
  status: row.status,
27
+ stepIndex: row.step_index,
25
28
  submittedAt: row.submitted_at,
26
29
  text: row.text,
27
30
  toAgentId: row.to_agent_id,
31
+ workflowRunId: row.workflow_run_id,
28
32
  workspaceId: row.workspace_id,
29
33
  });
30
34
  export const createDispatchLedgerStore = (db) => {
@@ -35,13 +39,17 @@ export const createDispatchLedgerStore = (db) => {
35
39
  deliveredAt: null,
36
40
  fromAgentId: input.fromAgentId ?? null,
37
41
  id: randomUUID(),
42
+ label: input.label ?? null,
43
+ phase: input.phase ?? null,
38
44
  reportedAt: null,
39
45
  reportText: null,
40
46
  sequence: null,
41
47
  status: 'queued',
48
+ stepIndex: input.stepIndex ?? null,
42
49
  submittedAt: null,
43
50
  text: input.text,
44
51
  toAgentId: input.toAgentId,
52
+ workflowRunId: input.workflowRunId ?? null,
45
53
  workspaceId: input.workspaceId,
46
54
  };
47
55
  db.prepare(`INSERT INTO dispatches (
@@ -56,8 +64,12 @@ export const createDispatchLedgerStore = (db) => {
56
64
  submitted_at,
57
65
  reported_at,
58
66
  report_text,
59
- artifacts
60
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(record.id, record.workspaceId, record.fromAgentId, record.toAgentId, record.text, record.status, record.createdAt, record.deliveredAt, record.submittedAt, record.reportedAt, record.reportText, JSON.stringify(record.artifacts));
67
+ artifacts,
68
+ workflow_run_id,
69
+ step_index,
70
+ phase,
71
+ label
72
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(record.id, record.workspaceId, record.fromAgentId, record.toAgentId, record.text, record.status, record.createdAt, record.deliveredAt, record.submittedAt, record.reportedAt, record.reportText, JSON.stringify(record.artifacts), record.workflowRunId, record.stepIndex, record.phase, record.label);
61
73
  return record;
62
74
  };
63
75
  const deleteDispatch = (dispatchId) => {
@@ -175,8 +187,41 @@ export const createDispatchLedgerStore = (db) => {
175
187
  db.prepare('DELETE FROM dispatches WHERE workspace_id = ?').run(workspaceId);
176
188
  };
177
189
  const deleteWorkerDispatches = (workspaceId, workerId) => {
178
- db.prepare('DELETE FROM dispatches WHERE workspace_id = ? AND to_agent_id = ?').run(workspaceId, workerId);
190
+ // Preserve workflow-run dispatch history (`workflow_run_id IS NOT NULL`)
191
+ // so the UI's run-detail timeline can still show what each ephemeral
192
+ // worker did after the worker itself is dismissed. Orchestrator-issued
193
+ // dispatches are tied to the worker identity and are dropped with it.
194
+ db.prepare(`DELETE FROM dispatches
195
+ WHERE workspace_id = ? AND to_agent_id = ? AND workflow_run_id IS NULL`).run(workspaceId, workerId);
179
196
  };
197
+ // Every dispatch fired by a workflow run carries the run id (M1-B added the
198
+ // column; M2-C plumbs it through). This is the timeline query the UI uses to
199
+ // explode a run row into per-worker activity.
200
+ const listWorkflowRunDispatches = (runId) => {
201
+ const rows = db
202
+ .prepare('SELECT * FROM dispatches WHERE workflow_run_id = ? ORDER BY sequence, created_at')
203
+ .all(runId);
204
+ return rows.map(toRecord);
205
+ };
206
+ // Open dispatch ids tied to a workflow run — drives the runner's stop path
207
+ // (each id gets a notifyCancel so the runner's await rejects).
208
+ const listOpenDispatchIdsForRun = (runId) => db
209
+ .prepare(`SELECT id FROM dispatches
210
+ WHERE workflow_run_id = ? AND status IN ('queued', 'submitted')`)
211
+ .all(runId).map((row) => row.id);
212
+ // Open workflow-tagged dispatches addressed to a specific worker. Drives the
213
+ // PTY-exit cancel path (TIER 1 #1): when a workflow-spawned worker dies
214
+ // without calling `team report`, the runner's `awaitReport` would otherwise
215
+ // hang for DEFAULT_TIMEOUT_MS (10 min). The exit handler enumerates these
216
+ // and `notifyCancel`s each so the surrounding `agent()`/`parallel`/`pipeline`
217
+ // sees an immediate reject.
218
+ const listOpenWorkflowDispatchesForWorker = (workspaceId, workerId) => db
219
+ .prepare(`SELECT id, workflow_run_id FROM dispatches
220
+ WHERE workspace_id = ?
221
+ AND to_agent_id = ?
222
+ AND workflow_run_id IS NOT NULL
223
+ AND status IN ('queued', 'submitted')`)
224
+ .all(workspaceId, workerId).map((row) => ({ dispatchId: row.id, runId: row.workflow_run_id }));
180
225
  return {
181
226
  createDispatch,
182
227
  deleteDispatch,
@@ -185,6 +230,9 @@ export const createDispatchLedgerStore = (db) => {
185
230
  findOpenDispatch,
186
231
  findOpenDispatchById,
187
232
  listOpenDispatchKinds,
233
+ listOpenDispatchIdsForRun,
234
+ listOpenWorkflowDispatchesForWorker,
235
+ listWorkflowRunDispatches,
188
236
  listWorkspaceDispatches,
189
237
  markCancelled,
190
238
  markReportedByWorker,
@@ -4,7 +4,7 @@ import { TASKS_RELATIVE_PATH } from './tasks-file.js';
4
4
  const TASKS_HEAD_LIMIT = 1024;
5
5
  const formatWorkers = (workers) => {
6
6
  if (workers.length === 0)
7
- return ['- 当前没有其他 worker'];
7
+ return ['- (no other workers)'];
8
8
  return workers.map((worker) => `- ${worker.name} (${worker.role}, ${worker.status}, pending_task_count: ${worker.pendingTaskCount})`);
9
9
  };
10
10
  const formatRestartWindow = (messages) => {
@@ -12,18 +12,18 @@ const formatRestartWindow = (messages) => {
12
12
  return message.type === 'send';
13
13
  });
14
14
  if (sends.length === 0)
15
- return ['- 重启期间未派新单'];
15
+ return ['- no new dispatches during the restart'];
16
16
  return sends.slice(-5).map((message) => `- send -> ${message.to}: ${message.text}`);
17
17
  };
18
18
  export const buildEnvSyncMessage = ({ agent, tasksContent, workers, workspace, restartWindowMessages, }) => wrapSystemMessage([
19
- '你刚被 Hive 重启了。期间环境变化:',
20
- `- 当前 workspace: ${workspace.name}`,
21
- '- 现有 worker:',
19
+ 'Hive just restarted you. Environment changes during the restart:',
20
+ `- Current workspace: ${workspace.name}`,
21
+ '- Existing workers:',
22
22
  ...formatWorkers(workers),
23
- `- ${TASKS_RELATIVE_PATH} 当前内容:`,
24
- tasksContent.slice(0, TASKS_HEAD_LIMIT) || '()',
23
+ `- Current ${TASKS_RELATIVE_PATH} contents:`,
24
+ tasksContent.slice(0, TASKS_HEAD_LIMIT) || '(empty)',
25
25
  ...formatRestartWindow(restartWindowMessages),
26
- agent.role === 'orchestrator' ? '- Hive worker 派单规则:' : '- Hive worker 边界:',
26
+ agent.role === 'orchestrator' ? '- Hive worker dispatch rules:' : '- Hive worker boundaries:',
27
27
  ...getHiveTeamRules(agent).map((rule) => ` - ${rule}`),
28
- `请继续。如果不确定,用 team list / Read ${TASKS_RELATIVE_PATH} 自查或问 user。`,
28
+ `Continue. If unsure, run team list / Read ${TASKS_RELATIVE_PATH} to self-check, or ask the user.`,
29
29
  ].join('\n'));
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Every experimental feature flag resolved into one snapshot.
3
+ *
4
+ * Threading this bag through the prompt-build call graph — instead of one
5
+ * `getX` accessor per flag — is the whole point of this module: a new flag adds
6
+ * a field here and is read at the one site that needs it, without touching any
7
+ * of the carriers in between (agent-runtime → run-starter / restart-policy /
8
+ * tasks-watcher → the pure builders in hive-team-guidance).
9
+ *
10
+ * Each flag keeps its own storage semantics and doc in its own file
11
+ * ([[workflow-feature]], [[team-autostaff]]); this module only composes them.
12
+ */
13
+ export interface FeatureFlags {
14
+ /** Workflow runtime — `team workflow`, the scheduler, the Drawer, and the
15
+ * orchestrator guidance that teaches them. Default OFF. */
16
+ workflowsEnabled: boolean;
17
+ /** Auto-staff orchestrator guidance — size the team to the task up front
18
+ * rather than one worker at a time. Default ON. */
19
+ autostaffEnabled: boolean;
20
+ }
21
+ /**
22
+ * Conservative all-off snapshot. Use as the parameter default wherever a
23
+ * builder is called without flags — it preserves the per-flag `= false`
24
+ * defaults the builders carried before this registry existed.
25
+ *
26
+ * This is NOT the storage default: an ABSENT `team.autostaff` key reads back
27
+ * ON via {@link readFeatureFlags}. Only an OMITTED argument falls back to off,
28
+ * which is the safe choice (never inject guidance for a flag nobody resolved).
29
+ */
30
+ export declare const FEATURE_FLAGS_ALL_OFF: FeatureFlags;
31
+ interface AppStateReader {
32
+ getAppState: (key: string) => {
33
+ value: string | null;
34
+ } | undefined;
35
+ }
36
+ /**
37
+ * Read every flag from app_state into one snapshot, each with its own storage
38
+ * default (workflows off-when-absent, auto-staff on-when-absent). Called fresh
39
+ * each time so a Settings toggle takes effect without restarting the runtime.
40
+ */
41
+ export declare const readFeatureFlags: (settings: AppStateReader) => FeatureFlags;
42
+ export {};
@@ -0,0 +1,24 @@
1
+ import { AUTOSTAFF_ENABLED_KEY, readAutostaffEnabled } from './team-autostaff.js';
2
+ import { readWorkflowEnabled, WORKFLOW_ENABLED_KEY } from './workflow-feature.js';
3
+ /**
4
+ * Conservative all-off snapshot. Use as the parameter default wherever a
5
+ * builder is called without flags — it preserves the per-flag `= false`
6
+ * defaults the builders carried before this registry existed.
7
+ *
8
+ * This is NOT the storage default: an ABSENT `team.autostaff` key reads back
9
+ * ON via {@link readFeatureFlags}. Only an OMITTED argument falls back to off,
10
+ * which is the safe choice (never inject guidance for a flag nobody resolved).
11
+ */
12
+ export const FEATURE_FLAGS_ALL_OFF = {
13
+ workflowsEnabled: false,
14
+ autostaffEnabled: false,
15
+ };
16
+ /**
17
+ * Read every flag from app_state into one snapshot, each with its own storage
18
+ * default (workflows off-when-absent, auto-staff on-when-absent). Called fresh
19
+ * each time so a Settings toggle takes effect without restarting the runtime.
20
+ */
21
+ export const readFeatureFlags = (settings) => ({
22
+ workflowsEnabled: readWorkflowEnabled(settings.getAppState(WORKFLOW_ENABLED_KEY)?.value ?? null),
23
+ autostaffEnabled: readAutostaffEnabled(settings.getAppState(AUTOSTAFF_ENABLED_KEY)?.value ?? null),
24
+ });
@@ -112,7 +112,11 @@ const windowsPick = async (run) => {
112
112
 
113
113
  `Add-Type -AssemblyName System.Drawing` is required because Point /
114
114
  Size live in System.Drawing.dll, not System.Windows.Forms.dll. */
115
+ // PS 5.1 on zh-CN Windows defaults [Console]::OutputEncoding to cp936/GBK;
116
+ // Node decodes stdout as UTF-8 and CJK paths arrive mojibake'd. Force UTF-8
117
+ // before any output. No-op on PS 7+ which already defaults to UTF-8.
115
118
  const script = [
119
+ '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8',
116
120
  'Add-Type -AssemblyName System.Windows.Forms',
117
121
  'Add-Type -AssemblyName System.Drawing',
118
122
  '$owner = New-Object System.Windows.Forms.Form',
@@ -1,5 +1,6 @@
1
1
  import { homedir } from 'node:os';
2
2
  import { isAbsolute, relative, resolve, sep } from 'node:path';
3
+ import { realpathNative } from './path-canonicalization.js';
3
4
  /**
4
5
  * Root directory the FS-browse API is allowed to reveal. We sandbox to
5
6
  * `$HOME` (override via `HIVE_FS_BROWSE_ROOT` for tests). Anything outside
@@ -7,7 +8,19 @@ import { isAbsolute, relative, resolve, sep } from 'node:path';
7
8
  */
8
9
  export const getFsBrowseRoot = () => {
9
10
  const override = process.env.HIVE_FS_BROWSE_ROOT;
10
- return override && override.length > 0 ? resolve(override) : resolve(homedir());
11
+ const root = override && override.length > 0 ? resolve(override) : resolve(homedir());
12
+ try {
13
+ return realpathNative(root);
14
+ }
15
+ catch {
16
+ return root;
17
+ }
18
+ };
19
+ const isResolvedPathWithinRoot = (rootPath, candidatePath) => {
20
+ if (candidatePath === rootPath)
21
+ return true;
22
+ const rel = relative(rootPath, candidatePath);
23
+ return rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
11
24
  };
12
25
  /**
13
26
  * True when `candidatePath` is `rootPath` itself or a descendant of it.
@@ -16,10 +29,26 @@ export const getFsBrowseRoot = () => {
16
29
  * isPathWithinRoot so the semantics match a project we already trust.
17
30
  */
18
31
  export const isPathWithinRoot = (rootPath, candidatePath) => {
19
- const resolvedRoot = resolve(rootPath);
20
- const resolvedCandidate = resolve(candidatePath);
21
- if (resolvedCandidate === resolvedRoot)
22
- return true;
23
- const rel = relative(resolvedRoot, resolvedCandidate);
24
- return rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
32
+ const lexicalRoot = resolve(rootPath);
33
+ const lexicalCandidate = resolve(candidatePath);
34
+ let resolvedRoot = lexicalRoot;
35
+ let resolvedCandidate = lexicalCandidate;
36
+ try {
37
+ resolvedRoot = realpathNative(resolvedRoot);
38
+ }
39
+ catch {
40
+ // Missing / inaccessible roots are handled by the caller's readdir/stat path.
41
+ }
42
+ try {
43
+ resolvedCandidate = realpathNative(resolvedCandidate);
44
+ }
45
+ catch {
46
+ // Non-existent children still need lexical sandboxing for "create later"
47
+ // probes; existing symlinks/junctions use the realpath branch above.
48
+ if (isResolvedPathWithinRoot(lexicalRoot, lexicalCandidate)) {
49
+ resolvedRoot = lexicalRoot;
50
+ resolvedCandidate = lexicalCandidate;
51
+ }
52
+ }
53
+ return isResolvedPathWithinRoot(resolvedRoot, resolvedCandidate);
25
54
  };
@@ -1,4 +1,6 @@
1
1
  import type { AgentSummary } from '../shared/types.js';
2
+ import { type FeatureFlags } from './feature-flags.js';
3
+ import { type WorkflowCliPolicy } from './workflow-cli-policy.js';
2
4
  /**
3
5
  * Tail reminder appended to every message that flows INTO the orchestrator
4
6
  * (worker reports, worker status updates, user chat input). Re-anchors the
@@ -11,10 +13,12 @@ import type { AgentSummary } from '../shared/types.js';
11
13
  * banner noise after a few occurrences, but `<...-system-reminder>` tags
12
14
  * mirror the out-of-band envelope LLMs are trained to attend to; placement
13
15
  * at the tail (right before the agent's reply turn) maximizes recency
14
- * weighting; phrasing as a two-option action menu is more actionable than
15
- * abstract identity restatement.
16
+ * weighting; phrasing as a short action menu is more actionable than abstract
17
+ * identity restatement. Kept deliberately SHORT — the full command syntax and
18
+ * the workflow DSL live in `.hive/PROTOCOL.md`, which agents re-read on demand.
19
+ * A long banner on every turn is itself the noise this envelope exists to beat.
16
20
  */
17
- export declare const ORCHESTRATOR_REMINDER_TAIL: string;
21
+ export declare const buildOrchestratorReminderTail: ({ workflowsEnabled }: FeatureFlags) => string;
18
22
  /**
19
23
  * Tail reminder appended to dispatches sent TO a worker. Reinforces the
20
24
  * worker identity (so the agent does not regress into its normal CLI
@@ -22,12 +26,14 @@ export declare const ORCHESTRATOR_REMINDER_TAIL: string;
22
26
  * with dispatch_id pre-bound.
23
27
  */
24
28
  export declare const buildWorkerReminderTail: (dispatchId: string) => string;
25
- export declare const getHiveTeamRules: (agent: Pick<AgentSummary, "role">) => string[];
29
+ export declare const getHiveTeamRules: (agent: Pick<AgentSummary, "role">, flags?: FeatureFlags) => readonly string[];
26
30
  /**
27
31
  * Workspace-local protocol cheat sheet written to `.hive/PROTOCOL.md`. Agents
28
32
  * are explicitly trained to look at project root markdown when confused, so
29
33
  * keeping a single canonical doc next to `.hive/tasks.md` doubles as a
30
34
  * "cat-recover" path when both the startup prompt and the in-message
31
- * reminders fail to anchor.
35
+ * reminders fail to anchor. This is also the single home of the full command
36
+ * syntax and the workflow DSL reference — the always-on injections only carry
37
+ * the lean core rules and point here.
32
38
  */
33
- export declare const buildProtocolDoc: () => string;
39
+ export declare const buildProtocolDoc: (cliPolicy?: WorkflowCliPolicy, flags?: FeatureFlags) => string;