sneakoscope 7.3.0 → 7.6.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 (283) hide show
  1. package/README.md +129 -10
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/cli/codex-app-command.js +1 -1
  5. package/dist/cli/command-manifest-lite.js +4 -1
  6. package/dist/cli/command-registry.js +2 -0
  7. package/dist/cli/install-helpers-codex-lb-chain.js +42 -0
  8. package/dist/cli/install-helpers-codex-lb-config.js +114 -9
  9. package/dist/cli/install-helpers-install-support.js +6 -16
  10. package/dist/cli/install-helpers.js +788 -600
  11. package/dist/cli/router.js +30 -2
  12. package/dist/commands/codex-app.js +37 -1
  13. package/dist/commands/codex-lb.js +491 -300
  14. package/dist/config/skills-manifest.json +57 -71
  15. package/dist/core/align/align-route.js +127 -0
  16. package/dist/core/codex-app/codex-app-fast-ui-repair.js +8 -4
  17. package/dist/core/codex-app/codex-app-restart.js +83 -0
  18. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +8 -4
  19. package/dist/core/codex-app/desktop-routing-snapshot.js +1 -1
  20. package/dist/core/codex-app/menubar/constants.js +5 -0
  21. package/dist/core/codex-app/menubar/generation-transaction-journal.js +1 -3
  22. package/dist/core/codex-app/menubar/installer.js +18 -0
  23. package/dist/core/codex-app/multi-provider-router.js +22 -10
  24. package/dist/core/codex-app/openrouter-activate.js +26 -1
  25. package/dist/core/codex-app.js +118 -26
  26. package/dist/core/codex-control/codex-app-server-runtime-env.js +86 -0
  27. package/dist/core/codex-control/codex-app-server-v2-client.js +78 -8
  28. package/dist/core/codex-control/codex-task-runner.js +2 -2
  29. package/dist/core/codex-lb/capability-runner.js +204 -0
  30. package/dist/core/codex-lb/capability-types.js +1 -0
  31. package/dist/core/codex-lb/codex-lb-env.js +9 -13
  32. package/dist/core/codex-lb/codex-lb-setup.js +45 -8
  33. package/dist/core/codex-lb/codex-lb-tool-catalog.js +52 -74
  34. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +1 -1
  35. package/dist/core/codex-lb/desktop-auth-invariant.js +185 -0
  36. package/dist/core/codex-lb/desktop-bridge/client.js +34 -0
  37. package/dist/core/codex-lb/desktop-bridge/header-policy.js +106 -0
  38. package/dist/core/codex-lb/desktop-bridge/http-forward.js +101 -0
  39. package/dist/core/codex-lb/desktop-bridge/index.js +10 -0
  40. package/dist/core/codex-lb/desktop-bridge/launchd.js +81 -0
  41. package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +27 -0
  42. package/dist/core/codex-lb/desktop-bridge/security.js +274 -0
  43. package/dist/core/codex-lb/desktop-bridge/server.js +179 -0
  44. package/dist/core/codex-lb/desktop-bridge/state.js +119 -0
  45. package/dist/core/codex-lb/desktop-bridge/types.js +16 -0
  46. package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +151 -0
  47. package/dist/core/codex-lb/desktop-center-credentials.js +189 -0
  48. package/dist/core/codex-lb/desktop-controller.js +1410 -0
  49. package/dist/core/codex-lb/desktop-mode.js +32 -0
  50. package/dist/core/codex-lb/desktop-real-evidence.js +168 -0
  51. package/dist/core/codex-lb/desktop-service.js +613 -0
  52. package/dist/core/codex-lb/legacy-migration.js +575 -0
  53. package/dist/core/codex-lb/migration-receipt.js +246 -0
  54. package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +60 -0
  55. package/dist/core/codex-lb/probes/bridge-probe.js +75 -0
  56. package/dist/core/codex-lb/probes/catalog-probe.js +128 -0
  57. package/dist/core/codex-lb/probes/computer-use-probe.js +50 -0
  58. package/dist/core/codex-lb/probes/image-generation-probe.js +47 -0
  59. package/dist/core/codex-lb/probes/probe-evidence.js +39 -0
  60. package/dist/core/codex-lb/probes/voice-realtime-probe.js +44 -0
  61. package/dist/core/codex-lb/trusted-deep-evidence.js +403 -0
  62. package/dist/core/codex-native/core-skill-manifest.js +22 -6
  63. package/dist/core/codex-runtime/codex-desktop-config-policy.js +2 -1
  64. package/dist/core/commands/align-command.js +220 -0
  65. package/dist/core/commands/image-ux-review-command.js +280 -68
  66. package/dist/core/commands/naruto-command.js +257 -8
  67. package/dist/core/commands/ppt-command.js +2 -2
  68. package/dist/core/commands/telegram-command.js +402 -34
  69. package/dist/core/commands/triwiki-command.js +11 -1
  70. package/dist/core/commands/triwiki-graph-command.js +160 -0
  71. package/dist/core/commands/wiki-command.js +100 -20
  72. package/dist/core/doctor/skill-legacy-surface.js +1 -3
  73. package/dist/core/errors/message.js +3 -0
  74. package/dist/core/evidence/evidence-freshness.js +14 -0
  75. package/dist/core/feature-fixtures.js +9 -1
  76. package/dist/core/feature-registry.js +5 -3
  77. package/dist/core/fsx.js +7 -3
  78. package/dist/core/hooks-runtime/codex-commit-hooks-selftest.js +82 -0
  79. package/dist/core/hooks-runtime/context-graph-freshness-preflight.js +113 -0
  80. package/dist/core/hooks-runtime/hook-context.js +15 -2
  81. package/dist/core/hooks-runtime/managed-skill-generation-heal.js +46 -0
  82. package/dist/core/hooks-runtime/naruto-terminal-finalization.js +1 -0
  83. package/dist/core/hooks-runtime/official-subagent-lifecycle.js +1 -1
  84. package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
  85. package/dist/core/hooks-runtime.js +33 -89
  86. package/dist/core/image-ux-review/callout-extraction.js +6 -0
  87. package/dist/core/image-ux-review/imagegen-adapter.js +64 -23
  88. package/dist/core/image-ux-review/real-callout-extractor.js +1 -0
  89. package/dist/core/image-ux-review.js +230 -12
  90. package/dist/core/imagegen/codex-lb-imagegen-target.js +21 -7
  91. package/dist/core/imagegen/imagegen-capability.js +10 -4
  92. package/dist/core/imagegen/require-imagegen.js +29 -5
  93. package/dist/core/init/skills.js +25 -13
  94. package/dist/core/init.js +1 -1
  95. package/dist/core/install/installed-package-smoke.js +157 -4
  96. package/dist/core/managed-assets/managed-assets-manifest.js +2 -1
  97. package/dist/core/managed-path-safety.js +8 -10
  98. package/dist/core/mcp-config/backup.js +2 -4
  99. package/dist/core/mcp-config/config-reader.js +2 -4
  100. package/dist/core/mcp-config/scope.js +3 -5
  101. package/dist/core/naruto/context-graph-advisor-scope.js +242 -0
  102. package/dist/core/naruto/context-graph-advisor.js +0 -0
  103. package/dist/core/perf/release-latency-slo.js +12 -6
  104. package/dist/core/pipeline-internals/runtime-core.js +78 -0
  105. package/dist/core/pipeline-internals/runtime-gates.js +5 -2
  106. package/dist/core/policy/latest-version-guidance.js +113 -0
  107. package/dist/core/ppt.js +8 -8
  108. package/dist/core/preflight/parallel-preflight-engine.js +1 -1
  109. package/dist/core/proof/auto-finalize.js +98 -6
  110. package/dist/core/proof/route-proof-gate.js +12 -1
  111. package/dist/core/proof/route-proof-policy.js +8 -8
  112. package/dist/core/release/gate-manifest.js +32 -1
  113. package/dist/core/release/npm-stage-contract.js +21 -0
  114. package/dist/core/release/package-size-budget.js +2 -2
  115. package/dist/core/release/release-gate-contract.js +5 -0
  116. package/dist/core/release/release-proof-io.js +1 -3
  117. package/dist/core/release/release-real-contract.js +5 -4
  118. package/dist/core/release/release-stamp-proof.js +1 -3
  119. package/dist/core/release/stage-publish.js +27 -0
  120. package/dist/core/remote/audit-idempotency.js +50 -18
  121. package/dist/core/remote/codex-public-activity.js +283 -0
  122. package/dist/core/remote/index.js +1 -0
  123. package/dist/core/remote/ssh-worker-client.js +4 -1
  124. package/dist/core/remote/worker.js +206 -27
  125. package/dist/core/research/research-adversarial-review.js +1 -3
  126. package/dist/core/research/research-claim-synthesizer.js +1 -3
  127. package/dist/core/research/research-falsification-runner.js +1 -3
  128. package/dist/core/research/research-source-evidence.js +1 -3
  129. package/dist/core/responses-stream.js +65 -19
  130. package/dist/core/routes/constants.js +1 -1
  131. package/dist/core/routes/design-policy.js +7 -2
  132. package/dist/core/routes/dollar-manifest-lite.js +2 -4
  133. package/dist/core/routes/evidence.js +1 -1
  134. package/dist/core/routes.js +30 -10
  135. package/dist/core/safety/command-contract/contracts.js +2 -0
  136. package/dist/core/safety/command-contract/types.js +1 -1
  137. package/dist/core/search/context-graph-seeds.js +205 -0
  138. package/dist/core/search/context.js +0 -0
  139. package/dist/core/search/provider.js +2 -2
  140. package/dist/core/secret-redaction.js +6 -0
  141. package/dist/core/subagents/naruto-help-contract.js +2 -1
  142. package/dist/core/subagents/naruto-host-credentials.js +161 -0
  143. package/dist/core/subagents/official-subagent-preparation.js +4 -1
  144. package/dist/core/subagents/official-subagent-prompt.js +44 -2
  145. package/dist/core/subagents/official-subagent-runner.js +26 -8
  146. package/dist/core/subagents/triwiki-attention.js +135 -123
  147. package/dist/core/telegram/bot-api.js +85 -10
  148. package/dist/core/telegram/center-snapshot.js +718 -0
  149. package/dist/core/telegram/config.js +158 -31
  150. package/dist/core/telegram/hub.js +288 -33
  151. package/dist/core/telegram/index.js +2 -0
  152. package/dist/core/telegram/ingress-spool.js +419 -0
  153. package/dist/core/telegram/ledgers.js +188 -29
  154. package/dist/core/telegram/messages.js +26 -6
  155. package/dist/core/telegram/owner-lock.js +10 -7
  156. package/dist/core/telegram/runtime-projection.js +38 -3
  157. package/dist/core/telegram/runtime.js +298 -63
  158. package/dist/core/telegram/service.js +137 -8
  159. package/dist/core/telegram/setup.js +291 -73
  160. package/dist/core/text/strings.js +3 -0
  161. package/dist/core/triwiki/code-pack.js +12 -120
  162. package/dist/core/triwiki/context-graph/compiler/cache-key.js +277 -0
  163. package/dist/core/triwiki/context-graph/compiler/extract.js +104 -0
  164. package/dist/core/triwiki/context-graph/compiler/freshness.js +108 -0
  165. package/dist/core/triwiki/context-graph/compiler/index.js +237 -0
  166. package/dist/core/triwiki/context-graph/compiler/merge.js +0 -0
  167. package/dist/core/triwiki/context-graph/compiler/serialize.js +115 -0
  168. package/dist/core/triwiki/context-graph/contracts.js +236 -0
  169. package/dist/core/triwiki/context-graph/extractors/code/builders.js +150 -0
  170. package/dist/core/triwiki/context-graph/extractors/code/declarations.js +161 -0
  171. package/dist/core/triwiki/context-graph/extractors/code/index.js +265 -0
  172. package/dist/core/triwiki/context-graph/extractors/code/inventory.js +237 -0
  173. package/dist/core/triwiki/context-graph/extractors/code/module-graph.js +252 -0
  174. package/dist/core/triwiki/context-graph/extractors/code/modules.js +79 -0
  175. package/dist/core/triwiki/context-graph/extractors/code/references.js +184 -0
  176. package/dist/core/triwiki/context-graph/extractors/code/selection.js +100 -0
  177. package/dist/core/triwiki/context-graph/extractors/code/ts-config.js +161 -0
  178. package/dist/core/triwiki/context-graph/extractors/code/types.js +18 -0
  179. package/dist/core/triwiki/context-graph/extractors/evidence/claims.js +289 -0
  180. package/dist/core/triwiki/context-graph/extractors/evidence/index.js +54 -0
  181. package/dist/core/triwiki/context-graph/extractors/evidence/proof-index.js +213 -0
  182. package/dist/core/triwiki/context-graph/extractors/evidence/proofs.js +266 -0
  183. package/dist/core/triwiki/context-graph/extractors/evidence/redaction.js +177 -0
  184. package/dist/core/triwiki/context-graph/extractors/evidence/shared.js +0 -0
  185. package/dist/core/triwiki/context-graph/extractors/evidence/sources.js +154 -0
  186. package/dist/core/triwiki/context-graph/extractors/index.js +7 -0
  187. package/dist/core/triwiki/context-graph/extractors/topology/commands.js +207 -0
  188. package/dist/core/triwiki/context-graph/extractors/topology/gate-edges.js +201 -0
  189. package/dist/core/triwiki/context-graph/extractors/topology/gates.js +182 -0
  190. package/dist/core/triwiki/context-graph/extractors/topology/globs.js +124 -0
  191. package/dist/core/triwiki/context-graph/extractors/topology/index.js +92 -0
  192. package/dist/core/triwiki/context-graph/extractors/topology/routes.js +135 -0
  193. package/dist/core/triwiki/context-graph/extractors/topology/shared.js +215 -0
  194. package/dist/core/triwiki/context-graph/graph-index.js +143 -0
  195. package/dist/core/triwiki/context-graph/ids.js +0 -0
  196. package/dist/core/triwiki/context-graph/lint/index.js +0 -0
  197. package/dist/core/triwiki/context-graph/lint/rules.js +232 -0
  198. package/dist/core/triwiki/context-graph/lint/warnings.js +93 -0
  199. package/dist/core/triwiki/context-graph/paths.js +116 -0
  200. package/dist/core/triwiki/context-graph/profiles.js +78 -0
  201. package/dist/core/triwiki/context-graph/projections/anchors.js +91 -0
  202. package/dist/core/triwiki/context-graph/projections/attention.js +58 -0
  203. package/dist/core/triwiki/context-graph/projections/code-pack-workspace.js +62 -0
  204. package/dist/core/triwiki/context-graph/projections/code-pack.js +144 -0
  205. package/dist/core/triwiki/context-graph/projections/index.js +7 -0
  206. package/dist/core/triwiki/context-graph/projections/module-view.js +140 -0
  207. package/dist/core/triwiki/context-graph/projections/node-summary.js +118 -0
  208. package/dist/core/triwiki/context-graph/projections/pack-contract.js +6 -0
  209. package/dist/core/triwiki/context-graph/query/explain.js +0 -0
  210. package/dist/core/triwiki/context-graph/query/index.js +178 -0
  211. package/dist/core/triwiki/context-graph/query/load.js +116 -0
  212. package/dist/core/triwiki/context-graph/query/pack.js +117 -0
  213. package/dist/core/triwiki/context-graph/query/rank.js +142 -0
  214. package/dist/core/triwiki/context-graph/query/ranking-config.js +64 -0
  215. package/dist/core/triwiki/context-graph/query/seeds.js +241 -0
  216. package/dist/core/triwiki/context-graph/query/snapshot-cache.js +72 -0
  217. package/dist/core/triwiki/context-graph/query/traverse.js +154 -0
  218. package/dist/core/triwiki/context-graph/query-types.js +29 -0
  219. package/dist/core/triwiki/context-graph/store/compile-lock.js +21 -0
  220. package/dist/core/triwiki/context-graph/store/event-log.js +48 -0
  221. package/dist/core/triwiki/context-graph/store/fragment-cache.js +85 -0
  222. package/dist/core/triwiki/context-graph/store/graph-status.js +85 -0
  223. package/dist/core/triwiki/context-graph/store/snapshot-store.js +155 -0
  224. package/dist/core/triwiki/triwiki-proof-bank-index-repair.js +115 -0
  225. package/dist/core/triwiki/triwiki-proof-bank-index-store.js +290 -0
  226. package/dist/core/triwiki/triwiki-proof-bank-index.js +126 -0
  227. package/dist/core/triwiki/triwiki-proof-bank.js +7 -1
  228. package/dist/core/verification/context-graph-affected.js +271 -0
  229. package/dist/core/version.js +1 -1
  230. package/dist/native/sks-menubar/Sources/AlertFactory.swift +11 -3
  231. package/dist/native/sks-menubar/Sources/AppDelegate.swift +9 -0
  232. package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +25 -3
  233. package/dist/native/sks-menubar/Sources/ControlKit.swift +19 -8
  234. package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +1 -2
  235. package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +45 -17
  236. package/dist/native/sks-menubar/Sources/OverviewSummary.swift +162 -0
  237. package/dist/native/sks-menubar/Sources/OverviewViewController.swift +136 -190
  238. package/dist/native/sks-menubar/Sources/ProcessClient.swift +107 -11
  239. package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +5 -1
  240. package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +16 -4
  241. package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +4 -1
  242. package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +131 -0
  243. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +288 -341
  244. package/dist/native/sks-menubar/Sources/RemoteTelegramCenterState.swift +447 -0
  245. package/dist/native/sks-menubar/Sources/RemoteTelegramRendering.swift +484 -0
  246. package/dist/native/sks-menubar/Sources/RemoteTelegramViewController.swift +364 -115
  247. package/dist/native/sks-menubar/Sources/SettingsViewController.swift +73 -12
  248. package/dist/native/sks-menubar/Sources/SidebarItem.swift +3 -3
  249. package/dist/native/sks-menubar/Sources/StatusItemController.swift +13 -13
  250. package/dist/native/sks-menubar/Sources/TelegramHubSupervisor.swift +469 -0
  251. package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +1 -6
  252. package/dist/native/sks-menubar/Tests/AppRuntimeTestSupport.swift +12 -0
  253. package/dist/native/sks-menubar/Tests/NativeTelegramRegressionRunner.swift +55 -0
  254. package/dist/native/sks-menubar/Tests/ProcessClientTests.swift +33 -0
  255. package/dist/native/sks-menubar/Tests/ProvidersViewControllerTests.swift +142 -0
  256. package/dist/native/sks-menubar/Tests/RemoteTelegramCenterStateTests.swift +56 -0
  257. package/dist/native/sks-menubar/Tests/TelegramHubSupervisorTests.swift +55 -0
  258. package/dist/scripts/codex-lb-catalog-passthrough-check.js +120 -0
  259. package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +169 -0
  260. package/dist/scripts/codex-lb-desktop-bridge-check.js +394 -0
  261. package/dist/scripts/codex-lb-desktop-bridge-latency-check.js +196 -0
  262. package/dist/scripts/codex-lb-desktop-capabilities-check.js +287 -0
  263. package/dist/scripts/codex-lb-desktop-real-evidence-check.js +123 -0
  264. package/dist/scripts/codex-lb-fast-mode-truth-check.js +10 -3
  265. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +81 -40
  266. package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +99 -37
  267. package/dist/scripts/context-graph-check.js +191 -0
  268. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +1 -1
  269. package/dist/scripts/gate-policy-audit-check.js +1 -1
  270. package/dist/scripts/helper-dedup-check.js +0 -2
  271. package/dist/scripts/installed-package-smoke-check.js +4 -1
  272. package/dist/scripts/latest-version-guidance-check.js +74 -0
  273. package/dist/scripts/release-metadata-check.js +21 -4
  274. package/dist/scripts/release-real-check.js +7 -0
  275. package/dist/scripts/ux-review-imagegen-blackbox-check.js +25 -1
  276. package/dist/scripts/ux-review-run-wires-imagegen-check.js +9 -1
  277. package/package.json +8 -3
  278. package/release-gates.v2.json +176 -1
  279. package/runtime-required-scripts.json +30 -0
  280. package/schemas/triwiki/context-graph.schema.json +119 -0
  281. package/dist/cli/install-helpers-codex-lb-selftest-chain.js +0 -112
  282. package/dist/cli/install-helpers-codex-lb-selftest.js +0 -481
  283. package/dist/core/triwiki/code-index-scanner.js +0 -309
@@ -1,10 +1,13 @@
1
1
  import path from 'node:path';
2
+ import { isDeepStrictEqual } from 'node:util';
2
3
  import { ui as cliUi } from '../../cli/cli-theme.js';
3
4
  import { createMission, findLatestMission, getOrCreateExplicitNarutoMission, getOrCreateSessionMission, loadStateForSession, loadMission, sessionStateKey, setCurrent, updateCurrentIfMissionAndRun } from '../mission.js';
4
5
  import { closeWorkOrderLedgerForRouteResult, createAndWriteWorkOrderLedgerForPrompt } from '../work-order-ledger.js';
5
6
  import { appendJsonl, exists, nowIso, readJson, sksRoot, writeJsonAtomic } from '../fsx.js';
6
- import { SUBAGENT_EVENT_LOG_FILENAME, SUBAGENT_PARENT_SUMMARY_FILENAME, bindTrustworthySubagentParentSummaryToRun, persistOrReuseTrustworthySubagentParentSummary, readSubagentEvents, writeSubagentEvidence } from '../subagents/subagent-evidence.js';
7
+ import { SUBAGENT_EVENT_LOG_FILENAME, SUBAGENT_EVIDENCE_FILENAME, SUBAGENT_PARENT_SUMMARY_FILENAME, bindTrustworthySubagentParentSummaryToRun, normalizeSubagentParentSummary, persistOrReuseTrustworthySubagentParentSummary, readSubagentEvents, writeSubagentEvidence } from '../subagents/subagent-evidence.js';
7
8
  import { buildNarutoHelpResult } from '../subagents/naruto-help-contract.js';
9
+ import { resolveNarutoCredentialPolicy } from '../subagents/naruto-host-credentials.js';
10
+ import { DEFAULT_SUBAGENT_EFFORT, DEFAULT_SUBAGENT_MODEL, NARUTO_PARENT_EFFORT, NARUTO_PARENT_MODEL } from '../subagents/model-policy.js';
8
11
  import { buildNarutoProofProjection } from '../subagents/naruto-proof-projection.js';
9
12
  import { withFileLock } from '../locks/file-lock.js';
10
13
  import { codexAppSessionKey, detectCodexAppSession, runOfficialSubagentWorkflow } from '../subagents/official-subagent-runner.js';
@@ -14,7 +17,9 @@ import { effectiveSubagentTarget, refreshSubagentWaveLifecycle } from '../subage
14
17
  import { HOST_CAPABILITY_HOOK_RUNTIME_FILENAME, bindParentSummaryToHostCapabilityEvidence, createHostCapabilityHookRuntimeBinding, resolveHostCapabilityHookRuntimeBinding } from '../agent-bridge/host-capability-runtime.js';
15
18
  import { renderHostCapabilityBlockedLines } from '../agent-bridge/host-capability-policy.js';
16
19
  import { uniqueStrings } from '../text/strings.js';
20
+ import { completeNarutoTerminalBundle, refreshOfficialSubagentCompletionArtifacts } from '../hooks-runtime/official-subagent-lifecycle.js';
17
21
  export { buildNarutoGateResult } from '../subagents/official-subagent-preparation.js';
22
+ const MAX_PARENT_SUMMARY_STDIN_BYTES = 1024 * 1024;
18
23
  let nextNarutoPreparationFailureInjectionForTest = null;
19
24
  export function injectNextNarutoPreparationFailureForTest(value) {
20
25
  nextNarutoPreparationFailureInjectionForTest = value;
@@ -24,6 +29,23 @@ export async function narutoCommand(commandOrArgs = 'naruto', maybeArgs = []) {
24
29
  if (args.some((arg) => arg === '--glm' || arg.startsWith('--glm=')))
25
30
  return blockGlmOverride(args.includes('--json'));
26
31
  const parsed = parseNarutoArgs(args);
32
+ const credentialPolicy = parsed.credentialPolicy;
33
+ if (credentialPolicy.blockers.length) {
34
+ const blocked = {
35
+ schema: 'sks.naruto-credential-policy.v1',
36
+ ok: false,
37
+ blockers: credentialPolicy.blockers,
38
+ hint: 'sks naruto run --auth-mode=host --model-provider=<config.toml provider block> --provider-env-key=<ENV NAME>'
39
+ };
40
+ if (args.includes('--json'))
41
+ console.log(JSON.stringify(blocked, null, 2));
42
+ else {
43
+ console.error(`Naruto credential policy blocked: ${credentialPolicy.blockers.join(', ')}`);
44
+ console.error(blocked.hint);
45
+ }
46
+ process.exitCode = 2;
47
+ return null;
48
+ }
27
49
  if (parsed.argumentErrors.length) {
28
50
  const result = argumentBlock(parsed.argumentErrors);
29
51
  return emit(parsed, result, () => {
@@ -41,8 +63,197 @@ export async function narutoCommand(commandOrArgs = 'naruto', maybeArgs = []) {
41
63
  return narutoSubagents(parsed);
42
64
  if (parsed.action === 'proof')
43
65
  return narutoProof(parsed);
66
+ if (parsed.action === 'parent-summary')
67
+ return narutoParentSummary(parsed);
44
68
  return narutoRun(parsed);
45
69
  }
70
+ async function narutoParentSummary(parsed) {
71
+ const root = await sksRoot();
72
+ const appSession = detectCodexAppSession();
73
+ const sessionKey = appSession ? codexAppSessionKey() : null;
74
+ if (!appSession || !sessionKey) {
75
+ return blockedParentSummary(parsed, ['naruto_parent_summary_app_session_required']);
76
+ }
77
+ return withFileLock({
78
+ lockPath: path.join(root, '.sneakoscope', 'state', `naruto-session-${sessionStateKey(sessionKey)}.lock`),
79
+ timeoutMs: 20_000,
80
+ staleMs: 120_000
81
+ }, () => narutoParentSummaryTransaction(parsed, root, sessionKey));
82
+ }
83
+ async function narutoParentSummaryTransaction(parsed, root, sessionKey) {
84
+ const state = await loadStateForSession(root, sessionKey).catch(() => null);
85
+ const route = String(state?.route || state?.route_command || state?.mode || '')
86
+ .replace(/^\$/, '')
87
+ .replace(/[-_]/g, '')
88
+ .toUpperCase();
89
+ const officialSubagentRoute = route === 'NARUTO'
90
+ || (state?.subagents_required === true
91
+ && typeof state?.official_subagent_run_id === 'string'
92
+ && state.official_subagent_run_id.trim().length > 0);
93
+ const stateBlockers = uniqueStrings([
94
+ ...(state?._session_key === sessionStateKey(sessionKey) ? [] : ['naruto_parent_summary_session_state_mismatch']),
95
+ ...(state?.session_scope === sessionKey ? [] : ['naruto_parent_summary_session_scope_mismatch']),
96
+ ...(state?.mission_id === parsed.missionId ? [] : ['naruto_parent_summary_active_mission_mismatch']),
97
+ ...(officialSubagentRoute ? [] : ['naruto_parent_summary_active_route_mismatch']),
98
+ ...(state?.route_closed === true ? ['naruto_parent_summary_route_closed'] : [])
99
+ ]);
100
+ if (stateBlockers.length > 0)
101
+ return blockedParentSummary(parsed, stateBlockers);
102
+ const loaded = await loadMission(root, parsed.missionId).catch(() => null);
103
+ if (!loaded)
104
+ return blockedParentSummary(parsed, [`naruto_parent_summary_mission_not_found:${parsed.missionId}`]);
105
+ const plan = await readJson(path.join(loaded.dir, SUBAGENT_PLAN_FILENAME), null).catch(() => null);
106
+ const workflowRunId = String(plan?.workflow_run_id || '').trim();
107
+ const planBlockers = uniqueStrings([
108
+ ...(plan?.schema === 'sks.subagent-plan.v1' ? [] : ['naruto_parent_summary_plan_schema_invalid']),
109
+ ...(plan?.workflow === 'official_codex_subagent' ? [] : ['naruto_parent_summary_plan_workflow_invalid']),
110
+ ...(plan?.mission_id === parsed.missionId ? [] : ['naruto_parent_summary_plan_mission_mismatch']),
111
+ ...(plan?.session_scope === sessionKey ? [] : ['naruto_parent_summary_plan_session_scope_mismatch']),
112
+ ...(workflowRunId ? [] : ['naruto_parent_summary_plan_run_id_missing']),
113
+ ...(workflowRunId && state?.official_subagent_run_id === workflowRunId
114
+ ? []
115
+ : ['naruto_parent_summary_active_run_mismatch'])
116
+ ]);
117
+ if (planBlockers.length > 0)
118
+ return blockedParentSummary(parsed, planBlockers);
119
+ const stdin = await readBoundedParentSummaryStdin();
120
+ if (!stdin.ok)
121
+ return blockedParentSummary(parsed, [stdin.blocker]);
122
+ const raw = stdin.value;
123
+ let submitted;
124
+ try {
125
+ submitted = JSON.parse(raw);
126
+ }
127
+ catch {
128
+ return blockedParentSummary(parsed, ['naruto_parent_summary_stdin_json_invalid']);
129
+ }
130
+ if (!submitted || typeof submitted !== 'object' || Array.isArray(submitted)) {
131
+ return blockedParentSummary(parsed, ['naruto_parent_summary_stdin_object_required']);
132
+ }
133
+ const normalized = normalizeSubagentParentSummary(submitted);
134
+ const summaryBlockers = uniqueStrings([
135
+ ...(normalized.trustworthy && normalized.raw ? [] : normalized.blockers.length
136
+ ? normalized.blockers.map((blocker) => `naruto_parent_summary_schema:${blocker}`)
137
+ : ['naruto_parent_summary_schema_invalid']),
138
+ ...(!normalized.run_id
139
+ ? ['naruto_parent_summary_run_id_missing']
140
+ : normalized.run_id === workflowRunId
141
+ ? []
142
+ : ['naruto_parent_summary_run_id_mismatch'])
143
+ ]);
144
+ if (summaryBlockers.length > 0)
145
+ return blockedParentSummary(parsed, summaryBlockers);
146
+ const submittedSummary = normalized.raw;
147
+ if (!submittedSummary)
148
+ return blockedParentSummary(parsed, ['naruto_parent_summary_schema_invalid']);
149
+ const existing = await readJson(path.join(loaded.dir, SUBAGENT_PARENT_SUMMARY_FILENAME), null).catch(() => null);
150
+ if (existing !== null) {
151
+ const normalizedExisting = normalizeSubagentParentSummary(existing);
152
+ const [existingGate, existingSummary, existingEvidence] = await Promise.all([
153
+ readJson(path.join(loaded.dir, NARUTO_GATE_FILENAME), null).catch(() => null),
154
+ readJson(path.join(loaded.dir, NARUTO_SUMMARY_FILENAME), null).catch(() => null),
155
+ readJson(path.join(loaded.dir, SUBAGENT_EVIDENCE_FILENAME), null).catch(() => null)
156
+ ]);
157
+ const terminal = completeNarutoTerminalBundle({
158
+ workflowRunId,
159
+ gate: existingGate,
160
+ summary: existingSummary,
161
+ evidence: existingEvidence,
162
+ parentSummary: existing
163
+ });
164
+ if (terminal) {
165
+ if (!normalizedExisting.trustworthy || !normalizedExisting.raw) {
166
+ return blockedParentSummary(parsed, ['naruto_parent_summary_existing_canonical_invalid']);
167
+ }
168
+ if (normalizedExisting.run_id !== workflowRunId) {
169
+ return blockedParentSummary(parsed, ['naruto_parent_summary_existing_run_id_mismatch']);
170
+ }
171
+ if (!sameParentAuthoredSummary(normalizedExisting.raw, submittedSummary)) {
172
+ return blockedParentSummary(parsed, ['naruto_parent_summary_conflicts_with_canonical']);
173
+ }
174
+ }
175
+ }
176
+ const evidence = await refreshOfficialSubagentCompletionArtifacts(root, state, submittedSummary, sessionKey);
177
+ if (!evidence)
178
+ return blockedParentSummary(parsed, ['naruto_parent_summary_lifecycle_commit_rejected']);
179
+ const [persisted, summary, gate] = await Promise.all([
180
+ readJson(path.join(loaded.dir, SUBAGENT_PARENT_SUMMARY_FILENAME), null).catch(() => null),
181
+ readJson(path.join(loaded.dir, NARUTO_SUMMARY_FILENAME), null).catch(() => null),
182
+ readJson(path.join(loaded.dir, NARUTO_GATE_FILENAME), null).catch(() => null)
183
+ ]);
184
+ const normalizedPersisted = normalizeSubagentParentSummary(persisted);
185
+ if (!normalizedPersisted.trustworthy
186
+ || normalizedPersisted.run_id !== workflowRunId
187
+ || !sameParentAuthoredSummary(normalizedPersisted.raw, submittedSummary)) {
188
+ return blockedParentSummary(parsed, ['naruto_parent_summary_canonical_commit_mismatch']);
189
+ }
190
+ const hardBlocked = normalizedPersisted.status === 'failed';
191
+ const completionEvidence = route === 'NARUTO'
192
+ ? gate?.passed === true
193
+ : evidence?.ok === true;
194
+ const completionBlockers = route === 'NARUTO'
195
+ ? (Array.isArray(gate?.blockers) ? gate.blockers : [])
196
+ : (Array.isArray(evidence?.blockers) ? evidence.blockers : []);
197
+ const accepted = completionEvidence || hardBlocked;
198
+ const result = {
199
+ schema: NARUTO_RESULT_SCHEMA,
200
+ action: 'parent-summary',
201
+ ok: completionEvidence,
202
+ accepted,
203
+ status: route === 'NARUTO'
204
+ ? summary?.status || evidence?.status || normalizedPersisted.status || 'incomplete'
205
+ : evidence?.status || normalizedPersisted.status || 'incomplete',
206
+ mission_id: parsed.missionId,
207
+ workflow_run_id: workflowRunId,
208
+ parent_summary_status: normalizedPersisted.status,
209
+ completion_evidence: completionEvidence,
210
+ blockers: completionBlockers,
211
+ artifacts: narutoArtifactLinks(evidence)
212
+ };
213
+ return emit(parsed, result, () => renderParentSummaryResult(result), result.ok !== true);
214
+ }
215
+ async function readBoundedParentSummaryStdin() {
216
+ let value = '';
217
+ let bytes = 0;
218
+ process.stdin.setEncoding('utf8');
219
+ for await (const chunk of process.stdin) {
220
+ const text = String(chunk);
221
+ bytes += Buffer.byteLength(text, 'utf8');
222
+ if (bytes > MAX_PARENT_SUMMARY_STDIN_BYTES) {
223
+ return { ok: false, blocker: `naruto_parent_summary_stdin_too_large:${MAX_PARENT_SUMMARY_STDIN_BYTES}` };
224
+ }
225
+ value += text;
226
+ }
227
+ if (!value.trim())
228
+ return { ok: false, blocker: 'naruto_parent_summary_stdin_empty' };
229
+ return { ok: true, value };
230
+ }
231
+ function sameParentAuthoredSummary(left, right) {
232
+ if (!left || typeof left !== 'object' || Array.isArray(left))
233
+ return false;
234
+ if (!right || typeof right !== 'object' || Array.isArray(right))
235
+ return false;
236
+ const omitHostReceipts = (value) => {
237
+ const { artifacts: _artifacts, capabilities_used: _capabilitiesUsed, ...authored } = value;
238
+ return authored;
239
+ };
240
+ return isDeepStrictEqual(omitHostReceipts(left), omitHostReceipts(right));
241
+ }
242
+ function blockedParentSummary(parsed, blockers) {
243
+ const result = {
244
+ schema: NARUTO_RESULT_SCHEMA,
245
+ action: 'parent-summary',
246
+ ok: false,
247
+ accepted: false,
248
+ status: 'blocked',
249
+ mission_id: parsed.missionId || null,
250
+ blockers: uniqueStrings(blockers)
251
+ };
252
+ return emit(parsed, result, () => {
253
+ for (const line of renderNarutoBlockedLines(result.blockers))
254
+ console.error(line);
255
+ }, true);
256
+ }
46
257
  async function narutoRun(parsed) {
47
258
  const root = await sksRoot();
48
259
  const appSession = detectCodexAppSession();
@@ -152,6 +363,7 @@ async function narutoRunTransaction(parsed, root, appSession, sessionKey, resolv
152
363
  missionId: id,
153
364
  workflowRunId,
154
365
  sessionKey,
366
+ credentialPolicy: parsed.credentialPolicy,
155
367
  ...(missionLease ? { onChildSpawn: missionLease.protectChildPid } : {})
156
368
  });
157
369
  const result = await withOfficialSubagentLifecycleLock(dir, async () => {
@@ -482,6 +694,7 @@ function narutoHelp(parsed) {
482
694
  console.log(`Nesting: max_depth=${result.max_depth}; Naruto children must not spawn children`);
483
695
  console.log('Context: bounded TriWiki attention.use_first anchors with on-demand source hydration');
484
696
  console.log('Evidence: SubagentStop is lifecycle-only; completion requires subagent-parent-summary.json with one structured outcome per Naruto child thread.');
697
+ console.log('Codex App finalization: submit the structured object with parent-summary --mission <id> --stdin, then return localized Markdown without exposing JSON.');
485
698
  });
486
699
  }
487
700
  async function resolveRunMission(root, parsed, sessionKey = null) {
@@ -541,7 +754,7 @@ export function parseNarutoArgs(args) {
541
754
  : args;
542
755
  const first = normalized[0] && !normalized[0].startsWith('-') ? normalized[0] : '';
543
756
  const actionName = first;
544
- const actions = new Set(['run', 'status', 'subagents', 'proof', 'help']);
757
+ const actions = new Set(['run', 'status', 'subagents', 'proof', 'parent-summary', 'help']);
545
758
  const action = (actions.has(actionName) ? actionName : 'run');
546
759
  const explicitAction = actions.has(actionName);
547
760
  const rest = explicitAction ? normalized.slice(1) : normalized;
@@ -571,7 +784,7 @@ export function parseNarutoArgs(args) {
571
784
  ? positional.join(' ').trim()
572
785
  : '';
573
786
  const positionalHead = String(positional[0] || '').toLowerCase();
574
- const subcommandNames = new Set(['run', 'status', 'subagents', 'proof', 'help']);
787
+ const subcommandNames = new Set(['run', 'status', 'subagents', 'proof', 'parent-summary', 'help']);
575
788
  if (!first && !explicitAction && positionalHead && !subcommandNames.has(positionalHead)) {
576
789
  argumentErrors.push(`unknown_subcommand:${positionalHead}`);
577
790
  }
@@ -599,6 +812,22 @@ export function parseNarutoArgs(args) {
599
812
  }
600
813
  if (action === 'run' && !prompt)
601
814
  argumentErrors.push('empty_task');
815
+ if (action === 'parent-summary') {
816
+ if (!missionOption.present || !missionOption.value || missionOption.value === 'latest') {
817
+ argumentErrors.push('parent_summary_requires_explicit_mission');
818
+ }
819
+ if (missionIdOption.present)
820
+ argumentErrors.push('parent_summary_mission_id_alias_not_supported');
821
+ if (!normalized.includes('--stdin'))
822
+ argumentErrors.push('parent_summary_requires_stdin');
823
+ if (agentsOption.present || maxThreadsOption.present || normalized.includes('--readonly')
824
+ || normalized.includes('--read-only') || normalized.includes('--trusted-project')) {
825
+ argumentErrors.push('parent_summary_unsupported_run_option');
826
+ }
827
+ }
828
+ else if (normalized.includes('--stdin')) {
829
+ argumentErrors.push('stdin_only_supported_for_parent_summary');
830
+ }
602
831
  return {
603
832
  action,
604
833
  prompt,
@@ -606,17 +835,28 @@ export function parseNarutoArgs(args) {
606
835
  maxThreads,
607
836
  missionId: String(missionFlag || positionalMission || 'latest'),
608
837
  json: normalized.includes('--json'),
838
+ stdin: normalized.includes('--stdin'),
609
839
  readOnly: normalized.includes('--readonly') || normalized.includes('--read-only'),
610
840
  trustedProject: optionArgs.includes('--trusted-project'),
611
- argumentErrors: uniqueStrings(argumentErrors)
841
+ argumentErrors: uniqueStrings(argumentErrors),
842
+ credentialPolicy: resolveNarutoCredentialPolicy({
843
+ args: optionArgs,
844
+ env: process.env,
845
+ defaultParentModel: NARUTO_PARENT_MODEL,
846
+ defaultParentEffort: NARUTO_PARENT_EFFORT,
847
+ defaultSubagentModel: DEFAULT_SUBAGENT_MODEL,
848
+ defaultSubagentEffort: DEFAULT_SUBAGENT_EFFORT
849
+ })
612
850
  };
613
851
  }
614
852
  function positionalValues(args) {
615
853
  const valueFlags = new Set([
616
- '--agents', '--max-threads', '--mission', '--mission-id'
854
+ '--agents', '--max-threads', '--mission', '--mission-id',
855
+ '--auth-mode', '--model-provider', '--provider-env-key',
856
+ '--parent-model', '--parent-effort', '--subagent-model', '--subagent-effort'
617
857
  ]);
618
858
  const booleanFlags = new Set([
619
- '--json', '--readonly', '--read-only', '--trusted-project'
859
+ '--json', '--stdin', '--readonly', '--read-only', '--trusted-project', '--no-forced-login-method'
620
860
  ]);
621
861
  const result = [];
622
862
  for (let index = 0; index < args.length; index += 1) {
@@ -679,7 +919,7 @@ function optionErrors(name, option, numeric) {
679
919
  function unknownOptionErrors(args) {
680
920
  const canonical = new Set([
681
921
  '--agents', '--max-threads', '--mission', '--mission-id',
682
- '--json', '--readonly', '--read-only', '--trusted-project', '--help', '-h', '--'
922
+ '--json', '--stdin', '--readonly', '--read-only', '--trusted-project', '--help', '-h', '--'
683
923
  ]);
684
924
  const errors = [];
685
925
  const optionArgs = args.includes('--') ? args.slice(0, args.indexOf('--')) : args;
@@ -693,7 +933,7 @@ function unknownOptionErrors(args) {
693
933
  return errors;
694
934
  }
695
935
  function booleanOptionErrors(args) {
696
- const booleanNames = new Set(['--json', '--readonly', '--read-only', '--trusted-project', '--help', '-h']);
936
+ const booleanNames = new Set(['--json', '--stdin', '--readonly', '--read-only', '--trusted-project', '--no-forced-login-method', '--help', '-h']);
697
937
  const optionArgs = args.includes('--') ? args.slice(0, args.indexOf('--')) : args;
698
938
  const errors = [];
699
939
  for (const arg of optionArgs) {
@@ -785,6 +1025,15 @@ function renderRunResult(result) {
785
1025
  if (result.status === 'delegation_context_ready')
786
1026
  console.log('Continue in the current Naruto parent and wait for every requested child before summarizing.');
787
1027
  }
1028
+ function renderParentSummaryResult(result) {
1029
+ if (result.ok !== true) {
1030
+ for (const line of renderNarutoBlockedLines(result.blockers || []))
1031
+ console.log(line);
1032
+ return;
1033
+ }
1034
+ console.log(`$sks-naruto parent summary committed: ${result.mission_id}`);
1035
+ console.log(`Workflow run: ${result.workflow_run_id}`);
1036
+ }
788
1037
  function renderStatusResult(result) {
789
1038
  if (['blocked', 'incomplete'].includes(result.status) && Array.isArray(result.blockers) && result.blockers.length) {
790
1039
  for (const line of renderNarutoBlockedLines(result.blockers))
@@ -47,7 +47,7 @@ export async function pptCommand(command, args = []) {
47
47
  process.exitCode = 1;
48
48
  if (flag(args, '--json'))
49
49
  return printJson(result);
50
- console.error('PPT build blocked: Codex App imagegen/gpt-image-2 is unavailable.');
50
+ console.error('PPT build blocked: no selected Codex imagegen/gpt-image-2 provider is ready.');
51
51
  for (const action of imagegenRequired.blocker?.next_actions || [])
52
52
  console.error(`- ${action}`);
53
53
  return result;
@@ -159,7 +159,7 @@ async function pptImagegenReview(root, command, action, args = []) {
159
159
  process.exitCode = 1;
160
160
  if (flag(args, '--json'))
161
161
  return printJson(result);
162
- console.error('PPT imagegen review blocked: Codex App imagegen/gpt-image-2 is unavailable.');
162
+ console.error('PPT imagegen review blocked: no selected Codex imagegen/gpt-image-2 provider is ready.');
163
163
  for (const action of imagegenRequired.blocker?.next_actions || [])
164
164
  console.error(`- ${action}`);
165
165
  return result;