blun-king-cli 9.1.624 → 9.1.625

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 (142) hide show
  1. package/CHANGELOG.md +62 -213
  2. package/LIESMICH.txt +57 -74
  3. package/README.md +76 -119
  4. package/agent-spine-plugin/scripts/check-install.js +4 -4
  5. package/agent-spine-plugin/src/hook.js +0 -4
  6. package/agent-spine-plugin/src/lib/documents.js +1 -1
  7. package/agent-spine-plugin/src/lib/hook-context.js +0 -1
  8. package/agent-spine-plugin/src/lib/host-instruction-budget.js +2 -1
  9. package/agent-spine-plugin/src/lib/preflight.js +9 -38
  10. package/agent-spine-plugin/src/lib/source-roots.js +1 -1
  11. package/bin/agentspine-king-goal-inbox.mjs +127 -127
  12. package/bin/agentspine-king-goal-intake.mjs +106 -106
  13. package/bin/agentspine-king-host-runner.mjs +109 -109
  14. package/bin/agentspine-king-snapshot-policy.cjs +80 -80
  15. package/bin/agentspine-king-status-policy.mjs +226 -226
  16. package/bin/agentspine-king-worker-host.mjs +160 -160
  17. package/bin/core-bootstrap.js +71 -100
  18. package/bin/launcher-mode.js +93 -93
  19. package/bin/launcher-restart-policy.cjs +131 -131
  20. package/bin/launcher-runtime.js +89 -254
  21. package/bin/managed-node.js +186 -186
  22. package/bin/managed-plugin-selection.cjs +109 -116
  23. package/bin/native-module-repair.js +201 -201
  24. package/bin/node-runtime.js +34 -34
  25. package/bin/node-version.js +49 -49
  26. package/bin/plugin-bootstrap.js +149 -172
  27. package/bin/private-paths.js +1578 -1624
  28. package/bin/runtime-exit-ledger.cjs +144 -144
  29. package/bin/runtime-exit-ledger.d.cts +23 -23
  30. package/bin/standard-tools-bootstrap.js +277 -272
  31. package/bin/turn-thinking-policy.cjs +82 -82
  32. package/bin/update-copy.js +200 -200
  33. package/bin/update-lease.js +597 -599
  34. package/bin/update-notice.js +1568 -1568
  35. package/bin/verify-agent-behavior.cjs +122 -122
  36. package/bin/verify-agent-components.cjs +104 -104
  37. package/bin/verify-bundled-agent-sources.cjs +91 -96
  38. package/bin/windows-node-crash-dump.cjs +289 -289
  39. package/blun.mjs +187640 -180475
  40. package/bundled-agent-sources.json +26 -30
  41. package/codebase-index/codebase_index.py +462 -470
  42. package/dist-web/assets/{CodeBlockNode-TKKkJX8L.js → CodeBlockNode-BMbuG85x.js} +1 -1
  43. package/dist-web/assets/{CodeBlockShell.vue_vue_type_style_index_0_lang-CUj2Ds5x.js → CodeBlockShell.vue_vue_type_style_index_0_lang-C1fv7l_Z.js} +1 -1
  44. package/dist-web/assets/DesignSystemView-6HgAUEmC.css +1 -0
  45. package/dist-web/assets/DesignSystemView-CEEBqXSX.js +12 -0
  46. package/dist-web/assets/{Tooltip-CTWv7WCU.js → Tooltip--YoauJ24.js} +1 -1
  47. package/dist-web/assets/{abnfDiagram-N423BO3Z-DA8V8Zjh.js → abnfDiagram-N423BO3Z-DZvBWkRg.js} +1 -1
  48. package/dist-web/assets/{arc-YtddKbdY.js → arc-B04JATeX.js} +1 -1
  49. package/dist-web/assets/{architectureDiagram-T3A2C74G-CGEiObmo.js → architectureDiagram-T3A2C74G-DmYnMep2.js} +1 -1
  50. package/dist-web/assets/{blockDiagram-VBNYF7ZC-Bd5Vt50e.js → blockDiagram-VBNYF7ZC-DJ1gPS1C.js} +1 -1
  51. package/dist-web/assets/{c4Diagram-5PPSVZJV-D2ApPM54.js → c4Diagram-5PPSVZJV-DmjxvUbd.js} +1 -1
  52. package/dist-web/assets/channel-472fcEvw.js +1 -0
  53. package/dist-web/assets/{chunk-2GRJ4B5K-BDcIEZSl.js → chunk-2GRJ4B5K-AB0raj3I.js} +1 -1
  54. package/dist-web/assets/{chunk-2Q5K7J3B-6aSabCX7.js → chunk-2Q5K7J3B-Drf039vM.js} +1 -1
  55. package/dist-web/assets/{chunk-5RXB4S5H-BFRQvIJS.js → chunk-5RXB4S5H-D5ILttmz.js} +1 -1
  56. package/dist-web/assets/{chunk-5VM5RSS4-ChAa-DNY.js → chunk-5VM5RSS4-DrLSdi8y.js} +1 -1
  57. package/dist-web/assets/{chunk-6Q2QTUOP-BIfrb2Jc.js → chunk-6Q2QTUOP-LiaqdEOQ.js} +1 -1
  58. package/dist-web/assets/{chunk-GF5L2VYU-BR0gvtWI.js → chunk-GF5L2VYU-AIYkb--o.js} +1 -1
  59. package/dist-web/assets/{chunk-JWPE2WC7-BgXKsx5E.js → chunk-JWPE2WC7-CogdNl0i.js} +1 -1
  60. package/dist-web/assets/{chunk-KBJHAD2P-I8mrZhpz.js → chunk-KBJHAD2P-DHjpNtZv.js} +1 -1
  61. package/dist-web/assets/{chunk-RYQCIY6F-BMPaem92.js → chunk-RYQCIY6F-BUSOqH2X.js} +1 -1
  62. package/dist-web/assets/{chunk-XXDRQBXY-COy0J-0j.js → chunk-XXDRQBXY-BpoMV0bh.js} +1 -1
  63. package/dist-web/assets/classDiagram-JCYQIIEL-BTZeLngj.js +1 -0
  64. package/dist-web/assets/classDiagram-v2-OCEON4UE-BTZeLngj.js +1 -0
  65. package/dist-web/assets/{cose-bilkent-JH36ORCC-MosTTRdo.js → cose-bilkent-JH36ORCC-BJr2I61o.js} +1 -1
  66. package/dist-web/assets/{cynefin-VYW2F7L2-5tjPgrkP.js → cynefin-VYW2F7L2-HtysQZ4A.js} +1 -1
  67. package/dist-web/assets/{cynefinDiagram-MW4NZA55-CbDcdInR.js → cynefinDiagram-MW4NZA55-CcpC_2uv.js} +1 -1
  68. package/dist-web/assets/{dagre-VZM6K2ZE-YaBom1ZH.js → dagre-VZM6K2ZE-D8Ao0LUg.js} +1 -1
  69. package/dist-web/assets/{diagram-7IWD3JNH-Da4m-Hgz.js → diagram-7IWD3JNH-BITiLhjX.js} +1 -1
  70. package/dist-web/assets/{diagram-B4RE2ZJO-CAUUegxg.js → diagram-B4RE2ZJO-CJtwfy9f.js} +1 -1
  71. package/dist-web/assets/{diagram-LBJQPF4R-o21mWKG4.js → diagram-LBJQPF4R-BsVTh6w8.js} +1 -1
  72. package/dist-web/assets/{diagram-Q27KOJAE-BA3z3sXf.js → diagram-Q27KOJAE-pA_MUCUf.js} +1 -1
  73. package/dist-web/assets/{diagram-UB23O5K3-CGRdSSDK.js → diagram-UB23O5K3-CIY8z7vu.js} +1 -1
  74. package/dist-web/assets/{ebnfDiagram-BXEA7PRR-Bw-iU9FP.js → ebnfDiagram-BXEA7PRR-C3FMioqp.js} +1 -1
  75. package/dist-web/assets/{erDiagram-JOGREHBK-BwM1yiR0.js → erDiagram-JOGREHBK-CzoyKmKc.js} +1 -1
  76. package/dist-web/assets/{flowDiagram-UKHOOZJN-z05eOR1Q.js → flowDiagram-UKHOOZJN-DOqfushy.js} +1 -1
  77. package/dist-web/assets/{ganttDiagram-PKOTCBZU-BMUubNTl.js → ganttDiagram-PKOTCBZU-Cf9XQSWl.js} +1 -1
  78. package/dist-web/assets/{gitGraphDiagram-DS77QQ5N-Dccbi1wU.js → gitGraphDiagram-DS77QQ5N-DHUDofE5.js} +1 -1
  79. package/dist-web/assets/{index-h0KEOmkU.js → index-B6qEMQMx.js} +14 -14
  80. package/dist-web/assets/{index-C9eDH3u-.css → index-BmKj7CB1.css} +1 -1
  81. package/dist-web/assets/{index-BBbC5LRF.js → index-DokxDX1w.js} +1 -1
  82. package/dist-web/assets/{index-D48p0M2S.js → index-auojtiAA.js} +2 -2
  83. package/dist-web/assets/{index10-Qbuw1N6u.js → index10-Drb2n5e5.js} +1 -1
  84. package/dist-web/assets/{index11-g8v025wN.js → index11-Cx-aV4G2.js} +1 -1
  85. package/dist-web/assets/{index5-BYNcV8BY.js → index5-Dg3qGTyH.js} +1 -1
  86. package/dist-web/assets/{index6-BetANtnV.js → index6-BgvtIICP.js} +1 -1
  87. package/dist-web/assets/{index7-BcPbgCKN.js → index7-uEnniPQG.js} +1 -1
  88. package/dist-web/assets/{index8-B1lp-RvF.js → index8-h4IKc0ek.js} +2 -2
  89. package/dist-web/assets/{infoDiagram-6WML65LV-BF_pbUnN.js → infoDiagram-6WML65LV-D-3tvEiJ.js} +1 -1
  90. package/dist-web/assets/{ishikawaDiagram-WSZJBQD7-Dedv4urS.js → ishikawaDiagram-WSZJBQD7-DIIBNv7a.js} +1 -1
  91. package/dist-web/assets/{journeyDiagram-NVQOT4AX-B1Ex3b6o.js → journeyDiagram-NVQOT4AX-DP4r1Vlx.js} +1 -1
  92. package/dist-web/assets/{kanban-definition-27J2QSJJ-BtCGliBH.js → kanban-definition-27J2QSJJ-C3_Ztgxv.js} +1 -1
  93. package/dist-web/assets/{linear-ByItc8Qr.js → linear-DnqhIw-y.js} +1 -1
  94. package/dist-web/assets/{mermaid.core-B1M2O7nN.js → mermaid.core-xYUgBa3T.js} +4 -4
  95. package/dist-web/assets/{mindmap-definition-FAOFIHXS-D0UHKUyj.js → mindmap-definition-FAOFIHXS-l-dq-zfr.js} +1 -1
  96. package/dist-web/assets/{pegDiagram-VL7TDLO6-D7zYCVmG.js → pegDiagram-VL7TDLO6-C8vXQiaJ.js} +1 -1
  97. package/dist-web/assets/{pieDiagram-7S7Q4E2Y-Bd0i9CHa.js → pieDiagram-7S7Q4E2Y-CyNRSsI6.js} +1 -1
  98. package/dist-web/assets/{quadrantDiagram-CIZ2JOQS-MG-Ug47d.js → quadrantDiagram-CIZ2JOQS-D-w8AD_g.js} +1 -1
  99. package/dist-web/assets/{railroadDiagram-AXF67PYL-AZdl90Gj.js → railroadDiagram-AXF67PYL-BLkyQCWy.js} +1 -1
  100. package/dist-web/assets/{requirementDiagram-LRYGKXZP-DjplF9kt.js → requirementDiagram-LRYGKXZP-CEWO7XfT.js} +1 -1
  101. package/dist-web/assets/{sankeyDiagram-W5VNT64P-Bi9Zgfjs.js → sankeyDiagram-W5VNT64P-ByGoAaGj.js} +1 -1
  102. package/dist-web/assets/{sequenceDiagram-SI44F4Z6-ChEpdCvb.js → sequenceDiagram-SI44F4Z6-Bhn9GQtd.js} +1 -1
  103. package/dist-web/assets/{sizeCapture-X5ZJPWSS-B5RFUdaa.js → sizeCapture-X5ZJPWSS-jVKR9CTu.js} +1 -1
  104. package/dist-web/assets/{stateDiagram-OKZ733FA-BkRblSKp.js → stateDiagram-OKZ733FA-wW3XbegA.js} +1 -1
  105. package/dist-web/assets/stateDiagram-v2-UEYNNEHI-B8aids-Z.js +1 -0
  106. package/dist-web/assets/{swimlanes-SLNWSIFB-DLXH6Zhc.js → swimlanes-SLNWSIFB-B8QyFS7G.js} +2 -2
  107. package/dist-web/assets/swimlanesDiagram-ULZ7WXOC-B8XAkdSm.js +8 -0
  108. package/dist-web/assets/{timeline-definition-Z64GVDOM-C_N88siO.js → timeline-definition-Z64GVDOM-DpvxS-1A.js} +1 -1
  109. package/dist-web/assets/{vennDiagram-T6HMQDX7-DMsnvDt0.js → vennDiagram-T6HMQDX7-BzGM0ihY.js} +1 -1
  110. package/dist-web/assets/{vue.runtime.esm-bundler-B-3uIy85.js → vue.runtime.esm-bundler-BOcpwIX1.js} +1 -1
  111. package/dist-web/assets/{wardleyDiagram-T6FBY63Y-C9SJIPzq.js → wardleyDiagram-T6FBY63Y-2DKAOs5e.js} +1 -1
  112. package/dist-web/assets/{xychartDiagram-ELKLHX3M-DZLWA6Go.js → xychartDiagram-ELKLHX3M-B0SP0TXd.js} +1 -1
  113. package/dist-web/index.html +32 -32
  114. package/dist-web/vis/index.html.gz +0 -0
  115. package/package.json +1 -1
  116. package/scripts/fix-node-pty-perms.js +53 -53
  117. package/standard-skills/blun-app-design-system/SKILL.md +30 -30
  118. package/standard-skills/blun-app-design-system/provenance.json +17 -17
  119. package/standard-skills/blun-app-design-system/references/tokens.md +48 -48
  120. package/standard-skills/blun-app-design-system/scripts/check-blun-design.mjs +49 -49
  121. package/standard-skills/translate-native/README.md +1 -1
  122. package/standard-skills/translate-native/scripts/blun_language_guard.py +2 -0
  123. package/standard-skills/translate-native/scripts/language_gateway.py +2 -0
  124. package/standard-skills/translate-native/scripts/pre_output_guard.py +2 -0
  125. package/standard-tools/language-guard/blun_language_guard.py +2 -0
  126. package/standard-tools/language-guard/language_gateway.py +2 -0
  127. package/standard-tools/language-guard/pre_output_guard.py +2 -0
  128. package/telegram-plugin/blun.plugin.json +20 -20
  129. package/telegram-plugin/commands/access.md +37 -37
  130. package/telegram-plugin/dist/bridge.mjs +310 -187
  131. package/telegram-plugin/dist/mcp-server.mjs +174 -261
  132. package/telegram-plugin/dist/noise.mjs +1 -19
  133. package/worker-host.mjs +13747 -16824
  134. package/bin/profile-handoff.cjs +0 -152
  135. package/bin/profile-launch.cjs +0 -120
  136. package/dist-web/assets/DesignSystemView-DwK1aQMo.js +0 -12
  137. package/dist-web/assets/DesignSystemView-szjTj7ns.css +0 -1
  138. package/dist-web/assets/channel-BnluexuN.js +0 -1
  139. package/dist-web/assets/classDiagram-JCYQIIEL-BliFdSD9.js +0 -1
  140. package/dist-web/assets/classDiagram-v2-OCEON4UE-BliFdSD9.js +0 -1
  141. package/dist-web/assets/stateDiagram-v2-UEYNNEHI-fVkQcACW.js +0 -1
  142. package/dist-web/assets/swimlanesDiagram-ULZ7WXOC-Bg-BiZJQ.js +0 -8
@@ -33,69 +33,28 @@ const { unsupportedNodeMessage } = require('./node-version');
33
33
  const { repairConfiguredNativeModules } = require('./native-module-repair');
34
34
  const { acquireSharedRuntimeLease, tryAcquireUpdateLease } = require('./update-lease');
35
35
  const { runExplicitUpdate, runUpdateNotice } = require('./update-notice');
36
- const {
37
- ensurePrivateDirectory,
38
- securePrivateFile,
39
- writePrivateFile,
40
- } = require('./private-paths');
41
- const { parseProfileLaunchArgs, resolveSelectedProfile } = require('./profile-launch.cjs');
42
- const { createProfileHandoff, PROFILE_HANDOFF_READY, PROFILE_HANDOFF_EXIT } = require('./profile-handoff.cjs');
43
-
44
- const PKG = path.resolve(__dirname, '..');
45
- const PROFILE = parseProfileLaunchArgs(process.argv.slice(2), launcherModeFromArgv(process.argv));
46
- const ARGS = PROFILE.args;
47
- const CORE_LOAD_TIMEOUT_MS = 30_000;
36
+ const {
37
+ ensurePrivateDirectory,
38
+ securePrivateFile,
39
+ writePrivateFile,
40
+ } = require('./private-paths');
41
+
42
+ const PKG = path.resolve(__dirname, '..');
43
+ const ARGS = process.argv.slice(2);
48
44
 
49
- function normalizeWindowsPath(value) {
50
- return path.win32.normalize(value).replace(/\\+$/u, '').toLowerCase();
51
- }
52
-
53
- function runningTuiPid(blunDir, options = {}) {
54
- const fsImpl = options.fsImpl || fs;
55
- const kill = options.kill || process.kill.bind(process);
56
- const now = options.now ?? Date.now();
57
- const stateDir = path.join(blunDir, 'channels', 'telegram');
58
- try {
59
- const leaseFile = path.join(stateDir, 'tui.pid');
60
- const owner = JSON.parse(fsImpl.readFileSync(path.join(stateDir, 'tui-owner.json'), 'utf8'));
61
- const leasePid = Number(fsImpl.readFileSync(leaseFile, 'utf8').trim());
62
- if (owner?.version !== 1 || !Number.isSafeInteger(owner.pid) || owner.pid <= 1
63
- || owner.pid !== leasePid || now - fsImpl.statSync(leaseFile).mtimeMs > 90_000) return null;
64
- kill(owner.pid, 0);
65
- return owner.pid;
66
- } catch {
67
- return null;
68
- }
69
- }
70
-
71
- function isInteractiveKingStart(args) {
72
- return args.length === 0 || (args.length === 1 && args[0] === '-c');
73
- }
45
+ function normalizeWindowsPath(value) {
46
+ return path.win32.normalize(value).replace(/\\+$/u, '').toLowerCase();
47
+ }
74
48
 
75
- function resolveLauncherPrivatePaths(options = {}) {
76
- const env = options.env || process.env;
77
- const platform = options.platform || process.platform;
78
- const configuredHome = String(env.BLUN_HOME || '').trim();
79
- const selectedProfile = options.profileName ?? PROFILE.name;
80
- if (platform !== 'win32') {
81
- const posix = path.posix;
82
- const userHome = (options.homedir || os.homedir)();
83
- if (selectedProfile !== undefined) {
84
- const configuredShared = String(env.BLUN_SHARED_HOME || '').trim();
85
- const sharedHome = configuredShared
86
- ? posix.resolve(configuredShared)
87
- : configuredHome && posix.basename(posix.dirname(configuredHome)) === 'profile'
88
- ? posix.resolve(configuredHome, '..', '..')
89
- : configuredHome ? posix.resolve(configuredHome) : posix.join(userHome, '.blun');
90
- const blunHome = resolveSelectedProfile(sharedHome, selectedProfile, posix);
91
- if (configuredShared && configuredHome && posix.resolve(configuredHome) !== blunHome) {
92
- throw new Error(`BLUN_HOME passt nicht zum Profil ${selectedProfile}: ${blunHome}`);
93
- }
94
- return { blunHome, sharedHome, userHome };
95
- }
96
- return {
97
- blunHome: configuredHome ? path.resolve(configuredHome) : path.join(userHome, '.blun'),
98
- userHome,
49
+ function resolveLauncherPrivatePaths(options = {}) {
50
+ const env = options.env || process.env;
51
+ const platform = options.platform || process.platform;
52
+ const configuredHome = String(env.BLUN_HOME || '').trim();
53
+ if (platform !== 'win32') {
54
+ const userHome = (options.homedir || os.homedir)();
55
+ return {
56
+ blunHome: configuredHome ? path.resolve(configuredHome) : path.join(userHome, '.blun'),
57
+ userHome,
99
58
  };
100
59
  }
101
60
 
@@ -118,20 +77,8 @@ function resolveLauncherPrivatePaths(options = {}) {
118
77
  throw new Error('Das lokale Windows-Benutzerprofil ist kein kanonischer lokaler Pfad.');
119
78
  }
120
79
 
121
- const blunHome = path.win32.join(userHome, '.blun');
122
- if (selectedProfile !== undefined) {
123
- const profileHome = resolveSelectedProfile(blunHome, selectedProfile, path.win32);
124
- const configuredShared = String(env.BLUN_SHARED_HOME || '').trim();
125
- if (configuredShared && normalizeWindowsPath(path.win32.resolve(configuredShared)) !== normalizeWindowsPath(blunHome)) {
126
- throw new Error(`BLUN_SHARED_HOME muss unter Windows exakt im Windows-Benutzerprofil liegen: ${blunHome}`);
127
- }
128
- if (configuredHome && normalizeWindowsPath(path.win32.resolve(configuredHome)) !== normalizeWindowsPath(profileHome)
129
- && normalizeWindowsPath(path.win32.resolve(configuredHome)) !== normalizeWindowsPath(blunHome)) {
130
- throw new Error(`BLUN_HOME passt nicht zum Profil ${selectedProfile}: ${profileHome}`);
131
- }
132
- return { blunHome: profileHome, sharedHome: blunHome, userHome };
133
- }
134
- if (configuredHome
80
+ const blunHome = path.win32.join(userHome, '.blun');
81
+ if (configuredHome
135
82
  && normalizeWindowsPath(path.win32.resolve(configuredHome)) !== normalizeWindowsPath(blunHome)) {
136
83
  throw new Error(`BLUN_HOME muss unter Windows exakt im Windows-Benutzerprofil liegen: ${blunHome}`);
137
84
  }
@@ -148,42 +95,34 @@ function readPackageVersion() {
148
95
 
149
96
  function shouldDetachProtectedCore(options = {}) {
150
97
  const platform = options.platform || process.platform;
151
- if (platform === 'win32' && options.interactive === true) return false;
152
98
  const stdinIsTTY = Object.hasOwn(options, 'stdinIsTTY')
153
99
  ? options.stdinIsTTY
154
100
  : process.stdin.isTTY;
155
101
  return platform !== 'win32' || stdinIsTTY !== true;
156
102
  }
157
103
 
158
- function spawnProtectedCore(args, env, cwd, onProfileMessage) {
104
+ function spawnProtectedCore(args, env, cwd) {
159
105
  const child = spawn(
160
106
  process.execPath,
161
107
  [path.join(PKG, 'bin', 'core-bootstrap.js'), ...args],
162
108
  {
163
109
  cwd,
164
- detached: shouldDetachProtectedCore({ interactive: Boolean(onProfileMessage) }),
165
- env: { ...env, BLUN_TERMINAL_OWNER: process.platform === 'win32' && onProfileMessage ? '1' : '0' },
110
+ detached: shouldDetachProtectedCore(),
111
+ env,
166
112
  stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
167
113
  windowsHide: true,
168
114
  },
169
115
  );
170
116
  let loadedSettled = false;
171
117
  let completedSettled = false;
172
- let operatorSignal;
173
- let profileReady = false;
118
+ let operatorSignal;
174
119
  let resolveLoaded;
175
120
  let resolveCompleted;
176
- const loadTimer = setTimeout(() => {
177
- try {
178
- child.kill();
179
- } catch {}
180
- }, CORE_LOAD_TIMEOUT_MS);
181
121
  const loaded = new Promise((resolve) => { resolveLoaded = resolve; });
182
122
  const completed = new Promise((resolve) => { resolveCompleted = resolve; });
183
123
  const settleLoaded = (value) => {
184
124
  if (loadedSettled) return;
185
125
  loadedSettled = true;
186
- clearTimeout(loadTimer);
187
126
  resolveLoaded(value);
188
127
  };
189
128
  const settleCompleted = (result) => {
@@ -204,29 +143,16 @@ function spawnProtectedCore(args, env, cwd, onProfileMessage) {
204
143
  signalHandlers.set(signal, handler);
205
144
  process.once(signal, handler);
206
145
  }
207
- child.on('message', (message) => {
208
- if (message?.type !== CORE_LOADED_MESSAGE) {
209
- if (completedSettled || !onProfileMessage) return;
210
- if (message?.type === PROFILE_HANDOFF_READY && Object.keys(message).length === 1) {
211
- profileReady = true;
212
- return;
213
- }
214
- if (!loadedSettled) return;
215
- const reply = onProfileMessage(message);
216
- if (reply) {
217
- try { child.send(reply, () => {}); } catch {}
218
- }
219
- return;
220
- }
221
- settleLoaded(true);
222
- if (onProfileMessage) child.channel?.unref();
223
- else {
224
- try { child.disconnect(); } catch {}
225
- }
146
+ child.on('message', (message) => {
147
+ if (message?.type !== CORE_LOADED_MESSAGE) return;
148
+ settleLoaded(true);
149
+ try {
150
+ child.disconnect();
151
+ } catch {}
226
152
  });
227
153
  child.once('error', (error) => settleCompleted({ error }));
228
154
  child.once('exit', (code, signal) => settleCompleted({ code, signal }));
229
- return { child, completed, loaded, isProfileReady: () => profileReady };
155
+ return { child, completed, loaded };
230
156
  }
231
157
 
232
158
  async function runInformationalCore(args, env, cwd, releaseNotice) {
@@ -238,14 +164,10 @@ async function runInformationalCore(args, env, cwd, releaseNotice) {
238
164
  return Number.isInteger(result.code) ? result.code : exitCodeForChild(result, false);
239
165
  }
240
166
 
241
- async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {}) {
242
- let noticeReleased = false;
243
- let rollback;
244
- let recoveryAttempted = false;
245
- for (;;) {
246
- const handoff = options.prepareProfile
247
- ? createProfileHandoff(env, target => runningTuiPid(target) !== null) : undefined;
248
- const core = spawnProtectedCore(args, env, cwd, handoff && ((message) => handoff.prepare(message)));
167
+ async function superviseProtectedCore(args, env, cwd, releaseNotice) {
168
+ let noticeReleased = false;
169
+ for (;;) {
170
+ const core = spawnProtectedCore(args, env, cwd);
249
171
  const loaded = await core.loaded;
250
172
  if (!noticeReleased) {
251
173
  noticeReleased = true;
@@ -256,47 +178,12 @@ async function superviseProtectedCore(args, env, cwd, releaseNotice, options = {
256
178
  const intentionalStop = consumeIntentionalStopMarker({
257
179
  homeDir: env.BLUN_HOME, childPid: core.child.pid, nowMs: Date.now(),
258
180
  });
259
- recordRuntimeExit({
181
+ recordRuntimeExit({
260
182
  homeDir: env.BLUN_HOME, source: 'launcher', kind: result.error ? 'child-error' : 'child-exit',
261
183
  exitCode, signal: result.signal, phase: loaded ? 'runtime' : 'startup',
262
184
  cliVersion: env.BLUN_PUBLIC_PACKAGE_VERSION, profile: env.BLUN_PROFILE,
263
- loaded, childPid: core.child.pid, error: result.error,
264
- });
265
- // A profile transition is committed only after the old process exits cleanly.
266
- // Failed target startup restores the previous owner, never the previous PID.
267
- if (rollback && (!loaded || !core.isProfileReady()) && !result.signal) {
268
- ({ args, env } = rollback);
269
- rollback = undefined;
270
- continue;
271
- }
272
- if (loaded && core.isProfileReady()) {
273
- rollback = undefined;
274
- recoveryAttempted = false;
275
- }
276
- if (handoff && loaded && !intentionalStop && !result.error && !result.signal
277
- && result.code === PROFILE_HANDOFF_EXIT) {
278
- if (!handoff.hasPending()) return 1;
279
- const sourceSessionId = handoff.getSourceSessionId();
280
- const recoveryArgs = sourceSessionId === undefined ? ['-c'] : ['-r', sourceSessionId];
281
- try {
282
- const selected = handoff.commit();
283
- const nextEnv = await options.prepareProfile(selected);
284
- handoff.commit();
285
- rollback = { args: recoveryArgs, env };
286
- args = ['-c'];
287
- env = { ...nextEnv, BLUN_PROFILE_HANDOFF: '1' };
288
- continue;
289
- } catch (error) {
290
- recordRuntimeExit({ homeDir: env.BLUN_HOME, source: 'launcher', kind: 'profile-handoff-failure',
291
- phase: 'startup', cliVersion: env.BLUN_PUBLIC_PACKAGE_VERSION, profile: env.BLUN_PROFILE,
292
- exitCode: 1, error });
293
- if (recoveryAttempted) return 1;
294
- recoveryAttempted = true;
295
- // Reopen the original owner when the selection became unavailable.
296
- args = recoveryArgs;
297
- continue;
298
- }
299
- }
185
+ loaded, childPid: core.child.pid, error: result.error,
186
+ });
300
187
  if (intentionalStop || !isAbnormalCoreExit(result, loaded)) {
301
188
  if (result.error) throw result.error;
302
189
  return exitCode;
@@ -327,7 +214,7 @@ function exitCodeForChild(result, loaded) {
327
214
  return 1;
328
215
  }
329
216
 
330
- function installTelegramForProfile(packageRoot, blunDir) {
217
+ function installTelegramForProfile(packageRoot, blunDir) {
331
218
  installManagedTelegramPlugin({ packageRoot, blunDir });
332
219
  const channelsDir = path.join(blunDir, 'channels');
333
220
  const channelDir = path.join(channelsDir, 'telegram');
@@ -339,37 +226,7 @@ function installTelegramForProfile(packageRoot, blunDir) {
339
226
  } else {
340
227
  securePrivateFile(envFile);
341
228
  }
342
- }
343
-
344
- function prepareProfileRuntime(blunDir, callerCwd, mode) {
345
- ensurePrivateDirectory(blunDir);
346
- const cfgFile = path.join(blunDir, 'config.toml');
347
- if (fs.existsSync(cfgFile)) securePrivateFile(cfgFile);
348
- const standardMcpNames = availableStandardToolNames({ packageRoot: PKG })
349
- .filter((name) => name !== 'telegram');
350
- seedStandardTools({ packageRoot: PKG, blunDir, names: standardMcpNames });
351
- seedStandardDesignSkill({ packageRoot: PKG, blunDir });
352
- installManagedAgentSpinePlugin({ packageRoot: PKG, blunDir });
353
- if (mode === LAUNCHER_MODES.KING) installTelegramForProfile(PKG, blunDir);
354
- return repairConfiguredNativeModules({
355
- blunDir, callerCwd,
356
- onRepairStart() {
357
- process.stdout.write('BLUN richtet native Node.js-Module fuer die neue Laufzeit ein.\n');
358
- },
359
- });
360
- }
361
-
362
- async function withProfileRuntimeReservation(homeDir, work) {
363
- const result = await tryAcquireUpdateLease({ packageRoot: homeDir, role: 'profile' });
364
- if (!result.acquired) throw Object.assign(new Error(`PROFILE_RUNTIME_${result.reason.toUpperCase()}`),
365
- { code: result.reason === 'busy' ? 'PROFILE_RUNTIME_BUSY' : 'PROFILE_RUNTIME_UNAVAILABLE' });
366
- try {
367
- result.lease.assertOwned();
368
- const value = await work();
369
- result.lease.assertOwned();
370
- return value;
371
- } finally { await result.lease.release(); }
372
- }
229
+ }
373
230
 
374
231
  function spawnManagedLauncher(binary, cwd) {
375
232
  return new Promise((resolve, reject) => {
@@ -503,29 +360,18 @@ async function runLauncher(options = {}) {
503
360
  }
504
361
  process.stdout.write(launcherHelpText());
505
362
  const env = createLauncherEnvironment(process.env, mode, readPackageVersion());
506
- const informationalEnv = { ...process.env };
507
- delete informationalEnv.BLUN_HOME;
508
- const paths = resolveLauncherPrivatePaths({ env: informationalEnv });
509
- env.BLUN_HOME = paths.blunHome;
510
- if (PROFILE.name !== undefined) {
511
- env.BLUN_SHARED_HOME = paths.sharedHome;
512
- env.BLUN_PROFILE = PROFILE.name;
513
- }
363
+ const informationalEnv = { ...process.env };
364
+ delete informationalEnv.BLUN_HOME;
365
+ env.BLUN_HOME = resolveLauncherPrivatePaths({ env: informationalEnv }).blunHome;
514
366
  process.exitCode = await runInformationalCore(ARGS, env, callerCwd, releaseNotice);
515
367
  return;
516
368
  }
517
369
 
518
- let privatePaths;
519
- const getPrivatePaths = () => {
520
- if (!privatePaths) {
521
- const resolved = resolveLauncherPrivatePaths();
522
- if (PROFILE.implicit && !fs.existsSync(resolved.blunHome)) {
523
- throw new Error(`Profil ${PROFILE.name} gibt es nicht. Anlegen mit king --profile ${PROFILE.name}.`);
524
- }
525
- privatePaths = resolved;
526
- }
527
- return privatePaths;
528
- };
370
+ let privatePaths;
371
+ const getPrivatePaths = () => {
372
+ privatePaths ||= resolveLauncherPrivatePaths();
373
+ return privatePaths;
374
+ };
529
375
  const nodeRuntime = await prepareManagedNodeRuntime({
530
376
  getBlunDir: () => getPrivatePaths().blunHome,
531
377
  });
@@ -544,28 +390,15 @@ async function runLauncher(options = {}) {
544
390
  if (ARGS.some((arg) => arg === '--help' || arg === '-h')) {
545
391
  process.stdout.write(launcherHelpText());
546
392
  const env = createLauncherEnvironment(process.env, mode, readPackageVersion());
547
- const informationalEnv = { ...process.env };
548
- delete informationalEnv.BLUN_HOME;
549
- const paths = resolveLauncherPrivatePaths({ env: informationalEnv });
550
- env.BLUN_HOME = paths.blunHome;
551
- if (PROFILE.name !== undefined) {
552
- env.BLUN_SHARED_HOME = paths.sharedHome;
553
- env.BLUN_PROFILE = PROFILE.name;
554
- }
393
+ const informationalEnv = { ...process.env };
394
+ delete informationalEnv.BLUN_HOME;
395
+ env.BLUN_HOME = resolveLauncherPrivatePaths({ env: informationalEnv }).blunHome;
555
396
  process.exitCode = await superviseProtectedCore(ARGS, env, callerCwd, releaseNotice);
556
397
  return;
557
398
  }
558
399
 
559
- const blunDir = getPrivatePaths().blunHome;
560
- if (mode === LAUNCHER_MODES.KING && isInteractiveKingStart(ARGS)) {
561
- const activePid = runningTuiPid(blunDir);
562
- if (activePid !== null) {
563
- process.stderr.write(`King läuft bereits (PID ${activePid}).\n`);
564
- process.exitCode = 1;
565
- return;
566
- }
567
- }
568
- ensurePrivateDirectory(blunDir);
400
+ const blunDir = getPrivatePaths().blunHome;
401
+ ensurePrivateDirectory(blunDir);
569
402
 
570
403
  // --- 1. Oeffentlicher npm-Update-Dialog. -------------------------------
571
404
  const updateResult = options.skipUpdateNotice === true
@@ -596,53 +429,55 @@ async function runLauncher(options = {}) {
596
429
  // --- 2. Bestehende Konfiguration absichern -------------------------------
597
430
  // Ein frischer Start bleibt absichtlich ohne statischen Anbieter. /login
598
431
  // provisioniert King ueber den BLUN-OAuth-Server.
599
- require('./verify-bundled-agent-sources.cjs').verifyBundledAgentSources(PKG);
600
- const nativeModules = mode === LAUNCHER_MODES.KING && isInteractiveKingStart(ARGS)
601
- ? await withProfileRuntimeReservation(blunDir, () => prepareProfileRuntime(blunDir, callerCwd, mode))
602
- : prepareProfileRuntime(blunDir, callerCwd, mode);
432
+ const cfgFile = path.join(blunDir, 'config.toml');
433
+ if (fs.existsSync(cfgFile)) securePrivateFile(cfgFile);
434
+ require('./verify-bundled-agent-sources.cjs').verifyBundledAgentSources(PKG);
435
+
436
+ // --- 3. BLUN-Standard-MCPs additiv im Benutzerprofil einrichten ---------
437
+ const standardMcpNames = availableStandardToolNames({ packageRoot: PKG })
438
+ .filter((name) => name !== 'telegram');
439
+ seedStandardTools({
440
+ packageRoot: PKG,
441
+ blunDir,
442
+ names: standardMcpNames,
443
+ });
603
444
 
445
+ // --- 4. Eigenes BLUN-Grunddesign als einzigen Standard-Skill installieren
446
+ seedStandardDesignSkill({ packageRoot: PKG, blunDir });
447
+ installManagedAgentSpinePlugin({ packageRoot: PKG, blunDir });
448
+
449
+ // --- 5. Telegram-Plugin + Token-Vorlage (nur King) -----------------------
450
+ if (mode === LAUNCHER_MODES.KING) {
451
+ installTelegramForProfile(PKG, blunDir);
452
+ }
453
+
454
+ const nativeModules = repairConfiguredNativeModules({
455
+ blunDir,
456
+ callerCwd,
457
+ onRepairStart() {
458
+ process.stdout.write('BLUN richtet native Node.js-Module fuer die neue Laufzeit ein.\n');
459
+ },
460
+ });
604
461
  if (nativeModules.repaired.length > 0) {
605
462
  process.stdout.write('Native Node.js-Module sind wieder einsatzbereit.\n');
606
463
  }
607
464
 
608
- // --- 6. Start -----------------------------------------------------------
609
- const env = createLauncherEnvironment(process.env, mode, readPackageVersion(), blunDir);
610
- env.BLUN_HOME = blunDir;
611
- if (PROFILE.name !== undefined) {
612
- env.BLUN_SHARED_HOME = getPrivatePaths().sharedHome;
613
- env.BLUN_PROFILE = PROFILE.name;
614
- }
615
- const handoffOptions = mode === LAUNCHER_MODES.KING && isInteractiveKingStart(ARGS)
616
- ? { prepareProfile: async (selected) => {
617
- const target = selected.homeDir;
618
- await withProfileRuntimeReservation(target, () => prepareProfileRuntime(target, callerCwd, mode));
619
- const next = createLauncherEnvironment(process.env, mode, readPackageVersion(), target);
620
- next.BLUN_HOME = target;
621
- next.BLUN_SHARED_HOME = selected.sharedHome;
622
- next.BLUN_PROFILE = selected.name;
623
- delete next.BLUN_TELEGRAM_STATE_DIR;
624
- delete next.BLUN_PLUGIN_ROOT;
625
- return next;
626
- } } : {};
627
- if (handoffOptions.prepareProfile) env.BLUN_PROFILE_HANDOFF = '1';
628
- else delete env.BLUN_PROFILE_HANDOFF;
465
+ // --- 6. Start -----------------------------------------------------------
466
+ const env = createLauncherEnvironment(process.env, mode, readPackageVersion(), blunDir);
467
+ env.BLUN_HOME = blunDir;
629
468
  process.exitCode = await superviseProtectedCore(
630
469
  ARGS,
631
470
  env,
632
471
  callerCwd,
633
- releaseNotice,
634
- handoffOptions,
472
+ releaseNotice,
635
473
  );
636
474
  } finally {
637
475
  await releaseNotice();
638
476
  }
639
477
  }
640
478
 
641
- module.exports = {
642
- withProfileRuntimeReservation,
643
- resolveLauncherPrivatePaths,
644
- isInteractiveKingStart,
645
- runningTuiPid,
479
+ module.exports = {
480
+ resolveLauncherPrivatePaths,
646
481
  runLauncher,
647
482
  shouldDetachProtectedCore,
648
483
  spawnManagedLauncher,