agents-bridge 0.1.4 → 0.1.6
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/README.md +199 -205
- package/config.example.json +28 -70
- package/dist/agents/cli-backends.js +3 -3
- package/dist/agents/cli-backends.js.map +1 -1
- package/dist/agents/cli-runner.d.ts +5 -2
- package/dist/agents/cli-runner.d.ts.map +1 -1
- package/dist/agents/cli-runner.js +73 -35
- package/dist/agents/cli-runner.js.map +1 -1
- package/dist/agents/cli-session-store.d.ts +6 -0
- package/dist/agents/cli-session-store.d.ts.map +1 -1
- package/dist/agents/cli-session-store.js +64 -0
- package/dist/agents/cli-session-store.js.map +1 -1
- package/dist/agents/codex-app-server-runtime.js +2 -2
- package/dist/agents/codex-app-server-runtime.js.map +1 -1
- package/dist/channels/command-gating.d.ts.map +1 -1
- package/dist/channels/command-gating.js +6 -6
- package/dist/channels/command-gating.js.map +1 -1
- package/dist/cli/cmd-add-agent.d.ts +19 -0
- package/dist/cli/cmd-add-agent.d.ts.map +1 -0
- package/dist/cli/cmd-add-agent.js +374 -0
- package/dist/cli/cmd-add-agent.js.map +1 -0
- package/dist/cli/cmd-restart.d.ts +3 -0
- package/dist/cli/cmd-restart.d.ts.map +1 -0
- package/dist/cli/cmd-restart.js +22 -0
- package/dist/cli/cmd-restart.js.map +1 -0
- package/dist/cli/cmd-start.d.ts.map +1 -1
- package/dist/cli/cmd-start.js +35 -10
- package/dist/cli/cmd-start.js.map +1 -1
- package/dist/cli/cmd-stop.d.ts +5 -0
- package/dist/cli/cmd-stop.d.ts.map +1 -1
- package/dist/cli/cmd-stop.js +32 -8
- package/dist/cli/cmd-stop.js.map +1 -1
- package/dist/cli/run-main.d.ts +5 -1
- package/dist/cli/run-main.d.ts.map +1 -1
- package/dist/cli/run-main.js +41 -14
- package/dist/cli/run-main.js.map +1 -1
- package/dist/config/default-config.d.ts.map +1 -1
- package/dist/config/default-config.js +0 -10
- package/dist/config/default-config.js.map +1 -1
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +8 -0
- package/dist/entry.js.map +1 -1
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +5 -1
- package/dist/agents/cli-output.test.d.ts +0 -2
- package/dist/agents/cli-output.test.d.ts.map +0 -1
- package/dist/agents/cli-output.test.js +0 -56
- package/dist/agents/cli-output.test.js.map +0 -1
- package/dist/agents/cli-runner.test.d.ts +0 -2
- package/dist/agents/cli-runner.test.d.ts.map +0 -1
- package/dist/agents/cli-runner.test.js +0 -119
- package/dist/agents/cli-runner.test.js.map +0 -1
- package/dist/agents/cli-session-store.test.d.ts +0 -2
- package/dist/agents/cli-session-store.test.d.ts.map +0 -1
- package/dist/agents/cli-session-store.test.js +0 -30
- package/dist/agents/cli-session-store.test.js.map +0 -1
- package/dist/agents/codex-app-server-runtime.test.d.ts +0 -2
- package/dist/agents/codex-app-server-runtime.test.d.ts.map +0 -1
- package/dist/agents/codex-app-server-runtime.test.js +0 -164
- package/dist/agents/codex-app-server-runtime.test.js.map +0 -1
- package/dist/cli/run-main.test.d.ts +0 -2
- package/dist/cli/run-main.test.d.ts.map +0 -1
- package/dist/cli/run-main.test.js +0 -17
- package/dist/cli/run-main.test.js.map +0 -1
- package/dist/config/default-config.test.d.ts +0 -2
- package/dist/config/default-config.test.d.ts.map +0 -1
- package/dist/config/default-config.test.js +0 -19
- package/dist/config/default-config.test.js.map +0 -1
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { mkdtemp, rm } from 'node:fs/promises';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import test from 'node:test';
|
|
6
|
-
import { LocalCliTurnExecutor } from './cli-runner.js';
|
|
7
|
-
import { CliSessionStore } from './cli-session-store.js';
|
|
8
|
-
const CODEX_BACKEND = {
|
|
9
|
-
command: 'codex',
|
|
10
|
-
runtimeMode: 'app-server',
|
|
11
|
-
sessionIdFields: ['thread_id'],
|
|
12
|
-
sessionMode: 'existing',
|
|
13
|
-
serialize: true,
|
|
14
|
-
appServer: {
|
|
15
|
-
requestTimeoutMs: 30_000,
|
|
16
|
-
startupTimeoutMs: 15_000,
|
|
17
|
-
approvalPolicy: 'never',
|
|
18
|
-
sandbox: 'workspace-write',
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
function createLogger() {
|
|
22
|
-
return {
|
|
23
|
-
debug() { return undefined; },
|
|
24
|
-
info() { return undefined; },
|
|
25
|
-
warn() { return undefined; },
|
|
26
|
-
error() { return undefined; },
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
function createEnvelope(sessionId) {
|
|
30
|
-
return {
|
|
31
|
-
sessionId,
|
|
32
|
-
source: {
|
|
33
|
-
channel: 'botlink',
|
|
34
|
-
chatId: 1,
|
|
35
|
-
chatType: 'private',
|
|
36
|
-
userId: 1,
|
|
37
|
-
messageId: 1,
|
|
38
|
-
},
|
|
39
|
-
content: {
|
|
40
|
-
text: 'reply with exactly OK',
|
|
41
|
-
mentions: [],
|
|
42
|
-
attachments: [],
|
|
43
|
-
},
|
|
44
|
-
meta: {
|
|
45
|
-
timestamp: Date.now(),
|
|
46
|
-
raw: {},
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
test('LocalCliTurnExecutor clears stale codex thread id and retries fresh via app-server runtime', async () => {
|
|
51
|
-
const tempDir = await mkdtemp(join(tmpdir(), 'agent-bridge-cli-runner-'));
|
|
52
|
-
const storePath = join(tempDir, 'cli-sessions.json');
|
|
53
|
-
const sessionStore = new CliSessionStore(storePath);
|
|
54
|
-
await sessionStore.setCliSessionId('session-1', 'codex-cli', 'thread-stale', {
|
|
55
|
-
model: 'gpt-5.4',
|
|
56
|
-
});
|
|
57
|
-
const runtimeCalls = [];
|
|
58
|
-
const fakeRuntime = {
|
|
59
|
-
async run(params) {
|
|
60
|
-
runtimeCalls.push(params.existingThreadId);
|
|
61
|
-
if (params.existingThreadId) {
|
|
62
|
-
throw new Error('no rollout found for thread id thread-stale');
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
text: 'READY',
|
|
66
|
-
cliSessionId: 'thread-fresh',
|
|
67
|
-
isResume: false,
|
|
68
|
-
diagnostics: {
|
|
69
|
-
queueWaitMs: 0,
|
|
70
|
-
commandElapsedMs: 10,
|
|
71
|
-
totalElapsedMs: 10,
|
|
72
|
-
outputMode: 'app-server',
|
|
73
|
-
runtimeMode: 'app-server',
|
|
74
|
-
hadStdout: false,
|
|
75
|
-
hadStderr: false,
|
|
76
|
-
reconnectCount: 0,
|
|
77
|
-
fellBackToHttps: false,
|
|
78
|
-
threadOperation: 'start',
|
|
79
|
-
threadOperationElapsedMs: 3,
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
},
|
|
83
|
-
async teardown() { },
|
|
84
|
-
};
|
|
85
|
-
const executor = new LocalCliTurnExecutor({
|
|
86
|
-
config: {
|
|
87
|
-
agents: {
|
|
88
|
-
defaults: {
|
|
89
|
-
model: { primary: 'codex-cli/gpt-5.4' },
|
|
90
|
-
cliBackends: {
|
|
91
|
-
'codex-cli': CODEX_BACKEND,
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
logger: createLogger(),
|
|
97
|
-
sessionStore,
|
|
98
|
-
createCodexRuntime: () => fakeRuntime,
|
|
99
|
-
});
|
|
100
|
-
try {
|
|
101
|
-
const result = await executor.run({
|
|
102
|
-
envelope: createEnvelope('session-1'),
|
|
103
|
-
provider: 'codex-cli',
|
|
104
|
-
model: 'gpt-5.4',
|
|
105
|
-
workspaceDir: process.cwd(),
|
|
106
|
-
timeoutMs: 60_000,
|
|
107
|
-
});
|
|
108
|
-
assert.equal(result.text, 'READY');
|
|
109
|
-
assert.equal(result.cliSessionId, 'thread-fresh');
|
|
110
|
-
assert.equal(result.isResume, false);
|
|
111
|
-
assert.deepEqual(runtimeCalls, ['thread-stale', undefined]);
|
|
112
|
-
assert.equal(await sessionStore.getCliSessionId('session-1', 'codex-cli'), 'thread-fresh');
|
|
113
|
-
}
|
|
114
|
-
finally {
|
|
115
|
-
await executor.teardown();
|
|
116
|
-
await rm(tempDir, { recursive: true, force: true });
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
//# sourceMappingURL=cli-runner.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-runner.test.js","sourceRoot":"","sources":["../../src/agents/cli-runner.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-session-store.test.d.ts","sourceRoot":"","sources":["../../src/agents/cli-session-store.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { mkdtemp, rm } from 'node:fs/promises';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import test from 'node:test';
|
|
6
|
-
import { CliSessionStore } from './cli-session-store.js';
|
|
7
|
-
test('findIncompleteSessions reports codex sessions without persisted thread ids', async () => {
|
|
8
|
-
const tempDir = await mkdtemp(join(tmpdir(), 'agent-bridge-session-store-'));
|
|
9
|
-
const storePath = join(tempDir, 'cli-sessions.json');
|
|
10
|
-
const store = new CliSessionStore(storePath);
|
|
11
|
-
try {
|
|
12
|
-
await store.ensureSession('session-codex-missing', {
|
|
13
|
-
provider: 'codex-cli',
|
|
14
|
-
model: 'gpt-5.4',
|
|
15
|
-
});
|
|
16
|
-
await store.setCliSessionId('session-codex-ready', 'codex-cli', 'thread-1', {
|
|
17
|
-
model: 'gpt-5.4',
|
|
18
|
-
});
|
|
19
|
-
await store.setCliSessionId('session-claude-ready', 'claude-cli', 'conversation-1', {
|
|
20
|
-
model: 'opus',
|
|
21
|
-
});
|
|
22
|
-
const incomplete = await store.findIncompleteSessions('codex-cli');
|
|
23
|
-
assert.deepEqual(incomplete.map((entry) => entry.sessionKey), ['session-codex-missing']);
|
|
24
|
-
assert.equal(incomplete[0]?.provider, 'codex-cli');
|
|
25
|
-
}
|
|
26
|
-
finally {
|
|
27
|
-
await rm(tempDir, { recursive: true, force: true });
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
//# sourceMappingURL=cli-session-store.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-session-store.test.js","sourceRoot":"","sources":["../../src/agents/cli-session-store.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,IAAI,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;IAC5F,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,6BAA6B,CAAC,CAAC,CAAA;IAC5E,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAA;IACpD,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,SAAS,CAAC,CAAA;IAE5C,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,aAAa,CAAC,uBAAuB,EAAE;YACjD,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,SAAS;SACjB,CAAC,CAAA;QACF,MAAM,KAAK,CAAC,eAAe,CAAC,qBAAqB,EAAE,WAAW,EAAE,UAAU,EAAE;YAC1E,KAAK,EAAE,SAAS;SACjB,CAAC,CAAA;QACF,MAAM,KAAK,CAAC,eAAe,CAAC,sBAAsB,EAAE,YAAY,EAAE,gBAAgB,EAAE;YAClF,KAAK,EAAE,MAAM;SACd,CAAC,CAAA;QAEF,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAA;QAElE,MAAM,CAAC,SAAS,CACd,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAC3C,CAAC,uBAAuB,CAAC,CAC1B,CAAA;QACD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;IACpD,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACrD,CAAC;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codex-app-server-runtime.test.d.ts","sourceRoot":"","sources":["../../src/agents/codex-app-server-runtime.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import test from 'node:test';
|
|
3
|
-
import { CodexAppServerRuntime } from './codex-app-server-runtime.js';
|
|
4
|
-
const CODEX_BACKEND = {
|
|
5
|
-
command: 'codex',
|
|
6
|
-
runtimeMode: 'app-server',
|
|
7
|
-
sessionIdFields: ['thread_id'],
|
|
8
|
-
appServer: {
|
|
9
|
-
requestTimeoutMs: 30_000,
|
|
10
|
-
startupTimeoutMs: 15_000,
|
|
11
|
-
approvalPolicy: 'never',
|
|
12
|
-
sandbox: 'workspace-write',
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
class FakeAppServerConnection {
|
|
16
|
-
requests = [];
|
|
17
|
-
notificationListener = null;
|
|
18
|
-
fatalListener = null;
|
|
19
|
-
turnCount = 0;
|
|
20
|
-
async ensureReady() { }
|
|
21
|
-
async request(method, params) {
|
|
22
|
-
this.requests.push({ method, params });
|
|
23
|
-
if (method === 'thread/resume') {
|
|
24
|
-
return { thread: { id: params.threadId } };
|
|
25
|
-
}
|
|
26
|
-
if (method === 'thread/start') {
|
|
27
|
-
return { thread: { id: 'thread-started' } };
|
|
28
|
-
}
|
|
29
|
-
if (method === 'turn/start') {
|
|
30
|
-
this.turnCount += 1;
|
|
31
|
-
const turnId = `turn-${this.turnCount}`;
|
|
32
|
-
const threadId = String(params.threadId);
|
|
33
|
-
queueMicrotask(() => {
|
|
34
|
-
this.notificationListener?.({
|
|
35
|
-
method: 'turn/started',
|
|
36
|
-
params: {
|
|
37
|
-
threadId,
|
|
38
|
-
turn: { id: turnId, status: 'inProgress', error: null },
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
this.notificationListener?.({
|
|
42
|
-
method: 'error',
|
|
43
|
-
params: {
|
|
44
|
-
threadId,
|
|
45
|
-
turnId,
|
|
46
|
-
willRetry: true,
|
|
47
|
-
error: {
|
|
48
|
-
message: 'Reconnecting... 2/5',
|
|
49
|
-
additionalDetails: 'timeout waiting for child process to exit',
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
this.notificationListener?.({
|
|
54
|
-
method: 'item/completed',
|
|
55
|
-
params: {
|
|
56
|
-
threadId,
|
|
57
|
-
turnId,
|
|
58
|
-
item: {
|
|
59
|
-
type: 'agentMessage',
|
|
60
|
-
id: `item-${turnId}`,
|
|
61
|
-
text: `READY-${this.turnCount}`,
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
this.notificationListener?.({
|
|
66
|
-
method: 'thread/tokenUsage/updated',
|
|
67
|
-
params: {
|
|
68
|
-
threadId,
|
|
69
|
-
turnId,
|
|
70
|
-
tokenUsage: {
|
|
71
|
-
last: {
|
|
72
|
-
inputTokens: 12,
|
|
73
|
-
outputTokens: 3,
|
|
74
|
-
cachedInputTokens: 4,
|
|
75
|
-
totalTokens: 15,
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
this.notificationListener?.({
|
|
81
|
-
method: 'turn/completed',
|
|
82
|
-
params: {
|
|
83
|
-
threadId,
|
|
84
|
-
turn: {
|
|
85
|
-
id: turnId,
|
|
86
|
-
status: 'completed',
|
|
87
|
-
error: null,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
return { turn: { id: turnId } };
|
|
93
|
-
}
|
|
94
|
-
if (method === 'turn/interrupt') {
|
|
95
|
-
return {};
|
|
96
|
-
}
|
|
97
|
-
throw new Error(`Unhandled request ${method}`);
|
|
98
|
-
}
|
|
99
|
-
notify() { }
|
|
100
|
-
getRestartCount() {
|
|
101
|
-
return 0;
|
|
102
|
-
}
|
|
103
|
-
onNotification(listener) {
|
|
104
|
-
this.notificationListener = listener;
|
|
105
|
-
}
|
|
106
|
-
onFatalError(listener) {
|
|
107
|
-
this.fatalListener = listener;
|
|
108
|
-
}
|
|
109
|
-
emitFatal(error) {
|
|
110
|
-
this.fatalListener?.(error);
|
|
111
|
-
}
|
|
112
|
-
async dispose() { }
|
|
113
|
-
}
|
|
114
|
-
function createLogger() {
|
|
115
|
-
return {
|
|
116
|
-
debug() { return undefined; },
|
|
117
|
-
info() { return undefined; },
|
|
118
|
-
warn() { return undefined; },
|
|
119
|
-
error() { return undefined; },
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
test('Codex app-server runtime resumes once and reuses the loaded thread afterwards', async () => {
|
|
123
|
-
const connection = new FakeAppServerConnection();
|
|
124
|
-
const runtime = new CodexAppServerRuntime({
|
|
125
|
-
backend: CODEX_BACKEND,
|
|
126
|
-
logger: createLogger(),
|
|
127
|
-
connection,
|
|
128
|
-
});
|
|
129
|
-
const first = await runtime.run({
|
|
130
|
-
sessionId: 'session-1',
|
|
131
|
-
runtimeSessionId: 'runtime-1',
|
|
132
|
-
existingThreadId: 'thread-existing',
|
|
133
|
-
model: 'gpt-5.4',
|
|
134
|
-
workspaceDir: process.cwd(),
|
|
135
|
-
timeoutMs: 60_000,
|
|
136
|
-
noProgressTimeoutMs: 10_000,
|
|
137
|
-
prompt: 'reply with exactly OK',
|
|
138
|
-
});
|
|
139
|
-
const second = await runtime.run({
|
|
140
|
-
sessionId: 'session-1',
|
|
141
|
-
runtimeSessionId: 'runtime-1',
|
|
142
|
-
existingThreadId: 'thread-existing',
|
|
143
|
-
model: 'gpt-5.4',
|
|
144
|
-
workspaceDir: process.cwd(),
|
|
145
|
-
timeoutMs: 60_000,
|
|
146
|
-
noProgressTimeoutMs: 10_000,
|
|
147
|
-
prompt: 'reply with exactly AGAIN',
|
|
148
|
-
});
|
|
149
|
-
assert.equal(first.cliSessionId, 'thread-existing');
|
|
150
|
-
assert.equal(first.isResume, true);
|
|
151
|
-
assert.equal(first.text, 'READY-1');
|
|
152
|
-
assert.equal(first.usage?.input, 12);
|
|
153
|
-
assert.equal(first.usage?.output, 3);
|
|
154
|
-
assert.equal(first.usage?.cacheRead, 4);
|
|
155
|
-
assert.equal(first.diagnostics.threadOperation, 'resume');
|
|
156
|
-
assert.equal(first.diagnostics.reconnectCount, 1);
|
|
157
|
-
assert.equal(second.cliSessionId, 'thread-existing');
|
|
158
|
-
assert.equal(second.isResume, true);
|
|
159
|
-
assert.equal(second.text, 'READY-2');
|
|
160
|
-
assert.equal(second.diagnostics.threadOperation, 'reuse');
|
|
161
|
-
assert.deepEqual(connection.requests.map((entry) => entry.method), ['thread/resume', 'turn/start', 'turn/start']);
|
|
162
|
-
await runtime.teardown();
|
|
163
|
-
});
|
|
164
|
-
//# sourceMappingURL=codex-app-server-runtime.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codex-app-server-runtime.test.js","sourceRoot":"","sources":["../../src/agents/codex-app-server-runtime.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-main.test.d.ts","sourceRoot":"","sources":["../../src/cli/run-main.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import test from 'node:test';
|
|
3
|
-
import { parseCliArgs } from './run-main.js';
|
|
4
|
-
test('parseCliArgs treats --version as the version command', () => {
|
|
5
|
-
const args = parseCliArgs(['--version']);
|
|
6
|
-
assert.equal(args.command, 'version');
|
|
7
|
-
assert.equal(args.version, true);
|
|
8
|
-
});
|
|
9
|
-
test('parseCliArgs accepts the common --verson typo as version', () => {
|
|
10
|
-
const args = parseCliArgs(['--verson']);
|
|
11
|
-
assert.equal(args.command, 'version');
|
|
12
|
-
assert.equal(args.version, true);
|
|
13
|
-
});
|
|
14
|
-
test('parseCliArgs rejects unknown options instead of silently starting', () => {
|
|
15
|
-
assert.throws(() => parseCliArgs(['--wat']), /Unknown option\(s\): --wat/);
|
|
16
|
-
});
|
|
17
|
-
//# sourceMappingURL=run-main.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-main.test.js","sourceRoot":"","sources":["../../src/cli/run-main.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAA;AACvC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,IAAI,CAAC,sDAAsD,EAAE,GAAG,EAAE;IAChE,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,CAAA;IACxC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACrC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,0DAA0D,EAAE,GAAG,EAAE;IACpE,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;IACvC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACrC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,mEAAmE,EAAE,GAAG,EAAE;IAC7E,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,EAC7B,4BAA4B,CAC7B,CAAA;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"default-config.test.d.ts","sourceRoot":"","sources":["../../src/config/default-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
3
|
-
import { dirname, resolve } from 'node:path';
|
|
4
|
-
import test from 'node:test';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { createDefaultConfig } from './default-config.js';
|
|
7
|
-
import { AppConfigSchema } from './zod-schema.js';
|
|
8
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const rootDir = resolve(__dirname, '..', '..');
|
|
10
|
-
test('createDefaultConfig stays aligned with config.example.json', () => {
|
|
11
|
-
const expected = createDefaultConfig({
|
|
12
|
-
gatewayUrl: 'https://your-botlink.com',
|
|
13
|
-
botToken: 'bot_xxx',
|
|
14
|
-
selectedModel: 'claude-cli/opus-4.6',
|
|
15
|
-
});
|
|
16
|
-
const exampleConfig = AppConfigSchema.parse(JSON.parse(readFileSync(resolve(rootDir, 'config.example.json'), 'utf-8').replace(/^\uFEFF/, '')));
|
|
17
|
-
assert.deepEqual(exampleConfig, expected);
|
|
18
|
-
});
|
|
19
|
-
//# sourceMappingURL=default-config.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"default-config.test.js","sourceRoot":"","sources":["../../src/config/default-config.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAE9C,IAAI,CAAC,4DAA4D,EAAE,GAAG,EAAE;IACtE,MAAM,QAAQ,GAAG,mBAAmB,CAAC;QACnC,UAAU,EAAE,0BAA0B;QACtC,QAAQ,EAAE,SAAS;QACnB,aAAa,EAAE,qBAAqB;KACrC,CAAC,CAAA;IAEF,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,CACzC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAY,CAC7G,CAAA;IAED,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;AAC3C,CAAC,CAAC,CAAA"}
|