@namzu/cli 34.1.1 → 35.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/commands/mcp.d.ts +3 -0
  3. package/dist/commands/mcp.d.ts.map +1 -1
  4. package/dist/commands/mcp.js +179 -6
  5. package/dist/commands/mcp.js.map +1 -1
  6. package/dist/integrations/mcp/servers.d.ts.map +1 -1
  7. package/dist/integrations/mcp/servers.js +107 -15
  8. package/dist/integrations/mcp/servers.js.map +1 -1
  9. package/dist/integrations/resident/session-step.d.ts.map +1 -1
  10. package/dist/integrations/resident/session-step.js +13 -8
  11. package/dist/integrations/resident/session-step.js.map +1 -1
  12. package/dist/tui/App.d.ts.map +1 -1
  13. package/dist/tui/App.js +385 -95
  14. package/dist/tui/App.js.map +1 -1
  15. package/dist/tui/BackgroundJobsPanel.d.ts +26 -0
  16. package/dist/tui/BackgroundJobsPanel.d.ts.map +1 -0
  17. package/dist/tui/BackgroundJobsPanel.js +129 -0
  18. package/dist/tui/BackgroundJobsPanel.js.map +1 -0
  19. package/dist/tui/Composer.d.ts +7 -2
  20. package/dist/tui/Composer.d.ts.map +1 -1
  21. package/dist/tui/Composer.js +65 -34
  22. package/dist/tui/Composer.js.map +1 -1
  23. package/dist/tui/PendingInputPanel.d.ts +34 -0
  24. package/dist/tui/PendingInputPanel.d.ts.map +1 -0
  25. package/dist/tui/PendingInputPanel.js +108 -0
  26. package/dist/tui/PendingInputPanel.js.map +1 -0
  27. package/dist/tui/agent.d.ts +10 -3
  28. package/dist/tui/agent.d.ts.map +1 -1
  29. package/dist/tui/agent.js +78 -12
  30. package/dist/tui/agent.js.map +1 -1
  31. package/dist/tui/slashCommands.d.ts +5 -1
  32. package/dist/tui/slashCommands.d.ts.map +1 -1
  33. package/dist/tui/slashCommands.js +9 -8
  34. package/dist/tui/slashCommands.js.map +1 -1
  35. package/package.json +5 -5
package/dist/tui/agent.js CHANGED
@@ -25,7 +25,7 @@ import { countListedResults, webActivityFromInput, webActivityKind, webCallTitle
25
25
  * `emptySession()` whose `send()` yields a single error event so the UI
26
26
  * renders an actionable hint rather than crashing.
27
27
  */
28
- import { BOOT_EVENT_NAMES, BackgroundJobRegistry, DiskSessionCheckpointStore, DiskSessionLog, DiskTaskStore, EVENT_NAME_ATTRIBUTE, GuardedFetchProvider, InMemorySessionLog, MarkdownMemoryStore, PromptContributionRegistry, ProviderRegistry, SCHEDULE_TOOL_NAME, SESSION_GOAL_TOOL_NAMES, SearchToolsTool, SessionPaths, ToolManager, WebFetchTool, abandonTurn, batchNeedsReview, buildAskUserQuestionTool, buildMemoryTools, buildResidentHistoryTools, buildResidentToolEvidenceTools, buildSessionGoalTools, compactNow, compactSession, computerUseUnavailableReason, createBrowserTools, createComputerUseTool, createFileReadTracker, createMemoryPromoter, createMemoryRecallStep, createResidentStepContext, createResidentStepContributions, createReviewHandler, createSkillTool, createToolPresenter, deferred, ensureProject, filtered, generateSessionId, generateTenantId, generateTopicId, generateTurnId, getBuiltinTools, isReviewExempt, isTurnInProgressError, mapTools, query, resolveContextWindow, resumeSession, seedObservationLedger, toolset, webGuidanceContribution, withProviderFallback, wrapUntrusted, } from '@namzu/sdk';
28
+ import { BOOT_EVENT_NAMES, BackgroundJobRegistry, DiskSessionCheckpointStore, DiskSessionLog, DiskTaskStore, EVENT_NAME_ATTRIBUTE, GuardedFetchProvider, InMemorySessionLog, MarkdownMemoryStore, PromptContributionRegistry, ProviderRegistry, SCHEDULE_TOOL_NAME, SESSION_GOAL_TOOL_NAMES, SearchToolsTool, SessionPaths, ToolManager, WebFetchTool, abandonTurn, batchNeedsReview, bindOwner, buildAskUserQuestionTool, buildMemoryTools, buildResidentHistoryTools, buildResidentToolEvidenceTools, buildSessionGoalTools, compactNow, compactSession, computerUseUnavailableReason, createBrowserTools, createComputerUseTool, createFileReadTracker, createMemoryPromoter, createMemoryRecallStep, createResidentStepContext, createResidentStepContributions, createReviewHandler, createSkillTool, createToolPresenter, deferred, ensureProject, filtered, generateSessionId, generateTenantId, generateTopicId, generateTurnId, getBuiltinTools, isReviewExempt, isTurnInProgressError, mapTools, query, resolveContextWindow, resumeSession, seedObservationLedger, toolset, webGuidanceContribution, withProviderFallback, wrapUntrusted, } from '@namzu/sdk';
29
29
  import { SubprocessComputerUseHost } from '@namzu/computer-use';
30
30
  import { realpath, stat } from 'node:fs/promises';
31
31
  import { parse, resolve } from 'node:path';
@@ -508,6 +508,21 @@ function buildBaseToolsets(paths, backgroundJobs) {
508
508
  // after runtime tools are registered. Ordinary CLI task tools are active.
509
509
  return { builtin, memory, memoryStore, memoryDirectory: directory };
510
510
  }
511
+ function clipRequestContext(prompt, limit, kind) {
512
+ if (!Number.isFinite(limit) || prompt.length <= limit)
513
+ return prompt;
514
+ const notice = `\n[Further ${kind} text omitted for this request.]`;
515
+ if (limit < notice.length + 64)
516
+ return null;
517
+ let end = Math.floor(limit) - notice.length;
518
+ // Do not leave half of a Unicode supplementary character at the boundary.
519
+ if (end > 0 && /[\uD800-\uDBFF]/.test(prompt[end - 1] ?? ''))
520
+ end--;
521
+ const lineEnd = prompt.lastIndexOf('\n', end);
522
+ if (lineEnd > end / 2)
523
+ end = lineEnd;
524
+ return prompt.slice(0, end).trimEnd() + notice;
525
+ }
511
526
  export async function createAgentSession(prefs, detected, options = {}) {
512
527
  const fileObservations = new Map();
513
528
  /**
@@ -951,6 +966,7 @@ export async function createAgentSession(prefs, detected, options = {}) {
951
966
  // runs on the host and must not sit beside a sandbox in one tool context.
952
967
  const jobRegistry = backgroundJobs ? new BackgroundJobRegistry() : undefined;
953
968
  const jobOwner = scope.sessionId;
969
+ const ownedJobs = jobRegistry ? bindOwner(jobRegistry, jobOwner) : undefined;
954
970
  // Session-scoped and mutable: `/add-dir` adds to it, and every turn reads
955
971
  // it fresh — the query, the sandbox binds and the environment prompt.
956
972
  const directories = [];
@@ -1007,6 +1023,50 @@ export async function createAgentSession(prefs, detected, options = {}) {
1007
1023
  };
1008
1024
  }
1009
1025
  };
1026
+ // File-backed memory and the stored index can contain text written by a
1027
+ // model or its tools. Admit their bounded snapshot after optional recalls
1028
+ // and model selection, without copying it into history.
1029
+ const memoryContextSteps = (filePrompt, storedPrompt) => filePrompt || storedPrompt
1030
+ ? [
1031
+ ({ prepared, contextBudget }) => {
1032
+ // One character per remaining token is conservative relative to the
1033
+ // kernel's estimate and leaves room for response and later recall.
1034
+ const budget = contextBudget
1035
+ ? Math.max(0, Math.floor(contextBudget.remainingTokens) - 100)
1036
+ : Number.POSITIVE_INFINITY;
1037
+ let fileLimit = filePrompt
1038
+ ? Math.max(0, Math.min(filePrompt.length, storedPrompt ? Math.floor((budget - 2) / 2) : budget))
1039
+ : 0;
1040
+ const storedLimit = storedPrompt
1041
+ ? Math.max(0, Math.min(storedPrompt.length, budget - fileLimit - (filePrompt ? 2 : 0)))
1042
+ : 0;
1043
+ if (filePrompt && storedPrompt)
1044
+ fileLimit = Math.max(0, Math.min(filePrompt.length, budget - storedLimit - 2));
1045
+ const block = [
1046
+ filePrompt ? clipRequestContext(filePrompt, fileLimit, 'memory') : null,
1047
+ storedPrompt ? clipRequestContext(storedPrompt, storedLimit, 'memory') : null,
1048
+ ]
1049
+ .filter(Boolean)
1050
+ .join('\n\n');
1051
+ return block
1052
+ ? { context: [prepared.context, block].filter(Boolean).join('\n\n') }
1053
+ : undefined;
1054
+ },
1055
+ ]
1056
+ : [];
1057
+ const extraContextSteps = (prompt) => prompt
1058
+ ? [
1059
+ ({ prepared, contextBudget }) => {
1060
+ const limit = contextBudget
1061
+ ? Math.max(0, Math.floor(contextBudget.remainingTokens) - 100)
1062
+ : Number.POSITIVE_INFINITY;
1063
+ const block = clipRequestContext(prompt, limit, 'context');
1064
+ return block
1065
+ ? { context: [prepared.context, block].filter(Boolean).join('\n\n') }
1066
+ : undefined;
1067
+ },
1068
+ ]
1069
+ : [];
1010
1070
  // Package presence is not tool reachability. The CLI used to probe and
1011
1071
  // report @namzu/computer-use without ever constructing its host or mounting
1012
1072
  // SDK's computer_use definition, so even an installed, healthy package was
@@ -1919,9 +1979,7 @@ export async function createAgentSession(prefs, detected, options = {}) {
1919
1979
  const storedMemory = await storedMemoryPrompt();
1920
1980
  if (storedMemory.notice)
1921
1981
  cliLogger().warn(storedMemory.notice);
1922
- const memoryPrompt = [composeMemoryPrompt(curatedMemory), storedMemory.prompt]
1923
- .filter((part) => Boolean(part))
1924
- .join('\n\n') || null;
1982
+ const curatedMemoryPrompt = composeMemoryPrompt(curatedMemory);
1925
1983
  const environmentPrompt = composeEnvironmentPrompt({
1926
1984
  ...(await readEnvironmentFacts(cwd)),
1927
1985
  additionalDirectories: [...directories],
@@ -1935,7 +1993,6 @@ export async function createAgentSession(prefs, detected, options = {}) {
1935
1993
  NAMZU_DELEGATION_DOCTRINE,
1936
1994
  options.conversationSessions ? CONVERSATION_EVIDENCE_GUIDANCE : undefined,
1937
1995
  environmentPrompt,
1938
- memoryPrompt,
1939
1996
  systemNote,
1940
1997
  turnSkills.overflowNote,
1941
1998
  ]
@@ -2026,6 +2083,7 @@ export async function createAgentSession(prefs, detected, options = {}) {
2026
2083
  ]),
2027
2084
  ...(options.conversationSessions ? [createContextInventoryStep()] : []),
2028
2085
  ...evidenceRecallFor(entry.sessionId),
2086
+ ...memoryContextSteps(curatedMemoryPrompt, storedMemory.prompt),
2029
2087
  ],
2030
2088
  ...(options.compaction?.consolidate
2031
2089
  ? { consolidateInto: memoryStore }
@@ -2242,7 +2300,13 @@ export async function createAgentSession(prefs, detected, options = {}) {
2242
2300
  agentIds: allowedAgentIds,
2243
2301
  currentTaskStore,
2244
2302
  resetTaskStore,
2245
- jobs: () => jobRegistry?.list(jobOwner) ?? [],
2303
+ jobs: () => ownedJobs?.list() ?? [],
2304
+ ...(ownedJobs
2305
+ ? {
2306
+ readJob: (id, fromOffset) => ownedJobs.read(id, fromOffset === undefined ? {} : { fromOffset }),
2307
+ stopJob: (id) => ownedJobs.kill(id),
2308
+ }
2309
+ : {}),
2246
2310
  ...(options.hooks ? { hooks: options.hooks } : {}),
2247
2311
  checkpoints,
2248
2312
  directories: sessionDirectories,
@@ -2419,9 +2483,7 @@ export async function createAgentSession(prefs, detected, options = {}) {
2419
2483
  shed: false,
2420
2484
  };
2421
2485
  }
2422
- const memoryPrompt = [composeMemoryPrompt(curatedMemory), storedMemory.prompt]
2423
- .filter((part) => Boolean(part))
2424
- .join('\n\n') || null;
2486
+ const curatedMemoryPrompt = composeMemoryPrompt(curatedMemory);
2425
2487
  currentOnQuestion = opts?.onQuestion;
2426
2488
  const [environmentFacts, turnSnapshot] = await Promise.all([
2427
2489
  readEnvironmentFacts(cwd),
@@ -2523,7 +2585,7 @@ export async function createAgentSession(prefs, detected, options = {}) {
2523
2585
  for (const contribution of bundle.contributions)
2524
2586
  promptContributions.register(contribution);
2525
2587
  // These are invocation snapshots, not the stable working policy.
2526
- const invocationContext = [environmentPrompt, memoryPrompt, opts?.extraSystem]
2588
+ const invocationContext = [environmentPrompt, opts?.extraSystem]
2527
2589
  .filter((text) => Boolean(text))
2528
2590
  .join('\n\n');
2529
2591
  promptContributions.register({
@@ -2552,7 +2614,6 @@ export async function createAgentSession(prefs, detected, options = {}) {
2552
2614
  ? NAMZU_PLAN_MODE_DOCTRINE
2553
2615
  : undefined,
2554
2616
  residentContext ? undefined : environmentPrompt,
2555
- residentContext ? undefined : memoryPrompt,
2556
2617
  residentContext ? undefined : opts?.extraSystem,
2557
2618
  residentContext ? undefined : opts?.systemNote,
2558
2619
  turnSkills.overflowNote,
@@ -2653,6 +2714,9 @@ export async function createAgentSession(prefs, detected, options = {}) {
2653
2714
  prepareStep: [
2654
2715
  createTaskContextStep(turnTaskStore, turnScope.tenantId),
2655
2716
  ...savedAgentsSteps(turnScope.sessionId),
2717
+ // A host-supplied resident step may select the request model.
2718
+ // Run it before every budgeted recall and memory admission.
2719
+ ...(options.residentEvidenceRecall ? [options.residentEvidenceRecall] : []),
2656
2720
  ...(options.memory?.recall === false
2657
2721
  ? []
2658
2722
  : [
@@ -2664,7 +2728,8 @@ export async function createAgentSession(prefs, detected, options = {}) {
2664
2728
  ]),
2665
2729
  ...(options.conversationSessions ? [createContextInventoryStep()] : []),
2666
2730
  ...evidenceRecallFor(turnScope.sessionId),
2667
- ...(options.residentEvidenceRecall ? [options.residentEvidenceRecall] : []),
2731
+ ...extraContextSteps(opts?.extraContext),
2732
+ ...memoryContextSteps(curatedMemoryPrompt, storedMemory.prompt),
2668
2733
  ],
2669
2734
  taskStore: turnTaskStore,
2670
2735
  systemPrompt,
@@ -3233,6 +3298,7 @@ async function* runTurn({ retainedToolPreviewChars, fileReadTracker, provider, c
3233
3298
  compactionConfig,
3234
3299
  ...(consolidateInto ? { consolidateInto } : {}),
3235
3300
  ...(backgroundJobs ? { backgroundJobs, backgroundJobOwner } : {}),
3301
+ ...(opts?.onJobNoticeDelivered ? { onJobNoticeDelivered: opts.onJobNoticeDelivered } : {}),
3236
3302
  turnConfig: {
3237
3303
  model,
3238
3304
  ...(sandboxProvider ? { sandbox: { workspace: sandboxWorkspace } } : {}),