@detergent-software/conductor 3.0.0-dev.9 → 3.1.0-dev.1
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 +486 -0
- package/README.md +272 -126
- package/build/brief-cli.js +5 -12
- package/build/brief-cli.js.map +1 -1
- package/build/brief.js +4 -3
- package/build/brief.js.map +1 -1
- package/build/broker-cli.js +41 -14
- package/build/broker-cli.js.map +1 -1
- package/build/broker.js +1 -1
- package/build/broker.js.map +1 -1
- package/build/cli.js +226 -64
- 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 +172 -40
- package/build/code-host-cli.js.map +1 -1
- package/build/code-host-service.js +35 -2
- package/build/code-host-service.js.map +1 -1
- package/build/code-host.js +138 -16
- package/build/code-host.js.map +1 -1
- package/build/conditions.js +33 -16
- package/build/conditions.js.map +1 -1
- package/build/config.js +58 -28
- package/build/config.js.map +1 -1
- package/build/console.js +17 -27
- package/build/console.js.map +1 -1
- package/build/credentials.js +86 -54
- package/build/credentials.js.map +1 -1
- package/build/daemon.js +54 -65
- package/build/daemon.js.map +1 -1
- package/build/file-lock.js +155 -40
- package/build/file-lock.js.map +1 -1
- package/build/follow-ups.js +2 -2
- package/build/follow-ups.js.map +1 -1
- package/build/help.js +242 -83
- package/build/help.js.map +1 -1
- package/build/history.js +10 -4
- package/build/history.js.map +1 -1
- package/build/host/attach-clients.js +56 -0
- package/build/host/attach-clients.js.map +1 -0
- package/build/host/credential-manager.js +109 -0
- package/build/host/credential-manager.js.map +1 -0
- package/build/host/keychain.js +44 -0
- package/build/host/keychain.js.map +1 -0
- package/build/host/launchd.js +118 -0
- package/build/host/launchd.js.map +1 -0
- package/build/host/libsecret.js +40 -0
- package/build/host/libsecret.js.map +1 -0
- package/build/host/macos-terminal.js +63 -0
- package/build/host/macos-terminal.js.map +1 -0
- package/build/host/platform.js +4 -0
- package/build/host/platform.js.map +1 -0
- package/build/host/secrets.js +46 -0
- package/build/host/secrets.js.map +1 -0
- package/build/host/shell.js +26 -0
- package/build/host/shell.js.map +1 -0
- package/build/host/startup.js +26 -0
- package/build/host/startup.js.map +1 -0
- package/build/host/systemd.js +91 -0
- package/build/host/systemd.js.map +1 -0
- package/build/host/task-scheduler.js +78 -0
- package/build/host/task-scheduler.js.map +1 -0
- package/build/host/terminal.js +47 -0
- package/build/host/terminal.js.map +1 -0
- package/build/host/tmux.js +39 -0
- package/build/host/tmux.js.map +1 -0
- package/build/host/windows-terminal.js +46 -0
- package/build/host/windows-terminal.js.map +1 -0
- package/build/in-process.js +5 -4
- package/build/in-process.js.map +1 -1
- package/build/inbox.js +47 -35
- package/build/inbox.js.map +1 -1
- package/build/init.js +509 -0
- package/build/init.js.map +1 -0
- package/build/landing.js +107 -10
- package/build/landing.js.map +1 -1
- package/build/lib/providers/ado/code-host.js +5 -1
- package/build/lib/providers/ado/code-host.js.map +1 -1
- package/build/lib/providers/ado/pipelines.js +138 -26
- package/build/lib/providers/ado/pipelines.js.map +1 -1
- package/build/lib/providers/ado/trigger.js +5 -0
- package/build/lib/providers/ado/trigger.js.map +1 -1
- package/build/lib/providers/ado/writes.js +17 -2
- package/build/lib/providers/ado/writes.js.map +1 -1
- package/build/lib/providers/github/actions.js +90 -3
- package/build/lib/providers/github/actions.js.map +1 -1
- package/build/lib/providers/github/code-host.js +2 -0
- package/build/lib/providers/github/code-host.js.map +1 -1
- package/build/lib/providers/github/writes.js +25 -2
- package/build/lib/providers/github/writes.js.map +1 -1
- package/build/lib/providers/index.js +3 -2
- package/build/lib/providers/index.js.map +1 -1
- package/build/lib/providers/npm/stage.js +14 -1
- package/build/lib/providers/npm/stage.js.map +1 -1
- package/build/lib/providers/timing.js +10 -0
- package/build/lib/providers/timing.js.map +1 -0
- package/build/lib/providers/verdicts/pr.js +47 -6
- package/build/lib/providers/verdicts/pr.js.map +1 -1
- package/build/lib/providers/verdicts/runs.js +12 -2
- package/build/lib/providers/verdicts/runs.js.map +1 -1
- package/build/logins.js +13 -6
- package/build/logins.js.map +1 -1
- package/build/manager.js +200 -55
- package/build/manager.js.map +1 -1
- package/build/note.js +5 -15
- package/build/note.js.map +1 -1
- package/build/notes.js +130 -23
- package/build/notes.js.map +1 -1
- package/build/notify.js +104 -42
- package/build/notify.js.map +1 -1
- package/build/npm-reads.js +151 -22
- package/build/npm-reads.js.map +1 -1
- package/build/ownership.js +2 -2
- package/build/paths.js +44 -1
- package/build/paths.js.map +1 -1
- package/build/plugin.js +4 -2
- package/build/plugin.js.map +1 -1
- package/build/profile-fields.js +153 -0
- package/build/profile-fields.js.map +1 -0
- package/build/profile-layers.js +264 -0
- package/build/profile-layers.js.map +1 -0
- package/build/profile.js +69 -49
- package/build/profile.js.map +1 -1
- package/build/project-check-cli.js +17 -19
- package/build/project-check-cli.js.map +1 -1
- package/build/project-check.js +166 -104
- package/build/project-check.js.map +1 -1
- package/build/protocol.js +5 -21
- package/build/protocol.js.map +1 -1
- package/build/pushover.js +5 -5
- package/build/pushover.js.map +1 -1
- package/build/queue.js +4 -4
- package/build/queue.js.map +1 -1
- package/build/registry.js +195 -36
- package/build/registry.js.map +1 -1
- package/build/release-kinds.js +34 -0
- package/build/release-kinds.js.map +1 -0
- package/build/rule-actions.js +8 -6
- package/build/rule-actions.js.map +1 -1
- package/build/rules-service.js +83 -44
- package/build/rules-service.js.map +1 -1
- package/build/rules.js +23 -23
- package/build/rules.js.map +1 -1
- package/build/run.js +20 -7
- package/build/run.js.map +1 -1
- package/build/runs.js +218 -68
- package/build/runs.js.map +1 -1
- package/build/scheduler.js +78 -12
- package/build/scheduler.js.map +1 -1
- package/build/search.js +2 -1
- package/build/search.js.map +1 -1
- package/build/server.js +51 -14
- package/build/server.js.map +1 -1
- package/build/spend.js +1 -1
- package/build/spend.js.map +1 -1
- package/build/store.js +79 -20
- package/build/store.js.map +1 -1
- package/build/supervise.js +1 -1
- package/build/supervise.js.map +1 -1
- package/build/timeline.js +104 -0
- package/build/timeline.js.map +1 -0
- package/build/tracker-reads-cli.js +4 -3
- package/build/tracker-reads-cli.js.map +1 -1
- package/build/trackers.js +56 -10
- package/build/trackers.js.map +1 -1
- package/build/train-cli.js +6 -5
- package/build/train-cli.js.map +1 -1
- package/build/train.js +2 -2
- package/build/train.js.map +1 -1
- package/build/upgrade.js +8 -9
- package/build/upgrade.js.map +1 -1
- package/build/wait.js +10 -10
- package/build/wait.js.map +1 -1
- package/build/watchers/ado.js +42 -19
- package/build/watchers/ado.js.map +1 -1
- package/build/watchers/github.js +18 -4
- package/build/watchers/github.js.map +1 -1
- package/build/watchers/index.js +2 -2
- package/build/watchers/index.js.map +1 -1
- package/build/watchers/linear-queue.js +47 -14
- package/build/watchers/linear-queue.js.map +1 -1
- package/build/watchers/linear-writes.js +26 -12
- package/build/watchers/linear-writes.js.map +1 -1
- package/build/watchers/linear.js +2 -2
- package/build/watchers/linear.js.map +1 -1
- package/build/watchers/source.js +5 -1
- package/build/watchers/source.js.map +1 -1
- package/build/webhook.js +80 -0
- package/build/webhook.js.map +1 -0
- package/build/why.js +1 -1
- package/build/why.js.map +1 -1
- package/build/worktrees.js +56 -93
- package/build/worktrees.js.map +1 -1
- package/package.json +61 -61
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/hooks/model.ts +55 -6
- package/plugin/hooks/register.tsx +43 -4
- package/plugin/skills/conductor-console/SKILL.md +26 -27
- package/plugin/skills/work-item/SKILL.md +58 -54
- package/plugin/skills/work-item/trackers/ado-boards.md +2 -2
- package/plugin/skills/work-item/trackers/github-issues.md +1 -1
- package/plugin/skills/work-item/trackers/linear.md +2 -2
- package/plugin/types/index.d.ts +1 -1
- package/protocol/PROTOCOL.md +3 -9
- package/build/checkout-sync.js +0 -249
- package/build/checkout-sync.js.map +0 -1
- package/build/credential.js +0 -66
- package/build/credential.js.map +0 -1
- package/build/startup.js +0 -92
- package/build/startup.js.map +0 -1
- package/build/tab.js +0 -32
- package/build/tab.js.map +0 -1
package/build/help.js
CHANGED
|
@@ -41,7 +41,7 @@ const WINDOW = [
|
|
|
41
41
|
'<when>',
|
|
42
42
|
'for --since or --until: now, today, yesterday, a span ago (30m, 24h, 7d), a date, or a date and time',
|
|
43
43
|
];
|
|
44
|
-
const WORKER = ['<worker>', 'its item (
|
|
44
|
+
const WORKER = ['<worker>', 'its item (ENG-309), its name (probe-ENG-309) or #<id>'];
|
|
45
45
|
const REPORT_OPTIONS = [
|
|
46
46
|
['--json', 'print the report as JSON'],
|
|
47
47
|
['--project <name>', 'one project only'],
|
|
@@ -51,12 +51,12 @@ const REPORT_OPTIONS = [
|
|
|
51
51
|
export const COMMANDS = [
|
|
52
52
|
{
|
|
53
53
|
arguments: [
|
|
54
|
-
['<item>', "the item (
|
|
54
|
+
['<item>', "the item (ENG-312), or the inbox item's id as '#12' (quoted: a shell reads #12 as a comment)"],
|
|
55
55
|
],
|
|
56
56
|
description: ['Posts "approve" on the item as you and wakes its worker.'],
|
|
57
57
|
examples: [
|
|
58
|
-
["approve
|
|
59
|
-
['the same, with a word for the worker', 'approve
|
|
58
|
+
["approve ENG-312's plan", 'approve ENG-312'],
|
|
59
|
+
['the same, with a word for the worker', 'approve ENG-312 --text "skip the docs"'],
|
|
60
60
|
],
|
|
61
61
|
group: 'Inbox and approvals',
|
|
62
62
|
name: 'approve',
|
|
@@ -67,8 +67,12 @@ export const COMMANDS = [
|
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
69
|
arguments: [WORKER],
|
|
70
|
-
description: [
|
|
71
|
-
|
|
70
|
+
description: [
|
|
71
|
+
"Wakes a parked worker (with no event text) and opens its session in a tab, whatever config.json's workers.tab says: in the terminal workers.terminal names (Windows Terminal, iTerm or Terminal on macOS, tmux elsewhere).",
|
|
72
|
+
'A tmux tab is in a detached session, and the command prints how to attach to it. With no terminal to open, it prints the claude attach to run yourself.',
|
|
73
|
+
'A worker whose session has a claude attach running already (its tab is open) gets no second tab: the command says so. Once its tab closes, the daemon hands the worker back within about a minute.',
|
|
74
|
+
],
|
|
75
|
+
examples: [["open ENG-309's worker in a tab", 'attach ENG-309']],
|
|
72
76
|
group: 'Projects and workers',
|
|
73
77
|
name: 'attach',
|
|
74
78
|
seeAlso: ['launch', 'retire', 'status'],
|
|
@@ -81,10 +85,10 @@ export const COMMANDS = [
|
|
|
81
85
|
['<slug>', 'a few words for the branch, joined by dashes'],
|
|
82
86
|
],
|
|
83
87
|
description: [
|
|
84
|
-
"Renames the worktree's branch (worktree-
|
|
88
|
+
"Renames the worktree's branch (worktree-ENG-454) to <type>/<key>-<slug>, such as feat/eng-454-code-host-writes, with the item from the worktree's name (or --item).",
|
|
85
89
|
'Prints JSON. Runs here, with or without a conductor.',
|
|
86
90
|
],
|
|
87
|
-
examples: [['in the
|
|
91
|
+
examples: [['in the ENG-454 worktree: feat/eng-454-code-host-writes', 'branch feat code-host-writes']],
|
|
88
92
|
group: 'Used by work skills',
|
|
89
93
|
name: 'branch',
|
|
90
94
|
options: [ITEM],
|
|
@@ -93,7 +97,7 @@ export const COMMANDS = [
|
|
|
93
97
|
usage: ['branch <type> <slug> [--item <item>]'],
|
|
94
98
|
},
|
|
95
99
|
{
|
|
96
|
-
arguments: [['<item>', 'the item (
|
|
100
|
+
arguments: [['<item>', 'the item (ENG-312)']],
|
|
97
101
|
description: [
|
|
98
102
|
"The item's context for a worker's orient step, read by the conductor from the tracker (no MCP): title, status, project, Area and labels, blockers, the items it blocks and related items, its phase notes, the approve or revise: after the newest Plan, and the description.",
|
|
99
103
|
"Also the work skill's phase (orient, plan, awaiting-approval, implement, wait, land, done, abandoned, canceled), from the status, the notes and the PR; and the PR (its worker's, else the newest PR opened note's) as its code host has it, with its verdict.",
|
|
@@ -101,8 +105,8 @@ export const COMMANDS = [
|
|
|
101
105
|
"With no conductor, it is read here from this checkout's project, as its account.",
|
|
102
106
|
],
|
|
103
107
|
examples: [
|
|
104
|
-
['orient on
|
|
105
|
-
['check for an approval after a wake', 'brief
|
|
108
|
+
['orient on ENG-312', 'brief ENG-312'],
|
|
109
|
+
['check for an approval after a wake', 'brief ENG-312 --fresh'],
|
|
106
110
|
],
|
|
107
111
|
exitCodes: [
|
|
108
112
|
[
|
|
@@ -132,9 +136,7 @@ export const COMMANDS = [
|
|
|
132
136
|
"The clone stays out of the worktree's git status, and conduct retire checks it for unpushed work.",
|
|
133
137
|
'Prints JSON. Runs here.',
|
|
134
138
|
],
|
|
135
|
-
examples: [
|
|
136
|
-
['clone the registry for a skill fix', 'checkout EmergentSoftware/agentic-toolkit-registry fix lock-path'],
|
|
137
|
-
],
|
|
139
|
+
examples: [['clone the registry for a skill fix', 'checkout contoso/skills-registry fix lock-path']],
|
|
138
140
|
group: 'Used by work skills',
|
|
139
141
|
name: 'checkout',
|
|
140
142
|
options: [ITEM],
|
|
@@ -143,13 +145,13 @@ export const COMMANDS = [
|
|
|
143
145
|
usage: ['checkout <owner>/<repo> <type> <slug> [--item <item>]'],
|
|
144
146
|
},
|
|
145
147
|
{
|
|
146
|
-
arguments: [['<item>', 'the item (
|
|
148
|
+
arguments: [['<item>', 'the item (ENG-312)']],
|
|
147
149
|
description: [
|
|
148
150
|
"Every comment on the item, oldest first, with its whole text: when, who, and whether an approver wrote it. Read as conduct brief reads the item: by the conductor (no MCP), else here from this checkout's project, as its account.",
|
|
149
151
|
],
|
|
150
152
|
examples: [
|
|
151
|
-
['read
|
|
152
|
-
['what was said since the plan', 'comments
|
|
153
|
+
['read ENG-312 whole', 'comments ENG-312'],
|
|
154
|
+
['what was said since the plan', 'comments ENG-312 --since 2026-10-15T09:00Z'],
|
|
153
155
|
],
|
|
154
156
|
exitCodes: [[1, 'refused, or nothing was read, as for conduct brief: the message says why']],
|
|
155
157
|
group: 'Used by work skills',
|
|
@@ -165,9 +167,9 @@ export const COMMANDS = [
|
|
|
165
167
|
},
|
|
166
168
|
{
|
|
167
169
|
description: [
|
|
168
|
-
"Opens the console, the Claude session the conductor mod serves, in a
|
|
170
|
+
"Opens the console, the Claude session the conductor mod serves, in a tab in the conductor's own folder (~/.conductor/console): it belongs to no project, so it opens with none registered.",
|
|
169
171
|
'It starts with the conductor plugin (--plugin-dir ~/.conductor/plugin), which brings the mod and /conductor:conductor-console.',
|
|
170
|
-
|
|
172
|
+
'The tab opens in the terminal config.json\'s workers.terminal names: Windows Terminal (window "conductor"), iTerm or Terminal on macOS, or tmux elsewhere (session conductor: the command prints its tmux attach). It starts with this terminal\'s CONDUCTOR_HOME. With no terminal to open (no tmux), it refuses: the start is claimed by then, so run `conduct console --here --force`.',
|
|
171
173
|
'Also how to get it back after it closed: it keeps no state of its own.',
|
|
172
174
|
'One at a time: it refuses while a console is open, or started in the last minute and not yet following the events.',
|
|
173
175
|
],
|
|
@@ -249,8 +251,8 @@ export const COMMANDS = [
|
|
|
249
251
|
],
|
|
250
252
|
examples: [
|
|
251
253
|
[
|
|
252
|
-
'a follow-up in apps/
|
|
253
|
-
'file --title "
|
|
254
|
+
'a follow-up in apps/web that waits on ENG-480',
|
|
255
|
+
'file --title "web: color the status" --body-file follow-up.md --area apps/web --blocked-by ENG-480',
|
|
254
256
|
],
|
|
255
257
|
],
|
|
256
258
|
exitCodes: [[1, 'refused or failed'], LOST_LOGIN],
|
|
@@ -259,7 +261,7 @@ export const COMMANDS = [
|
|
|
259
261
|
options: [
|
|
260
262
|
[
|
|
261
263
|
'--area <area>',
|
|
262
|
-
"one of the tracker's Areas: a label of the Area group, a path below a board's root, or the name after a GitHub Issues area prefix",
|
|
264
|
+
"one of the tracker's Areas: a label of the Area group, a path below a board's root, or the name after a GitHub Issues area prefix; left out for a Linear team with no Area group (tracker.areaLabelGroup null)",
|
|
263
265
|
],
|
|
264
266
|
['--blocked-by <item>…', 'the items it waits on; repeated or comma-separated'],
|
|
265
267
|
['--body-file <file>', 'its description'],
|
|
@@ -275,7 +277,7 @@ export const COMMANDS = [
|
|
|
275
277
|
seeAlso: ['brief', 'note'],
|
|
276
278
|
summary: 'file a follow-up of the item, in Backlog with its Area',
|
|
277
279
|
usage: [
|
|
278
|
-
'file --title <title> --body-file <file> --area <area> [--related <item>…] [--blocked-by <item>…] [--human] [--waits-release] [--item <item>]',
|
|
280
|
+
'file --title <title> --body-file <file> [--area <area>] [--related <item>…] [--blocked-by <item>…] [--human] [--waits-release] [--item <item>]',
|
|
279
281
|
],
|
|
280
282
|
},
|
|
281
283
|
{
|
|
@@ -284,8 +286,8 @@ export const COMMANDS = [
|
|
|
284
286
|
"Sets the project's slots or ordering weight until <when>; with neither, its items go first (weight 100).",
|
|
285
287
|
],
|
|
286
288
|
examples: [
|
|
287
|
-
['work
|
|
288
|
-
['six slots for
|
|
289
|
+
['work web first until 17:00', 'focus web --until 17:00'],
|
|
290
|
+
['six slots for web until tomorrow', 'focus web --slots 6 --until tomorrow'],
|
|
289
291
|
],
|
|
290
292
|
group: 'Scheduling',
|
|
291
293
|
name: 'focus',
|
|
@@ -306,7 +308,7 @@ export const COMMANDS = [
|
|
|
306
308
|
],
|
|
307
309
|
examples: [
|
|
308
310
|
['the last 24 hours', 'history'],
|
|
309
|
-
['a week of
|
|
311
|
+
['a week of web', 'history 7d --project web'],
|
|
310
312
|
['the last 30 minutes', 'history --since 30m'],
|
|
311
313
|
],
|
|
312
314
|
group: 'Logs and reports',
|
|
@@ -327,28 +329,70 @@ export const COMMANDS = [
|
|
|
327
329
|
usage: ['inbox [--json]'],
|
|
328
330
|
},
|
|
329
331
|
{
|
|
332
|
+
arguments: [['<path>', 'a checkout of the repo; by default the one you are in']],
|
|
330
333
|
description: [
|
|
331
|
-
"
|
|
334
|
+
"Onboards the repo of a checkout. It detects what it can: the code host from origin (GitHub or Azure DevOps), CI as the code host's own, the base branch from origin/HEAD, setup from the lockfiles at the root, a verify-* skill in .claude/skills, and the item key the commits carry. It asks for the rest, each detected value the default.",
|
|
335
|
+
"It writes a starter profile to ~/.conductor/projects/<name>.json, or with --shared to the checkout's .claude/conductor.json, which counts once it is pushed. A profile file that is there is never overwritten, and a repo profile on origin/<base> that names the project means nothing is written. Then it runs project add and project check.",
|
|
336
|
+
"Run it again after each step it prints: trust the new clone with `claude` once, and with no verify skill, the conductor plugin's /conductor:create-verification-skill in the checkout (in `claude --plugin-dir <the plugin>`), committed and pushed. Each run goes on from what is done, so a run on a project that is set up only fetches and checks it.",
|
|
337
|
+
'Without --yes it asks in the terminal, and refuses with no terminal (Git Bash under mintty is none to node).',
|
|
338
|
+
],
|
|
339
|
+
examples: [
|
|
340
|
+
['onboard the repo of the checkout you are in, answering its questions', 'init'],
|
|
341
|
+
['the same with no questions, for a GitHub repo with GitHub Issues', 'init --yes --key PAR'],
|
|
342
|
+
['with a Linear team as the tracker', 'init --tracker linear --team ENG'],
|
|
343
|
+
['a profile the team shares, committed to the repo', 'init --shared'],
|
|
344
|
+
],
|
|
345
|
+
group: 'Projects and workers',
|
|
346
|
+
name: 'init',
|
|
347
|
+
options: [
|
|
348
|
+
['--name <name>', "the project's name; by default the repo's, or the one it was added under"],
|
|
349
|
+
['--base <branch>', 'the base branch; by default origin/HEAD'],
|
|
350
|
+
['--tracker <kind>', "github-issues, ado-boards or linear; by default the code host's own"],
|
|
351
|
+
['--key <KEY>', 'the item key on GitHub Issues or ADO Boards (PAR-12 is issue #12)'],
|
|
352
|
+
['--team <key>', 'the Linear team key, with --tracker linear'],
|
|
353
|
+
['--query <query>', 'the saved Boards query that is the queue, with ADO Boards'],
|
|
354
|
+
['--shared', "write the repo's .claude/conductor.json instead of the machine profile"],
|
|
355
|
+
['--yes', 'ask nothing: take what was detected, and refuse what is missing with its flag'],
|
|
356
|
+
],
|
|
357
|
+
seeAlso: ['project', 'profile', 'launch'],
|
|
358
|
+
summary: 'onboard a repo: a starter profile, then add and check it',
|
|
359
|
+
usage: [
|
|
360
|
+
'init [<path>] [--name <name>] [--base <branch>] [--tracker <kind>] [--key <KEY>] [--team <key>] [--query <query>] [--shared] [--yes]',
|
|
361
|
+
],
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
description: [
|
|
365
|
+
"Registers what runs conduct supervise at logon, which restarts the daemon if it dies, with this build. Run it from the main checkout: a worktree's build goes away.",
|
|
366
|
+
'Windows: a Task Scheduler task, "Conductor", which it registers without starting.',
|
|
367
|
+
'macOS: a launchd agent, ~/Library/LaunchAgents/software.detergent.conductor.plist, which it loads into your login session, and that starts it. Its output goes to ~/.conductor/logs/startup.log. Run it in a terminal on the Mac, not over ssh alone.',
|
|
368
|
+
'Linux: a systemd user unit, ~/.config/systemd/user/conductor.service, which it enables and starts. Its output goes to the journal (journalctl --user -u conductor). It starts at your login; on a machine nobody logs in to, loginctl enable-linger starts it at boot, and the command says so.',
|
|
369
|
+
"The agent and the unit keep this terminal's PATH, since a login gives them a short one with no claude or git: run it again after that changes.",
|
|
370
|
+
'On macOS and Linux, running it again restarts a daemon the agent or unit started, so the new one counts. A daemon started another way keeps running, and the one the startup starts beside it ends on its lock. --remove leaves a running daemon alone.',
|
|
332
371
|
],
|
|
333
372
|
examples: [['start the daemon at every logon', 'install-startup']],
|
|
334
373
|
group: 'Setup',
|
|
335
374
|
name: 'install-startup',
|
|
336
|
-
options: [['--remove', 'remove that
|
|
375
|
+
options: [['--remove', 'remove that task, agent or unit']],
|
|
337
376
|
seeAlso: ['supervise', 'start'],
|
|
338
|
-
summary: 'start the daemon at logon
|
|
377
|
+
summary: 'start the daemon at every logon',
|
|
339
378
|
usage: ['install-startup', 'install-startup --remove'],
|
|
340
379
|
},
|
|
341
380
|
{
|
|
342
381
|
arguments: [['<pr>', 'the PR number']],
|
|
343
382
|
description: [
|
|
344
|
-
"Sets the worker's PR up to land, then gives its first verdict. Safe to repeat. A brake already on the PR (a comment, a failed build, conflicts) is reported and nothing is armed. Otherwise it arms the host's own landing: on Azure DevOps a +10 vote (auto mode) and auto-complete with noFastForward; on GitHub, auto-merge with a merge commit (auto mode, where the repo allows it, refused with the reason where it doesn't). Then it posts the Landing note.",
|
|
383
|
+
"Sets the worker's PR up to land, then gives its first verdict. Safe to repeat, except with --requeue. A brake already on the PR (a comment, a failed build, conflicts) is reported and nothing is armed. Otherwise it arms the host's own landing: on Azure DevOps a +10 vote (auto mode) and auto-complete with noFastForward; on GitHub, auto-merge with a merge commit (auto mode, where the repo allows it, refused with the reason where it doesn't). Then it posts the Landing note.",
|
|
345
384
|
'A Landing note with auto-complete or auto-merge gone means someone cancelled it: auto-merge-cancelled, until --rearm. A PR ADO started completing in the last few minutes, which clears auto-complete, is waiting instead.',
|
|
346
385
|
'With a conductor, the daemon records the landing and keeps it armed while the worker waits (conduct wait pr <pr>): it queues an expired build again and restores a cleared vote.',
|
|
386
|
+
"--requeue <run> queues one of a build-failed PR's failed builds again, for a flake no change caused, then arms as above: on Azure Repos through its policy evaluation, on GitHub by re-running the failed jobs of the check's Actions run (a PR the item opened from a checkout; one a hook's publish opened has none, so land refuses it). It posts a closed Requeue note with the run, the build and the PR's head commit first, and refuses a second requeue of that build on that head, even for the new run: a second failure is fixed and pushed. Each build that failed on the head can be queued again once. It refuses while a comment waits for an answer, and a GitHub run with a job still running. Until the PR shows the new run, the verdict waits on the build instead of reporting the old failure, for 15 minutes at most. A GitHub re-run keeps the run's id, so a failed check of it that finished after the note is the new attempt's failure, reported at once.",
|
|
347
387
|
'Prints JSON with the verdict and "via".',
|
|
348
388
|
],
|
|
349
389
|
examples: [
|
|
350
390
|
['land PR 1850 by itself', 'land 1850 --mode auto --reason "S fix, no review paths"'],
|
|
351
391
|
['arm it again after a cancel', 'land 1850 --rearm --reason "the operator said go on"'],
|
|
392
|
+
[
|
|
393
|
+
'queue a flaky build again, once',
|
|
394
|
+
'land 1850 --requeue 8040 --reason "ENG-637: the known flake, no change caused it"',
|
|
395
|
+
],
|
|
352
396
|
],
|
|
353
397
|
exitCodes: [[1, 'refused'], LOST_LOGIN],
|
|
354
398
|
group: 'Used by work skills',
|
|
@@ -359,23 +403,30 @@ export const COMMANDS = [
|
|
|
359
403
|
'--mode auto|review',
|
|
360
404
|
"held to the profile's landing rules for the PR's files and the plan's tier: auto where they allow it, else refused; without it the rules pick",
|
|
361
405
|
],
|
|
362
|
-
[
|
|
406
|
+
[
|
|
407
|
+
'--reason <why>',
|
|
408
|
+
'why this mode, for the Landing note (required); with --requeue, why the build is queued again, for the Requeue note',
|
|
409
|
+
],
|
|
363
410
|
['--rearm', 'arm it again after someone cancelled it'],
|
|
364
411
|
PR_REPO,
|
|
412
|
+
['--requeue <run>', 'queue that failed build again first, once per build and head commit'],
|
|
365
413
|
['--tier S|M|L', "the plan's tier without a conductor; the daemon takes it from the item's Plan note"],
|
|
366
414
|
],
|
|
367
415
|
seeAlso: ['wait', 'pr', 'runs'],
|
|
368
416
|
summary: "arm the worker's PR to land, and its first verdict",
|
|
369
|
-
usage: [
|
|
417
|
+
usage: [
|
|
418
|
+
'land <pr> --reason <why> [--mode auto|review] [--rearm] [--requeue <run>] [--tier S|M|L] [--repo <repo>] [--item <item>]',
|
|
419
|
+
],
|
|
370
420
|
},
|
|
371
421
|
{
|
|
372
|
-
arguments: [['<item>', 'the item to work (
|
|
422
|
+
arguments: [['<item>', 'the item to work (ENG-312)']],
|
|
373
423
|
description: [
|
|
374
|
-
"Starts a worker on the item: its worktree, a background session running the project's work skill
|
|
424
|
+
"Starts a worker on the item: its worktree, and a background session running the project's work skill.",
|
|
425
|
+
"Workers run headless. With config.json's workers.tab, each launch also opens a tab attached to the session (as conduct attach does); a tab that fails to open never fails the launch.",
|
|
375
426
|
],
|
|
376
427
|
examples: [
|
|
377
|
-
['start a worker on
|
|
378
|
-
['a probe with its own prompt', 'launch
|
|
428
|
+
['start a worker on ENG-312', 'launch ENG-312'],
|
|
429
|
+
['a probe with its own prompt', 'launch ENG-312 --probe --prompt "time the test suite"'],
|
|
379
430
|
],
|
|
380
431
|
group: 'Projects and workers',
|
|
381
432
|
name: 'launch',
|
|
@@ -386,7 +437,7 @@ export const COMMANDS = [
|
|
|
386
437
|
['--prompt <text>', "the session's first prompt instead of the work skill (or the probe prompt)"],
|
|
387
438
|
],
|
|
388
439
|
seeAlso: ['attach', 'retire', 'status'],
|
|
389
|
-
summary: 'start a worker: its worktree
|
|
440
|
+
summary: 'start a worker: its worktree and a background session',
|
|
390
441
|
usage: ['launch <item> [--project <name>] [--probe] [--prompt <text>] [--conductor <name>]'],
|
|
391
442
|
},
|
|
392
443
|
{
|
|
@@ -413,7 +464,10 @@ export const COMMANDS = [
|
|
|
413
464
|
group: 'Used by work skills',
|
|
414
465
|
name: 'lock',
|
|
415
466
|
options: [
|
|
416
|
-
[
|
|
467
|
+
[
|
|
468
|
+
'--owner <id>',
|
|
469
|
+
"who holds it; this checkout's worker's item by default, else the item key in the worktree's name or branch",
|
|
470
|
+
],
|
|
417
471
|
['--wait <minutes>', 'poll for the lock for up to that many minutes'],
|
|
418
472
|
],
|
|
419
473
|
seeAlso: ['ports', 'status'],
|
|
@@ -438,7 +492,7 @@ export const COMMANDS = [
|
|
|
438
492
|
},
|
|
439
493
|
{
|
|
440
494
|
arguments: [
|
|
441
|
-
['<item>', 'the item (
|
|
495
|
+
['<item>', 'the item (ENG-312)'],
|
|
442
496
|
['<file>', 'the note, its heading first'],
|
|
443
497
|
],
|
|
444
498
|
description: [
|
|
@@ -447,7 +501,7 @@ export const COMMANDS = [
|
|
|
447
501
|
"With no conductor, it is posted from this checkout as its project's account, and the item moves the same way.",
|
|
448
502
|
`The note must keep worker protocol ${PROTOCOL} (protocol/PROTOCOL.md in the package): a known phase (${PHASES.join(', ')}), a Handoff with a kind and one line (${HANDOFF_KINDS.join(', ')}), no kind on a phase that carries none, and a Plan with its **Size tier** and **Landing:** lines. One that breaks it is refused, with the rule, before anything is posted.`,
|
|
449
503
|
],
|
|
450
|
-
examples: [['post the Plan note', 'note
|
|
504
|
+
examples: [['post the Plan note', 'note ENG-312 plan.md']],
|
|
451
505
|
exitCodes: [
|
|
452
506
|
[
|
|
453
507
|
1,
|
|
@@ -466,14 +520,14 @@ export const COMMANDS = [
|
|
|
466
520
|
usage: ['note <item> <file> [--worker <worker>]'],
|
|
467
521
|
},
|
|
468
522
|
{
|
|
469
|
-
arguments: [['<item>', 'the item (
|
|
523
|
+
arguments: [['<item>', 'the item (ENG-312)']],
|
|
470
524
|
description: [
|
|
471
525
|
"The item's phase notes with their whole text, oldest first: what conduct brief lists as one line each. --phase and --kind keep the ones that match, and --last the newest of those, such as the Handoff an escalation is about.",
|
|
472
526
|
"Read as conduct brief reads the item: by the conductor (no MCP), else here from this checkout's project, as its account.",
|
|
473
527
|
],
|
|
474
528
|
examples: [
|
|
475
|
-
['every note on
|
|
476
|
-
['the newest conductor Handoff', 'notes
|
|
529
|
+
['every note on ENG-312', 'notes ENG-312'],
|
|
530
|
+
['the newest conductor Handoff', 'notes ENG-312 --phase Handoff --kind conductor --last'],
|
|
477
531
|
],
|
|
478
532
|
exitCodes: [[1, 'refused, or nothing was read, as for conduct brief: the message says why']],
|
|
479
533
|
group: 'Used by work skills',
|
|
@@ -509,7 +563,7 @@ export const COMMANDS = [
|
|
|
509
563
|
group: 'Inbox and approvals',
|
|
510
564
|
name: 'notify',
|
|
511
565
|
options: [
|
|
512
|
-
['--channel remote-control|pushover', 'with test: push on that channel'],
|
|
566
|
+
['--channel remote-control|pushover|webhook', 'with test: push on that channel'],
|
|
513
567
|
['--json', 'print the state as JSON'],
|
|
514
568
|
['--kind <kind>', 'with test: the kind of item (npm-otp by default)'],
|
|
515
569
|
['--raise', 'with test: put a real item in the inbox instead; it takes no --channel'],
|
|
@@ -520,7 +574,7 @@ export const COMMANDS = [
|
|
|
520
574
|
usage: [
|
|
521
575
|
'notify [--json]',
|
|
522
576
|
'notify profile [<name>] [--until <when>]',
|
|
523
|
-
'notify test [--kind <kind>] [--channel remote-control|pushover] [--raise]',
|
|
577
|
+
'notify test [--kind <kind>] [--channel remote-control|pushover|webhook] [--raise]',
|
|
524
578
|
],
|
|
525
579
|
},
|
|
526
580
|
{
|
|
@@ -528,7 +582,7 @@ export const COMMANDS = [
|
|
|
528
582
|
description: ['No new launches in the project, or in every project without one, until <when> or conduct unpause.'],
|
|
529
583
|
examples: [
|
|
530
584
|
['pause every project until tomorrow', 'pause --until tomorrow'],
|
|
531
|
-
['pause
|
|
585
|
+
['pause web until you unpause it', 'pause web'],
|
|
532
586
|
],
|
|
533
587
|
group: 'Scheduling',
|
|
534
588
|
name: 'pause',
|
|
@@ -557,27 +611,40 @@ export const COMMANDS = [
|
|
|
557
611
|
},
|
|
558
612
|
{
|
|
559
613
|
commands: [
|
|
614
|
+
[
|
|
615
|
+
'abandon <pr>',
|
|
616
|
+
"close the worker's PR unmerged (Azure DevOps abandons it), then post a closed `<skill> · Abandoned` note on it with --reason. Only the item's PR: its title and head branch carry the item key, and it is from the branch the checkout is on now (--force: from another branch of the item). A merged PR is refused; one closed already only gets the note if it lacks one, so it is safe to repeat",
|
|
617
|
+
],
|
|
560
618
|
[
|
|
561
619
|
'create',
|
|
562
620
|
"check the title carries the item key, the branch carries it too, the description fits the host, no PR is open from the branch, nothing is uncommitted, the branch is ahead of its base, and commitlint passes, all before anything is pushed. Then push and open the PR into the base branch (--repo: into the other repo's default branch, from its checkout)",
|
|
563
621
|
],
|
|
622
|
+
[
|
|
623
|
+
'status <pr>',
|
|
624
|
+
"any PR's verdict, as land gives the worker's own: merged (with its mergeCommit, and noFastForward: whether that commit has two parents), build-failed, conflicts, changes-requested, review-comment, abandoned or waiting. It needs no checkout and checks no ownership, and arms nothing, so it reads a PR the item didn't open, such as one a skill publish opened in another repo. A read, so it runs here",
|
|
625
|
+
],
|
|
564
626
|
[
|
|
565
627
|
'threads <pr>',
|
|
566
628
|
"the PR's threads (on GitHub each comment and review), each with needsAnswer: a person's, open, with no note after it, and asking for something. A read, so it runs here",
|
|
567
629
|
],
|
|
568
630
|
],
|
|
569
631
|
description: [
|
|
570
|
-
"Opens the worker's PR, checked and pushed, or
|
|
632
|
+
"Opens the worker's PR, checked and pushed, reads any PR's verdict or the worker's PR's threads, or abandons it.",
|
|
571
633
|
"The description ends with the tracker's reference when it has one (AB#<id> for an ADO Boards item on a GitHub PR, so the Boards GitHub app links it), counted in its length.",
|
|
572
|
-
'With a conductor, the daemon opens it for the worker that owns this checkout, checking the ownership again, and records the PR on the worker. Without one (or an older one) it
|
|
634
|
+
'With a conductor, the daemon opens or abandons it for the worker that owns this checkout, checking the ownership again, and records the PR on the worker. Without one (or an older one) it does it here.',
|
|
573
635
|
'Prints JSON with "via": "daemon" or "local".',
|
|
574
636
|
],
|
|
575
637
|
examples: [
|
|
576
638
|
[
|
|
577
639
|
'check everything, push nothing',
|
|
578
|
-
'pr create --title "feat(
|
|
640
|
+
'pr create --title "feat(web): help sections (ENG-478)" --body-file pr.md --dry-run',
|
|
579
641
|
],
|
|
580
642
|
["PR 1850's threads", 'pr threads 1850'],
|
|
643
|
+
[
|
|
644
|
+
'a registry PR a skill publish opened: its verdict, and once merged its merge commit for conduct runs',
|
|
645
|
+
'pr status 560 --repo github:EmergentSoftware/agentic-toolkit-registry',
|
|
646
|
+
],
|
|
647
|
+
['drop PR 1850, which another PR made redundant', 'pr abandon 1850 --reason "ENG-412\'s PR merged the same fix"'],
|
|
581
648
|
],
|
|
582
649
|
exitCodes: [[1, 'refused or failed'], LOST_LOGIN],
|
|
583
650
|
group: 'Used by work skills',
|
|
@@ -585,53 +652,83 @@ export const COMMANDS = [
|
|
|
585
652
|
options: [
|
|
586
653
|
['--body-file <file>', 'with create: its description'],
|
|
587
654
|
['--dry-run', 'with create: stop before the push'],
|
|
655
|
+
['--force', "with abandon: the item's PR from a branch the checkout isn't on"],
|
|
588
656
|
ITEM,
|
|
657
|
+
['--reason <why>', 'with abandon: why, in its note'],
|
|
589
658
|
PR_REPO,
|
|
590
659
|
['--title <title>', 'with create: its title, with the item key'],
|
|
591
660
|
],
|
|
592
661
|
seeAlso: ['land', 'reply', 'state'],
|
|
593
|
-
summary: "open the worker's PR
|
|
662
|
+
summary: "open or abandon the worker's PR; read a PR's verdict",
|
|
594
663
|
usage: [
|
|
664
|
+
'pr abandon <pr> --reason <why> [--repo <repo>] [--item <item>] [--force]',
|
|
595
665
|
'pr create --title <title> --body-file <file> [--repo <repo>] [--item <item>] [--dry-run]',
|
|
666
|
+
'pr status <pr> [--repo <repo>]',
|
|
596
667
|
'pr threads <pr> [--repo <repo>]',
|
|
597
668
|
],
|
|
598
669
|
},
|
|
670
|
+
{
|
|
671
|
+
arguments: [['<project>', 'a project added with conduct project add']],
|
|
672
|
+
description: [
|
|
673
|
+
"A project's profile as the conductor reads it: its machine profile (~/.conductor/projects/<project>.json) over the repo's .claude/conductor.json at origin/<base> in its clone, when there is one.",
|
|
674
|
+
"Objects merge key by key and the machine's wins; arrays are replaced whole; rules stack, the machine's first, so a machine rule shadows a repo rule with its id. Each field says whether it came from the machine, the repo or a default.",
|
|
675
|
+
'Read here from the files and the clone as fetched last, with or without the daemon.',
|
|
676
|
+
],
|
|
677
|
+
examples: [
|
|
678
|
+
["web's profile and where each field came from", 'profile web'],
|
|
679
|
+
['the same as JSON', 'profile web --json'],
|
|
680
|
+
],
|
|
681
|
+
exitCodes: [[1, 'no clone of the project, or its profile is invalid (the message names the files)']],
|
|
682
|
+
group: 'Projects and workers',
|
|
683
|
+
name: 'profile',
|
|
684
|
+
options: [['--json', 'print the profile and its sources as JSON']],
|
|
685
|
+
seeAlso: ['project', 'rules'],
|
|
686
|
+
summary: "a project's profile, each field with its source",
|
|
687
|
+
usage: ['profile <project> [--json]'],
|
|
688
|
+
},
|
|
599
689
|
{
|
|
600
690
|
commands: [
|
|
601
|
-
[
|
|
691
|
+
[
|
|
692
|
+
'add <url | path>',
|
|
693
|
+
"clone the project's remote into ~/.conductor/projects/<name>/repo and register it. A path names a checkout whose origin is cloned: the folder itself is never cloned or touched again. The name is the one the repo's .claude/conductor.json gives, or --name. Adding a project again fetches its clone and updates the registration in place, and moves a project registered by its checkout to a clone. Works without the daemon",
|
|
694
|
+
],
|
|
602
695
|
['list [--json]', 'the registered projects'],
|
|
603
696
|
[
|
|
604
697
|
'remove <name>',
|
|
605
|
-
|
|
698
|
+
'drop a registration: a project no longer conducted. Resolves its open inbox items; refused while it has workers in flight. Its clone and machine profile stay. Works without the daemon',
|
|
606
699
|
],
|
|
607
700
|
[
|
|
608
701
|
'check <name>',
|
|
609
|
-
'whether the project can be conducted, before its first launch finds out: its profile (
|
|
702
|
+
'whether the project can be conducted, before its first launch finds out: its profile (what differs from the stored copy, and fields newer than its conductor minimum), tracker, code host and base branch, release pipelines, a throwaway worktree made from the clone and removed, with its skills and Claude Code trust, the plugin skills, free ports and its health URLs. One ok, warn, fail or skip line each, with the fix',
|
|
610
703
|
],
|
|
611
704
|
],
|
|
612
705
|
description: [
|
|
613
706
|
'Registers a project, lists the registered ones, removes one, or checks one.',
|
|
614
|
-
'
|
|
615
|
-
'
|
|
707
|
+
'A project is a clone the conductor owns: its worktrees are made there (~/.conductor/projects/<name>/worktrees), never in a checkout of yours. The daemon fetches the clone every clones.fetchMinutes and takes the profile again when its .claude/conductor.json on the base branch changes, or when the machine profile (~/.conductor/projects/<name>.json) is saved. `conduct profile <name>` shows how the two merge.',
|
|
708
|
+
'Claude Code trusts a worktree by its repository: run `claude` in a new clone once and accept the trust prompt before its first launch.',
|
|
616
709
|
"check goes through the daemon, as its accounts, or runs here as the machine's when it isn't running. Only the worktree check writes, and it removes what it made.",
|
|
617
710
|
],
|
|
618
711
|
examples: [
|
|
619
|
-
['
|
|
712
|
+
['conduct the repo of the checkout you are in', 'project add .'],
|
|
713
|
+
[
|
|
714
|
+
'conduct a repo by its URL, under a name of your own',
|
|
715
|
+
'project add https://github.com/owner/repo.git --name mine',
|
|
716
|
+
],
|
|
620
717
|
['the registered projects', 'project list'],
|
|
621
|
-
['
|
|
622
|
-
['
|
|
623
|
-
['the same without the worktree (its hook runs pnpm install)', 'project check atk --no-worktree'],
|
|
718
|
+
['check web before conducting it', 'project check web'],
|
|
719
|
+
['the same without the worktree (its setup runs pnpm install)', 'project check web --no-worktree'],
|
|
624
720
|
],
|
|
625
721
|
group: 'Projects and workers',
|
|
626
722
|
name: 'project',
|
|
627
723
|
options: [
|
|
628
724
|
['--json', 'with list or check: print them as JSON'],
|
|
725
|
+
['--name <name>', "with add: the project's name, when the repo's profile gives none or another"],
|
|
629
726
|
['--no-worktree', 'with check: skip the throwaway worktree'],
|
|
630
727
|
],
|
|
631
|
-
seeAlso: ['launch', 'ports', 'status'],
|
|
728
|
+
seeAlso: ['init', 'profile', 'launch', 'ports', 'status'],
|
|
632
729
|
summary: 'register a project, or list, remove or check them',
|
|
633
730
|
usage: [
|
|
634
|
-
'project add <path>',
|
|
731
|
+
'project add <url | path> [--name <name>]',
|
|
635
732
|
'project list [--json]',
|
|
636
733
|
'project remove <name>',
|
|
637
734
|
'project check <name> [--no-worktree] [--json]',
|
|
@@ -674,9 +771,9 @@ export const COMMANDS = [
|
|
|
674
771
|
{
|
|
675
772
|
arguments: [WORKER],
|
|
676
773
|
description: [
|
|
677
|
-
"Stops the worker's session and removes its worktree. It refuses while the worker's turn runs or its worktree has unfinished work (uncommitted or unpushed).",
|
|
774
|
+
"Stops the worker's session and removes its worktree. It refuses while the worker's turn runs, while it is attached (open in a tab), or while its worktree has unfinished work (uncommitted or unpushed).",
|
|
678
775
|
],
|
|
679
|
-
examples: [['retire
|
|
776
|
+
examples: [['retire ENG-309 once it is done', 'retire ENG-309']],
|
|
680
777
|
group: 'Projects and workers',
|
|
681
778
|
name: 'retire',
|
|
682
779
|
options: [['--force', 'retire it anyway and throw that work away']],
|
|
@@ -689,7 +786,7 @@ export const COMMANDS = [
|
|
|
689
786
|
description: ['The same report as conduct history, as Markdown.', 'Give a <range> or --since/--until, not both.'],
|
|
690
787
|
examples: [
|
|
691
788
|
["yesterday's retro", 'retro yesterday'],
|
|
692
|
-
['a week of
|
|
789
|
+
['a week of web, to a file', 'retro 7d --project web > retro.md'],
|
|
693
790
|
],
|
|
694
791
|
group: 'Logs and reports',
|
|
695
792
|
name: 'retro',
|
|
@@ -700,13 +797,14 @@ export const COMMANDS = [
|
|
|
700
797
|
},
|
|
701
798
|
{
|
|
702
799
|
arguments: [
|
|
703
|
-
['<item>', "the item (
|
|
800
|
+
['<item>', "the item (ENG-312), or the inbox item's id as '#12' (quoted: a shell reads #12 as a comment)"],
|
|
704
801
|
['<text>', 'what to change in the plan'],
|
|
705
802
|
],
|
|
706
803
|
description: [
|
|
707
804
|
'Posts "revise: <text>" on the item as you and wakes its worker. Every word after <item> is the text, quoted or not.',
|
|
805
|
+
"With no plan of the item in the inbox, it revises the item's approved plan: the conductor posts the revise, wakes its parked worker to re-plan (not once its PR has merged), and holds back the worker's next note until it does.",
|
|
708
806
|
],
|
|
709
|
-
examples: [['ask for a smaller plan', 'revise
|
|
807
|
+
examples: [['ask for a smaller plan', 'revise ENG-312 put the web change in a PR of its own']],
|
|
710
808
|
group: 'Inbox and approvals',
|
|
711
809
|
name: 'revise',
|
|
712
810
|
seeAlso: ['approve', 'inbox'],
|
|
@@ -726,7 +824,7 @@ export const COMMANDS = [
|
|
|
726
824
|
],
|
|
727
825
|
description: [
|
|
728
826
|
'The rules in force, and a dry run of them on a sample. A sample for rules test:',
|
|
729
|
-
{ pre: ['{ "event": "pr.comment", "project": "
|
|
827
|
+
{ pre: ['{ "event": "pr.comment", "project": "web",', ' "fields": { "wait.kind": "merge" } }'] },
|
|
730
828
|
],
|
|
731
829
|
examples: [
|
|
732
830
|
['the rules in force', 'rules'],
|
|
@@ -744,14 +842,24 @@ export const COMMANDS = [
|
|
|
744
842
|
description: [
|
|
745
843
|
"One look at a merge's runs: on Azure Pipelines for the project's Azure DevOps repo (the pipelines whose YAML trigger the merge fires, read in this worktree), on GitHub Actions for a GitHub repo (the runs the merge's push started). The outcome is succeeded, failed, cancelled, waiting-for-approval, missing, none (nothing ran: at once on Azure Pipelines, after 5 minutes on GitHub) or waiting (look again, or conduct wait merge).",
|
|
746
844
|
"Each failed run comes with its failed tasks and the end of its log (logs). For the project's repo, each of the profile's releases whose run succeeded gives what it staged (stages): package, version, stageId, the npm stage approve line, and whether npm has it (published).",
|
|
747
|
-
"On Azure Pipelines a cancelled run (a newer push's batch, or a person) gives way to a later run on the base whose commit contains the merge: that run is the merge's, with supersedes naming the cancelled one. So cancelled means no newer run carries the merge, and the note gives the --requeue line.",
|
|
748
|
-
"
|
|
845
|
+
"On Azure Pipelines a cancelled run (a newer push's batch, or a person) gives way to a later run on the base whose commit contains the merge: that run is the merge's, with supersedes naming the cancelled one (or the failed one, for a run queued again for a failure: retryOf). So cancelled means no newer run carries the merge, and the note gives the --requeue line.",
|
|
846
|
+
"A batched pipeline (batch: true) holds the merge's push while its run on the base still goes, so a merge with no run yet waits as long as that run does and 2 minutes after (behind names it), not 15 minutes. Missing means no run, and none ahead of its batch, 15 minutes after the merge; the note gives the --requeue line.",
|
|
847
|
+
"--requeue <pipeline> queues that pipeline on the base at its tip, for the item's own merge (its branch's PR merged as <sha>) when its run was cancelled and no newer run carries it, when it failed, or when it is missing; it refuses a run that is waiting, running or succeeded, a batch still behind a run, a pipeline the merge didn't trigger, a cancelled or missing run under 15 minutes after the merge (Azure DevOps can still list a newer run). By the daemon for the worker that owns this checkout, else here. conduct wait merge <sha> then follows the new run.",
|
|
848
|
+
"On GitHub Actions (the project's repo, or one the item checked out under .scratch/repos, with --repo) --requeue re-runs the merge's run itself, at its own commit: the failed jobs of a failed run, all of a cancelled one. The run keeps its id, and conduct wait merge <sha> --repo <repo> follows its new attempt. It re-runs a run once (GitHub's run_attempt above 1 is refused), only while the run is its workflow's newest run on the base the PR merged into, of any event (re-running an older one would build an older commit after a newer one), and never a missing run, which has nothing to re-run.",
|
|
849
|
+
"A failed run is queued again once, for a flake its log shows that no change caused (a timeout in a test nothing touched, an agent or network error; not another merge's real failure); the note gives the line. A run queued by hand after the failed one stands in for it and names it (retryOf), so a second --requeue, of a run queued again that failed too, is refused. A newer push's run never stands in for a failed one.",
|
|
850
|
+
"--grep <pattern> searches every task log of the --for pipelines' runs, whatever their result, for a JavaScript regular expression (case-sensitive). grep.runs gives, for each run, the matching lines by stage and task (matches, at most 200 a task) and every task it searched with its line count (searched), so no match shows the run never printed it. A pipeline with no run, a run not finished or waiting on an approval, and a log that can't be read each say so in a note.",
|
|
749
851
|
'Prints JSON. A read, so it runs here, except with --requeue.',
|
|
750
852
|
],
|
|
751
853
|
examples: [
|
|
752
854
|
['the runs of the merge a1b2c3d', 'runs a1b2c3d'],
|
|
753
855
|
['its API deploy alone', 'runs a1b2c3d --for deploy-api'],
|
|
856
|
+
['what its API deploy printed about deploying', 'runs a1b2c3d --for deploy-api --grep Deploying'],
|
|
754
857
|
['queue its cancelled conductor release again', 'runs a1b2c3d --requeue release-conductor'],
|
|
858
|
+
['queue its CLI release again once, after a flaky test failed it', 'runs a1b2c3d --requeue release-cli'],
|
|
859
|
+
[
|
|
860
|
+
"re-run the registry merge's failed Build Registry once",
|
|
861
|
+
'runs 9ad075d --requeue build-registry --repo github:contoso/skills-registry',
|
|
862
|
+
],
|
|
755
863
|
],
|
|
756
864
|
exitCodes: [[1, 'refused or failed'], LOST_LOGIN],
|
|
757
865
|
group: 'Used by work skills',
|
|
@@ -765,12 +873,20 @@ export const COMMANDS = [
|
|
|
765
873
|
'--repo <repo>',
|
|
766
874
|
"github:<owner>/<repo> for another repo, such as the registry; the profile's code host by default",
|
|
767
875
|
],
|
|
768
|
-
['--
|
|
876
|
+
['--grep <pattern>', "with --for: the lines of those runs' logs that match, by task, whatever the run's result"],
|
|
877
|
+
[
|
|
878
|
+
'--requeue <pipeline>',
|
|
879
|
+
"queue the merge's cancelled, failed (once) or missing run of this pipeline; on GitHub Actions, re-run its failed or cancelled run once",
|
|
880
|
+
],
|
|
769
881
|
['--item <KEY-n>', "with --requeue: the item whose merge it is, when the worktree's name has no key"],
|
|
770
882
|
],
|
|
771
|
-
seeAlso: ['wait', 'land'],
|
|
883
|
+
seeAlso: ['wait', 'land', 'timeline'],
|
|
772
884
|
summary: "a merge's runs, their verdict, failed logs and npm stages",
|
|
773
|
-
usage: [
|
|
885
|
+
usage: [
|
|
886
|
+
'runs <sha> [--for <pipeline>[,<pipeline>…]] [--repo <repo>]',
|
|
887
|
+
'runs <sha> --for <pipeline>[,<pipeline>…] --grep <pattern> [--repo <repo>]',
|
|
888
|
+
'runs <sha> --requeue <pipeline> [--repo <repo>]',
|
|
889
|
+
],
|
|
774
890
|
},
|
|
775
891
|
{
|
|
776
892
|
arguments: [['<terms…>', 'the words to look for; an item matches only with every one']],
|
|
@@ -798,7 +914,7 @@ export const COMMANDS = [
|
|
|
798
914
|
},
|
|
799
915
|
{
|
|
800
916
|
description: [
|
|
801
|
-
|
|
917
|
+
"Starts the logon startup (install-startup's task, agent or unit) when it runs this build, else a detached conduct supervise --fail-fast, and waits until the daemon answers. Does nothing when one runs already.",
|
|
802
918
|
],
|
|
803
919
|
examples: [['start the daemon', 'start']],
|
|
804
920
|
group: 'Daemon',
|
|
@@ -814,7 +930,7 @@ export const COMMANDS = [
|
|
|
814
930
|
],
|
|
815
931
|
examples: [
|
|
816
932
|
['where this worktree stands', 'state'],
|
|
817
|
-
['the registry checkout alone', 'state --repo
|
|
933
|
+
['the registry checkout alone', 'state --repo contoso/skills-registry'],
|
|
818
934
|
],
|
|
819
935
|
exitCodes: [LOST_LOGIN],
|
|
820
936
|
group: 'Used by work skills',
|
|
@@ -849,9 +965,9 @@ export const COMMANDS = [
|
|
|
849
965
|
},
|
|
850
966
|
{
|
|
851
967
|
description: [
|
|
852
|
-
'Runs conduct serve and starts it again when it dies (a crash, a kill, a start that fails), after 1 s, 5 s, 15 s, 30 s, then every minute, and every 5 minutes once it has pushed. A daemon down 2 minutes sends one Pushover push, held through quiet hours. A stop (conduct stop, upgrade, Ctrl+C), or another daemon holding the lock, ends it. The logon
|
|
968
|
+
'Runs conduct serve and starts it again when it dies (a crash, a kill, a start that fails), after 1 s, 5 s, 15 s, 30 s, then every minute, and every 5 minutes once it has pushed. A daemon down 2 minutes sends one Pushover push, held through quiet hours. A stop (conduct stop, upgrade, Ctrl+C), or another daemon holding the lock, ends it. The logon startup (install-startup) runs it.',
|
|
853
969
|
],
|
|
854
|
-
examples: [['what the logon
|
|
970
|
+
examples: [['what the logon startup runs', 'supervise']],
|
|
855
971
|
group: 'Daemon',
|
|
856
972
|
name: 'supervise',
|
|
857
973
|
options: [['--fail-fast', 'end when the first serve exits before it comes up, as conduct start runs it']],
|
|
@@ -859,6 +975,49 @@ export const COMMANDS = [
|
|
|
859
975
|
summary: 'run the daemon and restart it when it dies',
|
|
860
976
|
usage: ['supervise [--fail-fast]'],
|
|
861
977
|
},
|
|
978
|
+
{
|
|
979
|
+
arguments: [['<run>', 'a run id (an Azure Pipelines build, a GitHub Actions run)']],
|
|
980
|
+
description: [
|
|
981
|
+
"A run's tasks and when each ran: on Azure Pipelines each timeline task under its stage and job, on GitHub Actions each step under its job, in the order they started, with started, finished and seconds (null until a task has both times), and the host's own state and result. The run itself has the same times.",
|
|
982
|
+
"--for <pipeline> reads the last finished runs of one pipeline on a branch instead (the profile's base by default, 3 runs, at most 20), newest first, so a step can be measured across runs without their merge commits.",
|
|
983
|
+
"--task <regex> keeps the tasks whose name matches (a JavaScript regular expression, not case-sensitive), so Cache Next build also matches its Post-job: Cache Next build save. --grep <regex> (case-sensitive, with --task) gives those tasks' log lines that match, as runs --grep does: the matches by task (at most 200 a task) and every task it searched with its line count. A run not finished, a --task that matches nothing (it lists the run's tasks) and a log that can't be read each say so in a note.",
|
|
984
|
+
'Prints JSON. A read, so it runs here.',
|
|
985
|
+
],
|
|
986
|
+
examples: [
|
|
987
|
+
['every task of build 8123 and how long it took', 'timeline 8123'],
|
|
988
|
+
[
|
|
989
|
+
'the Next cache and export steps of the last 3 web deploys on develop, with what they printed',
|
|
990
|
+
'timeline --for deploy-web --task "Cache Next build|Static export build" --grep "Cache restored|cache miss|Compiled successfully"',
|
|
991
|
+
],
|
|
992
|
+
[
|
|
993
|
+
"the registry's last 5 Build Registry runs on main",
|
|
994
|
+
'timeline --for build-registry --branch main --count 5 --repo github:contoso/skills-registry',
|
|
995
|
+
],
|
|
996
|
+
],
|
|
997
|
+
exitCodes: [[1, 'refused or failed'], LOST_LOGIN],
|
|
998
|
+
group: 'Used by work skills',
|
|
999
|
+
name: 'timeline',
|
|
1000
|
+
options: [
|
|
1001
|
+
[
|
|
1002
|
+
'--for <pipeline>',
|
|
1003
|
+
'one pipeline (YAML file name such as deploy-web, its path, or its name): its last finished runs',
|
|
1004
|
+
],
|
|
1005
|
+
['--branch <branch>', "with --for: the runs on this branch; the profile's base by default"],
|
|
1006
|
+
['--count <n>', 'with --for: how many runs, 1 to 20; 3 by default'],
|
|
1007
|
+
['--task <regex>', 'only the tasks whose name matches, not case-sensitive'],
|
|
1008
|
+
['--grep <regex>', "with --task: those tasks' log lines that match"],
|
|
1009
|
+
[
|
|
1010
|
+
'--repo <repo>',
|
|
1011
|
+
"github:<owner>/<repo> for another repo, such as the registry; the profile's code host by default",
|
|
1012
|
+
],
|
|
1013
|
+
],
|
|
1014
|
+
seeAlso: ['runs'],
|
|
1015
|
+
summary: "a run's tasks and their times; a pipeline's last runs",
|
|
1016
|
+
usage: [
|
|
1017
|
+
'timeline <run> [--task <regex>] [--grep <regex>] [--repo <repo>]',
|
|
1018
|
+
'timeline --for <pipeline> [--branch <branch>] [--count <n>] [--task <regex>] [--grep <regex>] [--repo <repo>]',
|
|
1019
|
+
],
|
|
1020
|
+
},
|
|
862
1021
|
{
|
|
863
1022
|
arguments: [['<project>', "a registered project; without it, the checkout you're in"]],
|
|
864
1023
|
description: [
|
|
@@ -867,7 +1026,7 @@ export const COMMANDS = [
|
|
|
867
1026
|
],
|
|
868
1027
|
examples: [
|
|
869
1028
|
['what a train would take and leave out', 'train --dry-run'],
|
|
870
|
-
["merge
|
|
1029
|
+
["merge web's waiting publishes", 'train web'],
|
|
871
1030
|
],
|
|
872
1031
|
group: 'Projects and workers',
|
|
873
1032
|
name: 'train',
|
|
@@ -883,7 +1042,7 @@ export const COMMANDS = [
|
|
|
883
1042
|
],
|
|
884
1043
|
examples: [
|
|
885
1044
|
['launch again everywhere', 'unpause'],
|
|
886
|
-
['launch again in
|
|
1045
|
+
['launch again in web', 'unpause web'],
|
|
887
1046
|
],
|
|
888
1047
|
group: 'Scheduling',
|
|
889
1048
|
name: 'unpause',
|
|
@@ -940,7 +1099,7 @@ export const COMMANDS = [
|
|
|
940
1099
|
"the project's login to the provider works again (projects.<name> in config.json says which account)",
|
|
941
1100
|
],
|
|
942
1101
|
['time <when>', 'such as 17:00 (the next one) or 2026-10-10T09:00 (local)'],
|
|
943
|
-
['<full form>', 'such as pr:ado:
|
|
1102
|
+
['<full form>', 'such as pr:ado:Contoso.Web#1850:merged'],
|
|
944
1103
|
],
|
|
945
1104
|
description: [
|
|
946
1105
|
"In a worker's worktree with the daemon running, registers the wait and exits 0 at once: end the turn, and the daemon resumes the session when the condition holds. Otherwise checks it here and blocks until it holds or --timeout passes.",
|
|
@@ -950,7 +1109,7 @@ export const COMMANDS = [
|
|
|
950
1109
|
['wait for PR 1850 to merge', 'wait pr 1850 merged'],
|
|
951
1110
|
["wait on PR 1850's merge, checks and comments at once", 'wait pr 1850 merged checks comment'],
|
|
952
1111
|
['wait for the plan approval', 'wait approval'],
|
|
953
|
-
['wait for a dev release on npm', 'wait npm 8.7.0-dev.8 --tag dev --package @
|
|
1112
|
+
['wait for a dev release on npm', 'wait npm 8.7.0-dev.8 --tag dev --package @contoso/cli'],
|
|
954
1113
|
],
|
|
955
1114
|
exitCodes: [
|
|
956
1115
|
[0, 'the condition holds, or the daemon registered the wait'],
|
|
@@ -979,12 +1138,12 @@ export const COMMANDS = [
|
|
|
979
1138
|
usage: ['wait <condition> [--local] [--timeout <minutes>] [--worker <worker>] [--item <item>]'],
|
|
980
1139
|
},
|
|
981
1140
|
{
|
|
982
|
-
arguments: [['<event id | item>', 'an event id (4200) or an item (
|
|
1141
|
+
arguments: [['<event id | item>', 'an event id (4200) or an item (ENG-312)']],
|
|
983
1142
|
description: [
|
|
984
1143
|
"With an event id, that event's rule and the events that led to it; with an item, the same for each of its newest actions.",
|
|
985
1144
|
],
|
|
986
1145
|
examples: [
|
|
987
|
-
['why the conductor acted on
|
|
1146
|
+
['why the conductor acted on ENG-312', 'why ENG-312'],
|
|
988
1147
|
['the rule behind event 4200', 'why 4200'],
|
|
989
1148
|
],
|
|
990
1149
|
group: 'Console and rules',
|
|
@@ -1003,7 +1162,7 @@ const HELP_ROWS = [
|
|
|
1003
1162
|
];
|
|
1004
1163
|
const FOOTER = [
|
|
1005
1164
|
'Run conduct help <command> for its options and examples.',
|
|
1006
|
-
'A <worker> is its item (
|
|
1165
|
+
'A <worker> is its item (ENG-309) or its name (probe-ENG-309).',
|
|
1007
1166
|
'Files live in ~/.conductor (CONDUCTOR_HOME overrides it).',
|
|
1008
1167
|
];
|
|
1009
1168
|
// A placeholder, `conduct <command>`, or a flag: what prose styles.
|