@matthugh1/conductor-cli 0.2.5 → 0.3.0
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/dist/{agent-spawner-BNOGEYDK.js → agent-spawner-YCGFXFXX.js} +32 -6
- package/dist/agent.js +10 -10
- package/dist/{branch-overview-RRHX3XGY.js → branch-overview-35OJQU7T.js} +3 -109
- package/dist/chunk-HXPYK5E3.js +116 -0
- package/dist/chunk-T27CR6PR.js +179 -0
- package/dist/daemon-427UNQNA.js +614 -0
- package/dist/{daemon-client-CTYOJMJP.js → daemon-client-RVY2YLMA.js} +13 -0
- package/dist/{git-hooks-RQ6WJQS4.js → git-hooks-CD25TLQV.js} +112 -14
- package/dist/{runner-prompt-MOOPKA5P.js → runner-prompt-7EUGIDWK.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-6AA726KG.js +0 -238
- package/dist/daemon-HAIV5MEA.js +0 -607
|
@@ -1,13 +1,96 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
query
|
|
4
|
+
} from "./chunk-HXPYK5E3.js";
|
|
2
5
|
import {
|
|
3
6
|
runGit
|
|
4
7
|
} from "./chunk-N2KKNG4C.js";
|
|
5
8
|
|
|
6
9
|
// ../../src/core/git-hooks.ts
|
|
7
10
|
import { chmod, mkdir, readFile, writeFile } from "fs/promises";
|
|
11
|
+
import path2 from "path";
|
|
12
|
+
|
|
13
|
+
// ../../src/core/hook-auth.ts
|
|
14
|
+
import { randomBytes } from "crypto";
|
|
15
|
+
function generateHookToken() {
|
|
16
|
+
return randomBytes(32).toString("hex");
|
|
17
|
+
}
|
|
18
|
+
async function storeHookToken(projectId, token) {
|
|
19
|
+
await query(
|
|
20
|
+
`UPDATE projects SET hook_token = $1 WHERE id = $2`,
|
|
21
|
+
[token, projectId]
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
async function getHookToken(projectId) {
|
|
25
|
+
const rows = await query(
|
|
26
|
+
`SELECT hook_token FROM projects WHERE id = $1 LIMIT 1`,
|
|
27
|
+
[projectId]
|
|
28
|
+
);
|
|
29
|
+
return rows.length > 0 ? rows[0].hook_token : null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ../../src/core/project-lookup.ts
|
|
33
|
+
import { realpath } from "fs/promises";
|
|
8
34
|
import path from "path";
|
|
35
|
+
function normalizeProjectPath(projectRoot) {
|
|
36
|
+
return path.resolve(projectRoot.trim());
|
|
37
|
+
}
|
|
38
|
+
async function pathVariantsForLookup(projectRoot) {
|
|
39
|
+
const resolved = normalizeProjectPath(projectRoot);
|
|
40
|
+
const variants = /* @__PURE__ */ new Set([resolved]);
|
|
41
|
+
try {
|
|
42
|
+
const canon = await realpath(resolved);
|
|
43
|
+
variants.add(canon);
|
|
44
|
+
} catch {
|
|
45
|
+
}
|
|
46
|
+
return [...variants];
|
|
47
|
+
}
|
|
48
|
+
async function findProjectByPath(projectRoot) {
|
|
49
|
+
const variants = await pathVariantsForLookup(projectRoot);
|
|
50
|
+
const rows = await query(
|
|
51
|
+
`
|
|
52
|
+
SELECT id, name, path, repo_url
|
|
53
|
+
FROM projects
|
|
54
|
+
WHERE path = ANY($1::text[])
|
|
55
|
+
LIMIT 1
|
|
56
|
+
`,
|
|
57
|
+
[variants]
|
|
58
|
+
);
|
|
59
|
+
return rows.length > 0 ? rows[0] : null;
|
|
60
|
+
}
|
|
61
|
+
async function findProjectByName(name) {
|
|
62
|
+
const rows = await query(
|
|
63
|
+
`SELECT id, name, path, repo_url
|
|
64
|
+
FROM projects
|
|
65
|
+
WHERE lower(name) = lower($1)
|
|
66
|
+
LIMIT 1`,
|
|
67
|
+
[name.trim()]
|
|
68
|
+
);
|
|
69
|
+
return rows.length > 0 ? rows[0] : null;
|
|
70
|
+
}
|
|
71
|
+
async function getRegisteredProjectIdOrNull(projectRoot) {
|
|
72
|
+
try {
|
|
73
|
+
const byPath = await findProjectByPath(projectRoot);
|
|
74
|
+
if (byPath) return byPath.id;
|
|
75
|
+
const trimmed = projectRoot.trim();
|
|
76
|
+
const byName = await findProjectByName(trimmed);
|
|
77
|
+
if (byName) return byName.id;
|
|
78
|
+
const basename = trimmed.split("/").pop() ?? trimmed;
|
|
79
|
+
if (basename !== trimmed) {
|
|
80
|
+
const byBasename = await findProjectByName(basename);
|
|
81
|
+
if (byBasename) return byBasename.id;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
} catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ../../src/core/git-hooks.ts
|
|
9
90
|
var CONDUCTOR_URL = process.env.CONDUCTOR_URL?.trim() || "http://localhost:3000";
|
|
10
|
-
function postCommitHook() {
|
|
91
|
+
function postCommitHook(token) {
|
|
92
|
+
const auth = token ? `
|
|
93
|
+
-H "Authorization: Bearer ${token}" \\` : "";
|
|
11
94
|
return `#!/bin/sh
|
|
12
95
|
# Conductor narration hook \u2014 post-commit.
|
|
13
96
|
# conductor-hook-${CONDUCTOR_VERSION}
|
|
@@ -19,7 +102,7 @@ COMMIT_HASH=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
|
19
102
|
FILES_CHANGED=$(git diff-tree --no-commit-id --name-only -r HEAD 2>/dev/null | wc -l | tr -d ' ')
|
|
20
103
|
|
|
21
104
|
curl -s -X POST "${CONDUCTOR_URL}/api/git/activity/hook" \\
|
|
22
|
-
-H "Content-Type: application/json"
|
|
105
|
+
-H "Content-Type: application/json" \\${auth}
|
|
23
106
|
-d "{
|
|
24
107
|
\\"hookName\\": \\"post-commit\\",
|
|
25
108
|
\\"eventType\\": \\"commit\\",
|
|
@@ -36,7 +119,9 @@ curl -s -X POST "${CONDUCTOR_URL}/api/git/activity/hook" \\
|
|
|
36
119
|
exit 0
|
|
37
120
|
`;
|
|
38
121
|
}
|
|
39
|
-
function postMergeHook() {
|
|
122
|
+
function postMergeHook(token) {
|
|
123
|
+
const auth = token ? `
|
|
124
|
+
-H "Authorization: Bearer ${token}" \\` : "";
|
|
40
125
|
return `#!/bin/sh
|
|
41
126
|
# Conductor narration hook \u2014 post-merge.
|
|
42
127
|
# conductor-hook-${CONDUCTOR_VERSION}
|
|
@@ -52,7 +137,7 @@ else
|
|
|
52
137
|
fi
|
|
53
138
|
|
|
54
139
|
curl -s -X POST "${CONDUCTOR_URL}/api/git/activity/hook" \\
|
|
55
|
-
-H "Content-Type: application/json"
|
|
140
|
+
-H "Content-Type: application/json" \\${auth}
|
|
56
141
|
-d "{
|
|
57
142
|
\\"hookName\\": \\"post-merge\\",
|
|
58
143
|
\\"eventType\\": \\"merge\\",
|
|
@@ -64,7 +149,9 @@ curl -s -X POST "${CONDUCTOR_URL}/api/git/activity/hook" \\
|
|
|
64
149
|
exit 0
|
|
65
150
|
`;
|
|
66
151
|
}
|
|
67
|
-
function postCheckoutHook() {
|
|
152
|
+
function postCheckoutHook(token) {
|
|
153
|
+
const auth = token ? `
|
|
154
|
+
-H "Authorization: Bearer ${token}" \\` : "";
|
|
68
155
|
return `#!/bin/sh
|
|
69
156
|
# Conductor narration hook \u2014 post-checkout.
|
|
70
157
|
# conductor-hook-${CONDUCTOR_VERSION}
|
|
@@ -82,7 +169,7 @@ BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
|
82
169
|
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
83
170
|
|
|
84
171
|
curl -s -X POST "${CONDUCTOR_URL}/api/git/activity/hook" \\
|
|
85
|
-
-H "Content-Type: application/json"
|
|
172
|
+
-H "Content-Type: application/json" \\${auth}
|
|
86
173
|
-d "{
|
|
87
174
|
\\"hookName\\": \\"post-checkout\\",
|
|
88
175
|
\\"eventType\\": \\"checkout\\",
|
|
@@ -94,7 +181,9 @@ curl -s -X POST "${CONDUCTOR_URL}/api/git/activity/hook" \\
|
|
|
94
181
|
exit 0
|
|
95
182
|
`;
|
|
96
183
|
}
|
|
97
|
-
function prePushHook() {
|
|
184
|
+
function prePushHook(token) {
|
|
185
|
+
const auth = token ? `
|
|
186
|
+
-H "Authorization: Bearer ${token}" \\` : "";
|
|
98
187
|
return `#!/bin/sh
|
|
99
188
|
# Conductor narration hook \u2014 pre-push.
|
|
100
189
|
# conductor-hook-${CONDUCTOR_VERSION}
|
|
@@ -118,7 +207,7 @@ if [ "$IS_FORCE" = "true" ]; then
|
|
|
118
207
|
fi
|
|
119
208
|
|
|
120
209
|
curl -s -X POST "${CONDUCTOR_URL}/api/git/activity/hook" \\
|
|
121
|
-
-H "Content-Type: application/json"
|
|
210
|
+
-H "Content-Type: application/json" \\${auth}
|
|
122
211
|
-d "{
|
|
123
212
|
\\"hookName\\": \\"pre-push\\",
|
|
124
213
|
\\"eventType\\": \\"$EVENT_TYPE\\",
|
|
@@ -145,11 +234,11 @@ var CONDUCTOR_MARKER = "# Conductor narration hook";
|
|
|
145
234
|
var CONDUCTOR_VERSION = "v1";
|
|
146
235
|
var CONDUCTOR_VERSION_MARKER = `# conductor-hook-${CONDUCTOR_VERSION}`;
|
|
147
236
|
async function getHookStatus(projectRoot) {
|
|
148
|
-
const hooksDir =
|
|
237
|
+
const hooksDir = path2.join(projectRoot, ".git", "hooks");
|
|
149
238
|
const hookResults = [];
|
|
150
239
|
let detectedVersion = null;
|
|
151
240
|
for (const hook of HOOKS) {
|
|
152
|
-
const hookPath =
|
|
241
|
+
const hookPath = path2.join(hooksDir, hook.name);
|
|
153
242
|
let content = null;
|
|
154
243
|
try {
|
|
155
244
|
content = await readFile(hookPath, "utf8");
|
|
@@ -178,12 +267,21 @@ async function getHookStatus(projectRoot) {
|
|
|
178
267
|
};
|
|
179
268
|
}
|
|
180
269
|
async function installHooks(projectRoot) {
|
|
181
|
-
const hooksDir =
|
|
270
|
+
const hooksDir = path2.join(projectRoot, ".git", "hooks");
|
|
182
271
|
await mkdir(hooksDir, { recursive: true });
|
|
272
|
+
const projectId = await getRegisteredProjectIdOrNull(projectRoot);
|
|
273
|
+
let token = null;
|
|
274
|
+
if (projectId) {
|
|
275
|
+
token = await getHookToken(projectId);
|
|
276
|
+
if (!token) {
|
|
277
|
+
token = generateHookToken();
|
|
278
|
+
await storeHookToken(projectId, token);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
183
281
|
const installed = [];
|
|
184
282
|
const skipped = [];
|
|
185
283
|
for (const hook of HOOKS) {
|
|
186
|
-
const hookPath =
|
|
284
|
+
const hookPath = path2.join(hooksDir, hook.name);
|
|
187
285
|
let existingContent = null;
|
|
188
286
|
try {
|
|
189
287
|
existingContent = await readFile(hookPath, "utf8");
|
|
@@ -193,7 +291,7 @@ async function installHooks(projectRoot) {
|
|
|
193
291
|
skipped.push(hook.name);
|
|
194
292
|
continue;
|
|
195
293
|
}
|
|
196
|
-
const script = hook.generate();
|
|
294
|
+
const script = hook.generate(token);
|
|
197
295
|
await writeFile(hookPath, script, "utf8");
|
|
198
296
|
await chmod(hookPath, 493);
|
|
199
297
|
installed.push(hook.name);
|
|
@@ -202,7 +300,7 @@ async function installHooks(projectRoot) {
|
|
|
202
300
|
}
|
|
203
301
|
async function installHooksForWorktree(worktreePath) {
|
|
204
302
|
const mainRoot = (await runGit(worktreePath, ["rev-parse", "--git-common-dir"])).trim();
|
|
205
|
-
const resolvedRoot =
|
|
303
|
+
const resolvedRoot = path2.resolve(worktreePath, mainRoot, "..");
|
|
206
304
|
return installHooks(resolvedRoot);
|
|
207
305
|
}
|
|
208
306
|
export {
|
package/package.json
CHANGED
package/dist/chunk-6AA726KG.js
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// ../../src/core/runner-prompt.ts
|
|
4
|
-
var AUTONOMOUS_WORKFLOW = `
|
|
5
|
-
## Identity
|
|
6
|
-
|
|
7
|
-
You are an autonomous implementation engineer spawned by Conductor's runner.
|
|
8
|
-
When you need human input, use conductor_log_decision followed by
|
|
9
|
-
conductor_await_decision \u2014 this blocks until the human responds in the
|
|
10
|
-
Conductor panel. Work carefully and methodically.
|
|
11
|
-
|
|
12
|
-
## Workflow (follow in order)
|
|
13
|
-
|
|
14
|
-
### 1. Start your session
|
|
15
|
-
|
|
16
|
-
Call conductor_session_brief with:
|
|
17
|
-
- projectRoot: the project name given in your assignment below
|
|
18
|
-
- deliverableId: the deliverable ID given in your assignment below
|
|
19
|
-
- agentRole: "implementation-engineer"
|
|
20
|
-
- agentType: "claude-code"
|
|
21
|
-
|
|
22
|
-
Save the returned sessionId \u2014 pass it to every subsequent Conductor call.
|
|
23
|
-
|
|
24
|
-
### 2. Read the brief and understand your assignment
|
|
25
|
-
|
|
26
|
-
The session brief contains your deliverable title, description, and
|
|
27
|
-
acceptance criteria. Read them carefully before writing any code.
|
|
28
|
-
|
|
29
|
-
### 3. Branch from dev
|
|
30
|
-
|
|
31
|
-
Run: git fetch origin && git checkout -b <branch-name> origin/dev
|
|
32
|
-
|
|
33
|
-
Name the branch after the deliverable (e.g., feat/prompt-template).
|
|
34
|
-
Branch from origin/dev (not main) so you pick up any prior autonomous
|
|
35
|
-
work that has been merged to dev but not yet reviewed into main.
|
|
36
|
-
Never use git checkout dev \u2014 use origin/dev directly to avoid worktree conflicts.
|
|
37
|
-
Never branch from another feature branch.
|
|
38
|
-
|
|
39
|
-
### 4. Mark your deliverable in-progress
|
|
40
|
-
|
|
41
|
-
Call conductor_update_deliverable with status "in_progress".
|
|
42
|
-
|
|
43
|
-
### 5. Do the work
|
|
44
|
-
|
|
45
|
-
Implement the deliverable according to its acceptance criteria.
|
|
46
|
-
After each meaningful chunk of work, call conductor_log_built with
|
|
47
|
-
a plain English summary and the sessionId.
|
|
48
|
-
|
|
49
|
-
### 6. Self-check before submitting
|
|
50
|
-
|
|
51
|
-
Before creating a PR, run ALL of these checks:
|
|
52
|
-
|
|
53
|
-
1. npx tsc --noEmit (type check)
|
|
54
|
-
2. npm run build (build)
|
|
55
|
-
3. npm test (tests)
|
|
56
|
-
4. git status (working tree clean?)
|
|
57
|
-
5. Review your own code for:
|
|
58
|
-
- No \`any\` type assertions
|
|
59
|
-
- No console.log in production code
|
|
60
|
-
- No large files (>200 lines of code)
|
|
61
|
-
- No large functions (>50 lines)
|
|
62
|
-
- No unused imports
|
|
63
|
-
- No secrets or .env files staged
|
|
64
|
-
|
|
65
|
-
### 7. Retry on failure (up to 3 attempts)
|
|
66
|
-
|
|
67
|
-
If any check fails:
|
|
68
|
-
- Read the error output carefully
|
|
69
|
-
- Fix the issue
|
|
70
|
-
- Re-run the failing check
|
|
71
|
-
- Repeat up to 3 total attempts per check
|
|
72
|
-
|
|
73
|
-
If a check still fails after 3 attempts, go to the parking procedure (step 10).
|
|
74
|
-
|
|
75
|
-
### 8. Create a PR and merge to dev
|
|
76
|
-
|
|
77
|
-
When all checks pass:
|
|
78
|
-
- git add the relevant files (never use git add -A)
|
|
79
|
-
- git commit with a descriptive message
|
|
80
|
-
- git push -u origin <branch-name>
|
|
81
|
-
- gh pr create --title "<deliverable title>" --body "<summary>"
|
|
82
|
-
- Save the PR URL \u2014 you need it for the completion report
|
|
83
|
-
|
|
84
|
-
After the PR is created, merge your branch to dev so the next agent
|
|
85
|
-
in the chain can build on your work without waiting for human review.
|
|
86
|
-
Use a temporary local branch to avoid worktree checkout conflicts:
|
|
87
|
-
|
|
88
|
-
git fetch origin
|
|
89
|
-
git checkout -b _dev-merge origin/dev
|
|
90
|
-
git merge --no-ff <your-branch-name> -m "chore: merge <branch-name> to dev"
|
|
91
|
-
git push origin HEAD:dev
|
|
92
|
-
git checkout <your-branch-name>
|
|
93
|
-
git branch -D _dev-merge
|
|
94
|
-
|
|
95
|
-
Never merge your own PR to main. Always merge to dev after creating the PR.
|
|
96
|
-
|
|
97
|
-
### 9. Submit for review
|
|
98
|
-
|
|
99
|
-
Call conductor_update_deliverable with:
|
|
100
|
-
- status: "review"
|
|
101
|
-
- completionReport with all check results and the prUrl
|
|
102
|
-
|
|
103
|
-
Then call conductor_end_session with the sessionId.
|
|
104
|
-
|
|
105
|
-
### 10. When you need a human decision
|
|
106
|
-
|
|
107
|
-
If you hit a judgment call, ambiguous requirement, or blocker that needs human input:
|
|
108
|
-
1. Call conductor_log_decision with the options and your reasoning.
|
|
109
|
-
This returns a decisionId.
|
|
110
|
-
2. Call conductor_await_decision with that decisionId.
|
|
111
|
-
This blocks until the human approves in the Conductor panel (polls every
|
|
112
|
-
3 seconds, up to 5 minutes per call).
|
|
113
|
-
3. If it returns "pending" (timeout), call conductor_await_decision again.
|
|
114
|
-
Keep calling until you get a resolution.
|
|
115
|
-
4. Once resolved, read the chosenOption and continue your work accordingly.
|
|
116
|
-
|
|
117
|
-
CRITICAL: You MUST call conductor_log_decision to create the decision.
|
|
118
|
-
Do not just say "I need a decision" in text \u2014 the human cannot see your
|
|
119
|
-
text output. The only way they know you need input is through the
|
|
120
|
-
Conductor decision panel.
|
|
121
|
-
|
|
122
|
-
### 11. Parking procedure (when truly stuck)
|
|
123
|
-
|
|
124
|
-
If you cannot complete the work and waiting for a decision won't help:
|
|
125
|
-
- Call conductor_update_deliverable with status "parked".
|
|
126
|
-
- Call conductor_log_next describing what remains and why you stopped.
|
|
127
|
-
- Call conductor_end_session with the sessionId.
|
|
128
|
-
- Exit cleanly.
|
|
129
|
-
|
|
130
|
-
## Rules
|
|
131
|
-
|
|
132
|
-
- Follow all rules in CLAUDE.md (included above if present).
|
|
133
|
-
- Never merge your own PR to main \u2014 only create it.
|
|
134
|
-
- Always merge your branch to dev after creating the PR (see step 8).
|
|
135
|
-
- Never make silent decisions \u2014 log every judgment call via conductor_log_decision.
|
|
136
|
-
- If a subsequent deliverable exists in the same outcome, create a handoff
|
|
137
|
-
prompt via conductor_create_prompt before submitting for review.
|
|
138
|
-
- Keep commits atomic and messages descriptive.
|
|
139
|
-
- Do not install new dependencies without logging a decision.
|
|
140
|
-
- Do not modify files outside the scope of your deliverable.
|
|
141
|
-
- If you encounter merge conflicts, resolve them yourself.
|
|
142
|
-
- Work within the existing code style and patterns.
|
|
143
|
-
`.trim();
|
|
144
|
-
var FREEFORM_TASK_WORKFLOW = `
|
|
145
|
-
## Identity
|
|
146
|
-
|
|
147
|
-
You are an agent spawned by Conductor's daemon to execute a task.
|
|
148
|
-
When you need human input, use conductor_log_decision followed by
|
|
149
|
-
conductor_await_decision \u2014 this blocks until the human responds in the
|
|
150
|
-
Conductor panel. Work carefully and methodically.
|
|
151
|
-
|
|
152
|
-
## Workflow
|
|
153
|
-
|
|
154
|
-
1. Read the task description below carefully.
|
|
155
|
-
2. Execute the task as described.
|
|
156
|
-
3. If you hit a judgment call or blocker, log a decision via conductor_log_decision
|
|
157
|
-
and wait via conductor_await_decision. Do not proceed without resolution.
|
|
158
|
-
4. When finished, report what you accomplished clearly.
|
|
159
|
-
|
|
160
|
-
## Rules
|
|
161
|
-
|
|
162
|
-
- Follow all rules in CLAUDE.md (included above if present).
|
|
163
|
-
- Never make silent decisions \u2014 log every judgment call.
|
|
164
|
-
- Work within the existing code style and patterns.
|
|
165
|
-
- Do not install new dependencies without logging a decision.
|
|
166
|
-
`.trim();
|
|
167
|
-
function assembleAutonomousPrompt(ctx) {
|
|
168
|
-
const parts = [];
|
|
169
|
-
if (ctx.claudeMd.length > 0) {
|
|
170
|
-
parts.push("# Project Rules (CLAUDE.md)\n\n" + ctx.claudeMd);
|
|
171
|
-
}
|
|
172
|
-
parts.push("# Autonomous Runner Instructions\n\n" + AUTONOMOUS_WORKFLOW);
|
|
173
|
-
parts.push(
|
|
174
|
-
`# Your Assignment
|
|
175
|
-
|
|
176
|
-
Project: ${ctx.projectName}
|
|
177
|
-
Deliverable: ${ctx.item.title}
|
|
178
|
-
Deliverable ID: ${ctx.item.entityId}
|
|
179
|
-
Initiative: ${ctx.item.initiativeTitle ?? "unknown"}
|
|
180
|
-
Priority: P${ctx.item.priority}
|
|
181
|
-
Action: ${ctx.item.action}
|
|
182
|
-
|
|
183
|
-
Start by calling conductor_session_brief with:
|
|
184
|
-
- projectRoot: "${ctx.projectName}"
|
|
185
|
-
- deliverableId: "${ctx.item.entityId}"
|
|
186
|
-
- agentRole: "implementation-engineer"
|
|
187
|
-
- agentType: "claude-code"`
|
|
188
|
-
);
|
|
189
|
-
return parts.join("\n\n---\n\n");
|
|
190
|
-
}
|
|
191
|
-
function assembleTaskPrompt(agent, task, claudeMd) {
|
|
192
|
-
const parts = [];
|
|
193
|
-
if (claudeMd.length > 0) {
|
|
194
|
-
parts.push("# Project Rules (CLAUDE.md)\n\n" + claudeMd);
|
|
195
|
-
}
|
|
196
|
-
if (agent.systemPrompt.length > 0) {
|
|
197
|
-
parts.push(
|
|
198
|
-
`# Agent: ${agent.name}
|
|
199
|
-
|
|
200
|
-
## System Prompt
|
|
201
|
-
|
|
202
|
-
` + agent.systemPrompt
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
if (task.deliverableId) {
|
|
206
|
-
parts.push("# Autonomous Runner Instructions\n\n" + AUTONOMOUS_WORKFLOW);
|
|
207
|
-
} else {
|
|
208
|
-
parts.push("# Task Instructions\n\n" + FREEFORM_TASK_WORKFLOW);
|
|
209
|
-
}
|
|
210
|
-
const assignmentLines = [
|
|
211
|
-
`# Your Assignment`,
|
|
212
|
-
``,
|
|
213
|
-
`Task: ${task.title}`,
|
|
214
|
-
`Project: ${task.projectName}`
|
|
215
|
-
];
|
|
216
|
-
if (task.deliverableId) {
|
|
217
|
-
assignmentLines.push(`Deliverable ID: ${task.deliverableId}`);
|
|
218
|
-
assignmentLines.push(``);
|
|
219
|
-
assignmentLines.push(`Start by calling conductor_session_brief with:`);
|
|
220
|
-
assignmentLines.push(`- projectRoot: "${task.projectName}"`);
|
|
221
|
-
assignmentLines.push(`- deliverableId: "${task.deliverableId}"`);
|
|
222
|
-
assignmentLines.push(`- agentRole: "implementation-engineer"`);
|
|
223
|
-
assignmentLines.push(`- agentType: "claude-code"`);
|
|
224
|
-
}
|
|
225
|
-
if (task.prompt.length > 0) {
|
|
226
|
-
assignmentLines.push(``);
|
|
227
|
-
assignmentLines.push(`## Task Details`);
|
|
228
|
-
assignmentLines.push(``);
|
|
229
|
-
assignmentLines.push(task.prompt);
|
|
230
|
-
}
|
|
231
|
-
parts.push(assignmentLines.join("\n"));
|
|
232
|
-
return parts.join("\n\n---\n\n");
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export {
|
|
236
|
-
assembleAutonomousPrompt,
|
|
237
|
-
assembleTaskPrompt
|
|
238
|
-
};
|