@adhdev/daemon-core 0.9.82-rc.209 → 0.9.82-rc.210

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 (64) hide show
  1. package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +2 -0
  2. package/dist/commands/router.d.ts +6 -0
  3. package/dist/git/git-commands.d.ts +2 -0
  4. package/dist/git/git-diff.d.ts +6 -0
  5. package/dist/index.d.ts +11 -5
  6. package/dist/index.js +5699 -3486
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +5679 -3483
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/mesh/coordinator-prompt.d.ts +6 -0
  11. package/dist/mesh/mesh-delivery-policy.d.ts +5 -0
  12. package/dist/mesh/mesh-events-coordinator.d.ts +151 -0
  13. package/dist/mesh/mesh-events-pending.d.ts +33 -0
  14. package/dist/mesh/mesh-events-stale.d.ts +40 -0
  15. package/dist/mesh/mesh-events-utils.d.ts +14 -0
  16. package/dist/mesh/mesh-events.d.ts +5 -198
  17. package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -3
  18. package/dist/mesh/mesh-ledger.d.ts +19 -0
  19. package/dist/mesh/mesh-missions.d.ts +58 -0
  20. package/dist/mesh/mesh-review-inbox.d.ts +90 -0
  21. package/dist/mesh/mesh-runtime-store.d.ts +175 -0
  22. package/dist/mesh/mesh-task-stats.d.ts +49 -0
  23. package/dist/mesh/mesh-work-queue.d.ts +82 -0
  24. package/dist/mesh/refine-config.d.ts +24 -2
  25. package/dist/mesh/worktree-bootstrap-config.d.ts +22 -0
  26. package/dist/providers/acp-provider-instance.d.ts +2 -0
  27. package/dist/providers/spec/driver.d.ts +8 -0
  28. package/dist/providers/spec/evaluator.d.ts +4 -5
  29. package/dist/providers/spec/loader.d.ts +1 -0
  30. package/dist/providers/spec/schema.gen.d.ts +1409 -6
  31. package/dist/providers/spec/types.d.ts +188 -175
  32. package/dist/repo-mesh-types.d.ts +1 -0
  33. package/package.json +1 -1
  34. package/src/boot/daemon-lifecycle.ts +3 -0
  35. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +20 -7
  36. package/src/commands/router.ts +594 -66
  37. package/src/git/git-commands.ts +5 -5
  38. package/src/git/git-diff.ts +53 -0
  39. package/src/index.ts +11 -5
  40. package/src/mesh/coordinator-prompt.ts +14 -1
  41. package/src/mesh/mesh-delivery-policy.ts +17 -0
  42. package/src/mesh/mesh-events-coordinator.ts +1404 -0
  43. package/src/mesh/mesh-events-pending.ts +371 -0
  44. package/src/mesh/mesh-events-stale.ts +283 -0
  45. package/src/mesh/mesh-events-utils.ts +161 -0
  46. package/src/mesh/mesh-events.ts +27 -2143
  47. package/src/mesh/mesh-ledger-reconciliation.ts +12 -5
  48. package/src/mesh/mesh-ledger.ts +134 -2
  49. package/src/mesh/mesh-missions.ts +151 -0
  50. package/src/mesh/mesh-review-inbox.ts +307 -0
  51. package/src/mesh/mesh-runtime-store.ts +539 -3
  52. package/src/mesh/mesh-task-stats.ts +154 -0
  53. package/src/mesh/mesh-work-queue.ts +233 -17
  54. package/src/mesh/refine-config.ts +42 -5
  55. package/src/mesh/worktree-bootstrap-config.ts +79 -0
  56. package/src/providers/acp-provider-instance.ts +15 -1
  57. package/src/providers/cli-provider-instance.ts +34 -13
  58. package/src/providers/spec/driver.ts +57 -29
  59. package/src/providers/spec/evaluator.ts +302 -112
  60. package/src/providers/spec/loader.ts +226 -37
  61. package/src/providers/spec/schema.gen.ts +450 -334
  62. package/src/providers/spec/schema.json +162 -75
  63. package/src/providers/spec/types.ts +234 -183
  64. package/src/repo-mesh-types.ts +1 -0
@@ -67,8 +67,8 @@ export interface GitPushResult extends GitRepoIdentity {
67
67
 
68
68
  export interface GitCommandServices {
69
69
  getStatus?: (params: { workspace: string; refreshUpstream?: boolean; includeSubmodules?: boolean; submoduleIgnorePaths?: string[] }) => Promise<GitRepoStatus> | GitRepoStatus;
70
- getDiffSummary?: (params: { workspace: string; staged?: boolean }) => Promise<GitDiffSummary> | GitDiffSummary;
71
- getDiffFile?: (params: { workspace: string; path: string; staged?: boolean }) => Promise<GitFileDiff> | GitFileDiff;
70
+ getDiffSummary?: (params: { workspace: string; staged?: boolean; base?: string }) => Promise<GitDiffSummary> | GitDiffSummary;
71
+ getDiffFile?: (params: { workspace: string; path: string; staged?: boolean; base?: string }) => Promise<GitFileDiff> | GitFileDiff;
72
72
  createSnapshot?: (params: {
73
73
  workspace: string;
74
74
  reason: GitSnapshotReason;
@@ -176,8 +176,8 @@ const defaultSnapshotStore = createGitSnapshotStore({
176
176
  export function createDefaultGitCommandServices(): GitCommandServices {
177
177
  return {
178
178
  getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
179
- getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
180
- getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
179
+ getDiffSummary: ({ workspace, base }) => getGitDiffSummary(workspace, base ? { baseRef: base } : {}),
180
+ getDiffFile: ({ workspace, path: filePath, base }) => getGitFileDiff(workspace, filePath, base ? { baseRef: base } : {}),
181
181
  createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
182
182
  workspace,
183
183
  reason,
@@ -309,7 +309,7 @@ export async function handleGitCommand(
309
309
 
310
310
  case 'git_diff_summary': {
311
311
  if (!services.getDiffSummary) return serviceNotImplemented(command);
312
- const diffSummary = await runService(() => services.getDiffSummary!({ workspace, staged: optionalBoolean(args?.staged) }));
312
+ const diffSummary = await runService(() => services.getDiffSummary!({ workspace, staged: optionalBoolean(args?.staged), base: optionalString(args?.base) }));
313
313
  return 'success' in diffSummary ? diffSummary : { success: true, diffSummary };
314
314
  }
315
315
 
@@ -10,6 +10,20 @@ export interface GitDiffOptions {
10
10
  timeoutMs?: number;
11
11
  maxFiles?: number;
12
12
  maxBytes?: number;
13
+ /**
14
+ * When set, diff `<baseRef>...HEAD` (merge-base range — "what this branch
15
+ * adds on top of base") instead of the working tree. Staged/untracked
16
+ * sections do not apply in this mode.
17
+ */
18
+ baseRef?: string;
19
+ }
20
+
21
+ function validateBaseRef(ref: string): string {
22
+ const trimmed = ref.trim();
23
+ if (!trimmed || trimmed.startsWith('-') || trimmed.includes('..') || !/^[A-Za-z0-9][A-Za-z0-9._/@-]*$/.test(trimmed)) {
24
+ throw new GitCommandError('invalid_args', `Invalid base ref: ${ref}`);
25
+ }
26
+ return trimmed;
13
27
  }
14
28
 
15
29
  export interface GitFileDiffResult {
@@ -44,6 +58,30 @@ export async function getGitDiffSummary(
44
58
  try {
45
59
  const repo = await resolveGitRepository(workspace, options);
46
60
  const repoRoot = repo.repoRoot!;
61
+
62
+ if (options.baseRef) {
63
+ const range = `${validateBaseRef(options.baseRef)}...HEAD`;
64
+ const [nameStatus, numstat] = await Promise.all([
65
+ runGit(repo, ['diff', '--no-ext-diff', '--name-status', range, '--'], { ...options, cwd: repoRoot }),
66
+ runGit(repo, ['diff', '--no-ext-diff', '--numstat', range, '--'], { ...options, cwd: repoRoot }),
67
+ ]);
68
+ const outputBytes = byteLength(nameStatus.stdout + numstat.stdout);
69
+ const changes = combineDiffEntries(nameStatus.stdout, numstat.stdout, false);
70
+ const maxFiles = normalizePositiveInteger(options.maxFiles, DEFAULT_MAX_FILES);
71
+ const maxBytes = normalizePositiveInteger(options.maxBytes, DEFAULT_MAX_BYTES);
72
+ const files = changes.slice(0, maxFiles);
73
+ return {
74
+ workspace: repo.workspace,
75
+ repoRoot,
76
+ isGitRepo: true,
77
+ files,
78
+ totalInsertions: files.reduce((sum, file) => sum + file.insertions, 0),
79
+ totalDeletions: files.reduce((sum, file) => sum + file.deletions, 0),
80
+ truncated: changes.length > files.length || outputBytes > maxBytes,
81
+ lastCheckedAt,
82
+ };
83
+ }
84
+
47
85
  const [unstagedNameStatus, unstagedNumstat, stagedNameStatus, stagedNumstat, untracked] = await Promise.all([
48
86
  runGit(repo, ['diff', '--no-ext-diff', '--name-status'], { ...options, cwd: repoRoot }),
49
87
  runGit(repo, ['diff', '--no-ext-diff', '--numstat'], { ...options, cwd: repoRoot }),
@@ -106,6 +144,21 @@ export async function getGitFileDiff(
106
144
  const selected = await resolveRepoFilePath(repoRoot, filePath);
107
145
  const maxBytes = normalizePositiveInteger(options.maxBytes, DEFAULT_MAX_BYTES);
108
146
 
147
+ if (options.baseRef) {
148
+ const range = `${validateBaseRef(options.baseRef)}...HEAD`;
149
+ const result = await runGit(repo, ['diff', '--no-ext-diff', range, '--', selected.relativePath], { ...options, cwd: repoRoot });
150
+ const bounded = truncateText(result.stdout, maxBytes);
151
+ return {
152
+ workspace: repo.workspace,
153
+ repoRoot,
154
+ isGitRepo: true,
155
+ path: selected.relativePath,
156
+ diff: bounded.text,
157
+ truncated: bounded.truncated,
158
+ lastCheckedAt,
159
+ };
160
+ }
161
+
109
162
  const [unstaged, staged] = await Promise.all([
110
163
  runGit(repo, ['diff', '--no-ext-diff', '--', selected.relativePath], { ...options, cwd: repoRoot }),
111
164
  runGit(repo, ['diff', '--cached', '--no-ext-diff', '--', selected.relativePath], { ...options, cwd: repoRoot }),
package/src/index.ts CHANGED
@@ -174,6 +174,12 @@ export type { CreateMeshOptions, UpdateMeshOptions, AddNodeOptions } from './con
174
174
 
175
175
  // ── Mesh Coordinator ──
176
176
  export { buildCoordinatorSystemPrompt } from './mesh/coordinator-prompt.js';
177
+ export { upsertMeshMission, getMeshMissions, getMeshMission, summarizeMissionTasks, summarizeMeshMission, getActiveMeshMissionSummaries, buildMissionPromptSection, MESH_MISSION_STATUSES } from './mesh/mesh-missions.js';
178
+ export type { MeshMissionRecord, MeshMissionStatus, MeshMissionSummary, MeshMissionTaskAggregate } from './mesh/mesh-missions.js';
179
+ export { computeMeshTaskStats, computeMeshMissionStats } from './mesh/mesh-task-stats.js';
180
+ export type { MeshTaskStats, MeshMissionStats } from './mesh/mesh-task-stats.js';
181
+ export { deriveMeshReviewInboxItems } from './mesh/mesh-review-inbox.js';
182
+ export type { MeshReviewInboxItem, MeshReviewInboxDerivation, MeshReviewInboxEvidence, MeshReviewInboxDiffSummary, MeshReviewInboxDiffFile, MeshReviewInboxReason, MeshReviewInboxConvergence } from './mesh/mesh-review-inbox.js';
177
183
  export type { CoordinatorPromptContext } from './mesh/coordinator-prompt.js';
178
184
  export { loadMeshCoordinatorRegistry, registerMeshCoordinator, unregisterMeshCoordinator, getCoordinatorForSession, listCoordinatorsForWorkspace } from './mesh/coordinator-registry.js';
179
185
  export type { CoordinatorRegistryEntry } from './mesh/coordinator-registry.js';
@@ -203,16 +209,16 @@ export type {
203
209
  } from './mesh/refine-config.js';
204
210
 
205
211
  // ── Mesh Task Ledger ──
206
- export { appendLedgerEntry, appendRemoteLedgerEntries, buildTaskCompletionEvidence, normalizeMeshWorkerResult, readLedgerEntries, readLedgerSlice, getLedgerSummary, getLedgerDir, getSessionRecoveryContext, MAX_LEDGER_SLICE_LIMIT } from './mesh/mesh-ledger.js';
212
+ export { appendLedgerEntry, appendRemoteLedgerEntries, buildTaskCompletionEvidence, normalizeMeshWorkerResult, readLedgerEntries, readLedgerSlice, readLedgerSliceFromStore, getLedgerSummary, getLedgerDir, getSessionRecoveryContext, MAX_LEDGER_SLICE_LIMIT } from './mesh/mesh-ledger.js';
207
213
  export type { AppendRemoteLedgerResult, MeshLedgerEntry, MeshLedgerKind, MeshLedgerSlice, MeshLedgerSummary, ReadLedgerOptions, ReadLedgerSliceOptions, SessionRecoveryContext, MeshTaskCompletionEvidence, MeshWorkerResultArtifact, MeshProcessArtifact, MeshValidationResultArtifact } from './mesh/mesh-ledger.js';
208
214
  export { fastForwardMeshNode } from './mesh/mesh-fast-forward.js';
209
215
  export type { MeshFastForwardNodeArgs, MeshFastForwardPlannedStep, MeshFastForwardResult } from './mesh/mesh-fast-forward.js';
210
216
  export { buildMeshLedgerReconciliationEvidence, buildMeshLedgerReplicaEvidence } from './mesh/mesh-ledger-reconciliation.js';
211
- export type { MeshLedgerReconciliationEvidence, MeshLedgerReplicaEvidence, MeshLedgerReplicaStatus } from './mesh/mesh-ledger-reconciliation.js';
217
+ export type { AnyLedgerSlice, MeshLedgerReconciliationEvidence, MeshLedgerReplicaEvidence, MeshLedgerReplicaStatus } from './mesh/mesh-ledger-reconciliation.js';
212
218
 
213
219
  // ── Mesh Work Queue (GUPP) ──
214
- export { enqueueTask, getQueue, claimNextTask, updateTaskStatus, updateSessionTaskStatus, cancelTask, requeueTask, getMeshQueueStats, getMeshQueueRevision, normalizeMeshTaskMode, validateMeshTaskModeRequest, buildMeshNodeCapabilityTags, nodeSatisfiesRequiredTags, normalizeMeshCapabilityTags, insertDirectDispatch, getActiveDirectDispatches, updateDirectDispatchStatus, cleanupTerminalDirectDispatches, markStaleDirectDispatches } from './mesh/mesh-work-queue.js';
215
- export type { MeshWorkQueueEntry, MeshTaskStatus, MeshTaskMode, MeshWorkQueueStats, MeshQueueMutationOptions, MeshTaskModeValidationResult, DirectDispatchRecord } from './mesh/mesh-work-queue.js';
220
+ export { enqueueTask, getQueue, claimNextTask, updateTaskStatus, updateSessionTaskStatus, cancelTask, requeueTask, getMeshQueueStats, getMeshQueueRevision, normalizeMeshTaskMode, validateMeshTaskModeRequest, buildMeshNodeCapabilityTags, nodeSatisfiesRequiredTags, normalizeMeshCapabilityTags, insertDirectDispatch, getActiveDirectDispatches, updateDirectDispatchStatus, cleanupTerminalDirectDispatches, markStaleDirectDispatches, recordMeshToolCall, assertNoDependencyCycle, hasPendingDependents, describeTaskDependencyState } from './mesh/mesh-work-queue.js';
221
+ export type { MeshWorkQueueEntry, MeshTaskStatus, MeshTaskMode, MeshWorkQueueStats, MeshQueueMutationOptions, MeshTaskModeValidationResult, DirectDispatchRecord, MeshToolCallRateResult } from './mesh/mesh-work-queue.js';
216
222
  export { buildCompactStaleDirectWorkSummary, buildMeshActiveWork, buildMeshActiveWorkSummary } from './mesh/mesh-active-work.js';
217
223
  export type { MeshActiveWorkRecord, MeshActiveWorkStatus, MeshActiveWorkSummary, MeshActiveWorkSource, MeshStaleDirectWorkSummary } from './mesh/mesh-active-work.js';
218
224
  export { buildMeshAsyncRefineJobs } from './mesh/mesh-refine-status.js';
@@ -233,7 +239,7 @@ export { triggerMeshQueue, drainPendingMeshCoordinatorEvents, getPendingMeshCoor
233
239
  export type { PendingMeshCoordinatorEvent } from './mesh/mesh-events.js';
234
240
 
235
241
  // ── Mesh Delivery Policy ──
236
- export { resolveDeliveryDecision, createSessionDelivery, updateSessionDeliveryStatus, getActiveSessionDeliveries, recordCompletionConflict, getRecentCompletionConflicts } from './mesh/mesh-delivery-policy.js';
242
+ export { resolveDeliveryDecision, createSessionDelivery, updateSessionDeliveryStatus, getActiveSessionDeliveries, markSessionDeliveriesTerminal, recordCompletionConflict, getRecentCompletionConflicts } from './mesh/mesh-delivery-policy.js';
237
243
  export type { MeshSessionDeliveryStatus, MeshSessionDeliveryKind, MeshDeliveryDecision, MeshDeliveryPolicyResult, SessionDeliveryRecord } from './mesh/mesh-delivery-policy.js';
238
244
 
239
245
  // ── Mesh P2P Relay Failure Classification ──
@@ -40,6 +40,12 @@ export interface CoordinatorPromptContext {
40
40
  status?: RepoMeshStatus;
41
41
  userInstruction?: string;
42
42
  coordinatorCliType?: string;
43
+ /**
44
+ * M3: pre-rendered active mission section (from buildMissionPromptSection).
45
+ * Empty/undefined when the mesh has no active mission — the prompt output
46
+ * stays identical to the pre-M3 form in that case.
47
+ */
48
+ missionSection?: string;
43
49
  }
44
50
 
45
51
  /**
@@ -121,6 +127,11 @@ Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `\nDefault branch: \`
121
127
  sections.push('## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.');
122
128
  }
123
129
 
130
+ // ── Active Mission (M3) — only present when one exists ──
131
+ if (ctx.missionSection?.trim()) {
132
+ sections.push(ctx.missionSection.trim());
133
+ }
134
+
124
135
  // ── Policy ──
125
136
  sections.push(buildPolicySection({ ...DEFAULT_MESH_POLICY, ...(mesh.policy || {}) }));
126
137
 
@@ -175,6 +186,7 @@ function readUserPromptFile(cliType: string | undefined, suffix: string): string
175
186
  * {{defaultBranch}} — mesh.defaultBranch or empty
176
187
  * {{cliType}} — coordinator CLI type or empty
177
188
  * {{nodes}} — full node section (status if known, otherwise config)
189
+ * {{mission}} — active mission summary section (empty when none)
178
190
  * {{policy}} — full policy section
179
191
  * {{tools}} — the canonical tools table
180
192
  * {{workflow}} — the canonical orchestration workflow
@@ -198,6 +210,7 @@ function expandPromptPlaceholders(template: string, ctx: CoordinatorPromptContex
198
210
  defaultBranch: mesh.defaultBranch || '',
199
211
  cliType: coordinatorCliType || '',
200
212
  nodes: nodesSection,
213
+ mission: ctx.missionSection?.trim() || '',
201
214
  policy: buildPolicySection({ ...DEFAULT_MESH_POLICY, ...(mesh.policy || {}) }),
202
215
  tools: TOOLS_SECTION,
203
216
  workflow: WORKFLOW_SECTION,
@@ -330,7 +343,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
330
343
  const WORKFLOW_SECTION = `## Orchestration Workflow
331
344
 
332
345
  1. **Assess** — Call \`mesh_status\` to see which nodes are healthy and available. Check \`mesh_task_history\` to understand what has already been done in this mesh — previous delegations, completions, and failures.
333
- 2. **Plan** — Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist. If \`mesh_task_history\` shows a recent failure for a task, decide whether to retry or reassign.
346
+ 2. **Plan** — Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist. If \`mesh_task_history\` shows a recent failure for a task, decide whether to retry or reassign. **For multi-task work, create a mission first**: call \`mesh_mission_upsert\` with a title and goal, then attach every enqueued task with \`mission_id\`. Express "B after A" ordering with \`depends_on\` on the queue task instead of waiting and polling — the system claims dependents automatically when their dependencies complete. When the mission's outcome is decided, update its status (\`completed\`/\`abandoned\`) via \`mesh_mission_upsert\`. If the prompt already shows an **Active Mission**, continue it from its current task state — do not re-enqueue tasks that already exist.
334
347
  3. **Queue / Delegate** — The Mesh uses an autonomous pull-based Work Queue:
335
348
  a. **General Tasks**: Enqueue tasks using \`mesh_enqueue_task\`. Idle node agents will automatically pull tasks from the queue and begin working.
336
349
  b. **Node Preparation**: Reuse an existing idle session on the correct node/provider before launching a new chat/session. Call \`mesh_launch_session\` only when no suitable session exists, when the user explicitly asks for a fresh provider/session, or when branch/worktree isolation requires it. If you need branch isolation for parallel work, call \`mesh_clone_node\` to create a worktree node first.
@@ -296,3 +296,20 @@ export function getRecentCompletionConflicts(meshId: string, limitMs?: number) {
296
296
  export function __clearSessionDeliveriesForTests(meshId: string): void {
297
297
  MeshRuntimeStore.getInstance().deleteSessionDeliveries(meshId);
298
298
  }
299
+
300
+ /**
301
+ * Mark all active (queued/delivering/delivered/acked) deliveries for a session as completed or failed.
302
+ * Called when a task's terminal status is confirmed so delivery records stay in sync.
303
+ */
304
+ export function markSessionDeliveriesTerminal(
305
+ meshId: string,
306
+ sessionId: string,
307
+ terminalStatus: 'completed' | 'failed',
308
+ ): void {
309
+ try {
310
+ const active = MeshRuntimeStore.getInstance().getActiveSessionDeliveries(meshId, sessionId);
311
+ for (const delivery of active) {
312
+ MeshRuntimeStore.getInstance().updateSessionDeliveryStatus(delivery.id, terminalStatus);
313
+ }
314
+ } catch { /* best-effort */ }
315
+ }