throughline 0.10.0 → 0.10.1
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/CHANGELOG.md +24 -1
- package/package.json +1 -1
- package/src/auditor-context.mjs +2 -1
- package/src/cli/codex-handoff-start.mjs +5 -23
- package/src/cli/codex-summarize.mjs +2 -1
- package/src/cli/codex-visibility-smoke.mjs +5 -4
- package/src/cli/grok-continue.mjs +8 -21
- package/src/cli/runtime-errors.test.mjs +1 -1
- package/src/codex-capture.mjs +14 -18
- package/src/codex-handoff-model-smoke.mjs +1 -1
- package/src/codex-sidecar.mjs +1 -1
- package/src/completed-turn-receipts.mjs +2 -29
- package/src/completed-turn-receipts.test.mjs +1 -1
- package/src/haiku-summarizer.mjs +1 -1
- package/src/handoff-record.mjs +3 -1
- package/src/hosts/claude.mjs +27 -0
- package/src/hosts/codex.mjs +28 -0
- package/src/hosts/grok.mjs +96 -0
- package/src/{hook-envelope.test.mjs → hosts/grok.test.mjs} +1 -1
- package/src/hosts/identity.mjs +71 -0
- package/src/hosts/identity.test.mjs +65 -0
- package/src/hosts/index.mjs +37 -0
- package/src/os/macos-terminal.mjs +44 -0
- package/src/os/open-url.mjs +16 -0
- package/src/os/paths.mjs +12 -0
- package/src/os/shell.mjs +16 -0
- package/src/os/windows-acl.mjs +57 -0
- package/src/project-path.mjs +4 -4
- package/src/prompt-submit.mjs +23 -55
- package/src/prompt-submit.test.mjs +27 -10
- package/src/runtime-error-hook.test.mjs +1 -1
- package/src/runtime-error-store.mjs +3 -40
- package/src/runtime-error-store.test.mjs +1 -1
- package/src/session-start.mjs +12 -4
- package/src/state-file.mjs +6 -5
- package/src/token-monitor.mjs +7 -6
- package/src/turn-processor.mjs +2 -2
- package/src/hook-envelope.mjs +0 -51
- /package/src/{portable-spawn-sync.mjs → os/portable-spawn-sync.mjs} +0 -0
- /package/src/{portable-spawn-sync.test.mjs → os/portable-spawn-sync.test.mjs} +0 -0
- /package/src/{windows-acl-test-helper.mjs → os/windows-acl-test-helper.mjs} +0 -0
package/src/token-monitor.mjs
CHANGED
|
@@ -28,6 +28,7 @@ import { buildCodexMonitorUsage } from './codex-usage.mjs';
|
|
|
28
28
|
import { listCodexThreadCandidates } from './codex-thread-index.mjs';
|
|
29
29
|
import { readLatestUsage } from './transcript-usage.mjs';
|
|
30
30
|
import { startSizeQuery } from './terminal-size.mjs';
|
|
31
|
+
import { CODEX_HOST, CODEX_SESSION_PREFIX, codexSessionIdToThreadId } from './hosts/identity.mjs';
|
|
31
32
|
|
|
32
33
|
const REFRESH_MS = 1000;
|
|
33
34
|
// データ変化が無くても N ms ごとに再描画して「(24m ago)」表示を進める。
|
|
@@ -292,7 +293,7 @@ export function resolveColumns() {
|
|
|
292
293
|
function formatLine({ state, usage, isActive, now = Date.now() }) {
|
|
293
294
|
const project = basename(state.projectPath || '?');
|
|
294
295
|
const shortId = formatShortSessionId(state);
|
|
295
|
-
const host = state.host ===
|
|
296
|
+
const host = state.host === CODEX_HOST ? 'Codex' : state.host === 'unknown' ? 'Unknown' : 'Claude';
|
|
296
297
|
const tokens = usage?.tokens ?? 0;
|
|
297
298
|
const max = usage?.contextWindowSize ?? 200_000;
|
|
298
299
|
const ratio = max > 0 ? tokens / max : 0;
|
|
@@ -337,8 +338,8 @@ function formatLine({ state, usage, isActive, now = Date.now() }) {
|
|
|
337
338
|
|
|
338
339
|
function formatShortSessionId(state) {
|
|
339
340
|
const sessionId = String(state?.sessionId ?? '');
|
|
340
|
-
if (state?.host ===
|
|
341
|
-
return sessionId.slice(
|
|
341
|
+
if (state?.host === CODEX_HOST && sessionId.startsWith(CODEX_SESSION_PREFIX)) {
|
|
342
|
+
return (codexSessionIdToThreadId(sessionId) ?? '').slice(0, 8);
|
|
342
343
|
}
|
|
343
344
|
return sessionId.slice(0, 8);
|
|
344
345
|
}
|
|
@@ -372,7 +373,7 @@ function withLiveActivity(state, now = Date.now()) {
|
|
|
372
373
|
}
|
|
373
374
|
|
|
374
375
|
function resolveMonitorUsage(state) {
|
|
375
|
-
if (state.host ===
|
|
376
|
+
if (state.host === CODEX_HOST && state.rolloutPath) {
|
|
376
377
|
return buildCodexMonitorUsage(state.rolloutPath) ?? state.usage ?? null;
|
|
377
378
|
}
|
|
378
379
|
if (state.transcriptPath) {
|
|
@@ -410,8 +411,8 @@ function discoverCodexSessionStates(args = {}, cwd = process.cwd()) {
|
|
|
410
411
|
|
|
411
412
|
lastCodexDiscoveryError = null;
|
|
412
413
|
return candidates.map((candidate) => ({
|
|
413
|
-
sessionId:
|
|
414
|
-
host:
|
|
414
|
+
sessionId: `${CODEX_SESSION_PREFIX}${candidate.id}`,
|
|
415
|
+
host: CODEX_HOST,
|
|
415
416
|
projectPath: normalizeProjectPath(candidate.cwd ?? cwd),
|
|
416
417
|
transcriptPath: null,
|
|
417
418
|
rolloutPath: candidate.rolloutPath,
|
package/src/turn-processor.mjs
CHANGED
|
@@ -46,7 +46,7 @@ import { readLatestUsage } from './transcript-usage.mjs';
|
|
|
46
46
|
import { pathToFileURL } from 'node:url';
|
|
47
47
|
import { recordRuntimeErrorBestEffort } from './runtime-error-store.mjs';
|
|
48
48
|
import { writeCompletedTurnReceipt } from './completed-turn-receipts.mjs';
|
|
49
|
-
import { normalizeHookPayload } from './
|
|
49
|
+
import { hostAdapterForSessionId, normalizeHookPayload } from './hosts/index.mjs';
|
|
50
50
|
|
|
51
51
|
/** 直近 N ターンは bodies を生で残し、それより古いものだけ L1 要約する。 */
|
|
52
52
|
export const L2_WINDOW = 20;
|
|
@@ -205,7 +205,7 @@ export async function run() {
|
|
|
205
205
|
process.stderr.write(`[vscode-task] ${msg}\n`);
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
if (
|
|
208
|
+
if (hostAdapterForSessionId(session_id).waitsForStopTranscriptFlush) {
|
|
209
209
|
await waitForClaudeStopTranscriptFlush({
|
|
210
210
|
transcriptPath: transcript_path,
|
|
211
211
|
lastAssistantMessage: last_assistant_message,
|
package/src/hook-envelope.mjs
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
// Grok sends Claude-compatible hook commands with a camelCase wire
|
|
2
|
-
// (sessionId, hookEventName) and no session_id. Throughline treats that
|
|
3
|
-
// envelope as host=grok: normalize to the Claude snake_case contract and
|
|
4
|
-
// prefix session ids so they never mix with Claude predecessor search.
|
|
5
|
-
import { homedir } from 'node:os';
|
|
6
|
-
import { join } from 'node:path';
|
|
7
|
-
|
|
8
|
-
export const GROK_SESSION_PREFIX = 'grok:';
|
|
9
|
-
|
|
10
|
-
export function isGrokEnvelope(payload) {
|
|
11
|
-
return payload !== null
|
|
12
|
-
&& typeof payload === 'object'
|
|
13
|
-
&& typeof payload.sessionId === 'string'
|
|
14
|
-
&& payload.sessionId.length > 0
|
|
15
|
-
&& typeof payload.hookEventName === 'string'
|
|
16
|
-
&& payload.hookEventName.length > 0
|
|
17
|
-
&& !Object.hasOwn(payload, 'session_id');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function grokBareSessionId(sessionId) {
|
|
21
|
-
if (typeof sessionId !== 'string' || sessionId.length === 0) return null;
|
|
22
|
-
return sessionId.startsWith(GROK_SESSION_PREFIX)
|
|
23
|
-
? sessionId.slice(GROK_SESSION_PREFIX.length)
|
|
24
|
-
: sessionId;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function deriveGrokChatHistoryPath(projectPath, sessionId, { home = homedir() } = {}) {
|
|
28
|
-
const bare = grokBareSessionId(sessionId);
|
|
29
|
-
if (!projectPath || !bare) return null;
|
|
30
|
-
return join(home, '.grok', 'sessions', encodeURIComponent(projectPath), bare, 'chat_history.jsonl');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function normalizeHookPayload(payload, { home = homedir() } = {}) {
|
|
34
|
-
if (!isGrokEnvelope(payload)) return payload;
|
|
35
|
-
const cwd = typeof payload.cwd === 'string' && payload.cwd.length > 0
|
|
36
|
-
? payload.cwd
|
|
37
|
-
: (typeof payload.workspaceRoot === 'string' ? payload.workspaceRoot : undefined);
|
|
38
|
-
// Live Grok Stop sets transcriptPath to updates.jsonl (sessionUpdate frames,
|
|
39
|
-
// no user/assistant rows). L2 lives in chat_history.jsonl only.
|
|
40
|
-
const transcriptPath = deriveGrokChatHistoryPath(cwd, payload.sessionId, { home });
|
|
41
|
-
return {
|
|
42
|
-
...payload,
|
|
43
|
-
session_id: `${GROK_SESSION_PREFIX}${payload.sessionId}`,
|
|
44
|
-
cwd,
|
|
45
|
-
source: payload.source,
|
|
46
|
-
prompt: payload.prompt,
|
|
47
|
-
hook_event_name: payload.hookEventName,
|
|
48
|
-
transcript_path: transcriptPath,
|
|
49
|
-
last_assistant_message: payload.lastAssistantMessage,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|