@pat-lewczuk/cezar 0.1.0 → 0.1.2
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/config.d.ts +62 -0
- package/dist/config.js +49 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-runner.d.ts +13 -0
- package/dist/core/claude-cli-runner.js +23 -2
- package/dist/core/claude-cli-runner.js.map +1 -1
- package/dist/git-worktree.d.ts +56 -0
- package/dist/git-worktree.js +143 -0
- package/dist/git-worktree.js.map +1 -0
- package/dist/handoff.d.ts +42 -0
- package/dist/handoff.js +120 -0
- package/dist/handoff.js.map +1 -0
- package/dist/index.js +27 -6
- package/dist/index.js.map +1 -1
- package/dist/planner.d.ts +17 -0
- package/dist/planner.js +244 -0
- package/dist/planner.js.map +1 -0
- package/dist/runs/store.d.ts +40 -13
- package/dist/runs/store.js +33 -3
- package/dist/runs/store.js.map +1 -1
- package/dist/server/git.d.ts +5 -0
- package/dist/server/git.js +38 -0
- package/dist/server/git.js.map +1 -1
- package/dist/server/github.d.ts +29 -0
- package/dist/server/github.js +140 -0
- package/dist/server/github.js.map +1 -0
- package/dist/server/launch-key.d.ts +7 -0
- package/dist/server/launch-key.js +33 -0
- package/dist/server/launch-key.js.map +1 -0
- package/dist/server/pr.d.ts +22 -0
- package/dist/server/pr.js +98 -0
- package/dist/server/pr.js.map +1 -0
- package/dist/server/server.js +537 -19
- package/dist/server/server.js.map +1 -1
- package/dist/skills-remote.d.ts +35 -0
- package/dist/skills-remote.js +266 -0
- package/dist/skills-remote.js.map +1 -0
- package/dist/skills.d.ts +20 -6
- package/dist/skills.js +77 -12
- package/dist/skills.js.map +1 -1
- package/dist/todos.d.ts +60 -0
- package/dist/todos.js +166 -0
- package/dist/todos.js.map +1 -0
- package/dist/workflows/load.js +8 -10
- package/dist/workflows/load.js.map +1 -1
- package/dist/workflows/run.d.ts +62 -3
- package/dist/workflows/run.js +351 -45
- package/dist/workflows/run.js.map +1 -1
- package/dist/workflows/types.d.ts +96 -26
- package/dist/workflows/types.js +73 -2
- package/dist/workflows/types.js.map +1 -1
- package/package.json +1 -1
- package/scripts/mock-claude.mjs +118 -0
- package/web/app.js +2821 -154
- package/web/index.html +82 -23
- package/web/open-mercato.svg +11 -0
- package/web/style.css +1652 -222
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { RunRecord } from '../runs/store.js';
|
|
2
|
+
export type DraftPrOutcome = {
|
|
3
|
+
ok: true;
|
|
4
|
+
url: string;
|
|
5
|
+
dryRun: boolean;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
error: string;
|
|
9
|
+
};
|
|
10
|
+
export interface DraftPrInput {
|
|
11
|
+
repoRoot: string;
|
|
12
|
+
run: RunRecord;
|
|
13
|
+
/** The task's handoff.md — becomes the PR body (goal + progress skim). */
|
|
14
|
+
handoffText: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function createDraftPr(input: DraftPrInput): Promise<DraftPrOutcome>;
|
|
17
|
+
/**
|
|
18
|
+
* PR body from the handoff journal: the "## Goal" section (task text as
|
|
19
|
+
* fallback) + the first ~10 lines of "## Progress log" (newest first) +
|
|
20
|
+
* the cezar footer.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildPrBody(handoffText: string, task: string): string;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { autosaveCommit } from '../git-worktree.js';
|
|
3
|
+
/**
|
|
4
|
+
* Draft-PR creation for the review gate (spec 009): final autosave-commit →
|
|
5
|
+
* `git push -u origin cez/<id8>` → `gh pr create --draft`, all executed in
|
|
6
|
+
* the task worktree (gh picks the repo up from the worktree's remote).
|
|
7
|
+
* Every failure maps to a one-line human error — the GUI shows it as a toast
|
|
8
|
+
* plus the manual `git merge <branch>` fallback. Never throws.
|
|
9
|
+
*/
|
|
10
|
+
const PR_URL_RE = /https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/pull\/\d+/;
|
|
11
|
+
const PUSH_TIMEOUT_MS = 60_000;
|
|
12
|
+
const PROGRESS_LINES_MAX = 10;
|
|
13
|
+
export async function createDraftPr(input) {
|
|
14
|
+
const { run } = input;
|
|
15
|
+
const worktree = run.worktreePath;
|
|
16
|
+
const branch = run.branch;
|
|
17
|
+
if (!worktree || !branch) {
|
|
18
|
+
return { ok: false, error: 'this task has no worktree/branch to publish' };
|
|
19
|
+
}
|
|
20
|
+
// Final autosave: the branch must hold everything before it leaves the box.
|
|
21
|
+
await autosaveCommit(worktree);
|
|
22
|
+
// DRY-RUN (CEZ_DRY_RUN=1): no push, no gh — simulate success with a fake PR
|
|
23
|
+
// URL so the whole review → PR flow is testable without GitHub.
|
|
24
|
+
if (process.env.CEZ_DRY_RUN === '1') {
|
|
25
|
+
return { ok: true, url: 'https://github.com/open-mercato/demo/pull/777', dryRun: true };
|
|
26
|
+
}
|
|
27
|
+
const remote = await exec('git', ['remote', 'get-url', 'origin'], worktree);
|
|
28
|
+
if (!remote.ok || !remote.stdout.trim()) {
|
|
29
|
+
return { ok: false, error: 'no git remote — add one (git remote add origin <url>) or merge the branch locally' };
|
|
30
|
+
}
|
|
31
|
+
const push = await exec('git', ['push', '-u', 'origin', branch], worktree, PUSH_TIMEOUT_MS);
|
|
32
|
+
if (!push.ok) {
|
|
33
|
+
return { ok: false, error: `git push failed — ${tail(push.stderr) || 'unknown error'}` };
|
|
34
|
+
}
|
|
35
|
+
const body = buildPrBody(input.handoffText, run.task);
|
|
36
|
+
// Target the branch the worktree forked from (config `baseBranch`) — without
|
|
37
|
+
// --base, gh aims at the repo default (main) even when work started on
|
|
38
|
+
// develop. `origin/x` normalizes to `x`; a raw sha (detached-HEAD fork
|
|
39
|
+
// point) can't be a PR base, so gh falls back to the default branch.
|
|
40
|
+
const prBase = run.baseBranch?.replace(/^origin\//, '');
|
|
41
|
+
const baseArgs = prBase && !/^[0-9a-f]{7,40}$/i.test(prBase) ? ['--base', prBase] : [];
|
|
42
|
+
const pr = await exec('gh', ['pr', 'create', '--draft', '--head', branch, ...baseArgs, '--title', run.title, '--body', body], worktree, PUSH_TIMEOUT_MS);
|
|
43
|
+
if (!pr.ok) {
|
|
44
|
+
if (pr.notFound) {
|
|
45
|
+
return { ok: false, error: 'gh not found — install the GitHub CLI and run `gh auth login`, or merge the branch locally' };
|
|
46
|
+
}
|
|
47
|
+
const hint = /auth|log ?in|credential/i.test(pr.stderr) ? ' (try `gh auth login`)' : '';
|
|
48
|
+
return { ok: false, error: `gh pr create failed — ${tail(pr.stderr) || 'unknown error'}${hint}` };
|
|
49
|
+
}
|
|
50
|
+
// gh prints the PR URL on stdout; some versions echo it to stderr instead.
|
|
51
|
+
const match = PR_URL_RE.exec(`${pr.stdout}\n${pr.stderr}`);
|
|
52
|
+
if (!match) {
|
|
53
|
+
return { ok: false, error: 'gh pr create returned no PR URL — check `gh pr list` manually' };
|
|
54
|
+
}
|
|
55
|
+
return { ok: true, url: match[0], dryRun: false };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* PR body from the handoff journal: the "## Goal" section (task text as
|
|
59
|
+
* fallback) + the first ~10 lines of "## Progress log" (newest first) +
|
|
60
|
+
* the cezar footer.
|
|
61
|
+
*/
|
|
62
|
+
export function buildPrBody(handoffText, task) {
|
|
63
|
+
const goal = section(handoffText, '## Goal') || task.trim();
|
|
64
|
+
const progress = section(handoffText, '## Progress log')
|
|
65
|
+
.split('\n')
|
|
66
|
+
.filter((l) => l.trim())
|
|
67
|
+
.slice(0, PROGRESS_LINES_MAX)
|
|
68
|
+
.join('\n');
|
|
69
|
+
const parts = ['## Goal', '', goal];
|
|
70
|
+
if (progress)
|
|
71
|
+
parts.push('', '## Progress log', '', progress);
|
|
72
|
+
parts.push('', '---', '', '🤖 made with cezar');
|
|
73
|
+
return parts.join('\n');
|
|
74
|
+
}
|
|
75
|
+
/** Text of one `## Header` section, up to the next `## ` header. */
|
|
76
|
+
function section(text, header) {
|
|
77
|
+
const start = text.indexOf(`${header}\n`);
|
|
78
|
+
if (start < 0)
|
|
79
|
+
return '';
|
|
80
|
+
const rest = text.slice(start + header.length + 1);
|
|
81
|
+
const next = rest.indexOf('\n## ');
|
|
82
|
+
return (next >= 0 ? rest.slice(0, next) : rest).trim();
|
|
83
|
+
}
|
|
84
|
+
/** Last 3 stderr lines, pipe-joined — enough context, toast-sized. */
|
|
85
|
+
function tail(stderr) {
|
|
86
|
+
return stderr.trim().split('\n').slice(-3).join(' | ').slice(0, 300);
|
|
87
|
+
}
|
|
88
|
+
function exec(bin, args, cwd, timeoutMs = 30_000) {
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
execFile(bin, args, { cwd, timeout: timeoutMs, maxBuffer: 4 * 1024 * 1024, encoding: 'utf8' }, (err, stdout, stderr) => resolve({
|
|
91
|
+
ok: !err,
|
|
92
|
+
stdout: stdout ?? '',
|
|
93
|
+
stderr: stderr ?? '',
|
|
94
|
+
notFound: err?.code === 'ENOENT',
|
|
95
|
+
}));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/server/pr.ts"],"names":[],"mappings":"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"}
|