cdx-cli 0.1.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/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/commands/run.d.ts +5 -0
- package/dist/commands/run.js +71 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/core/event-handler.d.ts +5 -0
- package/dist/core/event-handler.js +72 -0
- package/dist/core/event-handler.js.map +1 -0
- package/dist/core/session.d.ts +3 -0
- package/dist/core/session.js +111 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/trace-writer.d.ts +5 -0
- package/dist/core/trace-writer.js +36 -0
- package/dist/core/trace-writer.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Masao
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# cdx-cli
|
|
2
|
+
|
|
3
|
+
Codex SDK を使ってローカルの作業ディレクトリに対して実行する、シンプルな CLI ラッパーです。
|
|
4
|
+
|
|
5
|
+
## 前提
|
|
6
|
+
|
|
7
|
+
- Node.js 20+
|
|
8
|
+
- npm
|
|
9
|
+
- OpenAI API キー(例: `OPENAI_API_KEY`)
|
|
10
|
+
|
|
11
|
+
## インストール
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm i -g cdx-cli
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 使い方
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cdx-cli run -w <workdir> "やってほしいこと"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
例:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cdx-cli run -w /Users/masao/project/my-app "テストを実行して失敗を直して"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## コマンド
|
|
30
|
+
|
|
31
|
+
`cdx-cli run [options] "prompt"`
|
|
32
|
+
|
|
33
|
+
オプション:
|
|
34
|
+
|
|
35
|
+
- `--workdir, -w <path>`: 作業ディレクトリ(必須)
|
|
36
|
+
- `--instructions, -i <path>`: 追加指示を読み込むテキストファイル
|
|
37
|
+
- `--trace-file <path>`: トレースJSONの出力先
|
|
38
|
+
- `--agent-id <id>`: トレースへ記録する任意のエージェントID
|
|
39
|
+
- `--model, -m <model>`: 使用モデルの上書き
|
|
40
|
+
|
|
41
|
+
## 出力
|
|
42
|
+
|
|
43
|
+
標準出力に以下形式の JSON を返します。
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"session_id": "sess_xxx",
|
|
48
|
+
"status": "completed",
|
|
49
|
+
"files_changed": [
|
|
50
|
+
{ "path": "src/foo.ts", "kind": "update" }
|
|
51
|
+
],
|
|
52
|
+
"final_response": "作業内容の要約",
|
|
53
|
+
"duration_ms": 12345
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
終了コード:
|
|
58
|
+
|
|
59
|
+
- `0`: 成功(`status=completed`)
|
|
60
|
+
- `1`: 実行失敗(`status=failed`)
|
|
61
|
+
- `2`: CLI 実行時の致命エラー
|
|
62
|
+
|
|
63
|
+
## トレースファイル
|
|
64
|
+
|
|
65
|
+
実行ごとに `.agent-trace.json` へ追記します。
|
|
66
|
+
|
|
67
|
+
- `--trace-file` 未指定時は、Git リポジトリのルート(サブモジュール時は superproject ルート)に出力
|
|
68
|
+
- Git 管理外ディレクトリでは `<workdir>/.agent-trace.json` に出力
|
|
69
|
+
|
|
70
|
+
## 開発用コマンド
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install
|
|
74
|
+
npm run build
|
|
75
|
+
npm run typecheck
|
|
76
|
+
npm run start -- --help
|
|
77
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { runSession } from "../core/session.js";
|
|
3
|
+
/** CLI 引数をパースして RunOptions を生成 */
|
|
4
|
+
export function parseRunArgs(args) {
|
|
5
|
+
let workdir;
|
|
6
|
+
let instructions;
|
|
7
|
+
let traceFile;
|
|
8
|
+
let agentId;
|
|
9
|
+
let model;
|
|
10
|
+
const positional = [];
|
|
11
|
+
for (let i = 0; i < args.length; i++) {
|
|
12
|
+
const arg = args[i];
|
|
13
|
+
switch (arg) {
|
|
14
|
+
case "--workdir":
|
|
15
|
+
case "-w":
|
|
16
|
+
workdir = args[++i];
|
|
17
|
+
break;
|
|
18
|
+
case "--instructions":
|
|
19
|
+
case "-i":
|
|
20
|
+
instructions = args[++i];
|
|
21
|
+
break;
|
|
22
|
+
case "--trace-file":
|
|
23
|
+
traceFile = args[++i];
|
|
24
|
+
break;
|
|
25
|
+
case "--agent-id":
|
|
26
|
+
agentId = args[++i];
|
|
27
|
+
break;
|
|
28
|
+
case "--model":
|
|
29
|
+
case "-m":
|
|
30
|
+
model = args[++i];
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
if (!arg.startsWith("-")) {
|
|
34
|
+
positional.push(arg);
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!workdir) {
|
|
40
|
+
process.stderr.write("Error: --workdir (-w) is required\n");
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
const prompt = positional.join(" ");
|
|
44
|
+
if (!prompt) {
|
|
45
|
+
process.stderr.write("Error: prompt is required\n");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
workdir: resolve(workdir),
|
|
50
|
+
instructions: instructions ? resolve(instructions) : undefined,
|
|
51
|
+
traceFile: traceFile ? resolve(traceFile) : undefined,
|
|
52
|
+
agentId,
|
|
53
|
+
model,
|
|
54
|
+
prompt,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** run コマンドを実行 */
|
|
58
|
+
export async function executeRun(args) {
|
|
59
|
+
const options = parseRunArgs(args);
|
|
60
|
+
try {
|
|
61
|
+
const result = await runSession(options);
|
|
62
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
63
|
+
process.exit(result.status === "completed" ? 0 : 1);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
67
|
+
process.stderr.write(`[cdx] fatal: ${message}\n`);
|
|
68
|
+
process.exit(2);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ThreadEvent, EventAccumulator } from "../types.js";
|
|
2
|
+
/** 空の蓄積状態を生成 */
|
|
3
|
+
export declare function createAccumulator(): EventAccumulator;
|
|
4
|
+
/** ThreadEvent を処理し、蓄積状態を更新する */
|
|
5
|
+
export declare function handleEvent(acc: EventAccumulator, event: ThreadEvent): void;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** 空の蓄積状態を生成 */
|
|
2
|
+
export function createAccumulator() {
|
|
3
|
+
return {
|
|
4
|
+
sessionId: null,
|
|
5
|
+
filesChanged: [],
|
|
6
|
+
finalResponse: "",
|
|
7
|
+
status: "completed",
|
|
8
|
+
usage: null,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** stderr にログ出力 */
|
|
12
|
+
function log(msg) {
|
|
13
|
+
process.stderr.write(`[cdx] ${msg}\n`);
|
|
14
|
+
}
|
|
15
|
+
/** ThreadEvent を処理し、蓄積状態を更新する */
|
|
16
|
+
export function handleEvent(acc, event) {
|
|
17
|
+
switch (event.type) {
|
|
18
|
+
case "thread.started":
|
|
19
|
+
acc.sessionId = event.thread_id;
|
|
20
|
+
log(`session: ${event.thread_id}`);
|
|
21
|
+
break;
|
|
22
|
+
case "turn.started":
|
|
23
|
+
log("turn started");
|
|
24
|
+
break;
|
|
25
|
+
case "turn.completed":
|
|
26
|
+
acc.usage = event.usage;
|
|
27
|
+
log(`turn completed (tokens: in=${event.usage.input_tokens} out=${event.usage.output_tokens})`);
|
|
28
|
+
break;
|
|
29
|
+
case "turn.failed":
|
|
30
|
+
acc.status = "failed";
|
|
31
|
+
acc.error = event.error.message;
|
|
32
|
+
log(`turn failed: ${event.error.message}`);
|
|
33
|
+
break;
|
|
34
|
+
case "item.completed":
|
|
35
|
+
handleItemCompleted(acc, event.item);
|
|
36
|
+
break;
|
|
37
|
+
case "item.started":
|
|
38
|
+
case "item.updated":
|
|
39
|
+
// stderr に進捗表示のみ
|
|
40
|
+
if (event.item.type === "command_execution" && event.type === "item.started") {
|
|
41
|
+
log(`exec: ${event.item.command}`);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
case "error":
|
|
45
|
+
acc.status = "failed";
|
|
46
|
+
acc.error = event.message;
|
|
47
|
+
log(`error: ${event.message}`);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function handleItemCompleted(acc, item) {
|
|
52
|
+
switch (item.type) {
|
|
53
|
+
case "file_change": {
|
|
54
|
+
const changes = item.changes.map((c) => ({
|
|
55
|
+
path: c.path,
|
|
56
|
+
kind: c.kind,
|
|
57
|
+
}));
|
|
58
|
+
acc.filesChanged.push(...changes);
|
|
59
|
+
for (const c of changes) {
|
|
60
|
+
log(`file ${c.kind}: ${c.path}`);
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case "command_execution":
|
|
65
|
+
log(`exec done: ${item.command} (exit=${item.exit_code ?? "?"})`);
|
|
66
|
+
break;
|
|
67
|
+
case "agent_message":
|
|
68
|
+
acc.finalResponse = item.text;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=event-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-handler.js","sourceRoot":"","sources":["../../src/core/event-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Codex } from "@openai/codex-sdk";
|
|
2
|
+
import { createAccumulator, handleEvent } from "./event-handler.js";
|
|
3
|
+
import { appendTrace, resolveTraceFilePath } from "./trace-writer.js";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
import { execSync } from "node:child_process";
|
|
6
|
+
/** Codex セッションを実行し、結果を返す */
|
|
7
|
+
export async function runSession(options) {
|
|
8
|
+
const startTime = Date.now();
|
|
9
|
+
const codex = new Codex({
|
|
10
|
+
...(options.model ? { config: { model: options.model } } : {}),
|
|
11
|
+
});
|
|
12
|
+
const thread = codex.startThread({
|
|
13
|
+
workingDirectory: options.workdir,
|
|
14
|
+
sandboxMode: "workspace-write",
|
|
15
|
+
approvalPolicy: "never",
|
|
16
|
+
});
|
|
17
|
+
// プロンプト構築: instructions + タスク
|
|
18
|
+
let prompt = options.prompt;
|
|
19
|
+
if (options.instructions) {
|
|
20
|
+
const instructionsContent = await readFile(options.instructions, "utf-8");
|
|
21
|
+
prompt = `${instructionsContent}\n\n---\n\n${prompt}`;
|
|
22
|
+
}
|
|
23
|
+
const acc = createAccumulator();
|
|
24
|
+
const streamed = await thread.runStreamed(prompt);
|
|
25
|
+
for await (const event of streamed.events) {
|
|
26
|
+
handleEvent(acc, event);
|
|
27
|
+
}
|
|
28
|
+
const durationMs = Date.now() - startTime;
|
|
29
|
+
// git で実際の変更を検出(FileChangeItem だけでは shell 経由の変更を拾えない)
|
|
30
|
+
const gitChanges = detectGitChanges(options.workdir);
|
|
31
|
+
const filesChanged = mergeFileChanges(acc.filesChanged, gitChanges);
|
|
32
|
+
const result = {
|
|
33
|
+
session_id: acc.sessionId ?? "unknown",
|
|
34
|
+
status: acc.status,
|
|
35
|
+
files_changed: filesChanged,
|
|
36
|
+
final_response: acc.finalResponse,
|
|
37
|
+
duration_ms: durationMs,
|
|
38
|
+
};
|
|
39
|
+
// トレース書き込み
|
|
40
|
+
const traceFilePath = options.traceFile ?? await resolveTraceFilePath(options.workdir);
|
|
41
|
+
const transcriptPath = resolveTranscriptPath(acc.sessionId);
|
|
42
|
+
const traceEntry = {
|
|
43
|
+
coding_agent: "codex",
|
|
44
|
+
session_id: acc.sessionId ?? "unknown",
|
|
45
|
+
agent_id: options.agentId ?? "",
|
|
46
|
+
status: acc.status,
|
|
47
|
+
files_changed: filesChanged,
|
|
48
|
+
timestamp: new Date().toISOString(),
|
|
49
|
+
duration_ms: durationMs,
|
|
50
|
+
transcript: transcriptPath,
|
|
51
|
+
};
|
|
52
|
+
await appendTrace(traceFilePath, traceEntry);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
/** git status + diff で実際のファイル変更を検出 */
|
|
56
|
+
function detectGitChanges(workdir) {
|
|
57
|
+
try {
|
|
58
|
+
// --porcelain=v1: M/A/D/?? をパース
|
|
59
|
+
const output = execSync("git status --porcelain", {
|
|
60
|
+
cwd: workdir,
|
|
61
|
+
encoding: "utf-8",
|
|
62
|
+
}).trim();
|
|
63
|
+
if (!output)
|
|
64
|
+
return [];
|
|
65
|
+
return output.split("\n").map((line) => {
|
|
66
|
+
const status = line.substring(0, 2).trim();
|
|
67
|
+
const filePath = line.substring(3);
|
|
68
|
+
let kind;
|
|
69
|
+
switch (status) {
|
|
70
|
+
case "D":
|
|
71
|
+
kind = "delete";
|
|
72
|
+
break;
|
|
73
|
+
case "??":
|
|
74
|
+
case "A":
|
|
75
|
+
kind = "add";
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
kind = "update";
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
return { path: filePath, kind };
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** SDK の FileChangeItem と git 検出結果をマージ(重複排除) */
|
|
89
|
+
function mergeFileChanges(sdkChanges, gitChanges) {
|
|
90
|
+
const seen = new Set(sdkChanges.map((c) => c.path));
|
|
91
|
+
const merged = [...sdkChanges];
|
|
92
|
+
for (const gc of gitChanges) {
|
|
93
|
+
if (!seen.has(gc.path)) {
|
|
94
|
+
merged.push(gc);
|
|
95
|
+
seen.add(gc.path);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return merged;
|
|
99
|
+
}
|
|
100
|
+
/** Codex セッションの transcript パスを推定 */
|
|
101
|
+
function resolveTranscriptPath(sessionId) {
|
|
102
|
+
if (!sessionId)
|
|
103
|
+
return "";
|
|
104
|
+
const home = process.env["HOME"] ?? "";
|
|
105
|
+
const now = new Date();
|
|
106
|
+
const y = now.getFullYear();
|
|
107
|
+
const m = String(now.getMonth() + 1).padStart(2, "0");
|
|
108
|
+
const d = String(now.getDate()).padStart(2, "0");
|
|
109
|
+
return `${home}/.codex/sessions/${y}/${m}/${d}`;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TraceEntry } from "../types.js";
|
|
2
|
+
/** .agent-trace.json にトレースエントリを追記する */
|
|
3
|
+
export declare function appendTrace(traceFilePath: string, entry: TraceEntry): Promise<void>;
|
|
4
|
+
/** git common-dir からトレースファイルパスを算出 */
|
|
5
|
+
export declare function resolveTraceFilePath(workdir: string): Promise<string>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
const TRACE_VERSION = "0.1.0";
|
|
4
|
+
/** .agent-trace.json を読み込む。存在しなければ空構造を返す */
|
|
5
|
+
async function readTraceFile(path) {
|
|
6
|
+
if (!existsSync(path)) {
|
|
7
|
+
return { version: TRACE_VERSION, traces: [] };
|
|
8
|
+
}
|
|
9
|
+
const raw = await readFile(path, "utf-8");
|
|
10
|
+
return JSON.parse(raw);
|
|
11
|
+
}
|
|
12
|
+
/** .agent-trace.json にトレースエントリを追記する */
|
|
13
|
+
export async function appendTrace(traceFilePath, entry) {
|
|
14
|
+
const traceFile = await readTraceFile(traceFilePath);
|
|
15
|
+
traceFile.traces.push(entry);
|
|
16
|
+
await writeFile(traceFilePath, JSON.stringify(traceFile, null, 2) + "\n");
|
|
17
|
+
}
|
|
18
|
+
/** git common-dir からトレースファイルパスを算出 */
|
|
19
|
+
export async function resolveTraceFilePath(workdir) {
|
|
20
|
+
const { execSync } = await import("node:child_process");
|
|
21
|
+
try {
|
|
22
|
+
const superproject = execSync("git rev-parse --show-superproject-working-tree", {
|
|
23
|
+
cwd: workdir,
|
|
24
|
+
encoding: "utf-8",
|
|
25
|
+
}).trim();
|
|
26
|
+
const toplevel = superproject || execSync("git rev-parse --show-toplevel", {
|
|
27
|
+
cwd: workdir,
|
|
28
|
+
encoding: "utf-8",
|
|
29
|
+
}).trim();
|
|
30
|
+
return `${toplevel}/.agent-trace.json`;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return `${workdir}/.agent-trace.json`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=trace-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-writer.js","sourceRoot":"","sources":["../../src/core/trace-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,MAAM,aAAa,GAAG,OAAO,CAAC;AAE9B,4CAA4C;AAC5C,KAAK,UAAU,aAAa,CAAC,IAAY;IACvC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAChD,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;AACtC,CAAC;AAED,uCAAuC;AACvC,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,aAAqB,EACrB,KAAiB;IAEjB,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,CAAC;IACrD,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC5E,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAe;IAEf,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,QAAQ,CAAC,gDAAgD,EAAE;YAC9E,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,YAAY,IAAI,QAAQ,CAAC,+BAA+B,EAAE;YACzE,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,GAAG,QAAQ,oBAAoB,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,OAAO,oBAAoB,CAAC;IACxC,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { executeRun } from "./commands/run.js";
|
|
3
|
+
const USAGE = `cdx-cli - Codex SDK wrapper CLI
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
cdx-cli run [options] "prompt"
|
|
7
|
+
|
|
8
|
+
Options:
|
|
9
|
+
--workdir, -w <path> Working directory (required)
|
|
10
|
+
--instructions, -i <path> Instructions file
|
|
11
|
+
--trace-file <path> Trace output path
|
|
12
|
+
--agent-id <id> Agent ID
|
|
13
|
+
--model, -m <model> Model override
|
|
14
|
+
`;
|
|
15
|
+
async function main() {
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
const command = args[0];
|
|
18
|
+
if (!command || command === "--help" || command === "-h") {
|
|
19
|
+
process.stderr.write(USAGE);
|
|
20
|
+
process.exit(command ? 0 : 1);
|
|
21
|
+
}
|
|
22
|
+
switch (command) {
|
|
23
|
+
case "run":
|
|
24
|
+
await executeRun(args.slice(1));
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
process.stderr.write(`Unknown command: ${command}\n\n${USAGE}`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
main();
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,KAAK,GAAG;;;;;;;;;;;CAWb,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAExB,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM;QACR;YACE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ThreadEvent, ThreadItem, FileChangeItem, CommandExecutionItem, AgentMessageItem, Usage } from "@openai/codex-sdk";
|
|
2
|
+
/** CLI run コマンドのオプション */
|
|
3
|
+
export interface RunOptions {
|
|
4
|
+
workdir: string;
|
|
5
|
+
instructions?: string;
|
|
6
|
+
traceFile?: string;
|
|
7
|
+
agentId?: string;
|
|
8
|
+
model?: string;
|
|
9
|
+
prompt: string;
|
|
10
|
+
}
|
|
11
|
+
/** ファイル変更記録 */
|
|
12
|
+
export interface FileChange {
|
|
13
|
+
path: string;
|
|
14
|
+
kind: "add" | "delete" | "update";
|
|
15
|
+
}
|
|
16
|
+
/** run コマンドの実行結果(stdout JSON) */
|
|
17
|
+
export interface RunResult {
|
|
18
|
+
session_id: string;
|
|
19
|
+
status: "completed" | "failed";
|
|
20
|
+
files_changed: FileChange[];
|
|
21
|
+
final_response: string;
|
|
22
|
+
duration_ms: number;
|
|
23
|
+
}
|
|
24
|
+
/** .agent-trace.json 内の個別トレースエントリ */
|
|
25
|
+
export interface TraceEntry {
|
|
26
|
+
coding_agent: string;
|
|
27
|
+
session_id: string;
|
|
28
|
+
agent_id: string;
|
|
29
|
+
status: "completed" | "failed";
|
|
30
|
+
files_changed: FileChange[];
|
|
31
|
+
timestamp: string;
|
|
32
|
+
duration_ms: number;
|
|
33
|
+
transcript: string;
|
|
34
|
+
}
|
|
35
|
+
/** .agent-trace.json のルート構造 */
|
|
36
|
+
export interface TraceFile {
|
|
37
|
+
version: string;
|
|
38
|
+
traces: TraceEntry[];
|
|
39
|
+
}
|
|
40
|
+
/** イベントハンドラが蓄積する状態 */
|
|
41
|
+
export interface EventAccumulator {
|
|
42
|
+
sessionId: string | null;
|
|
43
|
+
filesChanged: FileChange[];
|
|
44
|
+
finalResponse: string;
|
|
45
|
+
status: "completed" | "failed";
|
|
46
|
+
error?: string;
|
|
47
|
+
usage: Usage | null;
|
|
48
|
+
}
|
|
49
|
+
export type { ThreadEvent, ThreadItem, FileChangeItem, CommandExecutionItem, AgentMessageItem, Usage, };
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cdx-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Codex SDK wrapper CLI for local coding tasks",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"cdx-cli": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/MASAKASUNO1/cdx-cli.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/MASAKASUNO1/cdx-cli/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/MASAKASUNO1/cdx-cli#readme",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=20"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc -p tsconfig.json",
|
|
31
|
+
"prepublishOnly": "npm run typecheck && npm run build",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"start": "tsx src/index.ts"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@openai/codex-sdk": "^0.98.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"typescript": "^5.9.0",
|
|
40
|
+
"tsx": "^4.19.0",
|
|
41
|
+
"@types/node": "^22.0.0"
|
|
42
|
+
}
|
|
43
|
+
}
|