@open-mercato/cezar 0.1.5-pr506.357
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 +573 -0
- package/dist/config.d.ts +144 -0
- package/dist/config.js +106 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-runner.d.ts +169 -0
- package/dist/core/agent-runner.js +23 -0
- package/dist/core/agent-runner.js.map +1 -0
- package/dist/core/backend-detect.d.ts +16 -0
- package/dist/core/backend-detect.js +118 -0
- package/dist/core/backend-detect.js.map +1 -0
- package/dist/core/claude-cli-runner.d.ts +56 -0
- package/dist/core/claude-cli-runner.js +416 -0
- package/dist/core/claude-cli-runner.js.map +1 -0
- package/dist/core/claude-ui-mapper.d.ts +71 -0
- package/dist/core/claude-ui-mapper.js +567 -0
- package/dist/core/claude-ui-mapper.js.map +1 -0
- package/dist/core/codex-app-server-runner.d.ts +29 -0
- package/dist/core/codex-app-server-runner.js +489 -0
- package/dist/core/codex-app-server-runner.js.map +1 -0
- package/dist/core/codex-ui-mapper.d.ts +63 -0
- package/dist/core/codex-ui-mapper.js +491 -0
- package/dist/core/codex-ui-mapper.js.map +1 -0
- package/dist/core/ndjson.d.ts +6 -0
- package/dist/core/ndjson.js +23 -0
- package/dist/core/ndjson.js.map +1 -0
- package/dist/core/opencode-server-runner.d.ts +30 -0
- package/dist/core/opencode-server-runner.js +488 -0
- package/dist/core/opencode-server-runner.js.map +1 -0
- package/dist/core/opencode-ui-mapper.d.ts +105 -0
- package/dist/core/opencode-ui-mapper.js +588 -0
- package/dist/core/opencode-ui-mapper.js.map +1 -0
- package/dist/core/process-usage.d.ts +63 -0
- package/dist/core/process-usage.js +181 -0
- package/dist/core/process-usage.js.map +1 -0
- package/dist/core/runner-factory.d.ts +8 -0
- package/dist/core/runner-factory.js +22 -0
- package/dist/core/runner-factory.js.map +1 -0
- package/dist/core/tool-display.d.ts +30 -0
- package/dist/core/tool-display.js +156 -0
- package/dist/core/tool-display.js.map +1 -0
- package/dist/core/ui-events.d.ts +308 -0
- package/dist/core/ui-events.js +25 -0
- package/dist/core/ui-events.js.map +1 -0
- package/dist/core/usage.d.ts +11 -0
- package/dist/core/usage.js +15 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/git-worktree.d.ts +88 -0
- package/dist/git-worktree.js +297 -0
- package/dist/git-worktree.js.map +1 -0
- package/dist/handoff.d.ts +62 -0
- package/dist/handoff.js +147 -0
- package/dist/handoff.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +466 -0
- package/dist/index.js.map +1 -0
- package/dist/install-as-command.d.ts +39 -0
- package/dist/install-as-command.js +51 -0
- package/dist/install-as-command.js.map +1 -0
- package/dist/pack-check.d.ts +17 -0
- package/dist/pack-check.js +27 -0
- package/dist/pack-check.js.map +1 -0
- package/dist/paths.d.ts +23 -0
- package/dist/paths.js +34 -0
- package/dist/paths.js.map +1 -0
- package/dist/planner.d.ts +17 -0
- package/dist/planner.js +248 -0
- package/dist/planner.js.map +1 -0
- package/dist/release/snapshot.d.ts +64 -0
- package/dist/release/snapshot.js +75 -0
- package/dist/release/snapshot.js.map +1 -0
- package/dist/release/stable.d.ts +46 -0
- package/dist/release/stable.js +57 -0
- package/dist/release/stable.js.map +1 -0
- package/dist/runs/auto-name.d.ts +75 -0
- package/dist/runs/auto-name.js +168 -0
- package/dist/runs/auto-name.js.map +1 -0
- package/dist/runs/retention.d.ts +60 -0
- package/dist/runs/retention.js +86 -0
- package/dist/runs/retention.js.map +1 -0
- package/dist/runs/review-gate.d.ts +18 -0
- package/dist/runs/review-gate.js +21 -0
- package/dist/runs/review-gate.js.map +1 -0
- package/dist/runs/store.d.ts +408 -0
- package/dist/runs/store.js +526 -0
- package/dist/runs/store.js.map +1 -0
- package/dist/runs/task-refs.d.ts +24 -0
- package/dist/runs/task-refs.js +74 -0
- package/dist/runs/task-refs.js.map +1 -0
- package/dist/runs/ui-event-sink.d.ts +81 -0
- package/dist/runs/ui-event-sink.js +210 -0
- package/dist/runs/ui-event-sink.js.map +1 -0
- package/dist/server/capabilities.d.ts +33 -0
- package/dist/server/capabilities.js +43 -0
- package/dist/server/capabilities.js.map +1 -0
- package/dist/server/forge/github.d.ts +70 -0
- package/dist/server/forge/github.js +375 -0
- package/dist/server/forge/github.js.map +1 -0
- package/dist/server/forge/index.d.ts +24 -0
- package/dist/server/forge/index.js +45 -0
- package/dist/server/forge/index.js.map +1 -0
- package/dist/server/forge/types.d.ts +80 -0
- package/dist/server/forge/types.js +2 -0
- package/dist/server/forge/types.js.map +1 -0
- package/dist/server/git-changes.d.ts +195 -0
- package/dist/server/git-changes.js +497 -0
- package/dist/server/git-changes.js.map +1 -0
- package/dist/server/git.d.ts +26 -0
- package/dist/server/git.js +103 -0
- package/dist/server/git.js.map +1 -0
- package/dist/server/github.d.ts +8 -0
- package/dist/server/github.js +8 -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/open-in-app.d.ts +51 -0
- package/dist/server/open-in-app.js +189 -0
- package/dist/server/open-in-app.js.map +1 -0
- package/dist/server/open-in-terminal.d.ts +25 -0
- package/dist/server/open-in-terminal.js +120 -0
- package/dist/server/open-in-terminal.js.map +1 -0
- package/dist/server/pr.d.ts +7 -0
- package/dist/server/pr.js +7 -0
- package/dist/server/pr.js.map +1 -0
- package/dist/server/server.d.ts +41 -0
- package/dist/server/server.js +1390 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/static-ui.d.ts +49 -0
- package/dist/server/static-ui.js +92 -0
- package/dist/server/static-ui.js.map +1 -0
- package/dist/server/wsl.d.ts +25 -0
- package/dist/server/wsl.js +92 -0
- package/dist/server/wsl.js.map +1 -0
- package/dist/server-install/engine.d.ts +33 -0
- package/dist/server-install/engine.js +314 -0
- package/dist/server-install/engine.js.map +1 -0
- package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
- package/dist/server-install/platforms/macosx-ngrok.js +345 -0
- package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
- package/dist/server-install/platforms/ubuntu-vps.d.ts +39 -0
- package/dist/server-install/platforms/ubuntu-vps.js +746 -0
- package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
- package/dist/server-install/state.d.ts +26 -0
- package/dist/server-install/state.js +125 -0
- package/dist/server-install/state.js.map +1 -0
- package/dist/server-install/steps.d.ts +109 -0
- package/dist/server-install/steps.js +330 -0
- package/dist/server-install/steps.js.map +1 -0
- package/dist/server-install/strategies.d.ts +4 -0
- package/dist/server-install/strategies.js +20 -0
- package/dist/server-install/strategies.js.map +1 -0
- package/dist/server-install/types.d.ts +597 -0
- package/dist/server-install/types.js +98 -0
- package/dist/server-install/types.js.map +1 -0
- package/dist/server-install/ui.d.ts +42 -0
- package/dist/server-install/ui.js +130 -0
- package/dist/server-install/ui.js.map +1 -0
- package/dist/skills-banner.d.ts +21 -0
- package/dist/skills-banner.js +40 -0
- package/dist/skills-banner.js.map +1 -0
- 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 +45 -0
- package/dist/skills.js +182 -0
- package/dist/skills.js.map +1 -0
- package/dist/todos.d.ts +63 -0
- package/dist/todos.js +168 -0
- package/dist/todos.js.map +1 -0
- package/dist/ui-state.d.ts +12 -0
- package/dist/ui-state.js +25 -0
- package/dist/ui-state.js.map +1 -0
- package/dist/update-check.d.ts +12 -0
- package/dist/update-check.js +41 -0
- package/dist/update-check.js.map +1 -0
- package/dist/workflows/load.d.ts +15 -0
- package/dist/workflows/load.js +56 -0
- package/dist/workflows/load.js.map +1 -0
- package/dist/workflows/run.d.ts +281 -0
- package/dist/workflows/run.js +1511 -0
- package/dist/workflows/run.js.map +1 -0
- package/dist/workflows/types.d.ts +307 -0
- package/dist/workflows/types.js +171 -0
- package/dist/workflows/types.js.map +1 -0
- package/package.json +90 -0
- package/scripts/check-pack.mjs +46 -0
- package/scripts/dev.mjs +74 -0
- package/scripts/install-as-command.mjs +120 -0
- package/scripts/mock-claude.mjs +310 -0
- package/scripts/release-snapshot.mjs +130 -0
- package/scripts/release.mjs +119 -0
- package/scripts/test-process-usage.mjs +47 -0
- package/web/dist/assets/arrow-left-BE957rJs.js +1 -0
- package/web/dist/assets/bundle-mjs-DLPpRFyl.js +1 -0
- package/web/dist/assets/centered-state-BddhEEtO.js +43 -0
- package/web/dist/assets/chunk-BO2N2NFS-f5igTtpB.js +131 -0
- package/web/dist/assets/command-CjhFbABo.js +1 -0
- package/web/dist/assets/compare-variants-Cs52IAEG.js +1 -0
- package/web/dist/assets/core-BuMqAF_1.js +12 -0
- package/web/dist/assets/css-BsVw1vtW.js +1 -0
- package/web/dist/assets/dialog-DFvXTkFv.js +1 -0
- package/web/dist/assets/diff-view-C9b8AITq.js +4 -0
- package/web/dist/assets/diff-woXpYk--.js +1 -0
- package/web/dist/assets/dist-FBs4wmIY.js +1 -0
- package/web/dist/assets/dist-o_kVMXjg.js +1 -0
- package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
- package/web/dist/assets/file-BVuztAOd.js +1 -0
- package/web/dist/assets/folder-0pJ1NZ_S.js +1 -0
- package/web/dist/assets/git-pull-request-DJkAMT0f.js +1 -0
- package/web/dist/assets/git-toolbar-CwhQdx3J.js +1 -0
- package/web/dist/assets/github-D0rAX4-r.js +1 -0
- package/web/dist/assets/go-rLFTqkRN.js +1 -0
- package/web/dist/assets/highlighted-body-OFNGDK62-DGHHie_q.js +1 -0
- package/web/dist/assets/highlighter-BKVEsACy.js +3 -0
- package/web/dist/assets/html-BY76lXLH.js +1 -0
- package/web/dist/assets/index-CEkI7QxN.css +2 -0
- package/web/dist/assets/index-CO2lH2et.js +11 -0
- package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
- package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/web/dist/assets/json-qhed-kSA.js +1 -0
- package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
- package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
- package/web/dist/assets/lib-CNGa3Dig.js +1 -0
- package/web/dist/assets/loader-circle-BV3DO9mE.js +1 -0
- package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
- package/web/dist/assets/markdown-D4-ADgH9.js +1 -0
- package/web/dist/assets/mermaid-GHXKKRXX-DM2VsGBG.js +1 -0
- package/web/dist/assets/open-mercato-toBr6SOa.svg +11 -0
- package/web/dist/assets/prompt-templates-C7ptKvDd.js +15 -0
- package/web/dist/assets/python-gzcpVVnB.js +1 -0
- package/web/dist/assets/react-dom-Ddtik4qM.js +1 -0
- package/web/dist/assets/refresh-cw-DCa-Rlwz.js +1 -0
- package/web/dist/assets/repo-git-DIhryGDx.js +1 -0
- package/web/dist/assets/run-diff-Dyow8B1q.js +3 -0
- package/web/dist/assets/run-header-jx9-18b8.js +1 -0
- package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
- package/web/dist/assets/search-x-CoCyl7zT.js +1 -0
- package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
- package/web/dist/assets/skill-detail-DB7x_FQp.js +1 -0
- package/web/dist/assets/skills-98vCroU8.js +1 -0
- package/web/dist/assets/skills-BKIoqD6K.js +1 -0
- package/web/dist/assets/sql-BsFa4tDR.js +1 -0
- package/web/dist/assets/square-terminal-B6PZX4Qp.js +1 -0
- package/web/dist/assets/tab-link-C5--YMQd.js +1 -0
- package/web/dist/assets/task-changes-ejxPGVJw.js +1 -0
- package/web/dist/assets/task-commits-C6GO5qT-.js +1 -0
- package/web/dist/assets/task-files-CatpCBXa.js +2 -0
- package/web/dist/assets/task-thread-BMbXDM3d.js +5 -0
- package/web/dist/assets/tasks-table-dgezlCcg.js +1 -0
- package/web/dist/assets/trash-2-CDtxmmc8.js +1 -0
- package/web/dist/assets/triangle-alert-6su4Js5O.js +1 -0
- package/web/dist/assets/tsx-udAQXfEw.js +1 -0
- package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
- package/web/dist/assets/upload-Bp7hQxll.js +1 -0
- package/web/dist/assets/use-desktop-CvTwojOJ.js +3 -0
- package/web/dist/assets/utils-rQGbOrwc.js +1 -0
- package/web/dist/assets/workflows-Dy2c6790.js +11 -0
- package/web/dist/assets/x-Br_jIDBw.js +1 -0
- package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
- package/web/dist/index.html +70 -0
- package/web/open-mercato.svg +11 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
const stepStateSchema = z.object({
|
|
7
|
+
id: z.string(),
|
|
8
|
+
name: z.string(),
|
|
9
|
+
kind: z.enum(['agent', 'check']),
|
|
10
|
+
status: z.enum(['pending', 'running', 'waiting', 'review', 'done', 'failed', 'cancelled', 'skipped']),
|
|
11
|
+
iterations: z.number(),
|
|
12
|
+
tokensUsed: z.number(),
|
|
13
|
+
startedAt: z.string().optional(),
|
|
14
|
+
finishedAt: z.string().optional(),
|
|
15
|
+
error: z.string().optional(),
|
|
16
|
+
/** Latest claude session id — the user can `claude --resume <id>` with it. */
|
|
17
|
+
sessionId: z.string().optional(),
|
|
18
|
+
/** Dollar cost reported by the claude CLI for this step's turns. */
|
|
19
|
+
costUsd: z.number().optional(),
|
|
20
|
+
});
|
|
21
|
+
const runRecordSchema = z.object({
|
|
22
|
+
id: z.string(),
|
|
23
|
+
title: z.string(),
|
|
24
|
+
/** Display title (#389): the auto-derived summary of the first agent turn,
|
|
25
|
+
* or the user's inline edit (`PATCH /api/runs/:id` sets it together with
|
|
26
|
+
* `title` so edits always win). The UI shows `titleSummary ?? title`. */
|
|
27
|
+
titleSummary: z.string().optional(),
|
|
28
|
+
/** `git diff --shortstat` of the worktree vs its base, refreshed on every
|
|
29
|
+
* turn-end (#389) — what the quick list / table shows without a git call. */
|
|
30
|
+
diffStat: z
|
|
31
|
+
.object({ adds: z.number(), dels: z.number(), files: z.number() })
|
|
32
|
+
.optional(),
|
|
33
|
+
workflow: z.string(),
|
|
34
|
+
task: z.string(),
|
|
35
|
+
/** URLs of images attached to the initial task prompt, for the thread's first bubble
|
|
36
|
+
* (#image-display) — persisted like agent screenshots, served from `/images/`. */
|
|
37
|
+
taskImages: z.array(z.string()).optional(),
|
|
38
|
+
model: z.string().optional(),
|
|
39
|
+
/** Agent backend this run used — drives "open in CLI" resume command. */
|
|
40
|
+
runner: z.enum(['claude', 'codex', 'opencode']).optional(),
|
|
41
|
+
/** Echo of the extra system prompt this run actually used (R2): the
|
|
42
|
+
* `POST /api/runs` override, or the `config.json` default it fell back to.
|
|
43
|
+
* Deliberately NOT the full composed prompt — skill bodies and the handoff
|
|
44
|
+
* contract are derivable from the persisted workflow and would bloat the
|
|
45
|
+
* index. Resolved at execute time (a queued run picks up config edits). */
|
|
46
|
+
systemPrompt: z.string().optional(),
|
|
47
|
+
/** Per-task follow-up inbox contract (spec 007, #444). Missing on old runs
|
|
48
|
+
* means enabled — the historical behavior. */
|
|
49
|
+
generateFollowups: z.boolean().optional(),
|
|
50
|
+
/** Autonomous mode (#489): the run was started with the "autonomous" checkbox,
|
|
51
|
+
* so it never parks at `waiting` (auto-nudge) and — once persisted here —
|
|
52
|
+
* never parks at the terminal `review` gate either (`settleSuccess` + the
|
|
53
|
+
* group-pick winner-park read it). Additive-safe: absent = falsy = not
|
|
54
|
+
* autonomous. Set at creation from `WorkflowInput.autonomous`. */
|
|
55
|
+
autonomous: z.boolean().optional(),
|
|
56
|
+
status: z.enum(['queued', 'running', 'waiting', 'review', 'done', 'failed', 'cancelled']),
|
|
57
|
+
/** Sub-state of `running` (spec 2026-07-18-subagent-monitoring-status, #490):
|
|
58
|
+
* `monitoring` while the agent is still working on its own downstream work.
|
|
59
|
+
* Optional/absent on old runs; cleared when the run resumes or ends. */
|
|
60
|
+
activity: z.enum(['monitoring']).optional(),
|
|
61
|
+
createdAt: z.string(),
|
|
62
|
+
startedAt: z.string().optional(),
|
|
63
|
+
finishedAt: z.string().optional(),
|
|
64
|
+
tokensUsed: z.number(),
|
|
65
|
+
costUsd: z.number().optional(),
|
|
66
|
+
/** First GitHub PR URL spotted in the transcript (the janitor trick). */
|
|
67
|
+
pullRequestUrl: z.string().optional(),
|
|
68
|
+
/** The PR this task is ABOUT (#407, spec 2026-07-16-pr-autodiscovery):
|
|
69
|
+
* auto-discovered from conversation references for tasks that work on an
|
|
70
|
+
* existing PR (review/continue/merge). Display-only tier — `pullRequestUrl`
|
|
71
|
+
* (the PR this task CREATED) always wins, and action gates ignore this. */
|
|
72
|
+
referencedPullRequestUrl: z.string().optional(),
|
|
73
|
+
/** The PR/issue number this task is ABOUT (spec 2026-07-17-task-auto-naming):
|
|
74
|
+
* regex-extracted from the task prompt, upgradable by the namer's
|
|
75
|
+
* cross-checked output. Display tier — never gates actions. */
|
|
76
|
+
prNumber: z.number().optional(),
|
|
77
|
+
issueNumber: z.number().optional(),
|
|
78
|
+
/** Who owns the display title: `user` (PATCH rename — never auto-overwritten)
|
|
79
|
+
* or `auto` (namer-owned — a later namer result may replace it). Missing on
|
|
80
|
+
* old runs = legacy behavior (auto fills only an unset titleSummary). */
|
|
81
|
+
titleOrigin: z.enum(['user', 'auto']).optional(),
|
|
82
|
+
/** Distinct PR URLs spotted so far — the referenced tier's working set,
|
|
83
|
+
* persisted so a resumed run keeps disambiguating against the full history
|
|
84
|
+
* instead of re-adopting the next URL as "the only one". Capped. */
|
|
85
|
+
referencedPrCandidates: z.array(z.string()).optional(),
|
|
86
|
+
/** Task worktree (spec 006) — absent when the run executed in the repo root. */
|
|
87
|
+
worktreePath: z.string().optional(),
|
|
88
|
+
/** The task's own branch (`cez/<id8>`), created off `baseBranch`. */
|
|
89
|
+
branch: z.string().optional(),
|
|
90
|
+
/** Branch (or commit, when HEAD was detached) the worktree was forked from. */
|
|
91
|
+
baseBranch: z.string().optional(),
|
|
92
|
+
/** Set when count-based retention (#483) reclaimed this run's worktree
|
|
93
|
+
* *directory* (the `cez/<id8>` branch is kept). Presence means "materialized
|
|
94
|
+
* dir gone, recoverable via `git worktree add`"; it excludes the run from the
|
|
95
|
+
* retention budget until the dir is re-materialized (resume clears it). */
|
|
96
|
+
worktreeReclaimedAt: z.string().optional(),
|
|
97
|
+
/** Parallel variants (spec 010): tasks sharing a groupId are one group. */
|
|
98
|
+
groupId: z.string().optional(),
|
|
99
|
+
/** Variant letter within the group — 'A' | 'B' | 'C' (kept as a string). */
|
|
100
|
+
variant: z.string().optional(),
|
|
101
|
+
/** Peak resident memory (bytes) / process count observed across the run's
|
|
102
|
+
* agent process trees (#348) — written when a session's telemetry ends.
|
|
103
|
+
* Optional: old runs.json files and `ps`-less platforms have neither. */
|
|
104
|
+
peakRssBytes: z.number().optional(),
|
|
105
|
+
peakProcCount: z.number().optional(),
|
|
106
|
+
archived: z.boolean().default(false),
|
|
107
|
+
archivedAt: z.string().optional(),
|
|
108
|
+
currentStepId: z.string().optional(),
|
|
109
|
+
error: z.string().optional(),
|
|
110
|
+
steps: z.array(stepStateSchema),
|
|
111
|
+
/** Full workflow definition, persisted so a `queued` run can be re-enqueued
|
|
112
|
+
* after a restart (#367) — including ad-hoc "(planned)" chains that exist
|
|
113
|
+
* nowhere else. Kept loose here to avoid an upward import; the run manager
|
|
114
|
+
* validates the shape before reviving it. */
|
|
115
|
+
workflowDef: z.record(z.string(), z.unknown()).optional(),
|
|
116
|
+
});
|
|
117
|
+
const MAX_RUNS_KEPT = 300;
|
|
118
|
+
const MAX_ARCHIVED_KEPT = 500;
|
|
119
|
+
const PR_URL_RE = /https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/pull\/\d+/;
|
|
120
|
+
// The transcript auto-link is convenience only (the cockpit's own `gh pr create` path sets the
|
|
121
|
+
// URL authoritatively). Adopt a PR URL ONLY when the agent actually CREATED one — a task that
|
|
122
|
+
// reviews or merely references an existing PR must not get mislabeled with its number (#fake-pr).
|
|
123
|
+
const CREATED_PR_RE = /\b(?:gh\s+pr\s+create|pull\s*request\s+created|created\s+(?:a\s+)?(?:draft\s+)?(?:pr|pull\s*request)|opened\s+(?:a\s+)?(?:draft\s+)?pull\s*request)\b/i;
|
|
124
|
+
/** Referenced-tier working-set cap (spec 2026-07-16-pr-autodiscovery): past
|
|
125
|
+
* this many distinct PRs the conversation is a survey, not a subject. */
|
|
126
|
+
const MAX_PR_CANDIDATES = 8;
|
|
127
|
+
/**
|
|
128
|
+
* Every scannable string of one persisted event: the v1 top-level fields plus
|
|
129
|
+
* the protocol-v2 `item.*` content (nested — the reason v2 streams were
|
|
130
|
+
* invisible to the janitor, #407). Reasoning items are skipped: thinking text
|
|
131
|
+
* speculates about PRs the task never touches.
|
|
132
|
+
*/
|
|
133
|
+
function eventTextFragments(event) {
|
|
134
|
+
const fragments = [];
|
|
135
|
+
for (const key of ['text', 'result', 'message']) {
|
|
136
|
+
const value = event[key];
|
|
137
|
+
if (typeof value === 'string')
|
|
138
|
+
fragments.push(value);
|
|
139
|
+
}
|
|
140
|
+
const item = event.item;
|
|
141
|
+
if (item && typeof item === 'object' && item.kind !== 'reasoning') {
|
|
142
|
+
const it = item;
|
|
143
|
+
for (const key of ['text', 'title', 'output']) {
|
|
144
|
+
const value = it[key];
|
|
145
|
+
if (typeof value === 'string')
|
|
146
|
+
fragments.push(value);
|
|
147
|
+
}
|
|
148
|
+
if (typeof it.input === 'string') {
|
|
149
|
+
fragments.push(it.input);
|
|
150
|
+
}
|
|
151
|
+
else if (it.input !== undefined) {
|
|
152
|
+
try {
|
|
153
|
+
fragments.push(JSON.stringify(it.input));
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// circular input — skip it
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return fragments;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* The referenced tier's resolution rule: one distinct URL is the subject;
|
|
164
|
+
* among several, the one whose PR number the task prompt names (and only when
|
|
165
|
+
* exactly one matches); otherwise ambiguous — no chip beats a wrong chip.
|
|
166
|
+
*/
|
|
167
|
+
function resolveReferencedPr(candidates, task) {
|
|
168
|
+
if (candidates.length === 1)
|
|
169
|
+
return candidates[0];
|
|
170
|
+
const named = candidates.filter((url) => {
|
|
171
|
+
const num = url.split('/').pop() ?? '';
|
|
172
|
+
// `\d` boundaries only: they reject `170` inside `4170` yet still match a
|
|
173
|
+
// number written as `#4170`, ` 4170`, or inside a pasted `…/pull/4170`.
|
|
174
|
+
return num !== '' && new RegExp(`(?<!\\d)#?${num}(?!\\d)`).test(task);
|
|
175
|
+
});
|
|
176
|
+
return named.length === 1 ? named[0] : undefined;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The PR URL a creation phrase *introduces*, or undefined. The created URL is
|
|
180
|
+
* the first one at or after the `CREATED_PR_RE` phrase — a PR the same event
|
|
181
|
+
* merely referenced *earlier* (e.g. the issue's own linked `…/pull/1`) must not
|
|
182
|
+
* be mistaken for the one just created (#495). Falls back to the last URL
|
|
183
|
+
* *before* the phrase for `gh` orderings that print the URL first. Selection
|
|
184
|
+
* only — the caller decides whether creation phrasing is present.
|
|
185
|
+
*/
|
|
186
|
+
function createdPrUrl(haystack) {
|
|
187
|
+
const phrase = CREATED_PR_RE.exec(haystack);
|
|
188
|
+
if (!phrase)
|
|
189
|
+
return undefined;
|
|
190
|
+
const after = PR_URL_RE.exec(haystack.slice(phrase.index));
|
|
191
|
+
if (after)
|
|
192
|
+
return after[0];
|
|
193
|
+
let before;
|
|
194
|
+
for (const m of haystack.slice(0, phrase.index).matchAll(new RegExp(PR_URL_RE.source, 'g'))) {
|
|
195
|
+
before = m[0];
|
|
196
|
+
}
|
|
197
|
+
return before;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* File-backed run store: `runs.json` index (atomic tmp+rename writes, the
|
|
201
|
+
* pattern from @cezar/core's IssueStore) plus one append-only NDJSON event
|
|
202
|
+
* file per run. Also the in-process event bus the SSE endpoints subscribe to:
|
|
203
|
+
* emits `('run', RunRecord)` and `('event', { runId, event: RunEvent })`.
|
|
204
|
+
*/
|
|
205
|
+
export class RunStore extends EventEmitter {
|
|
206
|
+
dataDir;
|
|
207
|
+
runs = new Map();
|
|
208
|
+
saveTimer = null;
|
|
209
|
+
constructor(dataDir) {
|
|
210
|
+
super();
|
|
211
|
+
this.dataDir = dataDir;
|
|
212
|
+
this.setMaxListeners(100);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* `keepLive` (#367): leave `queued`/`running`/`waiting` statuses untouched
|
|
216
|
+
* so the caller can recover them (RunManager.recover re-queues queued runs,
|
|
217
|
+
* resumes interrupted ones). Without it — one-shot CLI paths that never
|
|
218
|
+
* recover — live-looking runs are marked failed so no ghost stays behind.
|
|
219
|
+
*/
|
|
220
|
+
static open(dataDir, opts) {
|
|
221
|
+
mkdirSync(join(dataDir, 'runs'), { recursive: true });
|
|
222
|
+
const store = new RunStore(dataDir);
|
|
223
|
+
const indexPath = join(dataDir, 'runs.json');
|
|
224
|
+
if (existsSync(indexPath)) {
|
|
225
|
+
try {
|
|
226
|
+
const raw = JSON.parse(readFileSync(indexPath, 'utf8'));
|
|
227
|
+
const parsed = z.array(runRecordSchema).safeParse(raw);
|
|
228
|
+
if (parsed.success) {
|
|
229
|
+
for (const run of parsed.data) {
|
|
230
|
+
// A run that was live when the previous process exited can never
|
|
231
|
+
// finish — surface that instead of a forever-"running" ghost.
|
|
232
|
+
// `review` survives restarts on purpose: the gate is pure data
|
|
233
|
+
// (worktree + branch + record) with no live process, so the diff
|
|
234
|
+
// panel, Send back (resume) and Draft PR all still work.
|
|
235
|
+
if (!opts?.keepLive &&
|
|
236
|
+
(run.status === 'running' ||
|
|
237
|
+
run.status === 'queued' ||
|
|
238
|
+
run.status === 'waiting')) {
|
|
239
|
+
run.status = 'failed';
|
|
240
|
+
run.error = 'interrupted — cezar process exited during the run';
|
|
241
|
+
run.finishedAt = run.finishedAt ?? new Date().toISOString();
|
|
242
|
+
for (const step of run.steps) {
|
|
243
|
+
if (step.status === 'running' || step.status === 'waiting')
|
|
244
|
+
step.status = 'failed';
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
store.runs.set(run.id, run);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// corrupt index — start fresh; event files stay on disk untouched
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return store;
|
|
256
|
+
}
|
|
257
|
+
listRuns() {
|
|
258
|
+
return [...this.runs.values()].sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
259
|
+
}
|
|
260
|
+
getRun(id) {
|
|
261
|
+
return this.runs.get(id);
|
|
262
|
+
}
|
|
263
|
+
createRun(input) {
|
|
264
|
+
const run = {
|
|
265
|
+
id: randomUUID(),
|
|
266
|
+
title: input.title,
|
|
267
|
+
workflow: input.workflow,
|
|
268
|
+
task: input.task,
|
|
269
|
+
model: input.model,
|
|
270
|
+
runner: input.runner,
|
|
271
|
+
generateFollowups: input.generateFollowups,
|
|
272
|
+
autonomous: input.autonomous,
|
|
273
|
+
groupId: input.groupId,
|
|
274
|
+
variant: input.variant,
|
|
275
|
+
status: 'queued',
|
|
276
|
+
createdAt: new Date().toISOString(),
|
|
277
|
+
tokensUsed: 0,
|
|
278
|
+
archived: false,
|
|
279
|
+
steps: input.steps.map((s) => ({
|
|
280
|
+
...s,
|
|
281
|
+
status: 'pending',
|
|
282
|
+
iterations: 0,
|
|
283
|
+
tokensUsed: 0,
|
|
284
|
+
})),
|
|
285
|
+
};
|
|
286
|
+
// A prompt that pastes a PR URL is already about that PR — seed the
|
|
287
|
+
// referenced tier so the chip exists before the first event (#407).
|
|
288
|
+
this.trackReferencedPrs(run, input.task);
|
|
289
|
+
this.runs.set(run.id, run);
|
|
290
|
+
this.pruneOldRuns();
|
|
291
|
+
this.touch(run);
|
|
292
|
+
return run;
|
|
293
|
+
}
|
|
294
|
+
updateRun(id, patch) {
|
|
295
|
+
const run = this.runs.get(id);
|
|
296
|
+
if (!run)
|
|
297
|
+
return undefined;
|
|
298
|
+
Object.assign(run, patch);
|
|
299
|
+
this.touch(run);
|
|
300
|
+
return run;
|
|
301
|
+
}
|
|
302
|
+
/** Append a step to an existing run (used by "Continue" — spec 003). */
|
|
303
|
+
addStep(runId, step) {
|
|
304
|
+
const run = this.runs.get(runId);
|
|
305
|
+
if (!run || run.steps.some((s) => s.id === step.id))
|
|
306
|
+
return;
|
|
307
|
+
run.steps.push({ ...step, status: 'pending', iterations: 0, tokensUsed: 0 });
|
|
308
|
+
this.touch(run);
|
|
309
|
+
}
|
|
310
|
+
updateStep(runId, stepId, patch) {
|
|
311
|
+
const run = this.runs.get(runId);
|
|
312
|
+
const step = run?.steps.find((s) => s.id === stepId);
|
|
313
|
+
if (!run || !step)
|
|
314
|
+
return;
|
|
315
|
+
Object.assign(step, patch);
|
|
316
|
+
run.tokensUsed = run.steps.reduce((sum, s) => sum + s.tokensUsed, 0);
|
|
317
|
+
const cost = run.steps.reduce((sum, s) => sum + (s.costUsd ?? 0), 0);
|
|
318
|
+
run.costUsd = cost > 0 ? cost : undefined;
|
|
319
|
+
this.touch(run);
|
|
320
|
+
}
|
|
321
|
+
setArchived(id, archived) {
|
|
322
|
+
const run = this.runs.get(id);
|
|
323
|
+
if (!run)
|
|
324
|
+
return undefined;
|
|
325
|
+
run.archived = archived;
|
|
326
|
+
run.archivedAt = archived ? new Date().toISOString() : undefined;
|
|
327
|
+
this.touch(run);
|
|
328
|
+
return run;
|
|
329
|
+
}
|
|
330
|
+
/** Bulk-archive every finished run; returns how many were archived. */
|
|
331
|
+
archiveFinished() {
|
|
332
|
+
let count = 0;
|
|
333
|
+
for (const run of this.runs.values()) {
|
|
334
|
+
if (!run.archived && ['done', 'failed', 'cancelled'].includes(run.status)) {
|
|
335
|
+
run.archived = true;
|
|
336
|
+
run.archivedAt = new Date().toISOString();
|
|
337
|
+
this.touch(run);
|
|
338
|
+
count++;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return count;
|
|
342
|
+
}
|
|
343
|
+
appendEvent(runId, event) {
|
|
344
|
+
const run = this.runs.get(runId);
|
|
345
|
+
if (!run)
|
|
346
|
+
throw new Error(`unknown run: ${runId}`);
|
|
347
|
+
const seq = this.nextSeq(runId);
|
|
348
|
+
const full = { ...event, seq, ts: new Date().toISOString() };
|
|
349
|
+
// Sync append keeps event order without a write queue; local NDJSON
|
|
350
|
+
// appends at agent-event rates are effectively free.
|
|
351
|
+
appendFileSync(this.eventsPath(runId), `${JSON.stringify(full)}\n`, 'utf8');
|
|
352
|
+
this.emit('event', { runId, event: full });
|
|
353
|
+
// The janitor trick: agents print the PR URL after `gh pr create` — the
|
|
354
|
+
// first one spotted in the transcript becomes the run's PR link. Scans v1
|
|
355
|
+
// fields AND nested v2 `item.*` content (#407). A URL without the created
|
|
356
|
+
// phrasing still feeds the referenced tier (the PR the task is about).
|
|
357
|
+
if (!run.pullRequestUrl) {
|
|
358
|
+
const haystack = eventTextFragments(full).join(' ');
|
|
359
|
+
if (haystack.length > 0) {
|
|
360
|
+
const created = createdPrUrl(haystack);
|
|
361
|
+
if (created) {
|
|
362
|
+
this.updateRun(runId, { pullRequestUrl: created });
|
|
363
|
+
}
|
|
364
|
+
else if (PR_URL_RE.test(haystack) && this.trackReferencedPrs(run, haystack)) {
|
|
365
|
+
this.touch(run);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return full;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Fold every PR URL in `haystack` into the run's referenced-tier working
|
|
373
|
+
* set and re-resolve `referencedPullRequestUrl` (spec
|
|
374
|
+
* 2026-07-16-pr-autodiscovery). Mutates the record in place — the caller
|
|
375
|
+
* owns persistence/fan-out — and reports whether anything changed.
|
|
376
|
+
*/
|
|
377
|
+
trackReferencedPrs(run, haystack) {
|
|
378
|
+
const seen = new Set(run.referencedPrCandidates ?? []);
|
|
379
|
+
const before = seen.size;
|
|
380
|
+
for (const match of haystack.matchAll(new RegExp(PR_URL_RE.source, 'g'))) {
|
|
381
|
+
if (seen.size >= MAX_PR_CANDIDATES)
|
|
382
|
+
break;
|
|
383
|
+
seen.add(match[0]);
|
|
384
|
+
}
|
|
385
|
+
if (seen.size === before)
|
|
386
|
+
return false;
|
|
387
|
+
run.referencedPrCandidates = [...seen];
|
|
388
|
+
run.referencedPullRequestUrl = resolveReferencedPr(run.referencedPrCandidates, run.task);
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Fan an event out to live subscribers WITHOUT writing it to the NDJSON
|
|
393
|
+
* file — the channel for coalesced `item.delta` flushes (protocol-v2
|
|
394
|
+
* performance guardrail: raw deltas never hit disk; replay = the persisted
|
|
395
|
+
* snapshots). Stamped with `seq`/`ts` like persisted lines so the live
|
|
396
|
+
* wire keeps one ordering axis; the seq simply never appears in a replay
|
|
397
|
+
* (gaps are fine — dedup compares with `>`).
|
|
398
|
+
*/
|
|
399
|
+
emitEphemeral(runId, event) {
|
|
400
|
+
const full = { ...event, seq: this.nextSeq(runId), ts: new Date().toISOString() };
|
|
401
|
+
this.emit('event', { runId, event: full });
|
|
402
|
+
return full;
|
|
403
|
+
}
|
|
404
|
+
readEvents(runId) {
|
|
405
|
+
try {
|
|
406
|
+
const raw = readFileSync(this.eventsPath(runId), 'utf8');
|
|
407
|
+
return raw
|
|
408
|
+
.split('\n')
|
|
409
|
+
.filter(Boolean)
|
|
410
|
+
.map((line) => {
|
|
411
|
+
try {
|
|
412
|
+
return JSON.parse(line);
|
|
413
|
+
}
|
|
414
|
+
catch {
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
})
|
|
418
|
+
.filter((e) => e !== null);
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
return [];
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
deleteRun(id) {
|
|
425
|
+
const existed = this.runs.delete(id);
|
|
426
|
+
if (existed) {
|
|
427
|
+
try {
|
|
428
|
+
rmSync(this.eventsPath(id), { force: true });
|
|
429
|
+
rmSync(this.handoffPath(id), { force: true }); // spec 007: the journal goes with the task
|
|
430
|
+
rmSync(this.imagesDir(id), { recursive: true, force: true }); // agent screenshots
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
// best effort — the index is authoritative
|
|
434
|
+
}
|
|
435
|
+
this.seqs.delete(id);
|
|
436
|
+
this.scheduleSave();
|
|
437
|
+
this.emit('deleted', id);
|
|
438
|
+
}
|
|
439
|
+
return existed;
|
|
440
|
+
}
|
|
441
|
+
/** Write the index out now (used on shutdown). */
|
|
442
|
+
flush() {
|
|
443
|
+
if (this.saveTimer) {
|
|
444
|
+
clearTimeout(this.saveTimer);
|
|
445
|
+
this.saveTimer = null;
|
|
446
|
+
}
|
|
447
|
+
this.saveNow();
|
|
448
|
+
}
|
|
449
|
+
// ---- internals -----------------------------------------------------------
|
|
450
|
+
seqs = new Map();
|
|
451
|
+
nextSeq(runId) {
|
|
452
|
+
const next = (this.seqs.get(runId) ?? this.rehydrateSeq(runId)) + 1;
|
|
453
|
+
this.seqs.set(runId, next);
|
|
454
|
+
return next;
|
|
455
|
+
}
|
|
456
|
+
/** After a restart the in-memory counter is empty while the run's NDJSON file
|
|
457
|
+
* keeps the history. Restarting from 1 would collide with the seqs a client
|
|
458
|
+
* already replayed — its `seq > maxSeq` dedup then silently drops every
|
|
459
|
+
* resumed event, even across a reload (the frozen-transcript symptom class
|
|
460
|
+
* of #424). One file read on the first post-restart append per run. */
|
|
461
|
+
rehydrateSeq(runId) {
|
|
462
|
+
let max = 0;
|
|
463
|
+
for (const event of this.readEvents(runId)) {
|
|
464
|
+
if (typeof event.seq === 'number' && event.seq > max)
|
|
465
|
+
max = event.seq;
|
|
466
|
+
}
|
|
467
|
+
return max;
|
|
468
|
+
}
|
|
469
|
+
eventsPath(runId) {
|
|
470
|
+
return join(this.dataDir, 'runs', `${runId}.ndjson`);
|
|
471
|
+
}
|
|
472
|
+
/** Same location `handoffPath()` in handoff.ts produces — inlined to keep
|
|
473
|
+
* the store free of upward imports. */
|
|
474
|
+
handoffPath(runId) {
|
|
475
|
+
return join(this.dataDir, 'runs', `${runId}.handoff.md`);
|
|
476
|
+
}
|
|
477
|
+
/** Agent screenshots persisted by the run manager (see persistImage). */
|
|
478
|
+
imagesDir(runId) {
|
|
479
|
+
return join(this.dataDir, 'runs', `${runId}-images`);
|
|
480
|
+
}
|
|
481
|
+
touch(run) {
|
|
482
|
+
this.scheduleSave();
|
|
483
|
+
this.emit('run', run);
|
|
484
|
+
}
|
|
485
|
+
pruneOldRuns() {
|
|
486
|
+
const all = this.listRuns();
|
|
487
|
+
const stalePool = [
|
|
488
|
+
...all.filter((r) => !r.archived).slice(MAX_RUNS_KEPT),
|
|
489
|
+
...all.filter((r) => r.archived).slice(MAX_ARCHIVED_KEPT),
|
|
490
|
+
];
|
|
491
|
+
for (const stale of stalePool) {
|
|
492
|
+
this.runs.delete(stale.id);
|
|
493
|
+
try {
|
|
494
|
+
rmSync(this.eventsPath(stale.id), { force: true });
|
|
495
|
+
rmSync(this.handoffPath(stale.id), { force: true });
|
|
496
|
+
rmSync(this.imagesDir(stale.id), { recursive: true, force: true });
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
// best effort
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
/** Debounced so token-usage updates don't rewrite the index per event. */
|
|
504
|
+
scheduleSave() {
|
|
505
|
+
if (this.saveTimer)
|
|
506
|
+
return;
|
|
507
|
+
this.saveTimer = setTimeout(() => {
|
|
508
|
+
this.saveTimer = null;
|
|
509
|
+
this.saveNow();
|
|
510
|
+
}, 300);
|
|
511
|
+
this.saveTimer.unref?.();
|
|
512
|
+
}
|
|
513
|
+
saveNow() {
|
|
514
|
+
const indexPath = join(this.dataDir, 'runs.json');
|
|
515
|
+
const tmpPath = `${indexPath}.tmp`;
|
|
516
|
+
try {
|
|
517
|
+
writeFileSync(tmpPath, JSON.stringify(this.listRuns(), null, 2), 'utf8');
|
|
518
|
+
renameSync(tmpPath, indexPath);
|
|
519
|
+
}
|
|
520
|
+
catch (err) {
|
|
521
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
522
|
+
console.error(`[cez] failed to save runs.json: ${message}`);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/runs/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR/issue-number extraction from a task prompt (spec 2026-07-17-task-auto-naming,
|
|
3
|
+
* step 0): the always-available programmatic layer under the LLM namer. Pure and
|
|
4
|
+
* synchronous — it runs inline at `startRun` and its result both prefixes the
|
|
5
|
+
* heuristic title and cross-checks the namer's structured output (the regex wins
|
|
6
|
+
* every disagreement).
|
|
7
|
+
*/
|
|
8
|
+
export interface TaskRefs {
|
|
9
|
+
prNumber?: number;
|
|
10
|
+
issueNumber?: number;
|
|
11
|
+
/** A number present in the task whose kind (PR vs issue) is not determinable —
|
|
12
|
+
* a bare `469` argument or a plain `#469`. Still usable as a title prefix. */
|
|
13
|
+
ambiguousNumber?: number;
|
|
14
|
+
}
|
|
15
|
+
/** First match wins per kind, scanning the whole prompt. */
|
|
16
|
+
export declare function extractTaskRefs(task: string): TaskRefs;
|
|
17
|
+
/** The single number worth prefixing a title with, strongest kind first. */
|
|
18
|
+
export declare function titleRefNumber(refs: TaskRefs): number | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Skill-aware disambiguation for a bare number: `469` handed to a *-review-pr
|
|
21
|
+
* skill is a PR; handed to a *-fix-issue skill it is an issue. Only upgrades
|
|
22
|
+
* `ambiguousNumber` — explicit URL/worded matches are never overridden.
|
|
23
|
+
*/
|
|
24
|
+
export declare function refineTaskRefs(refs: TaskRefs, skillName?: string): TaskRefs;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR/issue-number extraction from a task prompt (spec 2026-07-17-task-auto-naming,
|
|
3
|
+
* step 0): the always-available programmatic layer under the LLM namer. Pure and
|
|
4
|
+
* synchronous — it runs inline at `startRun` and its result both prefixes the
|
|
5
|
+
* heuristic title and cross-checks the namer's structured output (the regex wins
|
|
6
|
+
* every disagreement).
|
|
7
|
+
*/
|
|
8
|
+
const MAX_REF = 10_000_000; // sanity bound — GitHub numbers are far below this
|
|
9
|
+
function num(raw) {
|
|
10
|
+
if (!raw)
|
|
11
|
+
return undefined;
|
|
12
|
+
const n = Number(raw);
|
|
13
|
+
return Number.isInteger(n) && n > 0 && n < MAX_REF ? n : undefined;
|
|
14
|
+
}
|
|
15
|
+
/** First match wins per kind, scanning the whole prompt. */
|
|
16
|
+
export function extractTaskRefs(task) {
|
|
17
|
+
const refs = {};
|
|
18
|
+
const text = task ?? '';
|
|
19
|
+
// 1. Explicit URLs — the strongest signal.
|
|
20
|
+
const prUrl = /github\.com\/[\w.-]+\/[\w.-]+\/pull\/(\d+)/i.exec(text);
|
|
21
|
+
if (prUrl)
|
|
22
|
+
refs.prNumber = num(prUrl[1]);
|
|
23
|
+
const issueUrl = /github\.com\/[\w.-]+\/[\w.-]+\/issues\/(\d+)/i.exec(text);
|
|
24
|
+
if (issueUrl)
|
|
25
|
+
refs.issueNumber = num(issueUrl[1]);
|
|
26
|
+
// 2. Worded references — covers the GitHub-tab templates verbatim
|
|
27
|
+
// ("Address GitHub pull request #N", "Fix GitHub issue #N") and free text
|
|
28
|
+
// ("pr 437", "PR#437", "review pull request 437", "issue #12").
|
|
29
|
+
if (refs.prNumber === undefined) {
|
|
30
|
+
const pr = /\b(?:pull\s+request|pr)\s*#?\s*(\d+)/i.exec(text);
|
|
31
|
+
if (pr)
|
|
32
|
+
refs.prNumber = num(pr[1]);
|
|
33
|
+
}
|
|
34
|
+
if (refs.issueNumber === undefined) {
|
|
35
|
+
const issue = /\bissue\s*#?\s*(\d+)/i.exec(text);
|
|
36
|
+
if (issue)
|
|
37
|
+
refs.issueNumber = num(issue[1]);
|
|
38
|
+
}
|
|
39
|
+
// 3. A task that IS a number — the argument-only skill invocation (`469`).
|
|
40
|
+
if (refs.prNumber === undefined && refs.issueNumber === undefined) {
|
|
41
|
+
const bare = /^\s*#?(\d+)\s*$/.exec(text);
|
|
42
|
+
if (bare)
|
|
43
|
+
refs.ambiguousNumber = num(bare[1]);
|
|
44
|
+
else {
|
|
45
|
+
// 4. Last resort: the first `#N` anywhere.
|
|
46
|
+
const hash = /#(\d+)\b/.exec(text);
|
|
47
|
+
if (hash)
|
|
48
|
+
refs.ambiguousNumber = num(hash[1]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return refs;
|
|
52
|
+
}
|
|
53
|
+
/** The single number worth prefixing a title with, strongest kind first. */
|
|
54
|
+
export function titleRefNumber(refs) {
|
|
55
|
+
return refs.prNumber ?? refs.issueNumber ?? refs.ambiguousNumber;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Skill-aware disambiguation for a bare number: `469` handed to a *-review-pr
|
|
59
|
+
* skill is a PR; handed to a *-fix-issue skill it is an issue. Only upgrades
|
|
60
|
+
* `ambiguousNumber` — explicit URL/worded matches are never overridden.
|
|
61
|
+
*/
|
|
62
|
+
export function refineTaskRefs(refs, skillName) {
|
|
63
|
+
if (refs.ambiguousNumber === undefined || !skillName)
|
|
64
|
+
return refs;
|
|
65
|
+
const name = skillName.toLowerCase();
|
|
66
|
+
if (/(^|\W)pr(\W|$)|pull-?request/.test(name)) {
|
|
67
|
+
return { ...refs, prNumber: refs.prNumber ?? refs.ambiguousNumber, ambiguousNumber: undefined };
|
|
68
|
+
}
|
|
69
|
+
if (name.includes('issue')) {
|
|
70
|
+
return { ...refs, issueNumber: refs.issueNumber ?? refs.ambiguousNumber, ambiguousNumber: undefined };
|
|
71
|
+
}
|
|
72
|
+
return refs;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=task-refs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-refs.js","sourceRoot":"","sources":["../../src/runs/task-refs.ts"],"names":[],"mappings":"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"}
|