@clemrig/factory 0.2.1 → 0.4.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/README.md +127 -37
- package/dist/app/board.d.ts +7 -0
- package/dist/app/board.js +47 -0
- package/dist/app/board.js.map +1 -0
- package/dist/app/define.d.ts +27 -0
- package/dist/app/define.js +68 -0
- package/dist/app/define.js.map +1 -0
- package/dist/app/doctor.js +5 -4
- package/dist/app/doctor.js.map +1 -1
- package/dist/app/factory.js +10 -2
- package/dist/app/factory.js.map +1 -1
- package/dist/app/run.js +1 -1
- package/dist/app/run.js.map +1 -1
- package/dist/app/workflows/implement.d.ts +8 -0
- package/dist/app/workflows/implement.js +268 -0
- package/dist/app/workflows/implement.js.map +1 -0
- package/dist/app/workflows/issue-save.d.ts +2 -0
- package/dist/app/workflows/issue-save.js +35 -0
- package/dist/app/workflows/issue-save.js.map +1 -0
- package/dist/cli/application.js +1 -1
- package/dist/cli/application.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +5 -3
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.js +4 -4
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/reporter.js +42 -15
- package/dist/cli/reporter.js.map +1 -1
- package/dist/cli/ui.d.ts +5 -2
- package/dist/cli/ui.js +20 -7
- package/dist/cli/ui.js.map +1 -1
- package/dist/domain/board.d.ts +65 -0
- package/dist/domain/board.js +95 -0
- package/dist/domain/board.js.map +1 -0
- package/dist/domain/definition.d.ts +15 -0
- package/dist/domain/definition.js +28 -0
- package/dist/domain/definition.js.map +1 -0
- package/dist/domain/delivery.d.ts +9 -0
- package/dist/domain/delivery.js +10 -0
- package/dist/domain/delivery.js.map +1 -0
- package/dist/domain/issue.d.ts +11 -0
- package/dist/domain/issue.js +22 -0
- package/dist/domain/issue.js.map +1 -0
- package/dist/domain/parsed.d.ts +8 -0
- package/dist/domain/parsed.js +2 -0
- package/dist/domain/parsed.js.map +1 -0
- package/dist/domain/plan.d.ts +24 -0
- package/dist/domain/plan.js +49 -0
- package/dist/domain/plan.js.map +1 -0
- package/dist/domain/pull-request.d.ts +17 -0
- package/dist/domain/pull-request.js +32 -0
- package/dist/domain/pull-request.js.map +1 -0
- package/dist/domain/review.d.ts +36 -0
- package/dist/domain/review.js +45 -0
- package/dist/domain/review.js.map +1 -0
- package/dist/domain/spec.d.ts +18 -0
- package/dist/domain/spec.js +118 -0
- package/dist/domain/spec.js.map +1 -0
- package/dist/domain/verification.d.ts +16 -0
- package/dist/domain/verification.js +11 -0
- package/dist/domain/verification.js.map +1 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/system/checks.d.ts +32 -0
- package/dist/system/checks.js +49 -0
- package/dist/system/checks.js.map +1 -0
- package/dist/system/factory.d.ts +7 -5
- package/dist/system/factory.js +19 -19
- package/dist/system/factory.js.map +1 -1
- package/dist/system/git.d.ts +25 -0
- package/dist/system/git.js +73 -0
- package/dist/system/git.js.map +1 -0
- package/dist/system/github.d.ts +8 -0
- package/dist/system/github.js +52 -0
- package/dist/system/github.js.map +1 -0
- package/dist/system/issues.d.ts +24 -0
- package/dist/system/issues.js +66 -0
- package/dist/system/issues.js.map +1 -0
- package/dist/system/lock.d.ts +8 -0
- package/dist/system/lock.js +35 -0
- package/dist/system/lock.js.map +1 -0
- package/dist/system/templates.d.ts +2 -1
- package/dist/system/templates.js +69 -3
- package/dist/system/templates.js.map +1 -1
- package/package.json +6 -4
- package/prompts/implement/implement.md +21 -0
- package/prompts/implement/plan.md +20 -0
- package/prompts/implement/review.md +17 -0
- package/templates/init/factory.ts +37 -2
- package/templates/init/workflows/ask/index.ts +2 -1
- package/templates/skills/issue/SKILL.md +82 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { agent, code, defineWorkflow, END, gate, node, retry, schemaGate, step, z, } from "@clemrig/flow";
|
|
2
|
+
import { isSlug } from "../../domain/issue.js";
|
|
3
|
+
import { planCommitMessage, planOutput, planProblem, renderPlan, } from "../../domain/plan.js";
|
|
4
|
+
import { DELIVERY } from "../../domain/delivery.js";
|
|
5
|
+
import { pullRequestBody } from "../../domain/pull-request.js";
|
|
6
|
+
import { implementationOutput, implementationProblem, reviewChanges, reviewOutput, reviewProblem, } from "../../domain/review.js";
|
|
7
|
+
import { parseSpec } from "../../domain/spec.js";
|
|
8
|
+
import { failureFeedback, seconds, } from "../../domain/verification.js";
|
|
9
|
+
import { runChecks } from "../../system/checks.js";
|
|
10
|
+
import * as git from "../../system/git.js";
|
|
11
|
+
import * as github from "../../system/github.js";
|
|
12
|
+
import { withTreeLock } from "../../system/lock.js";
|
|
13
|
+
import { artifactPath, hasArtifact, readArtifact, writeArtifact, } from "../../system/issues.js";
|
|
14
|
+
function facts(state) {
|
|
15
|
+
return state.data;
|
|
16
|
+
}
|
|
17
|
+
/** Corrections the review asked for so far. */
|
|
18
|
+
function reviewRounds(state) {
|
|
19
|
+
return state.retries?.["reviewed.changes"] ?? 0;
|
|
20
|
+
}
|
|
21
|
+
function short(commit) {
|
|
22
|
+
return commit.slice(0, 7);
|
|
23
|
+
}
|
|
24
|
+
/** Journals each check as it starts and passes: they can take minutes. */
|
|
25
|
+
function journalChecks(log, where = "") {
|
|
26
|
+
return ({ check, ...event }) => log(event.status === "started"
|
|
27
|
+
? `Running ${check.name}${where}: ${check.command.join(" ")}`
|
|
28
|
+
: `${check.name} passed in ${seconds(event.durationMs)}`);
|
|
29
|
+
}
|
|
30
|
+
/** Every reason not to start, found without changing anything; then the base must pass its checks. */
|
|
31
|
+
async function prepare(definition, { dir, state, log }) {
|
|
32
|
+
const slug = String(state.input.issue);
|
|
33
|
+
const base = await git.defaultBranch(dir);
|
|
34
|
+
const problems = [];
|
|
35
|
+
// The run commits and force-pushes on the branch the slug names.
|
|
36
|
+
if (slug === base)
|
|
37
|
+
problems.push(`Issue ${slug} names the main branch: its branch would replace ${base}; rename the issue`);
|
|
38
|
+
if ((await git.currentBranch(dir)) !== base)
|
|
39
|
+
problems.push(`Switch to ${base} first`);
|
|
40
|
+
if (await git.hasChanges(dir))
|
|
41
|
+
problems.push("Commit or discard the changes in progress first");
|
|
42
|
+
await git.fetchBranch(dir, base);
|
|
43
|
+
if ((await git.commitOf(dir, "HEAD")) !==
|
|
44
|
+
(await git.commitOf(dir, git.remoteRef(base))))
|
|
45
|
+
problems.push(`${base} must match origin/${base}: push or pull first`);
|
|
46
|
+
const text = await readArtifact(dir, slug, "spec");
|
|
47
|
+
const spec = text === undefined ? undefined : parseSpec(text);
|
|
48
|
+
if (!spec)
|
|
49
|
+
problems.push(`Issue ${slug} has no spec.md`);
|
|
50
|
+
else if (!spec.ok)
|
|
51
|
+
problems.push(...spec.problems.map((problem) => `spec.md: ${problem}`));
|
|
52
|
+
if (await hasArtifact(dir, slug, "plan"))
|
|
53
|
+
problems.push(`Issue ${slug} is already delivered (its plan.md is on ${base}): start a new issue`);
|
|
54
|
+
if (!(await github.isAuthenticated(dir)))
|
|
55
|
+
problems.push("gh is not logged in: run gh auth login");
|
|
56
|
+
if (problems.length > 0 || !spec?.ok || text === undefined)
|
|
57
|
+
throw new Error(["Cannot start:", ...problems.map((problem) => `- ${problem}`)].join("\n"));
|
|
58
|
+
log(`Starting point valid: ${base} matches origin, spec with ${spec.value.criteria.length} criteria, gh logged in`);
|
|
59
|
+
const baseCommit = await git.commitOf(dir, "HEAD");
|
|
60
|
+
const checks = await runChecks(dir, definition.verify, journalChecks(log, ` on ${base}`));
|
|
61
|
+
if (!checks.ok)
|
|
62
|
+
throw new Error(`${base} does not pass its own checks:\n${failureFeedback(checks.check, checks.cause, checks.output)}`);
|
|
63
|
+
// One run at a time per working tree: another one started during the checks
|
|
64
|
+
// may have moved it. Checking and taking the tree happen under one lock, so
|
|
65
|
+
// that two runs never both find it free; the branch starts from the approved
|
|
66
|
+
// commit, never from theirs.
|
|
67
|
+
await withTreeLock(dir, async () => {
|
|
68
|
+
const branch = await git.currentBranch(dir);
|
|
69
|
+
const head = await git.commitOf(dir, "HEAD");
|
|
70
|
+
if (branch !== base || head !== baseCommit)
|
|
71
|
+
throw new Error(`The repository moved while ${base}'s checks ran (now ${branch || "detached"} at ${short(head)}): another run is using it; start again once it is done`);
|
|
72
|
+
await git.switchTo(dir, slug, baseCommit);
|
|
73
|
+
});
|
|
74
|
+
log(`Created branch ${slug} from ${base} at ${short(baseCommit)}`);
|
|
75
|
+
return {
|
|
76
|
+
slug,
|
|
77
|
+
title: spec.value.title,
|
|
78
|
+
spec: text,
|
|
79
|
+
criteria: spec.value.criteria,
|
|
80
|
+
base,
|
|
81
|
+
baseCommit,
|
|
82
|
+
specPath: artifactPath(slug, "spec"),
|
|
83
|
+
planPath: artifactPath(slug, "plan"),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** The implementing agent may not commit, switch branches or touch .factory/: the run stops if it did. */
|
|
87
|
+
async function guard({ dir, state }) {
|
|
88
|
+
const { slug, planCommit } = facts(state);
|
|
89
|
+
if ((await git.commitOf(dir, "HEAD")) !== planCommit ||
|
|
90
|
+
(await git.currentBranch(dir)) !== slug)
|
|
91
|
+
throw new Error("The implementing agent committed or switched branches: the run stops");
|
|
92
|
+
if (await git.hasChanges(dir, ".factory"))
|
|
93
|
+
throw new Error("The implementing agent changed .factory/: the run stops");
|
|
94
|
+
}
|
|
95
|
+
/** Plans, implements, checks and reviews an approved spec, then opens its pull request. */
|
|
96
|
+
export function implement(definition) {
|
|
97
|
+
return defineWorkflow({
|
|
98
|
+
name: DELIVERY,
|
|
99
|
+
input: z.object({
|
|
100
|
+
issue: z
|
|
101
|
+
.string()
|
|
102
|
+
.refine(isSlug, "Expected lowercase words separated by hyphens"),
|
|
103
|
+
}),
|
|
104
|
+
maxCostUsd: definition.maxCostUsd,
|
|
105
|
+
initial: "prepare",
|
|
106
|
+
// The issue's card shows these steps; each check counts in the step it checks.
|
|
107
|
+
steps: [
|
|
108
|
+
{ name: "prepare", stages: ["prepare"] },
|
|
109
|
+
{ name: "plan", stages: ["plan", "planned", "commit-plan"] },
|
|
110
|
+
{ name: "implement", stages: ["implement", "implemented"] },
|
|
111
|
+
{ name: "verify", stages: ["verify"] },
|
|
112
|
+
{ name: "review", stages: ["diff", "review", "reviewed"] },
|
|
113
|
+
{ name: "deliver", stages: ["deliver"] },
|
|
114
|
+
],
|
|
115
|
+
nodes: {
|
|
116
|
+
prepare: node(step((context) => prepare(definition, context)), { ok: "plan" }),
|
|
117
|
+
plan: node(agent({
|
|
118
|
+
profile: definition.profiles.plan,
|
|
119
|
+
schema: planOutput,
|
|
120
|
+
context: ({ state }) => ({
|
|
121
|
+
issue: facts(state).slug,
|
|
122
|
+
spec: facts(state).spec,
|
|
123
|
+
}),
|
|
124
|
+
}), { ok: "planned" }),
|
|
125
|
+
planned: node(schemaGate({
|
|
126
|
+
schema: planOutput,
|
|
127
|
+
into: "plan",
|
|
128
|
+
check: (plan, { state }) => planProblem(plan, facts(state).criteria),
|
|
129
|
+
}), { ok: "commit-plan", invalid: retry("plan", 2) }),
|
|
130
|
+
"commit-plan": node(step(async ({ dir, state, log }) => {
|
|
131
|
+
const { slug, title, specPath, baseCommit, plan } = facts(state);
|
|
132
|
+
await writeArtifact(dir, slug, "plan", renderPlan(plan, { title, specPath, baseCommit }));
|
|
133
|
+
const planCommit = await git.commit(dir, planCommitMessage(slug), [
|
|
134
|
+
artifactPath(slug, "plan"),
|
|
135
|
+
]);
|
|
136
|
+
log(`Committed plan.md (${plan.steps.length} steps) as ${short(planCommit)}`);
|
|
137
|
+
return { planCommit };
|
|
138
|
+
}), { ok: "implement" }),
|
|
139
|
+
implement: node(agent({
|
|
140
|
+
profile: definition.profiles.implement,
|
|
141
|
+
schema: implementationOutput,
|
|
142
|
+
context: ({ state }) => {
|
|
143
|
+
const { slug, spec, plan } = facts(state);
|
|
144
|
+
return { issue: slug, spec, plan };
|
|
145
|
+
},
|
|
146
|
+
}), { ok: "implemented" }),
|
|
147
|
+
implemented: node(gate(["ok", "invalid"], async (context) => {
|
|
148
|
+
// First what the agent did, whatever it answered: a malformed
|
|
149
|
+
// response must not hide a change it may not make.
|
|
150
|
+
await guard(context);
|
|
151
|
+
const parsed = implementationOutput.safeParse(context.state.output);
|
|
152
|
+
if (!parsed.success)
|
|
153
|
+
return {
|
|
154
|
+
outcome: "invalid",
|
|
155
|
+
reason: `Invalid structured output:\n${z.prettifyError(parsed.error)}`,
|
|
156
|
+
};
|
|
157
|
+
const problem = implementationProblem(parsed.data, facts(context.state).criteria);
|
|
158
|
+
if (problem)
|
|
159
|
+
return { outcome: "invalid", reason: problem };
|
|
160
|
+
return {
|
|
161
|
+
outcome: "ok",
|
|
162
|
+
reason: "Structured output and invariants valid: implementation",
|
|
163
|
+
data: { implementation: parsed.data },
|
|
164
|
+
};
|
|
165
|
+
}), { ok: "verify", invalid: retry("implement", 2) }),
|
|
166
|
+
verify: node(code(["passed", "failed"], async ({ dir, log }) => {
|
|
167
|
+
const checks = await runChecks(dir, definition.verify, journalChecks(log));
|
|
168
|
+
if (checks.ok)
|
|
169
|
+
return {
|
|
170
|
+
outcome: "passed",
|
|
171
|
+
reason: "Every check passed",
|
|
172
|
+
data: { checks: checks.passed },
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
outcome: "failed",
|
|
176
|
+
reason: `${checks.check.name} failed: ${checks.cause}`,
|
|
177
|
+
feedback: failureFeedback(checks.check, checks.cause, checks.output),
|
|
178
|
+
};
|
|
179
|
+
}), { passed: "diff", failed: retry("implement", 3) }),
|
|
180
|
+
diff: node(step(async ({ dir, state, log }) => {
|
|
181
|
+
const diff = await git.stagedDiff(dir, facts(state).planCommit);
|
|
182
|
+
if (diff.truncated)
|
|
183
|
+
throw new Error("The changes are too large to review (over 2 MiB of diff): the run stops");
|
|
184
|
+
const files = diff.text.match(/^diff --git /gm)?.length ?? 0;
|
|
185
|
+
log(`Changes since the plan: ${files} files, ${diff.text.split("\n").length} diff lines`);
|
|
186
|
+
return { diff: diff.text };
|
|
187
|
+
}), { ok: "review" }),
|
|
188
|
+
review: node(agent({
|
|
189
|
+
profile: definition.profiles.review,
|
|
190
|
+
schema: reviewOutput,
|
|
191
|
+
// A new conversation for each review; a correction of its format resumes it.
|
|
192
|
+
session: (state) => `review-${reviewRounds(state)}`,
|
|
193
|
+
context: ({ state }) => {
|
|
194
|
+
const { slug, spec, diff, checks } = facts(state);
|
|
195
|
+
return { issue: slug, spec, diff, checks };
|
|
196
|
+
},
|
|
197
|
+
}), { ok: "reviewed" }),
|
|
198
|
+
reviewed: node(gate(["approved", "changes", "invalid"], async ({ state }) => {
|
|
199
|
+
const parsed = reviewOutput.safeParse(state.output);
|
|
200
|
+
if (!parsed.success)
|
|
201
|
+
return {
|
|
202
|
+
outcome: "invalid",
|
|
203
|
+
reason: `Invalid structured output:\n${z.prettifyError(parsed.error)}`,
|
|
204
|
+
};
|
|
205
|
+
const problem = reviewProblem(parsed.data, facts(state).criteria);
|
|
206
|
+
if (problem)
|
|
207
|
+
return { outcome: "invalid", reason: problem };
|
|
208
|
+
const changes = reviewChanges(parsed.data);
|
|
209
|
+
if (changes)
|
|
210
|
+
return {
|
|
211
|
+
outcome: "changes",
|
|
212
|
+
reason: "The review requires changes",
|
|
213
|
+
feedback: changes,
|
|
214
|
+
data: { review: parsed.data },
|
|
215
|
+
};
|
|
216
|
+
return {
|
|
217
|
+
outcome: "approved",
|
|
218
|
+
reason: "Every criterion is met and nothing blocks",
|
|
219
|
+
data: { review: parsed.data },
|
|
220
|
+
};
|
|
221
|
+
}), {
|
|
222
|
+
approved: "deliver",
|
|
223
|
+
changes: retry("implement", 2),
|
|
224
|
+
invalid: retry("review", 2),
|
|
225
|
+
}),
|
|
226
|
+
deliver: node(step(async ({ dir, state, log }) => {
|
|
227
|
+
const { slug, base, plan, specPath, planPath, baseCommit, criteria, implementation, review, checks, } = facts(state);
|
|
228
|
+
const commit = await git.commit(dir, `${plan.commit}\n\nSpec: ${specPath}`);
|
|
229
|
+
log(`Committed "${plan.commit}" as ${short(commit)}`);
|
|
230
|
+
await git.forcePush(dir, slug);
|
|
231
|
+
log(`Pushed ${slug}, replacing any earlier version of the branch`);
|
|
232
|
+
const pullRequest = await github.openPullRequest(dir, {
|
|
233
|
+
base,
|
|
234
|
+
head: slug,
|
|
235
|
+
title: plan.commit,
|
|
236
|
+
body: pullRequestBody({
|
|
237
|
+
criteria,
|
|
238
|
+
implementation,
|
|
239
|
+
review,
|
|
240
|
+
checks,
|
|
241
|
+
reviewRounds: reviewRounds(state),
|
|
242
|
+
specPath,
|
|
243
|
+
planPath,
|
|
244
|
+
baseCommit,
|
|
245
|
+
runId: state.id,
|
|
246
|
+
}),
|
|
247
|
+
});
|
|
248
|
+
log(`Pull request: ${pullRequest}`);
|
|
249
|
+
await git.switchTo(dir, base);
|
|
250
|
+
log(`Back on ${base}`);
|
|
251
|
+
return { pullRequest };
|
|
252
|
+
}), { ok: END }),
|
|
253
|
+
},
|
|
254
|
+
// Also called for a failed run, which opened no pull request.
|
|
255
|
+
presentResult: (state) => {
|
|
256
|
+
const { pullRequest, checks } = facts(state);
|
|
257
|
+
if (typeof pullRequest !== "string")
|
|
258
|
+
return [];
|
|
259
|
+
const rounds = reviewRounds(state);
|
|
260
|
+
return [
|
|
261
|
+
`Pull request: ${pullRequest}`,
|
|
262
|
+
`Review: approved ${rounds === 0 ? "at the first review" : `after ${rounds} round${rounds === 1 ? "" : "s"} of changes`}`,
|
|
263
|
+
`Checks passed: ${checks.map(({ name }) => name).join(", ")}`,
|
|
264
|
+
];
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=implement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"implement.js","sourceRoot":"","sources":["../../../src/app/workflows/implement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defineWorkflow, END, node, step, z } from "@clemrig/flow";
|
|
2
|
+
import { isSlug, parseIssue } from "../../domain/issue.js";
|
|
3
|
+
import { parseSpec } from "../../domain/spec.js";
|
|
4
|
+
import { hasArtifact, readDraft, writeArtifact } from "../../system/issues.js";
|
|
5
|
+
const input = z.object({
|
|
6
|
+
issue: z
|
|
7
|
+
.string()
|
|
8
|
+
.refine(isSlug, "Expected lowercase words separated by hyphens"),
|
|
9
|
+
kind: z.enum(["issue", "spec"]),
|
|
10
|
+
file: z.string().min(1),
|
|
11
|
+
});
|
|
12
|
+
/** Checks a draft written by an agent, then writes it as the issue's issue.md or spec.md. */
|
|
13
|
+
export const issueSave = defineWorkflow({
|
|
14
|
+
name: "issue-save",
|
|
15
|
+
input,
|
|
16
|
+
initial: "save",
|
|
17
|
+
nodes: {
|
|
18
|
+
save: node(step(async ({ dir, state }) => {
|
|
19
|
+
const { issue, kind, file } = state.input;
|
|
20
|
+
if (kind === "spec" && !(await hasArtifact(dir, issue, "issue")))
|
|
21
|
+
throw new Error(`Issue ${issue} does not exist: save its issue.md first`);
|
|
22
|
+
const text = await readDraft(file);
|
|
23
|
+
const parsed = kind === "issue" ? parseIssue(text) : parseSpec(text);
|
|
24
|
+
if (!parsed.ok)
|
|
25
|
+
throw new Error([
|
|
26
|
+
`Invalid ${kind}.md draft ${file}:`,
|
|
27
|
+
...parsed.problems.map((problem) => `- ${problem}`),
|
|
28
|
+
].join("\n"));
|
|
29
|
+
return { path: await writeArtifact(dir, issue, kind, text) };
|
|
30
|
+
}), { ok: END }),
|
|
31
|
+
},
|
|
32
|
+
// Also called for a failed run, which saved nothing.
|
|
33
|
+
presentResult: ({ data }) => typeof data.path === "string" ? [`Saved ${data.path}`] : [],
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=issue-save.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-save.js","sourceRoot":"","sources":["../../../src/app/workflows/issue-save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE/E,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;IACrB,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,MAAM,CAAC,MAAM,EAAE,+CAA+C,CAAC;IAClE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACxB,CAAC,CAAC;AAGH,6FAA6F;AAC7F,MAAM,CAAC,MAAM,SAAS,GAAG,cAAc,CAAC;IACtC,IAAI,EAAE,YAAY;IAClB,KAAK;IACL,OAAO,EAAE,MAAM;IACf,KAAK,EAAE;QACL,IAAI,EAAE,IAAI,CACR,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;YAC5B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,KAAc,CAAC;YACnD,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;gBAC9D,MAAM,IAAI,KAAK,CACb,SAAS,KAAK,0CAA0C,CACzD,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACrE,IAAI,CAAC,MAAM,CAAC,EAAE;gBACZ,MAAM,IAAI,KAAK,CACb;oBACE,WAAW,IAAI,aAAa,IAAI,GAAG;oBACnC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC;iBACpD,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;YACJ,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QAC/D,CAAC,CAAC,EACF,EAAE,EAAE,EAAE,GAAG,EAAE,CACZ;KACF;IACD,qDAAqD;IACrD,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAC1B,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;CAC9D,CAAC,CAAC"}
|
package/dist/cli/application.js
CHANGED
|
@@ -51,7 +51,7 @@ export async function main(argv, directory) {
|
|
|
51
51
|
if (error)
|
|
52
52
|
process.stderr.write(`factory: factory.ts cannot be loaded, results use the default rendering: ${error}\n`);
|
|
53
53
|
if (args.command === "ui")
|
|
54
|
-
return await ui(factory, dashboardPort);
|
|
54
|
+
return await ui(factory, dashboardPort, error);
|
|
55
55
|
const reporter = new TerminalReporter((state) => presentResult(factory, state), args.json);
|
|
56
56
|
return await status(factory, reporter, args.positional[0]);
|
|
57
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/cli/application.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/cli/application.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/help.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const help = "factory \u2014
|
|
1
|
+
export declare const help = "factory \u2014 this repository's issues, from spec to pull request, with .factory/\n\n factory init create .factory/ here and install it\n factory doctor [--json] check Node, workflows, prompts and runtimes\n factory run WORKFLOW [--INPUT VALUE\u2026] [--max-cost-usd USD] [--json]\n factory status [RUN_ID] [--json] list this repository's runs, or show one\n factory ui [--port N] serve the live read-only Kanban, runs under /runs/\n\nCommands other than init and help use the nearest .factory/ in the current directory\nor a parent, with the factory version installed there. factory doctor lists each\nworkflow's input options. factory run issue-save saves an issue or its spec;\nfactory run implement --issue SLUG takes a pushed spec to a pull request.\n.factory/.env is loaded; shell variables take precedence.\n--max-cost-usd fails the run once its agents' announced cost exceeds it, instead\nof the workflow's maxCostUsd. --json writes events, then the result, as JSON lines.\nCtrl-C stops a run, which ends failed; press it again to quit at once.\nExit codes: 0 completed, 1 error or failed run, 130 second Ctrl-C.\n";
|
package/dist/cli/help.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
export const help = `factory —
|
|
1
|
+
export const help = `factory — this repository's issues, from spec to pull request, with .factory/
|
|
2
2
|
|
|
3
3
|
factory init create .factory/ here and install it
|
|
4
4
|
factory doctor [--json] check Node, workflows, prompts and runtimes
|
|
5
5
|
factory run WORKFLOW [--INPUT VALUE…] [--max-cost-usd USD] [--json]
|
|
6
6
|
factory status [RUN_ID] [--json] list this repository's runs, or show one
|
|
7
|
-
factory ui [--port N] serve
|
|
7
|
+
factory ui [--port N] serve the live read-only Kanban, runs under /runs/
|
|
8
8
|
|
|
9
9
|
Commands other than init and help use the nearest .factory/ in the current directory
|
|
10
10
|
or a parent, with the factory version installed there. factory doctor lists each
|
|
11
|
-
workflow's input options.
|
|
11
|
+
workflow's input options. factory run issue-save saves an issue or its spec;
|
|
12
|
+
factory run implement --issue SLUG takes a pushed spec to a pull request.
|
|
13
|
+
.factory/.env is loaded; shell variables take precedence.
|
|
12
14
|
--max-cost-usd fails the run once its agents' announced cost exceeds it, instead
|
|
13
15
|
of the workflow's maxCostUsd. --json writes events, then the result, as JSON lines.
|
|
14
16
|
Ctrl-C stops a run, which ends failed; press it again to quit at once.
|
package/dist/cli/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;CAiBnB,CAAC"}
|
package/dist/cli/init.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `factory init`: creates `.factory/` in `cwd` from the templates, pinned to this
|
|
3
|
-
* factory version, then installs it. An existing
|
|
4
|
-
* a failed installation keeps the files.
|
|
3
|
+
* factory version, and the `issue` skill, then installs it. An existing
|
|
4
|
+
* `.factory/` or skill is refused untouched; a failed installation keeps the files.
|
|
5
5
|
*/
|
|
6
6
|
export declare function init(cwd: string): Promise<number>;
|
package/dist/cli/init.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { createFactory, installFactory } from "../app/init.js";
|
|
2
2
|
/**
|
|
3
3
|
* `factory init`: creates `.factory/` in `cwd` from the templates, pinned to this
|
|
4
|
-
* factory version, then installs it. An existing
|
|
5
|
-
* a failed installation keeps the files.
|
|
4
|
+
* factory version, and the `issue` skill, then installs it. An existing
|
|
5
|
+
* `.factory/` or skill is refused untouched; a failed installation keeps the files.
|
|
6
6
|
*/
|
|
7
7
|
export async function init(cwd) {
|
|
8
8
|
const { factoryDir, version } = await createFactory(cwd);
|
|
9
|
-
process.stdout.write(`Created ${factoryDir}; installing @clemrig/factory ${version}…\n`);
|
|
9
|
+
process.stdout.write(`Created ${factoryDir} and the issue skill (.agents/skills/issue, linked from .claude/skills/issue); installing @clemrig/factory ${version}…\n`);
|
|
10
10
|
const install = await installFactory(factoryDir);
|
|
11
11
|
if (!install.ok) {
|
|
12
12
|
process.stderr.write(`${install.output}\n`);
|
|
13
13
|
throw new Error("Installation failed; .factory/ is kept: run npm install --prefix .factory");
|
|
14
14
|
}
|
|
15
|
-
process.stdout.write(
|
|
15
|
+
process.stdout.write("Next: set your checks in .factory/factory.ts, run factory doctor, commit .factory/, .agents/ and .claude/skills/, then use /issue in Claude Code, Codex or Pi\n");
|
|
16
16
|
return 0;
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=init.js.map
|
package/dist/cli/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW;IACpC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,WAAW,UAAU,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW;IACpC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,WAAW,UAAU,8GAA8G,OAAO,KAAK,CAChJ,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iKAAiK,CAClK,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/cli/reporter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { elapsedMs, runtimeLabels, } from "@clemrig/flow";
|
|
1
|
+
import { elapsedMs, runtimeLabels, summarizeRun, } from "@clemrig/flow";
|
|
2
2
|
function duration(ms) {
|
|
3
3
|
const seconds = Math.max(0, Math.floor(ms / 1000));
|
|
4
4
|
const hours = Math.floor(seconds / 3600);
|
|
@@ -10,34 +10,62 @@ export function metricsSummary(state, now = Date.now()) {
|
|
|
10
10
|
const elapsed = elapsedMs(state, now);
|
|
11
11
|
const usage = state.metrics?.usage;
|
|
12
12
|
const count = (n) => n.toLocaleString("en-US");
|
|
13
|
+
const { costUsd } = summarizeRun(state);
|
|
13
14
|
return [
|
|
14
15
|
`Duration: ${elapsed === null ? "unavailable" : duration(elapsed)}`,
|
|
15
16
|
!usage
|
|
16
17
|
? "Agents: unavailable"
|
|
17
18
|
: usage.responses
|
|
18
|
-
? `Agents: ${count(usage.input)} input · ${count(usage.output)} output · ${count(usage.cacheRead)} cache read · ${count(usage.cacheWrite)} cache write tokens · estimated cost ${
|
|
19
|
+
? `Agents: ${count(usage.input)} input · ${count(usage.output)} output · ${count(usage.cacheRead)} cache read · ${count(usage.cacheWrite)} cache write tokens · estimated cost ${costUsd === null ? "unavailable" : `${costUsd.toFixed(6)} USD`}${usage.missing ? " (partial)" : ""}`
|
|
19
20
|
: `Agents: ${usage.missing ? "unavailable (partial)" : "no measured call"}`,
|
|
20
21
|
];
|
|
21
22
|
}
|
|
23
|
+
/** A setting's name as the operator reads it: `permissionMode` → `permission mode`. */
|
|
24
|
+
const settingLabel = (key) => key.replace(/[A-Z]/g, (letter) => ` ${letter.toLowerCase()}`);
|
|
25
|
+
/**
|
|
26
|
+
* An agent call's start with its settings as its runtime recorded them, whatever
|
|
27
|
+
* the runtime: its thinking and its other single values, then its tools when it
|
|
28
|
+
* names them; other lists stay in the dashboard.
|
|
29
|
+
*/
|
|
30
|
+
function settingsLines(started, settings) {
|
|
31
|
+
const values = Object.entries(settings).flatMap(([key, value]) => key === "thinking" ||
|
|
32
|
+
key === "timeoutMs" ||
|
|
33
|
+
value === undefined ||
|
|
34
|
+
Array.isArray(value)
|
|
35
|
+
? []
|
|
36
|
+
: [`${settingLabel(key)} ${String(value)}`]);
|
|
37
|
+
const tools = "tools" in settings ? settings.tools : undefined;
|
|
38
|
+
return [
|
|
39
|
+
[started, `thinking ${settings.thinking}`, ...values].join(" · "),
|
|
40
|
+
...(tools ? [`Tools: ${tools.join(", ") || "none"}`] : []),
|
|
41
|
+
];
|
|
42
|
+
}
|
|
22
43
|
const icons = { started: "→", passed: "✓", failed: "✗", completed: "✓" };
|
|
23
44
|
const inSeconds = (ms) => `${(ms / 1000).toFixed(1)} s`;
|
|
24
|
-
/**
|
|
25
|
-
|
|
45
|
+
/**
|
|
46
|
+
* An agent call's start with its model, thinking, runtime choices and tools, its end, its
|
|
47
|
+
* finished tools and its warnings; not each response.
|
|
48
|
+
*/
|
|
49
|
+
function activityLines(activity) {
|
|
26
50
|
switch (activity.kind) {
|
|
27
|
-
case "call":
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
51
|
+
case "call": {
|
|
52
|
+
const runtime = runtimeLabels[activity.runtime];
|
|
53
|
+
if (activity.status !== "started")
|
|
54
|
+
return [`${runtime} ${activity.status}`];
|
|
55
|
+
const started = `${runtime} started with ${activity.model}`;
|
|
56
|
+
const { settings } = activity;
|
|
57
|
+
return settings ? settingsLines(started, settings) : [started];
|
|
58
|
+
}
|
|
31
59
|
case "tool":
|
|
32
60
|
return activity.status === "started"
|
|
33
|
-
?
|
|
61
|
+
? []
|
|
34
62
|
: activity.status === "failed"
|
|
35
|
-
? `${activity.name} failed after ${inSeconds(activity.durationMs)}`
|
|
36
|
-
: `${activity.name} ${inSeconds(activity.durationMs)}
|
|
63
|
+
? [`${activity.name} failed after ${inSeconds(activity.durationMs)}`]
|
|
64
|
+
: [`${activity.name} ${inSeconds(activity.durationMs)}`];
|
|
37
65
|
case "warning":
|
|
38
|
-
return activity.message;
|
|
66
|
+
return [activity.message];
|
|
39
67
|
default:
|
|
40
|
-
return
|
|
68
|
+
return [];
|
|
41
69
|
}
|
|
42
70
|
}
|
|
43
71
|
/** Stage events and journal on stderr; results on stdout; JSON lines on stdout with --json. */
|
|
@@ -60,8 +88,7 @@ export class TerminalReporter {
|
|
|
60
88
|
return;
|
|
61
89
|
}
|
|
62
90
|
if (event.type === "agent") {
|
|
63
|
-
const line
|
|
64
|
-
if (line)
|
|
91
|
+
for (const line of activityLines(event.activity))
|
|
65
92
|
this.detail(line);
|
|
66
93
|
return;
|
|
67
94
|
}
|
package/dist/cli/reporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/cli/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/cli/reporter.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/ui.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { Factory } from "../app/factory.js";
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* `factory ui`: serves the Kanban of the repository's issues, and the dashboard
|
|
4
|
+
* of its runs under `/runs/`, until Ctrl-C, on `port` or one the system chooses.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ui(factory: Factory, port?: number, loadError?: string): Promise<number>;
|
package/dist/cli/ui.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { startFactoryUi } from "@clemrig/factory-ui";
|
|
3
|
+
import { dashboardHandler } from "@clemrig/flow-ui";
|
|
4
|
+
import { readBoard } from "../app/board.js";
|
|
3
5
|
import { presentResult } from "../app/runs.js";
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* `factory ui`: serves the Kanban of the repository's issues, and the dashboard
|
|
8
|
+
* of its runs under `/runs/`, until Ctrl-C, on `port` or one the system chooses.
|
|
9
|
+
*/
|
|
10
|
+
export async function ui(factory, port, loadError) {
|
|
11
|
+
const label = basename(factory.dir);
|
|
12
|
+
const runs = await dashboardHandler({
|
|
7
13
|
runsDir: factory.runsDir,
|
|
8
14
|
title: "factory",
|
|
9
|
-
label
|
|
15
|
+
label,
|
|
10
16
|
presentResult: (state) => presentResult(factory, state),
|
|
17
|
+
});
|
|
18
|
+
const page = await startFactoryUi({
|
|
19
|
+
title: "factory",
|
|
20
|
+
label,
|
|
21
|
+
// The board the factory computes is what the page shows: checked here, where both meet.
|
|
22
|
+
board: () => readBoard(factory, loadError),
|
|
23
|
+
runs,
|
|
11
24
|
}, port);
|
|
12
|
-
process.stdout.write(`factory ui: ${
|
|
25
|
+
process.stdout.write(`factory ui: ${page.url} (runs: ${page.url}runs/; read-only; Ctrl-C to stop)\n`);
|
|
13
26
|
await new Promise((resolve) => {
|
|
14
27
|
const stop = () => {
|
|
15
28
|
process.off("SIGINT", stop);
|
|
@@ -19,7 +32,7 @@ export async function ui(factory, port) {
|
|
|
19
32
|
process.on("SIGINT", stop);
|
|
20
33
|
process.on("SIGTERM", stop);
|
|
21
34
|
});
|
|
22
|
-
await
|
|
35
|
+
await page.close();
|
|
23
36
|
return 0;
|
|
24
37
|
}
|
|
25
38
|
//# sourceMappingURL=ui.js.map
|