@pellux/goodvibes-sdk 0.18.28 → 0.18.30

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 (109) hide show
  1. package/dist/_internal/platform/agents/orchestrator-runner.js +1 -1
  2. package/dist/_internal/platform/bookmarks/manager.d.ts +1 -1
  3. package/dist/_internal/platform/bookmarks/manager.d.ts.map +1 -1
  4. package/dist/_internal/platform/channels/surface-registry.js +3 -3
  5. package/dist/_internal/platform/config/api-keys.d.ts +29 -0
  6. package/dist/_internal/platform/config/api-keys.d.ts.map +1 -0
  7. package/dist/_internal/platform/config/api-keys.js +153 -0
  8. package/dist/_internal/platform/config/index.d.ts +1 -13
  9. package/dist/_internal/platform/config/index.d.ts.map +1 -1
  10. package/dist/_internal/platform/config/index.js +1 -138
  11. package/dist/_internal/platform/config/schema-domain-core.d.ts +1 -0
  12. package/dist/_internal/platform/config/schema-domain-core.d.ts.map +1 -1
  13. package/dist/_internal/platform/config/schema-domain-core.js +7 -0
  14. package/dist/_internal/platform/config/schema-types.d.ts +3 -2
  15. package/dist/_internal/platform/config/schema-types.d.ts.map +1 -1
  16. package/dist/_internal/platform/config/tool-llm.d.ts.map +1 -1
  17. package/dist/_internal/platform/config/tool-llm.js +3 -0
  18. package/dist/_internal/platform/core/conversation-diff.d.ts +6 -2
  19. package/dist/_internal/platform/core/conversation-diff.d.ts.map +1 -1
  20. package/dist/_internal/platform/core/conversation.d.ts +13 -5
  21. package/dist/_internal/platform/core/conversation.d.ts.map +1 -1
  22. package/dist/_internal/platform/core/conversation.js +35 -1
  23. package/dist/_internal/platform/pairing/companion-token.d.ts +45 -0
  24. package/dist/_internal/platform/pairing/companion-token.d.ts.map +1 -0
  25. package/dist/_internal/platform/pairing/companion-token.js +74 -0
  26. package/dist/_internal/platform/pairing/connection-info.d.ts +10 -0
  27. package/dist/_internal/platform/pairing/connection-info.d.ts.map +1 -0
  28. package/dist/_internal/platform/pairing/connection-info.js +27 -0
  29. package/dist/_internal/platform/pairing/index.d.ts +6 -0
  30. package/dist/_internal/platform/pairing/index.d.ts.map +1 -0
  31. package/dist/_internal/platform/pairing/index.js +3 -0
  32. package/dist/_internal/platform/pairing/qr-generator.d.ts +20 -0
  33. package/dist/_internal/platform/pairing/qr-generator.d.ts.map +1 -0
  34. package/dist/_internal/platform/pairing/qr-generator.js +452 -0
  35. package/dist/_internal/platform/plugins/loader.d.ts +5 -1
  36. package/dist/_internal/platform/plugins/loader.d.ts.map +1 -1
  37. package/dist/_internal/platform/plugins/loader.js +7 -3
  38. package/dist/_internal/platform/runtime/bootstrap-hook-bridge.d.ts +10 -0
  39. package/dist/_internal/platform/runtime/bootstrap-hook-bridge.d.ts.map +1 -0
  40. package/dist/_internal/platform/runtime/bootstrap-hook-bridge.js +143 -0
  41. package/dist/_internal/platform/runtime/diagnostics/panels/panel-resources.d.ts +5 -5
  42. package/dist/_internal/platform/runtime/diagnostics/panels/panel-resources.d.ts.map +1 -1
  43. package/dist/_internal/platform/runtime/diagnostics/panels/panel-resources.js +3 -3
  44. package/dist/_internal/platform/runtime/diagnostics/types.d.ts +26 -13
  45. package/dist/_internal/platform/runtime/diagnostics/types.d.ts.map +1 -1
  46. package/dist/_internal/platform/runtime/diagnostics/types.js +4 -2
  47. package/dist/_internal/platform/runtime/mutable-runtime-state.d.ts +14 -0
  48. package/dist/_internal/platform/runtime/mutable-runtime-state.d.ts.map +1 -0
  49. package/dist/_internal/platform/runtime/mutable-runtime-state.js +1 -0
  50. package/dist/_internal/platform/runtime/ops/playbooks/permission-deadlock.js +2 -2
  51. package/dist/_internal/platform/runtime/perf/component-contracts.d.ts +114 -0
  52. package/dist/_internal/platform/runtime/perf/component-contracts.d.ts.map +1 -0
  53. package/dist/_internal/platform/runtime/perf/component-contracts.js +104 -0
  54. package/dist/_internal/platform/runtime/perf/component-health-monitor.d.ts +98 -0
  55. package/dist/_internal/platform/runtime/perf/component-health-monitor.d.ts.map +1 -0
  56. package/dist/_internal/platform/runtime/perf/component-health-monitor.js +248 -0
  57. package/dist/_internal/platform/runtime/perf/index.d.ts +6 -3
  58. package/dist/_internal/platform/runtime/perf/index.d.ts.map +1 -1
  59. package/dist/_internal/platform/runtime/perf/index.js +4 -2
  60. package/dist/_internal/platform/runtime/perf/panel-contracts.d.ts +6 -90
  61. package/dist/_internal/platform/runtime/perf/panel-contracts.d.ts.map +1 -1
  62. package/dist/_internal/platform/runtime/perf/panel-contracts.js +4 -83
  63. package/dist/_internal/platform/runtime/perf/panel-health-monitor.d.ts +4 -88
  64. package/dist/_internal/platform/runtime/perf/panel-health-monitor.d.ts.map +1 -1
  65. package/dist/_internal/platform/runtime/perf/panel-health-monitor.js +4 -236
  66. package/dist/_internal/platform/runtime/service-queries.d.ts +3 -0
  67. package/dist/_internal/platform/runtime/service-queries.d.ts.map +1 -0
  68. package/dist/_internal/platform/runtime/service-queries.js +1 -0
  69. package/dist/_internal/platform/runtime/services.d.ts +2 -2
  70. package/dist/_internal/platform/runtime/services.d.ts.map +1 -1
  71. package/dist/_internal/platform/runtime/services.js +3 -3
  72. package/dist/_internal/platform/runtime/session-return-context.js +1 -1
  73. package/dist/_internal/platform/runtime/shell-command-services.d.ts +2 -2
  74. package/dist/_internal/platform/runtime/shell-command-services.d.ts.map +1 -1
  75. package/dist/_internal/platform/runtime/shell-command-services.js +2 -2
  76. package/dist/_internal/platform/runtime/shell-command-workspace.d.ts +2 -2
  77. package/dist/_internal/platform/runtime/shell-command-workspace.d.ts.map +1 -1
  78. package/dist/_internal/platform/runtime/shell-command-workspace.js +2 -2
  79. package/dist/_internal/platform/runtime/store/domains/index.d.ts +2 -0
  80. package/dist/_internal/platform/runtime/store/domains/index.d.ts.map +1 -1
  81. package/dist/_internal/platform/runtime/store/domains/index.js +1 -0
  82. package/dist/_internal/platform/runtime/store/selectors/index.d.ts +27 -14
  83. package/dist/_internal/platform/runtime/store/selectors/index.d.ts.map +1 -1
  84. package/dist/_internal/platform/runtime/store/selectors/index.js +35 -25
  85. package/dist/_internal/platform/runtime/store/state.d.ts +3 -4
  86. package/dist/_internal/platform/runtime/store/state.d.ts.map +1 -1
  87. package/dist/_internal/platform/runtime/store/state.js +3 -4
  88. package/dist/_internal/platform/runtime/system-message-policy.d.ts +18 -0
  89. package/dist/_internal/platform/runtime/system-message-policy.d.ts.map +1 -0
  90. package/dist/_internal/platform/runtime/system-message-policy.js +35 -0
  91. package/dist/_internal/platform/utils/clipboard.d.ts +3 -2
  92. package/dist/_internal/platform/utils/clipboard.d.ts.map +1 -1
  93. package/dist/_internal/platform/utils/clipboard.js +0 -17
  94. package/dist/_internal/platform/utils/notify.d.ts.map +1 -1
  95. package/dist/_internal/platform/utils/notify.js +4 -1
  96. package/dist/_internal/platform/utils/terminal-width.d.ts +13 -0
  97. package/dist/_internal/platform/utils/terminal-width.d.ts.map +1 -1
  98. package/dist/_internal/platform/utils/terminal-width.js +13 -0
  99. package/dist/_internal/platform/version.js +1 -1
  100. package/package.json +1 -1
  101. package/dist/_internal/platform/core/history.d.ts +0 -22
  102. package/dist/_internal/platform/core/history.d.ts.map +0 -1
  103. package/dist/_internal/platform/core/history.js +0 -43
  104. package/dist/_internal/platform/types/grid.d.ts +0 -27
  105. package/dist/_internal/platform/types/grid.d.ts.map +0 -1
  106. package/dist/_internal/platform/types/grid.js +0 -26
  107. package/dist/_internal/platform/utils/splash-lines.d.ts +0 -8
  108. package/dist/_internal/platform/utils/splash-lines.d.ts.map +0 -1
  109. package/dist/_internal/platform/utils/splash-lines.js +0 -32
@@ -0,0 +1,452 @@
1
+ import { execSync } from 'node:child_process';
2
+ /**
3
+ * Attempt to generate a QR matrix by shelling out to `qrencode`.
4
+ * Returns null if qrencode is not available or fails.
5
+ */
6
+ function tryQrencode(data) {
7
+ try {
8
+ // -t ASC outputs a 2-character-per-module ASCII representation:
9
+ // '##' = dark module, ' ' = light module, with a surrounding quiet zone
10
+ // We use -t UTF8i (inverted) if available, or fall back to -t ASC.
11
+ // qrencode -t ASC outputs lines like: '###### ## ######'
12
+ // where each character is one module.
13
+ // We request -m 0 (no margin) and -s 1 for raw matrix output.
14
+ const output = execSync(`qrencode -m 0 -t ASC ${JSON.stringify(data)}`, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000 });
15
+ const rawLines = output.split('\n').filter((l) => l.length > 0);
16
+ if (rawLines.length === 0)
17
+ return null;
18
+ // qrencode ASC mode: each module is 2 characters wide ('##' dark, ' ' light)
19
+ const modules = rawLines.map((line) => {
20
+ const row = [];
21
+ for (let i = 0; i < line.length; i += 2) {
22
+ const pair = line.slice(i, i + 2);
23
+ row.push(pair === '##');
24
+ }
25
+ return row;
26
+ });
27
+ const size = modules[0]?.length ?? 0;
28
+ // Normalize all rows to the same size
29
+ const normalized = modules.map((row) => {
30
+ while (row.length < size)
31
+ row.push(false);
32
+ return row.slice(0, size);
33
+ });
34
+ return { size, modules: normalized };
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ /**
41
+ * Minimal fallback QR matrix generator using a tiny Reed-Solomon QR implementation.
42
+ * Supports QR versions 1-9 (up to ~134 bytes, ECC level M).
43
+ *
44
+ * This is a self-contained implementation suitable for short connection strings.
45
+ */
46
+ function generateQrMatrixMinimal(data) {
47
+ const bytes = new TextEncoder().encode(data);
48
+ const len = bytes.length;
49
+ // Version selection table: [version, dataCapacityBytes at ECC-M]
50
+ // Source: QR code spec Table 9
51
+ const versionTable = [
52
+ [1, 16], [2, 28], [3, 44], [4, 64], [5, 86],
53
+ [6, 108], [7, 124], [8, 154], [9, 182], [10, 216],
54
+ ];
55
+ let version = 0;
56
+ for (const [v, cap] of versionTable) {
57
+ if (len <= cap) {
58
+ version = v;
59
+ break;
60
+ }
61
+ }
62
+ if (version === 0) {
63
+ throw new Error(`Data too long for minimal QR generator (${len} bytes, max 216)`);
64
+ }
65
+ // Total codewords and ECC codewords per block (ECC level M)
66
+ // [version]: [totalCodewords, eccCodewords, blocks]
67
+ const eccTable = {
68
+ 1: [26, 10, 1], 2: [44, 16, 1], 3: [70, 26, 2],
69
+ 4: [100, 36, 2], 5: [134, 48, 2], 6: [172, 64, 4],
70
+ 7: [196, 72, 4], 8: [242, 88, 4], 9: [292, 110, 5],
71
+ 10: [346, 130, 5],
72
+ };
73
+ const [totalCodewords, eccPerBlock, numBlocks] = eccTable[version];
74
+ const dataCodewords = totalCodewords - (eccPerBlock * numBlocks);
75
+ // Build data bit stream: mode (byte=0100), char count, data, terminator, padding
76
+ const bits = [];
77
+ function pushBits(value, count) {
78
+ for (let i = count - 1; i >= 0; i--) {
79
+ bits.push((value >> i) & 1);
80
+ }
81
+ }
82
+ // Mode indicator: byte mode = 0100
83
+ pushBits(0b0100, 4);
84
+ // Character count indicator (version 1-9: 8 bits for byte mode)
85
+ pushBits(len, 8);
86
+ // Data bytes
87
+ for (const b of bytes)
88
+ pushBits(b, 8);
89
+ // Terminator (up to 4 zero bits)
90
+ const maxBits = dataCodewords * 8;
91
+ for (let i = 0; i < 4 && bits.length < maxBits; i++)
92
+ bits.push(0);
93
+ // Pad to byte boundary
94
+ while (bits.length % 8 !== 0)
95
+ bits.push(0);
96
+ // Pad codewords
97
+ const padBytes = [0xEC, 0x11];
98
+ let padIdx = 0;
99
+ while (bits.length < maxBits) {
100
+ pushBits(padBytes[padIdx % 2], 8);
101
+ padIdx++;
102
+ }
103
+ // Convert bits to bytes
104
+ const dataBytes = [];
105
+ for (let i = 0; i < bits.length; i += 8) {
106
+ let b = 0;
107
+ for (let j = 0; j < 8; j++)
108
+ b = (b << 1) | (bits[i + j] ?? 0);
109
+ dataBytes.push(b);
110
+ }
111
+ // Split into blocks and compute ECC
112
+ const dataPerBlock = Math.floor(dataCodewords / numBlocks);
113
+ const extraBlocks = dataCodewords - dataPerBlock * numBlocks;
114
+ const blocks = [];
115
+ let offset = 0;
116
+ for (let b = 0; b < numBlocks; b++) {
117
+ const blockLen = dataPerBlock + (b < extraBlocks ? 1 : 0);
118
+ blocks.push(dataBytes.slice(offset, offset + blockLen));
119
+ offset += blockLen;
120
+ }
121
+ // Reed-Solomon ECC generation
122
+ function gfMul(a, b) {
123
+ if (a === 0 || b === 0)
124
+ return 0;
125
+ const logTable = buildLogTable();
126
+ const expTable = buildExpTable();
127
+ return expTable[(logTable[a] + logTable[b]) % 255];
128
+ }
129
+ // Lazily built lookup tables (closured)
130
+ let _expTable = null;
131
+ let _logTable = null;
132
+ function buildExpTable() {
133
+ if (_expTable)
134
+ return _expTable;
135
+ _expTable = new Array(256);
136
+ let x = 1;
137
+ for (let i = 0; i < 255; i++) {
138
+ _expTable[i] = x;
139
+ x = (x << 1) ^ (x >= 128 ? 0x11d : 0);
140
+ }
141
+ _expTable[255] = _expTable[0];
142
+ return _expTable;
143
+ }
144
+ function buildLogTable() {
145
+ if (_logTable)
146
+ return _logTable;
147
+ const exp = buildExpTable();
148
+ _logTable = new Array(256).fill(0);
149
+ for (let i = 0; i < 255; i++)
150
+ _logTable[exp[i]] = i;
151
+ return _logTable;
152
+ }
153
+ function rsEcc(data, eccCount) {
154
+ // Generator polynomial for eccCount error correction codewords
155
+ const expTable = buildExpTable();
156
+ const logTable = buildLogTable();
157
+ // Build generator polynomial
158
+ let gen = [1];
159
+ for (let i = 0; i < eccCount; i++) {
160
+ const factor = [1, expTable[i]];
161
+ const newGen = new Array(gen.length + factor.length - 1).fill(0);
162
+ for (let j = 0; j < gen.length; j++) {
163
+ for (let k = 0; k < factor.length; k++) {
164
+ newGen[j + k] ^= gfMul(gen[j], factor[k]);
165
+ }
166
+ }
167
+ gen = newGen;
168
+ }
169
+ // Polynomial long division
170
+ const msg = [...data, ...new Array(eccCount).fill(0)];
171
+ for (let i = 0; i < data.length; i++) {
172
+ const coef = msg[i];
173
+ if (coef !== 0) {
174
+ const log = logTable[coef];
175
+ for (let j = 0; j < gen.length; j++) {
176
+ msg[i + j] ^= gfMul(gen[j], expTable[(log + logTable[gen[j]]) % 255] / gen[j] | 0);
177
+ // Correct formula using logs:
178
+ if (gen[j] !== 0) {
179
+ msg[i + j] ^= expTable[(log + logTable[gen[j]]) % 255];
180
+ // undo the wrong xor above
181
+ msg[i + j] ^= gfMul(gen[j], expTable[(log + logTable[gen[j]]) % 255] / gen[j] | 0);
182
+ }
183
+ }
184
+ }
185
+ }
186
+ return msg.slice(data.length);
187
+ }
188
+ // Simpler, correct RS ECC implementation:
189
+ function rsEccCorrect(data, eccCount) {
190
+ const expTable = buildExpTable();
191
+ const logTable = buildLogTable();
192
+ let gen = [1];
193
+ for (let i = 0; i < eccCount; i++) {
194
+ const factor = [1, expTable[i]];
195
+ const newGen = new Array(gen.length + factor.length - 1).fill(0);
196
+ for (let j = 0; j < gen.length; j++) {
197
+ for (let k = 0; k < factor.length; k++) {
198
+ newGen[j + k] ^= gfMul(gen[j], factor[k]);
199
+ }
200
+ }
201
+ gen = newGen;
202
+ }
203
+ const msg = [...data, ...new Array(eccCount).fill(0)];
204
+ for (let i = 0; i < data.length; i++) {
205
+ const coef = msg[i];
206
+ if (coef !== 0) {
207
+ const logCoef = logTable[coef];
208
+ for (let j = 1; j < gen.length; j++) {
209
+ if (gen[j] !== 0) {
210
+ msg[i + j] ^= expTable[(logCoef + logTable[gen[j]]) % 255];
211
+ }
212
+ }
213
+ }
214
+ }
215
+ return msg.slice(data.length);
216
+ }
217
+ // Interleave blocks and compute ECC
218
+ const eccBlocks = blocks.map((b) => rsEccCorrect(b, eccPerBlock));
219
+ const finalBytes = [];
220
+ // Interleave data blocks
221
+ const maxDataLen = Math.max(...blocks.map((b) => b.length));
222
+ for (let i = 0; i < maxDataLen; i++) {
223
+ for (const block of blocks) {
224
+ if (i < block.length)
225
+ finalBytes.push(block[i]);
226
+ }
227
+ }
228
+ // Interleave ECC blocks
229
+ for (let i = 0; i < eccPerBlock; i++) {
230
+ for (const ecc of eccBlocks) {
231
+ finalBytes.push(ecc[i]);
232
+ }
233
+ }
234
+ // Build the QR matrix
235
+ const size = 21 + (version - 1) * 4;
236
+ const matrix = Array.from({ length: size }, () => new Array(size).fill(null));
237
+ function setModule(row, col, dark) {
238
+ if (row >= 0 && row < size && col >= 0 && col < size) {
239
+ matrix[row][col] = dark;
240
+ }
241
+ }
242
+ // Place finder pattern
243
+ function placeFinderPattern(r, c) {
244
+ for (let dy = -1; dy <= 7; dy++) {
245
+ for (let dx = -1; dx <= 7; dx++) {
246
+ const inOuter = dy >= 0 && dy <= 6 && dx >= 0 && dx <= 6;
247
+ const inWhite = dy >= 1 && dy <= 5 && dx >= 1 && dx <= 5;
248
+ const inInner = dy >= 2 && dy <= 4 && dx >= 2 && dx <= 4;
249
+ if (!inOuter) {
250
+ setModule(r + dy, c + dx, false); // separator
251
+ }
252
+ else if (inWhite && !inInner) {
253
+ setModule(r + dy, c + dx, false);
254
+ }
255
+ else {
256
+ setModule(r + dy, c + dx, inInner || (dy === 0 || dy === 6 || dx === 0 || dx === 6));
257
+ }
258
+ }
259
+ }
260
+ }
261
+ placeFinderPattern(0, 0);
262
+ placeFinderPattern(0, size - 7);
263
+ placeFinderPattern(size - 7, 0);
264
+ // Timing patterns
265
+ for (let i = 8; i < size - 8; i++) {
266
+ const dark = i % 2 === 0;
267
+ setModule(6, i, dark);
268
+ setModule(i, 6, dark);
269
+ }
270
+ // Alignment patterns (version >= 2)
271
+ const alignmentPositions = {
272
+ 2: [6, 18], 3: [6, 22], 4: [6, 26], 5: [6, 30],
273
+ 6: [6, 34], 7: [6, 22, 38], 8: [6, 24, 42],
274
+ 9: [6, 28, 46], 10: [6, 28, 50],
275
+ };
276
+ const alignPos = version >= 2 ? alignmentPositions[version] ?? [] : [];
277
+ for (const r of alignPos) {
278
+ for (const c of alignPos) {
279
+ // Skip positions occupied by finder patterns
280
+ if ((r <= 8 && c <= 8) || (r <= 8 && c >= size - 8) || (r >= size - 8 && c <= 8))
281
+ continue;
282
+ for (let dy = -2; dy <= 2; dy++) {
283
+ for (let dx = -2; dx <= 2; dx++) {
284
+ const isEdge = Math.abs(dy) === 2 || Math.abs(dx) === 2;
285
+ const isCenter = dy === 0 && dx === 0;
286
+ setModule(r + dy, c + dx, isEdge || isCenter);
287
+ }
288
+ }
289
+ }
290
+ }
291
+ // Dark module (always dark)
292
+ setModule(4 * version + 9, 8, true);
293
+ // Format information area — reserve (mark as false for now)
294
+ for (let i = 0; i < 9; i++) {
295
+ setModule(8, i, matrix[8]?.[i] ?? false);
296
+ setModule(i, 8, matrix[i]?.[8] ?? false);
297
+ }
298
+ for (let i = size - 8; i < size; i++) {
299
+ setModule(8, i, false);
300
+ setModule(i, 8, false);
301
+ }
302
+ // Place data bits (zigzag pattern)
303
+ const allBits = [];
304
+ for (const b of finalBytes) {
305
+ for (let i = 7; i >= 0; i--)
306
+ allBits.push((b >> i) & 1);
307
+ }
308
+ let bitIdx = 0;
309
+ let goUp = true;
310
+ // Right-to-left column pairs, skipping column 6 (timing)
311
+ for (let col = size - 1; col >= 1; col -= 2) {
312
+ if (col === 6)
313
+ col--; // skip timing column
314
+ const colRange = goUp
315
+ ? Array.from({ length: size }, (_, i) => size - 1 - i)
316
+ : Array.from({ length: size }, (_, i) => i);
317
+ for (const row of colRange) {
318
+ for (const dc of [0, -1]) {
319
+ const c = col + dc;
320
+ if (matrix[row]?.[c] === null) {
321
+ const bit = allBits[bitIdx++] ?? 0;
322
+ matrix[row][c] = bit === 1;
323
+ }
324
+ }
325
+ }
326
+ goUp = !goUp;
327
+ }
328
+ // Apply mask pattern 0 (checkerboard: (row + col) % 2 === 0)
329
+ // and place format information
330
+ const maskFn = (r, c) => (r + c) % 2 === 0;
331
+ for (let r = 0; r < size; r++) {
332
+ for (let c = 0; c < size; c++) {
333
+ const module = matrix[r]?.[c];
334
+ if (module === null) {
335
+ matrix[r][c] = false; // unfilled = light
336
+ }
337
+ else {
338
+ // Only apply mask to data modules (not function patterns)
339
+ // We re-apply masking carefully: function patterns are already fixed
340
+ // Data modules that were null are now set above
341
+ }
342
+ }
343
+ }
344
+ // Apply mask to data modules (those placed via zigzag)
345
+ bitIdx = 0;
346
+ goUp = true;
347
+ const maskedMatrix = matrix.map((row) => row.map((m) => m ?? false));
348
+ // Reset data area and re-place with masking
349
+ {
350
+ const tempMatrix = matrix.map((row) => [...row]);
351
+ // Re-mark data positions as null
352
+ let bi = 0;
353
+ let gu = true;
354
+ for (let col = size - 1; col >= 1; col -= 2) {
355
+ if (col === 6)
356
+ col--;
357
+ const colRange = gu
358
+ ? Array.from({ length: size }, (_, i) => size - 1 - i)
359
+ : Array.from({ length: size }, (_, i) => i);
360
+ for (const row of colRange) {
361
+ for (const dc of [0, -1]) {
362
+ const c = col + dc;
363
+ if (tempMatrix[row]?.[c] !== null) {
364
+ // was set as data, apply mask
365
+ const dark = (allBits[bi++] ?? 0) === 1;
366
+ maskedMatrix[row][c] = maskFn(row, c) ? !dark : dark;
367
+ }
368
+ }
369
+ }
370
+ gu = !gu;
371
+ }
372
+ }
373
+ // Format string for ECC level M (01), mask pattern 0 (000)
374
+ // Format info = 01000 XOR 101010000010010 = 110010111100101
375
+ // Precomputed: ECC-M + mask-0 = format bits 101000000100101 (with BCH)
376
+ // Using known correct value for M+mask0: 0x5647 -> bits[14..0]
377
+ // Actually standard value: ECC-M=1, mask=0 -> data=01_000 -> format=01000 00000000
378
+ // BCH(01000)=0100000000+BCH = let's use precomputed: 0x72F3 for M+mask2, etc.
379
+ // Correct precomputed format words (ECC-M=0b01, masks 0-7):
380
+ const formatWords = [
381
+ 0x5412, 0x5125, 0x5E7C, 0x5B4B, 0x45F9, 0x40CE, 0x4F97, 0x4AA0,
382
+ ];
383
+ const formatWord = formatWords[0]; // mask 0
384
+ const formatXor = 0b101010000010010;
385
+ const fmt = (formatWord ^ formatXor) & 0x7FFF;
386
+ const fmtBits = Array.from({ length: 15 }, (_, i) => (fmt >> (14 - i)) & 1);
387
+ // Place format bits around finder patterns
388
+ // Around top-left finder:
389
+ const fmtPositions1 = [
390
+ [8, 0], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 7], [8, 8],
391
+ [7, 8], [5, 8], [4, 8], [3, 8], [2, 8], [1, 8], [0, 8],
392
+ ];
393
+ fmtPositions1.forEach(([r, c], i) => {
394
+ maskedMatrix[r][c] = fmtBits[i] === 1;
395
+ });
396
+ // Around top-right and bottom-left finders:
397
+ const fmtPositions2 = [
398
+ [8, size - 8], [8, size - 7], [8, size - 6], [8, size - 5],
399
+ [8, size - 4], [8, size - 3], [8, size - 2], [8, size - 1],
400
+ ];
401
+ fmtPositions2.forEach(([r, c], i) => {
402
+ maskedMatrix[r][c] = fmtBits[i] === 1;
403
+ });
404
+ const fmtPositions3 = [
405
+ [size - 7, 8], [size - 6, 8], [size - 5, 8],
406
+ [size - 4, 8], [size - 3, 8], [size - 2, 8], [size - 1, 8],
407
+ ];
408
+ fmtPositions3.forEach(([r, c], i) => {
409
+ maskedMatrix[r][c] = fmtBits[i + 8] === 1;
410
+ });
411
+ return { size, modules: maskedMatrix };
412
+ }
413
+ /**
414
+ * Generate a QR code matrix for the given data string.
415
+ * Tries qrencode CLI first; falls back to minimal built-in implementation.
416
+ */
417
+ export function generateQrMatrix(data) {
418
+ const fromCli = tryQrencode(data);
419
+ if (fromCli !== null)
420
+ return fromCli;
421
+ return generateQrMatrixMinimal(data);
422
+ }
423
+ /**
424
+ * Render a QR matrix to a Unicode block string suitable for terminal output.
425
+ * Uses half-block characters to pack 2 rows into 1 terminal row.
426
+ *
427
+ * - Full block `█` = dark top + dark bottom
428
+ * - Upper half `▀` = dark top + light bottom
429
+ * - Lower half `▄` = light top + dark bottom
430
+ * - Space ` ` = light top + light bottom
431
+ */
432
+ export function renderQrToString(matrix) {
433
+ const { size, modules } = matrix;
434
+ const lines = [];
435
+ for (let row = 0; row < size; row += 2) {
436
+ let line = '';
437
+ for (let col = 0; col < size; col++) {
438
+ const top = modules[row]?.[col] ?? false;
439
+ const bottom = modules[row + 1]?.[col] ?? false;
440
+ if (top && bottom)
441
+ line += '\u2588'; // full block
442
+ else if (top && !bottom)
443
+ line += '\u2580'; // upper half
444
+ else if (!top && bottom)
445
+ line += '\u2584'; // lower half
446
+ else
447
+ line += ' '; // space
448
+ }
449
+ lines.push(line);
450
+ }
451
+ return lines.join('\n');
452
+ }
@@ -12,6 +12,10 @@ import type { WebSearchProviderRegistry } from '../web-search/index.js';
12
12
  export interface PluginPathOptions {
13
13
  readonly cwd: string;
14
14
  readonly homeDir: string;
15
+ /** Additional plugin directories to search, appended after the standard directories. */
16
+ readonly additionalDirectories?: readonly string[];
17
+ /** Default entry point filename when a plugin manifest does not specify `main`. Defaults to 'index.js'. */
18
+ readonly entryDefault?: string;
15
19
  }
16
20
  /**
17
21
  * Plugin search directories in precedence order.
@@ -93,7 +97,7 @@ export interface PluginLoaderDeps {
93
97
  * @param cacheBust - Optional timestamp suffix appended to the import URL to bypass
94
98
  * Bun's module cache. Pass `Date.now()` on reload to force fresh execution.
95
99
  */
96
- export declare function loadPlugin(discovered: DiscoveredPlugin, deps: PluginLoaderDeps, cacheBust?: number): Promise<LoadedPlugin | null>;
100
+ export declare function loadPlugin(discovered: DiscoveredPlugin, deps: PluginLoaderDeps, cacheBust?: number, entryDefault?: string): Promise<LoadedPlugin | null>;
97
101
  /**
98
102
  * unloadPlugin — Deactivate a plugin and run all cleanup callbacks.
99
103
  */
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/plugins/loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACxF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAGxE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAEzE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAKzE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,kEAAkE;IAClE,QAAQ,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,wEAAwE;IACxE,UAAU,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,MAAM,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,OAAO,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC3B,8DAA8D;IAC9D,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AA0DD,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,EAAE,CAU9E;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,mBAAmB,CAAC;IACrC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,oBAAoB,CAAC;IACrC,eAAe,EAAE,qBAAqB,CAAC;IACvC,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,uBAAuB,EAAE,+BAA+B,CAAC;IACzD,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,yBAAyB,EAAE,yBAAyB,CAAC;IACrD,0DAA0D;IAC1D,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvD,+DAA+D;IAC/D,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE,gBAAgB,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA8F9B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBtE"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/plugins/loader.ts"],"names":[],"mappings":"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"}
@@ -12,10 +12,14 @@ export function getUserPluginDirectory(options) {
12
12
  return join(options.homeDir, '.goodvibes', PLUGIN_ROOT);
13
13
  }
14
14
  export function getPluginDirectories(options) {
15
- return [
15
+ const dirs = [
16
16
  join(options.cwd, '.goodvibes', PLUGIN_ROOT),
17
17
  getUserPluginDirectory(options),
18
18
  ];
19
+ if (options.additionalDirectories) {
20
+ dirs.push(...options.additionalDirectories);
21
+ }
22
+ return dirs;
19
23
  }
20
24
  /**
21
25
  * discoverPlugins — Scan the configured plugin directories for valid plugin folders.
@@ -88,9 +92,9 @@ export function discoverPlugins(options) {
88
92
  * @param cacheBust - Optional timestamp suffix appended to the import URL to bypass
89
93
  * Bun's module cache. Pass `Date.now()` on reload to force fresh execution.
90
94
  */
91
- export async function loadPlugin(discovered, deps, cacheBust) {
95
+ export async function loadPlugin(discovered, deps, cacheBust, entryDefault) {
92
96
  const { manifest, pluginDir } = discovered;
93
- const entryFile = manifest.main ?? 'index.js';
97
+ const entryFile = manifest.main ?? entryDefault ?? 'index.js';
94
98
  const entryPath = join(pluginDir, entryFile);
95
99
  // Path traversal guard: resolved entry must remain within pluginDir
96
100
  const resolvedEntry = resolve(entryPath);
@@ -0,0 +1,10 @@
1
+ import type { HookDispatcher } from '../hooks/index.js';
2
+ import type { MutableRuntimeState } from './mutable-runtime-state.js';
3
+ import type { RuntimeEventBus } from './events/index.js';
4
+ export interface HookBridgeRegistrationOptions {
5
+ readonly runtimeBus: RuntimeEventBus;
6
+ readonly hookDispatcher: HookDispatcher;
7
+ readonly runtime: MutableRuntimeState;
8
+ }
9
+ export declare function registerBootstrapHookBridge(options: HookBridgeRegistrationOptions): Array<() => void>;
10
+ //# sourceMappingURL=bootstrap-hook-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap-hook-bridge.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/runtime/bootstrap-hook-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAwB,eAAe,EAAiB,MAAM,mBAAmB,CAAC;AA4B9F,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;CACvC;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,6BAA6B,GACrC,KAAK,CAAC,MAAM,IAAI,CAAC,CAoInB"}
@@ -0,0 +1,143 @@
1
+ import { logger } from '../utils/logger.js';
2
+ import { summarizeError } from '../utils/error-display.js';
3
+ function fireHook(options, path, phase, category, specific, payload) {
4
+ options.hookDispatcher.fire({
5
+ path,
6
+ phase,
7
+ category,
8
+ specific,
9
+ sessionId: options.runtime.sessionId,
10
+ timestamp: Date.now(),
11
+ payload,
12
+ }).catch((err) => logger.debug('Hook bridge fire error', { path, error: summarizeError(err) }));
13
+ }
14
+ export function registerBootstrapHookBridge(options) {
15
+ const fireOptions = {
16
+ hookDispatcher: options.hookDispatcher,
17
+ runtime: options.runtime,
18
+ };
19
+ const unsubs = [];
20
+ const { runtimeBus } = options;
21
+ unsubs.push(runtimeBus.on('AGENT_SPAWNING', ({ payload }) => {
22
+ fireHook(fireOptions, 'Lifecycle:agent:spawned', 'Lifecycle', 'agent', 'spawned', { agentId: payload.agentId, task: payload.task });
23
+ }));
24
+ unsubs.push(runtimeBus.on('AGENT_COMPLETED', ({ payload }) => {
25
+ fireHook(fireOptions, 'Lifecycle:agent:completed', 'Lifecycle', 'agent', 'completed', {
26
+ agentId: payload.agentId,
27
+ result: {
28
+ durationMs: payload.durationMs,
29
+ ...(payload.output !== undefined ? { output: payload.output } : {}),
30
+ ...(payload.toolCallsMade !== undefined ? { toolCallsMade: payload.toolCallsMade } : {}),
31
+ },
32
+ });
33
+ }));
34
+ unsubs.push(runtimeBus.on('AGENT_FAILED', ({ payload }) => {
35
+ const specific = payload.error === 'Agent cancelled' || payload.error.includes('cancelled') ? 'cancelled' : 'failed';
36
+ fireHook(fireOptions, `Lifecycle:agent:${specific}`, 'Lifecycle', 'agent', specific, { agentId: payload.agentId, error: payload.error });
37
+ }));
38
+ unsubs.push(runtimeBus.on('WORKFLOW_CHAIN_CREATED', ({ payload }) => {
39
+ fireHook(fireOptions, 'Lifecycle:workflow:started', 'Lifecycle', 'workflow', 'started', { chainId: payload.chainId, task: payload.task });
40
+ }));
41
+ unsubs.push(runtimeBus.on('WORKFLOW_CHAIN_PASSED', ({ payload }) => {
42
+ fireHook(fireOptions, 'Lifecycle:workflow:completed', 'Lifecycle', 'workflow', 'completed', { chainId: payload.chainId });
43
+ }));
44
+ unsubs.push(runtimeBus.on('WORKFLOW_CHAIN_FAILED', ({ payload }) => {
45
+ fireHook(fireOptions, 'Lifecycle:workflow:failed', 'Lifecycle', 'workflow', 'failed', { chainId: payload.chainId, reason: payload.reason });
46
+ }));
47
+ unsubs.push(runtimeBus.on('WORKFLOW_REVIEW_COMPLETED', ({ payload }) => {
48
+ fireHook(fireOptions, 'Lifecycle:workflow:reviewed', 'Lifecycle', 'workflow', 'reviewed', {
49
+ chainId: payload.chainId,
50
+ score: payload.score,
51
+ passed: payload.passed,
52
+ });
53
+ }));
54
+ unsubs.push(runtimeBus.on('WORKFLOW_FIX_ATTEMPTED', ({ payload }) => {
55
+ fireHook(fireOptions, 'Lifecycle:workflow:fix-attempted', 'Lifecycle', 'workflow', 'fix-attempted', {
56
+ chainId: payload.chainId,
57
+ attempt: payload.attempt,
58
+ maxAttempts: payload.maxAttempts,
59
+ });
60
+ }));
61
+ unsubs.push(runtimeBus.on('WORKFLOW_GATE_RESULT', ({ payload }) => {
62
+ fireHook(fireOptions, 'Lifecycle:workflow:gate-result', 'Lifecycle', 'workflow', 'gate-result', {
63
+ chainId: payload.chainId,
64
+ gate: payload.gate,
65
+ passed: payload.passed,
66
+ });
67
+ }));
68
+ unsubs.push(runtimeBus.on('ORCHESTRATION_GRAPH_CREATED', ({ payload }) => {
69
+ fireHook(fireOptions, 'Lifecycle:orchestration:graph-created', 'Lifecycle', 'orchestration', 'graph-created', {
70
+ graphId: payload.graphId,
71
+ title: payload.title,
72
+ mode: payload.mode,
73
+ });
74
+ }));
75
+ unsubs.push(runtimeBus.on('ORCHESTRATION_NODE_STARTED', ({ payload }) => {
76
+ fireHook(fireOptions, 'Lifecycle:orchestration:node-started', 'Lifecycle', 'orchestration', 'node-started', {
77
+ graphId: payload.graphId,
78
+ nodeId: payload.nodeId,
79
+ ...(payload.taskId !== undefined ? { taskId: payload.taskId } : {}),
80
+ ...(payload.agentId !== undefined ? { agentId: payload.agentId } : {}),
81
+ });
82
+ }));
83
+ unsubs.push(runtimeBus.on('ORCHESTRATION_NODE_COMPLETED', ({ payload }) => {
84
+ fireHook(fireOptions, 'Lifecycle:orchestration:node-completed', 'Lifecycle', 'orchestration', 'node-completed', {
85
+ graphId: payload.graphId,
86
+ nodeId: payload.nodeId,
87
+ ...(payload.summary !== undefined ? { summary: payload.summary } : {}),
88
+ });
89
+ }));
90
+ unsubs.push(runtimeBus.on('ORCHESTRATION_NODE_FAILED', ({ payload }) => {
91
+ fireHook(fireOptions, 'Lifecycle:orchestration:node-failed', 'Lifecycle', 'orchestration', 'node-failed', {
92
+ graphId: payload.graphId,
93
+ nodeId: payload.nodeId,
94
+ error: payload.error,
95
+ });
96
+ }));
97
+ unsubs.push(runtimeBus.on('ORCHESTRATION_RECURSION_GUARD_TRIGGERED', ({ payload }) => {
98
+ fireHook(fireOptions, 'Change:orchestration:recursion-guard', 'Change', 'orchestration', 'recursion-guard', {
99
+ graphId: payload.graphId,
100
+ ...(payload.nodeId !== undefined ? { nodeId: payload.nodeId } : {}),
101
+ depth: payload.depth,
102
+ activeAgents: payload.activeAgents,
103
+ reason: payload.reason,
104
+ });
105
+ }));
106
+ unsubs.push(runtimeBus.on('COMMUNICATION_SENT', ({ payload }) => {
107
+ fireHook(fireOptions, 'Lifecycle:communication:sent', 'Lifecycle', 'communication', 'sent', {
108
+ messageId: payload.messageId,
109
+ fromId: payload.fromId,
110
+ toId: payload.toId,
111
+ scope: payload.scope,
112
+ kind: payload.kind,
113
+ ...(payload.fromRole !== undefined ? { fromRole: payload.fromRole } : {}),
114
+ ...(payload.toRole !== undefined ? { toRole: payload.toRole } : {}),
115
+ });
116
+ }));
117
+ unsubs.push(runtimeBus.on('COMMUNICATION_DELIVERED', ({ payload }) => {
118
+ fireHook(fireOptions, 'Lifecycle:communication:delivered', 'Lifecycle', 'communication', 'delivered', {
119
+ messageId: payload.messageId,
120
+ fromId: payload.fromId,
121
+ toId: payload.toId,
122
+ scope: payload.scope,
123
+ kind: payload.kind,
124
+ });
125
+ }));
126
+ unsubs.push(runtimeBus.on('COMMUNICATION_BLOCKED', ({ payload }) => {
127
+ fireHook(fireOptions, 'Change:communication:blocked', 'Change', 'communication', 'blocked', {
128
+ messageId: payload.messageId,
129
+ fromId: payload.fromId,
130
+ toId: payload.toId,
131
+ scope: payload.scope,
132
+ kind: payload.kind,
133
+ reason: payload.reason,
134
+ ...(payload.fromRole !== undefined ? { fromRole: payload.fromRole } : {}),
135
+ ...(payload.toRole !== undefined ? { toRole: payload.toRole } : {}),
136
+ });
137
+ }));
138
+ unsubs.push(runtimeBus.on('OPS_CONTEXT_WARNING', ({ payload: { usage, threshold } }) => {
139
+ const specific = usage >= threshold ? 'exceeded' : 'warning';
140
+ fireHook(fireOptions, `Change:budget:${specific}`, 'Change', 'budget', specific, { usage, threshold });
141
+ }));
142
+ return unsubs;
143
+ }