moflo 4.9.19 → 4.9.20

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.
@@ -53,6 +53,36 @@ function findProjectRoot() {
53
53
 
54
54
  const projectRoot = findProjectRoot();
55
55
 
56
+ // Dogfood guard (#928). When this launcher runs inside the moflo repo itself,
57
+ // .claude/scripts/, .claude/helpers/, and .claude/guidance/ are committed git
58
+ // files — they ARE moflo's source of truth, not destinations to be re-synced
59
+ // from node_modules. Drift heal would silently revert any post-publish edit
60
+ // to one of those files (e.g. story #927's gate.cjs got reverted overnight
61
+ // because manifest.size still pointed at the previously-published version).
62
+ // Detection is `package.json#name === "moflo"` — the project's own package.json,
63
+ // NOT node_modules/moflo/package.json. Defaults to false on any read/parse
64
+ // error so a corrupt package.json never silently disables drift heal in a
65
+ // real consumer.
66
+ //
67
+ // Workspace caveat: findProjectRoot() walks up to the nearest package.json,
68
+ // so in a workspace child (packages/foo/) the read sees the child package
69
+ // (name !== "moflo") and the guard stays false. moflo isn't a workspace
70
+ // today; if it ever becomes one, run sessions from the repo root or extend
71
+ // this check to walk further up.
72
+ let isMofloDogfood = false;
73
+ try {
74
+ const projectPkgPath = resolve(projectRoot, 'package.json');
75
+ if (existsSync(projectPkgPath)) {
76
+ const projectPkg = JSON.parse(readFileSync(projectPkgPath, 'utf-8'));
77
+ isMofloDogfood = projectPkg?.name === 'moflo';
78
+ }
79
+ } catch (err) {
80
+ // Defaults to false — safer than accidentally disabling drift heal in a
81
+ // real consumer. Surface the failure so a corrupt project package.json
82
+ // doesn't silently change launcher behavior (per feedback_no_silent_failures).
83
+ process.stderr.write(`[moflo] dogfood-guard package.json read failed: ${err && err.message ? err.message : String(err)}\n`);
84
+ }
85
+
56
86
  // Visible mutation reporter (#716). Claude Code's SessionStart hook captures
57
87
  // stdout as `additionalContext`, so each line here surfaces to Claude — and
58
88
  // through it to the user — explaining what the launcher just changed. Keep
@@ -360,6 +390,8 @@ try {
360
390
  }
361
391
  }
362
392
  }
393
+ // Dogfood (#928): never drift-heal moflo's own committed copies.
394
+ if (isMofloDogfood) manifestDrifted = false;
363
395
 
364
396
  if (installedVersion !== cachedVersion || manifestDrifted) {
365
397
  if (installedVersion !== cachedVersion) {
@@ -444,6 +476,20 @@ try {
444
476
 
445
477
  const binDir = resolve(projectRoot, 'node_modules/moflo/bin');
446
478
 
479
+ // Dogfood (#928): in moflo's own repo, the destinations under
480
+ // .claude/scripts/, .claude/helpers/, .claude/guidance/ are committed
481
+ // git files — copying node_modules/moflo content over them clobbers
482
+ // in-flight work (the same bug that silently reverted #927 between
483
+ // commit and publish). Skip the sync, cleanup, and manifest write
484
+ // entirely; queue the version-stamp write so we don't re-enter this
485
+ // branch on every subsequent session. Daemon recycle still happens
486
+ // (the stopDaemon call earlier handled this) and 3a-pre will spawn a
487
+ // fresh daemon under the new code.
488
+ if (isMofloDogfood) {
489
+ pendingVersionStampWrite = { path: versionStampPath, version: installedVersion };
490
+ emitMutation('skipped file-sync', 'moflo dogfood — committed dogfood copies preserved');
491
+ } else {
492
+
447
493
  // ── Manifest-based auto-update ──────────────────────────────────────
448
494
  //
449
495
  // IMPORTANT: Every file moflo installs into the destination project
@@ -709,6 +755,7 @@ try {
709
755
  // queued for 3g.
710
756
  emitWarning(`manifest write failed (${errMessage(err)})`);
711
757
  }
758
+ } // end !isMofloDogfood file-sync branch (#928)
712
759
  }
713
760
  }
714
761
  } catch (err) {
@@ -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.19';
5
+ export const VERSION = '4.9.20';
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moflo",
3
- "version": "4.9.19",
3
+ "version": "4.9.20",
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.18",
84
+ "moflo": "^4.9.19",
85
85
  "tsx": "^4.21.0",
86
86
  "typescript": "^5.9.3",
87
87
  "vitest": "^4.0.0"