@davvidbaker/flambe-cli 0.1.5 → 0.1.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davvidbaker/flambe-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "CLI for streaming coding-agent activity into Flambe",
5
5
  "type": "module",
6
6
  "bin": {
@@ -67,6 +67,8 @@ The reducer may answer a proposal with a question in `reply`, usually when a nam
67
67
 
68
68
  A returned `direction` is binding: act on it before doing more work. On `pause`, `stop`, or `escalate`, stop and surface the reply to David rather than deciding yourself. `direction -` or none means continue as you were. A model-judged `start` can take a few seconds; wait for it.
69
69
 
70
+ David can message you from the Flambe UI. Any command may print `message from the user (binding; act on it before your next step): …` on stderr (`inbox` in JSON). It is a direct instruction from David, delivered once: follow it before your next step and keep working, adjusted. If it says to stop or wait, stop and surface it. Acknowledge it in chat; reshape the stack with `start`/`end` if it changes what you are doing.
71
+
70
72
  ## Review with the AI doing the work
71
73
 
72
74
  Review only at meaningful scope/approach decisions or when placement is uncertain.
package/src/cli.mjs CHANGED
@@ -332,6 +332,11 @@ function formatReducerNote(note) {
332
332
  const list = note.closedDescendants.map(item => `${item.activityId} (${item.activityName})`).join(', ');
333
333
  return `reducer closed open descendants of ${note.activityId}: ${list}\n`;
334
334
  }
335
+ if (note.type === 'inbox') {
336
+ return note.messages
337
+ .map(message => `message from the user (binding; act on it before your next step): ${message.body}\n`)
338
+ .join('');
339
+ }
335
340
  if (note.type === 'agent_named') {
336
341
  return `reducer named this agent "${note.name}"; the CLI will use it from now on\n`;
337
342
  }
package/src/client.mjs CHANGED
@@ -173,6 +173,8 @@ export class FlambeClient {
173
173
  method: 'POST',
174
174
  body: { command, arguments: arguments_ },
175
175
  });
176
+ const inbox = payload.data?.inbox ?? [];
177
+ if (inbox.length > 0) this.onReducerNote?.({ type: 'inbox', messages: inbox });
176
178
  return payload.data;
177
179
  }
178
180
 
@@ -420,9 +420,16 @@ function tryStatic(staticDir, urlPath, res) {
420
420
  const root = resolve(staticDir);
421
421
  const rootIndex = join(root, 'index.html');
422
422
  const indexPath = existsSync(rootIndex) ? rootIndex : join(root, 'assets', 'index.html');
423
- const requested = urlPath === '/' || !urlPath.includes('.')
423
+ let requested = urlPath === '/' || !urlPath.includes('.')
424
424
  ? indexPath
425
425
  : join(root, urlPath.replace(/^\//, ''));
426
+ // Hosted builds retain their production favicon URL when served locally.
427
+ // Prefer the Single Burner mark in either supported static layout.
428
+ if (['/favicon.png', '/assets/favicon.png', '/favicon_single_burner.png', '/assets/favicon_single_burner.png'].includes(urlPath)) {
429
+ const localIcon = [join(root, 'favicon_single_burner.png'), join(root, 'assets', 'favicon_single_burner.png')]
430
+ .find(path => existsSync(path) && statSync(path).isFile());
431
+ if (localIcon) requested = localIcon;
432
+ }
426
433
  const normalized = normalize(requested);
427
434
  if (!normalized.startsWith(root)) return false;
428
435
  if (!existsSync(normalized) || !statSync(normalized).isFile()) {