@open-agent-toolkit/cli 0.2.21 → 0.2.22

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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.2.21",
3
- "docs-config": "0.2.21",
4
- "docs-theme": "0.2.21",
5
- "docs-transforms": "0.2.21"
2
+ "cli": "0.2.22",
3
+ "docs-config": "0.2.22",
4
+ "docs-theme": "0.2.22",
5
+ "docs-transforms": "0.2.22"
6
6
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: explainer-kit
3
- version: 2.0.0
3
+ version: 2.0.1
4
4
  description: Use when building destination-neutral visual explainer artifacts from explicit, versioned inputs.
5
5
  user-invocable: true
6
6
  allowed-tools: Read, Write, Edit, Bash, Grep, Glob, Agent, mcp__*
@@ -580,7 +580,14 @@ function srcsetCandidates(value) {
580
580
  }
581
581
 
582
582
  function compactUrl(value) {
583
- return value.replace(/[\u0000-\u0020\u007f]+/g, '').toLowerCase();
583
+ // Strip C0 controls, ASCII space, and DEL without a control-char regex
584
+ // (oxlint/eslint no-control-regex flags those literals even when intentional).
585
+ let compact = '';
586
+ for (const ch of value) {
587
+ const code = ch.codePointAt(0);
588
+ if (code > 0x20 && code !== 0x7f) compact += ch;
589
+ }
590
+ return compact.toLowerCase();
584
591
  }
585
592
 
586
593
  // Shared with the render QA structural check so both call sites enforce one
@@ -770,7 +770,7 @@ function normalizeClaim(value) {
770
770
  throw new TypeError('Cohesion claims must be strings, numbers, or booleans.');
771
771
  }
772
772
 
773
- function validateProbeResult(result, artifactId, width, request) {
773
+ function validateProbeResult(result, id, width, request) {
774
774
  if (
775
775
  !isPlainObject(result) ||
776
776
  typeof result.pageOverflowX !== 'boolean' ||
@@ -779,7 +779,7 @@ function validateProbeResult(result, artifactId, width, request) {
779
779
  !isPlainObject(result.keyboard)
780
780
  ) {
781
781
  throw new TypeError(
782
- `Browser probe for ${artifactId} at ${width}px returned an invalid result.`,
782
+ `Browser probe for ${id} at ${width}px returned an invalid result.`,
783
783
  );
784
784
  }
785
785
  if (
@@ -791,17 +791,17 @@ function validateProbeResult(result, artifactId, width, request) {
791
791
  typeof result.animationsDisabled !== 'boolean')
792
792
  ) {
793
793
  throw new TypeError(
794
- `Browser layout probe for ${artifactId} at ${width}px returned an invalid result.`,
794
+ `Browser layout probe for ${id} at ${width}px returned an invalid result.`,
795
795
  );
796
796
  }
797
797
  if (request.themeToggle && !isPlainObject(result.themeToggle)) {
798
798
  throw new TypeError(
799
- `Browser theme probe for ${artifactId} at ${width}px returned an invalid result.`,
799
+ `Browser theme probe for ${id} at ${width}px returned an invalid result.`,
800
800
  );
801
801
  }
802
802
  if (request.scenario !== 'default' && !isPlainObject(result.deckLayout)) {
803
803
  throw new TypeError(
804
- `Browser deck probe for ${artifactId} at ${width}px returned an invalid result.`,
804
+ `Browser deck probe for ${id} at ${width}px returned an invalid result.`,
805
805
  );
806
806
  }
807
807
  }
@@ -116,9 +116,7 @@ export function evaluateExpansionProposals(recipe, proposals) {
116
116
  const seenIds = new Set();
117
117
  const acceptedByProfile = new Map();
118
118
  const acceptedByType = new Map();
119
- const maxPerType = new Map(
120
- Object.entries(expansion.limits.maxPerType ?? {}),
121
- );
119
+ const maxPerType = new Map(Object.entries(expansion.limits.maxPerType ?? {}));
122
120
 
123
121
  if (!Array.isArray(proposals)) {
124
122
  return {
@@ -180,7 +178,10 @@ export function evaluateExpansionProposals(recipe, proposals) {
180
178
  // A declared type cap binds across profiles, so proposals cannot spread
181
179
  // over sibling profiles that share one artifact type to evade it.
182
180
  const typeCount = acceptedByType.get(profile.type) ?? 0;
183
- if (maxPerType.has(profile.type) && typeCount >= maxPerType.get(profile.type)) {
181
+ if (
182
+ maxPerType.has(profile.type) &&
183
+ typeCount >= maxPerType.get(profile.type)
184
+ ) {
184
185
  rejected.push({
185
186
  ...structuredClone(proposal),
186
187
  status: 'rejected',
@@ -74,7 +74,12 @@ export async function runRenderQaStage({
74
74
  };
75
75
  }
76
76
 
77
- return probeSiteArtifacts({ siteDir, artifacts, probe: browserProbe, widths });
77
+ return probeSiteArtifacts({
78
+ siteDir,
79
+ artifacts,
80
+ probe: browserProbe,
81
+ widths,
82
+ });
78
83
  }
79
84
 
80
85
  async function probeSiteArtifacts({ siteDir, artifacts, probe, widths }) {
@@ -441,8 +441,7 @@ async function hydrateResumableState(state) {
441
441
  state.resumedApprovalStatus = approval.status;
442
442
  // Reopened stages rerun against the corrected content, so carrying their
443
443
  // prior warnings forward would outlive the fix that resolved them.
444
- const rerunning =
445
- approval.status === 'rejected' ? REOPENED_ON_REJECTION : [];
444
+ const rerunning = approval.status === 'rejected' ? REOPENED_ON_REJECTION : [];
446
445
  state.warnings.push(
447
446
  ...record.stages
448
447
  .filter(({ id }) => !rerunning.includes(id))
@@ -1039,11 +1038,7 @@ async function authorArtifact(state, artifact, author, trust) {
1039
1038
  }
1040
1039
  const retained = {
1041
1040
  ...structuredClone(result),
1042
- provenance: resolveAuthorProvenance(
1043
- result.provenance,
1044
- trust,
1045
- artifact.id,
1046
- ),
1041
+ provenance: resolveAuthorProvenance(result.provenance, trust, artifact.id),
1047
1042
  };
1048
1043
  const retainedValidation = validateContract('author-result/v2', retained);
1049
1044
  if (!retainedValidation.valid) {
@@ -1115,9 +1110,7 @@ function markdownContentModel(artifact, slug, markdown, artifactLinks) {
1115
1110
 
1116
1111
  // Prose between the document title and the first `##` is authored content,
1117
1112
  // so it is carried as a leading section rather than silently dropped.
1118
- const bodyStart = titleMatch
1119
- ? titleMatch.index + titleMatch[0].length
1120
- : 0;
1113
+ const bodyStart = titleMatch ? titleMatch.index + titleMatch[0].length : 0;
1121
1114
  const lead = markdown.slice(bodyStart, headings[0].index).trim();
1122
1115
  const authoredIds = new Set(
1123
1116
  headings.map((heading) => slugify(heading[1].trim())),
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-brainstorm
3
- version: 1.1.1
3
+ version: 1.1.2
4
4
  description: Use when the user explicitly invokes the `brainstorm` verb, including `/oat-brainstorm`, "let's brainstorm", "brainstorm this", "can we brainstorm X", or "help me brainstorm X". For ambiguous exploratory phrasing ("I've been thinking", "what if", "help me think through"), do NOT auto-enter; respond conversationally and offer mode only after ≥2 sustained exploratory turns. Do NOT use for review, debug, PR, status, implementation, or active-workflow questions.
5
5
  disable-model-invocation: false
6
6
  user-invocable: true
@@ -1,5 +1,5 @@
1
- (function() {
2
- const WS_URL = 'ws://' + window.location.host;
1
+ (function () {
2
+ const WS_URL = `ws://${window.location.host}`;
3
3
  let ws = null;
4
4
  let eventQueue = [];
5
5
 
@@ -7,7 +7,7 @@
7
7
  ws = new WebSocket(WS_URL);
8
8
 
9
9
  ws.onopen = () => {
10
- eventQueue.forEach(e => ws.send(JSON.stringify(e)));
10
+ eventQueue.forEach((e) => ws.send(JSON.stringify(e)));
11
11
  eventQueue = [];
12
12
  };
13
13
 
@@ -41,7 +41,7 @@
41
41
  type: 'click',
42
42
  text: target.textContent.trim(),
43
43
  choice: target.dataset.choice,
44
- id: target.id || null
44
+ id: target.id || null,
45
45
  });
46
46
 
47
47
  // Update indicator bar (defer so toggleSelect runs first)
@@ -51,12 +51,16 @@
51
51
  const container = target.closest('.options') || target.closest('.cards');
52
52
  const selected = container ? container.querySelectorAll('.selected') : [];
53
53
  if (selected.length === 0) {
54
- indicator.textContent = 'Click an option above, then return to the terminal';
54
+ indicator.textContent =
55
+ 'Click an option above, then return to the terminal';
55
56
  } else if (selected.length === 1) {
56
- const label = selected[0].querySelector('h3, .content h3, .card-body h3')?.textContent?.trim() || selected[0].dataset.choice;
57
- indicator.innerHTML = '<span class="selected-text">' + label + ' selected</span> — return to terminal to continue';
57
+ const label =
58
+ selected[0]
59
+ .querySelector('h3, .content h3, .card-body h3')
60
+ ?.textContent?.trim() || selected[0].dataset.choice;
61
+ indicator.innerHTML = `<span class="selected-text">${label} selected</span> — return to terminal to continue`;
58
62
  } else {
59
- indicator.innerHTML = '<span class="selected-text">' + selected.length + ' selected</span> — return to terminal to continue';
63
+ indicator.innerHTML = `<span class="selected-text">${selected.length} selected</span> — return to terminal to continue`;
60
64
  }
61
65
  }, 0);
62
66
  });
@@ -64,11 +68,13 @@
64
68
  // Frame UI: selection tracking
65
69
  window.selectedChoice = null;
66
70
 
67
- window.toggleSelect = function(el) {
71
+ window.toggleSelect = function (el) {
68
72
  const container = el.closest('.options') || el.closest('.cards');
69
73
  const multi = container && container.dataset.multiselect !== undefined;
70
74
  if (container && !multi) {
71
- container.querySelectorAll('.option, .card').forEach(o => o.classList.remove('selected'));
75
+ container
76
+ .querySelectorAll('.option, .card')
77
+ .forEach((o) => o.classList.remove('selected'));
72
78
  }
73
79
  if (multi) {
74
80
  el.classList.toggle('selected');
@@ -81,7 +87,8 @@
81
87
  // Expose API for explicit use
82
88
  window.brainstorm = {
83
89
  send: sendEvent,
84
- choice: (value, metadata = {}) => sendEvent({ type: 'choice', value, ...metadata })
90
+ choice: (value, metadata = {}) =>
91
+ sendEvent({ type: 'choice', value, ...metadata }),
85
92
  };
86
93
 
87
94
  connect();
@@ -5,11 +5,14 @@ const path = require('path');
5
5
 
6
6
  // ========== WebSocket Protocol (RFC 6455) ==========
7
7
 
8
- const OPCODES = { TEXT: 0x01, CLOSE: 0x08, PING: 0x09, PONG: 0x0A };
8
+ const OPCODES = { TEXT: 0x01, CLOSE: 0x08, PING: 0x09, PONG: 0x0a };
9
9
  const WS_MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
10
10
 
11
11
  function computeAcceptKey(clientKey) {
12
- return crypto.createHash('sha1').update(clientKey + WS_MAGIC).digest('base64');
12
+ return crypto
13
+ .createHash('sha1')
14
+ .update(clientKey + WS_MAGIC)
15
+ .digest('base64');
13
16
  }
14
17
 
15
18
  function encodeFrame(opcode, payload) {
@@ -40,9 +43,9 @@ function decodeFrame(buffer) {
40
43
  if (buffer.length < 2) return null;
41
44
 
42
45
  const secondByte = buffer[1];
43
- const opcode = buffer[0] & 0x0F;
46
+ const opcode = buffer[0] & 0x0f;
44
47
  const masked = (secondByte & 0x80) !== 0;
45
- let payloadLen = secondByte & 0x7F;
48
+ let payloadLen = secondByte & 0x7f;
46
49
  let offset = 2;
47
50
 
48
51
  if (!masked) throw new Error('Client frames must be masked');
@@ -73,18 +76,29 @@ function decodeFrame(buffer) {
73
76
 
74
77
  // ========== Configuration ==========
75
78
 
76
- const PORT = process.env.BRAINSTORM_PORT || (49152 + Math.floor(Math.random() * 16383));
79
+ const PORT =
80
+ process.env.BRAINSTORM_PORT || 49152 + Math.floor(Math.random() * 16383);
77
81
  const HOST = process.env.BRAINSTORM_HOST || '127.0.0.1';
78
- const URL_HOST = process.env.BRAINSTORM_URL_HOST || (HOST === '127.0.0.1' ? 'localhost' : HOST);
82
+ const URL_HOST =
83
+ process.env.BRAINSTORM_URL_HOST ||
84
+ (HOST === '127.0.0.1' ? 'localhost' : HOST);
79
85
  const SESSION_DIR = process.env.BRAINSTORM_DIR || '/tmp/brainstorm';
80
86
  const CONTENT_DIR = path.join(SESSION_DIR, 'content');
81
87
  const STATE_DIR = path.join(SESSION_DIR, 'state');
82
- let ownerPid = process.env.BRAINSTORM_OWNER_PID ? Number(process.env.BRAINSTORM_OWNER_PID) : null;
88
+ let ownerPid = process.env.BRAINSTORM_OWNER_PID
89
+ ? Number(process.env.BRAINSTORM_OWNER_PID)
90
+ : null;
83
91
 
84
92
  const MIME_TYPES = {
85
- '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript',
86
- '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg',
87
- '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg+xml'
93
+ '.html': 'text/html',
94
+ '.css': 'text/css',
95
+ '.js': 'application/javascript',
96
+ '.json': 'application/json',
97
+ '.png': 'image/png',
98
+ '.jpg': 'image/jpeg',
99
+ '.jpeg': 'image/jpeg',
100
+ '.gif': 'image/gif',
101
+ '.svg': 'image/svg+xml',
88
102
  };
89
103
 
90
104
  // ========== Templates and Constants ==========
@@ -98,9 +112,15 @@ h1 { color: #333; } p { color: #666; }</style>
98
112
  <body><h1>Brainstorm Companion</h1>
99
113
  <p>Waiting for the agent to push a screen...</p></body></html>`;
100
114
 
101
- const frameTemplate = fs.readFileSync(path.join(__dirname, 'frame-template.html'), 'utf-8');
102
- const helperScript = fs.readFileSync(path.join(__dirname, 'helper.js'), 'utf-8');
103
- const helperInjection = '<script>\n' + helperScript + '\n</script>';
115
+ const frameTemplate = fs.readFileSync(
116
+ path.join(__dirname, 'frame-template.html'),
117
+ 'utf-8',
118
+ );
119
+ const helperScript = fs.readFileSync(
120
+ path.join(__dirname, 'helper.js'),
121
+ 'utf-8',
122
+ );
123
+ const helperInjection = `<script>\n${helperScript}\n</script>`;
104
124
 
105
125
  // ========== Helper Functions ==========
106
126
 
@@ -114,9 +134,10 @@ function wrapInFrame(content) {
114
134
  }
115
135
 
116
136
  function getNewestScreen() {
117
- const files = fs.readdirSync(CONTENT_DIR)
118
- .filter(f => f.endsWith('.html'))
119
- .map(f => {
137
+ const files = fs
138
+ .readdirSync(CONTENT_DIR)
139
+ .filter((f) => f.endsWith('.html'))
140
+ .map((f) => {
120
141
  const fp = path.join(CONTENT_DIR, f);
121
142
  return { path: fp, mtime: fs.statSync(fp).mtime.getTime() };
122
143
  })
@@ -131,11 +152,13 @@ function handleRequest(req, res) {
131
152
  if (req.method === 'GET' && req.url === '/') {
132
153
  const screenFile = getNewestScreen();
133
154
  let html = screenFile
134
- ? (raw => isFullDocument(raw) ? raw : wrapInFrame(raw))(fs.readFileSync(screenFile, 'utf-8'))
155
+ ? ((raw) => (isFullDocument(raw) ? raw : wrapInFrame(raw)))(
156
+ fs.readFileSync(screenFile, 'utf-8'),
157
+ )
135
158
  : WAITING_PAGE;
136
159
 
137
160
  if (html.includes('</body>')) {
138
- html = html.replace('</body>', helperInjection + '\n</body>');
161
+ html = html.replace('</body>', `${helperInjection}\n</body>`);
139
162
  } else {
140
163
  html += helperInjection;
141
164
  }
@@ -166,14 +189,17 @@ const clients = new Set();
166
189
 
167
190
  function handleUpgrade(req, socket) {
168
191
  const key = req.headers['sec-websocket-key'];
169
- if (!key) { socket.destroy(); return; }
192
+ if (!key) {
193
+ socket.destroy();
194
+ return;
195
+ }
170
196
 
171
197
  const accept = computeAcceptKey(key);
172
198
  socket.write(
173
199
  'HTTP/1.1 101 Switching Protocols\r\n' +
174
- 'Upgrade: websocket\r\n' +
175
- 'Connection: Upgrade\r\n' +
176
- 'Sec-WebSocket-Accept: ' + accept + '\r\n\r\n'
200
+ 'Upgrade: websocket\r\n' +
201
+ 'Connection: Upgrade\r\n' +
202
+ `Sec-WebSocket-Accept: ${accept}\r\n\r\n`,
177
203
  );
178
204
 
179
205
  let buffer = Buffer.alloc(0);
@@ -185,7 +211,7 @@ function handleUpgrade(req, socket) {
185
211
  let result;
186
212
  try {
187
213
  result = decodeFrame(buffer);
188
- } catch (e) {
214
+ } catch {
189
215
  socket.end(encodeFrame(OPCODES.CLOSE, Buffer.alloc(0)));
190
216
  clients.delete(socket);
191
217
  return;
@@ -233,14 +259,18 @@ function handleMessage(text) {
233
259
  console.log(JSON.stringify({ source: 'user-event', ...event }));
234
260
  if (event.choice) {
235
261
  const eventsFile = path.join(STATE_DIR, 'events');
236
- fs.appendFileSync(eventsFile, JSON.stringify(event) + '\n');
262
+ fs.appendFileSync(eventsFile, `${JSON.stringify(event)}\n`);
237
263
  }
238
264
  }
239
265
 
240
266
  function broadcast(msg) {
241
267
  const frame = encodeFrame(OPCODES.TEXT, Buffer.from(JSON.stringify(msg)));
242
268
  for (const socket of clients) {
243
- try { socket.write(frame); } catch (e) { clients.delete(socket); }
269
+ try {
270
+ socket.write(frame);
271
+ } catch {
272
+ clients.delete(socket);
273
+ }
244
274
  }
245
275
  }
246
276
 
@@ -260,14 +290,15 @@ const debounceTimers = new Map();
260
290
  // ========== Server Startup ==========
261
291
 
262
292
  function startServer() {
263
- if (!fs.existsSync(CONTENT_DIR)) fs.mkdirSync(CONTENT_DIR, { recursive: true });
293
+ if (!fs.existsSync(CONTENT_DIR))
294
+ fs.mkdirSync(CONTENT_DIR, { recursive: true });
264
295
  if (!fs.existsSync(STATE_DIR)) fs.mkdirSync(STATE_DIR, { recursive: true });
265
296
 
266
297
  // Track known files to distinguish new screens from updates.
267
298
  // macOS fs.watch reports 'rename' for both new files and overwrites,
268
299
  // so we can't rely on eventType alone.
269
300
  const knownFiles = new Set(
270
- fs.readdirSync(CONTENT_DIR).filter(f => f.endsWith('.html'))
301
+ fs.readdirSync(CONTENT_DIR).filter((f) => f.endsWith('.html')),
271
302
  );
272
303
 
273
304
  const server = http.createServer(handleRequest);
@@ -276,25 +307,31 @@ function startServer() {
276
307
  const watcher = fs.watch(CONTENT_DIR, (eventType, filename) => {
277
308
  if (!filename || !filename.endsWith('.html')) return;
278
309
 
279
- if (debounceTimers.has(filename)) clearTimeout(debounceTimers.get(filename));
280
- debounceTimers.set(filename, setTimeout(() => {
281
- debounceTimers.delete(filename);
282
- const filePath = path.join(CONTENT_DIR, filename);
283
-
284
- if (!fs.existsSync(filePath)) return; // file was deleted
285
- touchActivity();
286
-
287
- if (!knownFiles.has(filename)) {
288
- knownFiles.add(filename);
289
- const eventsFile = path.join(STATE_DIR, 'events');
290
- if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile);
291
- console.log(JSON.stringify({ type: 'screen-added', file: filePath }));
292
- } else {
293
- console.log(JSON.stringify({ type: 'screen-updated', file: filePath }));
294
- }
310
+ if (debounceTimers.has(filename))
311
+ clearTimeout(debounceTimers.get(filename));
312
+ debounceTimers.set(
313
+ filename,
314
+ setTimeout(() => {
315
+ debounceTimers.delete(filename);
316
+ const filePath = path.join(CONTENT_DIR, filename);
317
+
318
+ if (!fs.existsSync(filePath)) return; // file was deleted
319
+ touchActivity();
320
+
321
+ if (!knownFiles.has(filename)) {
322
+ knownFiles.add(filename);
323
+ const eventsFile = path.join(STATE_DIR, 'events');
324
+ if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile);
325
+ console.log(JSON.stringify({ type: 'screen-added', file: filePath }));
326
+ } else {
327
+ console.log(
328
+ JSON.stringify({ type: 'screen-updated', file: filePath }),
329
+ );
330
+ }
295
331
 
296
- broadcast({ type: 'reload' });
297
- }, 100));
332
+ broadcast({ type: 'reload' });
333
+ }, 100),
334
+ );
298
335
  });
299
336
  watcher.on('error', (err) => console.error('fs.watch error:', err.message));
300
337
 
@@ -304,7 +341,7 @@ function startServer() {
304
341
  if (fs.existsSync(infoFile)) fs.unlinkSync(infoFile);
305
342
  fs.writeFileSync(
306
343
  path.join(STATE_DIR, 'server-stopped'),
307
- JSON.stringify({ reason, timestamp: Date.now() }) + '\n'
344
+ `${JSON.stringify({ reason, timestamp: Date.now() })}\n`,
308
345
  );
309
346
  watcher.close();
310
347
  clearInterval(lifecycleCheck);
@@ -313,13 +350,19 @@ function startServer() {
313
350
 
314
351
  function ownerAlive() {
315
352
  if (!ownerPid) return true;
316
- try { process.kill(ownerPid, 0); return true; } catch (e) { return e.code === 'EPERM'; }
353
+ try {
354
+ process.kill(ownerPid, 0);
355
+ return true;
356
+ } catch (e) {
357
+ return e.code === 'EPERM';
358
+ }
317
359
  }
318
360
 
319
361
  // Check every 60s: exit if owner process died or idle for 30 minutes
320
362
  const lifecycleCheck = setInterval(() => {
321
363
  if (!ownerAlive()) shutdown('owner process exited');
322
- else if (Date.now() - lastActivity > IDLE_TIMEOUT_MS) shutdown('idle timeout');
364
+ else if (Date.now() - lastActivity > IDLE_TIMEOUT_MS)
365
+ shutdown('idle timeout');
323
366
  }, 60 * 1000);
324
367
  lifecycleCheck.unref();
325
368
 
@@ -327,10 +370,17 @@ function startServer() {
327
370
  // was wrong (common on WSL, Tailscale SSH, and cross-user scenarios).
328
371
  // Disable monitoring and rely on the idle timeout instead.
329
372
  if (ownerPid) {
330
- try { process.kill(ownerPid, 0); }
331
- catch (e) {
373
+ try {
374
+ process.kill(ownerPid, 0);
375
+ } catch (e) {
332
376
  if (e.code !== 'EPERM') {
333
- console.log(JSON.stringify({ type: 'owner-pid-invalid', pid: ownerPid, reason: 'dead at startup' }));
377
+ console.log(
378
+ JSON.stringify({
379
+ type: 'owner-pid-invalid',
380
+ pid: ownerPid,
381
+ reason: 'dead at startup',
382
+ }),
383
+ );
334
384
  ownerPid = null;
335
385
  }
336
386
  }
@@ -338,12 +388,16 @@ function startServer() {
338
388
 
339
389
  server.listen(PORT, HOST, () => {
340
390
  const info = JSON.stringify({
341
- type: 'server-started', port: Number(PORT), host: HOST,
342
- url_host: URL_HOST, url: 'http://' + URL_HOST + ':' + PORT,
343
- screen_dir: CONTENT_DIR, state_dir: STATE_DIR
391
+ type: 'server-started',
392
+ port: Number(PORT),
393
+ host: HOST,
394
+ url_host: URL_HOST,
395
+ url: `http://${URL_HOST}:${PORT}`,
396
+ screen_dir: CONTENT_DIR,
397
+ state_dir: STATE_DIR,
344
398
  });
345
399
  console.log(info);
346
- fs.writeFileSync(path.join(STATE_DIR, 'server-info'), info + '\n');
400
+ fs.writeFileSync(path.join(STATE_DIR, 'server-info'), `${info}\n`);
347
401
  });
348
402
  }
349
403
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-explainer-kit
3
- version: 1.0.2
3
+ version: 1.0.3
4
4
  description: Use when building project explainers or recaps from OAT configuration, state, and lifecycle artifacts.
5
5
  disable-model-invocation: false
6
6
  user-invocable: true
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/tools/index.ts"],"names":[],"mappings":"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"}
@@ -947,11 +947,11 @@ export function createInitToolsCommand(overrides = {}) {
947
947
  for (const packCommand of packCommands) {
948
948
  command.addCommand(packCommand);
949
949
  }
950
- command.action(async (_options, command) => {
951
- const context = dependencies.buildCommandContext(readGlobalOptions(command));
950
+ command.action(async (_options, actionCommand) => {
951
+ const context = dependencies.buildCommandContext(readGlobalOptions(actionCommand));
952
952
  const selectedPacks = await runInitTools(context, dependencies);
953
- setInstalledCanonicalPaths(command, canonicalPathsForPacks(selectedPacks));
954
- await reconcileAfterInstall(command);
953
+ setInstalledCanonicalPaths(actionCommand, canonicalPathsForPacks(selectedPacks));
954
+ await reconcileAfterInstall(actionCommand);
955
955
  });
956
956
  return command;
957
957
  }
@@ -232,9 +232,9 @@ async function classifyObsoleteMappingRetirement(manifestEntry, scopeRoot) {
232
232
  }
233
233
  async function classifyOperation(canonicalEntry, providerPath, strategy, renderedContent) {
234
234
  if (strategy === 'symlink') {
235
- let stat;
235
+ let providerStat;
236
236
  try {
237
- stat = await lstat(providerPath);
237
+ providerStat = await lstat(providerPath);
238
238
  }
239
239
  catch (error) {
240
240
  if (typeof error === 'object' &&
@@ -248,7 +248,7 @@ async function classifyOperation(canonicalEntry, providerPath, strategy, rendere
248
248
  }
249
249
  throw error;
250
250
  }
251
- if (!stat.isSymbolicLink()) {
251
+ if (!providerStat.isSymbolicLink()) {
252
252
  return {
253
253
  operation: 'update_symlink',
254
254
  reason: 'provider path is not a symlink',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-agent-toolkit/cli",
3
- "version": "0.2.21",
3
+ "version": "0.2.22",
4
4
  "private": false,
5
5
  "description": "Open Agent Toolkit CLI",
6
6
  "homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
@@ -34,7 +34,7 @@
34
34
  "ora": "^9.0.0",
35
35
  "yaml": "2.8.2",
36
36
  "zod": "^3.25.76",
37
- "@open-agent-toolkit/control-plane": "0.2.21"
37
+ "@open-agent-toolkit/control-plane": "0.2.22"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.10.0",