great-cto 2.8.4 → 2.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapt.js +17 -186
- package/dist/ci.js +1 -1
- package/dist/main.js +26 -18
- package/package.json +1 -1
package/dist/adapt.js
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
|
-
// great-cto adapt —
|
|
1
|
+
// great-cto adapt — Claude Code config generator.
|
|
2
2
|
//
|
|
3
|
-
// Writes
|
|
4
|
-
// single great_cto installation work transparently with Claude Code, OpenAI
|
|
5
|
-
// Codex CLI, Cursor, Aider, and Continue. AGENTS.md is the de-facto cross-
|
|
6
|
-
// platform standard (used verbatim by Codex; consumed as fallback by most
|
|
7
|
-
// others) so it forms the shared core.
|
|
3
|
+
// Writes CLAUDE.md + AGENTS.md from .great_cto/PROJECT.md context.
|
|
8
4
|
//
|
|
9
5
|
// Usage:
|
|
10
|
-
// great-cto adapt
|
|
11
|
-
// great-cto adapt --
|
|
12
|
-
// great-cto adapt --platform cursor .cursorrules + .cursor/rules/*.mdc
|
|
13
|
-
// great-cto adapt --platform aider .aider.conf.yml + CONVENTIONS.md
|
|
14
|
-
// great-cto adapt --platform continue .continue/rules.md
|
|
15
|
-
// great-cto adapt --platform all all of the above
|
|
16
|
-
// great-cto adapt --dry-run show what would be written
|
|
17
|
-
//
|
|
18
|
-
// Each adapter writes ONLY platform-native files. All share the AGENTS.md
|
|
19
|
-
// core text via getAgentsCore(). To customize per-project, edit
|
|
20
|
-
// .great_cto/PROJECT.md (archetype, owners, compliance) — adapt re-derives.
|
|
6
|
+
// great-cto adapt Generate CLAUDE.md + AGENTS.md
|
|
7
|
+
// great-cto adapt --dry-run Show what would be written
|
|
21
8
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
22
9
|
import { dirname, join } from "node:path";
|
|
23
10
|
function readProjectMeta(cwd) {
|
|
@@ -36,8 +23,7 @@ function readProjectMeta(cwd) {
|
|
|
36
23
|
return { archetype, compliance, owners, hasGreatCto: true };
|
|
37
24
|
}
|
|
38
25
|
/**
|
|
39
|
-
*
|
|
40
|
-
* Codex CLI reads this verbatim. Cursor / Aider / Claude Code embed it.
|
|
26
|
+
* AGENTS.md — Claude Code reads this as the cross-tool agent contract.
|
|
41
27
|
*/
|
|
42
28
|
function getAgentsCore(meta) {
|
|
43
29
|
const compliance = meta.compliance.length > 0
|
|
@@ -45,10 +31,8 @@ function getAgentsCore(meta) {
|
|
|
45
31
|
: "_(none auto-detected — set in .great_cto/PROJECT.md)_";
|
|
46
32
|
return `# AGENTS.md
|
|
47
33
|
|
|
48
|
-
>
|
|
49
|
-
>
|
|
50
|
-
> tooling. Generated by \`great-cto adapt\` — re-run after editing
|
|
51
|
-
> \`.great_cto/PROJECT.md\`.
|
|
34
|
+
> Project agent contract for Claude Code. Generated by \`great-cto adapt\` —
|
|
35
|
+
> re-run after editing \`.great_cto/PROJECT.md\`.
|
|
52
36
|
|
|
53
37
|
## Project context
|
|
54
38
|
|
|
@@ -80,7 +64,7 @@ Override with \`/waiver\` and a written reason. Auto-expires in 14 days.
|
|
|
80
64
|
|
|
81
65
|
## Available tools (via MCP)
|
|
82
66
|
|
|
83
|
-
When this repo is opened in
|
|
67
|
+
When this repo is opened in Claude Code, \`great-cto mcp\` exposes:
|
|
84
68
|
|
|
85
69
|
- \`scan\` — OWASP LLM Top 10 + 24 rules · returns findings
|
|
86
70
|
- \`list_rules\` — full rule catalogue
|
|
@@ -88,7 +72,7 @@ When this repo is opened in any MCP-capable tool, \`great-cto mcp\` exposes:
|
|
|
88
72
|
- \`estimate_cost\` — LLM vs human time estimate for a task
|
|
89
73
|
- \`query_decisions\` — search ADR log
|
|
90
74
|
|
|
91
|
-
Configure
|
|
75
|
+
Configure Claude Code to launch:
|
|
92
76
|
\`\`\`bash
|
|
93
77
|
npx great-cto mcp
|
|
94
78
|
\`\`\`
|
|
@@ -131,17 +115,14 @@ function writeFile(path, content, dryRun) {
|
|
|
131
115
|
console.log(` ${existed ? "✎ updated" : "✓ wrote"} ${path}`);
|
|
132
116
|
return true;
|
|
133
117
|
}
|
|
134
|
-
// ──
|
|
118
|
+
// ── Claude Code adapter ────────────────────────────────────────────────────
|
|
135
119
|
function adaptClaude(cwd, meta, dryRun) {
|
|
136
|
-
// Claude Code reads CLAUDE.md (or AGENTS.md as fallback). We write both
|
|
137
|
-
// for maximum compat — projects with CLAUDE.md already get a top-level
|
|
138
|
-
// reference, and AGENTS.md unlocks any AGENTS.md-aware tool simultaneously.
|
|
139
120
|
const out = [];
|
|
140
121
|
const agentsBody = getAgentsCore(meta);
|
|
141
122
|
const claudeBody = `# CLAUDE.md
|
|
142
123
|
|
|
143
124
|
> Project guidance for Claude Code. The full agent contract lives in
|
|
144
|
-
> \`AGENTS.md\` — please read that first. This file adds Claude
|
|
125
|
+
> \`AGENTS.md\` — please read that first. This file adds Claude Code-specific
|
|
145
126
|
> overrides only.
|
|
146
127
|
|
|
147
128
|
## Cross-tool contract
|
|
@@ -160,9 +141,9 @@ conventions. Generated by \`great-cto adapt\`.
|
|
|
160
141
|
|
|
161
142
|
## Quick links
|
|
162
143
|
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
144
|
+
- \`/start "..."\` — kick off a feature pipeline
|
|
145
|
+
- \`/inbox\` — see what needs your decision
|
|
146
|
+
- \`/agent-review\` — performance scorecard for agents
|
|
166
147
|
|
|
167
148
|
`;
|
|
168
149
|
if (writeFile(join(cwd, "AGENTS.md"), agentsBody, dryRun))
|
|
@@ -171,141 +152,6 @@ conventions. Generated by \`great-cto adapt\`.
|
|
|
171
152
|
out.push("CLAUDE.md");
|
|
172
153
|
return out;
|
|
173
154
|
}
|
|
174
|
-
function adaptCodex(cwd, meta, dryRun) {
|
|
175
|
-
// OpenAI Codex CLI reads AGENTS.md. We write only that — Codex doesn't
|
|
176
|
-
// currently consume CLAUDE.md / .cursorrules.
|
|
177
|
-
const out = [];
|
|
178
|
-
if (writeFile(join(cwd, "AGENTS.md"), getAgentsCore(meta), dryRun))
|
|
179
|
-
out.push("AGENTS.md");
|
|
180
|
-
return out;
|
|
181
|
-
}
|
|
182
|
-
function adaptCursor(cwd, meta, dryRun) {
|
|
183
|
-
// Cursor reads .cursorrules (legacy single file) and .cursor/rules/*.mdc
|
|
184
|
-
// (modern modular). Write both for compat.
|
|
185
|
-
const out = [];
|
|
186
|
-
const rulesContent = `# Cursor rules — auto-generated by great-cto adapt
|
|
187
|
-
# See AGENTS.md for the full agent contract; this file is the Cursor-native
|
|
188
|
-
# subset focusing on inline-completion and chat behaviour.
|
|
189
|
-
|
|
190
|
-
archetype: ${meta.archetype}
|
|
191
|
-
compliance:
|
|
192
|
-
${meta.compliance.map(c => ` - ${c}`).join("\n") || " - none"}
|
|
193
|
-
|
|
194
|
-
## Behaviour
|
|
195
|
-
|
|
196
|
-
Before suggesting code changes:
|
|
197
|
-
- Read \`AGENTS.md\` for repo-wide conventions
|
|
198
|
-
- Read \`.great_cto/PROJECT.md\` for archetype constraints
|
|
199
|
-
- Check \`~/.great_cto/decisions.md\` for prior ADRs on the topic
|
|
200
|
-
|
|
201
|
-
## Gates that block merges (do not bypass)
|
|
202
|
-
|
|
203
|
-
- security-officer: auth/payments/PII changes
|
|
204
|
-
- qa-engineer: feature merges
|
|
205
|
-
- db-migration-reviewer: any migrations/ change
|
|
206
|
-
|
|
207
|
-
## Style
|
|
208
|
-
|
|
209
|
-
- TDD: tests RED → implementation GREEN → refactor
|
|
210
|
-
- Conventional commits
|
|
211
|
-
- One concern per PR
|
|
212
|
-
`;
|
|
213
|
-
const mdcContent = `---
|
|
214
|
-
description: great_cto archetype + compliance contract
|
|
215
|
-
globs: ["**/*"]
|
|
216
|
-
alwaysApply: true
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
This repo is a **${meta.archetype}** project. Compliance gates:
|
|
220
|
-
${meta.compliance.map(c => `- ${c}`).join("\n") || "- none"}
|
|
221
|
-
|
|
222
|
-
Read \`AGENTS.md\` and \`.great_cto/PROJECT.md\` before proposing changes.
|
|
223
|
-
Run \`npx great-cto ci\` before pushing.
|
|
224
|
-
`;
|
|
225
|
-
if (writeFile(join(cwd, ".cursorrules"), rulesContent, dryRun))
|
|
226
|
-
out.push(".cursorrules");
|
|
227
|
-
if (writeFile(join(cwd, ".cursor", "rules", "great-cto.mdc"), mdcContent, dryRun))
|
|
228
|
-
out.push(".cursor/rules/great-cto.mdc");
|
|
229
|
-
if (writeFile(join(cwd, "AGENTS.md"), getAgentsCore(meta), dryRun))
|
|
230
|
-
out.push("AGENTS.md");
|
|
231
|
-
return out;
|
|
232
|
-
}
|
|
233
|
-
function adaptAider(cwd, meta, dryRun) {
|
|
234
|
-
// Aider reads .aider.conf.yml for settings and CONVENTIONS.md (or files
|
|
235
|
-
// listed in read: arrays) for context.
|
|
236
|
-
const out = [];
|
|
237
|
-
const conf = `# .aider.conf.yml — auto-generated by great-cto adapt
|
|
238
|
-
# Aider config. Run aider in this dir and these settings apply.
|
|
239
|
-
|
|
240
|
-
# Always include AGENTS.md and PROJECT.md as context
|
|
241
|
-
read:
|
|
242
|
-
- AGENTS.md
|
|
243
|
-
- .great_cto/PROJECT.md
|
|
244
|
-
|
|
245
|
-
# Auto-test after edits
|
|
246
|
-
auto-test: true
|
|
247
|
-
test-cmd: "npx great-cto ci --severity high"
|
|
248
|
-
|
|
249
|
-
# Pretty output
|
|
250
|
-
pretty: true
|
|
251
|
-
|
|
252
|
-
# Conventional commits
|
|
253
|
-
commit-prompt: "Use conventional commit format: feat/fix/docs/refactor/test/chore"
|
|
254
|
-
|
|
255
|
-
# Archetype: ${meta.archetype}
|
|
256
|
-
# Compliance: ${meta.compliance.join(", ") || "none"}
|
|
257
|
-
`;
|
|
258
|
-
const conventions = `# CONVENTIONS.md
|
|
259
|
-
|
|
260
|
-
> This is the Aider-native conventions file. The cross-tool agent contract
|
|
261
|
-
> lives in \`AGENTS.md\` — please read that for full context.
|
|
262
|
-
|
|
263
|
-
## Quick rules
|
|
264
|
-
|
|
265
|
-
- **Archetype:** ${meta.archetype}
|
|
266
|
-
- **Compliance gates:** ${meta.compliance.join(", ") || "_(none)_"}
|
|
267
|
-
|
|
268
|
-
### Process
|
|
269
|
-
1. Tests first (TDD)
|
|
270
|
-
2. One concern per PR
|
|
271
|
-
3. Conventional commits
|
|
272
|
-
4. Run \`npx great-cto ci\` before push
|
|
273
|
-
|
|
274
|
-
### Style
|
|
275
|
-
- No secrets in code (\`great-cto scan\` enforces this)
|
|
276
|
-
- Read \`.great_cto/PROJECT.md\` before suggesting architectural changes
|
|
277
|
-
- Read \`~/.great_cto/decisions.md\` for prior ADRs
|
|
278
|
-
`;
|
|
279
|
-
if (writeFile(join(cwd, ".aider.conf.yml"), conf, dryRun))
|
|
280
|
-
out.push(".aider.conf.yml");
|
|
281
|
-
if (writeFile(join(cwd, "CONVENTIONS.md"), conventions, dryRun))
|
|
282
|
-
out.push("CONVENTIONS.md");
|
|
283
|
-
if (writeFile(join(cwd, "AGENTS.md"), getAgentsCore(meta), dryRun))
|
|
284
|
-
out.push("AGENTS.md");
|
|
285
|
-
return out;
|
|
286
|
-
}
|
|
287
|
-
function adaptContinue(cwd, meta, dryRun) {
|
|
288
|
-
const out = [];
|
|
289
|
-
const rulesContent = `# Continue rules — generated by great-cto adapt
|
|
290
|
-
|
|
291
|
-
## Project context
|
|
292
|
-
|
|
293
|
-
Archetype: **${meta.archetype}**.
|
|
294
|
-
Compliance: ${meta.compliance.join(", ") || "none"}.
|
|
295
|
-
Read \`AGENTS.md\` for the full contract.
|
|
296
|
-
|
|
297
|
-
## Behaviour
|
|
298
|
-
|
|
299
|
-
- Run \`npx great-cto ci\` before pushing
|
|
300
|
-
- Don't bypass gates (security / qa / db-migration)
|
|
301
|
-
- Append lessons to \`.great_cto/lessons.md\` after incidents
|
|
302
|
-
`;
|
|
303
|
-
if (writeFile(join(cwd, ".continue", "rules.md"), rulesContent, dryRun))
|
|
304
|
-
out.push(".continue/rules.md");
|
|
305
|
-
if (writeFile(join(cwd, "AGENTS.md"), getAgentsCore(meta), dryRun))
|
|
306
|
-
out.push("AGENTS.md");
|
|
307
|
-
return out;
|
|
308
|
-
}
|
|
309
155
|
// ── Main entry ─────────────────────────────────────────────────────────────
|
|
310
156
|
export async function runAdapt(args) {
|
|
311
157
|
const meta = readProjectMeta(args.cwd);
|
|
@@ -314,28 +160,13 @@ export async function runAdapt(args) {
|
|
|
314
160
|
console.error("Run `npx great-cto init` first to bootstrap the project.");
|
|
315
161
|
return 1;
|
|
316
162
|
}
|
|
317
|
-
|
|
318
|
-
? ["claude", "codex", "cursor", "aider", "continue"]
|
|
319
|
-
: [args.platform];
|
|
320
|
-
console.log(`great-cto adapt → ${platforms.join(", ")}${args.dryRun ? " (dry-run)" : ""}`);
|
|
163
|
+
console.log(`great-cto adapt → claude${args.dryRun ? " (dry-run)" : ""}`);
|
|
321
164
|
console.log(` archetype: ${meta.archetype} compliance: ${meta.compliance.join(", ") || "none"}`);
|
|
322
165
|
console.log("");
|
|
323
|
-
const written =
|
|
324
|
-
for (const p of platforms) {
|
|
325
|
-
console.log(`▸ ${p}`);
|
|
326
|
-
const adapter = {
|
|
327
|
-
claude: adaptClaude,
|
|
328
|
-
codex: adaptCodex,
|
|
329
|
-
cursor: adaptCursor,
|
|
330
|
-
aider: adaptAider,
|
|
331
|
-
continue: adaptContinue,
|
|
332
|
-
}[p];
|
|
333
|
-
const out = adapter(args.cwd, meta, args.dryRun);
|
|
334
|
-
written.push(...out);
|
|
335
|
-
}
|
|
166
|
+
const written = adaptClaude(args.cwd, meta, args.dryRun);
|
|
336
167
|
if (!args.dryRun) {
|
|
337
168
|
console.log("");
|
|
338
|
-
console.log(`✓ generated ${written.length} file(s)
|
|
169
|
+
console.log(`✓ generated ${written.length} file(s).`);
|
|
339
170
|
console.log(` Re-run after editing .great_cto/PROJECT.md to refresh.`);
|
|
340
171
|
}
|
|
341
172
|
return 0;
|
package/dist/ci.js
CHANGED
|
@@ -116,7 +116,7 @@ async function archetypeCheck(cwd, quiet) {
|
|
|
116
116
|
ok: false,
|
|
117
117
|
msg: `archetype drift: declared=${declared}, detected=${result.primary} (${result.confidence}). ` +
|
|
118
118
|
`Either:\n` +
|
|
119
|
-
` • run 'npx great-cto adapt
|
|
119
|
+
` • run 'npx great-cto adapt' to refresh CLAUDE.md + AGENTS.md after intentional change, or\n` +
|
|
120
120
|
` • run 'npx great-cto init --force --archetype ${result.primary}' to align PROJECT.md with the codebase, or\n` +
|
|
121
121
|
` • pass '--no-archetype' to ci to skip this check (e.g. during transitional refactors)`,
|
|
122
122
|
};
|
package/dist/main.js
CHANGED
|
@@ -66,6 +66,8 @@ function parseArgs(argv) {
|
|
|
66
66
|
args.version = argv[++i] ?? null;
|
|
67
67
|
else if (a === "--port")
|
|
68
68
|
args.boardPort = parseInt(argv[++i] ?? "3141", 10);
|
|
69
|
+
else if (a.startsWith("--port="))
|
|
70
|
+
args.boardPort = parseInt(a.slice("--port=".length), 10);
|
|
69
71
|
else if (a === "--no-open")
|
|
70
72
|
args.boardNoOpen = true;
|
|
71
73
|
else if (a === "--use-llm")
|
|
@@ -111,6 +113,16 @@ function parseArgs(argv) {
|
|
|
111
113
|
else if (a === "init" || a === "help" || a === "version") {
|
|
112
114
|
args.command = a;
|
|
113
115
|
}
|
|
116
|
+
else if (!a.startsWith("-") && args.command === "init" && i === 0) {
|
|
117
|
+
// First positional that isn't a recognised subcommand → unknown
|
|
118
|
+
args.command = "unknown";
|
|
119
|
+
args.unknownToken = a;
|
|
120
|
+
}
|
|
121
|
+
else if (a.startsWith("--") && args.command === "init") {
|
|
122
|
+
// Unknown long flag in init position → unknown
|
|
123
|
+
args.command = "unknown";
|
|
124
|
+
args.unknownToken = a;
|
|
125
|
+
}
|
|
114
126
|
else
|
|
115
127
|
rest.push(a);
|
|
116
128
|
}
|
|
@@ -340,7 +352,7 @@ ${bold("Usage:")}
|
|
|
340
352
|
npx great-cto list-rules
|
|
341
353
|
npx great-cto ci [path] [--fail-on LVL] [--sarif F] [--junit F]
|
|
342
354
|
npx great-cto mcp [--sse --port N]
|
|
343
|
-
npx great-cto adapt --
|
|
355
|
+
npx great-cto adapt [--dry-run]
|
|
344
356
|
npx great-cto serve [--port 3142]
|
|
345
357
|
npx great-cto help
|
|
346
358
|
npx great-cto version
|
|
@@ -372,18 +384,14 @@ ${bold("CI gate:")}
|
|
|
372
384
|
${dim("(auto-detects \$GITHUB_ACTIONS → emits ::error:: annotations)")}
|
|
373
385
|
|
|
374
386
|
${bold("MCP server (cross-platform):")}
|
|
375
|
-
great-cto mcp Stdio MCP server — works in Claude
|
|
376
|
-
|
|
387
|
+
great-cto mcp Stdio MCP server — works in Claude Code /
|
|
388
|
+
Claude Desktop / any MCP host
|
|
377
389
|
great-cto mcp --sse --port 8765 SSE mode for remote / multi-client (TODO v2.5)
|
|
378
390
|
${dim("Tools exposed: scan, list_rules, detect_archetype, estimate_cost, query_decisions")}
|
|
379
391
|
|
|
380
|
-
${bold("
|
|
381
|
-
great-cto adapt
|
|
382
|
-
great-cto adapt --
|
|
383
|
-
great-cto adapt --platform cursor Generate .cursorrules + .cursor/rules/*.mdc
|
|
384
|
-
great-cto adapt --platform aider Generate .aider.conf.yml + CONVENTIONS.md
|
|
385
|
-
great-cto adapt --platform continue Generate .continue/rules.md
|
|
386
|
-
great-cto adapt --platform all All of the above
|
|
392
|
+
${bold("Claude Code adapter:")}
|
|
393
|
+
great-cto adapt Generate AGENTS.md + CLAUDE.md
|
|
394
|
+
great-cto adapt --dry-run Preview what would be written
|
|
387
395
|
${dim("Idempotent — re-run after editing .great_cto/PROJECT.md")}
|
|
388
396
|
|
|
389
397
|
${bold("Webhook server (preview):")}
|
|
@@ -760,6 +768,13 @@ async function main() {
|
|
|
760
768
|
printHelp();
|
|
761
769
|
process.exit(0);
|
|
762
770
|
}
|
|
771
|
+
if (args.command === "unknown") {
|
|
772
|
+
const tok = args.unknownToken ?? "<arg>";
|
|
773
|
+
error(`great-cto: unknown command or flag '${tok}'`);
|
|
774
|
+
log("");
|
|
775
|
+
log(`Run ${cyan("great-cto --help")} for usage.`);
|
|
776
|
+
process.exit(2);
|
|
777
|
+
}
|
|
763
778
|
if (args.command === "scan") {
|
|
764
779
|
try {
|
|
765
780
|
const code = await runScan(args, rawArgv);
|
|
@@ -828,15 +843,8 @@ async function main() {
|
|
|
828
843
|
if (args.command === "adapt") {
|
|
829
844
|
try {
|
|
830
845
|
const { runAdapt } = await import("./adapt.js");
|
|
831
|
-
const platArg = rawArgv.indexOf("--platform");
|
|
832
|
-
const platform = (platArg >= 0 ? rawArgv[platArg + 1] : "all");
|
|
833
|
-
const valid = ["claude", "codex", "cursor", "aider", "continue", "all"];
|
|
834
|
-
if (!valid.includes(platform)) {
|
|
835
|
-
error(`adapt: --platform must be one of ${valid.join(", ")} (got: ${platform})`);
|
|
836
|
-
process.exit(2);
|
|
837
|
-
}
|
|
838
846
|
const code = await runAdapt({
|
|
839
|
-
platform,
|
|
847
|
+
platform: "claude",
|
|
840
848
|
dryRun: rawArgv.includes("--dry-run"),
|
|
841
849
|
cwd: args.dir,
|
|
842
850
|
});
|
package/package.json
CHANGED