@chiralkit/cli 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +97 -0
- package/dist/add.d.ts +4 -0
- package/dist/add.js +118 -0
- package/dist/add.js.map +1 -0
- package/dist/agents/subprocess.d.ts +10 -0
- package/dist/agents/subprocess.js +43 -0
- package/dist/agents/subprocess.js.map +1 -0
- package/dist/automation/index.d.ts +14 -0
- package/dist/automation/index.js +129 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/install.d.ts +19 -0
- package/dist/automation/install.js +116 -0
- package/dist/automation/install.js.map +1 -0
- package/dist/automation/parsers/audit-report.d.ts +2 -0
- package/dist/automation/parsers/audit-report.js +42 -0
- package/dist/automation/parsers/audit-report.js.map +1 -0
- package/dist/automation/parsers/exit-code.d.ts +2 -0
- package/dist/automation/parsers/exit-code.js +6 -0
- package/dist/automation/parsers/exit-code.js.map +1 -0
- package/dist/automation/parsers/index.d.ts +10 -0
- package/dist/automation/parsers/index.js +13 -0
- package/dist/automation/parsers/index.js.map +1 -0
- package/dist/automation/parsers/observer-snapshot.d.ts +2 -0
- package/dist/automation/parsers/observer-snapshot.js +30 -0
- package/dist/automation/parsers/observer-snapshot.js.map +1 -0
- package/dist/automation/parsers/plan-report.d.ts +2 -0
- package/dist/automation/parsers/plan-report.js +53 -0
- package/dist/automation/parsers/plan-report.js.map +1 -0
- package/dist/automation/parsers/refinement-report.d.ts +2 -0
- package/dist/automation/parsers/refinement-report.js +149 -0
- package/dist/automation/parsers/refinement-report.js.map +1 -0
- package/dist/automation/parsers/types.d.ts +7 -0
- package/dist/automation/parsers/types.js +2 -0
- package/dist/automation/parsers/types.js.map +1 -0
- package/dist/automation/run.d.ts +25 -0
- package/dist/automation/run.js +68 -0
- package/dist/automation/run.js.map +1 -0
- package/dist/automation/schema.d.ts +130 -0
- package/dist/automation/schema.js +46 -0
- package/dist/automation/schema.js.map +1 -0
- package/dist/automation/status.d.ts +16 -0
- package/dist/automation/status.js +56 -0
- package/dist/automation/status.js.map +1 -0
- package/dist/automation/verifiers/index.d.ts +7 -0
- package/dist/automation/verifiers/index.js +5 -0
- package/dist/automation/verifiers/index.js.map +1 -0
- package/dist/automation/verifiers/shell.d.ts +5 -0
- package/dist/automation/verifiers/shell.js +17 -0
- package/dist/automation/verifiers/shell.js.map +1 -0
- package/dist/automation/verifiers/types.d.ts +12 -0
- package/dist/automation/verifiers/types.js +2 -0
- package/dist/automation/verifiers/types.js.map +1 -0
- package/dist/backlog/add.d.ts +10 -0
- package/dist/backlog/add.js +30 -0
- package/dist/backlog/add.js.map +1 -0
- package/dist/backlog/index.d.ts +1 -0
- package/dist/backlog/index.js +53 -0
- package/dist/backlog/index.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.js +110 -0
- package/dist/config.js.map +1 -0
- package/dist/detect.d.ts +2 -0
- package/dist/detect.js +26 -0
- package/dist/detect.js.map +1 -0
- package/dist/doctor-invariants.d.ts +6 -0
- package/dist/doctor-invariants.js +50 -0
- package/dist/doctor-invariants.js.map +1 -0
- package/dist/doctor.d.ts +13 -0
- package/dist/doctor.js +281 -0
- package/dist/doctor.js.map +1 -0
- package/dist/generate.d.ts +1 -0
- package/dist/generate.js +275 -0
- package/dist/generate.js.map +1 -0
- package/dist/generator/agent.d.ts +8 -0
- package/dist/generator/agent.js +66 -0
- package/dist/generator/agent.js.map +1 -0
- package/dist/generator/api.d.ts +7 -0
- package/dist/generator/api.js +42 -0
- package/dist/generator/api.js.map +1 -0
- package/dist/generator/config.d.ts +23 -0
- package/dist/generator/config.js +121 -0
- package/dist/generator/config.js.map +1 -0
- package/dist/generator/parse-response.d.ts +5 -0
- package/dist/generator/parse-response.js +58 -0
- package/dist/generator/parse-response.js.map +1 -0
- package/dist/generator/prompt.d.ts +9 -0
- package/dist/generator/prompt.js +166 -0
- package/dist/generator/prompt.js.map +1 -0
- package/dist/generator/request.d.ts +17 -0
- package/dist/generator/request.js +15 -0
- package/dist/generator/request.js.map +1 -0
- package/dist/generators/prompts/stencil.md +45 -0
- package/dist/generators/prompts/vue.md +54 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +89 -0
- package/dist/init.js.map +1 -0
- package/dist/installers/context.d.ts +4 -0
- package/dist/installers/context.js +120 -0
- package/dist/installers/context.js.map +1 -0
- package/dist/installers/index.d.ts +7 -0
- package/dist/installers/index.js +22 -0
- package/dist/installers/index.js.map +1 -0
- package/dist/installers/installer.d.ts +12 -0
- package/dist/installers/installer.js +30 -0
- package/dist/installers/installer.js.map +1 -0
- package/dist/installers/stencil/django-template/installer.d.ts +10 -0
- package/dist/installers/stencil/django-template/installer.js +77 -0
- package/dist/installers/stencil/django-template/installer.js.map +1 -0
- package/dist/installers/stencil/react/installer.d.ts +9 -0
- package/dist/installers/stencil/react/installer.js +22 -0
- package/dist/installers/stencil/react/installer.js.map +1 -0
- package/dist/installers/stencil/react/manifest.json +17 -0
- package/dist/installers/types.d.ts +24 -0
- package/dist/installers/types.js +2 -0
- package/dist/installers/types.js.map +1 -0
- package/dist/lock.d.ts +25 -0
- package/dist/lock.js +86 -0
- package/dist/lock.js.map +1 -0
- package/dist/manifest.d.ts +1 -0
- package/dist/manifest.js +93 -0
- package/dist/manifest.js.map +1 -0
- package/dist/pm/audit.d.ts +36 -0
- package/dist/pm/audit.js +147 -0
- package/dist/pm/audit.js.map +1 -0
- package/dist/pm/backlog.d.ts +3 -0
- package/dist/pm/backlog.js +123 -0
- package/dist/pm/backlog.js.map +1 -0
- package/dist/pm/brief.d.ts +4 -0
- package/dist/pm/brief.js +18 -0
- package/dist/pm/brief.js.map +1 -0
- package/dist/pm/git.d.ts +3 -0
- package/dist/pm/git.js +43 -0
- package/dist/pm/git.js.map +1 -0
- package/dist/pm/grid.d.ts +8 -0
- package/dist/pm/grid.js +16 -0
- package/dist/pm/grid.js.map +1 -0
- package/dist/pm/index.d.ts +25 -0
- package/dist/pm/index.js +199 -0
- package/dist/pm/index.js.map +1 -0
- package/dist/pm/observe.d.ts +55 -0
- package/dist/pm/observe.js +177 -0
- package/dist/pm/observe.js.map +1 -0
- package/dist/pm/plan.d.ts +54 -0
- package/dist/pm/plan.js +151 -0
- package/dist/pm/plan.js.map +1 -0
- package/dist/pm/refinement-worktree.d.ts +31 -0
- package/dist/pm/refinement-worktree.js +160 -0
- package/dist/pm/refinement-worktree.js.map +1 -0
- package/dist/pm/refinement.d.ts +79 -0
- package/dist/pm/refinement.js +326 -0
- package/dist/pm/refinement.js.map +1 -0
- package/dist/pm/render.d.ts +2 -0
- package/dist/pm/render.js +39 -0
- package/dist/pm/render.js.map +1 -0
- package/dist/pm/roadmap-rings.d.ts +7 -0
- package/dist/pm/roadmap-rings.js +31 -0
- package/dist/pm/roadmap-rings.js.map +1 -0
- package/dist/pm/roadmap.d.ts +2 -0
- package/dist/pm/roadmap.js +118 -0
- package/dist/pm/roadmap.js.map +1 -0
- package/dist/pm/snapshot.d.ts +10 -0
- package/dist/pm/snapshot.js +129 -0
- package/dist/pm/snapshot.js.map +1 -0
- package/dist/pm/types.d.ts +99 -0
- package/dist/pm/types.js +29 -0
- package/dist/pm/types.js.map +1 -0
- package/dist/registry-layout.d.ts +18 -0
- package/dist/registry-layout.js +122 -0
- package/dist/registry-layout.js.map +1 -0
- package/dist/scaffold-registry.d.ts +10 -0
- package/dist/scaffold-registry.js +283 -0
- package/dist/scaffold-registry.js.map +1 -0
- package/dist/scaffold.d.ts +1 -0
- package/dist/scaffold.js +32 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/spec-from-react.d.ts +11 -0
- package/dist/spec-from-react.js +522 -0
- package/dist/spec-from-react.js.map +1 -0
- package/dist/spec-from-stencil.d.ts +7 -0
- package/dist/spec-from-stencil.js +275 -0
- package/dist/spec-from-stencil.js.map +1 -0
- package/dist/spec.d.ts +1 -0
- package/dist/spec.js +60 -0
- package/dist/spec.js.map +1 -0
- package/dist/tokens-map.d.ts +11 -0
- package/dist/tokens-map.js +43 -0
- package/dist/tokens-map.js.map +1 -0
- package/dist/update.d.ts +39 -0
- package/dist/update.js +490 -0
- package/dist/update.js.map +1 -0
- package/dist/workspace-init.d.ts +9 -0
- package/dist/workspace-init.js +119 -0
- package/dist/workspace-init.js.map +1 -0
- package/package.json +53 -0
package/dist/pm/plan.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
const CMD_PATTERN = /`(?:chiralkit|ck) ([a-z][a-z0-9-]*(?: [a-z][a-z0-9-]*)?)(?:[^a-z0-9-][^`]*)?`/;
|
|
3
|
+
function backlogSource(task) {
|
|
4
|
+
return task.kit ? `kits/${task.kit}/BACKLOG.md` : "BACKLOG.md";
|
|
5
|
+
}
|
|
6
|
+
function selectReadyItems(snapshot, priorityFilter) {
|
|
7
|
+
const items = [];
|
|
8
|
+
for (const task of snapshot.backlog.orderedTasks) {
|
|
9
|
+
if (task.checked || task.status !== "ready")
|
|
10
|
+
continue;
|
|
11
|
+
if (!priorityFilter.has(task.priority))
|
|
12
|
+
continue;
|
|
13
|
+
items.push({ source: backlogSource(task), line: task.line, priority: task.priority, title: task.text, kit: task.kit });
|
|
14
|
+
}
|
|
15
|
+
return items;
|
|
16
|
+
}
|
|
17
|
+
async function listWorktrees(deps) {
|
|
18
|
+
try {
|
|
19
|
+
const output = await deps.git(deps.cwd, ["worktree", "list", "--porcelain"]);
|
|
20
|
+
return output.trim().split(/\r?\n\r?\n/).map((record) => {
|
|
21
|
+
const lines = record.split(/\r?\n/);
|
|
22
|
+
if (lines.some((line) => line.startsWith("prunable")))
|
|
23
|
+
return undefined;
|
|
24
|
+
const path = lines.find((line) => line.startsWith("worktree "))?.slice(9);
|
|
25
|
+
if (!path)
|
|
26
|
+
return undefined;
|
|
27
|
+
const branch = lines.find((line) => line.startsWith("branch "))?.slice(7).replace(/^refs\/heads\//, "") ?? "detached";
|
|
28
|
+
return { path, branch, current: false, dirty: false };
|
|
29
|
+
}).filter((worktree) => worktree !== undefined);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function findActiveWorktrees(deps, worktrees, activeDays, mainBranch, now) {
|
|
36
|
+
const active = [];
|
|
37
|
+
for (const worktree of worktrees) {
|
|
38
|
+
if (worktree.branch === mainBranch)
|
|
39
|
+
continue;
|
|
40
|
+
try {
|
|
41
|
+
const isoRaw = (await deps.git(worktree.path, ["log", "-1", "--format=%cI", "HEAD"])).trim();
|
|
42
|
+
if (!isoRaw)
|
|
43
|
+
continue;
|
|
44
|
+
const lastCommit = new Date(isoRaw);
|
|
45
|
+
const daysSince = Math.floor((now.getTime() - lastCommit.getTime()) / 86_400_000);
|
|
46
|
+
if (daysSince <= activeDays)
|
|
47
|
+
active.push({ path: worktree.path, branch: worktree.branch, lastCommitISO: isoRaw, daysSince });
|
|
48
|
+
}
|
|
49
|
+
catch { /* worktree unreadable — skip */ }
|
|
50
|
+
}
|
|
51
|
+
return active;
|
|
52
|
+
}
|
|
53
|
+
function extractCommand(item) {
|
|
54
|
+
const source = `${item.title} ${item.description}`;
|
|
55
|
+
const match = CMD_PATTERN.exec(source);
|
|
56
|
+
return match?.[1];
|
|
57
|
+
}
|
|
58
|
+
async function findRoadmapGaps(deps, snapshot) {
|
|
59
|
+
const errors = [];
|
|
60
|
+
const cliIndex = join(deps.cwd, "packages/cli/src/index.ts");
|
|
61
|
+
let indexText = "";
|
|
62
|
+
try {
|
|
63
|
+
indexText = await deps.readText(cliIndex);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
errors.push(`plan: read ${cliIndex}: ${error.message}`);
|
|
67
|
+
}
|
|
68
|
+
const gaps = [];
|
|
69
|
+
for (const horizon of snapshot.roadmap.horizons) {
|
|
70
|
+
for (const item of horizon.items) {
|
|
71
|
+
if (item.checked)
|
|
72
|
+
continue;
|
|
73
|
+
if (item.area !== "CLI")
|
|
74
|
+
continue;
|
|
75
|
+
const command = extractCommand(item);
|
|
76
|
+
if (!command)
|
|
77
|
+
continue;
|
|
78
|
+
const top = command.split(" ")[0];
|
|
79
|
+
const caseNeedle = `case "${top}":`;
|
|
80
|
+
const wired = indexText.includes(caseNeedle);
|
|
81
|
+
const primary = join(deps.cwd, `packages/cli/src/${top}.ts`);
|
|
82
|
+
const hasPrimary = await deps.fileExists(primary);
|
|
83
|
+
if (!wired && !hasPrimary)
|
|
84
|
+
gaps.push({ line: item.line, title: item.title, area: item.area, command });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return { gaps, errors };
|
|
88
|
+
}
|
|
89
|
+
async function fetchOpenPullRequests(deps, now) {
|
|
90
|
+
const errors = [];
|
|
91
|
+
if (!deps.listOpenPullRequests)
|
|
92
|
+
return { prs: [], errors };
|
|
93
|
+
try {
|
|
94
|
+
const raw = await deps.listOpenPullRequests();
|
|
95
|
+
const prs = raw.map((pr) => {
|
|
96
|
+
const updated = new Date(pr.updatedAt);
|
|
97
|
+
const daysSince = Math.floor((now.getTime() - updated.getTime()) / 86_400_000);
|
|
98
|
+
return { number: pr.number, title: pr.title, branch: pr.headRefName, updatedISO: pr.updatedAt, daysSince };
|
|
99
|
+
});
|
|
100
|
+
return { prs, errors };
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
errors.push(`plan: list PRs: ${error.message}`);
|
|
104
|
+
return { prs: [], errors };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export async function runPlan(deps, snapshot) {
|
|
108
|
+
const now = (deps.now ?? (() => new Date()))();
|
|
109
|
+
const activeDays = deps.activeDays ?? 3;
|
|
110
|
+
const mainBranch = deps.mainBranch ?? "main";
|
|
111
|
+
const priorityFilter = deps.priorityFilter ?? new Set(["P0", "P1", "P2"]);
|
|
112
|
+
const errors = [];
|
|
113
|
+
const readyItems = selectReadyItems(snapshot, priorityFilter);
|
|
114
|
+
const worktrees = snapshot.git.available ? snapshot.git.worktrees : await listWorktrees(deps);
|
|
115
|
+
const activeWorktrees = await findActiveWorktrees(deps, worktrees, activeDays, mainBranch, now);
|
|
116
|
+
const roadmap = await findRoadmapGaps(deps, snapshot);
|
|
117
|
+
errors.push(...roadmap.errors);
|
|
118
|
+
const pullRequests = await fetchOpenPullRequests(deps, now);
|
|
119
|
+
errors.push(...pullRequests.errors);
|
|
120
|
+
return { readyItems, activeWorktrees, openPullRequests: pullRequests.prs, roadmapGaps: roadmap.gaps, errors };
|
|
121
|
+
}
|
|
122
|
+
export function renderPlanReport(report) {
|
|
123
|
+
const lines = ["", "PLAN — work ready today"];
|
|
124
|
+
lines.push(" ready P0/P1/P2 backlog items:");
|
|
125
|
+
if (report.readyItems.length === 0)
|
|
126
|
+
lines.push(" none");
|
|
127
|
+
for (const item of report.readyItems)
|
|
128
|
+
lines.push(` - ${item.source}:${item.line} [${item.priority}] ${item.title}`);
|
|
129
|
+
lines.push(" active worktrees (recent commits):");
|
|
130
|
+
if (report.activeWorktrees.length === 0)
|
|
131
|
+
lines.push(" none");
|
|
132
|
+
for (const worktree of report.activeWorktrees)
|
|
133
|
+
lines.push(` - ${worktree.branch} ${worktree.daysSince}d ago ${worktree.path}`);
|
|
134
|
+
lines.push(" open pull requests:");
|
|
135
|
+
if (report.openPullRequests.length === 0)
|
|
136
|
+
lines.push(" none");
|
|
137
|
+
for (const pr of report.openPullRequests)
|
|
138
|
+
lines.push(` - #${pr.number} ${pr.title} (${pr.branch}, updated ${pr.daysSince}d ago)`);
|
|
139
|
+
lines.push(" roadmap items with no implementation yet:");
|
|
140
|
+
if (report.roadmapGaps.length === 0)
|
|
141
|
+
lines.push(" none");
|
|
142
|
+
for (const gap of report.roadmapGaps)
|
|
143
|
+
lines.push(` - ROADMAP.md:${gap.line} ck ${gap.command} — ${gap.title}`);
|
|
144
|
+
if (report.errors.length > 0) {
|
|
145
|
+
lines.push(" plan errors:");
|
|
146
|
+
for (const error of report.errors)
|
|
147
|
+
lines.push(` ! ${error}`);
|
|
148
|
+
}
|
|
149
|
+
return `${lines.join("\n")}\n`;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/pm/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GitExec } from "./git.js";
|
|
2
|
+
import type { MutationRecord } from "./refinement.js";
|
|
3
|
+
export declare const REFINEMENT_BRANCH = "automations/pm-refinement";
|
|
4
|
+
export declare const REFINEMENT_WORKTREE_REL_PATH = ".worktrees/pm-refinement";
|
|
5
|
+
export interface EnsureWorktreeDeps {
|
|
6
|
+
repoRoot: string;
|
|
7
|
+
git: GitExec;
|
|
8
|
+
mainBranch?: string;
|
|
9
|
+
originName?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface EnsureWorktreeResult {
|
|
12
|
+
path: string;
|
|
13
|
+
branch: string;
|
|
14
|
+
created: boolean;
|
|
15
|
+
syncedFrom: string;
|
|
16
|
+
warnings: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface CommitDeps {
|
|
19
|
+
worktreePath: string;
|
|
20
|
+
git: GitExec;
|
|
21
|
+
now?: () => Date;
|
|
22
|
+
}
|
|
23
|
+
export interface CommitResult {
|
|
24
|
+
committed: boolean;
|
|
25
|
+
sha: string | null;
|
|
26
|
+
message: string;
|
|
27
|
+
reason?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function ensureRefinementWorktree(deps: EnsureWorktreeDeps): Promise<EnsureWorktreeResult>;
|
|
30
|
+
export declare function commitRefinementMutations(deps: CommitDeps, mutations: readonly MutationRecord[]): Promise<CommitResult>;
|
|
31
|
+
export declare function relativeToRepo(repoRoot: string, absPath: string): string;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { join, relative } from "node:path";
|
|
2
|
+
export const REFINEMENT_BRANCH = "automations/pm-refinement";
|
|
3
|
+
export const REFINEMENT_WORKTREE_REL_PATH = ".worktrees/pm-refinement";
|
|
4
|
+
function porcelainWorktreeIsRegistered(output, worktreePath) {
|
|
5
|
+
const target = worktreePath.endsWith("/") ? worktreePath.slice(0, -1) : worktreePath;
|
|
6
|
+
return output.split(/\r?\n/).some((line) => {
|
|
7
|
+
if (!line.startsWith("worktree "))
|
|
8
|
+
return false;
|
|
9
|
+
const registered = line.slice(9).trim();
|
|
10
|
+
const normalized = registered.endsWith("/") ? registered.slice(0, -1) : registered;
|
|
11
|
+
return normalized === target;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
async function tryGit(git, cwd, args) {
|
|
15
|
+
try {
|
|
16
|
+
const stdout = await git(cwd, args);
|
|
17
|
+
return { ok: true, stdout };
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Idempotent. Guarantees a git worktree exists at `.worktrees/pm-refinement/`
|
|
24
|
+
// tracking the `automations/pm-refinement` branch, reset hard to origin/main
|
|
25
|
+
// (or local main) so refinement always runs against the latest committed state.
|
|
26
|
+
//
|
|
27
|
+
// Design tradeoff: `git reset --hard` discards any un-merged content on the
|
|
28
|
+
// refinement branch (e.g. a previous cron commit not yet pulled into main).
|
|
29
|
+
// This is safe because refinement is idempotent: re-running against the current
|
|
30
|
+
// Inbox produces the same output. The previous commit's content is not lost —
|
|
31
|
+
// it can be re-derived from the same source.
|
|
32
|
+
export async function ensureRefinementWorktree(deps) {
|
|
33
|
+
const mainBranch = deps.mainBranch ?? "main";
|
|
34
|
+
const originName = deps.originName ?? "origin";
|
|
35
|
+
const worktreeAbsPath = join(deps.repoRoot, REFINEMENT_WORKTREE_REL_PATH);
|
|
36
|
+
const warnings = [];
|
|
37
|
+
const listResult = await tryGit(deps.git, deps.repoRoot, ["worktree", "list", "--porcelain"]);
|
|
38
|
+
if (!listResult.ok) {
|
|
39
|
+
throw new Error(`worktree: cannot list worktrees at ${deps.repoRoot}: ${listResult.error}`);
|
|
40
|
+
}
|
|
41
|
+
const fetchResult = await tryGit(deps.git, deps.repoRoot, ["fetch", originName, mainBranch]);
|
|
42
|
+
const originAvailable = fetchResult.ok;
|
|
43
|
+
if (!originAvailable) {
|
|
44
|
+
warnings.push(`worktree: fetch ${originName} ${mainBranch} failed, falling back to local ${mainBranch}: ${fetchResult.error}`);
|
|
45
|
+
}
|
|
46
|
+
// Sync-ref policy: prefer whichever of local `main` or `origin/main` is
|
|
47
|
+
// *ahead*, so refinement always sees the freshest committed inbox state.
|
|
48
|
+
// - remote unreachable → local `main`
|
|
49
|
+
// - local ahead, remote not → local `main`
|
|
50
|
+
// - remote ahead, local not → `origin/main`
|
|
51
|
+
// - same → `origin/main` (canonical when they match)
|
|
52
|
+
// - diverged → `origin/main` + a warning; local-only commits are dropped
|
|
53
|
+
// but refinement is idempotent, so nothing is lost from the inbox.
|
|
54
|
+
const originRef = `${originName}/${mainBranch}`;
|
|
55
|
+
let syncRef = mainBranch;
|
|
56
|
+
if (originAvailable) {
|
|
57
|
+
const cmp = await tryGit(deps.git, deps.repoRoot, [
|
|
58
|
+
"rev-list", "--left-right", "--count", `${mainBranch}...${originRef}`,
|
|
59
|
+
]);
|
|
60
|
+
if (cmp.ok) {
|
|
61
|
+
const [aheadRaw, behindRaw] = cmp.stdout.trim().split(/\s+/);
|
|
62
|
+
const localAhead = Number(aheadRaw ?? 0);
|
|
63
|
+
const remoteAhead = Number(behindRaw ?? 0);
|
|
64
|
+
if (localAhead > 0 && remoteAhead > 0) {
|
|
65
|
+
syncRef = originRef;
|
|
66
|
+
warnings.push(`worktree: local ${mainBranch} diverged from ${originRef} (local +${localAhead}, remote +${remoteAhead}); syncing to ${originRef}`);
|
|
67
|
+
}
|
|
68
|
+
else if (localAhead > 0) {
|
|
69
|
+
syncRef = mainBranch;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
syncRef = originRef;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
syncRef = originRef;
|
|
77
|
+
warnings.push(`worktree: rev-list compare failed, using ${originRef}: ${cmp.error}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const alreadyRegistered = porcelainWorktreeIsRegistered(listResult.stdout, worktreeAbsPath);
|
|
81
|
+
if (!alreadyRegistered) {
|
|
82
|
+
const addResult = await tryGit(deps.git, deps.repoRoot, [
|
|
83
|
+
"worktree", "add", "-B", REFINEMENT_BRANCH, worktreeAbsPath, syncRef,
|
|
84
|
+
]);
|
|
85
|
+
if (!addResult.ok) {
|
|
86
|
+
throw new Error(`worktree: cannot create ${REFINEMENT_WORKTREE_REL_PATH} on ${REFINEMENT_BRANCH} from ${syncRef}: ${addResult.error}`);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
path: worktreeAbsPath,
|
|
90
|
+
branch: REFINEMENT_BRANCH,
|
|
91
|
+
created: true,
|
|
92
|
+
syncedFrom: syncRef,
|
|
93
|
+
warnings,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const resetResult = await tryGit(deps.git, worktreeAbsPath, ["reset", "--hard", syncRef]);
|
|
97
|
+
if (!resetResult.ok) {
|
|
98
|
+
throw new Error(`worktree: cannot reset ${worktreeAbsPath} to ${syncRef}: ${resetResult.error}`);
|
|
99
|
+
}
|
|
100
|
+
const cleanResult = await tryGit(deps.git, worktreeAbsPath, ["clean", "-fd"]);
|
|
101
|
+
if (!cleanResult.ok) {
|
|
102
|
+
warnings.push(`worktree: clean failed (untracked leftovers may remain): ${cleanResult.error}`);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
path: worktreeAbsPath,
|
|
106
|
+
branch: REFINEMENT_BRANCH,
|
|
107
|
+
created: false,
|
|
108
|
+
syncedFrom: syncRef,
|
|
109
|
+
warnings,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export async function commitRefinementMutations(deps, mutations) {
|
|
113
|
+
if (mutations.length === 0) {
|
|
114
|
+
return { committed: false, sha: null, message: "", reason: "no mutations to commit" };
|
|
115
|
+
}
|
|
116
|
+
const kitsAffected = Array.from(new Set(mutations.map((m) => m.kit))).sort();
|
|
117
|
+
const message = buildCommitMessage(mutations);
|
|
118
|
+
// Stage every kits/*/BACKLOG.md that got mutated. Explicit paths only — never
|
|
119
|
+
// `git add -A` — so any unrelated leftover in the worktree stays out of the
|
|
120
|
+
// refinement commit.
|
|
121
|
+
const paths = kitsAffected.map((kit) => `kits/${kit}/BACKLOG.md`);
|
|
122
|
+
const addResult = await tryGit(deps.git, deps.worktreePath, ["add", "--", ...paths]);
|
|
123
|
+
if (!addResult.ok) {
|
|
124
|
+
return { committed: false, sha: null, message, reason: `git add failed: ${addResult.error}` };
|
|
125
|
+
}
|
|
126
|
+
const statusResult = await tryGit(deps.git, deps.worktreePath, ["diff", "--cached", "--name-only"]);
|
|
127
|
+
if (!statusResult.ok) {
|
|
128
|
+
return { committed: false, sha: null, message, reason: `git diff --cached failed: ${statusResult.error}` };
|
|
129
|
+
}
|
|
130
|
+
if (statusResult.stdout.trim() === "") {
|
|
131
|
+
return { committed: false, sha: null, message, reason: "no staged changes after add (mutation was a no-op)" };
|
|
132
|
+
}
|
|
133
|
+
const commitResult = await tryGit(deps.git, deps.worktreePath, ["commit", "-m", message]);
|
|
134
|
+
if (!commitResult.ok) {
|
|
135
|
+
return { committed: false, sha: null, message, reason: `git commit failed: ${commitResult.error}` };
|
|
136
|
+
}
|
|
137
|
+
const shaResult = await tryGit(deps.git, deps.worktreePath, ["rev-parse", "HEAD"]);
|
|
138
|
+
const sha = shaResult.ok ? shaResult.stdout.trim() : null;
|
|
139
|
+
return { committed: true, sha, message, reason: undefined };
|
|
140
|
+
}
|
|
141
|
+
function buildCommitMessage(mutations) {
|
|
142
|
+
const kitsAffected = Array.from(new Set(mutations.map((m) => m.kit))).sort();
|
|
143
|
+
const subject = `chore(refinement): route ${mutations.length} inbox ${mutations.length === 1 ? "item" : "items"} to Refined (${kitsAffected.join(", ")})`;
|
|
144
|
+
const bodyLines = mutations
|
|
145
|
+
.slice(0, 20)
|
|
146
|
+
.map((m) => `- kits/${m.kit}/BACKLOG.md:${m.oldLine} → ${truncate(m.newLineText, 96)}`);
|
|
147
|
+
if (mutations.length > 20)
|
|
148
|
+
bodyLines.push(`- … +${mutations.length - 20} more`);
|
|
149
|
+
return `${subject}\n\n${bodyLines.join("\n")}\n`;
|
|
150
|
+
}
|
|
151
|
+
function truncate(s, max) {
|
|
152
|
+
return s.length <= max ? s : `${s.slice(0, max - 1)}…`;
|
|
153
|
+
}
|
|
154
|
+
// Compute a repo-relative path from an absolute path anchored at `repoRoot`.
|
|
155
|
+
// Used by callers that need to render human-friendly locations in the report.
|
|
156
|
+
export function relativeToRepo(repoRoot, absPath) {
|
|
157
|
+
const rel = relative(repoRoot, absPath);
|
|
158
|
+
return rel === "" ? "." : rel;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=refinement-worktree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refinement-worktree.js","sourceRoot":"","sources":["../../src/pm/refinement-worktree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type KitName } from "@chiralkit/kits";
|
|
2
|
+
import type { Priority } from "./types.js";
|
|
3
|
+
export interface InboxItem {
|
|
4
|
+
kit: KitName;
|
|
5
|
+
line: number;
|
|
6
|
+
capturedDate: string;
|
|
7
|
+
source: string;
|
|
8
|
+
text: string;
|
|
9
|
+
}
|
|
10
|
+
export interface RefinementProposal {
|
|
11
|
+
kit: KitName;
|
|
12
|
+
line: number;
|
|
13
|
+
text: string;
|
|
14
|
+
priority: Priority;
|
|
15
|
+
time: 0 | 1 | 2 | 3 | 5 | 8 | 13;
|
|
16
|
+
difficulty: 0 | 1 | 2 | 3 | 5 | 8 | 13;
|
|
17
|
+
rationale: string;
|
|
18
|
+
}
|
|
19
|
+
export interface RefinementViolation {
|
|
20
|
+
kit: KitName;
|
|
21
|
+
line: number;
|
|
22
|
+
text: string;
|
|
23
|
+
reason: string;
|
|
24
|
+
}
|
|
25
|
+
export interface MutationRecord {
|
|
26
|
+
kit: KitName;
|
|
27
|
+
oldLine: number;
|
|
28
|
+
newLineText: string;
|
|
29
|
+
createdRefinedSection: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface SkippedMutation {
|
|
32
|
+
kit: KitName;
|
|
33
|
+
line: number;
|
|
34
|
+
reason: string;
|
|
35
|
+
}
|
|
36
|
+
export interface AppliedMutations {
|
|
37
|
+
mutated: MutationRecord[];
|
|
38
|
+
skipped: SkippedMutation[];
|
|
39
|
+
}
|
|
40
|
+
export interface WorktreeReport {
|
|
41
|
+
path: string;
|
|
42
|
+
branch: string;
|
|
43
|
+
created: boolean;
|
|
44
|
+
syncedFrom: string;
|
|
45
|
+
commit: {
|
|
46
|
+
committed: boolean;
|
|
47
|
+
sha: string | null;
|
|
48
|
+
subject: string;
|
|
49
|
+
reason?: string;
|
|
50
|
+
};
|
|
51
|
+
warnings: string[];
|
|
52
|
+
}
|
|
53
|
+
export interface RefinementReport {
|
|
54
|
+
proposals: RefinementProposal[];
|
|
55
|
+
violations: RefinementViolation[];
|
|
56
|
+
window: {
|
|
57
|
+
auditRuns: number;
|
|
58
|
+
planRuns: number;
|
|
59
|
+
};
|
|
60
|
+
applied: AppliedMutations | null;
|
|
61
|
+
worktree: WorktreeReport | null;
|
|
62
|
+
errors: string[];
|
|
63
|
+
}
|
|
64
|
+
export interface RefinementDependencies {
|
|
65
|
+
cwd: string;
|
|
66
|
+
kitsRoot?: string;
|
|
67
|
+
readText: (path: string) => Promise<string>;
|
|
68
|
+
writeText?: (path: string, content: string) => Promise<void>;
|
|
69
|
+
now?: () => Date;
|
|
70
|
+
windowDays?: number;
|
|
71
|
+
dryRun?: boolean;
|
|
72
|
+
}
|
|
73
|
+
export declare function applyMutationsToFile(md: string, proposals: readonly RefinementProposal[]): {
|
|
74
|
+
newMd: string;
|
|
75
|
+
mutated: MutationRecord[];
|
|
76
|
+
skipped: SkippedMutation[];
|
|
77
|
+
};
|
|
78
|
+
export declare function runRefinement(deps: RefinementDependencies): Promise<RefinementReport>;
|
|
79
|
+
export declare function renderRefinementReport(report: RefinementReport): string;
|