sprag-cli 3.63.0 → 3.65.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/bin/cli.js +3 -25
- package/docs/CODEX.ko.md +55 -1
- package/docs/CODEX.md +85 -3
- package/mod/sprag-delegation-meter/hooks/hooks.json +3 -0
- package/mod/sprag-delegation-meter/hooks/register.ts +197 -0
- package/mod/sprag-doc2md/hooks/hooks.json +3 -0
- package/mod/sprag-doc2md/hooks/register.ts +97 -0
- package/package.json +2 -2
- package/src/codex-brief.js +10 -1
- package/src/codex-delegation-diagnostics.js +42 -0
- package/src/codex-delegation.js +17 -0
- package/src/codex-doc2md-ledger.js +53 -8
- package/src/codex-doc2md.js +21 -4
- package/src/codex-doctor.js +9 -1
- package/src/codex-harness.js +2 -1
- package/src/codex-hooks.js +12 -3
- package/src/codex-installer.js +1 -0
- package/src/codex-ledger.js +25 -1
- package/src/codex-panel.js +33 -12
- package/src/codex-reply-language.js +43 -0
- package/src/codex-rule-health.js +23 -0
- package/src/commands/codex-delegate.js +16 -2
- package/src/commands/codex.js +40 -8
- package/src/commands/route-scan.js +2 -36
- package/src/commands/saved.js +10 -4
- package/src/commands/update-check.js +7 -4
- package/src/formatters/statusline.js +36 -9
- package/src/implementation-delegation.js +34 -0
- package/src/model-rules.js +3 -20
- package/src/reply-language.cjs +3 -2
- package/src/route-scan.js +21 -5
- package/src/savings-ledger.js +21 -7
- package/src/statusline-data.js +13 -4
- package/src/update-notice.js +37 -0
package/src/statusline-data.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { resolve } from 'node:path';
|
|
11
11
|
import { modelFamily } from './savings-ledger.js';
|
|
12
12
|
import { loadModelRules } from './model-rules.js';
|
|
13
|
+
import { sessionCostAcross } from './claude-price.js';
|
|
13
14
|
|
|
14
15
|
/** Longest family name shown before it is cut. Keeps an opaque gateway id from taking the line. */
|
|
15
16
|
const FAMILY_MAX = 14;
|
|
@@ -32,12 +33,17 @@ const shortFamily = (name) => (name.length > FAMILY_MAX ? `${name.slice(0, FAMIL
|
|
|
32
33
|
* is rather than folding it into a neighbour; the name is shortened here so an
|
|
33
34
|
* ARN cannot flood the line.
|
|
34
35
|
*
|
|
36
|
+
* `usd` is what the runs cost, each priced at its own model by the same path
|
|
37
|
+
* the session's own cost takes (a gateway session from the gateway's table),
|
|
38
|
+
* and `unpriced` counts the priced parts that had no rate and were left out.
|
|
39
|
+
*
|
|
35
40
|
* @param {Array} sessions parseAllSessions result
|
|
36
|
-
* @param {{ transcriptPath?: string|null, sessionId?: string|null }} [ids]
|
|
37
|
-
*
|
|
41
|
+
* @param {{ transcriptPath?: string|null, sessionId?: string|null, env?: object }} [ids]
|
|
42
|
+
* `env` decides the pricing path, as in sessionCost
|
|
43
|
+
* @returns {{ total: number, families: Array<{ family: string, runs: number }>, usd: number, unpriced: number }|null}
|
|
38
44
|
* null when the session cannot be found or ran no subagents
|
|
39
45
|
*/
|
|
40
|
-
export function sessionSubagentSummary(sessions, { transcriptPath = null, sessionId = null } = {}) {
|
|
46
|
+
export function sessionSubagentSummary(sessions, { transcriptPath = null, sessionId = null, env = process.env } = {}) {
|
|
41
47
|
if (!Array.isArray(sessions) || (!transcriptPath && !sessionId)) return null;
|
|
42
48
|
let hit = null;
|
|
43
49
|
if (transcriptPath) {
|
|
@@ -62,7 +68,10 @@ export function sessionSubagentSummary(sessions, { transcriptPath = null, sessio
|
|
|
62
68
|
const families = [...byFamily.entries()]
|
|
63
69
|
.map(([family, n]) => ({ family, runs: n }))
|
|
64
70
|
.sort((a, b) => b.runs - a.runs || a.family.localeCompare(b.family));
|
|
65
|
-
|
|
71
|
+
// A run is a session-shaped record (totals, model, modelTotals when it
|
|
72
|
+
// switched model), so it is priced the way a session is.
|
|
73
|
+
const cost = sessionCostAcross(runs, { env });
|
|
74
|
+
return { total: runs.length, families, usd: cost.actual, unpriced: cost.unpriced };
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
/**
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { updateStatus, maybeSpawnUpdateCheck, readUpdateState, updateCheckDisabled, SESSION_START_CHECK_INTERVAL_MS } from './update-check.js';
|
|
2
|
+
import { debug } from './debug.js';
|
|
3
|
+
|
|
4
|
+
/** Shared by terminal renders; registry I/O stays in the detached checker. */
|
|
5
|
+
export function readUpdateChip(version, { refresh = true, ...opts } = {}) {
|
|
6
|
+
try {
|
|
7
|
+
if (refresh) maybeSpawnUpdateCheck(version, opts);
|
|
8
|
+
const status = updateStatus(version, opts);
|
|
9
|
+
const checkedAt = updateCheckDisabled() ? null : (Number(readUpdateState().checkedAt) || null);
|
|
10
|
+
return { ...status, checkedAt };
|
|
11
|
+
} catch (e) {
|
|
12
|
+
debug('update-check:chip', e);
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function upgradeInstructions(agent = 'claude') {
|
|
18
|
+
return agent === 'codex'
|
|
19
|
+
? ['npm i -g sprag-cli --ignore-scripts', 'sprag install --agent codex']
|
|
20
|
+
: ['sprag upgrade'];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** The model must obtain consent; a hook never installs a package itself. */
|
|
24
|
+
export function updateOffer(version, { agent = 'claude', lang = 'en', ...opts } = {}) {
|
|
25
|
+
const u = readUpdateChip(version, { intervalMs: SESSION_START_CHECK_INTERVAL_MS, ...opts });
|
|
26
|
+
if (!u?.available || u.dismissed) return null;
|
|
27
|
+
const ko = lang === 'ko';
|
|
28
|
+
return [
|
|
29
|
+
ko ? `[sprag update] 새 버전이 나와 있습니다: v${u.current} → ${u.latest}.`
|
|
30
|
+
: `[sprag update] A newer version is available: v${u.current} → ${u.latest}.`,
|
|
31
|
+
...(u.highlights || []).slice(0, 3).map((note) => ` - ${note}`),
|
|
32
|
+
ko ? '사용자에게 변경 내용을 알리고 업그레이드할지 물어보십시오. 승낙한 경우에만 아래 명령을 실행하십시오.'
|
|
33
|
+
: 'Show the changes and ask the user whether to upgrade. Run these commands only if they agree; do not install without asking.',
|
|
34
|
+
...upgradeInstructions(agent).map((command) => ` ${command}`),
|
|
35
|
+
` sprag update-check --dismiss${agent === 'codex' ? ' --agent codex' : ''}`,
|
|
36
|
+
].join('\n');
|
|
37
|
+
}
|