@tt-a1i/hive 2.1.4 → 2.1.6

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 (71) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/src/cli/team.d.ts +4 -1
  3. package/dist/src/cli/team.js +95 -6
  4. package/dist/src/server/agent-startup-instructions.d.ts +1 -0
  5. package/dist/src/server/agent-startup-instructions.js +3 -2
  6. package/dist/src/server/hive-team-guidance.js +4 -4
  7. package/dist/src/server/routes-team-memory.js +53 -2
  8. package/dist/src/server/routes-workspace-memory.js +31 -2
  9. package/dist/src/server/runtime-store-contract.d.ts +2 -0
  10. package/dist/src/server/runtime-store-dream.d.ts +2 -5
  11. package/dist/src/server/runtime-store-dream.js +2 -12
  12. package/dist/src/server/runtime-store-helpers.d.ts +4 -0
  13. package/dist/src/server/runtime-store-helpers.js +21 -1
  14. package/dist/src/server/runtime-store-memory.d.ts +6 -0
  15. package/dist/src/server/runtime-store-memory.js +1 -0
  16. package/dist/src/server/sqlite-schema-v36.d.ts +3 -0
  17. package/dist/src/server/sqlite-schema-v36.js +21 -0
  18. package/dist/src/server/sqlite-schema.d.ts +1 -1
  19. package/dist/src/server/sqlite-schema.js +6 -1
  20. package/dist/src/server/team-memory-diagnostics.d.ts +86 -0
  21. package/dist/src/server/team-memory-diagnostics.js +87 -0
  22. package/dist/src/server/team-memory-digest.d.ts +7 -0
  23. package/dist/src/server/team-memory-digest.js +22 -5
  24. package/dist/src/server/team-memory-dream-applier.js +20 -3
  25. package/dist/src/server/team-memory-dream-cli.d.ts +13 -0
  26. package/dist/src/server/team-memory-dream-cli.js +115 -0
  27. package/dist/src/server/team-memory-dream-input.d.ts +15 -0
  28. package/dist/src/server/team-memory-dream-input.js +14 -0
  29. package/dist/src/server/team-memory-dream-ops.d.ts +4 -1
  30. package/dist/src/server/team-memory-dream-ops.js +32 -3
  31. package/dist/src/server/team-memory-dream-prompt.js +5 -3
  32. package/dist/src/server/team-memory-dream-reverter.js +13 -3
  33. package/dist/src/server/team-memory-dream-run-store.d.ts +1 -0
  34. package/dist/src/server/team-memory-dream-run-store.js +20 -0
  35. package/dist/src/server/team-memory-dream-runner.d.ts +10 -1
  36. package/dist/src/server/team-memory-dream-runner.js +34 -5
  37. package/dist/src/server/team-memory-dream-scheduler.js +2 -2
  38. package/dist/src/server/team-memory-dream-store.d.ts +2 -1
  39. package/dist/src/server/team-memory-dream-store.js +1 -1
  40. package/dist/src/server/team-memory-dream-types.d.ts +5 -1
  41. package/dist/src/server/team-memory-export.js +7 -0
  42. package/dist/src/server/team-memory-http-serializers.d.ts +15 -0
  43. package/dist/src/server/team-memory-http-serializers.js +7 -0
  44. package/dist/src/server/team-memory-provider.d.ts +33 -0
  45. package/dist/src/server/team-memory-provider.js +54 -0
  46. package/dist/src/server/team-memory-store.d.ts +10 -3
  47. package/dist/src/server/team-memory-store.js +134 -58
  48. package/dist/src/shared/team-memory.d.ts +13 -0
  49. package/dist/src/shared/team-memory.js +12 -0
  50. package/package.json +1 -1
  51. package/web/dist/assets/{AddWorkerDialog-CkCGKa0N.js → AddWorkerDialog-DFNkbR_Q.js} +2 -2
  52. package/web/dist/assets/AddWorkspaceFlow-BjpjCuRe.js +1 -0
  53. package/web/dist/assets/{FirstRunWizard-Db4HWbBQ.js → FirstRunWizard-BuLgUAny.js} +1 -1
  54. package/web/dist/assets/{MarketplaceDrawer-DHwl1if1.js → MarketplaceDrawer-BALuhrnd.js} +1 -1
  55. package/web/dist/assets/{TaskGraphDrawer-B_OibVQO.js → TaskGraphDrawer-DQTS6JPI.js} +1 -1
  56. package/web/dist/assets/{WhatsNewDialog-9QXlLVfy.js → WhatsNewDialog-DpgjEIaA.js} +1 -1
  57. package/web/dist/assets/{WorkerModal-BGdtte3-.js → WorkerModal-1y-Xdwv-.js} +1 -1
  58. package/web/dist/assets/{WorkflowsDrawer-DRuS0Ao5.js → WorkflowsDrawer-DPWlZs4S.js} +1 -1
  59. package/web/dist/assets/WorkspaceMemoryDrawer-C0vny4zK.js +1 -0
  60. package/web/dist/assets/WorkspaceTaskDrawer-CJcFZh8C.js +1 -0
  61. package/web/dist/assets/index-CEP_bvOg.css +1 -0
  62. package/web/dist/assets/index-CR1SPGBZ.js +84 -0
  63. package/web/dist/assets/{search-BHvXxsdK.js → search-Bl5O-SfR.js} +1 -1
  64. package/web/dist/assets/{square-terminal-CzkQzjCU.js → square-terminal-DCDaflg3.js} +1 -1
  65. package/web/dist/index.html +2 -2
  66. package/web/dist/sw.js +1 -1
  67. package/web/dist/assets/AddWorkspaceFlow-Cd73iChz.js +0 -1
  68. package/web/dist/assets/WorkspaceMemoryDrawer-C8PuHo0x.js +0 -1
  69. package/web/dist/assets/WorkspaceTaskDrawer-6mbgRoOq.js +0 -1
  70. package/web/dist/assets/index-BiGD5NhO.js +0 -84
  71. package/web/dist/assets/index-CG2TurwT.css +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,37 @@
2
2
 
3
3
  All notable user-facing changes will be documented in this file.
4
4
 
5
+ ## 2.1.6 - 2026-06-21
6
+
7
+ Team UX polish and release visibility.
8
+
9
+ - Adds a global package-update prompt so running Hive can surface a newer npm
10
+ version without relying only on the topbar badge.
11
+ - Makes worker startup handshakes explicit: newly started members now report a
12
+ ready status back to the Orchestrator after receiving Hive's injected startup
13
+ instructions, making failed starts easier to distinguish from idle workers.
14
+ - Removes the Orchestrator pane stop button from the UI so users cannot
15
+ accidentally close the central coordinator from the pane chrome.
16
+ - Reworks the Action Center entry into a dedicated drawer with live workspace
17
+ health, attention, recent activity, and worker selection instead of the old
18
+ compact popover.
19
+
20
+ ## 2.1.5 - 2026-06-21
21
+
22
+ Ambient memory reliability and background consolidation.
23
+
24
+ - Makes team memory quieter and more automatic by removing the visible
25
+ candidate-review surface from the Memory drawer while keeping active,
26
+ archived, and Dream audit history available when you look for it.
27
+ - Adds user-scoped memory for lightweight personal preferences and working
28
+ style, without mixing those preferences into workspace project facts.
29
+ - Adds structured procedure references so workflows, skills, and checklists can
30
+ be recalled as short references instead of long copied instructions.
31
+ - Improves dispatch memory retrieval so unrelated worker-role matches do not
32
+ inject stale or cross-task memory into a new assignment.
33
+ - Moves scheduled Dream consolidation into a background apply path with
34
+ transaction checks, source-window validation, failure isolation, and revert.
35
+
5
36
  ## 2.1.4 - 2026-06-21
6
37
 
7
38
  Quieter onboarding and team activity signals.
@@ -1,4 +1,4 @@
1
- import { type MemoryKind } from '../shared/team-memory.js';
1
+ import { type MemoryKind, type MemoryProcedureRef, type MemoryScope } from '../shared/team-memory.js';
2
2
  interface ParsedCancelArgs {
3
3
  dispatchId: string;
4
4
  reason: string;
@@ -19,6 +19,8 @@ export declare const parseRecallArgs: (args: string[]) => {
19
19
  export interface ParsedMemoryAddArgs {
20
20
  body: string;
21
21
  kind: MemoryKind;
22
+ procedureRef: MemoryProcedureRef | null;
23
+ scope: MemoryScope;
22
24
  tags: string[];
23
25
  }
24
26
  export declare const parseMemoryAddArgs: (args: string[]) => ParsedMemoryAddArgs;
@@ -26,6 +28,7 @@ export declare const parseMemoryShowArgs: (args: string[]) => {
26
28
  memoryId: string;
27
29
  };
28
30
  export declare const parseMemorySearchArgs: (args: string[]) => {
31
+ scope: "workspace" | "user" | "all";
29
32
  limit?: number;
30
33
  query: string;
31
34
  };
@@ -1,7 +1,7 @@
1
1
  import { fileURLToPath } from 'node:url';
2
2
  import { BUILTIN_COMMAND_PRESET_CLI_LIST } from '../server/command-preset-defaults.js';
3
3
  import { sameFilesystemPath } from '../server/path-canonicalization.js';
4
- import { isMemoryKind, MEMORY_BODY_MAX_CHARS, MEMORY_KINDS, MEMORY_QUERY_MAX_CHARS, MEMORY_SEARCH_MAX_LIMIT, MEMORY_TAG_MAX_CHARS, MEMORY_TAG_MAX_COUNT, } from '../shared/team-memory.js';
4
+ import { isMemoryKind, isMemoryProcedureRefType, isMemoryScope, MEMORY_BODY_MAX_CHARS, MEMORY_KINDS, MEMORY_PROCEDURE_REF_ID_MAX_CHARS, MEMORY_PROCEDURE_REF_TITLE_MAX_CHARS, MEMORY_PROCEDURE_REF_TYPES, MEMORY_QUERY_MAX_CHARS, MEMORY_SCOPES, MEMORY_SEARCH_MAX_LIMIT, MEMORY_TAG_MAX_CHARS, MEMORY_TAG_MAX_COUNT, } from '../shared/team-memory.js';
5
5
  import { RECALL_QUERY_MAX_CHARS } from '../shared/team-recall.js';
6
6
  const REQUIRED_ENV_KEYS = [
7
7
  'HIVE_PORT',
@@ -14,9 +14,9 @@ const TEAM_USAGE = [
14
14
  ' team list',
15
15
  ' team next (tasks in .hive/tasks.md that are unblocked now — those whose [needs: #n] deps are all done)',
16
16
  ' team recall "<query>" [--limit <n>] [--window <n>]',
17
- ' team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--tag <tag>]',
17
+ ' team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--scope workspace|user] [--tag <tag>] [--ref-type workflow|skill|procedure|template|doc --ref-id <id> [--ref-title <title>]]',
18
18
  ' team memory show <memory-id>',
19
- ' team memory search "<query>" [--limit <n>]',
19
+ ' team memory search "<query>" [--limit <n>] [--scope workspace|user|all]',
20
20
  ' team memory dream show <dream-run-id>',
21
21
  ' team memory apply --run <dream-run-id> --stdin',
22
22
  ' team memory forget <memory-id>',
@@ -107,9 +107,9 @@ const REPORT_USAGE = 'Usage: team report (<result> | --stdin) [--dispatch <dispa
107
107
  const STATUS_USAGE = 'Usage: team status (<current status> | --stdin) [--artifact <path>]';
108
108
  const CANCEL_USAGE = 'Usage: team cancel --dispatch <dispatch-id> <reason>';
109
109
  const RECALL_USAGE = 'Usage: team recall "<query>" [--limit <n>] [--window <n>]';
110
- const MEMORY_ADD_USAGE = 'Usage: team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--tag <tag>]';
110
+ const MEMORY_ADD_USAGE = 'Usage: team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--scope workspace|user] [--tag <tag>] [--ref-type workflow|skill|procedure|template|doc --ref-id <id> [--ref-title <title>]]';
111
111
  const MEMORY_SHOW_USAGE = 'Usage: team memory show <memory-id>';
112
- const MEMORY_SEARCH_USAGE = 'Usage: team memory search "<query>" [--limit <n>]';
112
+ const MEMORY_SEARCH_USAGE = 'Usage: team memory search "<query>" [--limit <n>] [--scope workspace|user|all]';
113
113
  const MEMORY_DREAM_SHOW_USAGE = 'Usage: team memory dream show <dream-run-id>';
114
114
  const MEMORY_APPLY_USAGE = 'Usage: team memory apply --run <dream-run-id> --stdin';
115
115
  const MEMORY_FORGET_USAGE = 'Usage: team memory forget <memory-id>';
@@ -256,6 +256,10 @@ export const parseMemoryAddArgs = (args) => {
256
256
  const positionals = [];
257
257
  const tags = [];
258
258
  let kind = 'fact';
259
+ let procedureRefId;
260
+ let procedureRefTitle = null;
261
+ let procedureRefType;
262
+ let scope = 'workspace';
259
263
  for (let index = 0; index < args.length; index += 1) {
260
264
  const arg = args[index];
261
265
  if (arg === undefined)
@@ -272,6 +276,58 @@ export const parseMemoryAddArgs = (args) => {
272
276
  index += 1;
273
277
  continue;
274
278
  }
279
+ if (arg === '--scope') {
280
+ const next = args[index + 1];
281
+ if (next === undefined || next.startsWith('--')) {
282
+ throw new Error(`--scope requires a value\n\n${MEMORY_ADD_USAGE}`);
283
+ }
284
+ if (!isMemoryScope(next)) {
285
+ throw new Error(`--scope must be one of: ${MEMORY_SCOPES.join(', ')}\n\n${MEMORY_ADD_USAGE}`);
286
+ }
287
+ scope = next;
288
+ index += 1;
289
+ continue;
290
+ }
291
+ if (arg === '--ref-type') {
292
+ const next = args[index + 1];
293
+ if (next === undefined || next.startsWith('--')) {
294
+ throw new Error(`--ref-type requires a value\n\n${MEMORY_ADD_USAGE}`);
295
+ }
296
+ if (!isMemoryProcedureRefType(next)) {
297
+ throw new Error(`--ref-type must be one of: ${MEMORY_PROCEDURE_REF_TYPES.join(', ')}\n\n${MEMORY_ADD_USAGE}`);
298
+ }
299
+ procedureRefType = next;
300
+ index += 1;
301
+ continue;
302
+ }
303
+ if (arg === '--ref-id') {
304
+ const next = args[index + 1];
305
+ if (next === undefined || next.startsWith('--')) {
306
+ throw new Error(`--ref-id requires a value\n\n${MEMORY_ADD_USAGE}`);
307
+ }
308
+ const refId = next.trim();
309
+ if (!refId)
310
+ throw new Error(`--ref-id requires a non-empty value\n\n${MEMORY_ADD_USAGE}`);
311
+ if ([...refId].length > MEMORY_PROCEDURE_REF_ID_MAX_CHARS) {
312
+ throw new Error(`--ref-id must be ${MEMORY_PROCEDURE_REF_ID_MAX_CHARS} characters or fewer\n\n${MEMORY_ADD_USAGE}`);
313
+ }
314
+ procedureRefId = refId;
315
+ index += 1;
316
+ continue;
317
+ }
318
+ if (arg === '--ref-title') {
319
+ const next = args[index + 1];
320
+ if (next === undefined || next.startsWith('--')) {
321
+ throw new Error(`--ref-title requires a value\n\n${MEMORY_ADD_USAGE}`);
322
+ }
323
+ const refTitle = next.trim();
324
+ if ([...refTitle].length > MEMORY_PROCEDURE_REF_TITLE_MAX_CHARS) {
325
+ throw new Error(`--ref-title must be ${MEMORY_PROCEDURE_REF_TITLE_MAX_CHARS} characters or fewer\n\n${MEMORY_ADD_USAGE}`);
326
+ }
327
+ procedureRefTitle = refTitle || null;
328
+ index += 1;
329
+ continue;
330
+ }
275
331
  if (arg === '--tag') {
276
332
  const next = args[index + 1];
277
333
  if (next === undefined || next.startsWith('--')) {
@@ -307,7 +363,23 @@ export const parseMemoryAddArgs = (args) => {
307
363
  if ([...body].length > MEMORY_BODY_MAX_CHARS) {
308
364
  throw new Error(`body must be ${MEMORY_BODY_MAX_CHARS} characters or fewer\n\n${MEMORY_ADD_USAGE}`);
309
365
  }
310
- return { body, kind, tags };
366
+ if ((procedureRefType || procedureRefId || procedureRefTitle) &&
367
+ (!procedureRefType || !procedureRefId)) {
368
+ throw new Error(`--ref-type and --ref-id must be provided together\n\n${MEMORY_ADD_USAGE}`);
369
+ }
370
+ const procedureRef = procedureRefType && procedureRefId
371
+ ? { id: procedureRefId, title: procedureRefTitle, type: procedureRefType }
372
+ : null;
373
+ if (kind === 'procedure_ref' && !procedureRef) {
374
+ throw new Error(`--kind procedure_ref requires --ref-type and --ref-id\n\n${MEMORY_ADD_USAGE}`);
375
+ }
376
+ return {
377
+ body,
378
+ kind,
379
+ procedureRef,
380
+ scope,
381
+ tags,
382
+ };
311
383
  };
312
384
  export const parseMemoryShowArgs = (args) => {
313
385
  if (args.length !== 1 || !args[0] || args[0].startsWith('--')) {
@@ -318,6 +390,7 @@ export const parseMemoryShowArgs = (args) => {
318
390
  export const parseMemorySearchArgs = (args) => {
319
391
  const positionals = [];
320
392
  let limit;
393
+ let scope = 'workspace';
321
394
  for (let index = 0; index < args.length; index += 1) {
322
395
  const arg = args[index];
323
396
  if (arg === undefined)
@@ -335,6 +408,18 @@ export const parseMemorySearchArgs = (args) => {
335
408
  index += 1;
336
409
  continue;
337
410
  }
411
+ if (arg === '--scope') {
412
+ const next = args[index + 1];
413
+ if (next === undefined || next.startsWith('--')) {
414
+ throw new Error(`--scope requires a value\n\n${MEMORY_SEARCH_USAGE}`);
415
+ }
416
+ if (next !== 'all' && !isMemoryScope(next)) {
417
+ throw new Error(`--scope must be workspace, user, or all\n\n${MEMORY_SEARCH_USAGE}`);
418
+ }
419
+ scope = next;
420
+ index += 1;
421
+ continue;
422
+ }
338
423
  if (arg.startsWith('--')) {
339
424
  throw new Error(`Unknown argument: ${arg}\n\n${MEMORY_SEARCH_USAGE}`);
340
425
  }
@@ -353,6 +438,7 @@ export const parseMemorySearchArgs = (args) => {
353
438
  return {
354
439
  query,
355
440
  ...(limit !== undefined ? { limit } : {}),
441
+ scope,
356
442
  };
357
443
  };
358
444
  export const parseMemoryDreamShowArgs = (args) => {
@@ -515,6 +601,8 @@ export const runTeamCommand = async (argv) => {
515
601
  token: env.HIVE_AGENT_TOKEN,
516
602
  body: memory.body,
517
603
  kind: memory.kind,
604
+ procedure_ref: memory.procedureRef,
605
+ scope: memory.scope,
518
606
  tags: memory.tags,
519
607
  });
520
608
  console.log(JSON.stringify(await response.json()));
@@ -541,6 +629,7 @@ export const runTeamCommand = async (argv) => {
541
629
  token: env.HIVE_AGENT_TOKEN,
542
630
  query: memory.query,
543
631
  ...(memory.limit !== undefined ? { limit: memory.limit } : {}),
632
+ scope: memory.scope,
544
633
  });
545
634
  console.log(JSON.stringify(await response.json()));
546
635
  return;
@@ -8,6 +8,7 @@ export declare const buildAgentLegacyIdentityMarker: ({ agent, workspace, }: {
8
8
  agent: AgentSummary;
9
9
  workspace: WorkspaceSummary;
10
10
  }) => string;
11
+ export declare const WORKER_STARTUP_READY_STATUS = "ready: startup prompt received; Hive CLI channel OK; waiting for dispatch.";
11
12
  export declare const buildAgentStartupInstructions: ({ agent, memoryDigest, workspace, flags, }: {
12
13
  agent: AgentSummary;
13
14
  memoryDigest?: string | null | undefined;
@@ -5,6 +5,7 @@ import { getHiveTeamRules } from './hive-team-guidance.js';
5
5
  import { TASKS_RELATIVE_PATH } from './tasks-file.js';
6
6
  export const buildAgentSessionBindingMarker = ({ agent, workspace, }) => `Hive session binding: workspace_id=${workspace.id}; agent_id=${agent.id}`;
7
7
  export const buildAgentLegacyIdentityMarker = ({ agent, workspace, }) => `You are ${escapeHiveEnvelopeText(agent.name)} (${agent.role}) in workspace ${escapeHiveEnvelopeText(workspace.name)}.`;
8
+ export const WORKER_STARTUP_READY_STATUS = 'ready: startup prompt received; Hive CLI channel OK; waiting for dispatch.';
8
9
  export const buildAgentStartupInstructions = ({ agent, memoryDigest, workspace, flags = FEATURE_FLAGS_ALL_OFF, }) => {
9
10
  const { workflowsEnabled } = flags;
10
11
  const lines = [
@@ -24,7 +25,7 @@ export const buildAgentStartupInstructions = ({ agent, memoryDigest, workspace,
24
25
  lines.push(memoryDigest, '');
25
26
  }
26
27
  if (agent.role === 'orchestrator') {
27
- lines.push('Your responsibilities:', '- Respond to the user directly; clarify the goal and break it into dispatchable tasks', `- Maintain ${TASKS_RELATIVE_PATH} (GFM task list; mark dependencies with a trailing \`[needs: #2, #5]\` — 1-based positions; \`team next\` lists the tasks unblocked right now)`, '- Dispatch by worker name and drive the next step from each report', '', 'Available team commands:', '- team list', '- team next', '- team recall "<query>" [--limit <n>] [--window <n>]', '- team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--tag <tag>]', '- team memory show <memory-id>', '- team memory search "<query>" [--limit <n>]', '- team memory dream show <dream-run-id>', '- team memory apply --run <dream-run-id> --stdin', '- team memory forget <memory-id>', '- team send "<worker-name>" "<task>"', `- team spawn <role> [--name <n>] [--cli <${BUILTIN_COMMAND_PRESET_CLI_LIST}>] [--ephemeral]`, '- team dismiss <worker-name>', '- team cancel --dispatch <id> "<reason>"', ...(workflowsEnabled
28
+ lines.push('Your responsibilities:', '- Respond to the user directly; clarify the goal and break it into dispatchable tasks', `- Maintain ${TASKS_RELATIVE_PATH} (GFM task list; mark dependencies with a trailing \`[needs: #2, #5]\` — 1-based positions; \`team next\` lists the tasks unblocked right now)`, '- Dispatch by worker name and drive the next step from each report', '', 'Available team commands:', '- team list', '- team next', '- team recall "<query>" [--limit <n>] [--window <n>]', '- team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--scope workspace|user] [--tag <tag>] [--ref-type workflow|skill|procedure|template|doc --ref-id <id> [--ref-title <title>]]', '- team memory show <memory-id>', '- team memory search "<query>" [--limit <n>] [--scope workspace|user|all]', '- team memory dream show <dream-run-id>', '- team memory apply --run <dream-run-id> --stdin', '- team memory forget <memory-id>', '- team send "<worker-name>" "<task>"', `- team spawn <role> [--name <n>] [--cli <${BUILTIN_COMMAND_PRESET_CLI_LIST}>] [--ephemeral]`, '- team dismiss <worker-name>', '- team cancel --dispatch <id> "<reason>"', ...(workflowsEnabled
28
29
  ? [
29
30
  '- team workflow run --stdin (fan-out / staged work — see .hive/PROTOCOL.md for the DSL)',
30
31
  ]
@@ -37,7 +38,7 @@ export const buildAgentStartupInstructions = ({ agent, memoryDigest, workspace,
37
38
  lines.push('Available team commands:', '- team status "<finding>" [--artifact <path>] escalate a patrol finding to the Orchestrator', '- team status --stdin [--artifact <path>] same, body read from stdin', '- team recall "<query>" [--limit <n>] [--window <n>] search prior team messages/reports in this workspace', '- team memory show <memory-id> inspect a memory entry and its evidence', '- team memory search "<query>" [--limit <n>] search active workspace memory', '- team --help command syntax only', '', 'You observe only: no dispatches are ever assigned to you, and `team report` is not available to your role.', '', 'Hive sentinel boundaries:', ...getHiveTeamRules(agent, flags));
38
39
  }
39
40
  else {
40
- lines.push('Available team commands:', '- team report "<result>" [--dispatch <id>] [--artifact <path>] report done / failed / blocked', '- team report --stdin [--dispatch <id>] [--artifact <path>] same, body read from stdin (multi-line / quotes / special chars)', '- team status "<state>" [--artifact <path>] progress / standby update at any time; never closes a dispatch', '- team status --stdin [--artifact <path>] same, body read from stdin', '- team recall "<query>" [--limit <n>] [--window <n>] search prior team messages/reports in this workspace', '- team memory show <memory-id> inspect a memory entry and its evidence', '- team memory search "<query>" [--limit <n>] search active workspace memory', '- team memory dream show <dream-run-id> inspect a pending Dream run only when the Orchestrator assigns memory review', '- team --help command syntax only; NOT a way to report', '', 'Syntax notes:', '- The body is the first positional argument; flag order is free: `team report "result" --dispatch X` and `team report --dispatch X "result"` are both valid.', "- Long bodies (multi-line / quotes / shell metacharacters) always go through `--stdin`, piped in via your shell (POSIX: a quoted heredoc `<<'EOF' … EOF` to stop $var / backtick expansion; Windows cmd: `type body.txt |` or `< body.txt`; PowerShell: `Get-Content -Raw -Encoding utf8 body.txt |`). `--stdin` only reads from stdin and relies on no shell syntax of its own.", '- On error the CLI also prints USAGE — fix the arguments against it.', '', 'Hive worker boundaries:', ...getHiveTeamRules(agent, flags));
41
+ lines.push('Available team commands:', '- team report "<result>" [--dispatch <id>] [--artifact <path>] report done / failed / blocked', '- team report --stdin [--dispatch <id>] [--artifact <path>] same, body read from stdin (multi-line / quotes / special chars)', '- team status "<state>" [--artifact <path>] progress / standby update at any time; never closes a dispatch', '- team status --stdin [--artifact <path>] same, body read from stdin', '- team recall "<query>" [--limit <n>] [--window <n>] search prior team messages/reports in this workspace', '- team memory show <memory-id> inspect a memory entry and its evidence', '- team memory search "<query>" [--limit <n>] search active workspace memory', '- team memory dream show <dream-run-id> inspect a pending Dream run only when the Orchestrator assigns memory review', '- team --help command syntax only; NOT a way to report', '', 'Startup handshake:', `- After reading this startup message, immediately run exactly once: \`team status "${WORKER_STARTUP_READY_STATUS}"\`.`, '- This readiness status tells the Orchestrator this member started successfully; it does not close any dispatch.', '- Do not use `team report` for startup readiness. Use `team report` only after you receive an assigned dispatch task.', '', 'Syntax notes:', '- The body is the first positional argument; flag order is free: `team report "result" --dispatch X` and `team report --dispatch X "result"` are both valid.', "- Long bodies (multi-line / quotes / shell metacharacters) always go through `--stdin`, piped in via your shell (POSIX: a quoted heredoc `<<'EOF' … EOF` to stop $var / backtick expansion; Windows cmd: `type body.txt |` or `< body.txt`; PowerShell: `Get-Content -Raw -Encoding utf8 body.txt |`). `--stdin` only reads from stdin and relies on no shell syntax of its own.", '- On error the CLI also prints USAGE — fix the arguments against it.', '', 'Hive worker boundaries:', ...getHiveTeamRules(agent, flags));
41
42
  }
42
43
  lines.push('', '</hive-message>', '');
43
44
  return lines.join('\n');
@@ -105,7 +105,7 @@ const WORKER_RULES = [
105
105
  'When an assigned task is done, blocked, or has failed, you MUST report to the Orchestrator with `team report`.',
106
106
  'Assume no one is watching your terminal: the user converses with the Orchestrator, not with you. Never stop to wait for terminal input — if you need a decision or are missing information, `team report` the question as blocked and let the Orchestrator decide.',
107
107
  'If you never report, your status stays `working` forever (Hive has no timeout detection) and your work counts as not done.',
108
- '`team status` may be sent at any time (mid-task progress or standby); it NEVER closes a dispatch — only `team report` (or an orchestrator `team cancel`) does.',
108
+ '`team status` may be sent at startup or any time afterward (ready / progress / standby); it NEVER closes a dispatch — only `team report` (or an orchestrator `team cancel`) does.',
109
109
  'Use `team recall "<query>"` when prior team messages or reports may contain useful evidence.',
110
110
  'Use `team memory search "<query>"` to inspect active workspace memory. Include durable findings in `team report`. If the Orchestrator explicitly assigns Dream review, you may run `team memory dream show <dream-run-id>` and propose ops in `team report`; workers cannot apply, add, or forget memory.',
111
111
  '`team --help` only prints command syntax — it is NOT a way to report; its output never reaches the Orchestrator. You still owe a real `team report` / `team status` afterward.',
@@ -320,9 +320,9 @@ export const buildProtocolDoc = (cliPolicy = DEFAULT_WORKFLOW_CLI_POLICY, flags
320
320
  '- `team list` — show workspace members and their status; each worker lists its open dispatches (id, age, queued/submitted) — use those ids for `team cancel`',
321
321
  '- `team next` — tasks in `.hive/tasks.md` that are unblocked right now (mark dependencies with a trailing `[needs: #2, #5]` — 1-based task positions; `team next` returns only tasks whose deps are all done)',
322
322
  '- `team recall "<query>" [--limit <n>] [--window <n>]` — search prior team messages/reports in this workspace',
323
- '- `team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--tag <tag>]` — save durable workspace memory (orchestrator entries become active)',
323
+ '- `team memory add "<body>" [--kind fact|preference|decision|pitfall|procedure_ref] [--scope workspace|user] [--tag <tag>] [--ref-type workflow|skill|procedure|template|doc --ref-id <id> [--ref-title <title>]]` — save durable workspace/user memory (orchestrator entries become active)',
324
324
  '- `team memory show <memory-id>` — inspect a memory entry and evidence snapshots',
325
- '- `team memory search "<query>" [--limit <n>]` — search active workspace memory',
325
+ '- `team memory search "<query>" [--limit <n>] [--scope workspace|user|all]` — search active memory',
326
326
  '- `team memory dream show <dream-run-id>` — inspect the bounded input for a pending memory maintenance run',
327
327
  '- `team memory apply --run <dream-run-id> --stdin` — apply strict JSON Dream ops for a pending maintenance run',
328
328
  '- `team memory forget <memory-id>` — archive obsolete memory (orchestrator only; does not physically delete evidence)',
@@ -341,7 +341,7 @@ export const buildProtocolDoc = (cliPolicy = DEFAULT_WORKFLOW_CLI_POLICY, flags
341
341
  '- `team memory dream show <dream-run-id>` — inspect a pending Dream run only when the orchestrator assigns memory review; propose ops in `team report`, never apply',
342
342
  '- `team report "<result>" --dispatch <id>` — report task outcome',
343
343
  '- `team report --stdin --dispatch <id>` — same, body from stdin (pipe content in via your shell — POSIX heredoc, Windows cmd `type file |`, PowerShell `Get-Content -Raw -Encoding utf8 file |`, or portable stdin redirection `< file`)',
344
- '- `team status "<state>"` — update orchestrator when no dispatch is active',
344
+ '- `team status "<state>"` — send startup readiness, progress, or standby; never closes a dispatch',
345
345
  '',
346
346
  '## `team` CLI — sentinel',
347
347
  '',
@@ -1,4 +1,4 @@
1
- import { isMemoryKind, MEMORY_BODY_MAX_CHARS, MEMORY_KINDS, MEMORY_QUERY_MAX_CHARS, MEMORY_SEARCH_MAX_LIMIT, MEMORY_TAG_MAX_CHARS, MEMORY_TAG_MAX_COUNT, } from '../shared/team-memory.js';
1
+ import { isMemoryKind, isMemoryProcedureRefType, isMemoryScope, MEMORY_BODY_MAX_CHARS, MEMORY_KINDS, MEMORY_PROCEDURE_REF_ID_MAX_CHARS, MEMORY_PROCEDURE_REF_TITLE_MAX_CHARS, MEMORY_PROCEDURE_REF_TYPES, MEMORY_QUERY_MAX_CHARS, MEMORY_SCOPES, MEMORY_SEARCH_MAX_LIMIT, MEMORY_TAG_MAX_CHARS, MEMORY_TAG_MAX_COUNT, } from '../shared/team-memory.js';
2
2
  import { BadRequestError } from './http-errors.js';
3
3
  import { readJsonBody, route, sendJson } from './route-helpers.js';
4
4
  import { authenticateCliAgent, requireCommandForRole } from './team-authz.js';
@@ -42,6 +42,49 @@ const parseKind = (value) => {
42
42
  }
43
43
  return value;
44
44
  };
45
+ const parseScope = (value) => {
46
+ if (value === undefined)
47
+ return 'workspace';
48
+ if (!isMemoryScope(value)) {
49
+ throw new BadRequestError(`scope must be one of: ${MEMORY_SCOPES.join(', ')}`);
50
+ }
51
+ return value;
52
+ };
53
+ const parseSearchScopes = (value) => {
54
+ if (value === undefined)
55
+ return ['workspace'];
56
+ if (value === 'all')
57
+ return ['workspace', 'user'];
58
+ if (isMemoryScope(value))
59
+ return [value];
60
+ throw new BadRequestError(`scope must be workspace, user, or all`);
61
+ };
62
+ const parseProcedureRef = (value) => {
63
+ if (value === undefined || value === null)
64
+ return null;
65
+ if (typeof value !== 'object' || Array.isArray(value)) {
66
+ throw new BadRequestError('procedure_ref must be an object');
67
+ }
68
+ const record = value;
69
+ if (!isMemoryProcedureRefType(record.type)) {
70
+ throw new BadRequestError(`procedure_ref.type must be one of: ${MEMORY_PROCEDURE_REF_TYPES.join(', ')}`);
71
+ }
72
+ if (typeof record.id !== 'string' || !record.id.trim()) {
73
+ throw new BadRequestError('procedure_ref.id must be a non-empty string');
74
+ }
75
+ const id = record.id.trim();
76
+ if ([...id].length > MEMORY_PROCEDURE_REF_ID_MAX_CHARS) {
77
+ throw new BadRequestError(`procedure_ref.id must be ${MEMORY_PROCEDURE_REF_ID_MAX_CHARS} characters or fewer`);
78
+ }
79
+ if (record.title !== undefined && record.title !== null && typeof record.title !== 'string') {
80
+ throw new BadRequestError('procedure_ref.title must be a string');
81
+ }
82
+ const title = typeof record.title === 'string' ? record.title.trim() || null : null;
83
+ if (title !== null && [...title].length > MEMORY_PROCEDURE_REF_TITLE_MAX_CHARS) {
84
+ throw new BadRequestError(`procedure_ref.title must be ${MEMORY_PROCEDURE_REF_TITLE_MAX_CHARS} characters or fewer`);
85
+ }
86
+ return { id, title, type: record.type };
87
+ };
45
88
  const parseTags = (value) => {
46
89
  if (value === undefined)
47
90
  return [];
@@ -83,6 +126,11 @@ export const teamMemoryRoutes = [
83
126
  const body = await readJsonBody(request);
84
127
  const { agent, workspaceId } = authenticateMemoryRequest(body, store);
85
128
  requireCommandForRole(agent, 'memory_add');
129
+ const kind = parseKind(body.kind);
130
+ const procedureRef = parseProcedureRef(body.procedure_ref);
131
+ if (kind === 'procedure_ref' && procedureRef === null) {
132
+ throw new BadRequestError('procedure_ref is required when kind is procedure_ref');
133
+ }
86
134
  const memory = store.addMemoryEntry({
87
135
  actor: {
88
136
  id: agent.id,
@@ -90,7 +138,9 @@ export const teamMemoryRoutes = [
90
138
  role: agent.role,
91
139
  },
92
140
  body: requireMemoryBody(body.body),
93
- kind: parseKind(body.kind),
141
+ kind,
142
+ procedureRef,
143
+ scope: parseScope(body.scope),
94
144
  tags: parseTags(body.tags),
95
145
  workspaceId,
96
146
  });
@@ -121,6 +171,7 @@ export const teamMemoryRoutes = [
121
171
  const limit = parseLimit(body.limit);
122
172
  const results = store.searchMemoryEntries(workspaceId, requireMemoryQuery(body.query), {
123
173
  ...(limit !== undefined ? { limit } : {}),
174
+ scopes: parseSearchScopes(body.scope),
124
175
  });
125
176
  sendJson(response, 200, {
126
177
  ok: true,
@@ -1,4 +1,4 @@
1
- import { MEMORY_QUERY_MAX_CHARS, MEMORY_SEARCH_MAX_LIMIT } from '../shared/team-memory.js';
1
+ import { isMemoryScope, MEMORY_QUERY_MAX_CHARS, MEMORY_SEARCH_MAX_LIMIT, } from '../shared/team-memory.js';
2
2
  import { BadRequestError } from './http-errors.js';
3
3
  import { getRequiredParam, readJsonBody, route, sendJson } from './route-helpers.js';
4
4
  import { readWorkspaceMemoryDreamEnabled, readWorkspaceMemoryEnabled, serializeWorkspaceMemoryDreamEnabled, serializeWorkspaceMemoryEnabled, workspaceMemoryDreamEnabledKey, workspaceMemoryEnabledKey, } from './team-memory-feature.js';
@@ -30,6 +30,15 @@ const parseQuery = (value) => {
30
30
  }
31
31
  return query;
32
32
  };
33
+ const parseScopes = (value) => {
34
+ if (value === null)
35
+ return ['workspace'];
36
+ if (value === 'all')
37
+ return ['workspace', 'user'];
38
+ if (isMemoryScope(value))
39
+ return [value];
40
+ throw new BadRequestError('scope must be workspace, user, or all');
41
+ };
33
42
  const requireBoolean = (value, field) => {
34
43
  if (typeof value !== 'boolean')
35
44
  throw new BadRequestError(`${field} must be a boolean`);
@@ -69,13 +78,15 @@ export const workspaceMemoryRoutes = [
69
78
  const statuses = parseStatuses(url.searchParams.get('status'));
70
79
  const limit = parseLimit(url.searchParams.get('limit'));
71
80
  const query = parseQuery(url.searchParams.get('query'));
81
+ const scopes = parseScopes(url.searchParams.get('scope'));
72
82
  const memories = query
73
83
  ? store.searchMemoryEntries(workspaceId, query, {
74
84
  includeDisabled: true,
75
85
  limit,
86
+ scopes,
76
87
  statuses,
77
88
  })
78
- : store.listMemoryEntries(workspaceId, { limit, statuses });
89
+ : store.listMemoryEntries(workspaceId, { limit, scopes, statuses });
79
90
  sendJson(response, 200, { memories: memories.map(serializeMemoryEntry), ok: true });
80
91
  }),
81
92
  route('GET', '/api/ui/workspaces/:workspaceId/memory/injections', ({ params, request, response, store }) => {
@@ -109,6 +120,24 @@ export const workspaceMemoryRoutes = [
109
120
  ok: true,
110
121
  });
111
122
  }),
123
+ route('GET', '/api/ui/workspaces/:workspaceId/memory/diagnostics', ({ params, request, response, store }) => {
124
+ requireUiTokenFromRequest(request, store.validateUiToken, store.authorizeRemoteTunnelRequest);
125
+ const workspaceId = getRequiredParam(response, params, 'workspaceId', 'Missing workspaceId');
126
+ if (!workspaceId)
127
+ return;
128
+ if (!requireWorkspace(response, store, workspaceId))
129
+ return;
130
+ const url = new URL(request.url ?? '/', 'http://127.0.0.1');
131
+ sendJson(response, 200, {
132
+ diagnostics: store.getMemoryDiagnostics({
133
+ query: parseQuery(url.searchParams.get('query')) || null,
134
+ taskText: parseQuery(url.searchParams.get('task_text')) || null,
135
+ workerDescription: parseQuery(url.searchParams.get('worker_description')) || null,
136
+ workspaceId,
137
+ }),
138
+ ok: true,
139
+ });
140
+ }),
112
141
  route('PUT', '/api/ui/workspaces/:workspaceId/memory/settings', async ({ params, request, response, store }) => {
113
142
  requireUiTokenFromRequest(request, store.validateUiToken, store.authorizeRemoteTunnelRequest);
114
143
  const workspaceId = getRequiredParam(response, params, 'workspaceId', 'Missing workspaceId');
@@ -13,6 +13,7 @@ import type { RemotePairing } from './remote-pairing.js';
13
13
  import type { RemoteTunnel, TunnelStatus } from './remote-tunnel.js';
14
14
  import type { MemoryDreamInput } from './runtime-store-dream.js';
15
15
  import type { SettingsStore } from './settings-store.js';
16
+ import type { BuildMemoryDiagnosticsInput, MemoryDiagnostics } from './team-memory-diagnostics.js';
16
17
  import type { DreamRunRecord } from './team-memory-dream-store.js';
17
18
  import type { AddMemoryEntryInput, LogMemoryInjectionsInput, MemoryEntryWithSources, MemoryInjectionWithMemory, MemoryListOptions, MemorySearchOptions, MemorySearchResult } from './team-memory-store.js';
18
19
  import type { CancelTaskInput, DispatchTaskInput, ReportTaskInput, ReportTaskResult, StatusTaskInput } from './team-operations.js';
@@ -80,6 +81,7 @@ export interface RuntimeStore {
80
81
  approveMemoryCandidate: (workspaceId: string, memoryId: string) => MemoryEntryWithSources;
81
82
  archiveMemoryEntry: (workspaceId: string, memoryId: string) => MemoryEntryWithSources;
82
83
  getMemoryEntry: (workspaceId: string, memoryId: string) => MemoryEntryWithSources | undefined;
84
+ getMemoryDiagnostics: (input: BuildMemoryDiagnosticsInput) => MemoryDiagnostics;
83
85
  listMemoryEntries: (workspaceId: string, options?: MemoryListOptions) => MemoryEntryWithSources[];
84
86
  listMemoryInjectionsForDispatch: (workspaceId: string, dispatchId: string) => MemoryInjectionWithMemory[];
85
87
  logMemoryInjections: (input: LogMemoryInjectionsInput) => string[];
@@ -1,9 +1,7 @@
1
+ import { type MemoryDreamInput } from './team-memory-dream-input.js';
1
2
  import { type DreamMessageInput, type DreamRunRecord } from './team-memory-dream-store.js';
2
3
  import type { MemoryEntryWithSources } from './team-memory-store.js';
3
- export interface MemoryDreamInput {
4
- prompt: string;
5
- run: DreamRunRecord;
6
- }
4
+ export type { MemoryDreamInput } from './team-memory-dream-input.js';
7
5
  interface RuntimeStoreDreamServices {
8
6
  teamMemoryDreamRunner: {
9
7
  runManual: (workspaceId: string) => Promise<DreamRunRecord>;
@@ -33,4 +31,3 @@ export declare const createRuntimeStoreDreamMethods: (services: RuntimeStoreDrea
33
31
  runMemoryDream(workspaceId: string): Promise<DreamRunRecord>;
34
32
  tickMemoryDreamScheduler(now?: number): Promise<void>;
35
33
  };
36
- export {};
@@ -1,4 +1,4 @@
1
- import { buildDreamPrompt, DREAM_PROMPT_MEMORY_LIMIT, DREAM_PROMPT_MESSAGE_LIMIT, } from './team-memory-dream-prompt.js';
1
+ import { buildMemoryDreamInput } from './team-memory-dream-input.js';
2
2
  import { DREAM_STALE_ERROR, DreamRunNotFoundError, DreamRunValidationError, } from './team-memory-dream-store.js';
3
3
  const shouldExportStaleRun = (run) => run.status === 'failed' && run.error === DREAM_STALE_ERROR;
4
4
  export const createRuntimeStoreDreamMethods = (services) => ({
@@ -31,17 +31,7 @@ export const createRuntimeStoreDreamMethods = (services) => ({
31
31
  services.teamMemoryExport.schedule(workspaceId);
32
32
  throw new DreamRunValidationError('Dream run is no longer running');
33
33
  }
34
- const messages = services.teamMemoryDreamStore
35
- .listInputMessages(workspaceId, run.inputSeqFrom, run.inputSeqTo)
36
- .slice(-DREAM_PROMPT_MESSAGE_LIMIT);
37
- const memories = services.teamMemoryStore
38
- .listAllEntries(workspaceId)
39
- .filter((memory) => memory.status === 'active' && memory.updatedAt <= run.startedAt)
40
- .slice(0, DREAM_PROMPT_MEMORY_LIMIT);
41
- return {
42
- prompt: buildDreamPrompt({ memories, messages, workspaceId }),
43
- run,
44
- };
34
+ return buildMemoryDreamInput(services, workspaceId, run);
45
35
  },
46
36
  listMemoryDreamRuns(workspaceId, limit) {
47
37
  const runs = services.teamMemoryDreamStore.listRuns(workspaceId, limit);
@@ -15,10 +15,12 @@ import { createSentinelHeartbeatService } from './sentinel-heartbeat.js';
15
15
  import { createSettingsStore } from './settings-store.js';
16
16
  import { createTasksFileService } from './tasks-file.js';
17
17
  import { createTasksFileWatcher } from './tasks-file-watcher.js';
18
+ import { createTeamMemoryDiagnostics } from './team-memory-diagnostics.js';
18
19
  import { createTeamMemoryDreamRunner } from './team-memory-dream-runner.js';
19
20
  import { createTeamMemoryDreamScheduler } from './team-memory-dream-scheduler.js';
20
21
  import { createTeamMemoryDreamStore } from './team-memory-dream-store.js';
21
22
  import { createTeamMemoryExportService } from './team-memory-export.js';
23
+ import { createLocalTeamMemoryProvider } from './team-memory-provider.js';
22
24
  import { createTeamMemoryStore } from './team-memory-store.js';
23
25
  import { createTeamOperations } from './team-operations.js';
24
26
  import { createTeamRecallStore } from './team-recall-store.js';
@@ -52,8 +54,10 @@ export interface RuntimeStoreServices {
52
54
  sentinelHeartbeat: ReturnType<typeof createSentinelHeartbeatService>;
53
55
  protocolEventStats: ReturnType<typeof createProtocolEventStats>;
54
56
  teamMemoryDreamStore: ReturnType<typeof createTeamMemoryDreamStore>;
57
+ teamMemoryDiagnostics: ReturnType<typeof createTeamMemoryDiagnostics>;
55
58
  teamMemoryStore: ReturnType<typeof createTeamMemoryStore>;
56
59
  teamMemoryExport: ReturnType<typeof createTeamMemoryExportService>;
60
+ teamMemoryProvider: ReturnType<typeof createLocalTeamMemoryProvider>;
57
61
  teamRecallStore: ReturnType<typeof createTeamRecallStore>;
58
62
  teamOps: ReturnType<typeof createTeamOperations>;
59
63
  uiAuth: ReturnType<typeof createUiAuth>;
@@ -21,11 +21,15 @@ import { createSentinelHeartbeatService } from './sentinel-heartbeat.js';
21
21
  import { createSettingsStore } from './settings-store.js';
22
22
  import { createTasksFileService } from './tasks-file.js';
23
23
  import { createTasksFileWatcher } from './tasks-file-watcher.js';
24
+ import { createTeamMemoryDiagnostics } from './team-memory-diagnostics.js';
24
25
  import { createWorkspaceMemoryDigestProvider } from './team-memory-digest.js';
26
+ import { createDreamCliExecutor } from './team-memory-dream-cli.js';
27
+ import { buildMemoryDreamInput } from './team-memory-dream-input.js';
25
28
  import { createTeamMemoryDreamRunner } from './team-memory-dream-runner.js';
26
29
  import { createTeamMemoryDreamScheduler } from './team-memory-dream-scheduler.js';
27
30
  import { createTeamMemoryDreamStore } from './team-memory-dream-store.js';
28
31
  import { createTeamMemoryExportService, MEMORY_EXPORT_DREAM_CHANGELOG_LIMIT, } from './team-memory-export.js';
32
+ import { createLocalTeamMemoryProvider } from './team-memory-provider.js';
29
33
  import { createTeamMemoryStore } from './team-memory-store.js';
30
34
  import { createTeamOperations } from './team-operations.js';
31
35
  import { createTeamRecallStore } from './team-recall-store.js';
@@ -87,8 +91,15 @@ export const createRuntimeStoreServices = (options = {}) => {
87
91
  const agentSessionStore = createAgentSessionStore(db);
88
92
  const settings = createSettingsStore(db);
89
93
  const getFlags = () => readFeatureFlags(settings);
90
- const memoryDigestProvider = createWorkspaceMemoryDigestProvider({
94
+ const teamMemoryProvider = createLocalTeamMemoryProvider({ memoryStore: teamMemoryStore });
95
+ const teamMemoryDreamCli = createDreamCliExecutor();
96
+ const teamMemoryDiagnostics = createTeamMemoryDiagnostics({
97
+ dreamStore: teamMemoryDreamStore,
98
+ memoryProvider: teamMemoryProvider,
91
99
  memoryStore: teamMemoryStore,
100
+ });
101
+ const memoryDigestProvider = createWorkspaceMemoryDigestProvider({
102
+ memoryStore: teamMemoryProvider,
92
103
  settings,
93
104
  });
94
105
  const memoryInjection = {
@@ -194,10 +205,16 @@ export const createRuntimeStoreServices = (options = {}) => {
194
205
  }
195
206
  }, restartPolicy, (workspaceId, agentId) => workspaceStore.getAgent(workspaceId, agentId), getFlags, memoryInjection);
196
207
  const teamMemoryDreamRunner = createTeamMemoryDreamRunner({
208
+ applyScheduledRun: teamMemoryDreamStore.applyAndCompleteRun,
209
+ buildScheduledInput: (workspaceId, run) => buildMemoryDreamInput({ teamMemoryDreamStore, teamMemoryStore }, workspaceId, run),
197
210
  dreamStore: teamMemoryDreamStore,
198
211
  deliverToOrchestrator: (workspaceId, text) => agentRuntime.deliverSystemMessageToAgent(workspaceId, getOrchestratorId(workspaceId), text, {
199
212
  requireActiveRun: true,
200
213
  }),
214
+ executeScheduledDream: ({ prompt, workspaceId }) => teamMemoryDreamCli.execute({
215
+ cwd: workspaceStore.getWorkspaceSnapshot(workspaceId).summary.path,
216
+ prompt,
217
+ }),
201
218
  scheduleExport: teamMemoryExport.schedule,
202
219
  });
203
220
  const teamMemoryDreamScheduler = createTeamMemoryDreamScheduler({
@@ -294,7 +311,9 @@ export const createRuntimeStoreServices = (options = {}) => {
294
311
  sentinelHeartbeat,
295
312
  protocolEventStats,
296
313
  teamMemoryDreamStore,
314
+ teamMemoryDiagnostics,
297
315
  teamMemoryExport,
316
+ teamMemoryProvider,
298
317
  teamMemoryStore,
299
318
  teamRecallStore,
300
319
  teamOps,
@@ -392,6 +411,7 @@ export const createRuntimeStoreLifecycle = ({ agentManager, services, }) => {
392
411
  // runner's `await agent(...)` rejects with a clear shutdown error
393
412
  // instead of hanging on a Promise that can never resolve.
394
413
  services.sentinelHeartbeat.close();
414
+ await services.teamMemoryDreamScheduler.close();
395
415
  services.workflowDispatchAwaiter.cancelAll('runtime closing');
396
416
  services.shellRuntime.close();
397
417
  await services.teamMemoryExport.close();