cli-jaw 2.2.18 → 2.2.20

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 (171) hide show
  1. package/README.md +106 -3
  2. package/dist/bin/cli-jaw.js +1 -1
  3. package/dist/bin/cli-jaw.js.map +1 -1
  4. package/dist/bin/commands/dispatch.js +14 -4
  5. package/dist/bin/commands/dispatch.js.map +1 -1
  6. package/dist/bin/commands/service.js +322 -222
  7. package/dist/bin/commands/service.js.map +1 -1
  8. package/dist/bin/postinstall.js +20 -4
  9. package/dist/bin/postinstall.js.map +1 -1
  10. package/dist/server.js +39 -2
  11. package/dist/server.js.map +1 -1
  12. package/dist/src/agent/spawn/process-kill.js +96 -2
  13. package/dist/src/agent/spawn/process-kill.js.map +1 -1
  14. package/dist/src/agent/spawn.js +35 -77
  15. package/dist/src/agent/spawn.js.map +1 -1
  16. package/dist/src/bgtask/runner.js +26 -21
  17. package/dist/src/bgtask/runner.js.map +1 -1
  18. package/dist/src/cli/acp-client.js +11 -5
  19. package/dist/src/cli/acp-client.js.map +1 -1
  20. package/dist/src/cli/cli-status-worker.js +59 -6
  21. package/dist/src/cli/cli-status-worker.js.map +1 -1
  22. package/dist/src/cli/employee-handler.js +3 -2
  23. package/dist/src/cli/employee-handler.js.map +1 -1
  24. package/dist/src/code-mode/acp-host.js +22 -10
  25. package/dist/src/code-mode/acp-host.js.map +1 -1
  26. package/dist/src/core/cli-detect.js +54 -8
  27. package/dist/src/core/cli-detect.js.map +1 -1
  28. package/dist/src/core/config.js +24 -0
  29. package/dist/src/core/config.js.map +1 -1
  30. package/dist/src/core/db.js +16 -0
  31. package/dist/src/core/db.js.map +1 -1
  32. package/dist/src/core/employees.js +22 -4
  33. package/dist/src/core/employees.js.map +1 -1
  34. package/dist/src/core/instance-lifecycle.js +120 -0
  35. package/dist/src/core/instance-lifecycle.js.map +1 -0
  36. package/dist/src/core/runtime-path.js +92 -12
  37. package/dist/src/core/runtime-path.js.map +1 -1
  38. package/dist/src/core/runtime-settings.js +4 -1
  39. package/dist/src/core/runtime-settings.js.map +1 -1
  40. package/dist/src/core/settings-watch.js +12 -1
  41. package/dist/src/core/settings-watch.js.map +1 -1
  42. package/dist/src/core/windows-shell.js +63 -0
  43. package/dist/src/core/windows-shell.js.map +1 -0
  44. package/dist/src/discord/bot.js +199 -147
  45. package/dist/src/discord/bot.js.map +1 -1
  46. package/dist/src/discord/gateway-supervisor.js +303 -0
  47. package/dist/src/discord/gateway-supervisor.js.map +1 -0
  48. package/dist/src/discord/rest-scheduler.js +448 -0
  49. package/dist/src/discord/rest-scheduler.js.map +1 -0
  50. package/dist/src/discord/send-only-client.js +59 -43
  51. package/dist/src/discord/send-only-client.js.map +1 -1
  52. package/dist/src/manager/lifecycle.js +7 -2
  53. package/dist/src/manager/lifecycle.js.map +1 -1
  54. package/dist/src/manager/notes/capabilities.js +9 -7
  55. package/dist/src/manager/notes/capabilities.js.map +1 -1
  56. package/dist/src/memory/bootstrap.js +5 -1
  57. package/dist/src/memory/bootstrap.js.map +1 -1
  58. package/dist/src/memory/host-toolchain.js +156 -0
  59. package/dist/src/memory/host-toolchain.js.map +1 -0
  60. package/dist/src/messaging/channel-capabilities.js +30 -0
  61. package/dist/src/messaging/channel-capabilities.js.map +1 -0
  62. package/dist/src/messaging/delivery-outcome.js +73 -0
  63. package/dist/src/messaging/delivery-outcome.js.map +1 -0
  64. package/dist/src/messaging/draft-stream.js +154 -0
  65. package/dist/src/messaging/draft-stream.js.map +1 -0
  66. package/dist/src/messaging/runtime.js +3 -9
  67. package/dist/src/messaging/runtime.js.map +1 -1
  68. package/dist/src/messaging/send.js +40 -8
  69. package/dist/src/messaging/send.js.map +1 -1
  70. package/dist/src/messaging/types.js +22 -1
  71. package/dist/src/messaging/types.js.map +1 -1
  72. package/dist/src/notes/search.js +31 -6
  73. package/dist/src/notes/search.js.map +1 -1
  74. package/dist/src/prompt/builder.js +169 -13
  75. package/dist/src/prompt/builder.js.map +1 -1
  76. package/dist/src/prompt/conversation-context.js +23 -0
  77. package/dist/src/prompt/conversation-context.js.map +1 -0
  78. package/dist/src/prompt/templates/a1-system.md +28 -12
  79. package/dist/src/prompt/templates/control-system.md +19 -6
  80. package/dist/src/prompt/templates/employee.md +16 -3
  81. package/dist/src/routes/settings.js +8 -1
  82. package/dist/src/routes/settings.js.map +1 -1
  83. package/dist/src/routes/system.js +5 -1
  84. package/dist/src/routes/system.js.map +1 -1
  85. package/dist/src/routes/wiki.js +17 -12
  86. package/dist/src/routes/wiki.js.map +1 -1
  87. package/dist/src/search/coordinator.js +13 -5
  88. package/dist/src/search/coordinator.js.map +1 -1
  89. package/dist/src/search/provider.js.map +1 -1
  90. package/dist/src/search/providers/wiki.js +17 -9
  91. package/dist/src/search/providers/wiki.js.map +1 -1
  92. package/dist/src/security/path-guards.js +124 -27
  93. package/dist/src/security/path-guards.js.map +1 -1
  94. package/dist/src/slack/api.js +38 -5
  95. package/dist/src/slack/api.js.map +1 -1
  96. package/dist/src/slack/bot.js +214 -35
  97. package/dist/src/slack/bot.js.map +1 -1
  98. package/dist/src/slack/context.js +192 -0
  99. package/dist/src/slack/context.js.map +1 -0
  100. package/dist/src/slack/conversation.js +275 -0
  101. package/dist/src/slack/conversation.js.map +1 -0
  102. package/dist/src/slack/enrichment-cache.js +334 -0
  103. package/dist/src/slack/enrichment-cache.js.map +1 -0
  104. package/dist/src/slack/history.js +47 -8
  105. package/dist/src/slack/history.js.map +1 -1
  106. package/dist/src/slack/identity.js +99 -190
  107. package/dist/src/slack/identity.js.map +1 -1
  108. package/dist/src/slack/ingress.js +78 -2
  109. package/dist/src/slack/ingress.js.map +1 -1
  110. package/dist/src/slack/manifest.js +14 -3
  111. package/dist/src/slack/manifest.js.map +1 -1
  112. package/dist/src/slack/progress.js +39 -51
  113. package/dist/src/slack/progress.js.map +1 -1
  114. package/dist/src/slack/thread-tracker.js +78 -0
  115. package/dist/src/slack/thread-tracker.js.map +1 -1
  116. package/dist/src/telegram/bot.js +105 -56
  117. package/dist/src/telegram/bot.js.map +1 -1
  118. package/dist/src/telegram/update-offset.js +152 -0
  119. package/dist/src/telegram/update-offset.js.map +1 -0
  120. package/dist/src/wiki/config.js +42 -14
  121. package/dist/src/wiki/config.js.map +1 -1
  122. package/dist/src/wiki/prompt.js +2 -2
  123. package/dist/src/wiki/prompt.js.map +1 -1
  124. package/package.json +1 -1
  125. package/public/dist/assets/Agent-C5EvX-_v.js +1 -0
  126. package/public/dist/assets/{app-DqSJmDwP.js → app-is76CHGZ.js} +4 -4
  127. package/public/dist/assets/{bgtask-badge-D6XYRFI5.js → bgtask-badge-B0B1nXUs.js} +1 -1
  128. package/public/dist/assets/bgtask-badge-B2jUZ5mC.js +1 -0
  129. package/public/dist/assets/{employees-B_wKPfTO.js → employees-eiW0cC8z.js} +1 -1
  130. package/public/dist/assets/{iframe-renderer-D1-zDg8V.js → iframe-renderer-C7qQJX4c.js} +2 -2
  131. package/public/dist/assets/iframe-renderer-D7PB_yrC.js +1 -0
  132. package/public/dist/assets/{manager-Bjuh1jpq.js → manager-CP-Au860.js} +1 -1
  133. package/public/dist/assets/{memory-CNUpXWEC.js → memory--Q8Tb5SZ.js} +1 -1
  134. package/public/dist/assets/memory-rsKN0aa2.js +1 -0
  135. package/public/dist/assets/message-history-BttkY77h.js +1 -0
  136. package/public/dist/assets/{message-history-DB1rynP-.js → message-history-CfAHmCDW.js} +1 -1
  137. package/public/dist/assets/{render-DXwQzjsJ.js → render-BDso7Yb5.js} +1 -1
  138. package/public/dist/assets/{settings-CXndjCad.js → settings-CqnIqxkG.js} +1 -1
  139. package/public/dist/assets/{settings-core-t5yYVRrv.js → settings-core-BxuFkt4a.js} +4 -4
  140. package/public/dist/assets/settings-core-CdZ7oKhM.js +1 -0
  141. package/public/dist/assets/settings-pPMHNs0G.js +1 -0
  142. package/public/dist/assets/{sidebar-DgIj-LuT.js → sidebar-BNT58qR0.js} +3 -3
  143. package/public/dist/assets/{skills-QqxjqDHg.js → skills-CwRBcm3m.js} +1 -1
  144. package/public/dist/assets/skills-DiVoaVdS.js +1 -0
  145. package/public/dist/assets/slash-commands-Bx4saHwR.js +1 -0
  146. package/public/dist/assets/{slash-commands-B2V_jngP.js → slash-commands-cm0U58n7.js} +1 -1
  147. package/public/dist/assets/{trace-drawer-CBe9nRjS.js → trace-drawer-BuwO4m2P.js} +1 -1
  148. package/public/dist/assets/{ui-CDozpEQt.js → ui-C-LHMki1.js} +1 -1
  149. package/public/dist/assets/ui-XPQDPe-5.js +1 -0
  150. package/public/dist/index.html +1 -1
  151. package/public/dist/manager/index.html +1 -1
  152. package/public/js/features/channel-onboarding.ts +8 -5
  153. package/public/locales/en.json +3 -2
  154. package/public/locales/ja.json +3 -2
  155. package/public/locales/ko.json +3 -2
  156. package/public/locales/zh.json +3 -2
  157. package/public/manager/src/settings/cli-status-polling.ts +84 -0
  158. package/public/manager/src/settings/pages/Agent.tsx +84 -5
  159. package/scripts/install-officecli.ps1 +38 -2
  160. package/scripts/install-officecli.sh +28 -0
  161. package/scripts/install.ps1 +1 -1
  162. package/public/dist/assets/Agent-nMPZsMfN.js +0 -1
  163. package/public/dist/assets/bgtask-badge-CjWz0F6U.js +0 -1
  164. package/public/dist/assets/iframe-renderer-qRVLHPnT.js +0 -1
  165. package/public/dist/assets/memory-CcWGiPy_.js +0 -1
  166. package/public/dist/assets/message-history-BamMPUnL.js +0 -1
  167. package/public/dist/assets/settings-RGpifFHy.js +0 -1
  168. package/public/dist/assets/settings-core-X_5UHfr3.js +0 -1
  169. package/public/dist/assets/skills-CbwIimit.js +0 -1
  170. package/public/dist/assets/slash-commands-tCNRlNTC.js +0 -1
  171. package/public/dist/assets/ui-o-VpvrSv.js +0 -1
@@ -20,6 +20,7 @@ import { buildTaskSnapshot } from '../memory/runtime.js';
20
20
  import { getActiveChatSession } from '../core/chat-sessions.js';
21
21
  import { currentSessionScope } from '../core/session-context.js';
22
22
  import { getSystemPrompt, regenerateB } from '../prompt/builder.js';
23
+ import { prependRemoteConversationContext } from '../prompt/conversation-context.js';
23
24
  import { extractSessionId, extractFromEvent, extractFromAcpUpdate, extractOutputChunk, logEventSummary, flushClaudeBuffers, flushOpenCodeBuffers } from './events.js';
24
25
  import { detectSmokeResponse } from './smoke-detector.js';
25
26
  import { saveUpload as _saveUpload, buildMediaPrompt, buildMediaPromptMany } from '../../lib/upload.js';
@@ -31,6 +32,7 @@ import { hasBlockingWorkers, hasPendingWorkerReplays, getActiveWorkers, clearAll
31
32
  import { sanitizeWorkerProgressTools } from '../orchestrator/worker-progress.js';
32
33
  import { handleAgentExit, setSpawnAgent, setMainMetaHandler } from './lifecycle-handler.js';
33
34
  import { buildServicePath } from '../core/runtime-path.js';
35
+ import { formatCliUnavailableMessage } from '../core/cli-detect.js';
34
36
  import { LOCAL_SESSION_SCOPE_ACTIVATION, resolveOrcScope } from '../orchestrator/scope.js';
35
37
  import { stripInterviewTracker } from '../orchestrator/sanitize.js';
36
38
  import { beginLiveRun, appendLiveRunText, setLiveRunTraceId, clearLiveRun, replaceLiveRunTools, appendLiveRunTool, getLiveRun } from './live-run-state.js';
@@ -60,6 +62,10 @@ const DUP_REGISTRATION_KILL_REASON = 'dup-registration';
60
62
  /** Grace before escalating that kill to SIGKILL, matching the sibling kill paths. */
61
63
  const DUP_REGISTRATION_KILL_GRACE_MS = 2_000;
62
64
  function registerActiveProcess(agentLabel, child) {
65
+ // Defensive: the concrete spawn site should already own this child, and
66
+ // ownProcess is memoized, so this returns that existing owner rather than
67
+ // installing a second escalation timer.
68
+ ownProcess(child);
63
69
  const prev = activeProcesses.get(agentLabel);
64
70
  if (prev && prev !== child) {
65
71
  // `killed` only records that a signal was delivered, so it is not a
@@ -80,22 +86,12 @@ function registerActiveProcess(agentLabel, child) {
80
86
  // Record a kill reason so the stale exit handler classifies this
81
87
  // as an intentional kill rather than a genuine agent error.
82
88
  killReasons.set(prevPid, DUP_REGISTRATION_KILL_REASON);
83
- try {
84
- killProcessTree(prevPid, 'SIGTERM');
85
- }
86
- catch (error) {
87
- console.warn(`[spawn:dup] failed to kill previous child for ${agentLabel}:`, error?.message ?? error);
88
- }
89
- // Escalate like every sibling kill path does: a CLI that traps
90
- // SIGTERM would otherwise survive with no map entry to find it.
91
- // Route through killProcessTreeIfAlive so a child that exited
92
- // during the grace period cannot have its recycled PID killed:
93
- // killProcessTree walks `pgrep -P`, so a blind escalation would
94
- // take an unrelated process tree down with it.
95
- const escalate = setTimeout(() => {
96
- killProcessTreeIfAlive(prev, prevPid);
97
- }, DUP_REGISTRATION_KILL_GRACE_MS);
98
- escalate.unref?.();
89
+ // The owner performs the SIGTERM tree walk, schedules the same
90
+ // grace, and re-checks the original child before escalating —
91
+ // so a PID recycled during the grace is never signalled.
92
+ ownProcess(prev, {
93
+ policy: () => ({ initialSignal: 'SIGTERM', graceMs: DUP_REGISTRATION_KILL_GRACE_MS }),
94
+ }).terminate('duplicate-registration');
99
95
  }
100
96
  }
101
97
  }
@@ -155,7 +151,7 @@ export function buildAiERuntimeStatusMeta(cli, provider, model) {
155
151
  },
156
152
  };
157
153
  }
158
- import { hasChildExited, killProcessTree, killProcessTreeIfAlive } from './spawn/process-kill.js';
154
+ import { hasChildExited, killProcessTree, killProcessTreeIfAlive, ownProcess } from './spawn/process-kill.js';
159
155
  import { releaseChildOutputAfterExit } from './spawn/exit-drain.js';
160
156
  import { clampPendingLine } from './spawn/line-buffer.js';
161
157
  import { appendBoundedFullText } from './events/fulltext-bound.js';
@@ -426,37 +422,26 @@ export function killActiveAgent(scopeKeyOrReason = 'user', scopedReason) {
426
422
  console.log(`[jaw:kill] reason=${reason} scope=${scopeKey} cli=${getActiveMainCli(scopeKey) || 'unknown'} signal=${policy.signal} escalationMs=${policy.escalationMs}`);
427
423
  if (activeProcess.pid)
428
424
  killReasons.set(activeProcess.pid, reason);
429
- try {
430
- if (activeProcess.pid) {
431
- killProcessTree(activeProcess.pid, policy.signal);
432
- }
433
- else {
434
- activeProcess.kill(policy.signal);
435
- }
436
- }
437
- catch (e) {
438
- console.warn(`[agent:kill] ${policy.signal} failed`, { pid: activeProcess?.pid, error: e.message });
439
- }
440
425
  const proc = activeProcess;
426
+ // One owner runs the whole termination: tree walk with the policy signal,
427
+ // then escalation after policy.escalationMs that re-checks the ORIGINAL
428
+ // child. The previous escalation guarded on `!proc.killed`, which only
429
+ // records that a signal was delivered — a CLI that traps SIGTERM stays
430
+ // alive with killed set, and was therefore never escalated.
431
+ ownProcess(proc, {
432
+ policy: () => ({ initialSignal: policy.signal, graceMs: policy.escalationMs }),
433
+ }).terminate(reason === 'steer' ? 'steer' : 'cancel');
441
434
  // Immediately sever stdio to stop late output from reaching broadcast handlers
442
435
  proc.stdout?.removeAllListeners('data');
443
436
  proc.stderr?.removeAllListeners('data');
444
- setTimeout(() => {
445
- try {
446
- if (proc && !proc.killed) {
447
- if (proc.pid)
448
- killProcessTree(proc.pid, 'SIGKILL');
449
- else
450
- proc.kill('SIGKILL');
451
- }
452
- }
453
- catch (e) {
454
- console.warn('[agent:kill] SIGKILL failed', { pid: proc?.pid, error: e.message });
455
- }
437
+ // Stdio teardown stays on its own timer: it must happen even when the
438
+ // owner short-circuits because the child had already exited.
439
+ const teardown = setTimeout(() => {
456
440
  proc.stdin?.destroy();
457
441
  proc.stdout?.destroy();
458
442
  proc.stderr?.destroy();
459
443
  }, policy.escalationMs);
444
+ teardown.unref?.();
460
445
  // Fix C1: 사용자 stop/steer 시 해당 scope busy가 즉시 false가 되도록 참조를 동기 해제.
461
446
  // 실제 child 종료는 위 setTimeout SIGKILL이 백그라운드에서 마무리.
462
447
  // exit handler의 setActiveProcess(null) / activeProcesses.delete 는 idempotent.
@@ -479,35 +464,19 @@ export function killAllAgents(reason = 'user') {
479
464
  console.log(`[jaw:killAll] killing ${id}, reason=${reason}`);
480
465
  if (proc.pid)
481
466
  killReasons.set(proc.pid, reason);
482
- try {
483
- if (proc.pid) {
484
- killProcessTree(proc.pid, 'SIGTERM');
485
- }
486
- else {
487
- proc.kill('SIGTERM');
488
- }
489
- killed++;
490
- }
491
- catch (e) {
492
- console.warn(`[agent:killAll] SIGTERM failed for ${id}`, e.message);
493
- }
467
+ // Same owner contract as killActiveAgent: tree walk now, escalation
468
+ // after the grace, guarded by real exit state rather than `killed`.
469
+ ownProcess(proc, {
470
+ policy: () => ({ initialSignal: 'SIGTERM', graceMs: 2000 }),
471
+ }).terminate('shutdown');
472
+ killed++;
494
473
  const ref = proc;
495
- setTimeout(() => {
496
- try {
497
- if (ref && !ref.killed) {
498
- if (ref.pid) {
499
- killProcessTree(ref.pid, 'SIGKILL');
500
- }
501
- else {
502
- ref.kill('SIGKILL');
503
- }
504
- }
505
- }
506
- catch { /* already dead */ }
474
+ const teardown = setTimeout(() => {
507
475
  ref.stdin?.destroy();
508
476
  ref.stdout?.destroy();
509
477
  ref.stderr?.destroy();
510
478
  }, 2000);
479
+ teardown.unref?.();
511
480
  }
512
481
  if (reason === 'api' || reason === 'user') {
513
482
  activeProcesses.clear();
@@ -588,18 +557,6 @@ function makeCleanEnv(extraEnv = {}) {
588
557
  PATH: buildServicePath(extraEnv["PATH"] || env["PATH"] || ''),
589
558
  };
590
559
  }
591
- function formatCliUnavailableMessage(cli, detected) {
592
- const rejected = detected.rejected || [];
593
- if (rejected.length > 0) {
594
- const details = rejected
595
- .slice(0, 3)
596
- .map((entry) => `${entry.path} (${entry.reason})`)
597
- .join('; ');
598
- const suffix = rejected.length > 3 ? `; +${rejected.length - 3} more` : '';
599
- return `CLI '${cli}' found on PATH but no spawnable executable was available. Rejected: ${details}${suffix}. Run \`jaw doctor --json\`.`;
600
- }
601
- return `CLI '${cli}' not found in PATH. Run \`jaw doctor --json\`.`;
602
- }
603
560
  function buildHistoryBlock(currentPrompt, workingDir, chatSessionId, maxSessions = 10, maxTotalChars = 8000) {
604
561
  const recent = getRecentMessages.all(workingDir || null, chatSessionId, Math.max(1, maxSessions * 2));
605
562
  if (!recent.length)
@@ -1058,7 +1015,8 @@ export function spawnAgent(prompt, opts = {}) {
1058
1015
  const memoryNudge = (!opts._isSmokeContinuation && !opts._isGoalContinuation)
1059
1016
  ? '\n(need history? L1: cli-jaw chat/memory search/context | L2: cli-jaw dashboard memory search, cli-jaw dashboard chat search)'
1060
1017
  : '';
1061
- prompt = `${ts}\n${projLine}${prompt}${memoryNudge}`;
1018
+ const promptWithConversation = prependRemoteConversationContext(prompt, opts.target);
1019
+ prompt = `${ts}\n${projLine}${promptWithConversation}${memoryNudge}`;
1062
1020
  }
1063
1021
  const resumeSessionId = empSid || (isResume ? bucketSessionId : null);
1064
1022
  const needsHistory = shouldBuildHistoryBlock({