maka-agent 0.2.0-dev.25.20260908 → 0.2.0-dev.26.20260909

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 (65) hide show
  1. package/dist/mcp-capability-provider.js +4 -1
  2. package/dist/pi-tui-mcp-status.js +2 -2
  3. package/dist/pi-tui-pickers.js +19 -29
  4. package/dist/tui-autocomplete-layout.js +3 -1
  5. package/dist/tui-copy-catalog.js +6 -3
  6. package/dist/tui-editor-render.js +36 -0
  7. package/dist/tui-mcp-control.js +41 -6
  8. package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
  9. package/node_modules/@maka/core/dist/runtime-event.js +3 -0
  10. package/node_modules/@maka/core/dist/session.js +29 -4
  11. package/node_modules/@maka/core/dist/workhub-action-result.js +68 -0
  12. package/node_modules/@maka/core/package.json +2 -3
  13. package/node_modules/@maka/eval/dist/toolchain-verification.js +1 -1
  14. package/node_modules/@maka/mcp/dist/form-elicitation.js +213 -0
  15. package/node_modules/@maka/mcp/dist/index.js +337 -71
  16. package/node_modules/@maka/runtime/dist/agent-run.js +10 -1
  17. package/node_modules/@maka/runtime/dist/goal-continuation.js +5 -1
  18. package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +20 -1
  19. package/node_modules/@maka/runtime/dist/runtime-kernel.js +120 -13
  20. package/node_modules/@maka/runtime/dist/session-manager.js +20 -36
  21. package/node_modules/@maka/runtime-host/dist/client/connection.js +30 -5
  22. package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +17 -1
  23. package/node_modules/@maka/runtime-host/dist/client/host-retirement.js +4 -2
  24. package/node_modules/@maka/runtime-host/dist/client/peer-client.js +18 -1
  25. package/node_modules/@maka/runtime-host/dist/protocol/index.js +5 -1
  26. package/node_modules/@maka/runtime-host/dist/protocol/operations.js +3 -2
  27. package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +1 -0
  28. package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +68 -168
  29. package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +4 -0
  30. package/node_modules/@maka/runtime-host/dist/server/canonical-session-projection.js +2 -1
  31. package/node_modules/@maka/runtime-host/dist/server/connection-session.js +28 -8
  32. package/node_modules/@maka/runtime-host/dist/server/daily-review-coordinator.js +112 -56
  33. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +45 -20
  34. package/node_modules/@maka/runtime-host/dist/server/failure-diagnostic.js +24 -0
  35. package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +7 -3
  36. package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +3 -3
  37. package/node_modules/@maka/runtime-host/dist/server/host-session-availability.js +5 -2
  38. package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +3 -2
  39. package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +34 -4
  40. package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +4 -1
  41. package/node_modules/@maka/runtime-host/dist/server/operation-dispatcher.js +2 -7
  42. package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +110 -14
  43. package/node_modules/@maka/runtime-host/dist/server/runtime-resource-coordinator.js +11 -8
  44. package/node_modules/@maka/runtime-host/dist/server/scheduled-task-coordinator.js +31 -21
  45. package/node_modules/@maka/runtime-host/dist/server/serial-outbound-writer.js +1 -1
  46. package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +20 -8
  47. package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +15 -104
  48. package/node_modules/@maka/runtime-host/dist/server/shared-session-transcript.js +3 -0
  49. package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +44 -85
  50. package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +120 -137
  51. package/node_modules/@maka/storage/dist/agent-run-store.js +14 -1
  52. package/node_modules/@maka/storage/dist/artifact-store.js +40 -3
  53. package/node_modules/@maka/storage/dist/atomic-file-write.js +74 -0
  54. package/node_modules/@maka/storage/dist/credential-store.js +12 -63
  55. package/node_modules/@maka/storage/dist/execution-stores.js +4 -1
  56. package/node_modules/@maka/storage/dist/mcp-config-store.js +10 -25
  57. package/node_modules/@maka/storage/dist/session-store.js +14 -2
  58. package/node_modules/@maka/storage/dist/settings-store.js +8 -4
  59. package/node_modules/@maka/storage/dist/sqlite-artifact-metadata.js +11 -0
  60. package/node_modules/@maka/storage/dist/sqlite-session-metadata-schema.js +12 -1
  61. package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +67 -3
  62. package/node_modules/@maka/storage/dist/stable-storage.js +14 -1
  63. package/package.json +1 -1
  64. package/node_modules/@maka/core/dist/workhub-creation-intent.js +0 -990
  65. package/node_modules/@maka/core/dist/workhub-session-resolver.js +0 -50
@@ -18,7 +18,6 @@
18
18
  */
19
19
  import { createHash } from 'node:crypto';
20
20
  import { WORKHUB_COORDINATION_SESSION_ID, isWorkHubCoordinationSessionTarget, } from '@maka/core/session';
21
- import { readWorkHubRequestIntent, workHubCorrectionTargetsSession, workHubCreationAuthorizesTitle, workHubNamedDelegationActionTargetsSession, } from '@maka/core/workhub-creation-intent';
22
21
  import { WORKHUB_COORDINATION_CANDIDATE_MAX_ITEMS } from '../protocol/index.js';
23
22
  const SIDE_CONVERSATION_LABEL = 'mode:side_conversation';
24
23
  const ACTION_REPLAY_MAX_ITEMS = 256;
@@ -54,10 +53,17 @@ export class WorkHubCoordinationActionGate {
54
53
  async candidates() {
55
54
  return candidateSet(await this.#effects.listSessions());
56
55
  }
57
- act(input, context) {
56
+ act(input, context, admittedTurnId) {
58
57
  if (!input.userText.trim()) {
59
58
  return Promise.reject(new WorkHubActionGateFailure('action_conflict', 'WorkHub action text is empty'));
60
59
  }
60
+ if (input.delegationText !== undefined &&
61
+ (!input.delegationText.trim() ||
62
+ (input.proposal.disposition !== 'delegate_existing' &&
63
+ input.proposal.disposition !== 'create_new' &&
64
+ input.proposal.disposition !== 'replace'))) {
65
+ return Promise.reject(new WorkHubActionGateFailure('action_conflict', 'Invalid WorkHub delegation text'));
66
+ }
61
67
  if (input.proposal.disposition === 'create_new' && !input.proposal.title.trim()) {
62
68
  return Promise.reject(new WorkHubActionGateFailure('action_conflict', 'WorkHub creation title is empty'));
63
69
  }
@@ -70,7 +76,7 @@ export class WorkHubCoordinationActionGate {
70
76
  }
71
77
  return replay.result;
72
78
  }
73
- const result = this.#act(input, fingerprint, context);
79
+ const result = this.#act({ ...input, ...(admittedTurnId ? { coordinationTurnId: admittedTurnId } : {}) }, fingerprint, context);
74
80
  const action = { requestFingerprint, result };
75
81
  this.#actions.set(input.actionId, action);
76
82
  // Successful actions remain a Host-lifetime fast path. Rejections release
@@ -87,12 +93,6 @@ export class WorkHubCoordinationActionGate {
87
93
  }
88
94
  async #act(input, fingerprint, context) {
89
95
  const proposal = input.proposal;
90
- const requestIntent = readWorkHubRequestIntent(input.userText);
91
- if (requestIntent.execution === 'ambiguous' &&
92
- proposal.disposition !== 'answer_here' &&
93
- proposal.disposition !== 'clarify') {
94
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub cannot write from an ambiguous instruction');
95
- }
96
96
  const durable = await this.#effects.readAssignment(input.actionId);
97
97
  if (durable) {
98
98
  const replayFingerprint = durable.replacesActionId
@@ -106,30 +106,7 @@ export class WorkHubCoordinationActionGate {
106
106
  }
107
107
  return this.#assign(assignmentInputFromRecord(durable), context);
108
108
  }
109
- if (proposal.disposition === 'answer_here') {
110
- const turnId = coordinationTurnId(input.actionId, 'answer');
111
- await this.#claimAction(input.actionId, 'answer_here', fingerprint, turnId);
112
- await this.#effects.answer({
113
- turnId,
114
- text: input.userText,
115
- ...(input.attachments ? { attachments: input.attachments } : {}),
116
- }, context);
117
- return { disposition: 'answer_here', coordinationTurnId: turnId };
118
- }
119
- if (proposal.disposition === 'clarify') {
120
- const turnId = coordinationTurnId(input.actionId, 'clarify');
121
- await this.#claimAction(input.actionId, 'clarify', fingerprint, turnId);
122
- await this.#effects.clarify({
123
- turnId,
124
- userText: input.userText,
125
- assistantText: proposal.assistantText,
126
- });
127
- return { disposition: 'clarify', coordinationTurnId: turnId };
128
- }
129
109
  if (proposal.disposition === 'stop_work') {
130
- if (input.confirmation?.kind !== 'user_stop' || !requestIntent.stop.imperative) {
131
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub stop requires an explicit named command in trusted user text');
132
- }
133
110
  const source = await this.#stopSource(input.actionId, proposal.expects.targetSessionId);
134
111
  const stopFingerprint = stopActionFingerprint(input, source);
135
112
  await this.#claimAction(input.actionId, 'stop', stopFingerprint, source.delegationId);
@@ -171,6 +148,7 @@ export class WorkHubCoordinationActionGate {
171
148
  }
172
149
  const requested = await this.#effects.prepareStop({
173
150
  actionId: input.actionId,
151
+ coordinationTurnId: input.coordinationTurnId,
174
152
  actionFingerprint: stopFingerprint,
175
153
  stopsActionId: source.actionId,
176
154
  stopsDelegationId: source.delegationId,
@@ -182,36 +160,33 @@ export class WorkHubCoordinationActionGate {
182
160
  return this.#stop(requested, source);
183
161
  }
184
162
  if (proposal.disposition === 'resume_work') {
185
- if (!requestIntent.resume.imperative) {
186
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub resume requires an explicit named command in trusted user text');
187
- }
188
- const candidates = await this.candidates();
189
- const target = candidates.candidates.find((candidate) => candidate.sessionId === proposal.expects.targetSessionId);
190
- if (!target)
191
- throw new WorkHubActionGateFailure('candidate_unavailable', 'WorkHub resume target is unavailable');
192
- this.#assertTarget(target);
193
- const source = await this.#soleWorkingDelegation(target.sessionId, 'resume');
194
- if (source.actionId !== proposal.resumesActionId) {
163
+ const source = await this.#effects.readAssignment(proposal.resumesActionId);
164
+ if (!source || source.targetSessionId !== proposal.expects.targetSessionId) {
195
165
  throw new WorkHubActionGateFailure('action_conflict', 'WorkHub resume target delegation changed');
196
166
  }
197
- const currentTargetName = target.sessionName;
198
- if (!currentTargetName ||
199
- !workHubNamedDelegationActionTargetsSession(requestIntent.resume, currentTargetName)) {
200
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub resume target is not affirmed in trusted user text');
201
- }
202
- return this.#effects.resume({ actionId: input.actionId, source }, context);
167
+ const validateFreshTarget = async () => {
168
+ const candidates = await this.candidates();
169
+ const target = candidates.candidates.find((candidate) => candidate.sessionId === proposal.expects.targetSessionId);
170
+ if (!target)
171
+ throw new WorkHubActionGateFailure('candidate_unavailable', 'WorkHub resume target is unavailable');
172
+ this.#assertTarget(target);
173
+ const current = await this.#soleWorkingDelegation(target.sessionId, 'resume');
174
+ if (current.actionId !== source.actionId) {
175
+ throw new WorkHubActionGateFailure('action_conflict', 'WorkHub resume target delegation changed');
176
+ }
177
+ if (!target.sessionName)
178
+ throw new WorkHubActionGateFailure('action_conflict', 'WorkHub resume target is unavailable');
179
+ };
180
+ return this.#effects.resume({ actionId: input.actionId, source, validateFreshTarget }, context);
203
181
  }
204
182
  if (proposal.disposition === 'create_new') {
205
- if (!input.create || !workHubCreationAuthorizesTitle(requestIntent, proposal.title)) {
206
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub creation requires an unambiguous instruction and creation context');
183
+ if (!input.create) {
184
+ throw new WorkHubActionGateFailure('action_conflict', 'WorkHub creation context is unavailable');
207
185
  }
208
186
  const sessionId = workHubCreatedSessionId(input.actionId);
209
187
  return this.#assign(delegationAssignment(input, fingerprint, sessionId, proposal.title), context);
210
188
  }
211
189
  if (proposal.disposition === 'replace') {
212
- if (input.confirmation?.kind !== 'user_correction' || !requestIntent.correction.cue) {
213
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub replacement requires explicit correction in trusted user text');
214
- }
215
190
  const replaced = await this.#effects.readAssignment(proposal.replacesActionId);
216
191
  if (!replaced) {
217
192
  throw new WorkHubActionGateFailure('action_conflict', 'WorkHub can replace only a durable delegation it owns');
@@ -221,9 +196,6 @@ export class WorkHubCoordinationActionGate {
221
196
  }
222
197
  const prepared = await this.#effects.readReplacement(replaced.delegationId);
223
198
  if (prepared) {
224
- if (!isExplicitWorkHubCorrectionText(input.userText, prepared.disposition, prepared.targetSessionName)) {
225
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub replacement target is not affirmed in trusted user text');
226
- }
227
199
  if (prepared.actionId !== input.actionId ||
228
200
  prepared.actionFingerprint !==
229
201
  replacementActionFingerprint(input, prepared.targetSessionId)) {
@@ -374,21 +346,20 @@ export class WorkHubCoordinationActionGate {
374
346
  }
375
347
  const target = input.proposal.target;
376
348
  if (target.disposition === 'create_new') {
377
- if (!isExplicitWorkHubCorrectionText(input.userText, 'create_new', target.title)) {
378
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub replacement creation requires explicit non-negated user intent');
379
- }
380
349
  if (!input.create) {
381
350
  throw new WorkHubActionGateFailure('action_conflict', 'WorkHub replacement creation context is unavailable');
382
351
  }
383
352
  const targetSessionId = workHubCreatedSessionId(input.actionId);
384
353
  return {
385
354
  actionId: input.actionId,
355
+ coordinationTurnId: input.coordinationTurnId,
386
356
  actionFingerprint: replacementActionFingerprint(input, targetSessionId),
387
357
  targetSessionId,
388
358
  targetSessionName: target.title,
389
359
  disposition: 'create_new',
390
360
  userText: input.userText,
391
361
  ...(input.attachments ? { attachments: input.attachments } : {}),
362
+ ...(input.delegationText === undefined ? {} : { delegationText: input.delegationText }),
392
363
  create: {
393
364
  title: target.title,
394
365
  workspace: input.create.workspace,
@@ -409,20 +380,19 @@ export class WorkHubCoordinationActionGate {
409
380
  throw new WorkHubActionGateFailure('candidate_unavailable', 'WorkHub replacement target is not in the admitted candidate set');
410
381
  }
411
382
  this.#assertTarget(destination);
412
- if (!isExplicitWorkHubCorrectionText(input.userText, 'delegate_existing', destination.sessionName)) {
413
- throw new WorkHubActionGateFailure('action_conflict', 'WorkHub replacement target is not affirmed in trusted user text');
414
- }
415
383
  if (destination.sessionId === replaced.targetSessionId) {
416
384
  throw new WorkHubActionGateFailure('action_conflict', 'WorkHub replacement must choose a different Session');
417
385
  }
418
386
  return {
419
387
  actionId: input.actionId,
388
+ coordinationTurnId: input.coordinationTurnId,
420
389
  actionFingerprint: replacementActionFingerprint(input, destination.sessionId),
421
390
  targetSessionId: destination.sessionId,
422
391
  targetSessionName: destination.sessionName,
423
392
  disposition: 'delegate_existing',
424
393
  userText: input.userText,
425
394
  ...(input.attachments ? { attachments: input.attachments } : {}),
395
+ ...(input.delegationText === undefined ? {} : { delegationText: input.delegationText }),
426
396
  replacesActionId: replaced.actionId,
427
397
  replacesDelegationId: replaced.delegationId,
428
398
  replacedTargetSessionId: replaced.targetSessionId,
@@ -609,9 +579,6 @@ function isCandidateSession(session) {
609
579
  function candidateRef(candidateSetId, sessionId) {
610
580
  return `whc_${hash(`${candidateSetId}\0${sessionId}`).slice(0, 48)}`;
611
581
  }
612
- function coordinationTurnId(actionId, kind) {
613
- return `wha_${hash(`${actionId}\0${kind}`).slice(0, 48)}`;
614
- }
615
582
  function delegationAssignment(input, actionFingerprint, targetSessionId, targetSessionName) {
616
583
  const create = input.create;
617
584
  if (input.proposal.disposition !== 'delegate_existing' &&
@@ -620,12 +587,14 @@ function delegationAssignment(input, actionFingerprint, targetSessionId, targetS
620
587
  }
621
588
  const base = {
622
589
  actionId: input.actionId,
590
+ coordinationTurnId: input.coordinationTurnId ?? input.actionId,
623
591
  actionFingerprint,
624
592
  targetSessionId,
625
593
  targetSessionName,
626
594
  disposition: input.proposal.disposition,
627
595
  userText: input.userText,
628
596
  ...(input.attachments ? { attachments: input.attachments } : {}),
597
+ ...(input.delegationText === undefined ? {} : { delegationText: input.delegationText }),
629
598
  };
630
599
  if (input.proposal.disposition === 'delegate_existing')
631
600
  return base;
@@ -671,6 +640,7 @@ function actionFingerprint(input) {
671
640
  userText: input.userText,
672
641
  ...(input.attachments ? { attachments: input.attachments } : {}),
673
642
  ...(input.newWorkDefaults ? { newWorkDefaults: input.newWorkDefaults } : {}),
643
+ ...(input.delegationText === undefined ? {} : { delegationText: input.delegationText }),
674
644
  disposition: input.proposal.disposition,
675
645
  ...(input.proposal.disposition === 'delegate_existing'
676
646
  ? { candidateRef: input.proposal.candidateRef }
@@ -681,9 +651,6 @@ function actionFingerprint(input) {
681
651
  workspace: input.create?.workspace,
682
652
  }
683
653
  : {}),
684
- ...(input.proposal.disposition === 'clarify'
685
- ? { assistantText: input.proposal.assistantText }
686
- : {}),
687
654
  ...(input.proposal.disposition === 'replace'
688
655
  ? {
689
656
  replacesActionId: input.proposal.replacesActionId,
@@ -703,6 +670,7 @@ function replacementActionFingerprint(input, targetSessionId) {
703
670
  userText: input.userText,
704
671
  ...(input.attachments ? { attachments: input.attachments } : {}),
705
672
  ...(input.newWorkDefaults ? { newWorkDefaults: input.newWorkDefaults } : {}),
673
+ ...(input.delegationText === undefined ? {} : { delegationText: input.delegationText }),
706
674
  disposition: input.proposal.disposition,
707
675
  replacesActionId: input.proposal.replacesActionId,
708
676
  target: {
@@ -758,12 +726,16 @@ function stopResultFromRecord(resolution, request) {
758
726
  function assignmentInputFromRecord(assignment) {
759
727
  return {
760
728
  actionId: assignment.actionId,
729
+ coordinationTurnId: assignment.coordinationTurnId,
761
730
  actionFingerprint: assignment.actionFingerprint,
762
731
  targetSessionId: assignment.targetSessionId,
763
732
  targetSessionName: assignment.targetSessionName,
764
733
  disposition: assignment.disposition,
765
734
  userText: assignment.userText,
766
735
  ...(assignment.attachments ? { attachments: assignment.attachments } : {}),
736
+ ...(assignment.delegationText === undefined
737
+ ? {}
738
+ : { delegationText: assignment.delegationText }),
767
739
  ...(assignment.create ? { create: assignment.create } : {}),
768
740
  ...(assignment.replacesActionId && assignment.replacesDelegationId
769
741
  ? {
@@ -776,12 +748,16 @@ function assignmentInputFromRecord(assignment) {
776
748
  function assignmentInputFromReplacement(replacement) {
777
749
  return {
778
750
  actionId: replacement.actionId,
751
+ coordinationTurnId: replacement.coordinationTurnId,
779
752
  actionFingerprint: replacement.actionFingerprint,
780
753
  targetSessionId: replacement.targetSessionId,
781
754
  targetSessionName: replacement.targetSessionName,
782
755
  disposition: replacement.disposition,
783
756
  userText: replacement.userText,
784
757
  ...(replacement.attachments ? { attachments: replacement.attachments } : {}),
758
+ ...(replacement.delegationText === undefined
759
+ ? {}
760
+ : { delegationText: replacement.delegationText }),
785
761
  ...(replacement.create ? { create: replacement.create } : {}),
786
762
  replacesActionId: replacement.replacesActionId,
787
763
  replacesDelegationId: replacement.replacesDelegationId,
@@ -790,20 +766,3 @@ function assignmentInputFromReplacement(replacement) {
790
766
  function hash(value) {
791
767
  return createHash('sha256').update(value, 'utf8').digest('hex');
792
768
  }
793
- /**
794
- * Destructive replacement needs evidence in the user-originated text itself;
795
- * a strategy-provided replacement proposal and confirmation marker are not
796
- * sufficient authority. Keep this deliberately narrower than route inference.
797
- */
798
- export function isExplicitWorkHubCorrectionText(value, targetDisposition, targetSessionName) {
799
- const intent = readWorkHubRequestIntent(value);
800
- if (targetDisposition === 'create_new') {
801
- return Boolean(intent.correction.cue &&
802
- intent.creation.explicit &&
803
- targetSessionName &&
804
- workHubCreationAuthorizesTitle(intent, targetSessionName));
805
- }
806
- return Boolean(targetSessionName &&
807
- intent.correction.cue &&
808
- workHubCorrectionTargetsSession(intent, targetSessionName));
809
- }