moflo 4.9.8 → 4.9.9

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/bin/hooks.mjs CHANGED
@@ -289,7 +289,20 @@ async function main() {
289
289
  // chain and producing the sqlite_autoindex corruption that #743 had
290
290
  // to repair on subsequent sessions. The launcher's foreground §3e
291
291
  // migration is the canonical migration site. See #744.
292
- spawnWindowless('node', [resolve(__dirname, 'index-all.mjs')], 'sequential indexing chain');
292
+ // Prefer the npm-bin copy of index-all.mjs over __dirname resolution
293
+ // (#866). When this hooks.mjs is loaded from `.claude/scripts/` (e.g.
294
+ // an older launcher spawned us before the launcher's bin-anchor fix
295
+ // landed), `resolve(__dirname, 'index-all.mjs')` would point at the
296
+ // synced mirror — which the launcher's section 3 may still be in the
297
+ // middle of overwriting during an upgrade. resolveBinOrLocal's
298
+ // bin-first ordering guarantees the spawned chain matches the
299
+ // installed package even when the mirror is mid-sync.
300
+ const indexAllScript = resolveBinOrLocal('flo-index-all', 'index-all.mjs');
301
+ if (indexAllScript) {
302
+ spawnWindowless('node', [indexAllScript], 'sequential indexing chain');
303
+ } else {
304
+ log('warn', 'index-all.mjs not found (checked npm bin + .claude/scripts/)');
305
+ }
293
306
  // Neural patterns now loaded by moflo core routing — no external patching.
294
307
  break;
295
308
  }
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { execFileSync } from 'child_process';
3
+ import { readFileSync } from 'fs';
3
4
  import { resolve } from 'path';
4
5
 
5
6
  // Read stdin JSON from Claude Code
@@ -70,6 +71,19 @@ if (TEST_HINTS.test(lower)) {
70
71
  }
71
72
  }
72
73
 
73
- var parts = [output.trim(), nsHint].filter(Boolean);
74
- if (parts.length) process.stdout.write(parts.join('\n') + '\n');
74
+ // #867 surface post-install restart notice. File is written by
75
+ // scripts/post-install-notice.mjs and cleared by the SessionStart launcher
76
+ // once the running moflo matches the file's version, so the file's
77
+ // existence at prompt-time is itself the "still needs restart" signal.
78
+ var restartNotice = '';
79
+ try {
80
+ var pendingPath = resolve(projectDir, '.moflo', 'restart-pending.json');
81
+ var pending = JSON.parse(readFileSync(pendingPath, 'utf-8'));
82
+ if (pending && typeof pending.message === 'string' && pending.message.length > 0) {
83
+ restartNotice = pending.message;
84
+ }
85
+ } catch (e) { /* ENOENT or malformed — silent fast-path */ }
86
+
87
+ var parts = [restartNotice, output.trim(), nsHint].filter(Boolean);
88
+ if (parts.length) process.stdout.write(parts.join('\n\n') + '\n');
75
89
  process.exit(0);
@@ -217,6 +217,23 @@ try {
217
217
  // own errors if the DB is still broken.
218
218
  }
219
219
 
220
+ // ── 0d. Clear post-install restart notice when version is current (#867) ───
221
+ // scripts/post-install-notice.mjs drops `.moflo/restart-pending.json` on every
222
+ // `npm install moflo`. The UserPromptSubmit hook surfaces it on every prompt
223
+ // until cleared, so this session only sees the message between install and
224
+ // the FIRST restart that actually picks up the new bits.
225
+ try {
226
+ const pendingPath = join(mofloDir(projectRoot), 'restart-pending.json');
227
+ const pkgPath = resolve(projectRoot, 'node_modules/moflo/package.json');
228
+ const pending = JSON.parse(readFileSync(pendingPath, 'utf-8'));
229
+ const installedVersion = JSON.parse(readFileSync(pkgPath, 'utf-8')).version;
230
+ if (pending && typeof pending.version === 'string' && pending.version === installedVersion) {
231
+ unlinkSync(pendingPath);
232
+ try { unlinkSync(join(mofloDir(projectRoot), 'last-install-banner.json')); } catch { /* tracker may not exist */ }
233
+ emitMutation('cleared post-install restart notice', `${installedVersion} now running`);
234
+ }
235
+ } catch { /* file missing or malformed — silent fast-path */ }
236
+
220
237
  // ── 1. Helper: fire-and-forget a background process ─────────────────────────
221
238
  function fireAndForget(cmd, args, label) {
222
239
  try {
@@ -1106,11 +1123,20 @@ if (mutationCount > 0) {
1106
1123
  }
1107
1124
 
1108
1125
  // ── 4. Spawn background tasks ───────────────────────────────────────────────
1109
- const localCli = resolve(projectRoot, 'node_modules/moflo/bin/cli.js');
1110
- const hasLocalCli = existsSync(localCli);
1111
1126
 
1112
- // hooks.mjs session-start (daemon, indexer, pretrain, HNSW, neural patterns)
1113
- const hooksScript = resolve(projectRoot, '.claude/scripts/hooks.mjs');
1127
+ // hooks.mjs session-start (daemon, indexer, pretrain, HNSW, neural patterns).
1128
+ // Prefer the npm-bin copy over the `.claude/scripts/` mirror (#866). The mirror
1129
+ // is a derived sync that races the launcher's section-3 file copies during the
1130
+ // very upgrade session — spawning the still-stale `.claude/scripts/hooks.mjs`
1131
+ // then chaining `__dirname/index-all.mjs` produces an orphan running pre-
1132
+ // upgrade argv (e.g. `rebuild-index --force` after #859 had already dropped
1133
+ // it). The bin/ copy is updated atomically by `npm install moflo` (single-
1134
+ // step), so spawning from there guarantees the running hook code matches the
1135
+ // installed package. Falls back to the mirror only when the package copy is
1136
+ // unresolvable (development / symlinked installs).
1137
+ const hooksPkg = resolve(projectRoot, 'node_modules/moflo/bin/hooks.mjs');
1138
+ const hooksMirror = resolve(projectRoot, '.claude/scripts/hooks.mjs');
1139
+ const hooksScript = existsSync(hooksPkg) ? hooksPkg : hooksMirror;
1114
1140
  if (existsSync(hooksScript)) {
1115
1141
  fireAndForget('node', [hooksScript, 'session-start'], 'hooks session-start');
1116
1142
  }
@@ -2,5 +2,5 @@
2
2
  * Auto-generated by build. Do not edit manually.
3
3
  * Source of truth: root package.json → scripts/sync-version.mjs
4
4
  */
5
- export const VERSION = '4.9.8';
5
+ export const VERSION = '4.9.9';
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moflo",
3
- "version": "4.9.8",
3
+ "version": "4.9.9",
4
4
  "description": "MoFlo — AI agent orchestration for Claude Code. A standalone, opinionated toolkit with semantic memory, learned routing, gates, spells, and the /flo issue-execution skill.",
5
5
  "main": "dist/src/cli/index.js",
6
6
  "type": "module",
@@ -81,7 +81,7 @@
81
81
  "@typescript-eslint/eslint-plugin": "^7.18.0",
82
82
  "@typescript-eslint/parser": "^7.18.0",
83
83
  "eslint": "^8.0.0",
84
- "moflo": "^4.9.7",
84
+ "moflo": "^4.9.8",
85
85
  "tsx": "^4.21.0",
86
86
  "typescript": "^5.9.3",
87
87
  "vitest": "^4.0.0"