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
@@ -1,201 +1,201 @@
1
- 'use strict';
2
-
3
- const { spawnSync } = require('node:child_process');
4
- const fs = require('node:fs');
5
- const path = require('node:path');
6
-
7
- const SQLITE_PROBE = [
8
- "const Database = require('better-sqlite3');",
9
- "const db = new Database(':memory:');",
10
- "const row = db.prepare('SELECT 1 AS ok').get();",
11
- 'db.close();',
12
- "if (row?.ok !== 1) throw new Error('SQLITE_PROBE_FAILED');",
13
- ].join(' ');
14
-
15
- function commandFailure(result) {
16
- return String(result?.stderr || result?.stdout || result?.error?.message || '').trim();
17
- }
18
-
19
- function packageHasDependency(document, dependency) {
20
- return ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']
21
- .some((field) => Object.hasOwn(document?.[field] || {}, dependency));
22
- }
23
-
24
- function nearestPackageDirectory(startDir) {
25
- let current = path.resolve(startDir);
26
- while (true) {
27
- if (fs.existsSync(path.join(current, 'package.json'))) return current;
28
- const parent = path.dirname(current);
29
- if (parent === current) return null;
30
- current = parent;
31
- }
32
- }
33
-
34
- function projectRoot(startDir) {
35
- let current = path.resolve(startDir);
36
- while (true) {
37
- if (fs.existsSync(path.join(current, '.git'))) return current;
38
- const parent = path.dirname(current);
39
- if (parent === current) return path.resolve(startDir);
40
- current = parent;
41
- }
42
- }
43
-
44
- function readMcpDocument(configPath) {
45
- if (!fs.existsSync(configPath)) return null;
46
- try {
47
- const document = JSON.parse(fs.readFileSync(configPath, 'utf8'));
48
- return document && typeof document === 'object' ? document : null;
49
- } catch {
50
- return null;
51
- }
52
- }
53
-
54
- function serverProjectDirectory(server, configPath) {
55
- if (!server || typeof server !== 'object' || server.enabled === false) return null;
56
- if (typeof server.cwd === 'string' && server.cwd.trim()) {
57
- const cwd = server.cwd.trim();
58
- return nearestPackageDirectory(
59
- path.isAbsolute(cwd) ? cwd : path.resolve(path.dirname(configPath), cwd),
60
- );
61
- }
62
- const args = Array.isArray(server.args) ? server.args : [];
63
- const script = args.find((arg) => typeof arg === 'string' && /\.[cm]?js$/iu.test(arg));
64
- if (!script) return null;
65
- const scriptPath = path.isAbsolute(script)
66
- ? script
67
- : path.resolve(path.dirname(configPath), script);
68
- return nearestPackageDirectory(path.dirname(scriptPath));
69
- }
70
-
71
- function configuredNativeProjectPaths({ blunDir, callerCwd }) {
72
- const root = projectRoot(callerCwd);
73
- const configPaths = [...new Set([
74
- path.join(blunDir, 'mcp.json'),
75
- path.join(root, '.mcp.json'),
76
- path.join(callerCwd, '.blun', 'mcp.json'),
77
- ].map((entry) => path.resolve(entry)))];
78
- const candidates = [nearestPackageDirectory(callerCwd)];
79
- for (const configPath of configPaths) {
80
- const document = readMcpDocument(configPath);
81
- const servers = document?.mcpServers;
82
- if (!servers || typeof servers !== 'object' || Array.isArray(servers)) continue;
83
- for (const server of Object.values(servers)) {
84
- candidates.push(serverProjectDirectory(server, configPath));
85
- }
86
- }
87
-
88
- const seen = new Set();
89
- const projects = [];
90
- for (const candidate of candidates) {
91
- if (!candidate) continue;
92
- const absolute = path.resolve(candidate);
93
- const key = process.platform === 'win32' ? absolute.toLowerCase() : absolute;
94
- if (seen.has(key)) continue;
95
- seen.add(key);
96
- projects.push(absolute);
97
- }
98
- return projects;
99
- }
100
-
101
- function probeBetterSqlite({ nodeBinary, projectDir, spawnSyncImpl }) {
102
- return spawnSyncImpl(nodeBinary, ['-e', SQLITE_PROBE], {
103
- cwd: projectDir,
104
- encoding: 'utf8',
105
- timeout: 30_000,
106
- windowsHide: true,
107
- });
108
- }
109
-
110
- function npmInvocation(nodeBinary) {
111
- const candidates = [
112
- path.join(path.dirname(nodeBinary), 'node_modules', 'npm', 'bin', 'npm-cli.js'),
113
- path.resolve(path.dirname(nodeBinary), '..', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
114
- ];
115
- const npmCli = candidates.find((candidate) => fs.existsSync(candidate));
116
- if (!npmCli) {
117
- throw new Error('npm-cli.js wurde fuer die aktive Node.js-Laufzeit nicht gefunden.');
118
- }
119
- return { args: [npmCli], command: nodeBinary };
120
- }
121
-
122
- function repairNativeProject({
123
- nodeBinary = process.execPath,
124
- npmCommand,
125
- onRepairStart,
126
- projectDir,
127
- spawnSyncImpl = spawnSync,
128
- }) {
129
- if (typeof projectDir !== 'string' || !path.isAbsolute(projectDir)) {
130
- throw new Error('Der Projektpfad fuer die native Ladeprobe muss absolut sein.');
131
- }
132
- const absoluteProjectDir = path.resolve(projectDir);
133
- const packagePath = path.join(absoluteProjectDir, 'package.json');
134
- let packageDocument;
135
- try {
136
- packageDocument = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
137
- } catch {
138
- return { kind: 'skipped', reason: 'package_unreadable' };
139
- }
140
- if (!packageHasDependency(packageDocument, 'better-sqlite3')) {
141
- return { kind: 'skipped', reason: 'dependency_missing' };
142
- }
143
-
144
- const before = probeBetterSqlite({ nodeBinary, projectDir: absoluteProjectDir, spawnSyncImpl });
145
- if (before.status === 0) return { kind: 'healthy' };
146
-
147
- const npm = npmCommand === undefined
148
- ? npmInvocation(nodeBinary)
149
- : { args: [], command: npmCommand };
150
- onRepairStart?.(absoluteProjectDir);
151
- const rebuilt = spawnSyncImpl(npm.command, [...npm.args, 'rebuild', 'better-sqlite3'], {
152
- cwd: absoluteProjectDir,
153
- encoding: 'utf8',
154
- timeout: 300_000,
155
- windowsHide: true,
156
- });
157
- if (rebuilt.status !== 0) {
158
- throw new Error(
159
- `Native Node.js-Module konnten nicht repariert werden: ${commandFailure(rebuilt) || 'ohne Fehlertext'}`,
160
- );
161
- }
162
-
163
- const after = probeBetterSqlite({ nodeBinary, projectDir: absoluteProjectDir, spawnSyncImpl });
164
- if (after.status !== 0) {
165
- throw new Error(
166
- `Ladeprobe nach dem Rebuild fehlgeschlagen: ${commandFailure(after) || 'ohne Fehlertext'}`,
167
- );
168
- }
169
- return { kind: 'repaired' };
170
- }
171
-
172
- function repairConfiguredNativeModules({
173
- blunDir,
174
- callerCwd,
175
- nodeBinary = process.execPath,
176
- onRepairStart,
177
- projectPaths,
178
- repairProject = repairNativeProject,
179
- spawnSyncImpl = spawnSync,
180
- }) {
181
- const projects = projectPaths || configuredNativeProjectPaths({ blunDir, callerCwd });
182
- const result = { checked: projects.length, healthy: [], repaired: [], skipped: [] };
183
- for (const projectDir of projects) {
184
- const firstResult = repairProject({
185
- nodeBinary,
186
- projectDir,
187
- spawnSyncImpl,
188
- onRepairStart,
189
- });
190
- if (firstResult.kind === 'healthy') result.healthy.push(projectDir);
191
- else if (firstResult.kind === 'repaired') result.repaired.push(projectDir);
192
- else result.skipped.push(projectDir);
193
- }
194
- return result;
195
- }
196
-
197
- module.exports = {
198
- configuredNativeProjectPaths,
199
- repairConfiguredNativeModules,
200
- repairNativeProject,
201
- };
1
+ 'use strict';
2
+
3
+ const { spawnSync } = require('node:child_process');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+
7
+ const SQLITE_PROBE = [
8
+ "const Database = require('better-sqlite3');",
9
+ "const db = new Database(':memory:');",
10
+ "const row = db.prepare('SELECT 1 AS ok').get();",
11
+ 'db.close();',
12
+ "if (row?.ok !== 1) throw new Error('SQLITE_PROBE_FAILED');",
13
+ ].join(' ');
14
+
15
+ function commandFailure(result) {
16
+ return String(result?.stderr || result?.stdout || result?.error?.message || '').trim();
17
+ }
18
+
19
+ function packageHasDependency(document, dependency) {
20
+ return ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']
21
+ .some((field) => Object.hasOwn(document?.[field] || {}, dependency));
22
+ }
23
+
24
+ function nearestPackageDirectory(startDir) {
25
+ let current = path.resolve(startDir);
26
+ while (true) {
27
+ if (fs.existsSync(path.join(current, 'package.json'))) return current;
28
+ const parent = path.dirname(current);
29
+ if (parent === current) return null;
30
+ current = parent;
31
+ }
32
+ }
33
+
34
+ function projectRoot(startDir) {
35
+ let current = path.resolve(startDir);
36
+ while (true) {
37
+ if (fs.existsSync(path.join(current, '.git'))) return current;
38
+ const parent = path.dirname(current);
39
+ if (parent === current) return path.resolve(startDir);
40
+ current = parent;
41
+ }
42
+ }
43
+
44
+ function readMcpDocument(configPath) {
45
+ if (!fs.existsSync(configPath)) return null;
46
+ try {
47
+ const document = JSON.parse(fs.readFileSync(configPath, 'utf8'));
48
+ return document && typeof document === 'object' ? document : null;
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+
54
+ function serverProjectDirectory(server, configPath) {
55
+ if (!server || typeof server !== 'object' || server.enabled === false) return null;
56
+ if (typeof server.cwd === 'string' && server.cwd.trim()) {
57
+ const cwd = server.cwd.trim();
58
+ return nearestPackageDirectory(
59
+ path.isAbsolute(cwd) ? cwd : path.resolve(path.dirname(configPath), cwd),
60
+ );
61
+ }
62
+ const args = Array.isArray(server.args) ? server.args : [];
63
+ const script = args.find((arg) => typeof arg === 'string' && /\.[cm]?js$/iu.test(arg));
64
+ if (!script) return null;
65
+ const scriptPath = path.isAbsolute(script)
66
+ ? script
67
+ : path.resolve(path.dirname(configPath), script);
68
+ return nearestPackageDirectory(path.dirname(scriptPath));
69
+ }
70
+
71
+ function configuredNativeProjectPaths({ blunDir, callerCwd }) {
72
+ const root = projectRoot(callerCwd);
73
+ const configPaths = [...new Set([
74
+ path.join(blunDir, 'mcp.json'),
75
+ path.join(root, '.mcp.json'),
76
+ path.join(callerCwd, '.blun', 'mcp.json'),
77
+ ].map((entry) => path.resolve(entry)))];
78
+ const candidates = [nearestPackageDirectory(callerCwd)];
79
+ for (const configPath of configPaths) {
80
+ const document = readMcpDocument(configPath);
81
+ const servers = document?.mcpServers;
82
+ if (!servers || typeof servers !== 'object' || Array.isArray(servers)) continue;
83
+ for (const server of Object.values(servers)) {
84
+ candidates.push(serverProjectDirectory(server, configPath));
85
+ }
86
+ }
87
+
88
+ const seen = new Set();
89
+ const projects = [];
90
+ for (const candidate of candidates) {
91
+ if (!candidate) continue;
92
+ const absolute = path.resolve(candidate);
93
+ const key = process.platform === 'win32' ? absolute.toLowerCase() : absolute;
94
+ if (seen.has(key)) continue;
95
+ seen.add(key);
96
+ projects.push(absolute);
97
+ }
98
+ return projects;
99
+ }
100
+
101
+ function probeBetterSqlite({ nodeBinary, projectDir, spawnSyncImpl }) {
102
+ return spawnSyncImpl(nodeBinary, ['-e', SQLITE_PROBE], {
103
+ cwd: projectDir,
104
+ encoding: 'utf8',
105
+ timeout: 30_000,
106
+ windowsHide: true,
107
+ });
108
+ }
109
+
110
+ function npmInvocation(nodeBinary) {
111
+ const candidates = [
112
+ path.join(path.dirname(nodeBinary), 'node_modules', 'npm', 'bin', 'npm-cli.js'),
113
+ path.resolve(path.dirname(nodeBinary), '..', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
114
+ ];
115
+ const npmCli = candidates.find((candidate) => fs.existsSync(candidate));
116
+ if (!npmCli) {
117
+ throw new Error('npm-cli.js wurde fuer die aktive Node.js-Laufzeit nicht gefunden.');
118
+ }
119
+ return { args: [npmCli], command: nodeBinary };
120
+ }
121
+
122
+ function repairNativeProject({
123
+ nodeBinary = process.execPath,
124
+ npmCommand,
125
+ onRepairStart,
126
+ projectDir,
127
+ spawnSyncImpl = spawnSync,
128
+ }) {
129
+ if (typeof projectDir !== 'string' || !path.isAbsolute(projectDir)) {
130
+ throw new Error('Der Projektpfad fuer die native Ladeprobe muss absolut sein.');
131
+ }
132
+ const absoluteProjectDir = path.resolve(projectDir);
133
+ const packagePath = path.join(absoluteProjectDir, 'package.json');
134
+ let packageDocument;
135
+ try {
136
+ packageDocument = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
137
+ } catch {
138
+ return { kind: 'skipped', reason: 'package_unreadable' };
139
+ }
140
+ if (!packageHasDependency(packageDocument, 'better-sqlite3')) {
141
+ return { kind: 'skipped', reason: 'dependency_missing' };
142
+ }
143
+
144
+ const before = probeBetterSqlite({ nodeBinary, projectDir: absoluteProjectDir, spawnSyncImpl });
145
+ if (before.status === 0) return { kind: 'healthy' };
146
+
147
+ const npm = npmCommand === undefined
148
+ ? npmInvocation(nodeBinary)
149
+ : { args: [], command: npmCommand };
150
+ onRepairStart?.(absoluteProjectDir);
151
+ const rebuilt = spawnSyncImpl(npm.command, [...npm.args, 'rebuild', 'better-sqlite3'], {
152
+ cwd: absoluteProjectDir,
153
+ encoding: 'utf8',
154
+ timeout: 300_000,
155
+ windowsHide: true,
156
+ });
157
+ if (rebuilt.status !== 0) {
158
+ throw new Error(
159
+ `Native Node.js-Module konnten nicht repariert werden: ${commandFailure(rebuilt) || 'ohne Fehlertext'}`,
160
+ );
161
+ }
162
+
163
+ const after = probeBetterSqlite({ nodeBinary, projectDir: absoluteProjectDir, spawnSyncImpl });
164
+ if (after.status !== 0) {
165
+ throw new Error(
166
+ `Ladeprobe nach dem Rebuild fehlgeschlagen: ${commandFailure(after) || 'ohne Fehlertext'}`,
167
+ );
168
+ }
169
+ return { kind: 'repaired' };
170
+ }
171
+
172
+ function repairConfiguredNativeModules({
173
+ blunDir,
174
+ callerCwd,
175
+ nodeBinary = process.execPath,
176
+ onRepairStart,
177
+ projectPaths,
178
+ repairProject = repairNativeProject,
179
+ spawnSyncImpl = spawnSync,
180
+ }) {
181
+ const projects = projectPaths || configuredNativeProjectPaths({ blunDir, callerCwd });
182
+ const result = { checked: projects.length, healthy: [], repaired: [], skipped: [] };
183
+ for (const projectDir of projects) {
184
+ const firstResult = repairProject({
185
+ nodeBinary,
186
+ projectDir,
187
+ spawnSyncImpl,
188
+ onRepairStart,
189
+ });
190
+ if (firstResult.kind === 'healthy') result.healthy.push(projectDir);
191
+ else if (firstResult.kind === 'repaired') result.repaired.push(projectDir);
192
+ else result.skipped.push(projectDir);
193
+ }
194
+ return result;
195
+ }
196
+
197
+ module.exports = {
198
+ configuredNativeProjectPaths,
199
+ repairConfiguredNativeModules,
200
+ repairNativeProject,
201
+ };
@@ -1,34 +1,34 @@
1
- 'use strict';
2
-
3
- const { ensureManagedNode } = require('./managed-node');
4
- const { unsupportedNodeMessage } = require('./node-version');
5
-
6
- async function prepareManagedNodeRuntime(options = {}) {
7
- const version = options.version || process.versions.node;
8
- const platform = options.platform || process.platform;
9
- const arch = options.arch || process.arch;
10
- const message = unsupportedNodeMessage(version, platform);
11
- if (message === null) return { kind: 'current' };
12
- if (platform !== 'darwin' && platform !== 'win32') return { kind: 'failed', message };
13
-
14
- try {
15
- const blunDir = options.blunDir || options.getBlunDir?.();
16
- const binary = await (options.ensureManagedNode || ensureManagedNode)(
17
- blunDir,
18
- platform,
19
- arch,
20
- );
21
- return { binary, kind: 'managed' };
22
- } catch (error) {
23
- return {
24
- kind: 'failed',
25
- message: [
26
- 'Die automatische Node.js-Einrichtung ist fehlgeschlagen.',
27
- error && error.message ? error.message : String(error),
28
- message,
29
- ].join('\n'),
30
- };
31
- }
32
- }
33
-
34
- module.exports = { prepareManagedNodeRuntime };
1
+ 'use strict';
2
+
3
+ const { ensureManagedNode } = require('./managed-node');
4
+ const { unsupportedNodeMessage } = require('./node-version');
5
+
6
+ async function prepareManagedNodeRuntime(options = {}) {
7
+ const version = options.version || process.versions.node;
8
+ const platform = options.platform || process.platform;
9
+ const arch = options.arch || process.arch;
10
+ const message = unsupportedNodeMessage(version, platform);
11
+ if (message === null) return { kind: 'current' };
12
+ if (platform !== 'darwin' && platform !== 'win32') return { kind: 'failed', message };
13
+
14
+ try {
15
+ const blunDir = options.blunDir || options.getBlunDir?.();
16
+ const binary = await (options.ensureManagedNode || ensureManagedNode)(
17
+ blunDir,
18
+ platform,
19
+ arch,
20
+ );
21
+ return { binary, kind: 'managed' };
22
+ } catch (error) {
23
+ return {
24
+ kind: 'failed',
25
+ message: [
26
+ 'Die automatische Node.js-Einrichtung ist fehlgeschlagen.',
27
+ error && error.message ? error.message : String(error),
28
+ message,
29
+ ].join('\n'),
30
+ };
31
+ }
32
+ }
33
+
34
+ module.exports = { prepareManagedNodeRuntime };
@@ -1,49 +1,49 @@
1
- 'use strict';
2
-
3
- const MINIMUM_NODE_VERSION = '24.15.0';
4
-
5
- function parseNodeVersion(version) {
6
- const match = /^(\d+)\.(\d+)\.(\d+)/.exec(String(version));
7
- return match ? match.slice(1).map(Number) : null;
8
- }
9
-
10
- function supportsNodeVersion(version) {
11
- const actual = parseNodeVersion(version);
12
- const minimum = parseNodeVersion(MINIMUM_NODE_VERSION);
13
- if (!actual || !minimum) return false;
14
-
15
- for (let index = 0; index < minimum.length; index += 1) {
16
- if (actual[index] > minimum[index]) return true;
17
- if (actual[index] < minimum[index]) return false;
18
- }
19
- return true;
20
- }
21
-
22
- function unsupportedNodeMessage(version, platform) {
23
- if (supportsNodeVersion(version)) return null;
24
-
25
- const lines = [
26
- '',
27
- 'BLUN kann mit dieser Node.js-Version nicht starten.',
28
- `Installiert: Node.js ${version}`,
29
- `Benoetigt: Node.js ${MINIMUM_NODE_VERSION} oder neuer`,
30
- '',
31
- ];
32
-
33
- if (platform === 'darwin') {
34
- lines.push(`Falls die automatische Einrichtung scheitert: nvm install ${MINIMUM_NODE_VERSION}`);
35
- } else if (platform === 'win32') {
36
- lines.push(`Falls die automatische Einrichtung scheitert: Node.js ${MINIMUM_NODE_VERSION} oder neuer von https://nodejs.org/ installieren.`);
37
- } else {
38
- lines.push(`Node.js ${MINIMUM_NODE_VERSION} oder neuer installieren: https://nodejs.org/`);
39
- }
40
- lines.push('Danach BLUN aktualisieren: npm i -g blun-king-cli@latest', '');
41
- return lines.join('\n');
42
- }
43
-
44
- module.exports = {
45
- MINIMUM_NODE_VERSION,
46
- parseNodeVersion,
47
- supportsNodeVersion,
48
- unsupportedNodeMessage,
49
- };
1
+ 'use strict';
2
+
3
+ const MINIMUM_NODE_VERSION = '24.15.0';
4
+
5
+ function parseNodeVersion(version) {
6
+ const match = /^(\d+)\.(\d+)\.(\d+)/.exec(String(version));
7
+ return match ? match.slice(1).map(Number) : null;
8
+ }
9
+
10
+ function supportsNodeVersion(version) {
11
+ const actual = parseNodeVersion(version);
12
+ const minimum = parseNodeVersion(MINIMUM_NODE_VERSION);
13
+ if (!actual || !minimum) return false;
14
+
15
+ for (let index = 0; index < minimum.length; index += 1) {
16
+ if (actual[index] > minimum[index]) return true;
17
+ if (actual[index] < minimum[index]) return false;
18
+ }
19
+ return true;
20
+ }
21
+
22
+ function unsupportedNodeMessage(version, platform) {
23
+ if (supportsNodeVersion(version)) return null;
24
+
25
+ const lines = [
26
+ '',
27
+ 'BLUN kann mit dieser Node.js-Version nicht starten.',
28
+ `Installiert: Node.js ${version}`,
29
+ `Benoetigt: Node.js ${MINIMUM_NODE_VERSION} oder neuer`,
30
+ '',
31
+ ];
32
+
33
+ if (platform === 'darwin') {
34
+ lines.push(`Falls die automatische Einrichtung scheitert: nvm install ${MINIMUM_NODE_VERSION}`);
35
+ } else if (platform === 'win32') {
36
+ lines.push(`Falls die automatische Einrichtung scheitert: Node.js ${MINIMUM_NODE_VERSION} oder neuer von https://nodejs.org/ installieren.`);
37
+ } else {
38
+ lines.push(`Node.js ${MINIMUM_NODE_VERSION} oder neuer installieren: https://nodejs.org/`);
39
+ }
40
+ lines.push('Danach BLUN aktualisieren: npm i -g blun-king-cli@latest', '');
41
+ return lines.join('\n');
42
+ }
43
+
44
+ module.exports = {
45
+ MINIMUM_NODE_VERSION,
46
+ parseNodeVersion,
47
+ supportsNodeVersion,
48
+ unsupportedNodeMessage,
49
+ };