great-cto 3.37.1 → 3.39.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
|
-
"description": "You already have the agent. This is everything around it. great_cto runs Claude Code as a pipeline of
|
|
4
|
-
"version": "3.
|
|
3
|
+
"description": "You already have the agent. This is everything around it. great_cto runs Claude Code as a pipeline of 71 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.39.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Alexander Velikiy",
|
|
7
7
|
"url": "https://hashnode.com/@Greatcto"
|
|
@@ -159,9 +159,9 @@
|
|
|
159
159
|
},
|
|
160
160
|
{
|
|
161
161
|
"type": "command",
|
|
162
|
-
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\";
|
|
162
|
+
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\"; PLUGIN_DIR=${CLAUDE_PLUGIN_ROOT:-$(ls -d ~/.claude/plugins/cache/*/great_cto/*/ 2>/dev/null | awk -F'/plugins/cache/' '{split($NF,p,\"/\"); print p[3], $0}' | sort -V | tail -1 | cut -d' ' -f2- | sed 's|/$||')}; node \"${PLUGIN_DIR}/scripts/hooks/destructive-guard.mjs\"; EXIT=$?; if [ $EXIT -eq 2 ]; then exit 2; fi; exit 0",
|
|
163
163
|
"timeout": 5,
|
|
164
|
-
"statusMessage": "
|
|
164
|
+
"statusMessage": "Destructive-command check..."
|
|
165
165
|
}
|
|
166
166
|
]
|
|
167
167
|
},
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
"hooks": [
|
|
202
202
|
{
|
|
203
203
|
"type": "command",
|
|
204
|
-
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\"; INPUT=$(cat 2>/dev/null); FILE=$(echo \"$INPUT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))\" 2>/dev/null); TOOL=$(echo \"$INPUT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('tool_name',''))\" 2>/dev/null); if [ -n \"$FILE\" ]; then mkdir -p .great_cto 2>/dev/null; printf '%s %s %s\\n' \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \"$TOOL\" \"$FILE\" >> .great_cto/agent-writes.log 2>/dev/null; fi; true",
|
|
204
|
+
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\"; INPUT=$(cat 2>/dev/null); FILE=$(echo \"$INPUT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print((d.get('tool_input') or {}).get('file_path') or d.get('file_path',''))\" 2>/dev/null); TOOL=$(echo \"$INPUT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('tool_name',''))\" 2>/dev/null); if [ -n \"$FILE\" ]; then mkdir -p .great_cto 2>/dev/null; printf '%s %s %s\\n' \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \"$TOOL\" \"$FILE\" >> .great_cto/agent-writes.log 2>/dev/null; fi; true",
|
|
205
205
|
"timeout": 3,
|
|
206
206
|
"async": true
|
|
207
207
|
},
|
|
@@ -211,6 +211,11 @@
|
|
|
211
211
|
"timeout": 12,
|
|
212
212
|
"async": true
|
|
213
213
|
},
|
|
214
|
+
{
|
|
215
|
+
"type": "command",
|
|
216
|
+
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\"; PLUGIN_DIR=${CLAUDE_PLUGIN_ROOT:-$(ls -d ~/.claude/plugins/cache/*/great_cto/*/ 2>/dev/null | awk -F'/plugins/cache/' '{split($NF,p,\"/\"); print p[3], $0}' | sort -V | tail -1 | cut -d' ' -f2- | sed 's|/$||')}; node \"${PLUGIN_DIR}/scripts/hooks/typecheck-accumulate.mjs\" 2>/dev/null; true",
|
|
217
|
+
"timeout": 5
|
|
218
|
+
},
|
|
214
219
|
{
|
|
215
220
|
"type": "command",
|
|
216
221
|
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\"; PLUGIN_DIR=${CLAUDE_PLUGIN_ROOT:-$(ls -d ~/.claude/plugins/cache/*/great_cto/*/ 2>/dev/null | awk -F'/plugins/cache/' '{split($NF,p,\"/\"); print p[3], $0}' | sort -V | tail -1 | cut -d' ' -f2- | sed 's|/$||')}; node \"${PLUGIN_DIR}/scripts/hooks/summary-enforce.mjs\" 2>/dev/null; true",
|
|
@@ -244,6 +249,11 @@
|
|
|
244
249
|
"timeout": 3,
|
|
245
250
|
"statusMessage": "Capturing tool failure...",
|
|
246
251
|
"async": true
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"type": "command",
|
|
255
|
+
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\"; PLUGIN_DIR=${CLAUDE_PLUGIN_ROOT:-$(ls -d ~/.claude/plugins/cache/*/great_cto/*/ 2>/dev/null | awk -F'/plugins/cache/' '{split($NF,p,\"/\"); print p[3], $0}' | sort -V | tail -1 | cut -d' ' -f2- | sed 's|/$||')}; node \"${PLUGIN_DIR}/scripts/hooks/loop-detector.mjs\" 2>/dev/null || true",
|
|
256
|
+
"timeout": 3
|
|
247
257
|
}
|
|
248
258
|
]
|
|
249
259
|
},
|
|
@@ -327,6 +337,11 @@
|
|
|
327
337
|
"type": "command",
|
|
328
338
|
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\"; node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/cross-review-gate.mjs\" 2>/dev/null || true"
|
|
329
339
|
},
|
|
340
|
+
{
|
|
341
|
+
"type": "command",
|
|
342
|
+
"command": "_gd=\"$PWD\"; while [ -n \"$_gd\" ] && [ ! -f \"$_gd/.great_cto/PROJECT.md\" ]; do _gd=\"${_gd%/*}\"; done; [ -n \"$_gd\" ] && cd \"$_gd\"; node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/stop-typecheck.mjs\" 2>/dev/null || true",
|
|
343
|
+
"timeout": 90
|
|
344
|
+
},
|
|
330
345
|
{
|
|
331
346
|
"type": "command",
|
|
332
347
|
"async": true,
|
|
@@ -370,6 +385,7 @@
|
|
|
370
385
|
"./agents-full/app-scaffolder.md",
|
|
371
386
|
"./agents-full/architect.md",
|
|
372
387
|
"./agents-full/auth-engineer.md",
|
|
388
|
+
"./agents-full/ci-resolver.md",
|
|
373
389
|
"./agents-full/cli-reviewer.md",
|
|
374
390
|
"./agents-full/cmmc-reviewer.md",
|
|
375
391
|
"./agents-full/cms-reviewer.md",
|
|
@@ -5929,7 +5929,7 @@ async function renderHarnesses() {
|
|
|
5929
5929
|
|
|
5930
5930
|
body.innerHTML = `
|
|
5931
5931
|
<div class="mp-card harness-hosts">
|
|
5932
|
-
<div><span class="dot ok"></span><b>Claude Code</b> <span class="mono cap muted">host · v${esc(h.claude_code?.version || '')}</span><span class="cap muted" style="margin-left:auto" title="
|
|
5932
|
+
<div><span class="dot ok"></span><b>Claude Code</b> <span class="mono cap muted">host · v${esc(h.claude_code?.version || '')}</span><span class="cap muted" style="margin-left:auto" title="71 agents · commands · skills · hooks">full pipeline</span></div>
|
|
5933
5933
|
<div><span class="${codexDot}"></span><b>OpenAI Codex</b> <span class="mono cap">${codexState}</span>${cx.version ? `<span class="mono cap muted">${esc(cx.version)}</span>` : ''}${cx.model ? `<span class="mono cap muted" style="margin-left:auto">${esc(cx.model)}</span>` : ''}</div>
|
|
5934
5934
|
</div>
|
|
5935
5935
|
<div class="mp-card" style="margin-top:12px">
|
|
@@ -161,6 +161,25 @@ export function resolvePrice(model, prices = effectivePrices()) {
|
|
|
161
161
|
*
|
|
162
162
|
* @returns {{usd:number, priced:boolean, assumed:boolean, source:string, model:string}}
|
|
163
163
|
*/
|
|
164
|
+
/**
|
|
165
|
+
* Cache-write dollars. Anthropic bills a 5-minute cache write at 1.25× the input
|
|
166
|
+
* price and a 1-hour write at 2×; `usage.cache_creation` splits the tokens by TTL
|
|
167
|
+
* (`ephemeral_5m_input_tokens` / `ephemeral_1h_input_tokens`). Pricing every write
|
|
168
|
+
* at 1.25× understated long sessions — Claude Code writes the 1-hour cache — which
|
|
169
|
+
* session-shape found on 2026-09-27. Without the split, the flat 1.25× stands.
|
|
170
|
+
*/
|
|
171
|
+
export function cacheWriteUsd(usage, inputPrice) {
|
|
172
|
+
const split = usage?.cache_creation;
|
|
173
|
+
const total = usage?.cache_creation_input_tokens || 0;
|
|
174
|
+
if (split && (split.ephemeral_1h_input_tokens != null || split.ephemeral_5m_input_tokens != null)) {
|
|
175
|
+
const h1 = split.ephemeral_1h_input_tokens || 0;
|
|
176
|
+
const m5 = split.ephemeral_5m_input_tokens || 0;
|
|
177
|
+
const rest = Math.max(0, total - h1 - m5); // any write the split does not name
|
|
178
|
+
return (h1 * 2 + (m5 + rest) * 1.25) * inputPrice;
|
|
179
|
+
}
|
|
180
|
+
return total * 1.25 * inputPrice;
|
|
181
|
+
}
|
|
182
|
+
|
|
164
183
|
export function priceUsage({ model, usage, prices }) {
|
|
165
184
|
const { price, source } = resolvePrice(model, prices || effectivePrices());
|
|
166
185
|
if (!usage || !price) {
|
|
@@ -168,10 +187,9 @@ export function priceUsage({ model, usage, prices }) {
|
|
|
168
187
|
}
|
|
169
188
|
const inTok = usage.input_tokens || 0;
|
|
170
189
|
const outTok = usage.output_tokens || 0;
|
|
171
|
-
const cacheWrite = usage.cache_creation_input_tokens || 0;
|
|
172
190
|
const cacheRead = usage.cache_read_input_tokens || 0;
|
|
173
191
|
const usd = (inTok * price.input + outTok * price.output
|
|
174
|
-
+
|
|
192
|
+
+ cacheWriteUsd(usage, price.input) + cacheRead * price.input * 0.1) / 1_000_000;
|
|
175
193
|
return { usd, priced: true, assumed: source === 'family', source, model: model || '' };
|
|
176
194
|
}
|
|
177
195
|
|
|
@@ -190,13 +208,13 @@ export function costForUsage({ model, usage, prices }) {
|
|
|
190
208
|
const inTok = usage.input_tokens || 0;
|
|
191
209
|
const outTok = usage.output_tokens || 0;
|
|
192
210
|
// Prompt-caching tokens bill at Anthropic's standard multipliers off the base
|
|
193
|
-
// input price: cache WRITE = 1.25× input
|
|
211
|
+
// input price: cache WRITE = 1.25× input (2× for the 1-hour TTL, see
|
|
212
|
+
// cacheWriteUsd), cache READ = 0.1× input. Ignoring
|
|
194
213
|
// them under-counts real spend badly (a cached turn is often 50k+ cache tokens
|
|
195
214
|
// vs a few hundred fresh input tokens).
|
|
196
|
-
const cacheWrite = usage.cache_creation_input_tokens || 0;
|
|
197
215
|
const cacheRead = usage.cache_read_input_tokens || 0;
|
|
198
216
|
return (inTok * p.input + outTok * p.output
|
|
199
|
-
+
|
|
217
|
+
+ cacheWriteUsd(usage, p.input) + cacheRead * p.input * 0.1) / 1_000_000;
|
|
200
218
|
}
|
|
201
219
|
|
|
202
220
|
export function round4(n) { return Math.round(n * 10000) / 10000; }
|
package/package.json
CHANGED