@code-yeongyu/senpi 2026.9.8 → 2026.9.9-2

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 (185) hide show
  1. package/CHANGELOG.md +43 -3
  2. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  3. package/dist/core/agent-session-runtime.js +2 -0
  4. package/dist/core/agent-session-runtime.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +8 -1
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +33 -0
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/compaction/compaction-execution.d.ts.map +1 -1
  10. package/dist/core/compaction/compaction-execution.js +5 -5
  11. package/dist/core/compaction/compaction-execution.js.map +1 -1
  12. package/dist/core/compaction/compaction-settings.d.ts +2 -0
  13. package/dist/core/compaction/compaction-settings.d.ts.map +1 -1
  14. package/dist/core/compaction/compaction-settings.js.map +1 -1
  15. package/dist/core/compaction/compaction.d.ts +3 -3
  16. package/dist/core/compaction/compaction.d.ts.map +1 -1
  17. package/dist/core/compaction/compaction.js +12 -7
  18. package/dist/core/compaction/compaction.js.map +1 -1
  19. package/dist/core/compaction/stream-watchdog.d.ts +29 -0
  20. package/dist/core/compaction/stream-watchdog.d.ts.map +1 -1
  21. package/dist/core/compaction/stream-watchdog.js +35 -0
  22. package/dist/core/compaction/stream-watchdog.js.map +1 -1
  23. package/dist/core/compaction-settings-access.d.ts +6 -0
  24. package/dist/core/compaction-settings-access.d.ts.map +1 -1
  25. package/dist/core/compaction-settings-access.js.map +1 -1
  26. package/dist/core/compaction-settings-resolver.d.ts +2 -0
  27. package/dist/core/compaction-settings-resolver.d.ts.map +1 -1
  28. package/dist/core/compaction-settings-resolver.js +5 -0
  29. package/dist/core/compaction-settings-resolver.js.map +1 -1
  30. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
  31. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +4 -1
  32. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  33. package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts +1 -1
  34. package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/compaction/model-usability-budget.js +23 -3
  36. package/dist/core/extensions/builtin/compaction/model-usability-budget.js.map +1 -1
  37. package/dist/core/extensions/builtin/compaction/resume-admission.d.ts +7 -0
  38. package/dist/core/extensions/builtin/compaction/resume-admission.d.ts.map +1 -0
  39. package/dist/core/extensions/builtin/compaction/resume-admission.js +7 -0
  40. package/dist/core/extensions/builtin/compaction/resume-admission.js.map +1 -0
  41. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts +2 -0
  42. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/compaction/speculative-summary.js +5 -2
  44. package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -1
  45. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/compaction/speculative.js +9 -3
  47. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  48. package/dist/core/extensions/builtin/compaction/summarization-retry.d.ts +10 -4
  49. package/dist/core/extensions/builtin/compaction/summarization-retry.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/compaction/summarization-retry.js +14 -5
  51. package/dist/core/extensions/builtin/compaction/summarization-retry.js.map +1 -1
  52. package/dist/core/extensions/builtin/imagegen/params.d.ts +36 -0
  53. package/dist/core/extensions/builtin/imagegen/params.d.ts.map +1 -0
  54. package/dist/core/extensions/builtin/imagegen/params.js +55 -0
  55. package/dist/core/extensions/builtin/imagegen/params.js.map +1 -0
  56. package/dist/core/extensions/builtin/imagegen/reference-images.d.ts +11 -0
  57. package/dist/core/extensions/builtin/imagegen/reference-images.d.ts.map +1 -0
  58. package/dist/core/extensions/builtin/imagegen/reference-images.js +55 -0
  59. package/dist/core/extensions/builtin/imagegen/reference-images.js.map +1 -0
  60. package/dist/core/extensions/builtin/imagegen/skill/SKILL.md +47 -4
  61. package/dist/core/extensions/builtin/imagegen/tool.d.ts +10 -19
  62. package/dist/core/extensions/builtin/imagegen/tool.d.ts.map +1 -1
  63. package/dist/core/extensions/builtin/imagegen/tool.js +21 -45
  64. package/dist/core/extensions/builtin/imagegen/tool.js.map +1 -1
  65. package/dist/core/extensions/loader.d.ts +2 -1
  66. package/dist/core/extensions/loader.d.ts.map +1 -1
  67. package/dist/core/extensions/loader.js +17 -8
  68. package/dist/core/extensions/loader.js.map +1 -1
  69. package/dist/core/extensions/types.d.ts +5 -0
  70. package/dist/core/extensions/types.d.ts.map +1 -1
  71. package/dist/core/extensions/types.js.map +1 -1
  72. package/dist/core/resource-loader.d.ts +2 -0
  73. package/dist/core/resource-loader.d.ts.map +1 -1
  74. package/dist/core/resource-loader.js +11 -7
  75. package/dist/core/resource-loader.js.map +1 -1
  76. package/dist/core/sdk.d.ts.map +1 -1
  77. package/dist/core/sdk.js +13 -1
  78. package/dist/core/sdk.js.map +1 -1
  79. package/dist/core/session-manager.d.ts.map +1 -1
  80. package/dist/core/session-manager.js +11 -1
  81. package/dist/core/session-manager.js.map +1 -1
  82. package/dist/core/session-write-reservation.d.ts +4 -0
  83. package/dist/core/session-write-reservation.d.ts.map +1 -0
  84. package/dist/core/session-write-reservation.js +12 -0
  85. package/dist/core/session-write-reservation.js.map +1 -0
  86. package/dist/core/tools/read-classifiers.d.ts +17 -0
  87. package/dist/core/tools/read-classifiers.d.ts.map +1 -0
  88. package/dist/core/tools/read-classifiers.js +26 -0
  89. package/dist/core/tools/read-classifiers.js.map +1 -0
  90. package/dist/core/tools/read.d.ts +5 -1
  91. package/dist/core/tools/read.d.ts.map +1 -1
  92. package/dist/core/tools/read.js +21 -1
  93. package/dist/core/tools/read.js.map +1 -1
  94. package/dist/index.d.ts +1 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +1 -0
  97. package/dist/index.js.map +1 -1
  98. package/dist/main.d.ts +14 -0
  99. package/dist/main.d.ts.map +1 -1
  100. package/dist/main.js +166 -147
  101. package/dist/main.js.map +1 -1
  102. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  103. package/dist/modes/interactive/interactive-mode.js +3 -0
  104. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  105. package/dist/modes/rpc/connection-handler.d.ts +2 -0
  106. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  107. package/dist/modes/rpc/connection-handler.js +1 -1
  108. package/dist/modes/rpc/connection-handler.js.map +1 -1
  109. package/dist/modes/rpc/multi-session-host.d.ts +2 -0
  110. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  111. package/dist/modes/rpc/multi-session-host.js +18 -8
  112. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  113. package/dist/modes/rpc/session-binding.d.ts.map +1 -1
  114. package/dist/modes/rpc/session-binding.js +3 -0
  115. package/dist/modes/rpc/session-binding.js.map +1 -1
  116. package/dist/modes/rpc/session-command-router.d.ts +1 -1
  117. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  118. package/dist/modes/rpc/session-command-router.js +57 -25
  119. package/dist/modes/rpc/session-command-router.js.map +1 -1
  120. package/dist/modes/rpc/session-event-writer.d.ts +23 -1
  121. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  122. package/dist/modes/rpc/session-event-writer.js +108 -1
  123. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  124. package/dist/modes/rpc/session-registry.d.ts +4 -2
  125. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  126. package/dist/modes/rpc/session-registry.js +1 -1
  127. package/dist/modes/rpc/session-registry.js.map +1 -1
  128. package/dist/modes/rpc/session-worker-client.d.ts +47 -0
  129. package/dist/modes/rpc/session-worker-client.d.ts.map +1 -0
  130. package/dist/modes/rpc/session-worker-client.js +226 -0
  131. package/dist/modes/rpc/session-worker-client.js.map +1 -0
  132. package/dist/modes/rpc/session-worker-protocol.d.ts +103 -0
  133. package/dist/modes/rpc/session-worker-protocol.d.ts.map +1 -0
  134. package/dist/modes/rpc/session-worker-protocol.js +12 -0
  135. package/dist/modes/rpc/session-worker-protocol.js.map +1 -0
  136. package/dist/modes/rpc/session-worker-requests.d.ts +24 -0
  137. package/dist/modes/rpc/session-worker-requests.d.ts.map +1 -0
  138. package/dist/modes/rpc/session-worker-requests.js +71 -0
  139. package/dist/modes/rpc/session-worker-requests.js.map +1 -0
  140. package/dist/modes/rpc/session-worker.d.ts +2 -0
  141. package/dist/modes/rpc/session-worker.d.ts.map +1 -0
  142. package/dist/modes/rpc/session-worker.js +229 -0
  143. package/dist/modes/rpc/session-worker.js.map +1 -0
  144. package/dist/modes/rpc/worker-session-registry.d.ts +37 -0
  145. package/dist/modes/rpc/worker-session-registry.d.ts.map +1 -0
  146. package/dist/modes/rpc/worker-session-registry.js +207 -0
  147. package/dist/modes/rpc/worker-session-registry.js.map +1 -0
  148. package/docs/rpc.md +70 -9
  149. package/docs/settings.md +1 -0
  150. package/docs/skills.md +1 -1
  151. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +24 -0
  152. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  153. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  154. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +23 -5
  155. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  156. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.d.ts +4 -0
  157. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.d.ts.map +1 -0
  158. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.js +11 -0
  159. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.js.map +1 -0
  160. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.d.ts +25 -0
  161. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.d.ts.map +1 -0
  162. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.js +58 -0
  163. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.js.map +1 -0
  164. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts +3 -6
  165. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts.map +1 -1
  166. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js +15 -33
  167. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js.map +1 -1
  168. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +61 -1
  169. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  170. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +61 -1
  171. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  172. package/node_modules/@earendil-works/pi-ai/dist/images.d.ts +1 -0
  173. package/node_modules/@earendil-works/pi-ai/dist/images.d.ts.map +1 -1
  174. package/node_modules/@earendil-works/pi-ai/dist/images.js +1 -0
  175. package/node_modules/@earendil-works/pi-ai/dist/images.js.map +1 -1
  176. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  177. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  178. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  179. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  180. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  181. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  182. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  183. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  184. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  185. package/package.json +7 -7
package/dist/main.js CHANGED
@@ -533,6 +533,156 @@ export function applyGrokNeoThemeFallback(settingsManager) {
533
533
  setTheme(theme);
534
534
  };
535
535
  }
536
+ /** Fixed launch data is cloneable; UI callbacks and extension factories stay in their isolate. */
537
+ export function createCliRuntimeFactory(configuration, local = {}) {
538
+ const { parsed, cwd, agentDir, appMode } = configuration;
539
+ const extensionFactories = local.extensionFactories ?? builtInExtensions;
540
+ const startupSettingsManager = local.startupSettingsManager ?? SettingsManager.create(cwd, agentDir);
541
+ const startupLoadingIndicator = local.startupLoadingIndicator ??
542
+ createStartupLoadingIndicator({
543
+ writer: () => { },
544
+ isTTY: false,
545
+ label: `Loading ${APP_NAME}`,
546
+ });
547
+ const trustStore = new ProjectTrustStore(agentDir);
548
+ const projectTrustByCwd = new Map();
549
+ const trustPromptMode = parsed.help || parsed.listModels !== undefined || parsed.listTips ? "print" : toProjectTrustMode(appMode);
550
+ const resolvedExtensionPaths = resolveCliPaths(cwd, parsed.extensions);
551
+ const resolvedSkillPaths = resolveCliPaths(cwd, parsed.skills);
552
+ const resolvedPromptTemplatePaths = resolveCliPaths(cwd, parsed.promptTemplates);
553
+ const resolvedThemePaths = resolveCliPaths(cwd, parsed.themes);
554
+ return async ({ cwd, agentDir, sessionManager, sessionStartEvent, projectTrustContext, launchProfile }) => {
555
+ const isInitialRuntime = sessionStartEvent === undefined;
556
+ const projectTrustDiagnostics = [];
557
+ const cachedProjectTrust = projectTrustByCwd.get(cwd);
558
+ const hasTrustRequiringResources = hasTrustRequiringProjectResources(cwd);
559
+ const shouldResolveProjectTrust = parsed.projectTrustOverride === undefined && cachedProjectTrust === undefined && hasTrustRequiringResources;
560
+ const projectTrusted = shouldResolveProjectTrust
561
+ ? false
562
+ : (cachedProjectTrust ??
563
+ parsed.projectTrustOverride ??
564
+ (!hasTrustRequiringResources || trustStore.get(cwd) === true));
565
+ const runtimeSettingsManager = SettingsManager.create(cwd, agentDir, { projectTrusted });
566
+ const services = await createAgentSessionServices({
567
+ cwd,
568
+ agentDir,
569
+ settingsManager: runtimeSettingsManager,
570
+ modelRuntimeSignal: AbortSignal.timeout(15_000),
571
+ extensionFlagValues: parsed.unknownFlags,
572
+ resourceLoaderReloadOptions: shouldResolveProjectTrust
573
+ ? {
574
+ resolveProjectTrust: async ({ extensionsResult }) => {
575
+ const trusted = await resolveProjectTrusted({
576
+ cwd,
577
+ trustStore,
578
+ trustOverride: parsed.projectTrustOverride,
579
+ defaultProjectTrust: startupSettingsManager.getDefaultProjectTrust(),
580
+ extensionsResult,
581
+ projectTrustContext: projectTrustContext ??
582
+ pauseIndicatorDuringPrompts(createProjectTrustContext({
583
+ cwd,
584
+ mode: isInitialRuntime ? trustPromptMode : toProjectTrustMode(appMode),
585
+ settingsManager: startupSettingsManager,
586
+ hasUI: isInitialRuntime && trustPromptMode === "interactive",
587
+ }), startupLoadingIndicator),
588
+ onExtensionError: (message) => projectTrustDiagnostics.push({ type: "warning", message }),
589
+ });
590
+ projectTrustByCwd.set(cwd, trusted);
591
+ return trusted;
592
+ },
593
+ }
594
+ : undefined,
595
+ resourceLoaderOptions: {
596
+ sharedHostEnabled: shouldJoinSharedHost(appMode, {
597
+ enableEnv: isTruthyEnvFlag(envValue("ENABLE_SHARED_HOST")),
598
+ settingEnabled: runtimeSettingsManager.getExperimentalSharedHost(),
599
+ }),
600
+ additionalExtensionPaths: resolvedExtensionPaths,
601
+ additionalSkillPaths: resolvedSkillPaths,
602
+ additionalPromptTemplatePaths: resolvedPromptTemplatePaths,
603
+ additionalThemePaths: resolvedThemePaths,
604
+ noExtensions: parsed.noExtensions,
605
+ noSkills: parsed.noSkills,
606
+ noPromptTemplates: parsed.noPromptTemplates,
607
+ noThemes: parsed.noThemes,
608
+ noContextFiles: parsed.noContextFiles,
609
+ systemPrompt: parsed.systemPrompt,
610
+ appendSystemPrompt: parsed.appendSystemPrompt,
611
+ extensionFactories,
612
+ },
613
+ });
614
+ const { settingsManager, modelRuntime, resourceLoader } = services;
615
+ const diagnostics = [
616
+ ...projectTrustDiagnostics,
617
+ ...services.diagnostics,
618
+ ...collectSettingsDiagnostics(settingsManager, "runtime creation"),
619
+ ...collectExtensionLoadDiagnostics(resourceLoader.getExtensions().errors),
620
+ ];
621
+ const modelPatterns = getModelNarrowingPatterns({
622
+ cliPatterns: parsed.models,
623
+ legacyEnabledPatterns: settingsManager.getEnabledModels(),
624
+ });
625
+ const scopedModels = modelPatterns && modelPatterns.length > 0
626
+ ? await resolveModelScope(modelPatterns, modelRuntime, { signal: AbortSignal.timeout(15_000) })
627
+ : [];
628
+ // Multi-session opens carry their per-session startup choices here rather
629
+ // than through process argv. This deliberately feeds the same resolver as
630
+ // --provider/--model/--thinking, preserving classic flag semantics.
631
+ const runtimeParsed = launchProfile === undefined
632
+ ? parsed
633
+ : {
634
+ ...parsed,
635
+ ...(launchProfile.creationModel === undefined
636
+ ? {}
637
+ : {
638
+ provider: launchProfile.creationModel.provider,
639
+ model: launchProfile.creationModel.modelId,
640
+ }),
641
+ ...(launchProfile.initialThinkingLevel === undefined
642
+ ? {}
643
+ : { thinking: launchProfile.initialThinkingLevel }),
644
+ };
645
+ const { options: sessionOptions, cliThinkingFromModel, diagnostics: sessionOptionDiagnostics, } = buildSessionOptions(runtimeParsed, scopedModels, sessionManager.hasContextMessages(), modelRuntime, settingsManager);
646
+ diagnostics.push(...sessionOptionDiagnostics);
647
+ if (parsed.apiKey) {
648
+ if (!sessionOptions.model) {
649
+ diagnostics.push({
650
+ type: "error",
651
+ message: "--api-key requires a model to be specified via --model, --provider/--model, or --models",
652
+ });
653
+ }
654
+ else {
655
+ await modelRuntime.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);
656
+ }
657
+ }
658
+ if (isInitialRuntime) {
659
+ startupLoadingIndicator.setPhase("opening session");
660
+ }
661
+ const created = await createAgentSessionFromServices({
662
+ services,
663
+ sessionManager,
664
+ sessionStartEvent,
665
+ model: sessionOptions.model,
666
+ thinkingLevel: sessionOptions.thinkingLevel,
667
+ thinkingSelection: sessionOptions.thinkingSelection,
668
+ scopedModels: sessionOptions.scopedModels,
669
+ tools: sessionOptions.tools,
670
+ excludeTools: sessionOptions.excludeTools,
671
+ noTools: sessionOptions.noTools,
672
+ customTools: sessionOptions.customTools,
673
+ autoTitleSessions: resolveAutoTitleSessions(appMode, parsed, sessionManager.hasContextMessages(), parseClientCapabilities(envValue("RPC_CLIENT_CAPABILITIES"))),
674
+ });
675
+ const cliThinkingOverride = runtimeParsed.thinking !== undefined || cliThinkingFromModel;
676
+ if (created.session.model && cliThinkingOverride) {
677
+ created.session.setThinkingLevel(created.session.thinkingLevel);
678
+ }
679
+ return {
680
+ ...created,
681
+ services,
682
+ diagnostics,
683
+ };
684
+ };
685
+ }
536
686
  export async function main(args, options) {
537
687
  resetTimings();
538
688
  const extensionFactories = [...builtInExtensions, ...(options?.extensionFactories ?? [])];
@@ -691,6 +841,21 @@ export async function main(args, options) {
691
841
  if (appMode === "interactive" && parsed.useTheme !== undefined) {
692
842
  startupSettingsManager.applyOverrides({ theme: parsed.useTheme });
693
843
  }
844
+ if (appMode === "rpc" && parsed.multiSession) {
845
+ if (options?.extensionFactories?.length)
846
+ throw new Error("Shared RPC workers require file-backed extensions; inline factories cannot cross isolates");
847
+ const workerConfiguration = { parsed, cwd, agentDir, appMode };
848
+ printTimings();
849
+ await runMultiSessionHost({
850
+ agentDir,
851
+ createRuntime: createCliRuntimeFactory(workerConfiguration),
852
+ workerConfiguration,
853
+ cwd,
854
+ creationModel: parsed.provider && parsed.model ? { provider: parsed.provider, modelId: parsed.model } : undefined,
855
+ initialThinkingLevel: parsed.thinking,
856
+ listen: parsed.listen,
857
+ });
858
+ }
694
859
  // Decide the final runtime cwd before creating cwd-bound runtime services.
695
860
  // --session and --resume may select a session from another project, so project-local
696
861
  // settings, resources, provider registrations, and models must be resolved only after
@@ -724,13 +889,10 @@ export async function main(args, options) {
724
889
  sessionManager.appendSessionInfo(name);
725
890
  }
726
891
  time("createSessionManager");
727
- const trustStore = new ProjectTrustStore(agentDir);
728
892
  const sessionCwd = sessionManager.getCwd();
729
893
  const autoTrustOnReloadCwd = parsed.projectTrustOverride === undefined && !hasTrustRequiringProjectResources(sessionCwd)
730
894
  ? sessionCwd
731
895
  : undefined;
732
- const trustPromptMode = parsed.help || parsed.listModels !== undefined || parsed.listTips ? "print" : toProjectTrustMode(appMode);
733
- const projectTrustByCwd = new Map();
734
896
  // Immediate feedback while the heavy runtime (extensions, models, trust) is
735
897
  // created; without it the terminal stays blank and looks stuck (codex-style
736
898
  // UI-first startup). Stopped before any other surface writes to stdout.
@@ -747,151 +909,8 @@ export async function main(args, options) {
747
909
  startupLoadingIndicator.start();
748
910
  startupLoadingIndicator.setPhase("extensions & models");
749
911
  }
750
- const createRuntime = async ({ cwd, agentDir, sessionManager, sessionStartEvent, projectTrustContext, launchProfile, }) => {
751
- const isInitialRuntime = sessionStartEvent === undefined;
752
- const projectTrustDiagnostics = [];
753
- const cachedProjectTrust = projectTrustByCwd.get(cwd);
754
- const hasTrustRequiringResources = hasTrustRequiringProjectResources(cwd);
755
- const shouldResolveProjectTrust = parsed.projectTrustOverride === undefined && cachedProjectTrust === undefined && hasTrustRequiringResources;
756
- const projectTrusted = shouldResolveProjectTrust
757
- ? false
758
- : (cachedProjectTrust ??
759
- parsed.projectTrustOverride ??
760
- (!hasTrustRequiringResources || trustStore.get(cwd) === true));
761
- const runtimeSettingsManager = SettingsManager.create(cwd, agentDir, { projectTrusted });
762
- const services = await createAgentSessionServices({
763
- cwd,
764
- agentDir,
765
- settingsManager: runtimeSettingsManager,
766
- modelRuntimeSignal: AbortSignal.timeout(15_000),
767
- extensionFlagValues: parsed.unknownFlags,
768
- resourceLoaderReloadOptions: shouldResolveProjectTrust
769
- ? {
770
- resolveProjectTrust: async ({ extensionsResult }) => {
771
- const trusted = await resolveProjectTrusted({
772
- cwd,
773
- trustStore,
774
- trustOverride: parsed.projectTrustOverride,
775
- defaultProjectTrust: startupSettingsManager.getDefaultProjectTrust(),
776
- extensionsResult,
777
- projectTrustContext: projectTrustContext ??
778
- pauseIndicatorDuringPrompts(createProjectTrustContext({
779
- cwd,
780
- mode: isInitialRuntime ? trustPromptMode : toProjectTrustMode(appMode),
781
- settingsManager: startupSettingsManager,
782
- hasUI: isInitialRuntime && trustPromptMode === "interactive",
783
- }), startupLoadingIndicator),
784
- onExtensionError: (message) => projectTrustDiagnostics.push({ type: "warning", message }),
785
- });
786
- projectTrustByCwd.set(cwd, trusted);
787
- return trusted;
788
- },
789
- }
790
- : undefined,
791
- resourceLoaderOptions: {
792
- additionalExtensionPaths: resolvedExtensionPaths,
793
- additionalSkillPaths: resolvedSkillPaths,
794
- additionalPromptTemplatePaths: resolvedPromptTemplatePaths,
795
- additionalThemePaths: resolvedThemePaths,
796
- noExtensions: parsed.noExtensions,
797
- noSkills: parsed.noSkills,
798
- noPromptTemplates: parsed.noPromptTemplates,
799
- noThemes: parsed.noThemes,
800
- noContextFiles: parsed.noContextFiles,
801
- systemPrompt: parsed.systemPrompt,
802
- appendSystemPrompt: parsed.appendSystemPrompt,
803
- extensionFactories,
804
- },
805
- });
806
- const { settingsManager, modelRuntime, resourceLoader } = services;
807
- const diagnostics = [
808
- ...projectTrustDiagnostics,
809
- ...services.diagnostics,
810
- ...collectSettingsDiagnostics(settingsManager, "runtime creation"),
811
- ...collectExtensionLoadDiagnostics(resourceLoader.getExtensions().errors),
812
- ];
813
- const modelPatterns = getModelNarrowingPatterns({
814
- cliPatterns: parsed.models,
815
- legacyEnabledPatterns: settingsManager.getEnabledModels(),
816
- });
817
- const scopedModels = modelPatterns && modelPatterns.length > 0
818
- ? await resolveModelScope(modelPatterns, modelRuntime, { signal: AbortSignal.timeout(15_000) })
819
- : [];
820
- // Multi-session opens carry their per-session startup choices here rather
821
- // than through process argv. This deliberately feeds the same resolver as
822
- // --provider/--model/--thinking, preserving classic flag semantics.
823
- const runtimeParsed = launchProfile === undefined
824
- ? parsed
825
- : {
826
- ...parsed,
827
- ...(launchProfile.creationModel === undefined
828
- ? {}
829
- : {
830
- provider: launchProfile.creationModel.provider,
831
- model: launchProfile.creationModel.modelId,
832
- }),
833
- ...(launchProfile.initialThinkingLevel === undefined
834
- ? {}
835
- : { thinking: launchProfile.initialThinkingLevel }),
836
- };
837
- const { options: sessionOptions, cliThinkingFromModel, diagnostics: sessionOptionDiagnostics, } = buildSessionOptions(runtimeParsed, scopedModels, sessionManager.hasContextMessages(), modelRuntime, settingsManager);
838
- diagnostics.push(...sessionOptionDiagnostics);
839
- if (parsed.apiKey) {
840
- if (!sessionOptions.model) {
841
- diagnostics.push({
842
- type: "error",
843
- message: "--api-key requires a model to be specified via --model, --provider/--model, or --models",
844
- });
845
- }
846
- else {
847
- await modelRuntime.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);
848
- }
849
- }
850
- if (isInitialRuntime) {
851
- startupLoadingIndicator.setPhase("opening session");
852
- }
853
- const created = await createAgentSessionFromServices({
854
- services,
855
- sessionManager,
856
- sessionStartEvent,
857
- model: sessionOptions.model,
858
- thinkingLevel: sessionOptions.thinkingLevel,
859
- thinkingSelection: sessionOptions.thinkingSelection,
860
- scopedModels: sessionOptions.scopedModels,
861
- tools: sessionOptions.tools,
862
- excludeTools: sessionOptions.excludeTools,
863
- noTools: sessionOptions.noTools,
864
- customTools: sessionOptions.customTools,
865
- autoTitleSessions: resolveAutoTitleSessions(appMode, parsed, sessionManager.hasContextMessages(), parseClientCapabilities(envValue("RPC_CLIENT_CAPABILITIES"))),
866
- });
867
- const cliThinkingOverride = runtimeParsed.thinking !== undefined || cliThinkingFromModel;
868
- if (created.session.model && cliThinkingOverride) {
869
- created.session.setThinkingLevel(created.session.thinkingLevel);
870
- }
871
- return {
872
- ...created,
873
- services,
874
- diagnostics,
875
- };
876
- };
912
+ const createRuntime = createCliRuntimeFactory({ parsed, cwd, agentDir, appMode }, { extensionFactories, startupSettingsManager, startupLoadingIndicator });
877
913
  time("createRuntime");
878
- if (appMode === "rpc" && parsed.multiSession) {
879
- // The multi-session host never returns, so the initTheme() call further down
880
- // is unreachable on this path. Extensions loaded per open_session (and any
881
- // tool render helper) read the theme proxy and would otherwise crash with
882
- // "Theme not initialized. Call initTheme() first." (surfaced in embedders
883
- // like T3 Code as transcript errors).
884
- initTheme(startupSettingsManager.getTheme(), false);
885
- printTimings();
886
- await runMultiSessionHost({
887
- agentDir,
888
- createRuntime,
889
- cwd,
890
- creationModel: parsed.provider && parsed.model ? { provider: parsed.provider, modelId: parsed.model } : undefined,
891
- initialThinkingLevel: parsed.thinking,
892
- listen: parsed.listen,
893
- });
894
- }
895
914
  const runtime = await createAgentSessionRuntime(createRuntime, {
896
915
  cwd: sessionManager.getCwd(),
897
916
  agentDir,