muse-crew 0.7.12 → 0.7.14

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.
@@ -51,9 +51,17 @@ cmd_init() {
51
51
  # Deploy HEAD
52
52
  cmd_deploy "$repo" "$home"
53
53
 
54
- # Create convenience symlinks if missing
55
- [ -L "$CREW_HOME/workflows" ] || ln -sfn current/workflows "$CREW_HOME/workflows"
56
- [ -L "$CREW_HOME/lib" ] || ln -sfn current/lib "$CREW_HOME/lib"
54
+ # The home-level convenience symlinks are part of the release layout and
55
+ # are owned by the release system: they ALWAYS point into the active
56
+ # release, unconditionally. A pre-existing symlink (e.g. an improvised
57
+ # agent-created link into the npm package's lib before init ran) is
58
+ # replaced, never preserved — preserving it once disabled the
59
+ # active-release guard in crew-api.js and left parent publish
60
+ # verification inert (Gate 1 clean-room defect, 2026-09-16).
61
+ # The same enforcement runs at the end of cmd_deploy, so every deploy
62
+ # repairs a broken home; this is a belt-and-suspenders repeat for init.
63
+ ln -sfn current/workflows "$CREW_HOME/workflows"
64
+ ln -sfn current/lib "$CREW_HOME/lib"
57
65
 
58
66
  # Verify: current resolves and workflows are readable through the chain
59
67
  local cur
@@ -215,6 +223,16 @@ cmd_deploy() {
215
223
 
216
224
  echo "ACTIVATED: $hash"
217
225
 
226
+ # Home-level convenience symlinks are owned by the release system: they
227
+ # ALWAYS point into the active release. A pre-existing symlink pointing
228
+ # elsewhere (e.g. an improvised agent-created lib link into the npm
229
+ # package before init ran) is replaced, never preserved — preserving it
230
+ # once disabled crew-api.js's active-release guard and left parent
231
+ # publish verification inert (Gate 1 clean-room defect, 2026-09-16).
232
+ # This also repairs broken homes on every subsequent deploy.
233
+ ln -sfn current/workflows "$CREW_HOME/workflows"
234
+ ln -sfn current/lib "$CREW_HOME/lib"
235
+
218
236
  # Keep the dashboard's workflow documents in sync with the release.
219
237
  _sync_workflow_docs "$CREW_HOME"
220
238
 
@@ -52,6 +52,8 @@ function parseArgs(argv) {
52
52
  }
53
53
 
54
54
  function loadPlaywright() {
55
+ // playwright-core is a declared dependency (package.json), so a normal
56
+ // npm install resolves it from the package's own node_modules.
55
57
  try {
56
58
  return require("playwright-core");
57
59
  } catch (e) { /* fall through */ }
@@ -64,12 +66,6 @@ function loadPlaywright() {
64
66
  return require(envDir);
65
67
  } catch (e) { /* fall through */ }
66
68
  }
67
- const conventional = "/home/hatch/workspace/crew-tools/node_modules/playwright-core";
68
- if (existsSync(conventional)) {
69
- try {
70
- return require(conventional);
71
- } catch (e) { /* fall through */ }
72
- }
73
69
  fail(3, {
74
70
  ok: false,
75
71
  not_possible: "NOT POSSIBLE: playwright-core is not installed or not resolvable. " +
package/lib/see-act.js CHANGED
@@ -70,6 +70,8 @@ function parseArgs(argv) {
70
70
  }
71
71
 
72
72
  function loadPlaywright() {
73
+ // playwright-core is a declared dependency (package.json), so a normal
74
+ // npm install resolves it from the package's own node_modules.
73
75
  try {
74
76
  return require("playwright-core");
75
77
  } catch (e) { /* fall through */ }
@@ -82,12 +84,6 @@ function loadPlaywright() {
82
84
  return require(envDir);
83
85
  } catch (e) { /* fall through */ }
84
86
  }
85
- const conventional = "/home/hatch/workspace/crew-tools/node_modules/playwright-core";
86
- if (existsSync(conventional)) {
87
- try {
88
- return require(conventional);
89
- } catch (e) { /* fall through */ }
90
- }
91
87
  fail(3, {
92
88
  ok: false,
93
89
  not_possible: "NOT POSSIBLE: playwright-core is not installed or not resolvable. " +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muse-crew",
3
- "version": "0.7.12",
3
+ "version": "0.7.14",
4
4
  "description": "Opinionated orchestration for Muse — workflows, identities, and tooling for autonomous software development.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -25,5 +25,8 @@
25
25
  "workflows",
26
26
  "software-development"
27
27
  ],
28
- "author": "emojimanegg1"
28
+ "author": "emojimanegg1",
29
+ "dependencies": {
30
+ "playwright-core": "1.63.0"
31
+ }
29
32
  }
@@ -29,21 +29,28 @@ if (!!dashboardSlug !== !!dashboardRepoPath) throw new Error("dashboardSlug and
29
29
 
30
30
  const orchDir = crewHome + "/.orchestration";
31
31
 
32
- // ── Gate 0: Launchable-path + repo validation ───────────────────────
32
+ // ── Gate 0: Launchable-path validation ─────────────────────────────
33
33
  // workflow_launch only accepts workspace-contained scripts. A crewHome
34
34
  // outside the workspace would produce an instance whose workflows can
35
35
  // never launch (the Gate 1 canary's /home/hatch/.crew-canary-gate1
36
36
  // defect, 2026-09-11: workers resorted to changing, manually staged
37
37
  // copies). Fail closed here so no such instance can ever be created.
38
+ // The crew home is state, not a repository: it is NEVER git-initialized.
39
+ // (2026-09-15: removed the old git-init — its unborn repo let a clean
40
+ // room register the crew home itself as a project's repo_path, and the
41
+ // worktree lifecycle then failed closed on the home's untracked state
42
+ // files. A home with no .git can never pass create-project's
43
+ // isGitRepoPath check, so the trap is structurally impossible. The
44
+ // crew's own source repo remains fully registerable — that is how a
45
+ // crew works on itself.)
38
46
  // The dashboard repo is validated too: init registers the dashboard
39
47
  // project against it, and a non-git path would only fail later at the
40
- // first Build (the canary's npm-package repo_path defect, 2026-09-13:
41
- // init registered the crew home itself as the dashboard repo_path).
42
- // Unlike the crew home, the dashboard repo is NEVER auto-created — it is
43
- // the user's own project repository; a non-git path is a user error.
48
+ // first Build. Unlike the crew home, the dashboard repo is NEVER
49
+ // auto-created it is the user's own project repository; a non-git
50
+ // path is a user error.
44
51
  // Gate 0 decision logic is pure JS — the agent is a sensor, not a judge.
45
- // It reports raw facts (HOME, expanded paths, the git rev-parse exit
46
- // codes); the launchable/repo_valid verdicts are computed here,
52
+ // It reports raw facts (HOME, expanded paths, the dashboard repo's git
53
+ // rev-parse exit code); the launchable verdicts are computed here,
47
54
  // deterministically. An agent asked for a verdict can mis-apply the
48
55
  // prefix rule (e.g. the "$ws-evil" trailing-slash trick); code cannot.
49
56
  // (Prompt hardening is a smell — this is the mechanical version.)
@@ -53,15 +60,15 @@ function expandTilde(p, home) {
53
60
  return p;
54
61
  }
55
62
  function gate0Decide(facts) {
56
- // facts: { home, crewHomeExpanded, gitExitCode, dashboardRepoExpanded, dashboardRepoGitExitCode }
63
+ // facts: { home, crewHomeExpanded, dashboardRepoExpanded, dashboardRepoGitExitCode }
57
64
  // The dashboard fields are null in CLI-only mode (no dashboard) — the
58
65
  // dashboard verdicts are then vacuously true (nothing to validate).
66
+ // The crew home carries no repo verdict: homes are state, never repos.
59
67
  var workspace = facts.home + "/workspace";
60
68
  var launchable = facts.crewHomeExpanded.indexOf(workspace + "/") === 0;
61
- var repoValid = facts.gitExitCode === 0;
62
69
  var dashboardRepoLaunchable = facts.dashboardRepoExpanded == null || facts.dashboardRepoExpanded.indexOf(workspace + "/") === 0;
63
70
  var dashboardRepoValid = facts.dashboardRepoGitExitCode == null || facts.dashboardRepoGitExitCode === 0;
64
- return { workspace: workspace, launchable: launchable, repoValid: repoValid, dashboardRepoLaunchable: dashboardRepoLaunchable, dashboardRepoValid: dashboardRepoValid };
71
+ return { workspace: workspace, launchable: launchable, dashboardRepoLaunchable: dashboardRepoLaunchable, dashboardRepoValid: dashboardRepoValid };
65
72
  }
66
73
  var gateFacts;
67
74
  try {
@@ -73,19 +80,16 @@ try {
73
80
  "1. home=$(echo $HOME)\\n" +
74
81
  "2. Expand a leading ~/ in the requested crewHome against $HOME (leave other paths untouched).\\n" +
75
82
  "3. If the expanded crewHome does not exist: mkdir -p <expanded crewHome>\\n" +
76
- "4. Run: git -C <expanded crewHome> rev-parse --git-dir; echo EXIT:$?\\n" +
77
- "5. If EXIT is not 0: run git -C <expanded crewHome> init -b main (or git init if -b not supported)\\n" +
78
- "6. Re-run: git -C <expanded crewHome> rev-parse --git-dir; echo EXIT:$?\\n" +
83
+ "4. If <expanded crewHome>/.git exists, remove it (rm -rf <expanded crewHome>/.git). The crew home is state, never a git repository — a vestigial .git would let the home be mistaken for a project repo.\\n" +
79
84
  (dashboardRepoPath ?
80
- "7. Expand a leading ~/ in the requested dashboardRepoPath against $HOME (leave other paths untouched).\\n" +
81
- "8. Run: git -C <expanded dashboardRepoPath> rev-parse --git-dir; echo EXIT:$?\\n" +
85
+ "5. Expand a leading ~/ in the requested dashboardRepoPath against $HOME (leave other paths untouched).\\n" +
86
+ "6. Run: git -C <expanded dashboardRepoPath> rev-parse --git-dir; echo EXIT:$?\\n" +
82
87
  " Do NOT create or git-init the dashboard repo — it must already be a git repository.\\n" +
83
- "9. Return JSON { home, crewHomeExpanded, gitExitCode, dashboardRepoExpanded, dashboardRepoGitExitCode }\\n" +
84
- " where gitExitCode is the FINAL crew-home exit code after init, and dashboardRepoGitExitCode\\n" +
85
- " is the dashboard repo's exit code (no init attempted).\\n" :
86
- "7. Return JSON { home, crewHomeExpanded, gitExitCode, dashboardRepoExpanded: null, dashboardRepoGitExitCode: null }.\\n") +
88
+ "7. Return JSON { home, crewHomeExpanded, dashboardRepoExpanded, dashboardRepoGitExitCode }\\n" +
89
+ " where dashboardRepoGitExitCode is the dashboard repo's exit code (no init attempted).\\n" :
90
+ "5. Return JSON { home, crewHomeExpanded, dashboardRepoExpanded: null, dashboardRepoGitExitCode: null }.\\n") +
87
91
  "\\n" +
88
- "This ensures the crew home is a valid git repository" + (dashboardRepoPath ? " and the dashboard repo exists as one" : "") + ". Do not judge — just ensure and report.",
92
+ "This ensures the crew home exists inside the workspace and is not a git repository" + (dashboardRepoPath ? ", and that the dashboard repo exists as one" : "") + ". Do not judge — just ensure and report.",
89
93
  {
90
94
  key: "gate-0",
91
95
  label: "Validate crew home",
@@ -94,11 +98,10 @@ try {
94
98
  properties: {
95
99
  home: { type: "string" },
96
100
  crewHomeExpanded: { type: "string" },
97
- gitExitCode: { type: "number" },
98
101
  dashboardRepoExpanded: { type: ["string", "null"] },
99
102
  dashboardRepoGitExitCode: { type: ["number", "null"] }
100
103
  },
101
- required: ["home", "crewHomeExpanded", "gitExitCode", "dashboardRepoExpanded", "dashboardRepoGitExitCode"]
104
+ required: ["home", "crewHomeExpanded", "dashboardRepoExpanded", "dashboardRepoGitExitCode"]
102
105
  }
103
106
  }
104
107
  );
@@ -115,15 +118,6 @@ if (!gateResult.launchable) {
115
118
  }
116
119
  };
117
120
  }
118
- if (!gateResult.repoValid) {
119
- return {
120
- __hatchWorkflowControl: "blocked",
121
- result: {
122
- blocked_reason: "crewHome git init failed",
123
- message: "crewHome (" + gateFacts.crewHomeExpanded + ") could not be initialized as a git repository (git exit code " + gateFacts.gitExitCode + "). Check permissions and try again."
124
- }
125
- };
126
- }
127
121
  if (!gateResult.dashboardRepoLaunchable) {
128
122
  return {
129
123
  __hatchWorkflowControl: "blocked",
@@ -142,7 +136,7 @@ if (!gateResult.dashboardRepoValid) {
142
136
  }
143
137
  };
144
138
  }
145
- log("Gate 0: crewHome " + gateFacts.crewHomeExpanded + " is workspace-contained and a valid git repo" + (gateFacts.dashboardRepoExpanded ? "; dashboard repo " + gateFacts.dashboardRepoExpanded + " is workspace-contained and a valid git repo" : " (CLI-only mode: no dashboard)"));
139
+ log("Gate 0: crewHome " + gateFacts.crewHomeExpanded + " is workspace-contained (a state dir, never a git repo)" + (gateFacts.dashboardRepoExpanded ? "; dashboard repo " + gateFacts.dashboardRepoExpanded + " is workspace-contained and a valid git repo" : " (CLI-only mode: no dashboard)"));
146
140
 
147
141
  // ── Crew name ─────────────────────────────────────────────────────────
148
142
  // The human names their crew during setup (SETUP-EXPERIENCE.md). Stored as