great-cto 3.24.0 → 3.25.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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "great-cto",
|
|
3
3
|
"description": "You already have the agent. This is everything around it. great_cto runs Claude Code as a pipeline of 70 specialist agents \u2014 an independent model checks each stage before the next builds on it, spending caps refuse rather than warn, and three decisions stay yours: what gets built, how, and whether it ships.",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.25.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Alexander Velikiy",
|
|
7
7
|
"url": "https://hashnode.com/@Greatcto"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
//
|
|
12
12
|
// Pairs with change-tier.mjs (the tier) + gate-plan.mjs (per-change plan) + ADR-004.
|
|
13
13
|
|
|
14
|
-
export const DEFAULT_FRONTIER_JUDGE = 'claude-opus-
|
|
14
|
+
export const DEFAULT_FRONTIER_JUDGE = 'claude-opus-5';
|
|
15
15
|
export const DEFAULT_CHEAP_JUDGE = 'claude-haiku-4-5';
|
|
16
16
|
|
|
17
17
|
/**
|
package/dist/adapt.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// great-cto adapt --dry-run Show what would be written
|
|
10
10
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
|
+
import { codexInstallPlan } from "./codex.js";
|
|
12
13
|
const VALID_AI_TOOLS = ["claude-code", "cursor", "copilot", "windsurf", "aider", "codex"];
|
|
13
14
|
function parseAiTools(text) {
|
|
14
15
|
const line = text.match(/^ai_tools:\s*(.+)$/m)?.[1] ?? "";
|
|
@@ -309,134 +310,68 @@ dirty-commits: false
|
|
|
309
310
|
`;
|
|
310
311
|
}
|
|
311
312
|
// ── Codex adapter helpers ──────────────────────────────────────────────────
|
|
313
|
+
// `getCodexHooksJson` used to live here, and `adapt` wrote its output to
|
|
314
|
+
// `.codex/hooks.json`. Six tests certified its shape — the split between
|
|
315
|
+
// blocking and advisory wrappers, the matchers covering `apply_patch` — and all
|
|
316
|
+
// six passed while the file went to a path Codex does not read.
|
|
317
|
+
//
|
|
318
|
+
// Two upstream issues settle it (openai/codex #16430, #39895): hooks load from
|
|
319
|
+
// the config layer only, a plugin cannot carry them, and the `hooks` field is
|
|
320
|
+
// read by nothing "with no warning, error, or log line". `.codex/hooks.json`,
|
|
321
|
+
// project-scoped, was never even the config layer. See
|
|
322
|
+
// docs/analysis/2026-09-05-codex-phase0-findings.md.
|
|
323
|
+
//
|
|
324
|
+
// So the generator is gone rather than corrected. A tested generator writing to
|
|
325
|
+
// a path nothing reads is the exact defect this repository exists to delete: it
|
|
326
|
+
// looked more finished than an absent one.
|
|
312
327
|
/**
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
* Phase 0 findings (2026-06-04, confirmed against Codex Desktop binary):
|
|
316
|
-
* - Hook events: PreToolUse, PostToolUse, SessionStart, SubagentStart,
|
|
317
|
-
* SubagentStop, PreCompact, PostCompact, UserPromptSubmit, PermissionRequest.
|
|
318
|
-
* - stdin payload: same keys as Claude Code (tool_name, tool_input, is_error).
|
|
319
|
-
* - block/deny: hookSpecificOutput.permissionDecision (same struct as CC)
|
|
320
|
-
* confirmed by binary string literals.
|
|
321
|
-
* - Hooks enabled by [features].hooks = true in config.toml.
|
|
322
|
-
*
|
|
323
|
-
* @param skillDir - absolute path to ~/.codex/skills/great_cto (used to build hook commands)
|
|
324
|
-
*/
|
|
325
|
-
/**
|
|
326
|
-
* hooks.json for Codex.
|
|
328
|
+
* The config.toml fragment for Codex — only the part that runs.
|
|
327
329
|
*
|
|
328
|
-
*
|
|
329
|
-
* and `permissionDecision` takes `allow | deny | ask`, the words we already
|
|
330
|
-
* write. No translation layer is needed; see
|
|
331
|
-
* docs/analysis/2026-09-05-codex-phase0-findings.md.
|
|
330
|
+
* What this used to emit, and why each line is gone:
|
|
332
331
|
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
332
|
+
* [features] hooks = true turns on a feature a plugin cannot reach
|
|
333
|
+
* (openai/codex#16430) and which has an open
|
|
334
|
+
* timeout regression on 0.148.0+ (#42279)
|
|
335
|
+
* CODEX_SKILL_DIR = ~/.codex/skills/great_cto
|
|
336
|
+
* a path a working Codex install does not have;
|
|
337
|
+
* Phase 0 checked, the directory is not created
|
|
338
|
+
* [agents.great_cto_*] six role descriptions presented as "the
|
|
339
|
+
* specialist fleet", with a comment claiming
|
|
340
|
+
* "full 57-agent routing" — we ship seventy, and
|
|
341
|
+
* Codex routes none of them
|
|
337
342
|
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
* `str_replace_editor`. This was found by running it: Codex wrote a file
|
|
343
|
-
* containing an API key and secret-scan never fired — the hook was correct, it
|
|
344
|
-
* was never called. A matcher that matches nothing looks exactly like a guard
|
|
345
|
-
* that passed.
|
|
346
|
-
* blocking (secret-scan) bare, so a non-zero exit reaches Codex
|
|
347
|
-
* advisory (format-check, tool-failure) keeps `|| true` — a formatter that
|
|
348
|
-
* dies must not stop the user's write
|
|
349
|
-
*/
|
|
350
|
-
export function getCodexHooksJson(skillDir) {
|
|
351
|
-
const s = skillDir; // shorthand
|
|
352
|
-
return JSON.stringify({
|
|
353
|
-
"SessionStart": [
|
|
354
|
-
{
|
|
355
|
-
"hooks": [
|
|
356
|
-
{ "command": `node "${s}/scripts/hooks/quota-check.mjs" 2>/dev/null || true`, "timeout": 15 }
|
|
357
|
-
]
|
|
358
|
-
}
|
|
359
|
-
],
|
|
360
|
-
"PreToolUse": [
|
|
361
|
-
{
|
|
362
|
-
"matcher": "computer|bash|shell",
|
|
363
|
-
"hooks": [
|
|
364
|
-
{ "command": `node "${s}/scripts/hooks/orchestrator-check.mjs" 2>/dev/null || true`, "timeout": 5 },
|
|
365
|
-
{ "command": `node "${s}/scripts/hooks/cost-guard.mjs" 2>/dev/null || true`, "timeout": 5 }
|
|
366
|
-
]
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
"matcher": "edit|write|str_replace_editor|computer|apply_patch",
|
|
370
|
-
"hooks": [
|
|
371
|
-
{ "command": `node "${s}/scripts/hooks/secret-scan.mjs"`, "timeout": 8 }
|
|
372
|
-
]
|
|
373
|
-
}
|
|
374
|
-
],
|
|
375
|
-
"PostToolUse": [
|
|
376
|
-
{
|
|
377
|
-
"matcher": "edit|write|str_replace_editor|apply_patch",
|
|
378
|
-
"hooks": [
|
|
379
|
-
{ "command": `node "${s}/scripts/hooks/format-check.mjs" 2>/dev/null; true`, "timeout": 12, "async": true },
|
|
380
|
-
{ "command": `node "${s}/scripts/hooks/tool-failure.mjs" 2>/dev/null || true`, "timeout": 3, "async": true }
|
|
381
|
-
]
|
|
382
|
-
},
|
|
383
|
-
{
|
|
384
|
-
"matcher": "",
|
|
385
|
-
"hooks": [
|
|
386
|
-
{ "command": `node "${s}/scripts/hooks/tool-failure.mjs" 2>/dev/null || true`, "timeout": 3, "async": true }
|
|
387
|
-
]
|
|
388
|
-
}
|
|
389
|
-
]
|
|
390
|
-
}, null, 2);
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* config.toml fragment to merge into ~/.codex/config.toml.
|
|
394
|
-
* Adds: [features].hooks=true, [mcp_servers.great_cto], [agents.great_cto_skill].
|
|
395
|
-
* Written as a separate file (.codex/great_cto.toml) since merging TOML is
|
|
396
|
-
* non-trivial; installer prints merge instructions.
|
|
343
|
+
* An MCP server is the one thing here Codex actually starts, so it is the one
|
|
344
|
+
* thing left. The rest of the fragment is now a statement of what does NOT come
|
|
345
|
+
* with it, taken from `codexInstallPlan` so the two cannot drift apart again —
|
|
346
|
+
* which is precisely how they drifted the first time.
|
|
397
347
|
*/
|
|
398
348
|
function getCodexConfigFragment(meta) {
|
|
399
|
-
|
|
400
|
-
|
|
349
|
+
const plan = codexInstallPlan({ repoDir: "<path-to-great_cto>", codexOnPath: true });
|
|
350
|
+
const notes = plan.notSupported.map((n) => `# - ${n}`).join("\n");
|
|
351
|
+
return `# great_cto ⇄ Codex — generated by great-cto adapt
|
|
401
352
|
# Generated: ${new Date().toISOString().slice(0, 10)}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
353
|
+
#
|
|
354
|
+
# This file contains ONE section, because one section is what Codex runs from a
|
|
355
|
+
# config fragment. Merge it into ~/.codex/config.toml.
|
|
356
|
+
#
|
|
357
|
+
# For skills, install the plugin instead of copying anything by hand:
|
|
358
|
+
# ${plan.commands.join("\n# ")}
|
|
359
|
+
#
|
|
360
|
+
# What does NOT come with either, on codex-cli as it stands today:
|
|
361
|
+
${notes}
|
|
362
|
+
#
|
|
363
|
+
# Details, measured rather than inferred:
|
|
364
|
+
# docs/analysis/2026-09-05-codex-phase0-findings.md
|
|
405
365
|
|
|
406
366
|
[mcp_servers.great_cto]
|
|
407
367
|
command = "npx"
|
|
408
368
|
args = ["great-cto@latest", "mcp"]
|
|
409
|
-
#
|
|
369
|
+
# Generous: npx downloads on first run.
|
|
410
370
|
startup_timeout_sec = 60
|
|
411
371
|
|
|
412
|
-
[mcp_servers.great_cto.env]
|
|
413
|
-
# Point hooks at the skill dir so hook scripts resolve correctly.
|
|
414
|
-
CODEX_SKILL_DIR = "${process.env.HOME ?? "~"}/.codex/skills/great_cto"
|
|
415
|
-
|
|
416
|
-
# Agents exposed via MCP (great_cto specialist fleet)
|
|
417
|
-
# Codex will use these as subagent personalities via the [agents] table.
|
|
418
|
-
# Full 57-agent routing is handled inside AGENTS.md / SKILL.md.
|
|
419
|
-
[agents.great_cto_architect]
|
|
420
|
-
description = "Deep architectural reasoning, ADRs, cross-cutting design decisions"
|
|
421
|
-
|
|
422
|
-
[agents.great_cto_senior_dev]
|
|
423
|
-
description = "Feature implementation with TDD — RED→GREEN→REFACTOR"
|
|
424
|
-
|
|
425
|
-
[agents.great_cto_qa_engineer]
|
|
426
|
-
description = "QA reports, coverage, regression check after implementation"
|
|
427
|
-
|
|
428
|
-
[agents.great_cto_security_officer]
|
|
429
|
-
description = "Security audit — OWASP Top 10, auth, PII, secrets"
|
|
430
|
-
|
|
431
|
-
[agents.great_cto_devops]
|
|
432
|
-
description = "Deploy, canary rollout, rollback, SLO monitoring"
|
|
433
|
-
|
|
434
|
-
[agents.great_cto_pm]
|
|
435
|
-
description = "Feature decomposition into tasks, timeline, dependency graph"
|
|
436
|
-
|
|
437
372
|
# Archetype: ${meta.archetype}
|
|
438
373
|
# Compliance: ${meta.compliance.join(", ") || "none"}
|
|
439
|
-
# Re-run great-cto adapt
|
|
374
|
+
# Re-run great-cto adapt to refresh.
|
|
440
375
|
`;
|
|
441
376
|
}
|
|
442
377
|
function getCliVersion() {
|
|
@@ -524,17 +459,30 @@ conventions. Generated by \`great-cto adapt\`.
|
|
|
524
459
|
break;
|
|
525
460
|
}
|
|
526
461
|
case "codex": {
|
|
527
|
-
//
|
|
528
|
-
|
|
529
|
-
|
|
462
|
+
// One file, and only the MCP section in it. The previous version also
|
|
463
|
+
// wrote `.codex/hooks.json` and then said "restart Codex to activate
|
|
464
|
+
// hooks and MCP server" — half of which was true. A user who followed
|
|
465
|
+
// that line came away believing the gate chain and secret-scan were
|
|
466
|
+
// guarding their session on Codex. They were not, and nothing said so.
|
|
530
467
|
const configPath = join(cwd, ".codex", "great_cto.toml");
|
|
531
|
-
if (writeFile(hooksPath, getCodexHooksJson(defaultSkillDir), dryRun))
|
|
532
|
-
out.push(".codex/hooks.json");
|
|
533
468
|
if (writeFile(configPath, getCodexConfigFragment(meta), dryRun))
|
|
534
469
|
out.push(".codex/great_cto.toml");
|
|
470
|
+
// A file we used to write and no longer do stays on disk. Say so rather
|
|
471
|
+
// than delete it: it is in the user's project, and it may be theirs now.
|
|
472
|
+
const stale = join(cwd, ".codex", "hooks.json");
|
|
535
473
|
if (!dryRun) {
|
|
536
|
-
console.log(" ⚠ Codex: merge .codex/great_cto.toml
|
|
537
|
-
console.log("
|
|
474
|
+
console.log(" ⚠ Codex: merge .codex/great_cto.toml into ~/.codex/config.toml, then restart Codex.");
|
|
475
|
+
console.log(" That gives you the MCP server. For the skills, install the plugin:");
|
|
476
|
+
for (const c of codexInstallPlan({ repoDir: "<path-to-great_cto>", codexOnPath: true }).commands) {
|
|
477
|
+
console.log(` ${c}`);
|
|
478
|
+
}
|
|
479
|
+
console.log(" Hooks, slash commands and the role agents do NOT carry over to Codex today —");
|
|
480
|
+
console.log(" see docs/analysis/2026-09-05-codex-phase0-findings.md.");
|
|
481
|
+
if (existsSync(stale)) {
|
|
482
|
+
console.log("");
|
|
483
|
+
console.log(" ⚠ .codex/hooks.json exists and an older great-cto wrote it. Codex never read it");
|
|
484
|
+
console.log(" (openai/codex#16430) — delete it yourself if it is not yours.");
|
|
485
|
+
}
|
|
538
486
|
}
|
|
539
487
|
break;
|
|
540
488
|
}
|
|
@@ -593,7 +541,10 @@ export function nextStepsAfterAdapt(aiTools = []) {
|
|
|
593
541
|
out.push(" 1. Restart Claude Code so it picks up the regenerated CLAUDE.md.", " 2. /audit — full analysis of this codebase (existing project)", " /start — scope and build a new feature (greenfield)", " /inbox — what needs your decision right now", " 3. great-cto board — Kanban + CTO dashboard at localhost:3141");
|
|
594
542
|
}
|
|
595
543
|
else {
|
|
596
|
-
|
|
544
|
+
// "is live" was wrong for Codex, whose fragment the user still has to merge
|
|
545
|
+
// into ~/.codex/config.toml by hand — and a line that says a thing is live
|
|
546
|
+
// is exactly how an unmerged file passes for a working one.
|
|
547
|
+
out.push(` Config written for ${aiTools.join(" / ")}. A fragment that says to merge it is not active`, " until you do — then reload the tool to pick it up.", " The agent pipeline (architecture review, QA, security gates) runs inside", " Claude Code. To use it here: add claude-code to ai_tools in PROJECT.md,", " then `npx great-cto install`.");
|
|
597
548
|
}
|
|
598
549
|
return out;
|
|
599
550
|
}
|
package/package.json
CHANGED