nterminal 1.2.56 → 1.2.58

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.
Files changed (29) hide show
  1. package/dist/client/assets/MarkdownPreview-D-oOD4FK.js +1 -0
  2. package/dist/client/assets/{TranscriptMarkdownBody-CDKYjgIZ.js → TranscriptMarkdownBody-BDE5VmlN.js} +1 -1
  3. package/dist/client/assets/index-1p5j5ZUZ.js +54 -0
  4. package/dist/client/assets/{index-fsgQPmdV.js → index-DLVKSDlo.js} +1 -1
  5. package/dist/client/index.html +1 -1
  6. package/dist/server/auth/authService.d.ts +6 -3
  7. package/dist/server/auth/authService.js +80 -28
  8. package/dist/server/auth/authService.js.map +1 -1
  9. package/dist/server/storage/fileStore.d.ts +7 -0
  10. package/dist/server/storage/fileStore.js +10 -0
  11. package/dist/server/storage/fileStore.js.map +1 -1
  12. package/dist/server/terminal/TmuxPtyAdapter.d.ts +28 -2
  13. package/dist/server/terminal/TmuxPtyAdapter.js +295 -122
  14. package/dist/server/terminal/TmuxPtyAdapter.js.map +1 -1
  15. package/dist/server/terminal/codexTranscriptSource.d.ts +5 -0
  16. package/dist/server/terminal/codexTranscriptSource.js +140 -82
  17. package/dist/server/terminal/codexTranscriptSource.js.map +1 -1
  18. package/dist/server/terminal/procfs.d.ts +8 -0
  19. package/dist/server/terminal/procfs.js +113 -0
  20. package/dist/server/terminal/procfs.js.map +1 -0
  21. package/dist/server/terminal/sessionId.d.ts +3 -0
  22. package/dist/server/terminal/sessionId.js +10 -0
  23. package/dist/server/terminal/sessionId.js.map +1 -0
  24. package/dist/server/terminal/ttlCache.d.ts +8 -0
  25. package/dist/server/terminal/ttlCache.js +33 -0
  26. package/dist/server/terminal/ttlCache.js.map +1 -0
  27. package/package.json +1 -1
  28. package/dist/client/assets/MarkdownPreview-Bk02CJkU.js +0 -1
  29. package/dist/client/assets/index-BBVLYVi6.js +0 -54
@@ -1,9 +1,92 @@
1
1
  import { spawnSync } from 'node:child_process';
2
- import { existsSync, readFileSync } from 'node:fs';
2
+ import { existsSync, readFileSync, readdirSync, readlinkSync } from 'node:fs';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
+ import { isSessionId, sessionIdPatternSource } from './sessionId.js';
6
+ import { readProcessStartedAtSeconds } from './procfs.js';
7
+ import { TtlCache } from './ttlCache.js';
5
8
  const PROCESS_START_SKEW_SECONDS = 2;
6
- let cachedClockTicksPerSecond = null;
9
+ const LOOKUP_CACHE_SUCCESS_TTL_MS = 30_000;
10
+ // Must exceed the client's steady transcript-source poll cadence (15s in
11
+ // XtermPane); a shorter negative TTL guarantees every poll misses the cache
12
+ // and re-runs the event-loop-blocking sqlite3 shell-out.
13
+ const LOOKUP_CACHE_FAILURE_TTL_MS = 20_000;
14
+ // The optional middle segment keeps this in sync with the loose
15
+ // startsWith('rollout-')/endsWith('<id>.jsonl') checks used elsewhere — a
16
+ // rollout named without the timestamp segment must not silently bypass the
17
+ // fd scan while passing the other matchers.
18
+ const CODEX_ROLLOUT_FILE_PATTERN = new RegExp(`^rollout-(?:.*-)?(${sessionIdPatternSource})\\.jsonl$`);
19
+ const processLogLookupCache = new TtlCache();
20
+ export function clearCodexTranscriptLookupCache() {
21
+ processLogLookupCache.clear();
22
+ }
23
+ // The cheapest and most current mapping there is: the codex binary keeps its
24
+ // active rollout JSONL open O_WRONLY|O_APPEND for the whole session, so
25
+ // /proc/<pid>/fd names the exact file — no sqlite, and it follows thread
26
+ // switches (/new, resume) the moment codex reopens a different rollout.
27
+ // Write access is required so that transient read-only opens (codex browsing
28
+ // other sessions' history) are never mistaken for the live transcript.
29
+ // /proc/<pid>/fd is same-uid readable, the same constraint as the
30
+ // /proc/<pid>/environ and /cwd reads the adapter already relies on.
31
+ export function resolveCodexTranscriptFromOpenFds(pid, options = {}) {
32
+ if (!Number.isInteger(pid) || pid <= 0) {
33
+ return null;
34
+ }
35
+ const procRoot = options.procRoot ?? '/proc';
36
+ const fdDir = path.join(procRoot, String(pid), 'fd');
37
+ let fdNames;
38
+ try {
39
+ fdNames = readdirSync(fdDir);
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ const openRollouts = new Map();
45
+ for (const fdName of fdNames) {
46
+ let target;
47
+ try {
48
+ target = readlinkSync(path.join(fdDir, fdName));
49
+ }
50
+ catch {
51
+ continue;
52
+ }
53
+ if (target.endsWith(' (deleted)')) {
54
+ continue;
55
+ }
56
+ const match = CODEX_ROLLOUT_FILE_PATTERN.exec(path.basename(target));
57
+ if (!match || !isFdOpenForWriting(procRoot, pid, fdName)) {
58
+ continue;
59
+ }
60
+ openRollouts.set(match[1], target);
61
+ }
62
+ if (openRollouts.size !== 1) {
63
+ return null;
64
+ }
65
+ const [sessionId, filePath] = [...openRollouts.entries()][0];
66
+ if (!existsSync(filePath)) {
67
+ return null;
68
+ }
69
+ return { provider: 'codex', sessionId, filePath };
70
+ }
71
+ function isFdOpenForWriting(procRoot, pid, fdName) {
72
+ let raw;
73
+ try {
74
+ raw = readFileSync(path.join(procRoot, String(pid), 'fdinfo', fdName), 'utf8');
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ const line = raw.split('\n').find((candidate) => candidate.startsWith('flags:'));
80
+ if (!line) {
81
+ return false;
82
+ }
83
+ const flags = parseInt(line.slice('flags:'.length).trim(), 8);
84
+ if (!Number.isFinite(flags)) {
85
+ return false;
86
+ }
87
+ const accessMode = flags & 0o3;
88
+ return accessMode === 0o1 || accessMode === 0o2;
89
+ }
7
90
  export function resolveCodexTranscriptFromProcessLogs(pid, options = {}) {
8
91
  if (!Number.isInteger(pid) || pid <= 0) {
9
92
  return null;
@@ -21,19 +104,48 @@ export function resolveCodexTranscriptFromProcessLogs(pid, options = {}) {
21
104
  if (processStartedAtSeconds === null) {
22
105
  return null;
23
106
  }
107
+ // The sqlite3 shell-out is bounded by a 1s kill timer and blocks the event
108
+ // loop while it runs, so successful and failed lookups are both cached.
109
+ // The db path is part of the key because it is what the lookup actually
110
+ // reads; pid + start time identify the process across pid reuse.
111
+ const cacheKey = `${logsDb}:${pid}:${processStartedAtSeconds}`;
112
+ const cached = processLogLookupCache.get(cacheKey);
113
+ if (cached) {
114
+ return cached.value;
115
+ }
116
+ const source = lookupCodexTranscriptInProcessLogs(pid, logsDb, stateDb, processStartedAtSeconds, options.runSqlite);
117
+ processLogLookupCache.set(cacheKey, source, source ? LOOKUP_CACHE_SUCCESS_TTL_MS : LOOKUP_CACHE_FAILURE_TTL_MS);
118
+ return source;
119
+ }
120
+ function lookupCodexTranscriptInProcessLogs(pid, logsDb, stateDb, processStartedAtSeconds, runSqliteOverride) {
24
121
  const minLogSeconds = Math.max(0, Math.floor(processStartedAtSeconds) - PROCESS_START_SKEW_SECONDS);
25
- const output = (options.runSqlite ?? runSqlite)(logsDb, [
122
+ // Driven from the small threads table with an indexed probe into logs per
123
+ // thread. The previous shape walked the ts index across every process's
124
+ // rows from the cutoff onward, evaluating process_uuid LIKE row by row
125
+ // over the whole log table — measured 7.2s cold / 0.5s warm on a 63MB log
126
+ // db, routinely overrunning the 1s sqlite timeout.
127
+ //
128
+ // last_ts (the newest log this pid wrote into each thread) preserves the
129
+ // old query's recency semantics: a process that switched threads (/new)
130
+ // has logged into several, and the one it touched most recently is the
131
+ // live one. Requiring global uniqueness instead would go permanently
132
+ // ambiguous after the first /new.
133
+ const output = (runSqliteOverride ?? runSqlite)(logsDb, [
26
134
  `ATTACH DATABASE ${sqlString(stateDb)} AS state;`,
27
- "SELECT l.thread_id || char(9) || state.threads.rollout_path",
28
- 'FROM logs l',
29
- 'JOIN state.threads ON state.threads.id = l.thread_id',
30
- `WHERE l.process_uuid LIKE ${sqlString(`pid:${pid}:%`)}`,
31
- 'AND l.thread_id IS NOT NULL',
32
- `AND l.ts >= ${minLogSeconds}`,
33
- "AND state.threads.source = 'cli'",
34
- "AND state.threads.model_provider = 'openai'",
35
- 'AND state.threads.rollout_path IS NOT NULL',
36
- 'ORDER BY l.ts DESC, l.ts_nanos DESC, l.id DESC',
135
+ 'SELECT id || char(9) || rollout_path || char(9) || last_ts FROM (',
136
+ ' SELECT t.id AS id, t.rollout_path AS rollout_path, (',
137
+ ' SELECT MAX(l.ts) FROM logs l',
138
+ ' WHERE l.thread_id = t.id',
139
+ ` AND l.ts >= ${minLogSeconds}`,
140
+ ` AND l.process_uuid LIKE ${sqlString(`pid:${pid}:%`)}`,
141
+ ' ) AS last_ts',
142
+ ' FROM state.threads t',
143
+ " WHERE t.source = 'cli'",
144
+ " AND t.model_provider = 'openai'",
145
+ ' AND t.rollout_path IS NOT NULL',
146
+ ')',
147
+ 'WHERE last_ts IS NOT NULL',
148
+ 'ORDER BY last_ts DESC',
37
149
  'LIMIT 50;'
38
150
  ].join('\n'));
39
151
  if (output === null) {
@@ -44,25 +156,30 @@ export function resolveCodexTranscriptFromProcessLogs(pid, options = {}) {
44
156
  const trimmed = line.trim();
45
157
  if (!trimmed)
46
158
  continue;
47
- const separator = trimmed.indexOf('\t');
48
- if (separator === -1)
159
+ const [sessionId, filePath, lastTsRaw] = trimmed.split('\t');
160
+ if (!sessionId || !filePath)
49
161
  continue;
50
- const sessionId = trimmed.slice(0, separator);
51
- const filePath = trimmed.slice(separator + 1);
52
162
  if (!isSessionId(sessionId) || !isCodexRolloutPath(filePath, sessionId) || !existsSync(filePath)) {
53
163
  continue;
54
164
  }
55
- matches.set(sessionId, filePath);
165
+ const lastLogSeconds = Number(lastTsRaw);
166
+ const normalized = Number.isFinite(lastLogSeconds) ? lastLogSeconds : 0;
167
+ const existing = matches.get(sessionId);
168
+ if (!existing || existing.lastLogSeconds < normalized) {
169
+ matches.set(sessionId, { filePath, lastLogSeconds: normalized });
170
+ }
56
171
  }
57
- if (matches.size !== 1) {
172
+ if (matches.size === 0) {
58
173
  return null;
59
174
  }
60
- const [entry] = matches.entries();
61
- if (!entry) {
175
+ const ranked = [...matches.entries()].sort((a, b) => b[1].lastLogSeconds - a[1].lastLogSeconds);
176
+ if (ranked.length > 1 && ranked[0][1].lastLogSeconds <= ranked[1][1].lastLogSeconds) {
177
+ // Two threads with equally recent activity (1s log granularity) — there
178
+ // is no safe winner, so refuse rather than guess.
62
179
  return null;
63
180
  }
64
- const [sessionId, filePath] = entry;
65
- return { provider: 'codex', sessionId, filePath };
181
+ const [sessionId, entry] = ranked[0];
182
+ return { provider: 'codex', sessionId, filePath: entry.filePath };
66
183
  }
67
184
  function runSqlite(databasePath, sql) {
68
185
  const result = spawnSync('sqlite3', ['-batch', '-noheader', databasePath, sql], {
@@ -75,69 +192,10 @@ function runSqlite(databasePath, sql) {
75
192
  }
76
193
  return result.stdout;
77
194
  }
78
- function readProcessStartedAtSeconds(pid) {
79
- const bootTime = readBootTimeSeconds();
80
- const clockTicks = readClockTicksPerSecond();
81
- if (bootTime === null || clockTicks === null) {
82
- return null;
83
- }
84
- let raw;
85
- try {
86
- raw = readFileSync(`/proc/${pid}/stat`, 'utf8');
87
- }
88
- catch {
89
- return null;
90
- }
91
- const closeParen = raw.lastIndexOf(')');
92
- if (closeParen === -1) {
93
- return null;
94
- }
95
- const fieldsAfterCommand = raw.slice(closeParen + 2).trim().split(/\s+/);
96
- const startTicksRaw = fieldsAfterCommand[19];
97
- const startTicks = Number(startTicksRaw);
98
- if (!Number.isFinite(startTicks) || startTicks < 0) {
99
- return null;
100
- }
101
- return bootTime + startTicks / clockTicks;
102
- }
103
- function readBootTimeSeconds() {
104
- let raw;
105
- try {
106
- raw = readFileSync('/proc/stat', 'utf8');
107
- }
108
- catch {
109
- return null;
110
- }
111
- const line = raw.split('\n').find((entry) => entry.startsWith('btime '));
112
- if (!line) {
113
- return null;
114
- }
115
- const bootTime = Number(line.slice('btime '.length).trim());
116
- return Number.isFinite(bootTime) && bootTime > 0 ? bootTime : null;
117
- }
118
- function readClockTicksPerSecond() {
119
- if (cachedClockTicksPerSecond !== null) {
120
- return cachedClockTicksPerSecond;
121
- }
122
- const result = spawnSync('getconf', ['CLK_TCK'], {
123
- stdio: ['ignore', 'pipe', 'ignore'],
124
- encoding: 'utf8',
125
- timeout: 1000
126
- });
127
- const ticks = Number(result.stdout.trim());
128
- if (!Number.isFinite(ticks) || ticks <= 0) {
129
- return null;
130
- }
131
- cachedClockTicksPerSecond = ticks;
132
- return ticks;
133
- }
134
195
  function isCodexRolloutPath(filePath, sessionId) {
135
196
  const base = path.basename(filePath);
136
197
  return base.startsWith('rollout-') && base.endsWith(`${sessionId}.jsonl`);
137
198
  }
138
- function isSessionId(value) {
139
- return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(value);
140
- }
141
199
  function sqlString(value) {
142
200
  return `'${value.replace(/'/g, "''")}'`;
143
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"codexTranscriptSource.js","sourceRoot":"","sources":["../../../src/server/terminal/codexTranscriptSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAW7B,MAAM,0BAA0B,GAAG,CAAC,CAAC;AACrC,IAAI,yBAAyB,GAAkB,IAAI,CAAC;AAEpD,MAAM,UAAU,qCAAqC,CACnD,GAAW,EACX,UAA2C,EAAE;IAE7C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IACtD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,uBAAuB,GAC3B,OAAO,CAAC,uBAAuB,KAAK,SAAS;QAC3C,CAAC,CAAC,OAAO,CAAC,uBAAuB;QACjC,CAAC,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,uBAAuB,KAAK,IAAI,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,GAAG,0BAA0B,CAAC,CAAC;IACpG,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,CAC7C,MAAM,EACN;QACE,mBAAmB,SAAS,CAAC,OAAO,CAAC,YAAY;QACjD,6DAA6D;QAC7D,aAAa;QACb,sDAAsD;QACtD,6BAA6B,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE;QACxD,6BAA6B;QAC7B,eAAe,aAAa,EAAE;QAC9B,kCAAkC;QAClC,6CAA6C;QAC7C,4CAA4C;QAC5C,gDAAgD;QAChD,WAAW;KACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,SAAS,KAAK,CAAC,CAAC;YAAE,SAAS;QAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjG,SAAS;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC;IACpC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,SAAS,CAAC,YAAoB,EAAE,GAAW;IAClD,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE;QAC9E,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;QACjC,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED,SAAS,2BAA2B,CAAC,GAAW;IAC9C,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,MAAM,UAAU,GAAG,uBAAuB,EAAE,CAAC;IAC7C,IAAI,QAAQ,KAAK,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,CAAC;IACR,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,SAAS,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,kBAAkB,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzE,MAAM,aAAa,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAC5C,CAAC;AAED,SAAS,mBAAmB;IAC1B,IAAI,GAAG,CAAC;IACR,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACrE,CAAC;AAED,SAAS,uBAAuB;IAC9B,IAAI,yBAAyB,KAAK,IAAI,EAAE,CAAC;QACvC,OAAO,yBAAyB,CAAC;IACnC,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE;QAC/C,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;QACnC,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,yBAAyB,GAAG,KAAK,CAAC;IAClC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB,EAAE,SAAiB;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,+EAA+E,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrG,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"codexTranscriptSource.js","sourceRoot":"","sources":["../../../src/server/terminal/codexTranscriptSource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare function readProcessStartTicks(pid: number): string | null;
2
+ export declare function processStartTicksToSeconds(startTicks: string | null): number | null;
3
+ export declare function readProcessStartedAtSeconds(pid: number): number | null;
4
+ export declare function readProcessStartedAtMilliseconds(pid: number): number | null;
5
+ export declare function readBootTimeSeconds(): number | null;
6
+ export declare function readClockTicksPerSecond(): number | null;
7
+ export declare function readProcessCwd(pid: number): string | null;
8
+ export declare function readProcessEnvValues(pid: number, keys: readonly string[]): Map<string, string>;
@@ -0,0 +1,113 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { readFileSync, readlinkSync } from 'node:fs';
3
+ // Shared /proc readers for the transcript resolvers. The stat field-22 parse
4
+ // is subtle (comm may contain spaces and parens, hence the lastIndexOf(')')
5
+ // anchor), so it lives in exactly one place: both Claude registry pid-reuse
6
+ // detection and Codex process-log time bounds depend on the same definition.
7
+ let cachedClockTicksPerSecond = null;
8
+ // /proc/<pid>/stat field 22 (starttime) as the raw tick string. Returned
9
+ // unconverted because Claude's session registry stores the same value
10
+ // verbatim — string equality is the most faithful comparison.
11
+ export function readProcessStartTicks(pid) {
12
+ let raw;
13
+ try {
14
+ raw = readFileSync(`/proc/${pid}/stat`, 'utf8');
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ const closeParen = raw.lastIndexOf(')');
20
+ if (closeParen === -1) {
21
+ return null;
22
+ }
23
+ const fieldsAfterCommand = raw.slice(closeParen + 2).trim().split(/\s+/);
24
+ const startTicks = fieldsAfterCommand[19];
25
+ return startTicks && /^\d+$/.test(startTicks) ? startTicks : null;
26
+ }
27
+ // null stays null: a failed stat read must not degrade into "started at
28
+ // boot" (Number(null) === 0), which would silently change downstream
29
+ // mtime-plausibility filtering.
30
+ export function processStartTicksToSeconds(startTicks) {
31
+ if (startTicks === null) {
32
+ return null;
33
+ }
34
+ const bootTime = readBootTimeSeconds();
35
+ const clockTicks = readClockTicksPerSecond();
36
+ if (bootTime === null || clockTicks === null) {
37
+ return null;
38
+ }
39
+ return bootTime + Number(startTicks) / clockTicks;
40
+ }
41
+ export function readProcessStartedAtSeconds(pid) {
42
+ return processStartTicksToSeconds(readProcessStartTicks(pid));
43
+ }
44
+ export function readProcessStartedAtMilliseconds(pid) {
45
+ const seconds = readProcessStartedAtSeconds(pid);
46
+ return seconds === null ? null : seconds * 1000;
47
+ }
48
+ export function readBootTimeSeconds() {
49
+ let raw;
50
+ try {
51
+ raw = readFileSync('/proc/stat', 'utf8');
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ const line = raw.split('\n').find((entry) => entry.startsWith('btime '));
57
+ if (!line) {
58
+ return null;
59
+ }
60
+ const bootTime = Number(line.slice('btime '.length).trim());
61
+ return Number.isFinite(bootTime) && bootTime > 0 ? bootTime : null;
62
+ }
63
+ export function readClockTicksPerSecond() {
64
+ if (cachedClockTicksPerSecond !== null) {
65
+ return cachedClockTicksPerSecond;
66
+ }
67
+ const result = spawnSync('getconf', ['CLK_TCK'], {
68
+ stdio: ['ignore', 'pipe', 'ignore'],
69
+ encoding: 'utf8',
70
+ timeout: 1000
71
+ });
72
+ const ticks = Number(result.stdout?.trim());
73
+ if (!Number.isFinite(ticks) || ticks <= 0) {
74
+ return null;
75
+ }
76
+ cachedClockTicksPerSecond = ticks;
77
+ return ticks;
78
+ }
79
+ export function readProcessCwd(pid) {
80
+ try {
81
+ return readlinkSync(`/proc/${pid}/cwd`);
82
+ }
83
+ catch {
84
+ return null;
85
+ }
86
+ }
87
+ // One environ read serving several keys — the buffer is commonly multiple KB
88
+ // and per-key callers used to re-read and re-split it for every variable.
89
+ export function readProcessEnvValues(pid, keys) {
90
+ const out = new Map();
91
+ let raw;
92
+ try {
93
+ raw = readFileSync(`/proc/${pid}/environ`, 'utf8');
94
+ }
95
+ catch {
96
+ return out;
97
+ }
98
+ for (const entry of raw.split('\0')) {
99
+ const separator = entry.indexOf('=');
100
+ if (separator === -1) {
101
+ continue;
102
+ }
103
+ const key = entry.slice(0, separator);
104
+ if (keys.includes(key) && !out.has(key)) {
105
+ const value = entry.slice(separator + 1);
106
+ if (value) {
107
+ out.set(key, value);
108
+ }
109
+ }
110
+ }
111
+ return out;
112
+ }
113
+ //# sourceMappingURL=procfs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procfs.js","sourceRoot":"","sources":["../../../src/server/terminal/procfs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const sessionIdPatternSource = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
2
+ export declare const SESSION_ID_PATTERN: RegExp;
3
+ export declare function isSessionId(value: string | undefined): value is string;
@@ -0,0 +1,10 @@
1
+ // Single source of truth for the UUID shape Codex thread ids and Claude
2
+ // session ids share. Both resolvers and the rollout-filename pattern build on
3
+ // this so the definition can never drift between code paths (a drift would
4
+ // make the same pane resolve through one mechanism and fail through another).
5
+ export const sessionIdPatternSource = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
6
+ export const SESSION_ID_PATTERN = new RegExp(`^${sessionIdPatternSource}$`);
7
+ export function isSessionId(value) {
8
+ return typeof value === 'string' && SESSION_ID_PATTERN.test(value);
9
+ }
10
+ //# sourceMappingURL=sessionId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionId.js","sourceRoot":"","sources":["../../../src/server/terminal/sessionId.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,8EAA8E;AAC9E,2EAA2E;AAC3E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GACjC,6EAA6E,CAAC;AAEhF,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,MAAM,CAAC,IAAI,sBAAsB,GAAG,CAAC,CAAC;AAE5E,MAAM,UAAU,WAAW,CAAC,KAAyB;IACnD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare class TtlCache<V> {
2
+ private readonly entries;
3
+ get(key: string): {
4
+ value: V;
5
+ } | null;
6
+ set(key: string, value: V, ttlMs: number): void;
7
+ clear(): void;
8
+ }
@@ -0,0 +1,33 @@
1
+ // Tiny TTL map used by the transcript resolvers. Unlike a bare Map with
2
+ // expiresAt fields, expired entries are actually removed — on read of the
3
+ // expired key and by a sweep on every write — so long-lived servers don't
4
+ // accumulate one dead entry per Claude /clear or per Codex process forever.
5
+ // `get` returns a wrapper object so cached `null` values (negative results)
6
+ // are distinguishable from a cache miss.
7
+ export class TtlCache {
8
+ entries = new Map();
9
+ get(key) {
10
+ const entry = this.entries.get(key);
11
+ if (!entry) {
12
+ return null;
13
+ }
14
+ if (entry.expiresAt <= Date.now()) {
15
+ this.entries.delete(key);
16
+ return null;
17
+ }
18
+ return { value: entry.value };
19
+ }
20
+ set(key, value, ttlMs) {
21
+ const now = Date.now();
22
+ for (const [existingKey, entry] of this.entries) {
23
+ if (entry.expiresAt <= now) {
24
+ this.entries.delete(existingKey);
25
+ }
26
+ }
27
+ this.entries.set(key, { expiresAt: now + ttlMs, value });
28
+ }
29
+ clear() {
30
+ this.entries.clear();
31
+ }
32
+ }
33
+ //# sourceMappingURL=ttlCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ttlCache.js","sourceRoot":"","sources":["../../../src/server/terminal/ttlCache.ts"],"names":[],"mappings":"AAKA,wEAAwE;AACxE,0EAA0E;AAC1E,0EAA0E;AAC1E,4EAA4E;AAC5E,4EAA4E;AAC5E,yCAAyC;AACzC,MAAM,OAAO,QAAQ;IACF,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE/D,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,KAAa;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAChD,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nterminal",
3
- "version": "1.2.56",
3
+ "version": "1.2.58",
4
4
  "license": "GPL-3.0-only",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.7",
@@ -1 +0,0 @@
1
- import{j as a}from"./index-BBVLYVi6.js";import{M as e,r as o}from"./index-fsgQPmdV.js";function s({content:r}){return a.jsx(e,{remarkPlugins:[o],children:r})}export{s as default};