muse-crew 0.13.1 → 0.13.2

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/docs/guide.md CHANGED
@@ -17,7 +17,7 @@ This is the full setup and operations reference. If you're new, start with the [
17
17
  - A **release** — the first immutable snapshot of the crew's runtime code.
18
18
  - An **`.orchestration/` directory** in the crew home with identities, personas, workflow docs, and feedback conventions.
19
19
  - A **project registration** — the task service registered as its own first project.
20
- - **Cron jobs** — the scheduler state declared in `seed/crons.json`: a polling loop (every 15 minutes via Muse's scheduling, even when nobody's in the conversation). The scheduler identity is dashboard-independent — owner `cli:<instance-id>`, chosen once at first init — so deleting the dashboard artifact does not stop the crew. Removing a crew entirely is `crew-uninstall`'s job.
20
+ - **Cron jobs** — the scheduler state declared in `seed/crons.json`: a polling loop (every 15 minutes via Muse's scheduling, even when nobody's in the conversation). The scheduler identity is dashboard-independent — chosen once at first init (no owner; the platform rejects `cli:` owners) — so deleting the dashboard artifact does not stop the crew. Removing a crew entirely is `crew-uninstall`'s job.
21
21
 
22
22
  The agent running in the main chat receives the dispatcher's claims and launches each task workflow. Workflows can't launch workflows, so this handoff is structural.
23
23
 
@@ -63,7 +63,7 @@ Optional arguments:
63
63
  - `dashboardName` — display name for the project registration (default: `"Muse Crew"`).
64
64
  - `crewName` — the human's chosen name for the crew. Stored as plain text at `$CREW_HOME/crew-name` and returned in the init summary. The setup conversation should always ask for one; init won't fail without it.
65
65
  - `cronIds` — manifest id → live id map for parallel instances on one account (default: `{}`). The manifest's ids are used as-is unless overridden, e.g. `{"crew-poll": "crew-poll-canary"}`.
66
- - `cronOwner` — explicit owner for the created cron jobs. Defaults to `cli:<instance-id>`: the instance id is chosen at first init (the crew-home basename) and kept from `.cron-registry.json` on re-runs, so re-init never renames the crew's jobs.
66
+ - `cronOwner` — explicit owner for the created cron jobs. Defaults to null (omitted): the instance id is chosen at first init (the crew-home basename) and kept from `.cron-registry.json` on re-runs, so re-init never renames the crew's jobs. The platform rejects `cli:` owners.
67
67
  - `autoUpdateCrew` — automatic crew upgrades on/off (default: `true`). Persists as the `auto_update_crew` config key; `false` turns the update watcher's crew check off.
68
68
  - `autoUpdateDashboard` — automatic dashboard upgrades on/off (default: `true`). Persists as the `auto_update_dashboard` config key.
69
69
  - `updateChannel` — `latest` (default) or `patch`: narrows crew upgrades to patch releases. Persists as the `update_channel` config key; any other value fails the init.
@@ -79,7 +79,7 @@ Init runs five phases, each idempotent — re-running converges anything that dr
79
79
 
80
80
  3. **Project registration** — registers the task service as a project in its own database via `createproject`, with `repo_path` set to the validated `dashboardRepoPath`. The dashboard becomes its own first project, so the crew can work on the dashboard itself. Re-running init is self-healing: a project already registered with the correct path is left alone, while one with a different path (e.g. from an older init) is repaired via `update-project`. Skipped entirely in CLI-only mode (no `dashboardSlug`) — create projects with `crew-api.js create-project` instead.
81
81
 
82
- 4. **Crons** — reads the manifest at `seed/crons.json` and makes the scheduler match it: missing jobs are created from the entry (title, enabled, mode, schedule, owner, timeout_secs, and the body built from the entry's template with `crewHome` substituted in); existing jobs are viewed and converged — drifted fields are updated, unchanged jobs are left alone. The scheduler identity (`instanceId`, `cli:<instanceId>` owner) is chosen once at first init and never renamed by re-runs: the instance id comes from the existing `.cron-registry.json` when present, otherwise the crew-home basename. One exception: init never touches `enabled` on an existing job. `enabled` is a creation-time default only — a disabled job is a deliberate human decision, and re-init must not silently resurrect it. Jobs removed from the manifest are left alone; deletion is a human decision.
82
+ 4. **Crons** — reads the manifest at `seed/crons.json` and makes the scheduler match it: missing jobs are created from the entry (title, enabled, mode, schedule, timeout_secs, and the body built from the entry's template with `crewHome` substituted in — owner is omitted); existing jobs are viewed and converged — drifted fields are updated, unchanged jobs are left alone. The scheduler identity (`instanceId`) is chosen once at first init and never renamed by re-runs: the instance id comes from the existing `.cron-registry.json` when present, otherwise the crew-home basename. One exception: init never touches `enabled` on an existing job. `enabled` is a creation-time default only — a disabled job is a deliberate human decision, and re-init must not silently resurrect it. Jobs removed from the manifest are left alone; deletion is a human decision.
83
83
 
84
84
  5. **Update policy** — persists the automatic-update policy (`auto_update_crew`, `auto_update_dashboard`, `update_channel`) via the Crew API's `update-config`, with the re-init semantics above: explicit inputs win, existing values survive, defaults apply only on first init. Seeds `$CREW_HOME/.update-watch.json` as `{}` only when it does not exist (the watcher's idempotency record is never overwritten).
85
85
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muse-crew",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "description": "Opinionated orchestration for Muse \u2014 workflows, identities, and tooling for autonomous software development.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -29,4 +29,4 @@
29
29
  "dependencies": {
30
30
  "playwright-core": "1.63.0"
31
31
  }
32
- }
32
+ }
package/seed/crons.json CHANGED
@@ -5,7 +5,6 @@
5
5
  "enabled": true,
6
6
  "id": "crew-poll",
7
7
  "mode": "task",
8
- "owner": "cli:{instanceId}",
9
8
  "schedule": {
10
9
  "every": "15m",
11
10
  "kind": "interval"
@@ -18,7 +17,6 @@
18
17
  "enabled": true,
19
18
  "id": "crew-update-watch",
20
19
  "mode": "task",
21
- "owner": "cli:{instanceId}",
22
20
  "schedule": {
23
21
  "every": "24h",
24
22
  "kind": "interval"
@@ -663,8 +663,8 @@ try {
663
663
  } catch (e) {
664
664
  return { __hatchWorkflowControl: "blocked", result: { blocked_reason: "Scheduler identity unreadable", message: String(e.message || e) } };
665
665
  }
666
- var cronOwner = inputs.cronOwner || ("cli:" + instanceId);
667
- log("Scheduler identity: instanceId=" + instanceId + " owner=" + cronOwner +
666
+ var cronOwner = inputs.cronOwner || null;
667
+ log("Scheduler identity: instanceId=" + instanceId + " owner=" + (cronOwner || "(omitted; instance-local)") +
668
668
  (identityFacts.registryJson ? " (kept from existing registry)" : " (first init; crew-home basename)"));
669
669
  var cronsResult;
670
670
  try {
@@ -673,13 +673,13 @@ try {
673
673
  "Manifest: " + crewRepoPath + "/seed/crons.json\n" +
674
674
  "crewHome: " + crewHome + "\n" +
675
675
  "Instance id (cron id suffix): " + instanceId + "\n" +
676
- "Cron owner: " + cronOwner + "\n" +
676
+ "Cron owner: " + (cronOwner || "(omitted)") + "\n" +
677
677
  "Id overrides (manifest id -> live id): " + JSON.stringify(cronIds) + "\n\n" +
678
678
  "Steps:\n" +
679
679
  "1. Read the manifest at " + crewRepoPath + "/seed/crons.json and parse it as JSON.\n" +
680
680
  " Fail closed (return passed: false) if the file is missing, is not valid JSON,\n" +
681
681
  " or any entry lacks a required field (id, title, enabled, mode, schedule,\n" +
682
- " owner, body_template).\n" +
682
+ " body_template).\n" +
683
683
  "2. For each manifest entry, in order:\n" +
684
684
  " a. The live id is the override for entry.id when present (inputs.cronIds[entry.id]).\n" +
685
685
  " Otherwise, the live id is entry.id + '-' + \"" + instanceId + "\" (instance-safe by\n" +
@@ -692,7 +692,7 @@ try {
692
692
  " - id: the live id\n" +
693
693
  " - title, enabled, mode from the entry\n" +
694
694
  " - schedule: the entry's schedule object\n" +
695
- " - owner: " + cronOwner + "\n" +
695
+ " - owner: omit (instance-local; do not pass owner)\n" +
696
696
  " - timeout_secs: the entry's timeout_secs when present\n" +
697
697
  " - body: the resolved template text\n" +
698
698
  " Record action 'created' with no updated fields.\n" +
@@ -708,7 +708,7 @@ try {
708
708
  "3. Write the cron registry at " + crewHome + "/.cron-registry.json — the exact\n" +
709
709
  " record a later uninstall uses to find these jobs. Build this JSON (one entry\n" +
710
710
  " per manifest entry, in manifest order, using the live ids from step 2):\n" +
711
- " {\"version\":1,\"instanceId\":\"" + instanceId + "\",\"owner\":\"" + cronOwner + "\",\n" +
711
+ " {\"version\":1,\"instanceId\":\"" + instanceId + "\",\n" +
712
712
  " \"crons\":[{\"id\":<live id>,\"manifestId\":<entry.id>}, ...]}\n" +
713
713
  " Write it with printf '%s' and a single-quoted heredoc so the shell\n" +
714
714
  " interpolates nothing, then read it back to confirm it parses.\n" +