@detergent-software/conductor 3.0.0-dev.14 → 3.0.0-dev.15
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/CHANGELOG.md +11 -0
- package/README.md +39 -20
- package/build/brief-cli.js +1 -1
- package/build/brief-cli.js.map +1 -1
- package/build/broker-cli.js +7 -6
- package/build/broker-cli.js.map +1 -1
- package/build/cli.js +35 -15
- package/build/cli.js.map +1 -1
- package/build/clones.js +92 -0
- package/build/clones.js.map +1 -0
- package/build/code-host-cli.js +17 -18
- package/build/code-host-cli.js.map +1 -1
- package/build/config.js +5 -7
- package/build/config.js.map +1 -1
- package/build/daemon.js +16 -17
- package/build/daemon.js.map +1 -1
- package/build/help.js +36 -10
- package/build/help.js.map +1 -1
- package/build/in-process.js +5 -4
- package/build/in-process.js.map +1 -1
- package/build/inbox.js +14 -4
- package/build/inbox.js.map +1 -1
- package/build/manager.js +42 -31
- package/build/manager.js.map +1 -1
- package/build/note.js +1 -1
- package/build/note.js.map +1 -1
- package/build/paths.js +44 -1
- package/build/paths.js.map +1 -1
- package/build/profile-layers.js +264 -0
- package/build/profile-layers.js.map +1 -0
- package/build/profile.js +3 -18
- package/build/profile.js.map +1 -1
- package/build/project-check-cli.js +2 -1
- package/build/project-check-cli.js.map +1 -1
- package/build/project-check.js +77 -85
- package/build/project-check.js.map +1 -1
- package/build/registry.js +195 -36
- package/build/registry.js.map +1 -1
- package/build/rules-service.js +80 -41
- package/build/rules-service.js.map +1 -1
- package/build/rules.js +1 -1
- package/build/rules.js.map +1 -1
- package/build/server.js +3 -5
- package/build/server.js.map +1 -1
- package/build/store.js +46 -15
- package/build/store.js.map +1 -1
- package/build/tracker-reads-cli.js +4 -3
- package/build/tracker-reads-cli.js.map +1 -1
- package/build/train-cli.js +6 -5
- package/build/train-cli.js.map +1 -1
- package/build/wait.js +6 -6
- package/build/wait.js.map +1 -1
- package/build/worktrees.js +53 -90
- package/build/worktrees.js.map +1 -1
- package/package.json +1 -1
- package/plugin/skills/conductor-console/SKILL.md +1 -1
- package/plugin/skills/work-item/SKILL.md +1 -1
- package/build/checkout-sync.js +0 -249
- package/build/checkout-sync.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
Releases are tagged `conductor-v<version>` and staged on npm by `atk-conductor-release` (`pipelines/release-conductor.yml`), which writes each section below. `scripts/check-changelog.mjs` fails when a tag has no section here.
|
|
4
4
|
|
|
5
|
+
## [3.0.0-dev.15](https://emergentcode.visualstudio.com/Emergent%20Software/_git/Emergent.AgenticToolkit/branchCompare?baseVersion=GTconductor-v3.0.0-dev.14&targetVersion=GTconductor-v3.0.0-dev.15) (2026-10-17)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **conductor:** conduct daemon-owned clones with layered profiles (ATK-527) ([bb12932](https://emergentcode.visualstudio.com/Emergent%20Software/_git/Emergent.AgenticToolkit/commit/bb1293234d3b8d409e4ae714dd874531e9380409))
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **conductor:** harden clones and project add from the review (ATK-527) ([43d16c1](https://emergentcode.visualstudio.com/Emergent%20Software/_git/Emergent.AgenticToolkit/commit/43d16c1d9b33520fbcc67cc856794e798c54f50d))
|
|
14
|
+
* **conductor:** match remotes and real paths, guard clone refs (ATK-527) ([7be6ece](https://emergentcode.visualstudio.com/Emergent%20Software/_git/Emergent.AgenticToolkit/commit/7be6ececa3b242c3720a1c23bbe5d6caf456a8da))
|
|
15
|
+
|
|
5
16
|
## [3.0.0-dev.14](https://emergentcode.visualstudio.com/Emergent%20Software/_git/Emergent.AgenticToolkit/branchCompare?baseVersion=GTconductor-v3.0.0-dev.13&targetVersion=GTconductor-v3.0.0-dev.14) (2026-10-17)
|
|
6
17
|
|
|
7
18
|
### Features
|
package/README.md
CHANGED
|
@@ -10,11 +10,14 @@ conduct start start the daemon detached and wait until it an
|
|
|
10
10
|
conduct stop stop the running daemon
|
|
11
11
|
conduct supervise [--fail-fast] run the daemon and restart it when it dies (see Restarts)
|
|
12
12
|
conduct status [--json] the daemon's pid, port, projects, workers and held locks
|
|
13
|
-
conduct project add <path>
|
|
13
|
+
conduct project add <url | path> [--name <name>]
|
|
14
|
+
clone the project's remote into ~/.conductor/projects/<name>/repo and register it
|
|
14
15
|
conduct project list [--json] the registered projects
|
|
15
16
|
conduct project remove <name> drop a registration (a renamed project's old name), resolving its inbox items
|
|
16
17
|
conduct project check <name> [--no-worktree] [--json]
|
|
17
18
|
whether the project can be conducted, before a launch finds out
|
|
19
|
+
conduct profile <project> [--json]
|
|
20
|
+
the project's profile, machine over repo, each field with its source (see Projects)
|
|
18
21
|
conduct launch <item> start a worker: worktree, background session, tab
|
|
19
22
|
[--project <name>] [--probe] [--prompt <text>] [--conductor <name>]
|
|
20
23
|
conduct retire <worker> [--force] stop a worker, remove its worktree and session
|
|
@@ -101,7 +104,7 @@ The session manager owns the `claude --bg` sessions it launches, and only those:
|
|
|
101
104
|
|
|
102
105
|
- **launch:** the worktree comes first, made by the daemon itself (design note v2, section 2; ATK-526), with no hooks:
|
|
103
106
|
1. the broker gives it a port for each name in the profile's `ports` (see Broker);
|
|
104
|
-
2. `git worktree add
|
|
107
|
+
2. `git worktree add`, run in the project's clone (see Projects), makes `~/.conductor/projects/<project>/worktrees/<name>` on `worktree-<name>` from `origin/<base>`, fetched first (after `git worktree prune`, and on Windows with `core.longpaths` on). It doesn't fetch, pull, add worktrees to or change a checkout of yours (a `localFilesFrom` checkout is only read). A worktree git still reads there is reused, its own changes and all; one with a `.git` git can't read is never deleted, and fails the launch. A `worktree-<name>` branch that is left is checked out again, with any commits it kept;
|
|
105
108
|
3. with `localFilesFrom` (an absolute path to a checkout the operator keeps), the gitignored files there that match its `.worktreeinclude` are copied in, as they are now;
|
|
106
109
|
4. the profile's `setup` commands run in order in the worktree, through the shell, with `CONDUCTOR_PORT_<NAME>` (such as `CONDUCTOR_PORT_WEB=41000`), `CONDUCTOR_ITEM`, `CONDUCTOR_PROJECT` and `CONDUCTOR_WORKTREE` set. They build its gitignored files from what the repo commits (ATK's: `pnpm install`, `atk setup --tool claude-code --yes`, `node scripts/dev-ports.mjs assign`, `atk install`). The first that fails fails the launch, with the end of its output. So does a setup that leaves changes git sees, such as an `.atk-lock.json` that `atk install` rewrote: the worker would take them for its own;
|
|
107
110
|
5. the ports go into the worktree's `.claude/settings.local.json` as `env`, merged into what the file had. A `claude --bg` session doesn't inherit the environment it is started from, but Claude Code applies that file's `env` to every session in the folder and to each resume;
|
|
@@ -119,7 +122,7 @@ The session manager owns the `claude --bg` sessions it launches, and only those:
|
|
|
119
122
|
- **not merged** (abandoned or closed, or no PR with work in it): it stops and removes the session and frees the ports, and keeps the worktree and its branch, so nothing the PR didn't land is lost. `worker.retired` names it under `kept`, which raises one `failed` inbox item with the path, the branch and the commands that remove them. A PR the project's code host can't read at all counts as not merged;
|
|
120
123
|
- **unread** (the code host didn't answer): it refuses, as a refusal that passes on its own, and the scheduler tries again.
|
|
121
124
|
|
|
122
|
-
A probe's worktree and a `--force` retire's always go. The removal moves the worktree aside, has git forget it, deletes the branch and then the directory with Node, which unlinks pnpm's junctions without following them (`git worktree remove` leaves them on Windows). The delete is asynchronous, so the API goes on answering through a minute of `node_modules`. With the directory gone already, it deletes the `worktree-<name>` branch only when none of its commits is unpushed. If the stop fails, nothing is removed.
|
|
125
|
+
A probe's worktree and a `--force` retire's always go. The removal moves the worktree aside, has git forget it, deletes the branch and then the directory with Node, which unlinks pnpm's junctions without following them (`git worktree remove` leaves them on Windows). The delete is asynchronous, so the API goes on answering through a minute of `node_modules`. It works in the repository the worktree's own `.git` names, so a worker launched before the daemon owned clones retires from the checkout its worktree was made in; it removes only a linked worktree that repository lists, never a main checkout. With the directory gone already, it deletes the `worktree-<name>` branch in the project's clone only when none of its commits is unpushed. If the stop fails, nothing is removed.
|
|
123
126
|
- **restarts:** a launch the daemon was stopped in adopts its session if one was started, and otherwise fails and removes its clean worktree.
|
|
124
127
|
- **attach:** a parked worker is resumed with no event text, so it wakes idle and keeps running when its tab closes. An attached worker isn't parked until it registers a new wait, or until its turn has been over `sessions.idleMinutes` (`worker.detached`). The daemon can't see the tab, so this also delivers a wait that resolved while it was attached. A wait that resolves after the attach, on a worker whose transcript shows no turn since then, is delivered at once: the worker is detached (`reason: wait resolved`), parked, which closes its tab, and resumed with the event. A worker someone woke outside the daemon counts as attached since its stop, so the turn that woke it counts. One that took a turn since the attach (or has no transcript to tell), or whose wait resolved before the attach, keeps it until the idle release, logs `worker.resume-held` (`reason: attached`) once, and `conduct status` shows it as `idle, holding resolved waits for the attached session`.
|
|
125
128
|
- **park failures:** a session whose process outlives `claude stop` by 30 s logs one `worker.park-failed` per spell, which raises a `stall` in the inbox (see Inbox), and the park is tried again every 5 minutes.
|
|
@@ -244,7 +247,7 @@ The `inbox` table holds everything that waits on the operator, across projects.
|
|
|
244
247
|
- the exact commands, and its links, each named (`{ label, href }`);
|
|
245
248
|
- when it was raised.
|
|
246
249
|
|
|
247
|
-
The console gives each link a button of its own, `open <label>`, and `conduct inbox` and `/inbox` print it as `<label>: <href>`. The daemon names the links it knows: a run is `run <n>`, a conflict's PR is `PR <n>`, a refused file is `rules` or `profile`, a
|
|
250
|
+
The console gives each link a button of its own, `open <label>`, and `conduct inbox` and `/inbox` print it as `<label>: <href>`. The daemon names the links it knows: a run is `run <n>`, a conflict's PR is `PR <n>`, a refused file is `rules` or `profile`, a train's are `<repo> PRs` and `train PR <n>`. Every other link is named from its shape:
|
|
248
251
|
|
|
249
252
|
- A pull request is `PR <n>`, or `<repo> PR <n>` when it isn't the project's repo.
|
|
250
253
|
- An Azure Pipelines or GitHub Actions run is `run <n>`.
|
|
@@ -341,11 +344,11 @@ Rules say what the conductor does when something happens (design note, section 9
|
|
|
341
344
|
]
|
|
342
345
|
```
|
|
343
346
|
|
|
344
|
-
- **Sources, in order:** the item's project's `rules
|
|
347
|
+
- **Sources, in order:** the item's project's `rules`, its machine profile's (`~/.conductor/projects/<project>.json`, named `project.<project>.machine:<id>`) before its repo's (`.claude/conductor.json`, changed by PR, named `project.<project>:<id>`; see Projects), then `~/.conductor/rules.json`, then the built-in defaults: conduct-atk's behavior written as rules (`launch`, `retire-closed`, `park-on-wait`, `resume-on-wait`, `compact-on-park`, `runaway`, `daily-cap`, `ready-to-release`, `queue-drained`, `triage`, which raises a new item that waits on the profile's triage label in the inbox, `conductor-handoff`, which escalates a worker's `Handoff · conductor` note to the console, and `hold-pre-start-handoff`, which adds the human label when a worker hands off as `human`, `operator`, `blocked` or `scope` before its `Started` note, so the scheduler never launches work no worker can do again; remove the label if the item should be picked later), and `release-pre-start-hold`, which takes that label off again when the worker clears the hold itself (its `Resumed`, or its `Started` after the hold), and leaves a human label the hold didn't add (ATK-575). A rule with an `id` replaces the rule with the same id further down, so a file holds only the differences, and a machine-profile rule replaces the repo's rule of its id (`"do": "none"` switches it off).
|
|
345
348
|
- **when:** `and`, `or`, `not` and parentheses over comparisons (`==`, `!=`, `<`, `<=`, `>`, `>=`, `in [a, b]`, `<label> in item.labels`, `Started in item.phases`) and events. An event rule fires when one of its events happens: `note`, `plan`, `wait.resolved`, `run.failed` (a failed launch, a session that stopped unexpectedly, or a PR's red checks: `pr.checks-failed`), `worker.idle`, `worker.exited`, `worker.permission`, `worker.waiting`, `worker.parked` (a park; the session manager also asks it of each parked worker on a sweep, for `compact`), `inbox.raised`, `pr.comment`, `item.unblocked`, `item.closed`, `provider.login-failed` (a project's login lost, once per spell; see Accounts), `queue.pick`, `queue.drained`, `queue.ready-to-release`, `queue.triage`. A rule without one is a state rule, checked on each scheduler tick against each wait, inbox item, worker or project, or once for the machine, by the fields it reads. Fields: `project`, `item.id/area/labels/tier/priority`, `item.phases` (the phases of every note the item has had, the one being posted too), `item.labelled-by` (the ids of the rules whose label add still stands on the item: a label they added, not one it had already, that no rule removed since), `plan.tier/landing`, `note.phase/kind`, `wait.kind/age`, `inbox.kind/age`, `worker.retries/phase`, `worker.context` (the session's context in tokens, see Workers), `spend.worker/item/project/today` (input, output and cache-write tokens, without cache reads: the worker's and the item's in all, the project's and the machine's today), `time`, `day`, `notify.profile`. Values carry units: `15m`, `2h`, `500k`, `2M`, `22:00`, `saturday`.
|
|
346
349
|
- **do:** `launch`, `retire`, `park`, `resume worker`, `retry`, `pause launches [in <project>] [until <when> | for <duration>]`, `pause all launches …`, `unpause launches`, `focus [<project>] weight|slots <n> until <when>`, `auto-approve now`, `auto-approve after <duration>`, `inbox <kind> ["<text>"]`, `remind operator`, `notify <channel> ["<text>"]`, `notify profile <name> [until <when>]`, `label add|remove human|triage|shipped-open`, `flag shipped-open`, `escalate console "<ask>"`, `none`. One string, or a list.
|
|
347
350
|
- **Guardrails:** rules act inside Area locks, slots, quiet hours and config.json's limits. A rule that would go past one is refused when it loads: `focus … slots` over `scheduler.slots`, an override with no end or one over 14 days, `retire` on anything but `item.closed`, `launch` outside `queue.pick` / `item.unblocked`, `park` outside `worker.waiting`, `resume` outside `wait.resolved` / `pr.comment`, `compact` outside `worker.parked`, `retry` outside `run.failed`. `merge`, `push`, `publish`, `approve`, `delete` and `run` aren't in the vocabulary: rules never merge, push, publish, approve prod, delete or run commands, and the daemon writes to a code host only when the owning worker asks (see Writes).
|
|
348
|
-
- **Reload:** saving `rules.json` or a project's profile reloads its rules.
|
|
351
|
+
- **Reload:** saving `rules.json` or a project's machine profile reloads its rules, and so does a fetch of its clone that brings another `.claude/conductor.json` on the base branch. A profile changed either way, or while the daemon was down, is taken whole: the daemon stores it and logs `project.updated` with the fields that `changed`, and the scheduler, watchers and the rest use it from then on. A project keeps the name its folder gives it: the repo's `name` is only what `project add` takes when no `--name` is given, and a machine profile that names another project is refused. To rename one, `conduct project remove <old name>`, then `conduct project add <url> --name <new name>` (in that order: with both registered, both would read the same queue and could launch the same item). The remove drops the old registration and its queue read, resolves its open inbox items (the refusal's among them) and logs `project.removed`, on which the daemon drops its rules and its watch of the file. It is refused while the project has workers in flight, and works without the daemon. A file the conductor refuses leaves its last good rules (for a profile, the whole last good profile) in force, logs `rules.rejected` and raises a `failed` inbox item until it loads again (`rules.loaded`), including after a restart. `conduct project add` refuses a profile whose rules don't load, with or without the daemon.
|
|
349
352
|
- **Checking:** `conduct rules` lists the rules in force (`project.atk:#2`, `machine:runaway`, `default:launch`) and what replaces what. `conduct rules test <file>` dry-runs a sample, such as `{ "event": "pr.comment", "project": "atk", "fields": { "wait.kind": "merge", "wait.age": "3h" } }` (leave out `event` for a state rule), and shows what fires, each action's guardrail, and why every other rule of the trigger didn't. Both read the files directly when the daemon isn't running.
|
|
350
353
|
|
|
351
354
|
- **Why:** every action the conductor takes is an event that names its rule, directly (`rule`) or through the event that caused it (`data.cause`). `conduct why <event id>` follows that chain back and shows the rule as it fired; `conduct why ATK-315` does it for the item's newest actions.
|
|
@@ -401,15 +404,30 @@ The scheduler moves conduct-atk's tick into the daemon (design note, section 8).
|
|
|
401
404
|
|
|
402
405
|
**Overrides** end on their own: `conduct pause atk --until 17:00`, `conduct pause --until tomorrow` (every project), `conduct unpause atk`, `conduct focus atk --slots 3 --until monday`. `--until` takes `17:00` (the next one), `tomorrow`, a day, or a date and time. Each is an `override.set` event, which `conduct why` attributes to the command, and they show in `conduct rules`.
|
|
403
406
|
|
|
404
|
-
##
|
|
407
|
+
## Projects
|
|
405
408
|
|
|
406
|
-
A
|
|
409
|
+
A conducted project is a clone the daemon owns (design note v2, sections 2 and 7; ATK-527). Everything of it lives under `~/.conductor/projects`:
|
|
407
410
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
+
| Path | Holds |
|
|
412
|
+
|---|---|
|
|
413
|
+
| `<name>.json` | its machine profile: what this machine says about the project, which wins over the repo's |
|
|
414
|
+
| `<name>/repo` | the clone of its remote, which the daemon fetches and adds worktrees to |
|
|
415
|
+
| `<name>/worktrees/<item>` | a worker's worktree (see Workers) |
|
|
416
|
+
|
|
417
|
+
**Adding one.** `conduct project add <url | path> [--name <name>]` clones the remote into `<name>/repo`, in the CLI's own process, so its output shows and no API timeout applies. Given a path, it reads that checkout's `origin` and clones from the remote: the folder itself is never cloned, and nothing the conductor does touches it again. The name is `--name`, else the `name` the repo's `.claude/conductor.json` gives on its default branch; a repo with no profile needs `--name`. The clone is made in a staging folder first, so one that fails leaves nothing. Adding a project again fetches its clone (its origin must be the same remote) and updates the registration in place: its inbox, items and workers stay. Then the daemon registers it (or the store, with none running). Claude Code trusts a worktree by its repository, and nobody has opened a new clone in Claude Code yet, so `add` ends with the one step that trusts it: run `claude` in the clone once and accept the trust prompt, then `conduct project check <name>`.
|
|
418
|
+
|
|
419
|
+
**Its profile** comes in two layers, merged as the files are written, before the schema reads them:
|
|
420
|
+
|
|
421
|
+
- the **machine profile**, `<name>.json` (JSONC), optional beside a repo profile. A project with no repo profile keeps a whole profile here;
|
|
422
|
+
- the **repo profile**, `.claude/conductor.json` at `origin/<base>` in the clone, optional, changed by PR and shared by the team. `<base>` is the machine profile's `baseBranch`, else the remote's default branch (`origin/HEAD`); when the file there names another `baseBranch`, it is read once more at that one.
|
|
423
|
+
|
|
424
|
+
Objects merge key by key and the machine's value wins; arrays (`ports`, `setup`, `approvers`, `gates`, …) are replaced whole. `rules` stack instead: the machine profile's first, then the repo's, then `rules.json`, then the defaults, so a machine rule replaces the repo's rule of its id (see Rules). Each layer's `conductor` minimum is checked on its own, and `protocol` on the merge. `name` is the registered one: a machine profile may repeat it, not change it.
|
|
425
|
+
|
|
426
|
+
`conduct profile <name>` prints the merged profile from the files and the clone as fetched last, one line per field with its value and its source (`machine`, `repo` or `default`), then each rule with its layer; `--json` gives `{ profile, sources }`. It works with or without the daemon.
|
|
427
|
+
|
|
428
|
+
**Keeping it current.** When the daemon starts and every `clones.fetchMinutes` (10) after, it runs `git fetch --quiet --prune origin` in each clone and then reads the profile again, so a changed `.claude/conductor.json` on the base branch is in force as a saved machine profile is (a watch on `<name>.json` takes that at once). A worktree create waits out a fetch that is running, and the fetches pass a clone by while a create works in it, so the two never write the clone's refs at once. A fetch can't prompt for credentials (`GIT_TERMINAL_PROMPT=0`) and gives up after 2 minutes. A failed fetch is logged once a spell, and the profile stays as it was. Nothing is pulled, installed or fast-forwarded anywhere else: a worktree's `setup` installs what its branch pins.
|
|
411
429
|
|
|
412
|
-
|
|
430
|
+
**From a project registered by its checkout** (before ATK-527): the daemon conducts such a row no longer. Its profile is refused with the step that moves it, `conduct project add "<that checkout>"`, which clones the checkout's origin and keeps the registration, and the scheduler launches none of its items meanwhile. Workers in flight keep their worktrees in that checkout, and retire from it: that retire is the one time the conductor runs git there (`git worktree prune`, and `git branch -D` of the worker's branch). A profile refusal of the project, whichever file it named, resolves once the project's profile loads.
|
|
413
431
|
|
|
414
432
|
## Skill trains
|
|
415
433
|
|
|
@@ -609,7 +627,8 @@ Everything lives in `~/.conductor` (`CONDUCTOR_HOME` overrides it):
|
|
|
609
627
|
|
|
610
628
|
| File | Holds |
|
|
611
629
|
|---|---|
|
|
612
|
-
| `
|
|
630
|
+
| `projects/` | each conducted project's machine profile, clone and worktrees (see Projects) |
|
|
631
|
+
| `config.json` | machine settings, JSONC (comments allowed), validated at startup; `clones.fetchMinutes` (10, see Projects); `inbox.runawayTokens` (1500000, the `runaway` rule's number); `notify` and `quietHours` (see Notifications); `scheduler` holds `mode` (`on`, `observe` or `off`), `slots` (4, across projects, and the most any rule can give one project), `dailyTokens` (20000000, the `daily-cap` rule's number) and `tickSeconds` (120); `sessions` holds `pollSeconds` (10), `settleSeconds` (5), `permissionMinutes` (5), `idleMinutes` (20), `compactTokens` (300000, the `compact-on-park` rule's number); `watchers` holds `ado`, `github`, `health`, `linear` and `npm`, each `{ intervalSeconds, perMinute }` (30/60, 30/30, 30/30, 30/10, 20/30), `statsMinutes` (10) and `conflictMinutes` (30) |
|
|
613
632
|
| `rules.json` | machine rules, JSONC, reloaded on save (see Rules) |
|
|
614
633
|
| `token` | the API token, readable by this user only; every request sends `Authorization: Bearer <token>` |
|
|
615
634
|
| `conductor.pid`, `port` | the single-instance lock and where the API listens (`127.0.0.1`) |
|
|
@@ -618,7 +637,7 @@ Everything lives in `~/.conductor` (`CONDUCTOR_HOME` overrides it):
|
|
|
618
637
|
|
|
619
638
|
## API
|
|
620
639
|
|
|
621
|
-
- `GET /projects`: the registered projects
|
|
640
|
+
- `GET /projects`: the registered projects, each with its `clone`, `url`, profile and `sources`. `POST /projects` with `{ "name": "<name>" }` registers the clone `conduct project add` made at `~/.conductor/projects/<name>/repo` (400 when there is none, or its profile doesn't read). `DELETE /projects/<name>` removes one: `{ project, resolved }` (the inbox items it resolved), 404 for a name no project is registered under, or 409 naming its workers in flight. `POST /projects/<name>/check` with `{ "worktree": false }` or `{}` runs `conduct project check` as the daemon's accounts: `{ project, results: [{ check, status, summary, details, fix }] }`, or 404 for a name no project is registered under.
|
|
622
641
|
- `GET /events`: the event log as server-sent events. Add `?since=<id>` (or send `Last-Event-ID`) to replay from an id. Without either, the stream starts at the live end. `conduct events` prints it one JSON event per line: the events after `--since` (all of them without it), or with `--follow` everything from there on (live without `--since`). `--follow` reconnects with `Last-Event-ID` when the daemon goes away, so a restart loses nothing, and prints the stream's state as lines without an id: `{"kind":"conduct.connected"}` and, once per outage, `{"kind":"conduct.disconnected","error":…}`. `?console=1` (`conduct events --follow --console`, which the conductor mod runs, or `conduct events --follow` with `CONDUCTOR_CONSOLE=1`, as a mod from before `--console` runs it until `/reload-plugins`) marks the console's stream: while one is open, escalations have a console to wake (see Console).
|
|
623
642
|
- `POST /shutdown`: a clean stop (`conduct stop`).
|
|
624
643
|
- `GET /console/escalations`: the open escalations, oldest first (see Console).
|
|
@@ -671,10 +690,10 @@ Install the package globally, next to `atk`. `dev` follows `develop`; `latest` f
|
|
|
671
690
|
```bash
|
|
672
691
|
npm install --global @detergent-software/conductor@dev
|
|
673
692
|
conduct install-startup
|
|
674
|
-
conduct project add <
|
|
693
|
+
conduct project add <the project's remote URL, or a checkout of it>
|
|
675
694
|
```
|
|
676
695
|
|
|
677
|
-
`conduct project add`
|
|
696
|
+
`conduct project add` clones the remote into `~/.conductor/projects/<name>/repo` (see Projects). After that the daemon reads the profile again when it starts, when the machine profile is saved and after each fetch of the clone, so a merge that changes `slots` or `skills.work` needs no `conduct project add`. An older daemon refuses a profile with fields it doesn't know, so upgrade the daemon before a profile that uses new ones lands.
|
|
678
697
|
|
|
679
698
|
A profile that uses new fields says which conductor reads them: `"conductor": "3.0.0-dev.9"`, the version that first read the newest of them (a `-dev.N` while it is only on `dev`; a stable minimum such as `3.0.0` is newer than every `3.0.0-dev.N`, as semver orders them). Every conductor from the one that knows this key (ATK-573) checks it before the rest of the profile, and an older one refuses the file with one line instead of a list of fields: `conductor: needs 3.0.0-dev.9 or newer; this is 3.0.0-dev.7: run \`conduct upgrade --tag dev\`` (`--tag latest` for a stable minimum). The worker verbs that read the profile in a worktree (`conduct state`, `conduct branch`, `conduct search`, a lock with no daemon) say the same and exit 1, and the daemon's inbox item carries the line and the upgrade command. While a project's profile on disk doesn't read (a minimum above this conductor, a schema problem, another protocol), the scheduler launches none of the project's items: each waits in `conduct queue` as `profile refused: <its first problem>`, since a new worktree would hold the same file and its verbs would refuse it. A profile that reads but whose rules are refused, or that renames the project, keeps the last good profile and launches as before. Workers already running carry on, and launches resume on the first tick after the file loads.
|
|
680
699
|
|
|
@@ -692,12 +711,12 @@ After an `--allow-downgrade` to a version without those fields, the stored copy
|
|
|
692
711
|
|
|
693
712
|
Then `conduct project check <name>` says whether the project can be conducted, before its first launch finds out. Each check prints one line, `ok`, `warn`, `fail` or `skip`, with a fix under a warn or a fail, and the command exits 1 when any check fails (`--json` prints the same as data):
|
|
694
713
|
|
|
695
|
-
- **profile:** the
|
|
714
|
+
- **profile:** the layers (see Projects) read with this build's schema; a `warn` lists the fields that differ from the daemon's stored copy, which it takes on the next save, fetch or start, and each field a file writes that is newer than its `conductor` minimum (`minimumProblems`, above), with the version to raise it to (ATK-580). A project still registered by a checkout fails, with the `conduct project add` that moves it to a clone. The later checks use the resolved profile when it reads, else the stored copy; with neither they are `skip`.
|
|
696
715
|
- **auth:** which credential each provider the project uses signs in with (project token, machine token or CLI login; see Accounts), probed as the daemon would. For each that isn't the project's own token, a detail line gives the scopes, the `cmdkey` line and the config key that would scope it; that is advice, and the check passes. A token that is there but refused, or no credential at all, fails.
|
|
697
716
|
- **tracker:** the tracker's login answers, and the queue reads (Linear: the team, and whether any of its projects has a priority; Boards: the saved query; GitHub Issues: the labelled issues).
|
|
698
717
|
- **code-host** and **ci:** the code host's login answers and the base branch exists; each release's `pipeline` names exactly one of the repo's pipelines.
|
|
699
|
-
- **worktree:** the launch's worktree steps on a throwaway `conduct-check-<time
|
|
700
|
-
- **skills:** `
|
|
718
|
+
- **worktree:** the launch's worktree steps on a throwaway `conduct-check-<time>` in the project's worktrees folder: `git worktree add` in the clone from `origin/<base>`, `localFilesFrom`'s files, the ports the broker would give, and `setup`. Then the profile's skills must be there after it, and a `warn` says when git doesn't ignore `.claude/settings.local.json`, where the ports go. A `claude --bg` with no prompt then checks that Claude Code would start a session there: it starts idle, costs no tokens and is removed at once. Claude Code keeps workspace trust per repository, so a clone nobody has opened in Claude Code fails here with the one step that trusts it, `claude` run in the clone once with its trust prompt accepted (ATK-571). It is removed with its branch, whatever happened. The one check that writes; `--no-worktree` skips it, since setup can take a while (ATK's runs `pnpm install`).
|
|
719
|
+
- **skills:** a `conductor:<skill>` is in this package's plugin, and `skills.work` declares `protocol: 2` in its SKILL.md frontmatter (worker protocol 2). A project's own skills arrive through its `setup` (ATK's runs `atk install`), not in the clone, so the worktree check looks for them.
|
|
701
720
|
- **ports:** the machine's pool has a free port for each of the profile's `ports`, saving nothing; `skip` for a profile with none.
|
|
702
721
|
- **health:** each `health` URL answers; a `warn` at most, since an environment can be down.
|
|
703
722
|
|
|
@@ -733,7 +752,7 @@ conduct upgrade
|
|
|
733
752
|
|
|
734
753
|
It takes the tag the installed version came from (`dev` for an `X.Y.Z-dev.N`, `latest` otherwise; `--tag` picks one), and does nothing when that tag's version is already installed. When the tag points at an older version (semver, so `1.2.0-dev.4` is older than `1.2.0`), it refuses before it stops anything and names that version; `--allow-downgrade` installs it anyway and reports `downgraded`. Otherwise it stops the daemon, runs `npm install --global @detergent-software/conductor@<the tag's version>` (the exact version it compared, in case the tag moves) and starts the daemon again: through the `Conductor` logon task when the task runs this `cli.js`, else as a detached `conduct supervise --fail-fast`. A supervisor waiting to restart a daemon that keeps dying is stopped the same way before npm runs (see Restarts), so it can't restart `serve` from the `cli.js` npm is replacing, and the conductor starts again on the new version. A daemon that wasn't running stays stopped. If npm fails, the daemon still starts again on whatever npm left in place, and `upgrade` exits 1 with npm's output. A linked build (below) refuses: its `cli.js` isn't under npm's global `node_modules`.
|
|
735
754
|
|
|
736
|
-
**From a checkout instead (development).** `npm link` puts
|
|
755
|
+
**From a checkout instead (development).** `npm link` puts a checkout's build on PATH, so every worktree and the logon task run that build. Run it from your own checkout of the conductor's repo, and upgrade by pulling `develop`, building, then `conduct stop` and `conduct serve`:
|
|
737
756
|
|
|
738
757
|
```bash
|
|
739
758
|
pnpm install
|
package/build/brief-cli.js
CHANGED
|
@@ -114,7 +114,7 @@ async function briefHere(paths, item, io, why) {
|
|
|
114
114
|
if (!ITEM.test(item))
|
|
115
115
|
throw new ConductorError(`"${item}" is not a tracker item, such as ATK-311`);
|
|
116
116
|
const key = item.toUpperCase();
|
|
117
|
-
const here = await checkoutProject(io.cwd, key, why, 'read it from');
|
|
117
|
+
const here = await checkoutProject(paths, io.cwd, key, why, 'read it from');
|
|
118
118
|
if ('refusal' in here)
|
|
119
119
|
return notBriefed(here.refusal);
|
|
120
120
|
const { profile } = here;
|
package/build/brief-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brief-cli.js","sourceRoot":"","sources":["../src/brief-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAEL,UAAU,EACV,UAAU,EACV,OAAO,EAEP,QAAQ,EAER,YAAY,EACZ,OAAO,GACR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAoB,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,mGAAmG;AACnG,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAWhC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAEvG,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,QAAQ,EAAE,CAAC;SACR,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;SAC3G,QAAQ,EAAE;IACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,CAAC,KAAK,CACf,CAAC,CAAC,MAAM,CAAC;QACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACzB,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE;QACvB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;KAC3G,CAAC,CACH;IACD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,KAAK,CACZ,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC1G;IACD,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,EAAE,EAAE,CAAC;SACF,MAAM,CAAC;QACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,OAAO,EAAE,CAAC;aACP,IAAI,CAAC;YACJ,WAAW;YACX,sBAAsB;YACtB,cAAc;YACd,mBAAmB;YACnB,WAAW;YACX,cAAc;YACd,QAAQ;YACR,gBAAgB;YAChB,SAAS;SACV,CAAC;aACD,QAAQ,EAAE;QACb,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;QACf,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;QACtD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC3B,CAAC;SACD,QAAQ,EAAE;IACb,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;IACtB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC3F,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;IACnE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC3B,CAA4B,CAAC;AAE9B,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAEzF,kGAAkG;AAClG,kGAAkG;AAClG,+BAA+B;AAC/B,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAqB,EACrB,IAAY,EACZ,OAA8D,EAC9D,EAAW;IAEX,KAAK,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,CAAC;AACX,CAAC;AAED,qGAAqG;AACrG,iGAAiG;AACjG,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAqB,EACrB,IAAY,EACZ,OAA+C,EAC/C,EAAW;IAEX,IAAI,MAAyC,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE;YAC5B,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,UAAU,kBAAkB,CAAC,IAAI,CAAC,UAAU,IAAI,eAAe,CAAC;gBACpE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3C,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClD,CAAC,CAAC,QAAQ,EAAE,EAAE;YACf,SAAS,EAAE,gBAAgB;SAC5B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,eAAe;YAAE,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,8BAA8B,CAAC,CAAC;QACxG,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtE,uFAAuF;QACvF,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,8CAA8C,CAAC,CAAC;QACtG,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;IAC1B,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;IAClD,iGAAiG;IACjG,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,KAAK,KAAK,WAAW;QACvD,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,iCAAiC,CAAC,CAAC;IACvE,sEAAsE;IACtE,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG;QACvB,OAAO,UAAU,CACf,GAAG,KAAK,EAAE,KAAK,IAAI,0CAA0C,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACjI,CAAC;IACJ,MAAM,IAAI,cAAc,CAAC,KAAK,EAAE,KAAK,IAAI,oBAAoB,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;AACtG,CAAC;AAED,8FAA8F;AAC9F,0FAA0F;AAC1F,KAAK,UAAU,SAAS,CAAC,KAAqB,EAAE,IAAY,EAAE,EAAW,EAAE,GAAW;IACpF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,IAAI,IAAI,0CAA0C,CAAC,CAAC;IACnG,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"brief-cli.js","sourceRoot":"","sources":["../src/brief-cli.ts"],"names":[],"mappings":"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"}
|
package/build/broker-cli.js
CHANGED
|
@@ -8,7 +8,8 @@ import { ConductorError } from "./errors.js";
|
|
|
8
8
|
import { fileLock } from "./file-lock.js";
|
|
9
9
|
import { usageError } from "./help.js";
|
|
10
10
|
import { samePath } from "./paths.js";
|
|
11
|
-
import {
|
|
11
|
+
import { profileHere } from "./profile-layers.js";
|
|
12
|
+
import { profileProblem } from "./profile.js";
|
|
12
13
|
import { lockSchema, portAssignmentSchema } from "./store.js";
|
|
13
14
|
import { daemonWorker, gitToplevel } from "./wait.js";
|
|
14
15
|
// How often `conduct lock acquire --wait` asks again, as the work-issue helper's lock does.
|
|
@@ -41,7 +42,7 @@ export async function lockCommand(paths, action, name, options, io) {
|
|
|
41
42
|
if (owner === null) {
|
|
42
43
|
const worker = await daemonWorker(paths, await gitToplevel(io.cwd), undefined);
|
|
43
44
|
if (worker === 'no-daemon')
|
|
44
|
-
return lockHere(action, name, options, io, 'the conductor is not running');
|
|
45
|
+
return lockHere(paths, action, name, options, io, 'the conductor is not running');
|
|
45
46
|
if (worker === 'unreachable')
|
|
46
47
|
throw new ConductorError("the conductor didn't answer");
|
|
47
48
|
owner = worker?.item ?? null;
|
|
@@ -57,7 +58,7 @@ export async function lockCommand(paths, action, name, options, io) {
|
|
|
57
58
|
path: `/locks/${name}`,
|
|
58
59
|
});
|
|
59
60
|
if (!answer.ok)
|
|
60
|
-
return lockHere(action, name, options, io, answer.why);
|
|
61
|
+
return lockHere(paths, action, name, options, io, answer.why);
|
|
61
62
|
const body = lockAnswer.parse(answer.body);
|
|
62
63
|
if (action !== 'acquire' || body.acquired !== false || Date.now() >= until) {
|
|
63
64
|
io.out(JSON.stringify(body, null, 2));
|
|
@@ -126,16 +127,16 @@ async function ask(paths, request) {
|
|
|
126
127
|
// The lock with no conductor to broker it: the file lock every worktree of this checkout's repo
|
|
127
128
|
// shares (file-lock.ts). The owner is --owner, else the item key in the worktree's name or branch.
|
|
128
129
|
// Refuses only outside a project checkout.
|
|
129
|
-
async function lockHere(action, name, options, io, why) {
|
|
130
|
+
async function lockHere(paths, action, name, options, io, why) {
|
|
130
131
|
const checkout = await gitToplevel(io.cwd);
|
|
131
132
|
if (checkout === null)
|
|
132
133
|
return notBrokered(`${why}, and this isn't a checkout to take a file lock in`);
|
|
133
134
|
let profile;
|
|
134
135
|
try {
|
|
135
|
-
profile =
|
|
136
|
+
profile = profileHere(checkout, paths);
|
|
136
137
|
}
|
|
137
138
|
catch (error) {
|
|
138
|
-
return notBrokered(`${why}, and ${checkout} has no readable
|
|
139
|
+
return notBrokered(`${why}, and ${checkout} has no readable profile: ${profileProblem(error)}`);
|
|
139
140
|
}
|
|
140
141
|
const given = options.owner?.trim();
|
|
141
142
|
// Status needs no owner; the others take the checkout's item, and refuse without one.
|
package/build/broker-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker-cli.js","sourceRoot":"","sources":["../src/broker-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAoB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"broker-cli.js","sourceRoot":"","sources":["../src/broker-cli.ts"],"names":[],"mappings":"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"}
|
package/build/cli.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { join,
|
|
4
|
+
import { join, sep } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { parseArgs } from 'node:util';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { briefCommand } from "./brief-cli.js";
|
|
9
9
|
import { heldLocks, lockCommand, lockLine, portsCommand } from "./broker-cli.js";
|
|
10
|
+
import { trustStep } from "./claude.js";
|
|
10
11
|
import { callApi, NotRunningError, ping, readEndpoint } from "./client.js";
|
|
11
12
|
import { branchCommand, checkoutCommand, fileCommand, landCommand, modeCommand, prCreateCommand, prThreadsCommand, replyCommand, runsCommand, stateCommand, } from "./code-host-cli.js";
|
|
12
13
|
import { configSchema, loadConfig } from "./config.js";
|
|
@@ -29,10 +30,11 @@ import { overrideViewSchema, PAUSE } from "./overrides.js";
|
|
|
29
30
|
import { packageInfo } from "./package-info.js";
|
|
30
31
|
import { conductorPaths } from "./paths.js";
|
|
31
32
|
import { refreshConductorPlugin } from "./plugin.js";
|
|
33
|
+
import { profileLines, projectProfile } from "./profile-layers.js";
|
|
32
34
|
import { projectCheckCommand } from "./project-check-cli.js";
|
|
33
35
|
import { noProject } from "./project-check.js";
|
|
34
36
|
import { pushoverCredential, pushoverSender } from "./pushover.js";
|
|
35
|
-
import { registerProject } from "./registry.js";
|
|
37
|
+
import { cloneProject, registerProject } from "./registry.js";
|
|
36
38
|
import { rulesLines, rulesService, rulesTestResultSchema, rulesViewSchema, testLines, } from "./rules-service.js";
|
|
37
39
|
import { resolveUntil } from "./rules.js";
|
|
38
40
|
import { outputOf, run } from "./run.js";
|
|
@@ -98,11 +100,13 @@ const answerRefusal = z.object({
|
|
|
98
100
|
error: z.string(),
|
|
99
101
|
posted: z.enum(['no', 'unknown']).optional(),
|
|
100
102
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
// `conduct project add <url | path> [--name <name>]`: the clone is made here, where its progress
|
|
104
|
+
// shows and no API timeout applies, then the daemon registers it (or the store, with none running).
|
|
105
|
+
async function addProject(paths, source, name) {
|
|
106
|
+
const made = await cloneProject(paths, source, { ...(name === undefined ? {} : { name }), say: out });
|
|
103
107
|
let result;
|
|
104
108
|
try {
|
|
105
|
-
result = addBody.parse(await expectOk(callApi(paths, { body: {
|
|
109
|
+
result = addBody.parse(await expectOk(callApi(paths, { body: { name: made.name }, method: 'POST', path: '/projects' })));
|
|
106
110
|
}
|
|
107
111
|
catch (error) {
|
|
108
112
|
if (!(error instanceof NotRunningError))
|
|
@@ -110,9 +114,14 @@ async function addProject(paths, path) {
|
|
|
110
114
|
// No daemon: write the store directly. The daemon reads it when it starts.
|
|
111
115
|
// Its rules are checked against config.json here too, as the daemon would.
|
|
112
116
|
const check = rulesService({ config: loadConfig(paths.config), listProjects: () => [], paths }).checkProfile;
|
|
113
|
-
result = withStore(paths, (store) => registerProject(store,
|
|
117
|
+
result = withStore(paths, (store) => registerProject(store, paths, made.name, check));
|
|
114
118
|
}
|
|
115
119
|
out(`${result.created ? 'registered' : 'updated'} ${projectLine(result.project).trim()}`);
|
|
120
|
+
out(made.cloned ? `cloned ${made.url} into ${made.clone}` : `fetched ${made.clone}, the clone it has`);
|
|
121
|
+
out(`its machine profile, which wins over the repo's: ${result.project.profilePath}`);
|
|
122
|
+
// Claude Code trusts a worktree by its repository, and nobody has run Claude in a new clone yet.
|
|
123
|
+
if (made.cloned)
|
|
124
|
+
out(`next: ${trustStep(made.clone)}, then \`conduct project check ${made.name}\``);
|
|
116
125
|
}
|
|
117
126
|
// `conduct approve|revise|done`: Jason's answer to an inbox item, by id, or for approve and revise
|
|
118
127
|
// by the item whose plan waits.
|
|
@@ -399,7 +408,7 @@ async function listProjects(paths, json) {
|
|
|
399
408
|
if (json)
|
|
400
409
|
return out(JSON.stringify(projects, null, 2));
|
|
401
410
|
if (projects.length === 0)
|
|
402
|
-
return out('no projects; add one with `conduct project add <path>`');
|
|
411
|
+
return out('no projects; add one with `conduct project add <url | path>`');
|
|
403
412
|
projects.forEach((p) => out(projectLine(p)));
|
|
404
413
|
}
|
|
405
414
|
async function main(argv) {
|
|
@@ -460,6 +469,7 @@ async function main(argv) {
|
|
|
460
469
|
kind: { type: 'string' },
|
|
461
470
|
last: { type: 'boolean' },
|
|
462
471
|
mode: { type: 'string' },
|
|
472
|
+
name: { type: 'string' },
|
|
463
473
|
'no-worktree': { type: 'boolean' },
|
|
464
474
|
owner: { type: 'string' },
|
|
465
475
|
phase: { type: 'string' },
|
|
@@ -511,7 +521,7 @@ async function main(argv) {
|
|
|
511
521
|
case 'branch':
|
|
512
522
|
if (sub === undefined || arg === undefined)
|
|
513
523
|
throw usageError('branch');
|
|
514
|
-
process.exitCode = await branchCommand(sub, arg, item, verbIo());
|
|
524
|
+
process.exitCode = await branchCommand(paths, sub, arg, item, verbIo());
|
|
515
525
|
return;
|
|
516
526
|
case 'brief':
|
|
517
527
|
if (sub === undefined)
|
|
@@ -525,7 +535,7 @@ async function main(argv) {
|
|
|
525
535
|
case 'checkout':
|
|
526
536
|
if (sub === undefined || arg === undefined || fourth === undefined)
|
|
527
537
|
throw usageError('checkout');
|
|
528
|
-
process.exitCode = await checkoutCommand(sub, arg, fourth, item, verbIo());
|
|
538
|
+
process.exitCode = await checkoutCommand(paths, sub, arg, fourth, item, verbIo());
|
|
529
539
|
return;
|
|
530
540
|
case 'comments': {
|
|
531
541
|
if (sub === undefined || arg !== undefined)
|
|
@@ -633,7 +643,7 @@ async function main(argv) {
|
|
|
633
643
|
throw usageError('mode');
|
|
634
644
|
if (tier !== 'S' && tier !== 'M' && tier !== 'L')
|
|
635
645
|
throw new ConductorError('--tier takes S, M or L');
|
|
636
|
-
process.exitCode = await modeCommand({ files: values.files, tier }, verbIo());
|
|
646
|
+
process.exitCode = await modeCommand(paths, { files: values.files, tier }, verbIo());
|
|
637
647
|
return;
|
|
638
648
|
}
|
|
639
649
|
case 'note':
|
|
@@ -682,9 +692,19 @@ async function main(argv) {
|
|
|
682
692
|
case 'ports':
|
|
683
693
|
process.exitCode = await portsCommand(paths, sub, { json: values.json === true }, brokerIo());
|
|
684
694
|
return;
|
|
695
|
+
case 'profile': {
|
|
696
|
+
if (sub === undefined || arg !== undefined)
|
|
697
|
+
throw usageError('profile');
|
|
698
|
+
// Resolved here from the machine file and the clone, as the daemon resolves it.
|
|
699
|
+
const layered = projectProfile(paths, sub);
|
|
700
|
+
if (values.json === true)
|
|
701
|
+
return out(JSON.stringify({ profile: layered.profile, sources: layered.sources }, null, 2));
|
|
702
|
+
profileLines(sub, layered).forEach((line) => out(line));
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
685
705
|
case 'project':
|
|
686
706
|
if (sub === 'add' && arg !== undefined)
|
|
687
|
-
return addProject(paths, arg);
|
|
707
|
+
return addProject(paths, arg, values.name);
|
|
688
708
|
if (sub === 'remove' && arg !== undefined)
|
|
689
709
|
return removeProject(paths, arg);
|
|
690
710
|
if (sub === 'list')
|
|
@@ -905,11 +925,11 @@ async function planItem(paths, ref) {
|
|
|
905
925
|
}
|
|
906
926
|
function projectLine(p) {
|
|
907
927
|
const state = p.problem
|
|
908
|
-
? `${p.problem}; the daemon reads
|
|
928
|
+
? `${p.problem}; the daemon reads the profile again when it starts, when ~/.conductor/projects/${p.name}.json is saved, and after each fetch of the clone`
|
|
909
929
|
: p.enabled
|
|
910
930
|
? 'enabled'
|
|
911
931
|
: 'disabled';
|
|
912
|
-
return ` ${p.name} ${p.
|
|
932
|
+
return ` ${p.name} ${p.clone} (protocol ${p.protocol}, ${state})`;
|
|
913
933
|
}
|
|
914
934
|
// The registered projects: from the daemon, or from the store when it isn't running.
|
|
915
935
|
async function projectsNow(paths) {
|
|
@@ -954,7 +974,7 @@ async function removeProject(paths, name) {
|
|
|
954
974
|
});
|
|
955
975
|
}
|
|
956
976
|
const { project, resolved } = result;
|
|
957
|
-
out(`removed ${project.name} (${project.
|
|
977
|
+
out(`removed ${project.name} (${project.clone})`);
|
|
958
978
|
for (const item of resolved)
|
|
959
979
|
out(` resolved #${item.id} (${item.kind}${item.item ? ` ${item.item}` : ''})`);
|
|
960
980
|
}
|
|
@@ -1148,7 +1168,7 @@ async function status(paths, json) {
|
|
|
1148
1168
|
if (json)
|
|
1149
1169
|
return out(JSON.stringify({ home: paths.home, inbox: items, locks, pid, port, projects, running: true, workers, workersFrom: 'daemon' }, null, 2));
|
|
1150
1170
|
out(`conductor running (pid ${pid ?? '?'}, port ${port ?? '?'}, home ${paths.home})`);
|
|
1151
|
-
out(projects.length === 0 ? 'no projects; add one with `conduct project add <path>`' : 'projects:');
|
|
1171
|
+
out(projects.length === 0 ? 'no projects; add one with `conduct project add <url | path>`' : 'projects:');
|
|
1152
1172
|
projects.forEach((p) => out(projectLine(p)));
|
|
1153
1173
|
out(workers.length === 0 ? 'no workers' : 'workers:');
|
|
1154
1174
|
workers.forEach((w) => out(workerLine(w)));
|