throughline 0.10.15 → 0.10.16
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
CHANGED
|
@@ -10,6 +10,14 @@ shipped to npm but were not individually tagged on GitHub.
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
+
## [0.10.16] — 2026-09-07
|
|
14
|
+
|
|
15
|
+
### 修正
|
|
16
|
+
|
|
17
|
+
- WindowsのDesktop引き継ぎで、稼働中のアプリが使うCodex実行ファイルを選ぶようにした。
|
|
18
|
+
PATH上の古いCodexがデスクトップ版の設定を読めず、新規タスクの作成に失敗する問題を修正した。
|
|
19
|
+
- 引き継ぎ結果へCodex実行元を表示する。アプリの実体を特定できない場合は理由を出して停止する。
|
|
20
|
+
|
|
13
21
|
## [0.10.15] — 2026-09-06
|
|
14
22
|
|
|
15
23
|
### Fixed
|
|
@@ -1449,7 +1457,8 @@ two attempts, instrument first instead of patching again.
|
|
|
1449
1457
|
|
|
1450
1458
|
---
|
|
1451
1459
|
|
|
1452
|
-
[Unreleased]: https://github.com/kitepon/Throughline/compare/v0.10.
|
|
1460
|
+
[Unreleased]: https://github.com/kitepon/Throughline/compare/v0.10.16...HEAD
|
|
1461
|
+
[0.10.16]: https://github.com/kitepon/Throughline/compare/v0.10.15...v0.10.16
|
|
1453
1462
|
[0.10.15]: https://github.com/kitepon/Throughline/compare/v0.10.14...v0.10.15
|
|
1454
1463
|
[0.10.14]: https://github.com/kitepon/Throughline/compare/v0.10.13...v0.10.14
|
|
1455
1464
|
[0.10.13]: https://github.com/kitepon/Throughline/compare/v0.10.12...v0.10.13
|
package/README.md
CHANGED
|
@@ -638,6 +638,10 @@ opens the new task in Codex Desktop when invoked there, while preserving the
|
|
|
638
638
|
existing VS Code and CLI routes. The result reports both the requested and
|
|
639
639
|
resolved host. The installed `$throughline` skill passes the current Codex
|
|
640
640
|
surface explicitly so a persistent shell or PTY cannot redirect the handoff.
|
|
641
|
+
WindowsのDesktop引き継ぎは、稼働中のCodex Desktopが使う実行ファイルを選びます。
|
|
642
|
+
PATH上の別バージョンによる設定読取りエラーを避け、選んだ実行元を結果へ表示します。
|
|
643
|
+
Desktopを起動してから実行してください。実行ファイルが見つからない場合や、異なる実行ファイルの
|
|
644
|
+
Desktopが複数稼働している場合は理由を出して停止します。明示した`--codex-app-server-bin`は優先します。
|
|
641
645
|
The
|
|
642
646
|
individual commands remain available: validate the fresh-thread handoff with
|
|
643
647
|
`throughline codex-handoff-smoke --session codex:<thread-id>`, optionally audit
|
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@ import { sameProjectPath } from '../project-path.mjs';
|
|
|
9
9
|
import { shQuote } from '../os/shell.mjs';
|
|
10
10
|
import { openUrlWithOsHandler } from '../os/open-url.mjs';
|
|
11
11
|
import { runTerminalDoScript } from '../os/macos-terminal.mjs';
|
|
12
|
+
import { resolveCodexRuntime } from '../os/codex-runtime.mjs';
|
|
12
13
|
|
|
13
14
|
async function readStdin() {
|
|
14
15
|
let raw = '';
|
|
@@ -242,6 +243,7 @@ function renderTextResult(result) {
|
|
|
242
243
|
lines.push(` execute: ${result.execute ? 'yes' : 'no'}`);
|
|
243
244
|
lines.push(` open requested: ${result.requestedOpenHost ?? result.openHost}`);
|
|
244
245
|
lines.push(` open resolved: ${result.resolvedOpenHost ?? result.open?.host ?? result.openHost}`);
|
|
246
|
+
if (result.runtime) lines.push(` Codex実行元: ${result.runtime.command} (${result.runtime.source})`);
|
|
245
247
|
lines.push(` handoff smoke: ${result.handoffSmoke.status}`);
|
|
246
248
|
lines.push(` prompt chars: ${result.handoffSmoke.promptChars}/${result.handoffSmoke.maxPromptChars}`);
|
|
247
249
|
lines.push(` model prompt: ${result.modelPromptChars}`);
|
|
@@ -452,11 +454,16 @@ export async function run(args) {
|
|
|
452
454
|
}
|
|
453
455
|
|
|
454
456
|
if (parsed.execute && result.status === 'ready') {
|
|
457
|
+
const runtime = resolveCodexRuntime({
|
|
458
|
+
host: result.resolvedOpenHost,
|
|
459
|
+
override: parsed.codexAppServerBin,
|
|
460
|
+
});
|
|
461
|
+
result.runtime = runtime;
|
|
455
462
|
const startResult = await runCodexNewThreadHandoff({
|
|
456
463
|
cwd: process.cwd(),
|
|
457
464
|
prompt: handoffPrompt,
|
|
458
|
-
command:
|
|
459
|
-
commandArgs:
|
|
465
|
+
command: runtime.command,
|
|
466
|
+
commandArgs: runtime.commandArgs,
|
|
460
467
|
timeoutMs: parsed.timeoutMs,
|
|
461
468
|
requestTimeoutMs: parsed.requestTimeoutMs,
|
|
462
469
|
waitForTurn: false,
|
|
@@ -310,6 +310,9 @@ test('codex-handoff-start execute creates a new app-server thread and can skip o
|
|
|
310
310
|
assert.equal(payload.startThreadManually, false);
|
|
311
311
|
assert.equal(payload.newThread.threadId, '019e2000-0000-7000-8000-000000000001');
|
|
312
312
|
assert.equal(payload.newThread.delivery, 'developer-item');
|
|
313
|
+
assert.equal(payload.runtime.command, script);
|
|
314
|
+
assert.equal(payload.runtime.source, 'explicit');
|
|
315
|
+
assert.deepEqual(payload.runtime.commandArgs, []);
|
|
313
316
|
assert.equal(payload.newThread.injectSent, true);
|
|
314
317
|
assert.equal(payload.newThread.turnStatus, 'not-started');
|
|
315
318
|
assert.equal(payload.open.status, 'skipped');
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { spawnPortableSync } from './portable-spawn-sync.mjs';
|
|
2
|
+
|
|
3
|
+
function discoverWindowsDesktopCodex() {
|
|
4
|
+
const result = spawnPortableSync('pwsh.exe', ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', `
|
|
5
|
+
$ErrorActionPreference = 'Stop'
|
|
6
|
+
$processes = @(Get-CimInstance Win32_Process)
|
|
7
|
+
$paths = @($processes | Where-Object { $_.Name -eq 'codex.exe' } | ForEach-Object {
|
|
8
|
+
$child = $_
|
|
9
|
+
$parent = $processes | Where-Object { $_.ProcessId -eq $child.ParentProcessId }
|
|
10
|
+
if ($parent.ExecutablePath -match '[\\\\/]OpenAI\\.Codex_[^\\\\/]+[\\\\/]app[\\\\/]ChatGPT\\.exe$' -and $child.ExecutablePath) {
|
|
11
|
+
$child.ExecutablePath
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
ConvertTo-Json -InputObject $paths -Compress
|
|
15
|
+
`], { encoding: 'utf8', timeout: 15000 });
|
|
16
|
+
if (result.error || result.status !== 0) {
|
|
17
|
+
throw new Error(`Codex Desktopの実行ファイルを取得できません: ${result.error?.message ?? result.stderr.trim()}`);
|
|
18
|
+
}
|
|
19
|
+
return JSON.parse(result.stdout.trim());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function resolveCodexRuntime({ host, override = null, platform = process.platform,
|
|
23
|
+
discover = discoverWindowsDesktopCodex } = {}) {
|
|
24
|
+
if (override) return { command: override, commandArgs: [], source: 'explicit' };
|
|
25
|
+
const commandArgs = ['app-server', '--listen', 'stdio://'];
|
|
26
|
+
if (platform !== 'win32' || host !== 'desktop') {
|
|
27
|
+
return { command: 'codex', commandArgs, source: 'path' };
|
|
28
|
+
}
|
|
29
|
+
const candidates = [...new Set(discover())];
|
|
30
|
+
if (candidates.length !== 1) {
|
|
31
|
+
throw new Error(candidates.length === 0
|
|
32
|
+
? '稼働中のCodex Desktopの実行ファイルが見つかりません。アプリを起動してから再実行してください。'
|
|
33
|
+
: '複数のCodex Desktop実行ファイルが稼働しています。使用するアプリだけを残して再実行してください。');
|
|
34
|
+
}
|
|
35
|
+
return { command: candidates[0], commandArgs, source: 'desktop-process' };
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { resolveCodexRuntime } from './codex-runtime.mjs';
|
|
4
|
+
|
|
5
|
+
test('Windows Desktopは稼働中アプリのCodexを使う', () => {
|
|
6
|
+
const runtime = resolveCodexRuntime({ platform: 'win32', host: 'desktop',
|
|
7
|
+
discover: () => ['C:\\Codex\\codex.exe', 'C:\\Codex\\codex.exe'] });
|
|
8
|
+
assert.equal(runtime.command, 'C:\\Codex\\codex.exe');
|
|
9
|
+
assert.deepEqual(runtime.commandArgs, ['app-server', '--listen', 'stdio://']);
|
|
10
|
+
assert.equal(runtime.source, 'desktop-process');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('明示したapp-serverはDesktopの探索より優先する', () => {
|
|
14
|
+
const runtime = resolveCodexRuntime({ platform: 'win32', host: 'desktop', override: 'fake.mjs',
|
|
15
|
+
discover: () => { throw new Error('探索してはいけない'); } });
|
|
16
|
+
assert.equal(runtime.command, 'fake.mjs');
|
|
17
|
+
assert.deepEqual(runtime.commandArgs, []);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('対象外のOSとhostは従来のCodexを使う', () => {
|
|
21
|
+
for (const [platform, host] of [['darwin', 'desktop'], ['win32', 'cli'], ['win32', 'vscode']]) {
|
|
22
|
+
assert.equal(resolveCodexRuntime({ platform, host }).command, 'codex');
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('Desktopの実体がない場合や複数ある場合は古いCLIへ切り替えない', () => {
|
|
27
|
+
for (const candidates of [[], ['C:\\one\\codex.exe', 'C:\\two\\codex.exe']]) {
|
|
28
|
+
assert.throws(() => resolveCodexRuntime({ platform: 'win32', host: 'desktop',
|
|
29
|
+
discover: () => candidates }), /Codex Desktop/);
|
|
30
|
+
}
|
|
31
|
+
});
|