@popoverai/dotrequirements 0.23.0 → 0.24.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 +167 -20
- package/dist/cli.js +121 -60
- package/dist/codebase-to-spec/budget.d.ts +53 -0
- package/dist/codebase-to-spec/budget.js +80 -0
- package/dist/codebase-to-spec/cache.d.ts +49 -0
- package/dist/codebase-to-spec/cache.js +54 -0
- package/dist/codebase-to-spec/claude.d.ts +69 -0
- package/dist/codebase-to-spec/claude.js +126 -0
- package/dist/codebase-to-spec/compose.d.ts +49 -0
- package/dist/codebase-to-spec/compose.js +124 -0
- package/dist/codebase-to-spec/edit-loop.d.ts +54 -0
- package/dist/codebase-to-spec/edit-loop.js +195 -0
- package/dist/codebase-to-spec/editor.d.ts +54 -0
- package/dist/codebase-to-spec/editor.js +74 -0
- package/dist/codebase-to-spec/exit-codes.d.ts +40 -0
- package/dist/codebase-to-spec/exit-codes.js +58 -0
- package/dist/codebase-to-spec/fan-out.d.ts +63 -0
- package/dist/codebase-to-spec/fan-out.js +215 -0
- package/dist/codebase-to-spec/interactive.d.ts +30 -0
- package/dist/codebase-to-spec/interactive.js +48 -0
- package/dist/codebase-to-spec/outline-review-loop.d.ts +51 -0
- package/dist/codebase-to-spec/outline-review-loop.js +187 -0
- package/dist/codebase-to-spec/pack.d.ts +51 -0
- package/dist/codebase-to-spec/pack.js +127 -0
- package/dist/codebase-to-spec/planner.d.ts +41 -0
- package/dist/codebase-to-spec/planner.js +76 -0
- package/dist/codebase-to-spec/present.d.ts +94 -0
- package/dist/codebase-to-spec/present.js +288 -0
- package/dist/codebase-to-spec/progress.d.ts +33 -0
- package/dist/codebase-to-spec/progress.js +28 -0
- package/dist/codebase-to-spec/prompts/editor.d.ts +13 -0
- package/dist/codebase-to-spec/prompts/editor.js +57 -0
- package/dist/codebase-to-spec/prompts/outline-reviewer.d.ts +12 -0
- package/dist/codebase-to-spec/prompts/outline-reviewer.js +87 -0
- package/dist/codebase-to-spec/prompts/planner-apply.d.ts +12 -0
- package/dist/codebase-to-spec/prompts/planner-apply.js +32 -0
- package/dist/codebase-to-spec/prompts/planner-initial.d.ts +11 -0
- package/dist/codebase-to-spec/prompts/planner-initial.js +125 -0
- package/dist/codebase-to-spec/prompts/planner-revise.d.ts +14 -0
- package/dist/codebase-to-spec/prompts/planner-revise.js +60 -0
- package/dist/codebase-to-spec/prompts/spec-reviewer.d.ts +16 -0
- package/dist/codebase-to-spec/prompts/spec-reviewer.js +96 -0
- package/dist/codebase-to-spec/prompts/specifier.d.ts +12 -0
- package/dist/codebase-to-spec/prompts/specifier.js +100 -0
- package/dist/codebase-to-spec/prompts/style-check.d.ts +12 -0
- package/dist/codebase-to-spec/prompts/style-check.js +78 -0
- package/dist/codebase-to-spec/schemas.d.ts +257 -0
- package/dist/codebase-to-spec/schemas.js +183 -0
- package/dist/codebase-to-spec/skill-install.d.ts +57 -0
- package/dist/codebase-to-spec/skill-install.js +79 -0
- package/dist/codebase-to-spec/slice.d.ts +49 -0
- package/dist/codebase-to-spec/slice.js +111 -0
- package/dist/codebase-to-spec/specifier.d.ts +60 -0
- package/dist/codebase-to-spec/specifier.js +79 -0
- package/dist/codebase-to-spec/style-check.d.ts +29 -0
- package/dist/codebase-to-spec/style-check.js +33 -0
- package/dist/codebase-to-spec/summary.d.ts +51 -0
- package/dist/codebase-to-spec/summary.js +183 -0
- package/dist/codebase-to-spec/validate.d.ts +46 -0
- package/dist/codebase-to-spec/validate.js +130 -0
- package/dist/commands/acceptance-test.d.ts +6 -0
- package/dist/commands/acceptance-test.js +212 -0
- package/dist/commands/ai-setup.d.ts +5 -0
- package/dist/commands/ai-setup.js +441 -0
- package/dist/commands/browsertest.js +34 -27
- package/dist/commands/codebase-to-spec/compose.d.ts +14 -0
- package/dist/commands/codebase-to-spec/compose.js +57 -0
- package/dist/commands/codebase-to-spec/edit-loop.d.ts +16 -0
- package/dist/commands/codebase-to-spec/edit-loop.js +83 -0
- package/dist/commands/codebase-to-spec/fan-out.d.ts +19 -0
- package/dist/commands/codebase-to-spec/fan-out.js +77 -0
- package/dist/commands/codebase-to-spec/index.d.ts +9 -0
- package/dist/commands/codebase-to-spec/index.js +135 -0
- package/dist/commands/codebase-to-spec/pack.d.ts +22 -0
- package/dist/commands/codebase-to-spec/pack.js +76 -0
- package/dist/commands/codebase-to-spec/plan-loop.d.ts +26 -0
- package/dist/commands/codebase-to-spec/plan-loop.js +105 -0
- package/dist/commands/codebase-to-spec/present.d.ts +21 -0
- package/dist/commands/codebase-to-spec/present.js +92 -0
- package/dist/commands/codebase-to-spec/run.d.ts +20 -0
- package/dist/commands/codebase-to-spec/run.js +85 -0
- package/dist/commands/codebase-to-spec/skill-install.d.ts +20 -0
- package/dist/commands/codebase-to-spec/skill-install.js +51 -0
- package/dist/commands/codebase-to-spec/specify-area.d.ts +18 -0
- package/dist/commands/codebase-to-spec/specify-area.js +82 -0
- package/dist/commands/codebase-to-spec/style-check.d.ts +15 -0
- package/dist/commands/codebase-to-spec/style-check.js +42 -0
- package/dist/commands/codebase-to-spec/validate.d.ts +18 -0
- package/dist/commands/codebase-to-spec/validate.js +38 -0
- package/dist/commands/create-requirement-document.d.ts +2 -0
- package/dist/commands/create-requirement-document.js +41 -0
- package/dist/commands/finalize.js +7 -7
- package/dist/commands/get.d.ts +2 -0
- package/dist/commands/get.js +55 -0
- package/dist/commands/init.js +132 -117
- package/dist/commands/link.js +27 -27
- package/dist/commands/list.d.ts +6 -0
- package/dist/commands/list.js +43 -0
- package/dist/commands/mcp-setup.js +159 -149
- package/dist/commands/mcp.js +1 -1
- package/dist/commands/prepare.js +4 -4
- package/dist/commands/pull.js +116 -121
- package/dist/commands/push.js +106 -112
- package/dist/commands/report.d.ts +6 -2
- package/dist/commands/report.js +177 -122
- package/dist/commands/requirements-for.d.ts +2 -0
- package/dist/commands/requirements-for.js +29 -0
- package/dist/commands/review-test.d.ts +2 -0
- package/dist/commands/review-test.js +75 -0
- package/dist/commands/search.d.ts +6 -0
- package/dist/commands/search.js +39 -0
- package/dist/commands/style-check.d.ts +7 -0
- package/dist/commands/style-check.js +75 -0
- package/dist/commands/test.js +53 -59
- package/dist/commands/tests-for.d.ts +2 -0
- package/dist/commands/tests-for.js +80 -0
- package/dist/commands/validate.d.ts +6 -0
- package/dist/commands/validate.js +72 -0
- package/dist/config.js +1 -1
- package/dist/convex.d.ts +34 -22
- package/dist/convex.js +38 -22
- package/dist/harness/cache.d.ts +1 -5
- package/dist/harness/cache.js +49 -59
- package/dist/harness/convexReporting.d.ts +1 -1
- package/dist/harness/convexReporting.js +9 -7
- package/dist/harness/coverageCache.js +3 -3
- package/dist/harness/finalize.js +59 -46
- package/dist/harness/index.d.ts +6 -7
- package/dist/harness/index.js +9 -10
- package/dist/harness/prepare.js +6 -5
- package/dist/harness/requirementsLoader.d.ts +2 -2
- package/dist/harness/requirementsLoader.js +13 -35
- package/dist/harness/tracking.js +18 -18
- package/dist/harness/types.d.ts +1 -1
- package/dist/mcp/convexClient.d.ts +0 -39
- package/dist/mcp/convexClient.js +2 -107
- package/dist/mcp/grep.d.ts +1 -1
- package/dist/mcp/grep.js +87 -42
- package/dist/mcp/handlers/authoring.d.ts +1 -1
- package/dist/mcp/handlers/authoring.js +30 -234
- package/dist/mcp/handlers/coverage.d.ts +1 -1
- package/dist/mcp/handlers/coverage.js +13 -15
- package/dist/mcp/handlers/debug.d.ts +2 -3
- package/dist/mcp/handlers/debug.js +10 -10
- package/dist/mcp/handlers/get.d.ts +1 -1
- package/dist/mcp/handlers/get.js +11 -10
- package/dist/mcp/handlers/index.d.ts +20 -20
- package/dist/mcp/handlers/index.js +10 -10
- package/dist/mcp/handlers/list.d.ts +4 -33
- package/dist/mcp/handlers/list.js +16 -38
- package/dist/mcp/handlers/push.d.ts +1 -1
- package/dist/mcp/handlers/push.js +28 -18
- package/dist/mcp/handlers/report.d.ts +16 -0
- package/dist/mcp/handlers/report.js +134 -0
- package/dist/mcp/handlers/review.d.ts +1 -1
- package/dist/mcp/handlers/review.js +40 -59
- package/dist/mcp/handlers/search.d.ts +1 -1
- package/dist/mcp/handlers/search.js +7 -9
- package/dist/mcp/handlers/test-mapping.d.ts +1 -1
- package/dist/mcp/handlers/test-mapping.js +14 -14
- package/dist/mcp/handlers/types.d.ts +3 -3
- package/dist/mcp/handlers/types.js +2 -2
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +147 -167
- package/dist/mcp/requirements.d.ts +2 -2
- package/dist/mcp/requirements.js +30 -30
- package/dist/mcp/testCodeExtractor.js +24 -26
- package/dist/mcp/types.d.ts +1 -1
- package/dist/push/core.d.ts +2 -2
- package/dist/push/core.js +20 -20
- package/dist/push/index.d.ts +1 -1
- package/dist/push/index.js +2 -2
- package/dist/requirements/cloud-ai.d.ts +57 -0
- package/dist/requirements/cloud-ai.js +104 -0
- package/dist/requirements/cloud-coverage.d.ts +41 -0
- package/dist/requirements/cloud-coverage.js +60 -0
- package/dist/requirements/coverage.d.ts +45 -0
- package/dist/requirements/coverage.js +114 -0
- package/dist/requirements/grep.d.ts +33 -0
- package/dist/requirements/grep.js +306 -0
- package/dist/requirements/index.d.ts +73 -0
- package/dist/requirements/index.js +174 -0
- package/dist/requirements/style-guide.d.ts +67 -0
- package/dist/requirements/style-guide.js +299 -0
- package/dist/requirements/testCodeExtractor.d.ts +22 -0
- package/dist/requirements/testCodeExtractor.js +150 -0
- package/dist/schema/browser.d.ts +8 -8
- package/dist/schema/browser.js +13 -15
- package/dist/schema/builder.d.ts +1 -1
- package/dist/schema/builder.js +13 -44
- package/dist/schema/conversions.d.ts +2 -2
- package/dist/schema/conversions.js +11 -11
- package/dist/schema/index.d.ts +9 -9
- package/dist/schema/index.js +15 -15
- package/dist/schema/parser-core.d.ts +1 -1
- package/dist/schema/parser-core.js +23 -22
- package/dist/schema/parser.d.ts +3 -3
- package/dist/schema/parser.js +27 -31
- package/dist/schema/resolver.d.ts +1 -1
- package/dist/schema/resolver.js +9 -9
- package/dist/schema/scenario.d.ts +1 -1
- package/dist/schema/scenario.js +1 -1
- package/dist/schema/schemas.d.ts +3 -3
- package/dist/schema/schemas.js +41 -28
- package/dist/schema/test-schema.js +27 -27
- package/dist/templates/context-file-section.md +3 -2
- package/dist/templates/example-requirements.js +1 -1
- package/dist/templates/example-requirements.ts +3 -1
- package/dist/templates/requirements-readme.js +1 -1
- package/dist/templates/requirements-readme.ts +1 -1
- package/dist/templates/skills/codebase-to-spec/SKILL.md +118 -0
- package/dist/utils/brand.js +3 -3
- package/dist/utils/browser-launch.js +4 -4
- package/dist/utils/context-file.d.ts +1 -1
- package/dist/utils/context-file.js +26 -26
- package/dist/utils/env.js +7 -7
- package/dist/utils/gitignore.js +7 -7
- package/dist/utils/oauth-callback-server.d.ts +1 -1
- package/dist/utils/oauth-callback-server.js +27 -25
- package/dist/utils/oauth-flow.js +32 -29
- package/dist/utils/project-discovery.d.ts +3 -3
- package/dist/utils/project-discovery.js +18 -17
- package/dist/utils/project-name.js +8 -8
- package/dist/utils/project-selector.d.ts +1 -1
- package/dist/utils/project-selector.js +24 -21
- package/dist/utils/project-settings.d.ts +1 -1
- package/dist/utils/project-settings.js +24 -22
- package/dist/utils/templates.js +6 -6
- package/package.json +2 -1
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON schemas for outline + reviewer output.
|
|
3
|
+
*
|
|
4
|
+
* The CLI passes these to `claude -p --json-schema` to constrain agent output,
|
|
5
|
+
* then validates the parsed result before driving the loop.
|
|
6
|
+
*
|
|
7
|
+
* Requirements covered:
|
|
8
|
+
* - CTS-PLAN-1: outline structure
|
|
9
|
+
* - CTS-PLAN-2: outline reviewer output structure (categorized findings + verdict)
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
export declare const AreaSchema: z.ZodObject<{
|
|
13
|
+
name: z.ZodString;
|
|
14
|
+
description: z.ZodString;
|
|
15
|
+
prefix: z.ZodString;
|
|
16
|
+
files: z.ZodArray<z.ZodString, "many">;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
prefix: string;
|
|
19
|
+
files: string[];
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
}, {
|
|
23
|
+
prefix: string;
|
|
24
|
+
files: string[];
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
}>;
|
|
28
|
+
export type Area = z.infer<typeof AreaSchema>;
|
|
29
|
+
export declare const OutlineSchema: z.ZodObject<{
|
|
30
|
+
title: z.ZodString;
|
|
31
|
+
defaultPrefix: z.ZodString;
|
|
32
|
+
summary: z.ZodString;
|
|
33
|
+
areas: z.ZodArray<z.ZodObject<{
|
|
34
|
+
name: z.ZodString;
|
|
35
|
+
description: z.ZodString;
|
|
36
|
+
prefix: z.ZodString;
|
|
37
|
+
files: z.ZodArray<z.ZodString, "many">;
|
|
38
|
+
}, "strip", z.ZodTypeAny, {
|
|
39
|
+
prefix: string;
|
|
40
|
+
files: string[];
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
}, {
|
|
44
|
+
prefix: string;
|
|
45
|
+
files: string[];
|
|
46
|
+
name: string;
|
|
47
|
+
description: string;
|
|
48
|
+
}>, "many">;
|
|
49
|
+
}, "strip", z.ZodTypeAny, {
|
|
50
|
+
title: string;
|
|
51
|
+
defaultPrefix: string;
|
|
52
|
+
summary: string;
|
|
53
|
+
areas: {
|
|
54
|
+
prefix: string;
|
|
55
|
+
files: string[];
|
|
56
|
+
name: string;
|
|
57
|
+
description: string;
|
|
58
|
+
}[];
|
|
59
|
+
}, {
|
|
60
|
+
title: string;
|
|
61
|
+
defaultPrefix: string;
|
|
62
|
+
summary: string;
|
|
63
|
+
areas: {
|
|
64
|
+
prefix: string;
|
|
65
|
+
files: string[];
|
|
66
|
+
name: string;
|
|
67
|
+
description: string;
|
|
68
|
+
}[];
|
|
69
|
+
}>;
|
|
70
|
+
export type Outline = z.infer<typeof OutlineSchema>;
|
|
71
|
+
/**
|
|
72
|
+
* JSON Schema for the outline, passed to `claude -p --json-schema`.
|
|
73
|
+
* Mirrors OutlineSchema in JSON Schema form (which `claude -p` accepts).
|
|
74
|
+
*/
|
|
75
|
+
export declare const OUTLINE_JSON_SCHEMA: {
|
|
76
|
+
readonly type: "object";
|
|
77
|
+
readonly properties: {
|
|
78
|
+
readonly title: {
|
|
79
|
+
readonly type: "string";
|
|
80
|
+
};
|
|
81
|
+
readonly defaultPrefix: {
|
|
82
|
+
readonly type: "string";
|
|
83
|
+
};
|
|
84
|
+
readonly summary: {
|
|
85
|
+
readonly type: "string";
|
|
86
|
+
};
|
|
87
|
+
readonly areas: {
|
|
88
|
+
readonly type: "array";
|
|
89
|
+
readonly items: {
|
|
90
|
+
readonly type: "object";
|
|
91
|
+
readonly properties: {
|
|
92
|
+
readonly name: {
|
|
93
|
+
readonly type: "string";
|
|
94
|
+
};
|
|
95
|
+
readonly description: {
|
|
96
|
+
readonly type: "string";
|
|
97
|
+
};
|
|
98
|
+
readonly prefix: {
|
|
99
|
+
readonly type: "string";
|
|
100
|
+
};
|
|
101
|
+
readonly files: {
|
|
102
|
+
readonly type: "array";
|
|
103
|
+
readonly items: {
|
|
104
|
+
readonly type: "string";
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
readonly required: readonly ["name", "description", "prefix", "files"];
|
|
109
|
+
readonly additionalProperties: false;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
readonly required: readonly ["title", "defaultPrefix", "summary", "areas"];
|
|
114
|
+
readonly additionalProperties: false;
|
|
115
|
+
};
|
|
116
|
+
export declare const VerdictValues: readonly ["approved", "approved-with-revisions", "requires-another-review"];
|
|
117
|
+
export type Verdict = (typeof VerdictValues)[number];
|
|
118
|
+
export declare const OutlineReviewSchema: z.ZodObject<{
|
|
119
|
+
coverage_gaps: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
120
|
+
framing_errors: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
121
|
+
granularity_issues: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
122
|
+
file_assignment_issues: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
123
|
+
revisions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
124
|
+
verdict: z.ZodEnum<["approved", "approved-with-revisions", "requires-another-review"]>;
|
|
125
|
+
}, "strip", z.ZodTypeAny, {
|
|
126
|
+
coverage_gaps: string[];
|
|
127
|
+
framing_errors: string[];
|
|
128
|
+
granularity_issues: string[];
|
|
129
|
+
file_assignment_issues: string[];
|
|
130
|
+
revisions: string[];
|
|
131
|
+
verdict: "approved" | "approved-with-revisions" | "requires-another-review";
|
|
132
|
+
}, {
|
|
133
|
+
verdict: "approved" | "approved-with-revisions" | "requires-another-review";
|
|
134
|
+
coverage_gaps?: string[] | undefined;
|
|
135
|
+
framing_errors?: string[] | undefined;
|
|
136
|
+
granularity_issues?: string[] | undefined;
|
|
137
|
+
file_assignment_issues?: string[] | undefined;
|
|
138
|
+
revisions?: string[] | undefined;
|
|
139
|
+
}>;
|
|
140
|
+
export type OutlineReview = z.infer<typeof OutlineReviewSchema>;
|
|
141
|
+
export declare const OUTLINE_REVIEW_JSON_SCHEMA: {
|
|
142
|
+
readonly type: "object";
|
|
143
|
+
readonly properties: {
|
|
144
|
+
readonly coverage_gaps: {
|
|
145
|
+
readonly type: "array";
|
|
146
|
+
readonly items: {
|
|
147
|
+
readonly type: "string";
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
readonly framing_errors: {
|
|
151
|
+
readonly type: "array";
|
|
152
|
+
readonly items: {
|
|
153
|
+
readonly type: "string";
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
readonly granularity_issues: {
|
|
157
|
+
readonly type: "array";
|
|
158
|
+
readonly items: {
|
|
159
|
+
readonly type: "string";
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
readonly file_assignment_issues: {
|
|
163
|
+
readonly type: "array";
|
|
164
|
+
readonly items: {
|
|
165
|
+
readonly type: "string";
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
readonly revisions: {
|
|
169
|
+
readonly type: "array";
|
|
170
|
+
readonly items: {
|
|
171
|
+
readonly type: "string";
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
readonly verdict: {
|
|
175
|
+
readonly type: "string";
|
|
176
|
+
readonly enum: readonly string[];
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
readonly required: readonly ["coverage_gaps", "framing_errors", "granularity_issues", "file_assignment_issues", "revisions", "verdict"];
|
|
180
|
+
readonly additionalProperties: false;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Try to parse a string as JSON and validate against the outline schema.
|
|
184
|
+
* Throws with a descriptive message on failure (caller catches and either
|
|
185
|
+
* retries or fails the loop).
|
|
186
|
+
*/
|
|
187
|
+
export declare function parseOutline(text: string): Outline;
|
|
188
|
+
/**
|
|
189
|
+
* Parse a reviewer's JSON output and validate against the outline-review schema.
|
|
190
|
+
*/
|
|
191
|
+
export declare function parseOutlineReview(text: string): OutlineReview;
|
|
192
|
+
export declare const SpecReviewSchema: z.ZodObject<{
|
|
193
|
+
coverage_gaps: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
194
|
+
framing_errors: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
195
|
+
cross_area_issues: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
196
|
+
internal_mechanics_drift: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
197
|
+
revisions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
198
|
+
verdict: z.ZodEnum<["approved", "approved-with-revisions", "requires-another-review"]>;
|
|
199
|
+
}, "strip", z.ZodTypeAny, {
|
|
200
|
+
coverage_gaps: string[];
|
|
201
|
+
framing_errors: string[];
|
|
202
|
+
revisions: string[];
|
|
203
|
+
verdict: "approved" | "approved-with-revisions" | "requires-another-review";
|
|
204
|
+
cross_area_issues: string[];
|
|
205
|
+
internal_mechanics_drift: string[];
|
|
206
|
+
}, {
|
|
207
|
+
verdict: "approved" | "approved-with-revisions" | "requires-another-review";
|
|
208
|
+
coverage_gaps?: string[] | undefined;
|
|
209
|
+
framing_errors?: string[] | undefined;
|
|
210
|
+
revisions?: string[] | undefined;
|
|
211
|
+
cross_area_issues?: string[] | undefined;
|
|
212
|
+
internal_mechanics_drift?: string[] | undefined;
|
|
213
|
+
}>;
|
|
214
|
+
export type SpecReview = z.infer<typeof SpecReviewSchema>;
|
|
215
|
+
export declare const SPEC_REVIEW_JSON_SCHEMA: {
|
|
216
|
+
readonly type: "object";
|
|
217
|
+
readonly properties: {
|
|
218
|
+
readonly coverage_gaps: {
|
|
219
|
+
readonly type: "array";
|
|
220
|
+
readonly items: {
|
|
221
|
+
readonly type: "string";
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
readonly framing_errors: {
|
|
225
|
+
readonly type: "array";
|
|
226
|
+
readonly items: {
|
|
227
|
+
readonly type: "string";
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
readonly cross_area_issues: {
|
|
231
|
+
readonly type: "array";
|
|
232
|
+
readonly items: {
|
|
233
|
+
readonly type: "string";
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
readonly internal_mechanics_drift: {
|
|
237
|
+
readonly type: "array";
|
|
238
|
+
readonly items: {
|
|
239
|
+
readonly type: "string";
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
readonly revisions: {
|
|
243
|
+
readonly type: "array";
|
|
244
|
+
readonly items: {
|
|
245
|
+
readonly type: "string";
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
readonly verdict: {
|
|
249
|
+
readonly type: "string";
|
|
250
|
+
readonly enum: readonly string[];
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
readonly required: readonly ["coverage_gaps", "framing_errors", "cross_area_issues", "internal_mechanics_drift", "revisions", "verdict"];
|
|
254
|
+
readonly additionalProperties: false;
|
|
255
|
+
};
|
|
256
|
+
export declare function parseSpecReview(text: string): SpecReview;
|
|
257
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON schemas for outline + reviewer output.
|
|
3
|
+
*
|
|
4
|
+
* The CLI passes these to `claude -p --json-schema` to constrain agent output,
|
|
5
|
+
* then validates the parsed result before driving the loop.
|
|
6
|
+
*
|
|
7
|
+
* Requirements covered:
|
|
8
|
+
* - CTS-PLAN-1: outline structure
|
|
9
|
+
* - CTS-PLAN-2: outline reviewer output structure (categorized findings + verdict)
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
// ---------- Outline ----------
|
|
13
|
+
export const AreaSchema = z.object({
|
|
14
|
+
name: z.string().min(1),
|
|
15
|
+
description: z.string().min(1),
|
|
16
|
+
prefix: z
|
|
17
|
+
.string()
|
|
18
|
+
.regex(/^[A-Z][A-Z0-9_]*$/, "prefix must be uppercase alphanumeric/underscore"),
|
|
19
|
+
files: z.array(z.string()).min(0),
|
|
20
|
+
});
|
|
21
|
+
export const OutlineSchema = z.object({
|
|
22
|
+
title: z.string().min(1),
|
|
23
|
+
defaultPrefix: z
|
|
24
|
+
.string()
|
|
25
|
+
.regex(/^[A-Z][A-Z0-9_]*$/, "defaultPrefix must be uppercase alphanumeric/underscore"),
|
|
26
|
+
summary: z.string().min(1),
|
|
27
|
+
areas: z.array(AreaSchema).min(1),
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* JSON Schema for the outline, passed to `claude -p --json-schema`.
|
|
31
|
+
* Mirrors OutlineSchema in JSON Schema form (which `claude -p` accepts).
|
|
32
|
+
*/
|
|
33
|
+
export const OUTLINE_JSON_SCHEMA = {
|
|
34
|
+
type: "object",
|
|
35
|
+
properties: {
|
|
36
|
+
title: { type: "string" },
|
|
37
|
+
defaultPrefix: { type: "string" },
|
|
38
|
+
summary: { type: "string" },
|
|
39
|
+
areas: {
|
|
40
|
+
type: "array",
|
|
41
|
+
items: {
|
|
42
|
+
type: "object",
|
|
43
|
+
properties: {
|
|
44
|
+
name: { type: "string" },
|
|
45
|
+
description: { type: "string" },
|
|
46
|
+
prefix: { type: "string" },
|
|
47
|
+
files: { type: "array", items: { type: "string" } },
|
|
48
|
+
},
|
|
49
|
+
required: ["name", "description", "prefix", "files"],
|
|
50
|
+
additionalProperties: false,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
required: ["title", "defaultPrefix", "summary", "areas"],
|
|
55
|
+
additionalProperties: false,
|
|
56
|
+
};
|
|
57
|
+
// ---------- Outline review verdict ----------
|
|
58
|
+
export const VerdictValues = [
|
|
59
|
+
"approved",
|
|
60
|
+
"approved-with-revisions",
|
|
61
|
+
"requires-another-review",
|
|
62
|
+
];
|
|
63
|
+
export const OutlineReviewSchema = z.object({
|
|
64
|
+
coverage_gaps: z.array(z.string()).default([]),
|
|
65
|
+
framing_errors: z.array(z.string()).default([]),
|
|
66
|
+
granularity_issues: z.array(z.string()).default([]),
|
|
67
|
+
file_assignment_issues: z.array(z.string()).default([]),
|
|
68
|
+
revisions: z.array(z.string()).default([]),
|
|
69
|
+
verdict: z.enum(VerdictValues),
|
|
70
|
+
});
|
|
71
|
+
export const OUTLINE_REVIEW_JSON_SCHEMA = {
|
|
72
|
+
type: "object",
|
|
73
|
+
properties: {
|
|
74
|
+
coverage_gaps: { type: "array", items: { type: "string" } },
|
|
75
|
+
framing_errors: { type: "array", items: { type: "string" } },
|
|
76
|
+
granularity_issues: { type: "array", items: { type: "string" } },
|
|
77
|
+
file_assignment_issues: { type: "array", items: { type: "string" } },
|
|
78
|
+
revisions: { type: "array", items: { type: "string" } },
|
|
79
|
+
verdict: {
|
|
80
|
+
type: "string",
|
|
81
|
+
enum: VerdictValues,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
required: [
|
|
85
|
+
"coverage_gaps",
|
|
86
|
+
"framing_errors",
|
|
87
|
+
"granularity_issues",
|
|
88
|
+
"file_assignment_issues",
|
|
89
|
+
"revisions",
|
|
90
|
+
"verdict",
|
|
91
|
+
],
|
|
92
|
+
additionalProperties: false,
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Try to parse a string as JSON and validate against the outline schema.
|
|
96
|
+
* Throws with a descriptive message on failure (caller catches and either
|
|
97
|
+
* retries or fails the loop).
|
|
98
|
+
*/
|
|
99
|
+
export function parseOutline(text) {
|
|
100
|
+
const trimmed = text.trim();
|
|
101
|
+
// Try direct parse first; fall back to extracting first {...} block.
|
|
102
|
+
let raw;
|
|
103
|
+
try {
|
|
104
|
+
raw = JSON.parse(trimmed);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
const match = trimmed.match(/(\{[\s\S]*\})/);
|
|
108
|
+
if (!match) {
|
|
109
|
+
throw new Error("Outline output is not valid JSON and contains no JSON object");
|
|
110
|
+
}
|
|
111
|
+
raw = JSON.parse(match[1]);
|
|
112
|
+
}
|
|
113
|
+
return OutlineSchema.parse(raw);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Parse a reviewer's JSON output and validate against the outline-review schema.
|
|
117
|
+
*/
|
|
118
|
+
export function parseOutlineReview(text) {
|
|
119
|
+
const trimmed = text.trim();
|
|
120
|
+
let raw;
|
|
121
|
+
try {
|
|
122
|
+
raw = JSON.parse(trimmed);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
const match = trimmed.match(/(\{[\s\S]*\})/);
|
|
126
|
+
if (!match) {
|
|
127
|
+
throw new Error("Reviewer output is not valid JSON and contains no JSON object");
|
|
128
|
+
}
|
|
129
|
+
raw = JSON.parse(match[1]);
|
|
130
|
+
}
|
|
131
|
+
return OutlineReviewSchema.parse(raw);
|
|
132
|
+
}
|
|
133
|
+
// ---------- Spec review verdict ----------
|
|
134
|
+
//
|
|
135
|
+
// Same three-verdict structure as the outline reviewer, with categories
|
|
136
|
+
// tailored to document-level cohesion concerns.
|
|
137
|
+
export const SpecReviewSchema = z.object({
|
|
138
|
+
coverage_gaps: z.array(z.string()).default([]),
|
|
139
|
+
framing_errors: z.array(z.string()).default([]),
|
|
140
|
+
cross_area_issues: z.array(z.string()).default([]),
|
|
141
|
+
internal_mechanics_drift: z.array(z.string()).default([]),
|
|
142
|
+
revisions: z.array(z.string()).default([]),
|
|
143
|
+
verdict: z.enum(VerdictValues),
|
|
144
|
+
});
|
|
145
|
+
export const SPEC_REVIEW_JSON_SCHEMA = {
|
|
146
|
+
type: "object",
|
|
147
|
+
properties: {
|
|
148
|
+
coverage_gaps: { type: "array", items: { type: "string" } },
|
|
149
|
+
framing_errors: { type: "array", items: { type: "string" } },
|
|
150
|
+
cross_area_issues: { type: "array", items: { type: "string" } },
|
|
151
|
+
internal_mechanics_drift: { type: "array", items: { type: "string" } },
|
|
152
|
+
revisions: { type: "array", items: { type: "string" } },
|
|
153
|
+
verdict: {
|
|
154
|
+
type: "string",
|
|
155
|
+
enum: VerdictValues,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
required: [
|
|
159
|
+
"coverage_gaps",
|
|
160
|
+
"framing_errors",
|
|
161
|
+
"cross_area_issues",
|
|
162
|
+
"internal_mechanics_drift",
|
|
163
|
+
"revisions",
|
|
164
|
+
"verdict",
|
|
165
|
+
],
|
|
166
|
+
additionalProperties: false,
|
|
167
|
+
};
|
|
168
|
+
export function parseSpecReview(text) {
|
|
169
|
+
const trimmed = text.trim();
|
|
170
|
+
let raw;
|
|
171
|
+
try {
|
|
172
|
+
raw = JSON.parse(trimmed);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
const match = trimmed.match(/(\{[\s\S]*\})/);
|
|
176
|
+
if (!match) {
|
|
177
|
+
throw new Error("Spec reviewer output is not valid JSON and contains no JSON object");
|
|
178
|
+
}
|
|
179
|
+
raw = JSON.parse(match[1]);
|
|
180
|
+
}
|
|
181
|
+
return SpecReviewSchema.parse(raw);
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill installation logic for the codebase-to-spec skill.
|
|
3
|
+
*
|
|
4
|
+
* The skill is a thin conversational wrapper around `dotrequirements cts run`.
|
|
5
|
+
* It ships as a SKILL.md template bundled in the CLI package, and this module
|
|
6
|
+
* copies it into the host's skill directory (default: `.claude/skills/` for
|
|
7
|
+
* Claude Code).
|
|
8
|
+
*
|
|
9
|
+
* Host portability (CTS-SKILL-5): the install logic supports any host that
|
|
10
|
+
* follows the Agent Skills format. The default target is Claude Code's
|
|
11
|
+
* convention; `--target-dir` lets users place the skill anywhere.
|
|
12
|
+
*
|
|
13
|
+
* Requirements covered:
|
|
14
|
+
* - CTS-SKILL-1: skill artifact exists and points users at `dotrequirements cts run`
|
|
15
|
+
* - CTS-SKILL-5: install logic is host-agnostic and works on any host with
|
|
16
|
+
* Agent Skills format support
|
|
17
|
+
*/
|
|
18
|
+
export type SkillInstallScope = "project" | "global" | "custom";
|
|
19
|
+
export interface SkillInstallOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Where to install:
|
|
22
|
+
* - `project` (default): `<projectRoot>/.claude/skills/codebase-to-spec/`
|
|
23
|
+
* - `global`: `~/.claude/skills/codebase-to-spec/`
|
|
24
|
+
* - `custom`: requires `targetDir`
|
|
25
|
+
*/
|
|
26
|
+
scope?: SkillInstallScope;
|
|
27
|
+
/** Required when `scope === 'custom'`. The skill directory will be created here. */
|
|
28
|
+
targetDir?: string;
|
|
29
|
+
/** Project root (used when scope === 'project'). Defaults to cwd. */
|
|
30
|
+
projectRoot?: string;
|
|
31
|
+
/** Overwrite existing SKILL.md if present. Default false. */
|
|
32
|
+
overwrite?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface SkillInstallResult {
|
|
35
|
+
/** Final on-disk path to SKILL.md. */
|
|
36
|
+
installedPath: string;
|
|
37
|
+
/** True if a new file was written; false if it was already in place (no overwrite). */
|
|
38
|
+
installed: boolean;
|
|
39
|
+
/** True if an existing file was replaced. */
|
|
40
|
+
overwrote: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the directory in which the skill should live, given the user's
|
|
44
|
+
* scope choice. The directory itself is the `codebase-to-spec/` skill dir;
|
|
45
|
+
* `SKILL.md` is written inside it.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveSkillDir(options: SkillInstallOptions): string;
|
|
48
|
+
/**
|
|
49
|
+
* Load the bundled SKILL.md template from the package.
|
|
50
|
+
*/
|
|
51
|
+
export declare function loadSkillTemplate(): string;
|
|
52
|
+
/**
|
|
53
|
+
* Install (or refuse to overwrite) the codebase-to-spec SKILL.md at the
|
|
54
|
+
* resolved location.
|
|
55
|
+
*/
|
|
56
|
+
export declare function installSkill(options?: SkillInstallOptions): SkillInstallResult;
|
|
57
|
+
//# sourceMappingURL=skill-install.d.ts.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill installation logic for the codebase-to-spec skill.
|
|
3
|
+
*
|
|
4
|
+
* The skill is a thin conversational wrapper around `dotrequirements cts run`.
|
|
5
|
+
* It ships as a SKILL.md template bundled in the CLI package, and this module
|
|
6
|
+
* copies it into the host's skill directory (default: `.claude/skills/` for
|
|
7
|
+
* Claude Code).
|
|
8
|
+
*
|
|
9
|
+
* Host portability (CTS-SKILL-5): the install logic supports any host that
|
|
10
|
+
* follows the Agent Skills format. The default target is Claude Code's
|
|
11
|
+
* convention; `--target-dir` lets users place the skill anywhere.
|
|
12
|
+
*
|
|
13
|
+
* Requirements covered:
|
|
14
|
+
* - CTS-SKILL-1: skill artifact exists and points users at `dotrequirements cts run`
|
|
15
|
+
* - CTS-SKILL-5: install logic is host-agnostic and works on any host with
|
|
16
|
+
* Agent Skills format support
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
19
|
+
import { homedir } from "node:os";
|
|
20
|
+
import { dirname, join, resolve } from "node:path";
|
|
21
|
+
import { loadTemplate } from "../utils/templates.js";
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the directory in which the skill should live, given the user's
|
|
24
|
+
* scope choice. The directory itself is the `codebase-to-spec/` skill dir;
|
|
25
|
+
* `SKILL.md` is written inside it.
|
|
26
|
+
*/
|
|
27
|
+
export function resolveSkillDir(options) {
|
|
28
|
+
const scope = options.scope ?? "project";
|
|
29
|
+
switch (scope) {
|
|
30
|
+
case "project": {
|
|
31
|
+
const root = options.projectRoot ?? process.cwd();
|
|
32
|
+
return join(root, ".claude", "skills", "codebase-to-spec");
|
|
33
|
+
}
|
|
34
|
+
case "global":
|
|
35
|
+
return join(homedir(), ".claude", "skills", "codebase-to-spec");
|
|
36
|
+
case "custom":
|
|
37
|
+
if (!options.targetDir) {
|
|
38
|
+
throw new Error('targetDir is required when scope === "custom"');
|
|
39
|
+
}
|
|
40
|
+
// Treat targetDir as the parent skills/ directory; create the
|
|
41
|
+
// skill subdir under it.
|
|
42
|
+
return join(resolve(options.targetDir), "codebase-to-spec");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Load the bundled SKILL.md template from the package.
|
|
47
|
+
*/
|
|
48
|
+
export function loadSkillTemplate() {
|
|
49
|
+
return loadTemplate("skills/codebase-to-spec/SKILL.md");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Install (or refuse to overwrite) the codebase-to-spec SKILL.md at the
|
|
53
|
+
* resolved location.
|
|
54
|
+
*/
|
|
55
|
+
export function installSkill(options = {}) {
|
|
56
|
+
const skillDir = resolveSkillDir(options);
|
|
57
|
+
const skillPath = join(skillDir, "SKILL.md");
|
|
58
|
+
const template = loadSkillTemplate();
|
|
59
|
+
const exists = existsSync(skillPath);
|
|
60
|
+
if (exists && !options.overwrite) {
|
|
61
|
+
// Idempotent no-op: if the on-disk content already matches the template,
|
|
62
|
+
// there's nothing to do and we shouldn't surface that as a conflict.
|
|
63
|
+
const onDisk = readFileSync(skillPath, "utf-8");
|
|
64
|
+
if (onDisk === template) {
|
|
65
|
+
return { installedPath: skillPath, installed: false, overwrote: false };
|
|
66
|
+
}
|
|
67
|
+
// Stale or hand-edited copy: refuse without --overwrite so we don't
|
|
68
|
+
// silently clobber user changes.
|
|
69
|
+
throw new Error(`SKILL.md already exists at ${skillPath} and differs from the bundled template. Pass --overwrite to replace it, or delete the file first.`);
|
|
70
|
+
}
|
|
71
|
+
mkdirSync(dirname(skillPath), { recursive: true });
|
|
72
|
+
writeFileSync(skillPath, template, "utf-8");
|
|
73
|
+
return {
|
|
74
|
+
installedPath: skillPath,
|
|
75
|
+
installed: true,
|
|
76
|
+
overwrote: exists,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=skill-install.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice extraction: given a Repomix pack and a list of file paths (or
|
|
3
|
+
* directory-prefix paths), produce a smaller pack containing only the matching
|
|
4
|
+
* files.
|
|
5
|
+
*
|
|
6
|
+
* Pack format (from Repomix --style plain):
|
|
7
|
+
*
|
|
8
|
+
* ================
|
|
9
|
+
* File: path/to/file
|
|
10
|
+
* ================
|
|
11
|
+
* <file contents>
|
|
12
|
+
*
|
|
13
|
+
* ================
|
|
14
|
+
* File: next/file
|
|
15
|
+
* ================
|
|
16
|
+
* ...
|
|
17
|
+
*
|
|
18
|
+
* We preserve the pack header (everything before the first File: section) and
|
|
19
|
+
* the matching sections.
|
|
20
|
+
*
|
|
21
|
+
* Requirements covered:
|
|
22
|
+
* - CTS-SPEC-1: CLI fans out one specifier worker per area; each worker
|
|
23
|
+
* receives a slice extracted from the uncompressed pack
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Return true when `path` matches one of the entries in `wanted`.
|
|
27
|
+
*
|
|
28
|
+
* Each entry can be:
|
|
29
|
+
* - An exact file path (e.g., `src/foo.ts`) — matches that exact path.
|
|
30
|
+
* - A directory prefix ending in `/` (e.g., `src/services/browser/`) — matches
|
|
31
|
+
* any file under that directory tree.
|
|
32
|
+
*/
|
|
33
|
+
export declare function pathMatchesWanted(path: string, wanted: Iterable<string>): boolean;
|
|
34
|
+
export interface SliceExtractionResult {
|
|
35
|
+
/** Number of file sections matched (and written to the output). */
|
|
36
|
+
matched: number;
|
|
37
|
+
/** Total number of file sections in the input pack. */
|
|
38
|
+
total: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Extract sections matching `wanted` from the pack at `inputPath` and write
|
|
42
|
+
* them to `outputPath`. Preserves the pack header (Repomix metadata).
|
|
43
|
+
*/
|
|
44
|
+
export declare function extractSlice(inputPath: string, outputPath: string, wanted: Iterable<string>): SliceExtractionResult;
|
|
45
|
+
/**
|
|
46
|
+
* Pure variant operating on already-loaded text. Useful for tests.
|
|
47
|
+
*/
|
|
48
|
+
export declare function extractSliceFromText(text: string, outputPath: string, wanted: Iterable<string>): SliceExtractionResult;
|
|
49
|
+
//# sourceMappingURL=slice.d.ts.map
|