throughline 0.3.24 → 0.3.25
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/.claude/commands/tl-trim.md +42 -0
- package/.codex-sidecar.yml +62 -0
- package/CHANGELOG.md +583 -0
- package/README.ja.md +42 -5
- package/README.md +383 -23
- package/bin/throughline.mjs +168 -4
- package/codex/skills/throughline/SKILL.md +157 -0
- package/codex/skills/throughline/agents/openai.yaml +7 -0
- package/docs/INHERITANCE_ON_CLEAR_ONLY.md +146 -0
- package/docs/L1_L2_L3_REDESIGN.md +415 -0
- package/docs/PUBLIC_RELEASE_PLAN.md +184 -0
- package/docs/THROUGHLINE_CODEX_DUAL_SUPPORT.md +249 -0
- package/docs/THROUGHLINE_CODEX_FIRST_ROADMAP.md +555 -0
- package/docs/THROUGHLINE_CODEX_MONITOR_IMPLEMENTATION_PLAN.md +220 -0
- package/docs/THROUGHLINE_CODEX_TRIM_IMPLEMENTATION_PLAN.md +528 -0
- package/docs/THROUGHLINE_CODEX_TRIM_ROLLBACK_FIX_PLAN.md +672 -0
- package/docs/archive/CONCEPT.md +476 -0
- package/docs/archive/EXPERIMENT.md +371 -0
- package/docs/archive/README.md +22 -0
- package/docs/archive/SESSION_LINKING_DESIGN.md +231 -0
- package/docs/archive/THROUGHLINE_NEXT_STEPS.md +134 -0
- package/docs/throughline-codex-trim-rollback-incident-report.md +306 -0
- package/docs/throughline-handoff-context.example.json +57 -0
- package/docs/throughline-rollback-context-trim-insight.md +455 -0
- package/package.json +6 -2
- package/src/cli/codex-capture.mjs +95 -0
- package/src/cli/codex-handoff-model-smoke.mjs +292 -0
- package/src/cli/codex-handoff-model-smoke.test.mjs +262 -0
- package/src/cli/codex-handoff-smoke.mjs +163 -0
- package/src/cli/codex-handoff-smoke.test.mjs +149 -0
- package/src/cli/codex-handoff-start.mjs +291 -0
- package/src/cli/codex-handoff-start.test.mjs +194 -0
- package/src/cli/codex-hook.mjs +276 -0
- package/src/cli/codex-hook.test.mjs +293 -0
- package/src/cli/codex-host-primitive-audit.mjs +110 -0
- package/src/cli/codex-host-primitive-audit.test.mjs +75 -0
- package/src/cli/codex-restore-smoke.mjs +357 -0
- package/src/cli/codex-restore-source-audit.mjs +304 -0
- package/src/cli/codex-resume.mjs +138 -0
- package/src/cli/codex-rollback-model-visible-smoke.mjs +373 -0
- package/src/cli/codex-rollback-model-visible-smoke.test.mjs +255 -0
- package/src/cli/codex-sidecar-diagnostics.mjs +48 -0
- package/src/cli/codex-sidecar-dry-run.mjs +85 -0
- package/src/cli/codex-summarize.mjs +224 -0
- package/src/cli/codex-threads.mjs +89 -0
- package/src/cli/codex-visibility-smoke.mjs +196 -0
- package/src/cli/codex-vscode-restore-smoke.mjs +226 -0
- package/src/cli/codex-vscode-rollback-smoke.mjs +114 -0
- package/src/cli/doctor.mjs +503 -1
- package/src/cli/doctor.test.mjs +542 -3
- package/src/cli/handoff-preview.mjs +78 -0
- package/src/cli/help.test.mjs +64 -0
- package/src/cli/install.mjs +227 -4
- package/src/cli/install.test.mjs +207 -4
- package/src/cli/trim.mjs +564 -0
- package/src/codex-app-server.mjs +1816 -0
- package/src/codex-app-server.test.mjs +512 -0
- package/src/codex-auto-refresh.mjs +194 -0
- package/src/codex-auto-refresh.test.mjs +182 -0
- package/src/codex-capture.mjs +235 -0
- package/src/codex-capture.test.mjs +393 -0
- package/src/codex-handoff-model-smoke.mjs +114 -0
- package/src/codex-handoff-model-smoke.test.mjs +89 -0
- package/src/codex-handoff-smoke.mjs +124 -0
- package/src/codex-handoff-smoke.test.mjs +103 -0
- package/src/codex-handoff.mjs +331 -0
- package/src/codex-handoff.test.mjs +220 -0
- package/src/codex-host-primitive-audit.mjs +374 -0
- package/src/codex-host-primitive-audit.test.mjs +208 -0
- package/src/codex-restore-smoke.test.mjs +639 -0
- package/src/codex-restore-source-audit.mjs +1348 -0
- package/src/codex-restore-source-audit.test.mjs +623 -0
- package/src/codex-resume.test.mjs +242 -0
- package/src/codex-rollout-memory.mjs +711 -0
- package/src/codex-rollout-memory.test.mjs +610 -0
- package/src/codex-sidecar-cli.test.mjs +75 -0
- package/src/codex-sidecar.mjs +246 -0
- package/src/codex-sidecar.test.mjs +172 -0
- package/src/codex-summarize.test.mjs +143 -0
- package/src/codex-thread-identity.mjs +23 -0
- package/src/codex-thread-index.mjs +173 -0
- package/src/codex-thread-index.test.mjs +164 -0
- package/src/codex-usage.mjs +110 -0
- package/src/codex-usage.test.mjs +140 -0
- package/src/codex-visibility-smoke.test.mjs +222 -0
- package/src/codex-vscode-restore-smoke.mjs +206 -0
- package/src/codex-vscode-restore-smoke.test.mjs +325 -0
- package/src/codex-vscode-rollback-smoke.mjs +90 -0
- package/src/codex-vscode-rollback-smoke.test.mjs +290 -0
- package/src/db-schema.test.mjs +97 -0
- package/src/haiku-summarizer.mjs +267 -26
- package/src/haiku-summarizer.test.mjs +282 -0
- package/src/handoff-preview.test.mjs +108 -0
- package/src/handoff-record.mjs +294 -0
- package/src/handoff-record.test.mjs +226 -0
- package/src/hook-entrypoints.test.mjs +326 -0
- package/src/package-files.test.mjs +19 -0
- package/src/prompt-submit.mjs +9 -6
- package/src/resume-context.mjs +44 -140
- package/src/resume-context.test.mjs +172 -0
- package/src/session-start.mjs +8 -5
- package/src/state-file.mjs +50 -6
- package/src/state-file.test.mjs +50 -0
- package/src/token-monitor.mjs +14 -10
- package/src/token-monitor.test.mjs +27 -0
- package/src/trim-cli.test.mjs +1584 -0
- package/src/trim-model.mjs +584 -0
- package/src/trim-model.test.mjs +568 -0
- package/src/turn-processor.mjs +17 -10
- package/src/vscode-task.mjs +33 -10
- package/src/vscode-task.test.mjs +19 -9
package/src/token-monitor.mjs
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
* - setInterval (1s) + mtime 差分検知で更新を捕捉
|
|
15
15
|
* - updatedAt 降順ソート、先頭行を ▶ でハイライト
|
|
16
16
|
* - stale は PID 生存チェックで判定
|
|
17
|
-
* -
|
|
17
|
+
* - Claude は transcript JSONL の最新 assistant usage を直読
|
|
18
|
+
* - Codex は Stop hook が state.usage に固定した rollout usage / estimate を表示
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
21
|
import { basename, dirname, join } from 'node:path';
|
|
@@ -191,7 +192,7 @@ function parseArgs(argv) {
|
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
// --- 表示 ---
|
|
194
|
-
function renderBar(ratio, width =
|
|
195
|
+
function renderBar(ratio, width = 10) {
|
|
195
196
|
// NaN は 0、+Infinity は 1(オーバーフロー = 満タン表示)、負値 / -Infinity は 0 にクランプ
|
|
196
197
|
let safe;
|
|
197
198
|
if (Number.isNaN(ratio)) safe = 0;
|
|
@@ -288,11 +289,10 @@ export function resolveColumns() {
|
|
|
288
289
|
function formatLine({ state, usage, isActive, now = Date.now() }) {
|
|
289
290
|
const project = basename(state.projectPath || '?');
|
|
290
291
|
const shortId = state.sessionId.slice(0, 8);
|
|
292
|
+
const host = state.host === 'codex' ? 'Codex' : state.host === 'unknown' ? 'Unknown' : 'Claude';
|
|
291
293
|
const tokens = usage?.tokens ?? 0;
|
|
292
294
|
const max = usage?.contextWindowSize ?? 200_000;
|
|
293
295
|
const ratio = max > 0 ? tokens / max : 0;
|
|
294
|
-
const pct = Math.round(ratio * 100);
|
|
295
|
-
const remaining = Math.max(0, max - tokens);
|
|
296
296
|
|
|
297
297
|
const bar = renderBar(ratio);
|
|
298
298
|
const barColor =
|
|
@@ -310,11 +310,15 @@ function formatLine({ state, usage, isActive, now = Date.now() }) {
|
|
|
310
310
|
|
|
311
311
|
const marker = isActive ? color(ANSI.bold + ANSI.cyan, '▶') : ' ';
|
|
312
312
|
const projectCol = padCellsEnd(project, 18);
|
|
313
|
+
const hostCol = color(ANSI.dim, padCellsEnd(host, 6));
|
|
313
314
|
const idCol = color(ANSI.dim, shortId);
|
|
314
315
|
const barCol = color(barColor, bar);
|
|
315
|
-
const tokCol = `${formatNumber(tokens).padStart(6)} / ${
|
|
316
|
-
const
|
|
317
|
-
const
|
|
316
|
+
const tokCol = `${formatNumber(tokens).padStart(6)} / ${formatNumber(max).padStart(6)}`;
|
|
317
|
+
const estimateMark = usage?.estimated ? ' est' : '';
|
|
318
|
+
const windowMark = usage?.contextWindowEstimated ? ' win?' : '';
|
|
319
|
+
const modelCol = usage?.model
|
|
320
|
+
? color(ANSI.dim, `${usage.model}${estimateMark}${windowMark}`)
|
|
321
|
+
: color(ANSI.dim, '(未取得)');
|
|
318
322
|
// 最終更新からの経過: 表示が「止まって見える」とき、それが idle なのか障害なのかを
|
|
319
323
|
// 即座に判別できるようにする。updatedAt は state.writeSessionState 時の Date.now()。
|
|
320
324
|
// 位置は session id の直後(左寄せ固定幅)。狭いターミナルでもモデル名より先に
|
|
@@ -325,7 +329,7 @@ function formatLine({ state, usage, isActive, now = Date.now() }) {
|
|
|
325
329
|
// 8 セル固定: "just now" が最長 (8 セル)、"99d ago" は 7 セル。括弧なしで OK
|
|
326
330
|
const agoCol = color(ANSI.dim, padCellsEnd(agoText, 8));
|
|
327
331
|
|
|
328
|
-
return `${marker} ${projectCol} ${idCol} ${agoCol} ${barCol} ${tokCol} ${
|
|
332
|
+
return `${marker} ${projectCol} ${hostCol} ${idCol} ${agoCol} ${barCol} ${tokCol} ${modelCol}${warn}`;
|
|
329
333
|
}
|
|
330
334
|
|
|
331
335
|
// --- フィルタ ---
|
|
@@ -428,8 +432,8 @@ function renderFrame(args) {
|
|
|
428
432
|
for (let i = 0; i < filtered.length; i++) {
|
|
429
433
|
const state = filtered[i];
|
|
430
434
|
// Stop hook が state.usage に固定値を入れていればそれを使う(JSONL 再スキャン不要)。
|
|
431
|
-
// 旧バージョンが書いた state や usage スナップショットが取れなかったターンでは
|
|
432
|
-
// transcriptPath
|
|
435
|
+
// 旧バージョンが書いた Claude state や usage スナップショットが取れなかったターンでは
|
|
436
|
+
// transcriptPath を直読。state 側の情報が 1 本化されると
|
|
433
437
|
// 「state が古い JSONL を指している」時の表示ブレが減る。
|
|
434
438
|
const usage = state.usage
|
|
435
439
|
?? (state.transcriptPath ? readLatestUsage(state.transcriptPath) : null);
|
|
@@ -254,6 +254,10 @@ test('renderBar: ratio=0 は全部 ░', () => {
|
|
|
254
254
|
assert.equal(renderBar(0, 5), '░░░░░');
|
|
255
255
|
});
|
|
256
256
|
|
|
257
|
+
test('renderBar: default width は 10 セル', () => {
|
|
258
|
+
assert.equal(renderBar(0.5), '█████░░░░░');
|
|
259
|
+
});
|
|
260
|
+
|
|
257
261
|
test('renderBar: ratio=1 は全部 █', () => {
|
|
258
262
|
assert.equal(renderBar(1, 5), '█████');
|
|
259
263
|
});
|
|
@@ -287,6 +291,7 @@ function makeLineArgs(ratio) {
|
|
|
287
291
|
return {
|
|
288
292
|
state: {
|
|
289
293
|
sessionId: 'abc12345-xxxx',
|
|
294
|
+
host: 'claude',
|
|
290
295
|
projectPath: '/tmp/foo',
|
|
291
296
|
transcriptPath: null,
|
|
292
297
|
updatedAt: Date.now(),
|
|
@@ -303,11 +308,33 @@ function makeLineArgs(ratio) {
|
|
|
303
308
|
|
|
304
309
|
test('formatLine: 70% 未満は警告テキストなし', () => {
|
|
305
310
|
const out = stripColors(formatLine(makeLineArgs(0.5)));
|
|
311
|
+
assert.ok(out.includes('Claude'));
|
|
312
|
+
assert.ok(out.includes('100.0k / 200.0k'));
|
|
313
|
+
assert.ok(!out.includes('残'));
|
|
314
|
+
assert.ok(!out.includes('/ 50%'));
|
|
306
315
|
assert.ok(!out.includes('!!'));
|
|
307
316
|
assert.ok(!out.includes('! '));
|
|
308
317
|
assert.ok(!out.includes('/tl'));
|
|
309
318
|
});
|
|
310
319
|
|
|
320
|
+
test('formatLine: Codex estimated usage は host と est marker を表示する', () => {
|
|
321
|
+
const args = makeLineArgs(0.5);
|
|
322
|
+
args.state.host = 'codex';
|
|
323
|
+
args.usage = {
|
|
324
|
+
tokens: 100_000,
|
|
325
|
+
model: 'codex',
|
|
326
|
+
contextWindowSize: 200_000,
|
|
327
|
+
contextWindowEstimated: true,
|
|
328
|
+
outputTokens: 0,
|
|
329
|
+
estimated: true,
|
|
330
|
+
source: 'codex-rollout-chars-div-4',
|
|
331
|
+
};
|
|
332
|
+
const out = stripColors(formatLine(args));
|
|
333
|
+
assert.ok(out.includes('Codex'));
|
|
334
|
+
assert.ok(out.includes('100.0k / 200.0k'));
|
|
335
|
+
assert.ok(out.includes('codex est win?'));
|
|
336
|
+
});
|
|
337
|
+
|
|
311
338
|
test('formatLine: 70% 以上で "!" マーカーと弱めの文言', () => {
|
|
312
339
|
const out = stripColors(formatLine(makeLineArgs(0.75)));
|
|
313
340
|
assert.ok(out.includes('!'), 'should include ! marker');
|