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 +14 -1
- package/bin/prompt-hook.mjs +16 -2
- package/bin/session-start-launcher.mjs +30 -4
- package/dist/src/cli/version.js +1 -1
- package/package.json +2 -2
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
|
-
|
|
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
|
}
|
package/bin/prompt-hook.mjs
CHANGED
|
@@ -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
|
-
|
|
74
|
-
|
|
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
|
-
|
|
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
|
}
|
package/dist/src/cli/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moflo",
|
|
3
|
-
"version": "4.9.
|
|
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.
|
|
84
|
+
"moflo": "^4.9.8",
|
|
85
85
|
"tsx": "^4.21.0",
|
|
86
86
|
"typescript": "^5.9.3",
|
|
87
87
|
"vitest": "^4.0.0"
|