@detergent-software/conductor 2.2.0-dev.3 → 3.0.0-dev.10
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 +98 -0
- package/README.md +86 -37
- package/build/broker-cli.js +19 -21
- package/build/broker-cli.js.map +1 -1
- package/build/broker.js +66 -92
- package/build/broker.js.map +1 -1
- package/build/checkout-sync.js +4 -21
- package/build/checkout-sync.js.map +1 -1
- package/build/claude.js +56 -9
- package/build/claude.js.map +1 -1
- package/build/cli.js +43 -46
- package/build/cli.js.map +1 -1
- package/build/code-host.js +10 -8
- package/build/code-host.js.map +1 -1
- package/build/config.js +10 -0
- package/build/config.js.map +1 -1
- package/build/console.js +39 -29
- package/build/console.js.map +1 -1
- package/build/daemon.js +55 -6
- package/build/daemon.js.map +1 -1
- package/build/help.js +19 -33
- package/build/help.js.map +1 -1
- package/build/in-process.js +3 -3
- package/build/in-process.js.map +1 -1
- package/build/inbox.js +47 -4
- package/build/inbox.js.map +1 -1
- package/build/lib/providers/index.js +1 -1
- package/build/lib/providers/index.js.map +1 -1
- package/build/lib/providers/npm/stage.js +14 -4
- package/build/lib/providers/npm/stage.js.map +1 -1
- package/build/local-files.js +95 -0
- package/build/local-files.js.map +1 -0
- package/build/manager.js +215 -27
- package/build/manager.js.map +1 -1
- package/build/npm-reads.js +194 -0
- package/build/npm-reads.js.map +1 -0
- package/build/paths.js +2 -0
- package/build/paths.js.map +1 -1
- package/build/plugin.js +146 -0
- package/build/plugin.js.map +1 -0
- package/build/profile.js +60 -21
- package/build/profile.js.map +1 -1
- package/build/project-check-cli.js +4 -1
- package/build/project-check-cli.js.map +1 -1
- package/build/project-check.js +89 -30
- package/build/project-check.js.map +1 -1
- package/build/rules-service.js +22 -4
- package/build/rules-service.js.map +1 -1
- package/build/scheduler.js +11 -1
- package/build/scheduler.js.map +1 -1
- package/build/server.js +8 -16
- package/build/server.js.map +1 -1
- package/build/spend.js +4 -0
- package/build/spend.js.map +1 -1
- package/build/store.js +11 -10
- package/build/store.js.map +1 -1
- package/build/tracker-reads-cli.js +2 -4
- package/build/tracker-reads-cli.js.map +1 -1
- package/build/upgrade.js +25 -3
- package/build/upgrade.js.map +1 -1
- package/build/watchers/ado.js +3 -2
- package/build/watchers/ado.js.map +1 -1
- package/build/watchers/github.js +3 -2
- package/build/watchers/github.js.map +1 -1
- package/build/watchers/npm.js +6 -4
- package/build/watchers/npm.js.map +1 -1
- package/build/worktrees.js +182 -38
- package/build/worktrees.js.map +1 -1
- package/package.json +9 -9
- package/plugin/.claude-plugin/plugin.json +7 -0
- package/plugin/README.md +18 -0
- package/{mod → plugin}/hooks/model.ts +22 -4
- package/{mod → plugin}/hooks/register.tsx +63 -17
- package/plugin/skills/conductor-console/SKILL.md +94 -0
- package/plugin/skills/create-verification-skill/LICENSE +21 -0
- package/plugin/skills/create-verification-skill/README.md +9 -0
- package/plugin/skills/create-verification-skill/SKILL.md +44 -0
- package/plugin/skills/create-verification-skill/manifest.json +27 -0
- package/plugin/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
- package/plugin/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
- package/plugin/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
- package/plugin/skills/maintain-verification-skill/LICENSE +21 -0
- package/plugin/skills/maintain-verification-skill/README.md +9 -0
- package/plugin/skills/maintain-verification-skill/SKILL.md +39 -0
- package/plugin/skills/maintain-verification-skill/manifest.json +23 -0
- package/plugin/skills/work-item/SKILL.md +253 -0
- package/plugin/skills/work-item/trackers/ado-boards.md +23 -0
- package/plugin/skills/work-item/trackers/github-issues.md +23 -0
- package/plugin/skills/work-item/trackers/linear.md +21 -0
- package/protocol/PROTOCOL.md +1 -1
- package/build/mod.js +0 -53
- package/build/mod.js.map +0 -1
- package/mod/.claude-plugin/marketplace.json +0 -6
- package/mod/.claude-plugin/plugin.json +0 -7
- package/mod/README.md +0 -19
- /package/{mod → plugin}/hooks/hooks.json +0 -0
- /package/{mod → plugin}/types/index.d.ts +0 -0
package/build/worktrees.js
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { rm } from 'node:fs/promises';
|
|
3
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
import { realDirty, runGit, scratchClones } from "./checkout.js";
|
|
5
6
|
import { ConductorError } from "./errors.js";
|
|
7
|
+
import { copyLocalFiles } from "./local-files.js";
|
|
8
|
+
import { missingProjectSkills } from "./plugin.js";
|
|
6
9
|
import { outputOf, run } from "./run.js";
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
+
import { claudeSkillsDir } from "./spend.js";
|
|
11
|
+
export const BRANCH_PREFIX = 'worktree-';
|
|
12
|
+
// Each setup command's limit: ATK's `pnpm install` takes about a minute.
|
|
13
|
+
const SETUP_MS = 10 * 60_000;
|
|
14
|
+
// `atk audit` and `atk install`, for checkout-sync's skills check.
|
|
15
|
+
const ATK_MS = 5 * 60_000;
|
|
16
|
+
// How long a removal waits for a process to let go of the worktree before it gives up.
|
|
17
|
+
const RELEASE_MS = 15_000;
|
|
18
|
+
// A .trash-* folder older than this is an interrupted removal's, not one still deleting.
|
|
19
|
+
const STALE_TRASH_MS = 60 * 60_000;
|
|
10
20
|
const LOCKFILE = '.atk-lock.json';
|
|
11
|
-
export
|
|
12
|
-
return join(root, '.claude', 'hooks', 'worktree-hooks.mjs');
|
|
13
|
-
}
|
|
21
|
+
export const SESSION_SETTINGS = join('.claude', 'settings.local.json');
|
|
14
22
|
// The pinned skills whose installed files don't match the lockfile, from `atk audit --json`, as
|
|
15
23
|
// "<name> <version> <status>" lines. One the lockfile doesn't list is `not installed`.
|
|
16
24
|
export function staleSkills(audit, names) {
|
|
@@ -25,6 +33,12 @@ export function staleSkills(audit, names) {
|
|
|
25
33
|
return found.filter((e) => e.status !== 'ok').map((e) => `${name}${e.version ? ` ${e.version}` : ''} ${e.status}`);
|
|
26
34
|
});
|
|
27
35
|
}
|
|
36
|
+
export function worktreePath(root, name) {
|
|
37
|
+
return join(worktreesDir(root), name);
|
|
38
|
+
}
|
|
39
|
+
function worktreesDir(root) {
|
|
40
|
+
return join(root, '.claude', 'worktrees');
|
|
41
|
+
}
|
|
28
42
|
const auditSchema = z.looseObject({
|
|
29
43
|
tools: z.array(z.looseObject({
|
|
30
44
|
entries: z
|
|
@@ -32,31 +46,124 @@ const auditSchema = z.looseObject({
|
|
|
32
46
|
.optional(),
|
|
33
47
|
})),
|
|
34
48
|
});
|
|
35
|
-
export function gitWorktrees() {
|
|
49
|
+
export function gitWorktrees(deps = {}) {
|
|
50
|
+
const gitRun = deps.git ?? runGit;
|
|
51
|
+
const skillsHome = deps.skillsHome ?? claudeSkillsDir();
|
|
52
|
+
const platform = deps.platform ?? process.platform;
|
|
53
|
+
const sleep = deps.sleep ?? ((ms) => new Promise((done) => setTimeout(done, ms)));
|
|
36
54
|
// Untrimmed: porcelain status starts with a space for a file changed only in the worktree.
|
|
37
55
|
const git = async (args, cwd) => {
|
|
38
|
-
const result = await
|
|
56
|
+
const result = await gitRun(args, cwd);
|
|
39
57
|
return result.code === 0 ? result.stdout : null;
|
|
40
58
|
};
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
if (!existsSync(path)) {
|
|
44
|
-
throw new ConductorError(`no worktree hooks at ${path}`, ['the project needs the ATK worktree-kit bundle']);
|
|
45
|
-
}
|
|
46
|
-
// The hook reads CLAUDE_PROJECT_DIR the way Claude Code runs it.
|
|
47
|
-
const result = await run('node', [path], {
|
|
48
|
-
cwd: root,
|
|
49
|
-
env: { ...process.env, CLAUDE_PROJECT_DIR: root },
|
|
50
|
-
input: JSON.stringify({ ...input, cwd: root }),
|
|
51
|
-
timeoutMs,
|
|
52
|
-
});
|
|
59
|
+
const must = async (args, cwd, what) => {
|
|
60
|
+
const result = await gitRun(args, cwd);
|
|
53
61
|
if (result.code !== 0)
|
|
54
|
-
throw new ConductorError(
|
|
55
|
-
|
|
62
|
+
throw new ConductorError(what, [outputOf(result, 500)]);
|
|
63
|
+
};
|
|
64
|
+
const branchOf = async (path) => (await git(['symbolic-ref', '--quiet', '--short', 'HEAD'], path))?.trim() || null;
|
|
65
|
+
const create = async (request) => {
|
|
66
|
+
const { base, env, localFilesFrom, name, root, sessionEnv, setup } = request;
|
|
67
|
+
const path = worktreePath(root, name);
|
|
68
|
+
const reused = existsSync(join(path, '.git'));
|
|
69
|
+
if (reused) {
|
|
70
|
+
// Never deleted: it may hold someone's work, and a git call can fail for a moment.
|
|
71
|
+
if ((await git(['rev-parse', '--is-inside-work-tree'], path))?.trim() !== 'true')
|
|
72
|
+
throw new ConductorError(`${path} has a .git that git can't read`, [
|
|
73
|
+
'look at what is in it, then delete it, or run git worktree repair in the main checkout',
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Left over from a removal that didn't finish: no .git, so no worktree's work.
|
|
78
|
+
if (existsSync(path))
|
|
79
|
+
await rm(path, { force: true, maxRetries: 3, recursive: true });
|
|
80
|
+
// Git still lists a worktree whose directory went without it, and refuses to add at its path.
|
|
81
|
+
await git(['worktree', 'prune'], root);
|
|
82
|
+
// Deep node_modules paths under .claude/worktrees/<name> pass 260 characters, and without this
|
|
83
|
+
// Git for Windows can't check them out or remove them.
|
|
84
|
+
if (platform === 'win32')
|
|
85
|
+
await git(['config', 'core.longpaths', 'true'], root);
|
|
86
|
+
// Offline, the worktree starts from the origin/<base> fetched last; with none, the add says so.
|
|
87
|
+
await git(['fetch', '--quiet', 'origin', base], root);
|
|
88
|
+
const branch = `${BRANCH_PREFIX}${name}`;
|
|
89
|
+
const known = await hasBranch(root, branch);
|
|
90
|
+
await must(known ? ['worktree', 'add', path, branch] : ['worktree', 'add', '-b', branch, path, `origin/${base}`], root, `git worktree add failed for ${path}`);
|
|
91
|
+
}
|
|
92
|
+
// A reused worktree's own changes (a kept worker's) are its; only what setup changes counts.
|
|
93
|
+
const before = new Set(reused ? (await realDirty(gitRun, path)).dirty : []);
|
|
94
|
+
if (localFilesFrom !== undefined)
|
|
95
|
+
await copyLocalFiles(gitRun, localFilesFrom, path);
|
|
96
|
+
for (const command of setup) {
|
|
97
|
+
// Through the shell: a setup command is the profile's, a command line as a person would type it.
|
|
98
|
+
const result = await run(command, [], {
|
|
99
|
+
cwd: path,
|
|
100
|
+
env: { ...process.env, ...env },
|
|
101
|
+
shell: true,
|
|
102
|
+
timeoutMs: SETUP_MS,
|
|
103
|
+
});
|
|
104
|
+
if (result.code !== 0)
|
|
105
|
+
throw new ConductorError(`setup "${command}" failed in ${path}`, [outputOf(result, 1500)]);
|
|
106
|
+
}
|
|
107
|
+
// A worker that starts with changes it didn't make takes them for its own, and retire then
|
|
108
|
+
// refuses them as unfinished work: setup builds gitignored files only. (atk install rewrites
|
|
109
|
+
// .atk-lock.json when the registry's checksums aren't the base branch's.)
|
|
110
|
+
const dirty = (await realDirty(gitRun, path)).dirty.filter((file) => !before.has(file));
|
|
111
|
+
if (dirty.length > 0)
|
|
112
|
+
throw new ConductorError(`setup left changes in ${path}: ${dirty.join(', ')}`, [
|
|
113
|
+
'setup must build only gitignored files; fix the command that changed them, or ignore them in the repo',
|
|
114
|
+
]);
|
|
115
|
+
// Last, so no setup command can write over it.
|
|
116
|
+
writeSessionEnv(path, sessionEnv);
|
|
117
|
+
return path;
|
|
118
|
+
};
|
|
119
|
+
const hasBranch = async (root, branch) => (await git(['show-ref', '--verify', '--quiet', `refs/heads/${branch}`], root)) !== null;
|
|
120
|
+
// Not `git worktree remove`, which leaves pnpm's node_modules junctions behind on Windows: the
|
|
121
|
+
// worktree is moved aside, which frees its path at once, git forgets it, and Node deletes the
|
|
122
|
+
// directory, unlinking junctions without following them (the worktree-kit hook's way).
|
|
123
|
+
const remove = async (root, path, { deleteBranch }) => {
|
|
124
|
+
const dir = worktreesDir(root);
|
|
125
|
+
if (!isInside(dir, path))
|
|
126
|
+
throw new ConductorError(`${path} isn't under ${dir}`, ['the conductor removes only the worktrees it makes']);
|
|
127
|
+
// With the directory gone already, the branch a launch made, but only while no commit of it is
|
|
128
|
+
// anywhere else: nothing on a remote is lost by deleting it, and nothing else is deleted.
|
|
129
|
+
let branch = existsSync(path) ? await branchOf(path) : null;
|
|
130
|
+
if (branch === null && deleteBranch) {
|
|
131
|
+
const made = `${BRANCH_PREFIX}${basename(path)}`;
|
|
132
|
+
const unpushed = (await hasBranch(root, made))
|
|
133
|
+
? await git(['rev-list', '--count', made, '--not', '--remotes'], root)
|
|
134
|
+
: null;
|
|
135
|
+
if (unpushed?.trim() === '0')
|
|
136
|
+
branch = made;
|
|
137
|
+
}
|
|
138
|
+
let trash = null;
|
|
139
|
+
for (let waited = 0; existsSync(path); waited += 1000) {
|
|
140
|
+
trash = moveAside(path);
|
|
141
|
+
if (trash)
|
|
142
|
+
break;
|
|
143
|
+
if (waited >= RELEASE_MS)
|
|
144
|
+
throw new ConductorError(`${path} is in use`, [
|
|
145
|
+
'a process still holds a file in it, such as a dev server it started',
|
|
146
|
+
]);
|
|
147
|
+
await sleep(1000);
|
|
148
|
+
}
|
|
149
|
+
await must(['worktree', 'prune'], root, 'git worktree prune failed');
|
|
150
|
+
if (deleteBranch && branch)
|
|
151
|
+
await must(['branch', '-D', branch], root, `git couldn't delete the branch ${branch}`);
|
|
152
|
+
// Asynchronous: a worktree's node_modules takes a minute to delete, and the daemon's API and
|
|
153
|
+
// sweeps go on answering meanwhile.
|
|
154
|
+
if (trash)
|
|
155
|
+
await rm(trash, { force: true, maxRetries: 5, recursive: true, retryDelay: 500 });
|
|
156
|
+
// A removal interrupted earlier leaves its .trash-* folder; one under an hour old may be another
|
|
157
|
+
// removal's, still deleting.
|
|
158
|
+
for (const entry of existsSync(dir) ? readdirSync(dir) : []) {
|
|
159
|
+
const at = Number(/^\.trash-.+-(\d+)$/.exec(entry)?.[1] ?? Number.NaN);
|
|
160
|
+
if (Date.now() - at > STALE_TRASH_MS)
|
|
161
|
+
await rm(join(dir, entry), { force: true, maxRetries: 5, recursive: true });
|
|
162
|
+
}
|
|
56
163
|
};
|
|
57
164
|
// One checkout's uncommitted changes (without line-ending-only ones) and commits on no remote.
|
|
58
165
|
const workIn = async (path) => {
|
|
59
|
-
const { dirty } = await realDirty(
|
|
166
|
+
const { dirty } = await realDirty(gitRun, path);
|
|
60
167
|
const count = await git(['rev-list', '--count', 'HEAD', '--not', '--remotes'], path);
|
|
61
168
|
const unpushed = Number(count ?? 0);
|
|
62
169
|
return {
|
|
@@ -66,7 +173,7 @@ export function gitWorktrees() {
|
|
|
66
173
|
...(count === null ? { unknown: `git rev-list failed in ${path}` } : {}),
|
|
67
174
|
};
|
|
68
175
|
};
|
|
69
|
-
const atk = (args) => run('atk', args, { shell: true, timeoutMs:
|
|
176
|
+
const atk = (args) => run('atk', args, { shell: true, timeoutMs: ATK_MS });
|
|
70
177
|
const audit = async (worktree, skills) => {
|
|
71
178
|
const result = await atk(['audit', '--json', '-P', worktree]); // exits 1 when a checksum fails
|
|
72
179
|
try {
|
|
@@ -79,7 +186,7 @@ export function gitWorktrees() {
|
|
|
79
186
|
};
|
|
80
187
|
return {
|
|
81
188
|
auditSkills: async (checkout, skills) => (existsSync(join(checkout, LOCKFILE)) ? audit(checkout, skills) : null),
|
|
82
|
-
branchOf
|
|
189
|
+
branchOf,
|
|
83
190
|
checkSkills: async (worktree, skills) => {
|
|
84
191
|
if (!existsSync(join(worktree, LOCKFILE)))
|
|
85
192
|
return null;
|
|
@@ -101,17 +208,9 @@ export function gitWorktrees() {
|
|
|
101
208
|
}
|
|
102
209
|
return null;
|
|
103
210
|
},
|
|
104
|
-
create
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
throw new ConductorError('the WorktreeCreate hook printed no path');
|
|
108
|
-
return path;
|
|
109
|
-
},
|
|
110
|
-
remove: async (root, path) => {
|
|
111
|
-
await hook(root, { hook_event_name: 'WorktreeRemove', worktree_path: path }, REMOVE_MS);
|
|
112
|
-
if (existsSync(path))
|
|
113
|
-
throw new ConductorError(`${path} is still there after the WorktreeRemove hook`);
|
|
114
|
-
},
|
|
211
|
+
create,
|
|
212
|
+
missingSkills: (worktree, skills) => missingProjectSkills(worktree, skills, skillsHome),
|
|
213
|
+
remove,
|
|
115
214
|
unfinishedWork: async (path) => {
|
|
116
215
|
if (!existsSync(path))
|
|
117
216
|
return null;
|
|
@@ -132,4 +231,49 @@ export function gitWorktrees() {
|
|
|
132
231
|
},
|
|
133
232
|
};
|
|
134
233
|
}
|
|
234
|
+
// Merges the env into the worktree's .claude/settings.local.json, whose `env` Claude Code applies to
|
|
235
|
+
// every session in the folder, and to each resume of one. Claude Code's convention gitignores the
|
|
236
|
+
// file, so it isn't work of the worker's (`conduct project check` warns when the repo doesn't).
|
|
237
|
+
export function writeSessionEnv(worktree, env) {
|
|
238
|
+
if (Object.keys(env).length === 0)
|
|
239
|
+
return;
|
|
240
|
+
const file = join(worktree, SESSION_SETTINGS);
|
|
241
|
+
let settings = {};
|
|
242
|
+
if (existsSync(file)) {
|
|
243
|
+
const parsed = settingsSchema.safeParse(parseOrNull(readFileSync(file, 'utf8')));
|
|
244
|
+
if (!parsed.success)
|
|
245
|
+
throw new ConductorError(`${file} is not a JSON object`, [
|
|
246
|
+
'fix or delete it: the conductor writes the ports into its env',
|
|
247
|
+
]);
|
|
248
|
+
settings = parsed.data;
|
|
249
|
+
}
|
|
250
|
+
const current = envSchema.safeParse(settings.env).data ?? {};
|
|
251
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
252
|
+
writeFileSync(file, `${JSON.stringify({ ...settings, env: { ...current, ...env } }, null, 2)}\n`);
|
|
253
|
+
}
|
|
254
|
+
const settingsSchema = z.record(z.string(), z.unknown());
|
|
255
|
+
const envSchema = z.record(z.string(), z.string());
|
|
256
|
+
function isInside(parent, child) {
|
|
257
|
+
const rel = relative(resolve(parent), resolve(child));
|
|
258
|
+
return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel);
|
|
259
|
+
}
|
|
260
|
+
// Renames a directory to .trash-<name>-<time> beside it; null when something holds it.
|
|
261
|
+
function moveAside(dir) {
|
|
262
|
+
const trash = join(dirname(dir), `.trash-${basename(dir)}-${Date.now()}`);
|
|
263
|
+
try {
|
|
264
|
+
renameSync(dir, trash);
|
|
265
|
+
return trash;
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function parseOrNull(text) {
|
|
272
|
+
try {
|
|
273
|
+
return JSON.parse(text);
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
135
279
|
//# sourceMappingURL=worktrees.js.map
|
package/build/worktrees.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktrees.js","sourceRoot":"","sources":["../src/worktrees.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AA2BzC,4FAA4F;AAC5F,MAAM,SAAS,GAAG,EAAE,GAAG,MAAM,CAAC;AAC9B,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC;AAC7B,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC;AAC9D,CAAC;AAED,gGAAgG;AAChG,uFAAuF;AACvF,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,KAAwB;IAClE,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAClE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACrD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC;QACzD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACrH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;IAChC,KAAK,EAAE,CAAC,CAAC,KAAK,CACZ,CAAC,CAAC,WAAW,CAAC;QACZ,OAAO,EAAE,CAAC;aACP,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;aAC7F,QAAQ,EAAE;KACd,CAAC,CACH;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,YAAY;IAC1B,2FAA2F;IAC3F,MAAM,GAAG,GAAG,KAAK,EAAE,IAAc,EAAE,GAAW,EAA0B,EAAE;QACxE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/C,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,EAAE,IAAY,EAAE,KAA6B,EAAE,SAAiB,EAAmB,EAAE;QACrG,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,cAAc,CAAC,wBAAwB,IAAI,EAAE,EAAE,CAAC,+CAA+C,CAAC,CAAC,CAAC;QAC9G,CAAC;QACD,iEAAiE;QACjE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;YACvC,GAAG,EAAE,IAAI;YACT,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE;YACjD,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YAC9C,SAAS;SACV,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;YACnB,MAAM,IAAI,cAAc,CAAC,OAAO,KAAK,CAAC,eAAe,cAAc,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAChG,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC,CAAC;IACF,+FAA+F;IAC/F,MAAM,MAAM,GAAG,KAAK,EAAE,IAAY,EAA8C,EAAE;QAChF,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC;QACrF,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QACpC,OAAO;YACL,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,6EAA6E;YAC7E,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,0BAA0B,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,GAAG,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IACxF,MAAM,KAAK,GAAG,KAAK,EAAE,QAAgB,EAAE,MAAyB,EAAqB,EAAE;QACrF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,gCAAgC;QAC/F,IAAI,CAAC;YACH,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,kDAAkD;YAClD,OAAO,CAAC,qBAAqB,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAChH,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI;QAC3G,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;YACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACvD,IAAI,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC1C,IAAI,YAAY,GAAG,EAAE,CAAC;YACtB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACnE,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;oBAAE,YAAY,GAAG,kBAAkB,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC;gBACvF,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAClB,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,QAAQ,kCAAkC,YAAY,EAAE,CAAC;YACjG,+FAA+F;YAC/F,sFAAsF;YACtF,IAAI,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACnE,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,mBAAmB;gBACtE,OAAO,uBAAuB,QAAQ,+DAA+D,CAAC;YACxG,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,eAAe,EAAE,gBAAgB,EAAE,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;YACtF,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,cAAc,CAAC,yCAAyC,CAAC,CAAC;YAC/E,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC3B,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;YACxF,IAAI,UAAU,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,cAAc,CAAC,GAAG,IAAI,+CAA+C,CAAC,CAAC;QACzG,CAAC;QACD,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YACnC,MAAM,IAAI,GAAmB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,SAAS,GAAsD,EAAE,CAAC;YACxE,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtC,2FAA2F;gBAC3F,qCAAqC;gBACrC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC;oBACzD,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC,CAAC,CAAC;gBACJ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC;oBAAE,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;YACtE,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;YAClE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACpD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"worktrees.js","sourceRoot":"","sources":["../src/worktrees.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@detergent-software/conductor",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-dev.10",
|
|
4
4
|
"description": "Conductor: the local daemon that runs conducted projects' work loops (conduct serve) and its conduct CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,19 +9,19 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"build",
|
|
11
11
|
"!build/__tests__",
|
|
12
|
-
"
|
|
13
|
-
"!
|
|
14
|
-
"!
|
|
12
|
+
"plugin",
|
|
13
|
+
"!plugin/tests",
|
|
14
|
+
"!plugin/.claude-plugin/types",
|
|
15
15
|
"protocol",
|
|
16
16
|
"CHANGELOG.md"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc",
|
|
20
20
|
"dev": "tsc --watch",
|
|
21
|
-
"format": "prettier --write \"src/**/*.{ts,tsx}\" \"
|
|
22
|
-
"format:check": "prettier --check \"src/**/*.{ts,tsx}\" \"
|
|
23
|
-
"lint": "eslint src/
|
|
24
|
-
"lint:fix": "eslint src/
|
|
21
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\" \"plugin/**/*.{ts,tsx}\" \"scripts/**/*.mjs\"",
|
|
22
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx}\" \"plugin/**/*.{ts,tsx}\" \"scripts/**/*.mjs\"",
|
|
23
|
+
"lint": "eslint src/ plugin/",
|
|
24
|
+
"lint:fix": "eslint src/ plugin/ --fix --cache",
|
|
25
25
|
"test": "vitest run",
|
|
26
26
|
"test:watch": "vitest",
|
|
27
27
|
"typecheck": "tsc --noEmit && tsc -p tsconfig.mod.json && tsc -p tsconfig.mod-specs.json"
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"directory": "apps/conductor"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
|
35
|
-
"node": ">=24.
|
|
35
|
+
"node": ">=24.5.0"
|
|
36
36
|
},
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"registry": "https://registry.npmjs.org",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "conductor",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "The conductor's plugin, loaded only into the sessions it starts: the mod (the console's band, pane and commands, and each session's report to the daemon), the console skill, the reference work skill and the verification-skill pair.",
|
|
5
|
+
"author": { "name": "Emergent Software" },
|
|
6
|
+
"types": "./types/index.d.ts"
|
|
7
|
+
}
|
package/plugin/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Conductor plugin
|
|
2
|
+
|
|
3
|
+
The conductor's Claude Code plugin, named `conductor`. It loads only into the sessions the conductor starts (the workers and the console), each with `--plugin-dir <CONDUCTOR_HOME>/plugin`, a copy the daemon keeps in step with this folder. Nothing installs it for the user. The conductor README's *Plugin* section (`apps/conductor/README.md`) says how the copy is kept and what a session that lost it shows.
|
|
4
|
+
|
|
5
|
+
| Path | Holds |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `hooks/register.tsx` | the mod's hooks: the plugin report every session sends on start, then the console's commands, band, pane and event stream; only its top-level functions take `$` |
|
|
8
|
+
| `hooks/model.ts` | the mod's logic without the engine: parsing the daemon's answers, what the band and pane show, what each event asks for |
|
|
9
|
+
| `skills/conductor-console/` | `/conductor:conductor-console`, the console skill |
|
|
10
|
+
| `skills/work-item/` | `/conductor:work-item`, the reference work skill (worker protocol 2) |
|
|
11
|
+
| `skills/create-verification-skill/`, `skills/maintain-verification-skill/` | vendored from the ATK registry with their pstack MIT `LICENSE`; `scripts/vendor-skills.mjs` and `vendored-skills.json` keep them pinned |
|
|
12
|
+
| `types/index.d.ts` | the `$.state` contract (`conductor.snapshot`, `confirming`, `expanded`) |
|
|
13
|
+
| `tests/conductor.test.tsx` | `claude plugin test apps/conductor/plugin`: the hooks against the engine, the daemon faked beneath them |
|
|
14
|
+
| `tests/model.spec.ts` | vitest (`pnpm -C apps/conductor test`, in CI): `model.ts` |
|
|
15
|
+
|
|
16
|
+
The mod does the console's plumbing in code, so it costs no tokens: the inbox band, the fleet pane, `/conductor` `/inbox` `/approve` `/revise` `/attach` `/notify` `/pause` `/unpause` `/focus-project`, toasts, Remote Control pushes (and the one warning when Remote Control is off), the one model wake-up for an escalation, a nudge to load `/conductor:conductor-console` in a console started without it, and a warm prompt cache while the console idles. Only the console (`CONDUCTOR_CONSOLE=1`) gets those; every other conductor session only reports the plugin.
|
|
17
|
+
|
|
18
|
+
`pnpm -C apps/conductor typecheck` type-checks the hooks in CI against Claude Code's plugin API, kept in `apps/conductor/mod-types/` (the conductor README's *Mod* section says how to refresh it).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// The conductor mod's logic, with nothing of the engine in it: what the daemon's answers mean, what
|
|
2
2
|
// the band and pane show, and what each event asks the mod to do. register.tsx does
|
|
3
3
|
// the engine's part (only its top-level functions may take `$`); vitest tests this file in CI
|
|
4
|
-
// (apps/conductor/
|
|
4
|
+
// (apps/conductor/plugin/tests/model.spec.ts).
|
|
5
5
|
import type { ConductorInboxItem, ConductorLink, ConductorNotify, ConductorSnapshot, ConductorWorker } from '../types';
|
|
6
6
|
|
|
7
7
|
// A daemon API answer: its status and parsed JSON body.
|
|
@@ -46,9 +46,10 @@ export function reportedState(outcome: PushOutcome): 'failing' | 'inactive' | 'o
|
|
|
46
46
|
return outcome.state === 'failed' ? 'failing' : outcome.state;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
// The skill a console runs first (ATK-385)
|
|
50
|
-
//
|
|
51
|
-
|
|
49
|
+
// The skill a console runs first (ATK-385), as this plugin namespaces it: the engine names a plugin
|
|
50
|
+
// skill `<plugin>:<skill>` in skill.prompt (ATK-525). `conduct console` starts with it as the first
|
|
51
|
+
// prompt; a console started by hand (`claude --plugin-dir … -n conductor`) has to be told.
|
|
52
|
+
export const CONSOLE_SKILL = 'conductor:conductor-console';
|
|
52
53
|
// What the model reads beside each prompt of a console whose skill hasn't run.
|
|
53
54
|
export const NO_SKILL_CONTEXT = `This session is the conductor console (CONDUCTOR_CONSOLE=1), but /${CONSOLE_SKILL} hasn't run in it, so its rules don't hold. Load the ${CONSOLE_SKILL} skill with the Skill tool and follow it, then answer this prompt.`;
|
|
54
55
|
export const NO_SKILL_WARNING = `console without its skill: run /${CONSOLE_SKILL}`;
|
|
@@ -552,6 +553,23 @@ export function answerText(action: 'approve' | 'done' | 'revise', id: number, an
|
|
|
552
553
|
return `${action === 'approve' ? 'approved' : 'asked for a revision of'} ${key}: ${where}`;
|
|
553
554
|
}
|
|
554
555
|
|
|
556
|
+
// The conductor this plugin folder belongs to: the CLI the mod runs, and the daemon's home. The
|
|
557
|
+
// daemon's copy (<CONDUCTOR_HOME>/plugin) names both in conductor.json, written on each refresh.
|
|
558
|
+
// The home matters because a `claude --bg` session doesn't see its launcher's environment: a worker
|
|
559
|
+
// of a daemon kept in CONDUCTOR_HOME would otherwise report to ~/.conductor (ATK-525). The package's
|
|
560
|
+
// own plugin folder (a `claude plugin test`, a `--plugin-dir` on a checkout) has none: its CLI sits
|
|
561
|
+
// beside it, and its home is the environment's (homeOf).
|
|
562
|
+
export function daemonOf(root: string, conductorJson: null | string): { cli: string; home: null | string } {
|
|
563
|
+
let named: { cli?: unknown; home?: unknown } = {};
|
|
564
|
+
try {
|
|
565
|
+
if (conductorJson !== null) named = JSON.parse(conductorJson) as typeof named;
|
|
566
|
+
} catch {
|
|
567
|
+
// Not JSON: as if there were none.
|
|
568
|
+
}
|
|
569
|
+
const text = (value: unknown): null | string => (typeof value === 'string' && value !== '' ? value : null);
|
|
570
|
+
return { cli: text(named.cli) ?? `${root}/../build/cli.js`, home: text(named.home) };
|
|
571
|
+
}
|
|
572
|
+
|
|
555
573
|
// The port and token files' text as an endpoint; null unless both are whole.
|
|
556
574
|
export function endpointOf(portText: string, tokenText: string): null | { port: number; token: string } {
|
|
557
575
|
const port = Number(portText.trim());
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
bandEntries,
|
|
12
12
|
clearedText,
|
|
13
13
|
CONSOLE_SKILL,
|
|
14
|
+
daemonOf,
|
|
14
15
|
endpointOf,
|
|
15
16
|
errorOf,
|
|
16
17
|
findPlan,
|
|
@@ -77,6 +78,8 @@ const cleared = atom({ key: 'cleared', plugin: 'conductor' } as const, null);
|
|
|
77
78
|
// flags start over with the module, and session.start sets the first again after a reload.
|
|
78
79
|
let isConsole = false;
|
|
79
80
|
let isRefreshing = false;
|
|
81
|
+
// The plugin folder's conductor.json, read once per load (daemon).
|
|
82
|
+
let named: null | Promise<ReturnType<typeof daemonOf>> = null;
|
|
80
83
|
// The newest event id the stream showed, so a restarted `conduct events` picks up after it.
|
|
81
84
|
let lastEventId: null | number = null;
|
|
82
85
|
// Set once the console has said that pushes no longer reach the phone; a push that does clears it.
|
|
@@ -104,13 +107,13 @@ async function answer(
|
|
|
104
107
|
body: { action: 'approve' | 'done' } | { action: 'revise'; text: string },
|
|
105
108
|
): Promise<string> {
|
|
106
109
|
try {
|
|
107
|
-
const cli =
|
|
110
|
+
const cli = await cliPath($);
|
|
108
111
|
if (body.action !== 'done' && (await $.fs.exists(cli))) {
|
|
109
112
|
const failed = `not ${body.action}d`;
|
|
110
113
|
const argv = body.action === 'revise' ? ['revise', `#${id}`, body.text] : ['approve', `#${id}`];
|
|
111
114
|
let run;
|
|
112
115
|
try {
|
|
113
|
-
run = await $.process.run(['node', cli, ...argv], { timeoutMs: ANSWER_RUN_MS });
|
|
116
|
+
run = await $.process.run(['node', cli, ...argv], { ...(await cliInit($)), timeoutMs: ANSWER_RUN_MS });
|
|
114
117
|
} catch (error) {
|
|
115
118
|
return `${failed}: ${error instanceof Error ? error.message : String(error)}`;
|
|
116
119
|
}
|
|
@@ -146,10 +149,13 @@ function armIdle($: EngineInterface): void {
|
|
|
146
149
|
// and resumes quickly. The daemon refuses a second attach of a worker while one runs.
|
|
147
150
|
async function attach($: EngineInterface, id: number, name: string): Promise<string> {
|
|
148
151
|
try {
|
|
149
|
-
const cli =
|
|
152
|
+
const cli = await cliPath($);
|
|
150
153
|
if (await $.fs.exists(cli)) {
|
|
151
154
|
$.ui.toast(`attaching to ${name}…`);
|
|
152
|
-
const run = await $.process.run(['node', cli, 'attach', `#${id}`], {
|
|
155
|
+
const run = await $.process.run(['node', cli, 'attach', `#${id}`], {
|
|
156
|
+
...(await cliInit($)),
|
|
157
|
+
timeoutMs: ATTACH_RUN_MS,
|
|
158
|
+
});
|
|
153
159
|
refreshSoon($);
|
|
154
160
|
return runText(run, { failed: `could not attach to ${name}`, ok: `attached to ${name}` });
|
|
155
161
|
}
|
|
@@ -187,9 +193,16 @@ async function callApi(
|
|
|
187
193
|
return { body: parsed, status: answer.status };
|
|
188
194
|
}
|
|
189
195
|
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
|
|
196
|
+
// What a CLI the mod runs needs to reach this plugin's daemon: its home, which a session the
|
|
197
|
+
// conductor started in the background doesn't have in its environment.
|
|
198
|
+
async function cliInit($: EngineInterface): Promise<{ env?: Record<string, string> }> {
|
|
199
|
+
const { home } = await daemon($);
|
|
200
|
+
return home === null ? {} : { env: { CONDUCTOR_HOME: home } };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// The conductor's own CLI (model.ts, daemonOf); a checkout without a build has none.
|
|
204
|
+
async function cliPath($: EngineInterface): Promise<string> {
|
|
205
|
+
return (await daemon($)).cli;
|
|
193
206
|
}
|
|
194
207
|
|
|
195
208
|
// Stages a band approve for its `y`; it lapses unless pressed within CONFIRM_MS.
|
|
@@ -207,18 +220,36 @@ async function copy(
|
|
|
207
220
|
$.ui.toast(copied.isCopied ? `copied: ${text}` : `not copied: ${text}`);
|
|
208
221
|
}
|
|
209
222
|
|
|
223
|
+
// The conductor this plugin folder belongs to (model.ts, daemonOf). Read once per load: the file
|
|
224
|
+
// changes only with the folder, and that reloads this module.
|
|
225
|
+
async function daemon($: EngineInterface): Promise<ReturnType<typeof daemonOf>> {
|
|
226
|
+
named ??= (async () => {
|
|
227
|
+
let text: null | string = null;
|
|
228
|
+
try {
|
|
229
|
+
text = await $.fs.read(`${$.plugin.root}/conductor.json`);
|
|
230
|
+
} catch {
|
|
231
|
+
// The package's own plugin folder has none.
|
|
232
|
+
}
|
|
233
|
+
return daemonOf($.plugin.root, text);
|
|
234
|
+
})();
|
|
235
|
+
return named;
|
|
236
|
+
}
|
|
237
|
+
|
|
210
238
|
function disarmIdle(): void {
|
|
211
239
|
idleTimer?.cancel();
|
|
212
240
|
idleTimer = null;
|
|
213
241
|
}
|
|
214
242
|
|
|
215
|
-
// The running daemon's port and token, from its home's files
|
|
243
|
+
// The running daemon's port and token, from its home's files: the home the plugin's copy names,
|
|
244
|
+
// else the environment's. Throws when none runs.
|
|
216
245
|
async function endpoint($: EngineInterface): Promise<Endpoint> {
|
|
217
|
-
const home =
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
246
|
+
const home =
|
|
247
|
+
(await daemon($)).home ??
|
|
248
|
+
homeOf({
|
|
249
|
+
conductorHome: await $.env.get('CONDUCTOR_HOME'),
|
|
250
|
+
home: await $.env.get('HOME'),
|
|
251
|
+
userProfile: await $.env.get('USERPROFILE'),
|
|
252
|
+
});
|
|
222
253
|
if (home === null) throw new Error(NOT_RUNNING);
|
|
223
254
|
let found: Endpoint | null;
|
|
224
255
|
try {
|
|
@@ -235,7 +266,7 @@ async function endpoint($: EngineInterface): Promise<Endpoint> {
|
|
|
235
266
|
// the last event it showed, so nothing in between is lost. One that keeps exiting at once (no
|
|
236
267
|
// build, no node) is given up on, and the poll carries on alone.
|
|
237
268
|
async function follow($: EngineInterface): Promise<void> {
|
|
238
|
-
const cli =
|
|
269
|
+
const cli = await cliPath($);
|
|
239
270
|
if (!(await $.fs.exists(cli))) {
|
|
240
271
|
$.ui.log(`conductor: no ${cli}; the console polls instead of following events`, { to: 'debug' });
|
|
241
272
|
return;
|
|
@@ -253,7 +284,7 @@ async function follow($: EngineInterface): Promise<void> {
|
|
|
253
284
|
'--console',
|
|
254
285
|
...(lastEventId === null ? [] : ['--since', String(lastEventId)]),
|
|
255
286
|
];
|
|
256
|
-
for await (const chunk of $.process.spawn({ argv })) {
|
|
287
|
+
for await (const chunk of $.process.spawn({ argv, ...(await cliInit($)) })) {
|
|
257
288
|
if (chunk.stream !== 'stdout') continue;
|
|
258
289
|
buffer += chunk.text;
|
|
259
290
|
for (let end = buffer.indexOf('\n'); end >= 0; end = buffer.indexOf('\n')) {
|
|
@@ -507,6 +538,17 @@ async function reportCache($: EngineInterface, body: Record<string, unknown>): P
|
|
|
507
538
|
}
|
|
508
539
|
}
|
|
509
540
|
|
|
541
|
+
// POST /plugin/seen with this session's id. No daemon, no report: nothing waits on it then.
|
|
542
|
+
async function reportPlugin($: EngineInterface): Promise<void> {
|
|
543
|
+
try {
|
|
544
|
+
await callApi($, 'POST', '/plugin/seen', { sessionId: await $.session.id() });
|
|
545
|
+
} catch (error) {
|
|
546
|
+
$.ui.log(`conductor: no plugin report (${error instanceof Error ? error.message : String(error)})`, {
|
|
547
|
+
to: 'debug',
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
510
552
|
// `/notify <profile> [--until <when>]` and the pane's picker: switch the notification profile.
|
|
511
553
|
async function switchProfile($: EngineInterface, name: string, until: null | string = null): Promise<string> {
|
|
512
554
|
try {
|
|
@@ -530,6 +572,10 @@ async function why($: EngineInterface, item: string): Promise<string> {
|
|
|
530
572
|
export const register: Register = (on) => {
|
|
531
573
|
on('session.start', async ($, e, next) => {
|
|
532
574
|
const started = await next(e);
|
|
575
|
+
// Every session that loads this plugin was started by the conductor. Workers too, which run in
|
|
576
|
+
// the background: the daemon wants each start's report, so it can tell a worker that woke
|
|
577
|
+
// without the plugin (its saved --plugin-dir gone, ATK-522), and says so (ATK-525).
|
|
578
|
+
void reportPlugin($);
|
|
533
579
|
if (!e.isInteractive) return started;
|
|
534
580
|
isConsole = (await $.env.get('CONDUCTOR_CONSOLE')) === '1';
|
|
535
581
|
if (!isConsole) return started;
|
|
@@ -544,7 +590,7 @@ export const register: Register = (on) => {
|
|
|
544
590
|
});
|
|
545
591
|
|
|
546
592
|
// A console the skill never ran in (one started by hand as `claude -n conductor`, ATK-385) is
|
|
547
|
-
// told to load it before it answers, each prompt until it has. `/conductor-console` or the Skill
|
|
593
|
+
// told to load it before it answers, each prompt until it has. `/conductor:conductor-console` or the Skill
|
|
548
594
|
// tool expands it before its prompt is submitted; a /clear or a resume starts a conversation
|
|
549
595
|
// without it.
|
|
550
596
|
on('skill.prompt', { skill: CONSOLE_SKILL }, async ($, e, next) => {
|
|
@@ -652,7 +698,7 @@ export const register: Register = (on) => {
|
|
|
652
698
|
|
|
653
699
|
// The band above the prompt, in the console, while the inbox has items. A bare digit typed into
|
|
654
700
|
// an empty prompt presses a band Button, so a plan's approve takes a second press (`y`). Until
|
|
655
|
-
// /conductor-console runs, a warning sits above it, or above the engine's own (ATK-385); after the
|
|
701
|
+
// /conductor:conductor-console runs, a warning sits above it, or above the engine's own (ATK-385); after the
|
|
656
702
|
// mod cleared an idle console, a plain line that says so instead (ATK-386).
|
|
657
703
|
on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
|
|
658
704
|
if (!isConsole || e.props.hasSurvey) return next(e);
|