blun-king-cli 9.1.587 → 9.1.589

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 (436) hide show
  1. package/CHANGELOG.md +11 -185
  2. package/LIESMICH.txt +51 -13
  3. package/README.md +44 -47
  4. package/agent-spine-plugin/.codex-plugin/plugin.json +16 -4
  5. package/agent-spine-plugin/CHANGELOG.md +37 -5
  6. package/agent-spine-plugin/README.md +3 -3
  7. package/agent-spine-plugin/blun.plugin.json +45 -10
  8. package/agent-spine-plugin/docs/artifact-evaluation.md +93 -0
  9. package/agent-spine-plugin/docs/host-integration.md +42 -27
  10. package/agent-spine-plugin/docs/preflight-recall.md +4 -2
  11. package/agent-spine-plugin/docs/session-timeline.md +97 -236
  12. package/agent-spine-plugin/docs/world-model.md +25 -0
  13. package/agent-spine-plugin/hooks/codex.json +1 -1
  14. package/agent-spine-plugin/hooks/hooks.json +1 -1
  15. package/agent-spine-plugin/package.json +1 -3
  16. package/agent-spine-plugin/scripts/check-hosts.js +3 -3
  17. package/agent-spine-plugin/scripts/release-check.js +10 -5
  18. package/agent-spine-plugin/scripts/run-checks.js +4 -1
  19. package/agent-spine-plugin/scripts/run-tests-hermetic.js +32 -6
  20. package/agent-spine-plugin/src/cli-learning.js +15 -0
  21. package/agent-spine-plugin/src/cli.js +2 -0
  22. package/agent-spine-plugin/src/hook.js +32 -32
  23. package/agent-spine-plugin/src/lib/action-lesson-recall.js +73 -8
  24. package/agent-spine-plugin/src/lib/briefing.js +146 -36
  25. package/agent-spine-plugin/src/lib/channel-continuity.js +19 -0
  26. package/agent-spine-plugin/src/lib/delivery-agent-usage.js +14 -7
  27. package/agent-spine-plugin/src/lib/gateway-group-response.js +128 -0
  28. package/agent-spine-plugin/src/lib/gateway-runs.js +24 -15
  29. package/agent-spine-plugin/src/lib/hook-briefing-use.js +13 -3
  30. package/agent-spine-plugin/src/lib/hook-context.js +16 -3
  31. package/agent-spine-plugin/src/lib/hook-output.js +129 -5
  32. package/agent-spine-plugin/src/lib/hook-timeline.js +5 -3
  33. package/agent-spine-plugin/src/lib/indexed-memory.js +2 -2
  34. package/agent-spine-plugin/src/lib/learning-artifact-evaluator.js +114 -0
  35. package/agent-spine-plugin/src/lib/learning-context.js +11 -4
  36. package/agent-spine-plugin/src/lib/learning-measurements.js +2 -2
  37. package/agent-spine-plugin/src/lib/mcp-runtime.js +89 -3
  38. package/agent-spine-plugin/src/lib/mcp-source-context.js +12 -2
  39. package/agent-spine-plugin/src/lib/mcp-timeline-tools.js +91 -8
  40. package/agent-spine-plugin/src/lib/mcp-world-tools.js +2 -2
  41. package/agent-spine-plugin/src/lib/owned-file-lock.js +20 -1
  42. package/agent-spine-plugin/src/lib/persona-runtime.js +2 -2
  43. package/agent-spine-plugin/src/lib/preflight-delivery-id.js +27 -0
  44. package/agent-spine-plugin/src/lib/preflight.js +4 -4
  45. package/agent-spine-plugin/src/lib/session-timeline-codex.js +15 -0
  46. package/agent-spine-plugin/src/lib/session-timeline-contract.js +12 -4
  47. package/agent-spine-plugin/src/lib/session-timeline-event-extract.js +36 -7
  48. package/agent-spine-plugin/src/lib/session-timeline-host-origin.js +13 -10
  49. package/agent-spine-plugin/src/lib/session-timeline-invocation.js +1 -1
  50. package/agent-spine-plugin/src/lib/session-timeline-king.js +14 -0
  51. package/agent-spine-plugin/src/lib/session-timeline-prior.js +18 -12
  52. package/agent-spine-plugin/src/lib/session-timeline-provider.js +5 -0
  53. package/agent-spine-plugin/src/lib/session-timeline-query.js +2 -0
  54. package/agent-spine-plugin/src/lib/session-timeline-results.js +35 -10
  55. package/agent-spine-plugin/src/lib/session-timeline-source-open.js +30 -0
  56. package/agent-spine-plugin/src/lib/session-timeline.js +122 -75
  57. package/agent-spine-plugin/src/lib/source-roots.js +3 -2
  58. package/agent-spine-plugin/src/lib/task-knowledge-context.js +22 -1
  59. package/agent-spine-plugin/src/lib/timeline-continuation-update.js +100 -0
  60. package/agent-spine-plugin/src/lib/timeline-tool-guard.js +30 -7
  61. package/agent-spine-plugin/src/lib/timeline-user-feedback.js +217 -0
  62. package/agent-spine-plugin/src/lib/timeline-world-capture.js +233 -0
  63. package/agent-spine-plugin/src/lib/world-knowledge.js +59 -2
  64. package/agent-spine-plugin/src/lib/world-model.js +64 -9
  65. package/agent-spine-plugin/src/worker.js +13 -1
  66. package/bin/blun.js +43 -28
  67. package/bin/core-bootstrap.js +5 -4
  68. package/bin/king.js +43 -28
  69. package/bin/launcher-mode.js +1 -10
  70. package/bin/launcher-runtime.js +128 -295
  71. package/bin/managed-node.js +0 -0
  72. package/bin/managed-plugin-selection.cjs +0 -1
  73. package/bin/native-module-repair.js +0 -0
  74. package/bin/node-runtime.js +0 -0
  75. package/bin/node-version.js +0 -0
  76. package/bin/plugin-bootstrap.js +56 -120
  77. package/bin/private-paths.js +11 -34
  78. package/bin/standard-tools-bootstrap.js +34 -114
  79. package/bin/turn-thinking-policy.cjs +3 -11
  80. package/bin/update-copy.js +200 -0
  81. package/bin/update-lease.js +0 -0
  82. package/bin/update-notice.js +155 -274
  83. package/bin/verify-agent-behavior.cjs +122 -0
  84. package/bin/verify-agent-components.cjs +104 -0
  85. package/bin/verify-bundled-agent-sources.cjs +57 -0
  86. package/blun.mjs +143076 -135288
  87. package/bundled-agent-sources.json +701 -0
  88. package/package.json +12 -15
  89. package/standard-skills/translate-native/README.md +1293 -0
  90. package/standard-skills/translate-native/SKILL.md +172 -22
  91. package/standard-skills/translate-native/VERSION +1 -1
  92. package/standard-skills/translate-native/agents/openai.yaml +18 -0
  93. package/standard-skills/translate-native/assets/icon.svg +8 -0
  94. package/standard-skills/translate-native/docs/BLUN_CODE_INTEGRATION.md +76 -0
  95. package/standard-skills/translate-native/docs/PREMORTEM.md +489 -0
  96. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION.md +2035 -0
  97. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_API.md +1302 -0
  98. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_EVIDENCE_HTTP.md +136 -0
  99. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HEALTH_HTTP.md +130 -0
  100. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HTTP_PROVIDER.md +175 -0
  101. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_RECEIPT_VERIFIER_HTTP.md +86 -0
  102. package/standard-skills/translate-native/integrations/AGENT_RULES.md +32 -0
  103. package/standard-skills/translate-native/integrations/adapters/blun-code-language-guard.js +514 -0
  104. package/standard-skills/translate-native/integrations/adapters/node-language-guard.js +230 -0
  105. package/standard-skills/translate-native/integrations/audit_log.py +327 -0
  106. package/standard-skills/translate-native/integrations/claude_language_hook.js +1536 -0
  107. package/standard-skills/translate-native/integrations/commercial_localization_profile.py +42 -0
  108. package/standard-skills/translate-native/integrations/delivery-policy.example.json +28 -0
  109. package/standard-skills/translate-native/integrations/enforced_delivery.py +543 -0
  110. package/standard-skills/translate-native/integrations/guard_service.py +435 -0
  111. package/standard-skills/translate-native/integrations/language_gateway.py +67 -0
  112. package/standard-skills/translate-native/integrations/mcp_auth_headers.py +198 -0
  113. package/standard-skills/translate-native/integrations/mcp_http_gateway.py +429 -0
  114. package/standard-skills/translate-native/integrations/non_language_html_entities.js +1485 -0
  115. package/standard-skills/translate-native/integrations/pre_output_guard.py +65 -0
  116. package/standard-skills/translate-native/integrations/task_router.py +101 -0
  117. package/standard-skills/translate-native/integrations/website_localization.py +401 -0
  118. package/standard-skills/translate-native/integrations/website_localization_api.py +581 -0
  119. package/standard-skills/translate-native/integrations/website_localization_benchmark.py +1885 -0
  120. package/standard-skills/translate-native/integrations/website_localization_benchmark_campaign.py +1772 -0
  121. package/standard-skills/translate-native/integrations/website_localization_benchmark_candidate.py +506 -0
  122. package/standard-skills/translate-native/integrations/website_localization_benchmark_http.py +400 -0
  123. package/standard-skills/translate-native/integrations/website_localization_benchmark_review_store.py +781 -0
  124. package/standard-skills/translate-native/integrations/website_localization_benchmark_reviewer_http.py +500 -0
  125. package/standard-skills/translate-native/integrations/website_localization_benchmark_runtime.py +1107 -0
  126. package/standard-skills/translate-native/integrations/website_localization_benchmark_suite.py +463 -0
  127. package/standard-skills/translate-native/integrations/website_localization_cms.py +2835 -0
  128. package/standard-skills/translate-native/integrations/website_localization_cms_client.py +875 -0
  129. package/standard-skills/translate-native/integrations/website_localization_cms_dispatch.py +805 -0
  130. package/standard-skills/translate-native/integrations/website_localization_cms_http.py +588 -0
  131. package/standard-skills/translate-native/integrations/website_localization_cms_lifecycle_monitor.py +991 -0
  132. package/standard-skills/translate-native/integrations/website_localization_cms_receiver.py +1441 -0
  133. package/standard-skills/translate-native/integrations/website_localization_cms_receiver_runtime.py +414 -0
  134. package/standard-skills/translate-native/integrations/website_localization_cms_receiver_store.py +1073 -0
  135. package/standard-skills/translate-native/integrations/website_localization_cms_removal_dispatch.py +865 -0
  136. package/standard-skills/translate-native/integrations/website_localization_cms_source_client.py +583 -0
  137. package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery.py +964 -0
  138. package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_runtime.py +665 -0
  139. package/standard-skills/translate-native/integrations/website_localization_cms_source_http.py +1153 -0
  140. package/standard-skills/translate-native/integrations/website_localization_cms_source_runtime.py +675 -0
  141. package/standard-skills/translate-native/integrations/website_localization_cms_source_service.py +1125 -0
  142. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification.py +674 -0
  143. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_http.py +444 -0
  144. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver.py +1469 -0
  145. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver_runtime.py +1142 -0
  146. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_processing_monitor.py +634 -0
  147. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_receiver_client.py +804 -0
  148. package/standard-skills/translate-native/integrations/website_localization_deepl_baseline.py +922 -0
  149. package/standard-skills/translate-native/integrations/website_localization_evidence_http.py +482 -0
  150. package/standard-skills/translate-native/integrations/website_localization_health.py +1541 -0
  151. package/standard-skills/translate-native/integrations/website_localization_health_http.py +372 -0
  152. package/standard-skills/translate-native/integrations/website_localization_http_provider.py +297 -0
  153. package/standard-skills/translate-native/integrations/website_localization_native_reference_http.py +479 -0
  154. package/standard-skills/translate-native/integrations/website_localization_native_reference_intake.py +363 -0
  155. package/standard-skills/translate-native/integrations/website_localization_native_reference_queue.py +1449 -0
  156. package/standard-skills/translate-native/integrations/website_localization_native_reference_store.py +420 -0
  157. package/standard-skills/translate-native/integrations/website_localization_quality_profiles.py +235 -0
  158. package/standard-skills/translate-native/integrations/website_localization_queue.py +671 -0
  159. package/standard-skills/translate-native/integrations/website_localization_receipt_verifier_http.py +516 -0
  160. package/standard-skills/translate-native/integrations/website_localization_release.py +928 -0
  161. package/standard-skills/translate-native/integrations/website_localization_release_coordinator.py +1008 -0
  162. package/standard-skills/translate-native/integrations/website_localization_runner.py +276 -0
  163. package/standard-skills/translate-native/integrations/website_localization_runtime.py +862 -0
  164. package/standard-skills/translate-native/integrations/website_localization_service.py +350 -0
  165. package/standard-skills/translate-native/integrations/website_localization_supervisor.py +511 -0
  166. package/standard-skills/translate-native/integrations/website_localization_worker.py +663 -0
  167. package/standard-skills/translate-native/provenance.json +3 -4
  168. package/standard-skills/translate-native/references/commercial-localization.md +177 -0
  169. package/standard-skills/translate-native/scripts/blun_language_guard.py +7 -1
  170. package/standard-skills/translate-native/scripts/check_commercial_review.py +80 -0
  171. package/standard-skills/translate-native/scripts/commercial_localization_profile.py +333 -0
  172. package/standard-tools/language-guard/LICENSE +21 -0
  173. package/standard-tools/language-guard/VERSION +1 -0
  174. package/standard-tools/language-guard/blun_language_guard.py +7 -1
  175. package/standard-tools/language-guard/check_commercial_review.py +80 -0
  176. package/standard-tools/language-guard/commercial_localization_profile.py +333 -0
  177. package/standard-tools/language-guard/language_gateway.py +62 -0
  178. package/standard-tools/language-guard/pre_output_guard.py +64 -0
  179. package/standard-tools/language-guard/provenance.json +4 -11
  180. package/standard-tools/manifest.json +34 -11
  181. package/telegram-plugin/commands/access.md +2 -10
  182. package/telegram-plugin/dist/bridge.mjs +64041 -687
  183. package/telegram-plugin/dist/mcp-server.mjs +72810 -9027
  184. package/telegram-plugin/dist/noise.mjs +28 -63511
  185. package/agent-spine-plugin/CONTRIBUTING.md +0 -52
  186. package/agent-spine-plugin/SECURITY.md +0 -47
  187. package/agent-spine-plugin/docs/assignment-continuation.md +0 -48
  188. package/agent-spine-plugin/docs/releasing.md +0 -85
  189. package/agent-spine-plugin/docs/structured-completion.md +0 -67
  190. package/bin/abort-listener-policy.cjs +0 -43
  191. package/bin/active-steer-priority-policy.cjs +0 -24
  192. package/bin/agent-api-http-adapter.mjs +0 -446
  193. package/bin/agent-api-private-http-server.mjs +0 -288
  194. package/bin/agent-api-runtime.mjs +0 -252
  195. package/bin/agent-api-service-environment.mjs +0 -236
  196. package/bin/agent-api-service-host.mjs +0 -209
  197. package/bin/agent-api-service-process.mjs +0 -171
  198. package/bin/agent-api-session-registry.mjs +0 -428
  199. package/bin/agent-api-tool-broker.cjs +0 -248
  200. package/bin/agent-api-turn-controller.mjs +0 -461
  201. package/bin/agent-api-usage-journal.cjs +0 -259
  202. package/bin/agent-resume-snapshot.cjs +0 -241
  203. package/bin/agentspine-king-goal-inbox.mjs +0 -111
  204. package/bin/agentspine-king-goal-intake.mjs +0 -106
  205. package/bin/approval-rejection-stop.cjs +0 -15
  206. package/bin/assistant-message-offload-policy.cjs +0 -284
  207. package/bin/baseline-skill-performance-policy.cjs +0 -39
  208. package/bin/bash-search-scope-policy.cjs +0 -49
  209. package/bin/codebase-search-runtime.cjs +0 -23
  210. package/bin/cognitive-action-checkpoint.cjs +0 -1104
  211. package/bin/cognitive-attention-delivery.cjs +0 -76
  212. package/bin/cognitive-attention-policy.cjs +0 -143
  213. package/bin/cognitive-attention-runtime.cjs +0 -91
  214. package/bin/cognitive-context-projection.cjs +0 -73
  215. package/bin/cognitive-cross-portal-acceptance.cjs +0 -443
  216. package/bin/cognitive-effective-view.cjs +0 -77
  217. package/bin/cognitive-focus-projection.cjs +0 -206
  218. package/bin/cognitive-focus-scope.cjs +0 -37
  219. package/bin/cognitive-goal-autostart-policy.cjs +0 -72
  220. package/bin/cognitive-goal-time-trigger-controller.cjs +0 -146
  221. package/bin/cognitive-memory-adapter.cjs +0 -282
  222. package/bin/cognitive-memory-command.cjs +0 -293
  223. package/bin/cognitive-memory-provider.cjs +0 -92
  224. package/bin/cognitive-salience-policy.cjs +0 -159
  225. package/bin/cognitive-state-store.cjs +0 -508
  226. package/bin/cognitive-turn-lifecycle.cjs +0 -624
  227. package/bin/cognitive-work-focus.cjs +0 -180
  228. package/bin/compaction-history-archive.cjs +0 -166
  229. package/bin/compaction-history-startup.cjs +0 -50
  230. package/bin/compaction-model-policy.cjs +0 -31
  231. package/bin/compaction-stage-policy.cjs +0 -21
  232. package/bin/compaction-transaction-policy.cjs +0 -122
  233. package/bin/config-write-dedup-policy.cjs +0 -27
  234. package/bin/context-budget-ledger.cjs +0 -31
  235. package/bin/context-doctor-policy.cjs +0 -70
  236. package/bin/context-insight-policy.cjs +0 -36
  237. package/bin/context-performance-policy.cjs +0 -19
  238. package/bin/context-pressure-policy.cjs +0 -20
  239. package/bin/cron-run-output.cjs +0 -45
  240. package/bin/cron-run-store.cjs +0 -145
  241. package/bin/curiosity-scout-policy.cjs +0 -49
  242. package/bin/default-model-output-budget-policy.cjs +0 -28
  243. package/bin/durable-task-resume-policy.cjs +0 -130
  244. package/bin/durable-task-resume-runtime.cjs +0 -117
  245. package/bin/durable-task-resume-store.cjs +0 -88
  246. package/bin/editable-tool-approval-policy.cjs +0 -540
  247. package/bin/editable-tool-approval-runtime.cjs +0 -99
  248. package/bin/effective-system-prompt-cache-policy.cjs +0 -33
  249. package/bin/error-memory-performance-policy.cjs +0 -113
  250. package/bin/file-observation-policy.cjs +0 -133
  251. package/bin/foreground-output-capture-policy.cjs +0 -41
  252. package/bin/generated-source-health.cjs +0 -142
  253. package/bin/glob-pattern-policy.cjs +0 -13
  254. package/bin/goal-completion-evidence-policy.cjs +0 -120
  255. package/bin/grep-output-limit-policy.cjs +0 -39
  256. package/bin/historical-media-projection-policy.cjs +0 -48
  257. package/bin/history-offload-pressure-policy.cjs +0 -33
  258. package/bin/html-to-research-markdown.cjs +0 -147
  259. package/bin/identity-context-policy.cjs +0 -764
  260. package/bin/identity-journal-policy.cjs +0 -107
  261. package/bin/input-draft-persistence.cjs +0 -77
  262. package/bin/king-tui-function-contract.json +0 -33
  263. package/bin/launcher-restart-policy.cjs +0 -150
  264. package/bin/live-response-repetition-guard.cjs +0 -196
  265. package/bin/llm-config-log-dedup-policy.cjs +0 -76
  266. package/bin/loop-event-record-policy.cjs +0 -174
  267. package/bin/managed-context-startup-policy.cjs +0 -27
  268. package/bin/media-activity-layout-policy.cjs +0 -34
  269. package/bin/media-auto-retrieval-policy.cjs +0 -90
  270. package/bin/media-result-policy.cjs +0 -59
  271. package/bin/micro-compaction-policy.cjs +0 -145
  272. package/bin/mistake-relevance-policy.cjs +0 -319
  273. package/bin/model-retry-progress-policy.cjs +0 -46
  274. package/bin/native-large-file-io.cjs +0 -42
  275. package/bin/native-runtime-cache.cjs +0 -76
  276. package/bin/natural-presence-policy.cjs +0 -28
  277. package/bin/noninteractive-shell-env-policy.cjs +0 -19
  278. package/bin/observer-hooks.cjs +0 -14
  279. package/bin/outbound-claim-provenance.cjs +0 -150
  280. package/bin/oversized-context-offload-policy.cjs +0 -86
  281. package/bin/pending-media-policy.cjs +0 -182
  282. package/bin/pending-token-estimate-policy.cjs +0 -41
  283. package/bin/personal-memory-consent-policy.cjs +0 -72
  284. package/bin/personal-memory-performance-policy.cjs +0 -12
  285. package/bin/personality-choice-policy.cjs +0 -101
  286. package/bin/personality-memory-adapter.cjs +0 -379
  287. package/bin/personality-mode.cjs +0 -46
  288. package/bin/personality-setup-policy.cjs +0 -197
  289. package/bin/proactive-compaction-policy.cjs +0 -25
  290. package/bin/profile-identity-resolution.cjs +0 -136
  291. package/bin/profile-runtime.cjs +0 -318
  292. package/bin/profile-tool-exclusion-policy.cjs +0 -37
  293. package/bin/programmatic-context-isolation.cjs +0 -25
  294. package/bin/programmatic-tool-runtime.mjs +0 -627
  295. package/bin/provider-idle-timeout-policy.cjs +0 -14
  296. package/bin/provider-model-refresh-deadline.cjs +0 -53
  297. package/bin/provider-model-refresh-policy.cjs +0 -107
  298. package/bin/rate-limit-recovery-policy.cjs +0 -47
  299. package/bin/read-batch-policy.cjs +0 -32
  300. package/bin/read-continuation-policy.cjs +0 -59
  301. package/bin/recurring-cron-history-policy.cjs +0 -124
  302. package/bin/relationship-continuity-policy.cjs +0 -143
  303. package/bin/relationship-curiosity-policy.cjs +0 -107
  304. package/bin/relationship-learning-policy.cjs +0 -168
  305. package/bin/release-artifact-freeze-policy.cjs +0 -30
  306. package/bin/reload-plugin-bootstrap.cjs +0 -18
  307. package/bin/reload-queue-policy.cjs +0 -38
  308. package/bin/repeated-assistant-response-policy.cjs +0 -232
  309. package/bin/repeated-injection-projection.cjs +0 -107
  310. package/bin/repeated-user-message-projection.cjs +0 -8
  311. package/bin/research-page-result.cjs +0 -74
  312. package/bin/retry-checkpoint-policy.cjs +0 -13
  313. package/bin/runtime-exit-ledger.cjs +0 -144
  314. package/bin/scoped-cron-run-policy.cjs +0 -358
  315. package/bin/session-checkpoint-policy.cjs +0 -25
  316. package/bin/session-compaction-policy.cjs +0 -84
  317. package/bin/session-replay-policy.cjs +0 -20
  318. package/bin/session-replay-window-policy.cjs +0 -40
  319. package/bin/session-resume-checkpoint.cjs +0 -254
  320. package/bin/session-scrollback-archive.cjs +0 -229
  321. package/bin/skill-activation-performance-policy.cjs +0 -69
  322. package/bin/skill-listing-performance-policy.cjs +0 -92
  323. package/bin/soul-organization-policy.cjs +0 -78
  324. package/bin/soul-preservation-policy.cjs +0 -20
  325. package/bin/startup-preferences.cjs +0 -131
  326. package/bin/streaming-flush-performance-policy.cjs +0 -28
  327. package/bin/structured-agent-swarm-output.cjs +0 -325
  328. package/bin/structured-subagent-output.cjs +0 -252
  329. package/bin/subagent-context-fork-policy.cjs +0 -155
  330. package/bin/subagent-max-tokens-handoff-policy.cjs +0 -69
  331. package/bin/subagent-parent-responsiveness.cjs +0 -19
  332. package/bin/subagent-skill-policy.cjs +0 -206
  333. package/bin/subagent-timeout-policy.cjs +0 -182
  334. package/bin/subagent-tool-policy.cjs +0 -60
  335. package/bin/subagent-usage-rollup-policy.cjs +0 -29
  336. package/bin/system-prompt-context-policy.cjs +0 -124
  337. package/bin/system-prompt-token-cache-policy.cjs +0 -60
  338. package/bin/telegram-addressed-focus.cjs +0 -55
  339. package/bin/telegram-addressed-priority.cjs +0 -12
  340. package/bin/telegram-approval-relay.cjs +0 -290
  341. package/bin/telegram-bot-priority.cjs +0 -17
  342. package/bin/telegram-console-status-policy.cjs +0 -174
  343. package/bin/telegram-context-projection-policy.cjs +0 -141
  344. package/bin/telegram-delivery-lifecycle.cjs +0 -125
  345. package/bin/telegram-direct-focus-policy.cjs +0 -273
  346. package/bin/telegram-mcp-compatibility.cjs +0 -49
  347. package/bin/telegram-media-delivery-policy.cjs +0 -42
  348. package/bin/telegram-private-conversation-policy.cjs +0 -185
  349. package/bin/telegram-queue-handoff-policy.cjs +0 -73
  350. package/bin/telegram-remote-status-policy.cjs +0 -120
  351. package/bin/telegram-session-queue-runtime.mjs +0 -306
  352. package/bin/telegram-text-chunk-policy.cjs +0 -63
  353. package/bin/telegram-truncated-reply-policy.cjs +0 -37
  354. package/bin/telegram-urgent-policy.cjs +0 -45
  355. package/bin/telemetry-spool-policy.cjs +0 -57
  356. package/bin/thinking-activity-status-policy.cjs +0 -132
  357. package/bin/thinking-only-guard.cjs +0 -80
  358. package/bin/todo-list-turn-policy.cjs +0 -131
  359. package/bin/tool-call-loop-policy.cjs +0 -51
  360. package/bin/tool-file-persistence.cjs +0 -141
  361. package/bin/tool-result-offload-policy.cjs +0 -359
  362. package/bin/tool-result-offload-telemetry.cjs +0 -12
  363. package/bin/tool-schema-token-cache-policy.cjs +0 -41
  364. package/bin/tool-stream-preview-policy.cjs +0 -9
  365. package/bin/tui-functional-contract.cjs +0 -55
  366. package/bin/turn-tool-performance-policy.cjs +0 -486
  367. package/bin/usage-cache-efficiency-policy.cjs +0 -26
  368. package/bin/user-home-path-policy.cjs +0 -13
  369. package/bin/user-message-offload-policy.cjs +0 -103
  370. package/bin/user-prompt-hook-origin-policy.cjs +0 -34
  371. package/bin/user-tool-record-policy.cjs +0 -7
  372. package/bin/validated-learning-insight-policy.cjs +0 -58
  373. package/bin/validated-learning-outcome-trace.cjs +0 -107
  374. package/bin/validated-learning-performance-policy.cjs +0 -53
  375. package/bin/validated-learning-signal.cjs +0 -463
  376. package/bin/windows-bash-dialect-policy.cjs +0 -25
  377. package/bin/windows-node-crash-dump.cjs +0 -110
  378. package/bin/write-continuation-policy.cjs +0 -69
  379. package/codebase-index/README.md +0 -82
  380. package/codebase-index/codebase_index.py +0 -470
  381. package/standard-skills/agent-browser/SKILL.md +0 -19
  382. package/standard-skills/agent-browser/references/runtime.md +0 -8
  383. package/standard-skills/blun-session-inspector/SKILL.md +0 -41
  384. package/standard-skills/blun-session-inspector/scripts/inspect-session.cjs +0 -437
  385. package/standard-skills/design-taste-frontend/SKILL.md +0 -1206
  386. package/standard-skills/full-output-enforcement/SKILL.md +0 -49
  387. package/standard-skills/high-end-visual-design/SKILL.md +0 -98
  388. package/standard-skills/image-to-code/SKILL.md +0 -1228
  389. package/standard-skills/industrial-brutalist-ui/SKILL.md +0 -92
  390. package/standard-skills/minimalist-ui/SKILL.md +0 -85
  391. package/standard-skills/motion-design-taste/SKILL.md +0 -74
  392. package/standard-skills/playwright-testing/SKILL.md +0 -19
  393. package/standard-skills/playwright-testing/references/runtime.md +0 -7
  394. package/standard-skills/premortem/SKILL.md +0 -148
  395. package/standard-skills/redesign-existing-projects/SKILL.md +0 -178
  396. package/standard-skills/research-evidence/SKILL.md +0 -39
  397. package/standard-skills/research-evidence/references/evidence-format.md +0 -104
  398. package/standard-skills/research-evidence/scripts/evidence-collection.cjs +0 -260
  399. package/standard-skills/research-evidence/scripts/score-report.cjs +0 -130
  400. package/standard-skills/screenshot-lesen/SKILL.md +0 -52
  401. package/standard-skills/stitch-design-taste/DESIGN.md +0 -121
  402. package/standard-skills/stitch-design-taste/SKILL.md +0 -184
  403. package/standard-skills/telegram-channel/SKILL.md +0 -18
  404. package/standard-skills/telegram-channel/references/runtime.md +0 -7
  405. package/standard-skills/venture-flywheel/SKILL.md +0 -32
  406. package/standard-skills/venture-flywheel/identity/project-identity.cjs +0 -146
  407. package/standard-skills/venture-flywheel/policy/capability-engine.cjs +0 -114
  408. package/standard-skills/venture-flywheel/policy/repository-trust.cjs +0 -229
  409. package/standard-skills/venture-flywheel/references/BEISPIELE-phase0.md +0 -146
  410. package/standard-skills/venture-flywheel/references/CAPABILITY-MAP.md +0 -34
  411. package/standard-skills/venture-flywheel/references/SPEC-phase0-identity-trust.md +0 -77
  412. package/standard-skills/venture-flywheel/references/SPEC-phase0-state-events.md +0 -93
  413. package/standard-skills/venture-flywheel/schemas/capability-decision.schema.json +0 -13
  414. package/standard-skills/venture-flywheel/schemas/execution-event.schema.json +0 -44
  415. package/standard-skills/venture-flywheel/schemas/project-identity.schema.json +0 -32
  416. package/standard-skills/venture-flywheel/schemas/repository-trust.schema.json +0 -57
  417. package/standard-skills/venture-flywheel/schemas/run-transition.schema.json +0 -59
  418. package/standard-skills/venture-flywheel/state/execution-event.cjs +0 -191
  419. package/standard-skills/venture-flywheel/state/task-state-machine.cjs +0 -190
  420. package/standard-skills/web-lesen/SKILL.md +0 -73
  421. package/standard-skills/web-lesen/scripts/crawl_public.py +0 -379
  422. package/standard-skills/windows-mcp/SKILL.md +0 -19
  423. package/standard-skills/windows-mcp/references/runtime.md +0 -9
  424. package/telegram-plugin/DELIVERY.md +0 -36
  425. package/telegram-plugin/bin/telegram-approval-relay.cjs +0 -290
  426. package/telegram-plugin/bin/telegram-console-status-policy.cjs +0 -175
  427. package/telegram-plugin/bin/telegram-delivery-lifecycle.cjs +0 -125
  428. package/telegram-plugin/bin/telegram-direct-reply-policy.cjs +0 -48
  429. package/telegram-plugin/bin/telegram-launcher-status-queue.cjs +0 -122
  430. package/telegram-plugin/bin/telegram-private-conversation-policy.cjs +0 -186
  431. package/telegram-plugin/bin/telegram-remote-status-policy.cjs +0 -121
  432. package/telegram-plugin/bin/telegram-reply-parts.cjs +0 -149
  433. package/telegram-plugin/bin/telegram-text-chunk-policy.cjs +0 -63
  434. package/telegram-plugin/bin/telegram-typing-keepalive.cjs +0 -89
  435. package/telegram-plugin/compat/mcp-server-fa511cd1.mjs +0 -73825
  436. /package/{bin → scripts}/fix-node-pty-perms.js +0 -0
@@ -9,6 +9,7 @@ const { StringDecoder } = require('node:string_decoder');
9
9
  const { types } = require('node:util');
10
10
 
11
11
  const { tryAcquireUpdateLease } = require('./update-lease');
12
+ const { resolveUpdateLocale, updateText } = require('./update-copy');
12
13
 
13
14
  const {
14
15
  ensurePrivateDirectory,
@@ -22,7 +23,6 @@ const INSTALL_REGISTRY_URL = 'https://registry.npmjs.org/';
22
23
  const FALLBACK_MANIFEST_URL = 'https://chat.blun.ai/blun-code-version.json';
23
24
  const SNOOZE_MS = 7 * 24 * 60 * 60 * 1000;
24
25
  const REQUEST_TIMEOUT_MS = 2_500;
25
- const UPDATE_SOURCE_RETRY_DELAYS_MS = Object.freeze([250, 750]);
26
26
  const STATE_FILE = 'update-notice.json';
27
27
  const UPDATE_SKIP_FILE = 'update-skip-version.json';
28
28
  const PENDING_UPDATE_FILE = 'update-pending.json';
@@ -35,7 +35,6 @@ const UPDATE_SIGNAL_EXIT_CODES = Object.freeze({
35
35
  SIGTERM: 143,
36
36
  });
37
37
  const INTERACTIVE_START_MODE_FLAGS = new Set([
38
- '-c',
39
38
  '-y',
40
39
  '--auto',
41
40
  '--auto-approve',
@@ -57,40 +56,33 @@ const LEGACY_MANIFEST_KEYS = Object.freeze([
57
56
  'releasedAt',
58
57
  ]);
59
58
  const RELEASE_NOTES_MANIFEST_KEYS = Object.freeze([
60
- 'install',
61
- 'latest',
62
- 'minSupported',
63
- 'name',
64
- 'notesUrl',
65
- 'releaseNotes',
66
- 'releasedAt',
59
+ 'install', 'latest', 'minSupported', 'name', 'notesUrl', 'releaseNotes', 'releasedAt',
67
60
  ]);
68
61
  const MANIFEST_KEYS = Object.freeze([
69
- 'install',
70
- 'integrity',
71
- 'latest',
72
- 'minSupported',
73
- 'name',
74
- 'notesUrl',
75
- 'releaseNotes',
76
- 'releasedAt',
62
+ 'install', 'integrity', 'latest', 'minSupported', 'name', 'notesUrl', 'releaseNotes', 'releasedAt',
77
63
  ]);
78
- const RELEASE_NOTES_MAX_COUNT = 8;
79
- const RELEASE_NOTE_MAX_BYTES = 240;
64
+
65
+ function parseReleaseNotes(value) {
66
+ if (!Array.isArray(value) || value.length > 8) return undefined;
67
+ const notes = [];
68
+ for (const note of value) {
69
+ if (!isBoundedText(note, 240)) return undefined;
70
+ notes.push(note);
71
+ }
72
+ return Object.freeze(notes);
73
+ }
74
+
75
+ function validIntegrity(value) {
76
+ if (typeof value !== 'string') return false;
77
+ const match = /^sha512-([A-Za-z0-9+/]+={0,2})$/u.exec(value);
78
+ if (!match) return false;
79
+ return Buffer.from(match[1], 'base64').length === 64;
80
+ }
80
81
  const ENDPOINT_LIMITS = new Map([
81
82
  [REGISTRY_URL, 1024 * 1024],
82
83
  [FALLBACK_MANIFEST_URL, 64 * 1024],
83
84
  ]);
84
85
 
85
- function isInternalPackagePinned(packageRoot) {
86
- try {
87
- const manifest = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
88
- return manifest?.blunUpdateChannel === 'internal';
89
- } catch {
90
- return false;
91
- }
92
- }
93
-
94
86
  function parseSemver(value) {
95
87
  if (typeof value !== 'string' || value.length > 128) return undefined;
96
88
  const match = SEMVER_PATTERN.exec(value);
@@ -210,7 +202,7 @@ function canonicalOfficialNotesUrl(value) {
210
202
 
211
203
  function isIsoTimestamp(value) {
212
204
  if (typeof value !== 'string') return false;
213
- const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?Z$/.exec(value);
205
+ const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,3})?Z$/.exec(value);
214
206
  if (!match) {
215
207
  return false;
216
208
  }
@@ -225,27 +217,6 @@ function isIsoTimestamp(value) {
225
217
  && date.getUTCSeconds() === Number(match[6]);
226
218
  }
227
219
 
228
- function parseReleaseNotes(value) {
229
- if (!Array.isArray(value) || value.length > RELEASE_NOTES_MAX_COUNT) return undefined;
230
- const notes = [];
231
- for (const note of value) {
232
- if (!isBoundedText(note, RELEASE_NOTE_MAX_BYTES)) return undefined;
233
- notes.push(note);
234
- }
235
- return Object.freeze(notes);
236
- }
237
-
238
- function validIntegrity(value) {
239
- if (typeof value !== 'string') return false;
240
- const match = /^sha512-([A-Za-z0-9+/]+={0,2})$/u.exec(value);
241
- if (!match) return false;
242
- try {
243
- return Buffer.from(match[1], 'base64').length === 64;
244
- } catch {
245
- return false;
246
- }
247
- }
248
-
249
220
  function parseFallbackManifest(value) {
250
221
  const record = exactDataRecord(value, MANIFEST_KEYS)
251
222
  || exactDataRecord(value, RELEASE_NOTES_MANIFEST_KEYS)
@@ -306,13 +277,8 @@ function resolveEffectiveRelease(currentVersion, registryTags, fallbackManifest)
306
277
  if (compareSemver(version, currentVersion) <= 0) return undefined;
307
278
 
308
279
  if (validFallback && compareSemver(validFallback.latest, version) === 0) {
309
- return {
310
- channel: 'stable',
311
- version,
312
- notesUrl: validFallback.notesUrl,
313
- ...(validFallback.releaseNotes === undefined
314
- ? {}
315
- : { releaseNotes: validFallback.releaseNotes }),
280
+ return { channel: 'stable', version, notesUrl: validFallback.notesUrl,
281
+ ...(validFallback.releaseNotes === undefined ? {} : { releaseNotes: validFallback.releaseNotes }),
316
282
  };
317
283
  }
318
284
  return { channel: 'stable', version };
@@ -396,54 +362,10 @@ function requestTrustedJson(url, options = {}) {
396
362
  });
397
363
  }
398
364
 
399
- function retryableUpdateSourceError(error) {
400
- const message = error instanceof Error ? error.message : String(error || '');
401
- if (message === 'UPDATE_REQUEST_TIMEOUT') return true;
402
- const statusMatch = /^UPDATE_HTTP_STATUS_(\d{3})$/u.exec(message);
403
- if (statusMatch) {
404
- const status = Number(statusMatch[1]);
405
- return status === 408 || status === 425 || status === 429 || status >= 500;
406
- }
407
- return new Set([
408
- 'EAI_AGAIN',
409
- 'ECONNREFUSED',
410
- 'ECONNRESET',
411
- 'ENETDOWN',
412
- 'ENETUNREACH',
413
- 'ENOTFOUND',
414
- 'EPIPE',
415
- 'ETIMEDOUT',
416
- ]).has(error?.code);
417
- }
418
-
419
- function sleepForUpdateRetry(delayMs) {
420
- return new Promise((resolve) => setTimeout(resolve, delayMs));
421
- }
422
-
423
- async function requestTrustedJsonWithRetry(url, options = {}) {
424
- const request = options.request || requestTrustedJson;
425
- const sleep = options.sleep || sleepForUpdateRetry;
426
- const configuredDelays = Array.isArray(options.retryDelaysMs)
427
- ? options.retryDelaysMs
428
- : UPDATE_SOURCE_RETRY_DELAYS_MS;
429
- const retryDelaysMs = configuredDelays
430
- .slice(0, UPDATE_SOURCE_RETRY_DELAYS_MS.length)
431
- .map((value) => (Number.isFinite(value) && value >= 0 ? Math.min(value, 2_000) : 0));
432
-
433
- for (let attempt = 0; ; attempt += 1) {
434
- try {
435
- return await request(url, options);
436
- } catch (error) {
437
- if (attempt >= retryDelaysMs.length || !retryableUpdateSourceError(error)) throw error;
438
- await sleep(retryDelaysMs[attempt]);
439
- }
440
- }
441
- }
442
-
443
- async function loadReleaseSources(options = {}) {
365
+ async function loadReleaseSources() {
444
366
  const [registry, fallback] = await Promise.allSettled([
445
- requestTrustedJsonWithRetry(REGISTRY_URL, options),
446
- requestTrustedJsonWithRetry(FALLBACK_MANIFEST_URL, options),
367
+ requestTrustedJson(REGISTRY_URL),
368
+ requestTrustedJson(FALLBACK_MANIFEST_URL),
447
369
  ]);
448
370
  return {
449
371
  registryDocument: registry.status === 'fulfilled' ? registry.value : undefined,
@@ -455,9 +377,8 @@ function statePath(blunDir) {
455
377
  return path.join(blunDir, STATE_FILE);
456
378
  }
457
379
 
458
- function readSnoozeState(blunDir, targetVersion, now = Date.now()) {
380
+ function readSnoozeState(blunDir, now = Date.now()) {
459
381
  try {
460
- if (!parseSemver(targetVersion)) return false;
461
382
  const filePath = statePath(blunDir);
462
383
  if (!fs.existsSync(filePath)) return false;
463
384
  securePrivateFile(filePath);
@@ -465,13 +386,10 @@ function readSnoozeState(blunDir, targetVersion, now = Date.now()) {
465
386
  if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 1_024) return false;
466
387
  const record = exactDataRecord(JSON.parse(fs.readFileSync(filePath, 'utf8')), [
467
388
  'snoozedUntil',
468
- 'targetVersion',
469
389
  'version',
470
390
  ]);
471
391
  if (!record
472
- || record.version !== 2
473
- || record.targetVersion !== targetVersion
474
- || !parseSemver(record.targetVersion)
392
+ || record.version !== 1
475
393
  || !Number.isSafeInteger(record.snoozedUntil)
476
394
  || record.snoozedUntil <= now
477
395
  || record.snoozedUntil > now + SNOOZE_MS) {
@@ -483,8 +401,7 @@ function readSnoozeState(blunDir, targetVersion, now = Date.now()) {
483
401
  }
484
402
  }
485
403
 
486
- function writeSnoozeState(blunDir, targetVersion, now = Date.now()) {
487
- if (!parseSemver(targetVersion)) throw new Error('INVALID_UPDATE_VERSION');
404
+ function writeSnoozeState(blunDir, now = Date.now()) {
488
405
  ensurePrivateDirectory(blunDir);
489
406
  const filePath = statePath(blunDir);
490
407
  const temporaryPath = path.join(
@@ -493,8 +410,7 @@ function writeSnoozeState(blunDir, targetVersion, now = Date.now()) {
493
410
  );
494
411
  try {
495
412
  writePrivateFile(temporaryPath, `${JSON.stringify({
496
- version: 2,
497
- targetVersion,
413
+ version: 1,
498
414
  snoozedUntil: now + SNOOZE_MS,
499
415
  })}\n`);
500
416
  const handle = fs.openSync(temporaryPath, 'r+');
@@ -566,18 +482,56 @@ function pendingUpdatePath(blunDir) {
566
482
  return path.join(blunDir, PENDING_UPDATE_FILE);
567
483
  }
568
484
 
485
+ function readPendingUpdate(blunDir) {
486
+ try {
487
+ const filePath = pendingUpdatePath(blunDir);
488
+ if (!fs.existsSync(filePath)) return undefined;
489
+ securePrivateFile(filePath);
490
+ const stat = fs.lstatSync(filePath);
491
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 1_024) return undefined;
492
+ const record = exactDataRecord(JSON.parse(fs.readFileSync(filePath, 'utf8')), [
493
+ 'targetVersion',
494
+ 'version',
495
+ ]);
496
+ if (!record || record.version !== 1 || !parseSemver(record.targetVersion)) return undefined;
497
+ return record.targetVersion;
498
+ } catch {
499
+ return undefined;
500
+ }
501
+ }
502
+
503
+ function writePendingUpdate(blunDir, targetVersion) {
504
+ if (!parseSemver(targetVersion)) throw new Error('INVALID_UPDATE_VERSION');
505
+ ensurePrivateDirectory(blunDir);
506
+ const filePath = pendingUpdatePath(blunDir);
507
+ const temporaryPath = path.join(
508
+ blunDir,
509
+ `.${PENDING_UPDATE_FILE}.${process.pid}.${randomUUID()}.tmp`,
510
+ );
511
+ try {
512
+ writePrivateFile(temporaryPath, `${JSON.stringify({
513
+ version: 1,
514
+ targetVersion,
515
+ })}\n`);
516
+ const handle = fs.openSync(temporaryPath, 'r+');
517
+ try {
518
+ fs.fsyncSync(handle);
519
+ } finally {
520
+ fs.closeSync(handle);
521
+ }
522
+ fs.renameSync(temporaryPath, filePath);
523
+ securePrivateFile(filePath);
524
+ } catch (error) {
525
+ fs.rmSync(temporaryPath, { force: true });
526
+ throw error;
527
+ }
528
+ }
529
+
569
530
  function clearPendingUpdate(blunDir) {
570
531
  fs.rmSync(pendingUpdatePath(blunDir), { force: true });
571
532
  }
572
533
 
573
- function writeCoreInstallSuccess(
574
- blunDir,
575
- fromVersion,
576
- version,
577
- releaseNotes,
578
- initiatedBy,
579
- now = Date.now(),
580
- ) {
534
+ function writeCoreInstallSuccess(blunDir, fromVersion, version, now = Date.now()) {
581
535
  if (!parseSemver(fromVersion) || !parseSemver(version)) {
582
536
  throw new Error('INVALID_UPDATE_VERSION');
583
537
  }
@@ -596,8 +550,6 @@ function writeCoreInstallSuccess(
596
550
  lastSuccess: {
597
551
  version,
598
552
  fromVersion,
599
- ...(releaseNotes === undefined ? {} : { releaseNotes }),
600
- initiatedBy,
601
553
  installedAt: new Date(now).toISOString(),
602
554
  notifiedAt: null,
603
555
  },
@@ -630,64 +582,6 @@ function installCommandText(version) {
630
582
  return `npm i -g ${PACKAGE_NAME}@${version}`;
631
583
  }
632
584
 
633
- function updateCopy(uiLocale) {
634
- const german = String(uiLocale || '').toLowerCase().startsWith('de');
635
- if (german) {
636
- return {
637
- available: (current, next) => `BLUN Code-Update verfügbar: ${current} -> ${next}`,
638
- current: (version) => `Kein Update verfügbar. Installiert: ${version} · Aktuell: ${version}.`,
639
- enter: 'Enter drücken, um fortzufahren',
640
- failed: (code) => `Update fehlgeschlagen (Code ${code}).`,
641
- invalidCurrentVersion: 'Die installierte Versionsnummer ist ungültig. Das Update wurde nicht gestartet.',
642
- updateBusy: 'Update gesperrt. Beende laufende King-Sitzungen nach Abschluss ihrer Arbeit regulär und warte, bis andere Updates fertig sind. Bleibt die Sperre bestehen, muss ihr Zustand geprüft werden.',
643
- leaseUnavailable: 'Die Updatesperre konnte nicht geprüft werden. Das Update wurde nicht gestartet.',
644
- privateHomeUnavailable: 'Das private BLUN-Verzeichnis konnte nicht abgesichert werden. Das Update wurde nicht gestartet.',
645
- installerUnavailable: 'Der geschützte Installer konnte nicht vorbereitet werden.',
646
- install: (version) => `Jetzt aktualisieren (führt \`${installCommandText(version)}\` aus)`,
647
- installFailed: (code) => `Update fehlgeschlagen (Code ${code}). Die vorhandene Version wird gestartet.`,
648
- installed: 'Installation geprüft',
649
- installedContinue: (current, next) => `Update ${current} -> ${next} erfolgreich installiert. Die letzte Sitzung wird mit der neuen Version fortgesetzt.`,
650
- installedRestart: (current, next) => `Update ${current} -> ${next} erfolgreich installiert. Starte BLUN Code neu, um die neue Version zu verwenden.`,
651
- installerReady: 'Installer bereit',
652
- installing: 'Paket wird installiert',
653
- invalidTarget: (version) => `Kein sicherer Update-Zielstand verfügbar. Installiert: ${version}.`,
654
- nextRelease: 'Auf den nächsten Release warten',
655
- notes: 'Versionshinweise',
656
- skip: 'Überspringen',
657
- startupNoticeFailed: (version) => `Update ${version} wurde installiert, aber die Startmeldung konnte nicht gespeichert werden.`,
658
- updateChecked: 'Update geprüft',
659
- verificationFailed: 'Das Update konnte nicht verifiziert werden.',
660
- verificationRestart: 'Update konnte nicht verifiziert werden. Starte BLUN Code neu.',
661
- };
662
- }
663
- return {
664
- available: (current, next) => `BLUN Code update available: ${current} -> ${next}`,
665
- current: (version) => `No update available. Installed: ${version} · Current: ${version}.`,
666
- enter: 'Press Enter to continue',
667
- failed: (code) => `Update failed (code ${code}).`,
668
- invalidCurrentVersion: 'The installed version number is invalid. The update has not started.',
669
- updateBusy: 'Update blocked. Finish and close running King sessions normally, and wait for other updates to finish. If it remains blocked, the lock state needs to be checked.',
670
- leaseUnavailable: 'The update lock could not be checked. The update has not started.',
671
- privateHomeUnavailable: 'The private BLUN directory could not be secured. The update has not started.',
672
- installerUnavailable: 'The protected installer could not be prepared.',
673
- install: (version) => `Update now (runs \`${installCommandText(version)}\`)`,
674
- installFailed: (code) => `Update failed (code ${code}). The installed version will start.`,
675
- installed: 'Installation verified',
676
- installedContinue: (current, next) => `Update ${current} -> ${next} installed successfully. The last session will continue with the new version.`,
677
- installedRestart: (current, next) => `Update ${current} -> ${next} installed successfully. Restart BLUN Code to use the new version.`,
678
- installerReady: 'Installer ready',
679
- installing: 'Installing package',
680
- invalidTarget: (version) => `No safe update target is available. Installed: ${version}.`,
681
- nextRelease: 'Wait for the next release',
682
- notes: 'Release notes',
683
- skip: 'Skip',
684
- startupNoticeFailed: (version) => `Update ${version} was installed, but the startup notice could not be saved.`,
685
- updateChecked: 'Update checked',
686
- verificationFailed: 'The update could not be verified.',
687
- verificationRestart: 'The update could not be verified. Restart BLUN Code.',
688
- };
689
- }
690
-
691
585
  function createUpdateProgress(output) {
692
586
  const enabled = output?.isTTY === true;
693
587
  const phaseCount = 4;
@@ -713,14 +607,7 @@ function createUpdateProgress(output) {
713
607
  return update;
714
608
  }
715
609
 
716
- function promptUpdateAction({
717
- currentVersion,
718
- release,
719
- input,
720
- output,
721
- processRef = process,
722
- uiLocale = 'en',
723
- }) {
610
+ function promptUpdateAction({ currentVersion, release, input, output, locale = 'en', processRef = process }) {
724
611
  return new Promise((resolve, reject) => {
725
612
  let selected = 0;
726
613
  let settled = false;
@@ -733,14 +620,13 @@ function promptUpdateAction({
733
620
  const dim = '\u001B[2m';
734
621
  const underline = '\u001B[4m';
735
622
  const reset = '\u001B[0m';
736
- const copy = updateCopy(uiLocale);
737
623
  const actions = [
738
624
  {
739
625
  choice: 'install',
740
- label: copy.install(release.version),
626
+ label: updateText(locale, 'install', { command: installCommandText(release.version) }),
741
627
  },
742
- { choice: 'skip-once', label: copy.skip },
743
- { choice: 'skip-version', label: copy.nextRelease },
628
+ { choice: 'skip-once', label: updateText(locale, 'skipOnce') },
629
+ { choice: 'skip-version', label: updateText(locale, 'skipVersion') },
744
630
  ];
745
631
  const signalHandlers = new Map();
746
632
 
@@ -750,7 +636,7 @@ function promptUpdateAction({
750
636
  const line = `${selected === index ? '›' : ' '} ${index + 1}. ${actions[index].label}`;
751
637
  output.write(`\r\u001B[2K${selected === index ? cyan : ''}${line}${selected === index ? reset : ''}\n`);
752
638
  }
753
- output.write(`\r\u001B[2K${dim}${copy.enter}${reset}\n`);
639
+ output.write(`\r\u001B[2K${dim}${updateText(locale, 'confirm')}${reset}\n`);
754
640
  };
755
641
  const cleanup = () => {
756
642
  if (escapeTimer !== undefined) clearTimeout(escapeTimer);
@@ -905,9 +791,9 @@ function promptUpdateAction({
905
791
  signalHandlers.set(signal, handler);
906
792
  processRef.once(signal, handler);
907
793
  }
908
- output.write(`\n${copy.available(currentVersion, release.version)}\n`);
794
+ output.write(`\n${updateText(locale, 'available', { currentVersion, targetVersion: release.version })}\n`);
909
795
  if (release.notesUrl) {
910
- output.write(`${dim}${copy.notes}:${reset} ${underline}${release.notesUrl}${reset}\n`);
796
+ output.write(`${dim}${updateText(locale, 'releaseNotes')}${reset} ${underline}${release.notesUrl}${reset}\n`);
911
797
  }
912
798
  output.write('\n');
913
799
  cursorHidden = true;
@@ -1365,28 +1251,17 @@ function noReleaseReason(currentVersion, registryTags, fallbackManifest) {
1365
1251
  return parseSemver(latest) || fallbackManifest ? 'current' : 'unavailable';
1366
1252
  }
1367
1253
 
1368
- function explicitNoTarget(stdout, reason, currentVersion, uiLocale) {
1369
- const copy = updateCopy(uiLocale);
1370
- stdout.write(reason === 'current'
1371
- ? `${copy.current(currentVersion)}\n`
1372
- : `${copy.invalidTarget(currentVersion)}\n`);
1254
+ function explicitNoTarget(stdout, reason, currentVersion, locale) {
1255
+ stdout.write(`${updateText(locale, reason === 'current' ? 'noUpdate' : 'noTarget', { currentVersion })}\n`);
1373
1256
  return { kind: 'current', reason };
1374
1257
  }
1375
1258
 
1376
- function explicitFailure(stderr, reason, exitCode, uiLocale) {
1377
- const copy = updateCopy(uiLocale);
1259
+ function explicitFailure(stderr, reason, exitCode, locale) {
1378
1260
  const hasExitCode = Number.isInteger(exitCode) && exitCode !== 0;
1379
1261
  if (hasExitCode) {
1380
- stderr.write(`${copy.failed(exitCode)}\n`);
1262
+ stderr.write(`${updateText(locale, 'failedCode', { exitCode })}\n`);
1381
1263
  } else {
1382
- const messages = new Map([
1383
- ['invalid_current_version', copy.invalidCurrentVersion],
1384
- ['update_in_progress', copy.updateBusy],
1385
- ['lease_unavailable', copy.leaseUnavailable],
1386
- ['private_home_unavailable', copy.privateHomeUnavailable],
1387
- ['installer_unavailable', copy.installerUnavailable],
1388
- ]);
1389
- stderr.write(`${messages.get(reason) || copy.verificationFailed}\n`);
1264
+ stderr.write(`${updateText(locale, 'verifyFailed')}\n`);
1390
1265
  }
1391
1266
  return {
1392
1267
  kind: 'failed',
@@ -1395,6 +1270,19 @@ function explicitFailure(stderr, reason, exitCode, uiLocale) {
1395
1270
  };
1396
1271
  }
1397
1272
 
1273
+ function queueExplicitUpdate(blunDir, release, stdout, stderr, locale) {
1274
+ try {
1275
+ ensurePrivateDirectory(blunDir);
1276
+ writePendingUpdate(blunDir, release.version);
1277
+ } catch {
1278
+ return explicitFailure(stderr, 'private_home_unavailable', undefined, locale);
1279
+ }
1280
+ stdout.write(
1281
+ `${updateText(locale, 'queued', { targetVersion: release.version })}\n`,
1282
+ );
1283
+ return { kind: 'queued', version: release.version };
1284
+ }
1285
+
1398
1286
  async function runUpdateFlow(options, explicitUpdate) {
1399
1287
  const {
1400
1288
  currentVersion,
@@ -1405,26 +1293,27 @@ async function runUpdateFlow(options, explicitUpdate) {
1405
1293
  stderr,
1406
1294
  blunDir,
1407
1295
  } = options;
1408
- const uiLocale = options.uiLocale || 'en';
1409
- const copy = updateCopy(uiLocale);
1296
+ const locale = resolveUpdateLocale(options);
1410
1297
  if (!explicitUpdate && !isInteractiveUpdateStart({ argv, env, stdin, stdout })) {
1411
1298
  return { kind: 'continue', reason: 'not_interactive' };
1412
1299
  }
1413
1300
  if (!parseSemver(currentVersion)) {
1414
1301
  return explicitUpdate
1415
- ? explicitFailure(stderr, 'invalid_current_version', undefined, uiLocale)
1302
+ ? explicitFailure(stderr, 'invalid_current_version', undefined, locale)
1416
1303
  : { kind: 'continue', reason: 'invalid_current_version' };
1417
1304
  }
1418
1305
 
1306
+ let pendingVersion = readPendingUpdate(blunDir);
1307
+ if (pendingVersion !== undefined && compareSemver(currentVersion, pendingVersion) >= 0) {
1308
+ clearPendingUpdate(blunDir);
1309
+ pendingVersion = undefined;
1310
+ }
1419
1311
  const now = (options.now || Date.now)();
1312
+ if (!explicitUpdate && pendingVersion === undefined && readSnoozeState(blunDir, now)) {
1313
+ return { kind: 'continue', reason: 'snoozed' };
1314
+ }
1420
1315
 
1421
1316
  const packageRoot = path.resolve(options.packageRoot || path.resolve(__dirname, '..'));
1422
- if (isInternalPackagePinned(packageRoot)) {
1423
- if (explicitUpdate) explicitNoTarget(stdout, 'current', currentVersion, uiLocale);
1424
- return explicitUpdate
1425
- ? { kind: 'current', reason: 'internal_channel' }
1426
- : { kind: 'continue', reason: 'internal_channel' };
1427
- }
1428
1317
  let leaseResult;
1429
1318
  const ownsNoticeLease = options.noticeLease === undefined;
1430
1319
  if (ownsNoticeLease) {
@@ -1432,7 +1321,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1432
1321
  leaseResult = await (options.acquireLease || tryAcquireUpdateLease)({ packageRoot });
1433
1322
  } catch {
1434
1323
  return explicitUpdate
1435
- ? explicitFailure(stderr, 'lease_unavailable', undefined, uiLocale)
1324
+ ? explicitFailure(stderr, 'lease_unavailable', undefined, locale)
1436
1325
  : { kind: 'continue', reason: 'lease_unavailable' };
1437
1326
  }
1438
1327
  } else {
@@ -1444,7 +1333,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1444
1333
  stderr,
1445
1334
  leaseResult?.reason === 'busy' ? 'update_in_progress' : 'lease_unavailable',
1446
1335
  undefined,
1447
- uiLocale,
1336
+ locale,
1448
1337
  );
1449
1338
  }
1450
1339
  return leaseResult?.reason === 'busy'
@@ -1455,12 +1344,17 @@ async function runUpdateFlow(options, explicitUpdate) {
1455
1344
  let installerSession;
1456
1345
 
1457
1346
  try {
1347
+ if (!explicitUpdate
1348
+ && pendingVersion === undefined
1349
+ && readSnoozeState(blunDir, (options.now || Date.now)())) {
1350
+ return { kind: 'continue', reason: 'snoozed' };
1351
+ }
1458
1352
  let sources;
1459
1353
  try {
1460
1354
  sources = await (options.loadReleaseSources || loadReleaseSources)();
1461
1355
  } catch {
1462
1356
  return explicitUpdate
1463
- ? explicitNoTarget(stdout, 'unavailable', currentVersion, uiLocale)
1357
+ ? explicitNoTarget(stdout, 'unavailable', currentVersion, locale)
1464
1358
  : { kind: 'continue', reason: 'unavailable' };
1465
1359
  }
1466
1360
  const registryTags = parseRegistryDocument(sources?.registryDocument);
@@ -1469,51 +1363,47 @@ async function runUpdateFlow(options, explicitUpdate) {
1469
1363
  if (!release) {
1470
1364
  const reason = noReleaseReason(currentVersion, registryTags, fallbackManifest);
1471
1365
  return explicitUpdate
1472
- ? explicitNoTarget(stdout, reason, currentVersion, uiLocale)
1366
+ ? explicitNoTarget(stdout, reason, currentVersion, locale)
1473
1367
  : { kind: 'continue', reason };
1474
1368
  }
1475
- if (!explicitUpdate
1476
- && readSnoozeState(blunDir, release.version, now)) {
1477
- return { kind: 'continue', reason: 'snoozed' };
1478
- }
1369
+ const queuedForRelease = pendingVersion === release.version;
1479
1370
  const initialInstallLease = await probeInstallLease(options, packageRoot);
1480
1371
  if (initialInstallLease === 'busy') {
1481
1372
  return explicitUpdate
1482
- ? explicitFailure(stderr, 'update_in_progress', undefined, uiLocale)
1373
+ ? queueExplicitUpdate(blunDir, release, stdout, stderr, locale)
1483
1374
  : { kind: 'update_in_progress' };
1484
1375
  }
1485
1376
  if (initialInstallLease !== 'clear') {
1486
1377
  return explicitUpdate
1487
- ? explicitFailure(stderr, 'lease_unavailable', undefined, uiLocale)
1378
+ ? explicitFailure(stderr, 'lease_unavailable', undefined, locale)
1488
1379
  : { kind: 'continue', reason: 'lease_unavailable' };
1489
1380
  }
1490
- if (!explicitUpdate
1491
- && readSkippedVersion(blunDir) === release.version) {
1381
+ if (!explicitUpdate && !queuedForRelease && readSkippedVersion(blunDir) === release.version) {
1492
1382
  return { kind: 'continue', reason: 'skipped_version' };
1493
1383
  }
1494
- if (explicitUpdate) {
1384
+ if (explicitUpdate || queuedForRelease) {
1495
1385
  try {
1496
1386
  ensurePrivateDirectory(blunDir);
1497
1387
  } catch {
1498
- return explicitFailure(stderr, 'private_home_unavailable', undefined, uiLocale);
1388
+ return explicitFailure(stderr, 'private_home_unavailable', undefined, locale);
1499
1389
  }
1500
1390
  }
1501
1391
  try {
1502
1392
  lease.assertOwned();
1503
1393
  } catch {
1504
1394
  return explicitUpdate
1505
- ? explicitFailure(stderr, 'update_in_progress', undefined, uiLocale)
1395
+ ? explicitFailure(stderr, 'update_in_progress', undefined, locale)
1506
1396
  : { kind: 'update_in_progress' };
1507
1397
  }
1508
1398
  const prePromptInstallLease = await probeInstallLease(options, packageRoot);
1509
1399
  if (prePromptInstallLease === 'busy') {
1510
1400
  return explicitUpdate
1511
- ? explicitFailure(stderr, 'update_in_progress', undefined, uiLocale)
1401
+ ? queueExplicitUpdate(blunDir, release, stdout, stderr, locale)
1512
1402
  : { kind: 'update_in_progress' };
1513
1403
  }
1514
1404
  if (prePromptInstallLease !== 'clear') {
1515
1405
  return explicitUpdate
1516
- ? explicitFailure(stderr, 'lease_unavailable', undefined, uiLocale)
1406
+ ? explicitFailure(stderr, 'lease_unavailable', undefined, locale)
1517
1407
  : { kind: 'continue', reason: 'lease_unavailable' };
1518
1408
  }
1519
1409
  if (!options.installVersion) {
@@ -1523,7 +1413,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1523
1413
  );
1524
1414
  if (!installerSession?.ready) {
1525
1415
  if (explicitUpdate) {
1526
- return explicitFailure(stderr, 'installer_unavailable', undefined, uiLocale);
1416
+ return explicitFailure(stderr, 'installer_unavailable', undefined, locale);
1527
1417
  }
1528
1418
  return installerSession?.reason === 'failed'
1529
1419
  ? { kind: 'continue', reason: 'installer_unavailable' }
@@ -1531,7 +1421,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1531
1421
  }
1532
1422
  }
1533
1423
  let action;
1534
- if (explicitUpdate || options.autoInstall === true) {
1424
+ if (explicitUpdate || queuedForRelease) {
1535
1425
  action = 'install';
1536
1426
  } else {
1537
1427
  try {
@@ -1540,17 +1430,14 @@ async function runUpdateFlow(options, explicitUpdate) {
1540
1430
  release,
1541
1431
  input: stdin,
1542
1432
  output: stdout,
1543
- uiLocale,
1433
+ locale,
1544
1434
  });
1545
1435
  } catch {
1546
1436
  return { kind: 'continue', reason: 'prompt_failed' };
1547
1437
  }
1548
1438
  }
1549
1439
  if (action !== 'install') {
1550
- if (installerSession?.ready) {
1551
- await installerSession.cancel();
1552
- installerSession = undefined;
1553
- }
1440
+ if (installerSession?.ready) await installerSession.cancel();
1554
1441
  if (action === 'skip-once') {
1555
1442
  return { kind: 'continue', reason: 'skipped_once' };
1556
1443
  }
@@ -1563,7 +1450,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1563
1450
  return { kind: 'continue', reason: 'skipped_version' };
1564
1451
  }
1565
1452
  try {
1566
- writeSnoozeState(blunDir, release.version, (options.now || Date.now)());
1453
+ writeSnoozeState(blunDir, (options.now || Date.now)());
1567
1454
  } catch {
1568
1455
  // A failed preference write must not block the existing console.
1569
1456
  }
@@ -1571,18 +1458,18 @@ async function runUpdateFlow(options, explicitUpdate) {
1571
1458
  }
1572
1459
 
1573
1460
  const updateProgress = createUpdateProgress(stdout);
1574
- updateProgress(1, copy.updateChecked);
1575
- updateProgress(2, copy.installerReady);
1461
+ updateProgress(1, updateText(locale, 'progressChecked'));
1462
+ updateProgress(2, updateText(locale, 'installerReady'));
1576
1463
 
1577
1464
  try {
1578
1465
  lease.assertOwned();
1579
1466
  } catch {
1580
1467
  return explicitUpdate
1581
- ? explicitFailure(stderr, 'update_in_progress', undefined, uiLocale)
1468
+ ? explicitFailure(stderr, 'update_in_progress', undefined, locale)
1582
1469
  : { kind: 'update_in_progress' };
1583
1470
  }
1584
1471
  let installResult;
1585
- updateProgress(3, copy.installing);
1472
+ updateProgress(3, updateText(locale, 'installing'));
1586
1473
  try {
1587
1474
  installResult = options.installVersion
1588
1475
  ? await options.installVersion(release.version)
@@ -1595,48 +1482,42 @@ async function runUpdateFlow(options, explicitUpdate) {
1595
1482
  || installResult?.unknownState === true) {
1596
1483
  updateProgress.finish();
1597
1484
  return explicitUpdate
1598
- ? explicitFailure(stderr, 'update_in_progress', undefined, uiLocale)
1485
+ ? explicitFailure(stderr, 'update_in_progress', undefined, locale)
1599
1486
  : { kind: 'update_in_progress' };
1600
1487
  }
1601
1488
  if (installResult?.code === 0 && installResult?.verified === true) {
1602
- updateProgress(4, copy.installed);
1489
+ updateProgress(4, updateText(locale, 'installVerified'));
1603
1490
  clearPendingUpdate(blunDir);
1604
1491
  try {
1605
1492
  writeCoreInstallSuccess(
1606
1493
  blunDir,
1607
1494
  currentVersion,
1608
1495
  release.version,
1609
- release.releaseNotes,
1610
- explicitUpdate ? 'manual' : options.autoInstall === true ? 'startup_auto' : 'startup_prompt',
1611
1496
  (options.now || Date.now)(),
1612
1497
  );
1613
1498
  } catch {
1614
- stderr.write(`${copy.startupNoticeFailed(release.version)}\n`);
1499
+ stderr.write(
1500
+ `${updateText(locale, 'stateWarning', { targetVersion: release.version })}\n`,
1501
+ );
1615
1502
  }
1616
- const continuesLastSession = Array.isArray(options.argv)
1617
- && options.argv.length === 1
1618
- && options.argv[0] === '-c';
1619
- stdout.write(`${continuesLastSession
1620
- ? copy.installedContinue(currentVersion, release.version)
1621
- : copy.installedRestart(currentVersion, release.version)}\n`);
1622
- if (release.notesUrl) stdout.write(`${copy.notes}: ${release.notesUrl}\n`);
1623
- return {
1624
- kind: 'installed',
1625
- version: release.version,
1626
- };
1503
+ stdout.write(
1504
+ `${updateText(locale, 'success', { currentVersion, targetVersion: release.version })}\n`,
1505
+ );
1506
+ if (release.notesUrl) stdout.write(`${updateText(locale, 'releaseNotes')} ${release.notesUrl}\n`);
1507
+ return { kind: 'installed', version: release.version };
1627
1508
  }
1628
1509
 
1629
1510
  if (Number.isInteger(installResult?.code) && installResult.code !== 0) {
1630
1511
  updateProgress.finish();
1631
1512
  if (explicitUpdate) {
1632
- return explicitFailure(stderr, 'install_failed', installResult.code, uiLocale);
1513
+ return explicitFailure(stderr, 'install_failed', installResult.code, locale);
1633
1514
  }
1634
- stderr.write(`${copy.installFailed(installResult.code)}\n`);
1515
+ stderr.write(`${updateText(locale, 'failedContinue', { exitCode: installResult.code })}\n`);
1635
1516
  return { kind: 'continue', reason: 'install_failed', exitCode: installResult.code };
1636
1517
  }
1637
1518
  updateProgress.finish();
1638
- if (explicitUpdate) return explicitFailure(stderr, 'verification_failed', undefined, uiLocale);
1639
- stderr.write(`${copy.verificationRestart}\n`);
1519
+ if (explicitUpdate) return explicitFailure(stderr, 'verification_failed', undefined, locale);
1520
+ stderr.write(`${updateText(locale, 'verifyRestart')}\n`);
1640
1521
  return { kind: 'update_in_progress' };
1641
1522
  } finally {
1642
1523
  if (installerSession?.ready) {
@@ -1652,7 +1533,7 @@ async function runUpdateFlow(options, explicitUpdate) {
1652
1533
  }
1653
1534
  }
1654
1535
 
1655
- async function runExplicitUpdate(options) {
1536
+ function runExplicitUpdate(options) {
1656
1537
  return runUpdateFlow(options, true);
1657
1538
  }
1658
1539
 
@@ -1668,7 +1549,6 @@ module.exports = {
1668
1549
  compareSemver,
1669
1550
  createInstallInvocation,
1670
1551
  installPinnedVersion,
1671
- isInternalPackagePinned,
1672
1552
  preparePinnedInstaller,
1673
1553
  isInteractiveUpdateStart,
1674
1554
  loadReleaseSources,
@@ -1678,10 +1558,11 @@ module.exports = {
1678
1558
  readSkippedVersion,
1679
1559
  readSnoozeState,
1680
1560
  requestTrustedJson,
1681
- requestTrustedJsonWithRetry,
1682
1561
  resolveEffectiveRelease,
1562
+ resolveUpdateLocale,
1683
1563
  runExplicitUpdate,
1684
1564
  runUpdateNotice,
1565
+ updateText,
1685
1566
  writeSkippedVersion,
1686
1567
  writeSnoozeState,
1687
1568
  };