@agent-relay/sdk 2.3.14 → 3.0.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/README.md +68 -838
- package/bin/agent-relay-broker +0 -0
- package/dist/__tests__/contract-fixtures.test.d.ts +2 -0
- package/dist/__tests__/contract-fixtures.test.d.ts.map +1 -0
- package/dist/__tests__/contract-fixtures.test.js +85 -0
- package/dist/__tests__/contract-fixtures.test.js.map +1 -0
- package/dist/__tests__/facade.test.d.ts +2 -0
- package/dist/__tests__/facade.test.d.ts.map +1 -0
- package/dist/__tests__/facade.test.js +257 -0
- package/dist/__tests__/facade.test.js.map +1 -0
- package/dist/__tests__/integration.test.d.ts +2 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.js +164 -0
- package/dist/__tests__/integration.test.js.map +1 -0
- package/dist/__tests__/pty.test.d.ts +2 -0
- package/dist/__tests__/pty.test.d.ts.map +1 -0
- package/dist/__tests__/pty.test.js +20 -0
- package/dist/__tests__/pty.test.js.map +1 -0
- package/dist/__tests__/quickstart.test.d.ts +2 -0
- package/dist/__tests__/quickstart.test.d.ts.map +1 -0
- package/dist/__tests__/quickstart.test.js +176 -0
- package/dist/__tests__/quickstart.test.js.map +1 -0
- package/dist/__tests__/spawn-from-env.test.d.ts +2 -0
- package/dist/__tests__/spawn-from-env.test.d.ts.map +1 -0
- package/dist/__tests__/spawn-from-env.test.js +206 -0
- package/dist/__tests__/spawn-from-env.test.js.map +1 -0
- package/dist/__tests__/unit.test.d.ts +2 -0
- package/dist/__tests__/unit.test.d.ts.map +1 -0
- package/dist/__tests__/unit.test.js +311 -0
- package/dist/__tests__/unit.test.js.map +1 -0
- package/dist/browser.d.ts +16 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +19 -0
- package/dist/browser.js.map +1 -0
- package/dist/client.d.ts +138 -526
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +407 -1509
- package/dist/client.js.map +1 -1
- package/dist/consensus-helpers.d.ts +103 -0
- package/dist/consensus-helpers.d.ts.map +1 -0
- package/dist/consensus-helpers.js +147 -0
- package/dist/consensus-helpers.js.map +1 -0
- package/dist/consensus.d.ts +72 -0
- package/dist/consensus.d.ts.map +1 -0
- package/dist/consensus.js +378 -0
- package/dist/consensus.js.map +1 -0
- package/dist/examples/demo.d.ts +2 -0
- package/dist/examples/demo.d.ts.map +1 -0
- package/dist/examples/demo.js +63 -0
- package/dist/examples/demo.js.map +1 -0
- package/dist/examples/example.d.ts +2 -0
- package/dist/examples/example.d.ts.map +1 -0
- package/dist/examples/example.js +80 -0
- package/dist/examples/example.js.map +1 -0
- package/dist/examples/quickstart.d.ts +2 -0
- package/dist/examples/quickstart.d.ts.map +1 -0
- package/dist/examples/quickstart.js +56 -0
- package/dist/examples/quickstart.js.map +1 -0
- package/dist/examples/ralph-loop.d.ts +2 -0
- package/dist/examples/ralph-loop.d.ts.map +1 -0
- package/dist/examples/ralph-loop.js +281 -0
- package/dist/examples/ralph-loop.js.map +1 -0
- package/dist/examples/workflow-superiority.d.ts +32 -0
- package/dist/examples/workflow-superiority.d.ts.map +1 -0
- package/dist/examples/workflow-superiority.js +1421 -0
- package/dist/examples/workflow-superiority.js.map +1 -0
- package/dist/index.d.ts +13 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -26
- package/dist/index.js.map +1 -1
- package/dist/logs.d.ts +70 -25
- package/dist/logs.d.ts.map +1 -1
- package/dist/logs.js +238 -42
- package/dist/logs.js.map +1 -1
- package/dist/models.d.ts +9 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +17 -0
- package/dist/models.js.map +1 -0
- package/dist/protocol.d.ts +366 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +2 -0
- package/dist/protocol.js.map +1 -0
- package/dist/pty.d.ts +8 -0
- package/dist/pty.d.ts.map +1 -0
- package/dist/pty.js +26 -0
- package/dist/pty.js.map +1 -0
- package/dist/relay-adapter.d.ts +139 -0
- package/dist/relay-adapter.d.ts.map +1 -0
- package/dist/relay-adapter.js +210 -0
- package/dist/relay-adapter.js.map +1 -0
- package/dist/relay.d.ts +277 -0
- package/dist/relay.d.ts.map +1 -0
- package/dist/relay.js +853 -0
- package/dist/relay.js.map +1 -0
- package/dist/shadow.d.ts +101 -0
- package/dist/shadow.d.ts.map +1 -0
- package/dist/shadow.js +174 -0
- package/dist/shadow.js.map +1 -0
- package/dist/spawn-from-env.d.ts +77 -0
- package/dist/spawn-from-env.d.ts.map +1 -0
- package/dist/spawn-from-env.js +172 -0
- package/dist/spawn-from-env.js.map +1 -0
- package/dist/workflows/barrier.d.ts +72 -0
- package/dist/workflows/barrier.d.ts.map +1 -0
- package/dist/workflows/barrier.js +162 -0
- package/dist/workflows/barrier.js.map +1 -0
- package/dist/workflows/builder.d.ts +114 -0
- package/dist/workflows/builder.d.ts.map +1 -0
- package/dist/workflows/builder.js +201 -0
- package/dist/workflows/builder.js.map +1 -0
- package/dist/workflows/cli.d.ts +11 -0
- package/dist/workflows/cli.d.ts.map +1 -0
- package/dist/workflows/cli.js +144 -0
- package/dist/workflows/cli.js.map +1 -0
- package/dist/workflows/coordinator.d.ts +73 -0
- package/dist/workflows/coordinator.d.ts.map +1 -0
- package/dist/workflows/coordinator.js +647 -0
- package/dist/workflows/coordinator.js.map +1 -0
- package/dist/workflows/custom-steps.d.ts +73 -0
- package/dist/workflows/custom-steps.d.ts.map +1 -0
- package/dist/workflows/custom-steps.js +321 -0
- package/dist/workflows/custom-steps.js.map +1 -0
- package/dist/workflows/dry-run-format.d.ts +6 -0
- package/dist/workflows/dry-run-format.d.ts.map +1 -0
- package/dist/workflows/dry-run-format.js +68 -0
- package/dist/workflows/dry-run-format.js.map +1 -0
- package/dist/workflows/file-db.d.ts +33 -0
- package/dist/workflows/file-db.d.ts.map +1 -0
- package/dist/workflows/file-db.js +108 -0
- package/dist/workflows/file-db.js.map +1 -0
- package/dist/workflows/index.d.ts +15 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/index.js +15 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/memory-db.d.ts +17 -0
- package/dist/workflows/memory-db.d.ts.map +1 -0
- package/dist/workflows/memory-db.js +33 -0
- package/dist/workflows/memory-db.js.map +1 -0
- package/dist/workflows/run.d.ts +38 -0
- package/dist/workflows/run.d.ts.map +1 -0
- package/dist/workflows/run.js +25 -0
- package/dist/workflows/run.js.map +1 -0
- package/dist/workflows/runner.d.ts +320 -0
- package/dist/workflows/runner.d.ts.map +1 -0
- package/dist/workflows/runner.js +2821 -0
- package/dist/workflows/runner.js.map +1 -0
- package/dist/workflows/state.d.ts +77 -0
- package/dist/workflows/state.d.ts.map +1 -0
- package/dist/workflows/state.js +140 -0
- package/dist/workflows/state.js.map +1 -0
- package/dist/workflows/templates.d.ts +47 -0
- package/dist/workflows/templates.d.ts.map +1 -0
- package/dist/workflows/templates.js +405 -0
- package/dist/workflows/templates.js.map +1 -0
- package/dist/workflows/trajectory.d.ts +87 -0
- package/dist/workflows/trajectory.d.ts.map +1 -0
- package/dist/workflows/trajectory.js +441 -0
- package/dist/workflows/trajectory.js.map +1 -0
- package/dist/workflows/types.d.ts +306 -0
- package/dist/workflows/types.d.ts.map +1 -0
- package/dist/workflows/types.js +23 -0
- package/dist/workflows/types.js.map +1 -0
- package/dist/workflows/validator.d.ts +11 -0
- package/dist/workflows/validator.d.ts.map +1 -0
- package/dist/workflows/validator.js +128 -0
- package/dist/workflows/validator.js.map +1 -0
- package/package.json +59 -53
- package/dist/discovery.d.ts +0 -10
- package/dist/discovery.d.ts.map +0 -1
- package/dist/discovery.js +0 -22
- package/dist/discovery.js.map +0 -1
- package/dist/errors.d.ts +0 -9
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -9
- package/dist/errors.js.map +0 -1
- package/dist/protocol/index.d.ts +0 -8
- package/dist/protocol/index.d.ts.map +0 -1
- package/dist/protocol/index.js +0 -8
- package/dist/protocol/index.js.map +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-fixtures.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/contract-fixtures.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import test from 'node:test';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { AgentRelayClient, AgentRelayProtocolError } from '../client.js';
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
const fixturesDir = path.resolve(__dirname, '../../../contracts/fixtures');
|
|
10
|
+
function readFixture(name) {
|
|
11
|
+
const fixturePath = path.join(fixturesDir, name);
|
|
12
|
+
const raw = fs.readFileSync(fixturePath, 'utf8');
|
|
13
|
+
return JSON.parse(raw);
|
|
14
|
+
}
|
|
15
|
+
function isCurrentSdkBrokerEventShape(event) {
|
|
16
|
+
const kind = event.kind;
|
|
17
|
+
if (typeof kind !== 'string')
|
|
18
|
+
return false;
|
|
19
|
+
switch (kind) {
|
|
20
|
+
case 'relay_inbound':
|
|
21
|
+
return (typeof event.event_id === 'string' &&
|
|
22
|
+
typeof event.from === 'string' &&
|
|
23
|
+
typeof event.target === 'string' &&
|
|
24
|
+
typeof event.body === 'string');
|
|
25
|
+
case 'agent_spawned':
|
|
26
|
+
return typeof event.name === 'string' && typeof event.runtime === 'string';
|
|
27
|
+
case 'agent_exited':
|
|
28
|
+
return typeof event.name === 'string';
|
|
29
|
+
case 'agent_released':
|
|
30
|
+
return typeof event.name === 'string';
|
|
31
|
+
case 'worker_ready':
|
|
32
|
+
return typeof event.name === 'string' && typeof event.runtime === 'string';
|
|
33
|
+
case 'agent_idle':
|
|
34
|
+
return typeof event.name === 'string' && typeof event.idle_secs === 'number';
|
|
35
|
+
case 'delivery_verified':
|
|
36
|
+
return (typeof event.name === 'string' &&
|
|
37
|
+
typeof event.delivery_id === 'string' &&
|
|
38
|
+
typeof event.event_id === 'string');
|
|
39
|
+
case 'delivery_failed':
|
|
40
|
+
return (typeof event.name === 'string' &&
|
|
41
|
+
typeof event.delivery_id === 'string' &&
|
|
42
|
+
typeof event.event_id === 'string' &&
|
|
43
|
+
typeof event.reason === 'string');
|
|
44
|
+
case 'worker_error':
|
|
45
|
+
return (typeof event.name === 'string' &&
|
|
46
|
+
typeof event.code === 'string' &&
|
|
47
|
+
typeof event.message === 'string');
|
|
48
|
+
case 'agent_restarting':
|
|
49
|
+
case 'agent_restarted':
|
|
50
|
+
case 'agent_permanently_dead':
|
|
51
|
+
return typeof event.name === 'string';
|
|
52
|
+
default:
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
test('contracts: broker-sdk unsupported_operation fallback maps to shared RelayErrorCode set', async () => {
|
|
57
|
+
const fixture = readFixture('error-fixtures.json');
|
|
58
|
+
const allowedCodes = new Set(fixture.relay_errors.map((entry) => entry.code));
|
|
59
|
+
const client = new AgentRelayClient();
|
|
60
|
+
client.start = async () => undefined;
|
|
61
|
+
client.requestOk = async () => {
|
|
62
|
+
throw new AgentRelayProtocolError({
|
|
63
|
+
code: 'unsupported_operation',
|
|
64
|
+
message: 'send_message unsupported',
|
|
65
|
+
retryable: false,
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
const result = await client.sendMessage({
|
|
69
|
+
to: 'WorkerA',
|
|
70
|
+
text: 'contract-gate probe',
|
|
71
|
+
});
|
|
72
|
+
assert.equal(result.event_id, 'unsupported_operation');
|
|
73
|
+
// TODO(contract-wave1-error-codes): broker-sdk fallback sentinel should align
|
|
74
|
+
// with shared RelayErrorCode contracts, or be mapped before surface exposure.
|
|
75
|
+
assert.equal(allowedCodes.has(result.event_id), true, `unsupported fallback code \"${result.event_id}\" is outside shared RelayErrorCode fixture set`);
|
|
76
|
+
});
|
|
77
|
+
test('contracts: broker-sdk event surface conforms to shared BrokerEvent fixture envelope', async () => {
|
|
78
|
+
const fixture = readFixture('event-fixtures.json');
|
|
79
|
+
for (const event of fixture.contract_events) {
|
|
80
|
+
// TODO(contract-wave1-event-envelope): broker-sdk should consume/emit the
|
|
81
|
+
// shared envelope shape (eventId/seq/timestamp/payload) from contracts fixtures.
|
|
82
|
+
assert.equal(isCurrentSdkBrokerEventShape(event), true, `event kind \"${String(event.kind)}\" does not match current broker-sdk event surface`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=contract-fixtures.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-fixtures.test.js","sourceRoot":"","sources":["../../src/__tests__/contract-fixtures.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facade.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/facade.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facade integration tests — exercises new AgentRelay capabilities:
|
|
3
|
+
* spawn with initial task, getLogs, waitForAny, broadcast, onAgentReady, exit code.
|
|
4
|
+
*
|
|
5
|
+
* Run:
|
|
6
|
+
* npm run build && node --test dist/__tests__/facade.test.js
|
|
7
|
+
*
|
|
8
|
+
* Requires:
|
|
9
|
+
* RELAY_API_KEY — Relaycast workspace key
|
|
10
|
+
* AGENT_RELAY_BIN (optional) — path to agent-relay-broker binary
|
|
11
|
+
*/
|
|
12
|
+
import assert from "node:assert/strict";
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import test from "node:test";
|
|
16
|
+
import { AgentRelay } from "../relay.js";
|
|
17
|
+
// ── helpers ─────────────────────────────────────────────────────────────────
|
|
18
|
+
function resolveBinaryPath() {
|
|
19
|
+
if (process.env.AGENT_RELAY_BIN) {
|
|
20
|
+
return process.env.AGENT_RELAY_BIN;
|
|
21
|
+
}
|
|
22
|
+
return path.resolve(process.cwd(), "../../target/debug/agent-relay-broker");
|
|
23
|
+
}
|
|
24
|
+
function requireRelaycast(t) {
|
|
25
|
+
if (!process.env.RELAY_API_KEY?.trim()) {
|
|
26
|
+
t.skip("RELAY_API_KEY is required");
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
function requireBinary(t) {
|
|
32
|
+
const bin = resolveBinaryPath();
|
|
33
|
+
if (!fs.existsSync(bin)) {
|
|
34
|
+
t.skip(`agent-relay-broker binary not found at ${bin}`);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return bin;
|
|
38
|
+
}
|
|
39
|
+
function makeRelay(bin) {
|
|
40
|
+
return new AgentRelay({
|
|
41
|
+
binaryPath: bin,
|
|
42
|
+
requestTimeoutMs: 10_000,
|
|
43
|
+
env: process.env,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// ── spawn with initial task ─────────────────────────────────────────────────
|
|
47
|
+
test("facade: spawn with initial task delivers task after worker_ready", async (t) => {
|
|
48
|
+
if (!requireRelaycast(t))
|
|
49
|
+
return;
|
|
50
|
+
const bin = requireBinary(t);
|
|
51
|
+
if (!bin)
|
|
52
|
+
return;
|
|
53
|
+
const suffix = Date.now().toString(36);
|
|
54
|
+
const relay = makeRelay(bin);
|
|
55
|
+
const readyNames = [];
|
|
56
|
+
relay.onAgentReady = (agent) => readyNames.push(agent.name);
|
|
57
|
+
try {
|
|
58
|
+
const agent = await relay.spawnPty({
|
|
59
|
+
name: `Task-${suffix}`,
|
|
60
|
+
cli: "cat",
|
|
61
|
+
channels: ["general"],
|
|
62
|
+
task: "Hello from initial task",
|
|
63
|
+
});
|
|
64
|
+
// Wait a bit for worker_ready event to propagate
|
|
65
|
+
await new Promise((r) => setTimeout(r, 2_000));
|
|
66
|
+
assert.ok(readyNames.includes(agent.name), "onAgentReady should fire for spawned agent");
|
|
67
|
+
await agent.release();
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
await relay.shutdown();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
// ── onAgentReady ────────────────────────────────────────────────────────────
|
|
74
|
+
test("facade: onAgentReady fires when worker becomes ready", async (t) => {
|
|
75
|
+
if (!requireRelaycast(t))
|
|
76
|
+
return;
|
|
77
|
+
const bin = requireBinary(t);
|
|
78
|
+
if (!bin)
|
|
79
|
+
return;
|
|
80
|
+
const suffix = Date.now().toString(36);
|
|
81
|
+
const relay = makeRelay(bin);
|
|
82
|
+
const readyAgents = [];
|
|
83
|
+
relay.onAgentReady = (agent) => readyAgents.push(agent);
|
|
84
|
+
try {
|
|
85
|
+
const agent = await relay.spawnPty({
|
|
86
|
+
name: `Ready-${suffix}`,
|
|
87
|
+
cli: "cat",
|
|
88
|
+
channels: ["general"],
|
|
89
|
+
});
|
|
90
|
+
// Give the worker time to send worker_ready
|
|
91
|
+
await new Promise((r) => setTimeout(r, 2_000));
|
|
92
|
+
assert.ok(readyAgents.some((a) => a.name === agent.name), "onAgentReady should fire with the correct agent");
|
|
93
|
+
await agent.release();
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await relay.shutdown();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// ── broadcast ───────────────────────────────────────────────────────────────
|
|
100
|
+
test("facade: broadcast sends to all agents", async (t) => {
|
|
101
|
+
if (!requireRelaycast(t))
|
|
102
|
+
return;
|
|
103
|
+
const bin = requireBinary(t);
|
|
104
|
+
if (!bin)
|
|
105
|
+
return;
|
|
106
|
+
const suffix = Date.now().toString(36);
|
|
107
|
+
const relay = makeRelay(bin);
|
|
108
|
+
const sentMessages = [];
|
|
109
|
+
relay.onMessageSent = (msg) => sentMessages.push(msg);
|
|
110
|
+
try {
|
|
111
|
+
const agent = await relay.spawnPty({
|
|
112
|
+
name: `Broadcast-${suffix}`,
|
|
113
|
+
cli: "cat",
|
|
114
|
+
channels: ["general"],
|
|
115
|
+
});
|
|
116
|
+
const msg = await relay.broadcast("Hello everyone!");
|
|
117
|
+
assert.equal(msg.to, "*");
|
|
118
|
+
assert.equal(msg.text, "Hello everyone!");
|
|
119
|
+
assert.equal(msg.from, "human:orchestrator");
|
|
120
|
+
assert.equal(sentMessages.length, 1);
|
|
121
|
+
// Broadcast with custom from
|
|
122
|
+
const msg2 = await relay.broadcast("Custom sender", { from: "System" });
|
|
123
|
+
assert.equal(msg2.from, "System");
|
|
124
|
+
await agent.release();
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
await relay.shutdown();
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
// ── waitForAny ──────────────────────────────────────────────────────────────
|
|
131
|
+
test("facade: waitForAny returns first agent to exit", async (t) => {
|
|
132
|
+
if (!requireRelaycast(t))
|
|
133
|
+
return;
|
|
134
|
+
const bin = requireBinary(t);
|
|
135
|
+
if (!bin)
|
|
136
|
+
return;
|
|
137
|
+
const suffix = Date.now().toString(36);
|
|
138
|
+
const relay = makeRelay(bin);
|
|
139
|
+
try {
|
|
140
|
+
const [a, b] = await Promise.all([
|
|
141
|
+
relay.spawnPty({ name: `WaitA-${suffix}`, cli: "cat", channels: ["general"] }),
|
|
142
|
+
relay.spawnPty({ name: `WaitB-${suffix}`, cli: "cat", channels: ["general"] }),
|
|
143
|
+
]);
|
|
144
|
+
// Release agent A — it should be the first to exit
|
|
145
|
+
setTimeout(() => a.release(), 500);
|
|
146
|
+
const { agent, result } = await AgentRelay.waitForAny([a, b], 10_000);
|
|
147
|
+
assert.equal(agent.name, a.name);
|
|
148
|
+
assert.equal(result, "released");
|
|
149
|
+
await b.release();
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
await relay.shutdown();
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
// ── waitForAny with timeout ─────────────────────────────────────────────────
|
|
156
|
+
test("facade: waitForAny respects timeout", async (t) => {
|
|
157
|
+
if (!requireRelaycast(t))
|
|
158
|
+
return;
|
|
159
|
+
const bin = requireBinary(t);
|
|
160
|
+
if (!bin)
|
|
161
|
+
return;
|
|
162
|
+
const suffix = Date.now().toString(36);
|
|
163
|
+
const relay = makeRelay(bin);
|
|
164
|
+
try {
|
|
165
|
+
const agent = await relay.spawnPty({
|
|
166
|
+
name: `Timeout-${suffix}`,
|
|
167
|
+
cli: "cat",
|
|
168
|
+
channels: ["general"],
|
|
169
|
+
});
|
|
170
|
+
const { result } = await AgentRelay.waitForAny([agent], 500);
|
|
171
|
+
assert.equal(result, "timeout");
|
|
172
|
+
await agent.release();
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
await relay.shutdown();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
// ── exit code ───────────────────────────────────────────────────────────────
|
|
179
|
+
test("facade: onAgentExited populates exitCode and exitSignal", async (t) => {
|
|
180
|
+
if (!requireRelaycast(t))
|
|
181
|
+
return;
|
|
182
|
+
const bin = requireBinary(t);
|
|
183
|
+
if (!bin)
|
|
184
|
+
return;
|
|
185
|
+
const suffix = Date.now().toString(36);
|
|
186
|
+
const relay = makeRelay(bin);
|
|
187
|
+
const exitedAgents = [];
|
|
188
|
+
relay.onAgentExited = (agent) => exitedAgents.push(agent);
|
|
189
|
+
try {
|
|
190
|
+
const agent = await relay.spawnPty({
|
|
191
|
+
name: `Exit-${suffix}`,
|
|
192
|
+
cli: "cat",
|
|
193
|
+
channels: ["general"],
|
|
194
|
+
});
|
|
195
|
+
await agent.release();
|
|
196
|
+
// Give time for exit event to propagate
|
|
197
|
+
await new Promise((r) => setTimeout(r, 1_000));
|
|
198
|
+
// The agent should have exited — check that exitCode or exitSignal is set
|
|
199
|
+
// (exact values depend on how cat is terminated)
|
|
200
|
+
const exited = exitedAgents.find((a) => a.name === agent.name);
|
|
201
|
+
if (exited) {
|
|
202
|
+
assert.ok(exited.exitCode !== undefined || exited.exitSignal !== undefined, "exitCode or exitSignal should be populated");
|
|
203
|
+
}
|
|
204
|
+
// It's also valid for only onAgentReleased to fire (not onAgentExited)
|
|
205
|
+
// since the broker may clean up before the process exits
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
await relay.shutdown();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
// ── getLogs ──────────────────────────────────────────────────────────────────
|
|
212
|
+
test("facade: getLogs returns log content for agent", async (t) => {
|
|
213
|
+
if (!requireRelaycast(t))
|
|
214
|
+
return;
|
|
215
|
+
const bin = requireBinary(t);
|
|
216
|
+
if (!bin)
|
|
217
|
+
return;
|
|
218
|
+
const suffix = Date.now().toString(36);
|
|
219
|
+
const relay = makeRelay(bin);
|
|
220
|
+
try {
|
|
221
|
+
const agent = await relay.spawnPty({
|
|
222
|
+
name: `Logs-${suffix}`,
|
|
223
|
+
cli: "cat",
|
|
224
|
+
channels: ["general"],
|
|
225
|
+
});
|
|
226
|
+
// Give time for some output to be logged
|
|
227
|
+
await new Promise((r) => setTimeout(r, 2_000));
|
|
228
|
+
const logs = await relay.getLogs(agent.name);
|
|
229
|
+
// Logs may or may not be found depending on whether the worker writes to the log file
|
|
230
|
+
// The important thing is the API works without error
|
|
231
|
+
assert.equal(logs.agent, agent.name);
|
|
232
|
+
assert.equal(typeof logs.found, "boolean");
|
|
233
|
+
assert.equal(typeof logs.content, "string");
|
|
234
|
+
await agent.release();
|
|
235
|
+
}
|
|
236
|
+
finally {
|
|
237
|
+
await relay.shutdown();
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
// ── listLoggedAgents ────────────────────────────────────────────────────────
|
|
241
|
+
test("facade: listLoggedAgents returns array", async (t) => {
|
|
242
|
+
if (!requireRelaycast(t))
|
|
243
|
+
return;
|
|
244
|
+
const bin = requireBinary(t);
|
|
245
|
+
if (!bin)
|
|
246
|
+
return;
|
|
247
|
+
const relay = makeRelay(bin);
|
|
248
|
+
try {
|
|
249
|
+
// Just verify the API works and returns an array
|
|
250
|
+
const agents = await relay.listLoggedAgents();
|
|
251
|
+
assert.ok(Array.isArray(agents));
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
await relay.shutdown();
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
//# sourceMappingURL=facade.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facade.test.js","sourceRoot":"","sources":["../../src/__tests__/facade.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import test, { before } from 'node:test';
|
|
6
|
+
import { AgentRelayClient, AgentRelayProcessError } from '../client.js';
|
|
7
|
+
import { RelayCast } from '@relaycast/sdk';
|
|
8
|
+
function resolveBinaryPath() {
|
|
9
|
+
if (process.env.AGENT_RELAY_BIN) {
|
|
10
|
+
return process.env.AGENT_RELAY_BIN;
|
|
11
|
+
}
|
|
12
|
+
return path.resolve(process.cwd(), '../../target/debug/agent-relay-broker');
|
|
13
|
+
}
|
|
14
|
+
function resolveBundledBinaryPath() {
|
|
15
|
+
const exe = process.platform === 'win32' ? 'agent-relay-broker.exe' : 'agent-relay-broker';
|
|
16
|
+
return path.resolve(process.cwd(), 'bin', exe);
|
|
17
|
+
}
|
|
18
|
+
// Ensure RELAY_API_KEY is available before any tests run.
|
|
19
|
+
// Creates an ephemeral workspace if no key is set.
|
|
20
|
+
before(async () => {
|
|
21
|
+
if (process.env.RELAY_API_KEY?.trim())
|
|
22
|
+
return;
|
|
23
|
+
const ws = await RelayCast.createWorkspace(`sdk-test-${Date.now().toString(36)}`);
|
|
24
|
+
process.env.RELAY_API_KEY = ws.apiKey;
|
|
25
|
+
});
|
|
26
|
+
test('sdk can use bundled binary by default', async (t) => {
|
|
27
|
+
const bundledBinary = resolveBundledBinaryPath();
|
|
28
|
+
if (!fs.existsSync(bundledBinary)) {
|
|
29
|
+
t.skip(`bundled binary not found at ${bundledBinary}`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const client = await AgentRelayClient.start({
|
|
33
|
+
env: process.env,
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
const agents = await client.listAgents();
|
|
37
|
+
assert.ok(Array.isArray(agents), 'listAgents should return an array');
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
await client.shutdown();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
test('sdk can start broker and manage agent lifecycle', async (t) => {
|
|
44
|
+
const binaryPath = resolveBinaryPath();
|
|
45
|
+
if (!fs.existsSync(binaryPath)) {
|
|
46
|
+
t.skip(`agent-relay-broker binary not found at ${binaryPath}`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const client = await AgentRelayClient.start({
|
|
50
|
+
binaryPath,
|
|
51
|
+
requestTimeoutMs: 8_000,
|
|
52
|
+
shutdownTimeoutMs: 2_000,
|
|
53
|
+
env: process.env,
|
|
54
|
+
});
|
|
55
|
+
const spawnedName = `sdk-test-${Date.now().toString(36)}`;
|
|
56
|
+
const seenEvents = [];
|
|
57
|
+
const unsub = client.onEvent((event) => {
|
|
58
|
+
seenEvents.push(event.kind);
|
|
59
|
+
});
|
|
60
|
+
try {
|
|
61
|
+
const spawned = await client.spawnPty({
|
|
62
|
+
name: spawnedName,
|
|
63
|
+
cli: 'cat',
|
|
64
|
+
channels: ['general'],
|
|
65
|
+
});
|
|
66
|
+
assert.equal(spawned.name, spawnedName);
|
|
67
|
+
assert.equal(spawned.runtime, 'pty');
|
|
68
|
+
const agentsAfterSpawn = await client.listAgents();
|
|
69
|
+
const spawnedAgent = agentsAfterSpawn.find((agent) => agent.name === spawnedName);
|
|
70
|
+
assert.ok(spawnedAgent, 'spawned agent should be present in listAgents()');
|
|
71
|
+
assert.equal(spawnedAgent?.runtime, 'pty');
|
|
72
|
+
const released = await client.release(spawnedName);
|
|
73
|
+
assert.equal(released.name, spawnedName);
|
|
74
|
+
const agentsAfterRelease = await client.listAgents();
|
|
75
|
+
assert.equal(agentsAfterRelease.some((agent) => agent.name === spawnedName), false, 'released agent should not be present in listAgents()');
|
|
76
|
+
assert.ok(seenEvents.includes('agent_spawned'), 'expected agent_spawned event');
|
|
77
|
+
assert.ok(seenEvents.includes('agent_released'), 'expected agent_released event');
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
unsub();
|
|
81
|
+
await client.shutdown();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
test('sdk can spawn and release headless claude worker', async (t) => {
|
|
85
|
+
const binaryPath = resolveBinaryPath();
|
|
86
|
+
if (!fs.existsSync(binaryPath)) {
|
|
87
|
+
t.skip(`agent-relay-broker binary not found at ${binaryPath}`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const client = await AgentRelayClient.start({
|
|
91
|
+
binaryPath,
|
|
92
|
+
requestTimeoutMs: 8_000,
|
|
93
|
+
shutdownTimeoutMs: 2_000,
|
|
94
|
+
env: process.env,
|
|
95
|
+
});
|
|
96
|
+
const spawnedName = `sdk-headless-${Date.now().toString(36)}`;
|
|
97
|
+
const seenEvents = [];
|
|
98
|
+
const unsub = client.onEvent((event) => {
|
|
99
|
+
seenEvents.push(event.kind);
|
|
100
|
+
});
|
|
101
|
+
try {
|
|
102
|
+
const spawned = await client.spawnHeadlessClaude({
|
|
103
|
+
name: spawnedName,
|
|
104
|
+
channels: ['general'],
|
|
105
|
+
});
|
|
106
|
+
assert.equal(spawned.name, spawnedName);
|
|
107
|
+
assert.equal(spawned.runtime, 'headless_claude');
|
|
108
|
+
const agentsAfterSpawn = await client.listAgents();
|
|
109
|
+
const spawnedAgent = agentsAfterSpawn.find((agent) => agent.name === spawnedName);
|
|
110
|
+
assert.ok(spawnedAgent, 'spawned headless agent should be present in listAgents()');
|
|
111
|
+
assert.equal(spawnedAgent?.runtime, 'headless_claude');
|
|
112
|
+
const released = await client.release(spawnedName);
|
|
113
|
+
assert.equal(released.name, spawnedName);
|
|
114
|
+
const agentsAfterRelease = await client.listAgents();
|
|
115
|
+
assert.equal(agentsAfterRelease.some((agent) => agent.name === spawnedName), false, 'released headless agent should not be present in listAgents()');
|
|
116
|
+
assert.ok(seenEvents.includes('agent_spawned'), 'expected agent_spawned event');
|
|
117
|
+
assert.ok(seenEvents.includes('agent_released'), 'expected agent_released event');
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
unsub();
|
|
121
|
+
await client.shutdown();
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
test('sdk surfaces process error when binary is missing', async () => {
|
|
125
|
+
await assert.rejects(AgentRelayClient.start({
|
|
126
|
+
binaryPath: '/definitely/missing/agent-relay-broker',
|
|
127
|
+
requestTimeoutMs: 1_000,
|
|
128
|
+
}), (error) => {
|
|
129
|
+
return error instanceof AgentRelayProcessError || error instanceof Error;
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
test('sdk includes broker stderr details when startup fails', async (t) => {
|
|
133
|
+
const binaryPath = resolveBinaryPath();
|
|
134
|
+
if (!fs.existsSync(binaryPath)) {
|
|
135
|
+
t.skip(`agent-relay-broker binary not found at ${binaryPath}`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'sdk-broker-lock-'));
|
|
139
|
+
const first = await AgentRelayClient.start({
|
|
140
|
+
binaryPath,
|
|
141
|
+
cwd,
|
|
142
|
+
requestTimeoutMs: 8_000,
|
|
143
|
+
shutdownTimeoutMs: 2_000,
|
|
144
|
+
env: process.env,
|
|
145
|
+
});
|
|
146
|
+
try {
|
|
147
|
+
await assert.rejects(AgentRelayClient.start({
|
|
148
|
+
binaryPath,
|
|
149
|
+
cwd,
|
|
150
|
+
requestTimeoutMs: 2_000,
|
|
151
|
+
shutdownTimeoutMs: 2_000,
|
|
152
|
+
env: process.env,
|
|
153
|
+
}), (error) => {
|
|
154
|
+
assert.ok(error instanceof AgentRelayProcessError || error instanceof Error);
|
|
155
|
+
assert.match(String(error.message), /another broker instance is already running/i);
|
|
156
|
+
return true;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
await first.shutdown();
|
|
161
|
+
fs.rmSync(cwd, { recursive: true, force: true });
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
//# sourceMappingURL=integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,SAAS,iBAAiB;IACxB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,uCAAuC,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,wBAAwB;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAC3F,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,0DAA0D;AAC1D,mDAAmD;AACnD,MAAM,CAAC,KAAK,IAAI,EAAE;IAChB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE;QAAE,OAAO;IAC9C,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,eAAe,CAAC,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,EAAE,CAAC,MAAM,CAAC;AACxC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACxD,MAAM,aAAa,GAAG,wBAAwB,EAAE,CAAC;IACjD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,CAAC,CAAC,IAAI,CAAC,+BAA+B,aAAa,EAAE,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC;QAC1C,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,mCAAmC,CAAC,CAAC;IACxE,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iDAAiD,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAClE,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,CAAC,CAAC,IAAI,CAAC,0CAA0C,UAAU,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC;QAC1C,UAAU;QACV,gBAAgB,EAAE,KAAK;QACvB,iBAAiB,EAAE,KAAK;QACxB,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IAC1D,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACrC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;YACpC,IAAI,EAAE,WAAW;YACjB,GAAG,EAAE,KAAK;YACV,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAErC,MAAM,gBAAgB,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QACnD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;QAClF,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,iDAAiD,CAAC,CAAC;QAC3E,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAE3C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAEzC,MAAM,kBAAkB,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QACrD,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,EAC9D,KAAK,EACL,sDAAsD,CACvD,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,8BAA8B,CAAC,CAAC;QAChF,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,+BAA+B,CAAC,CAAC;IACpF,CAAC;YAAS,CAAC;QACT,KAAK,EAAE,CAAC;QACR,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACnE,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,CAAC,CAAC,IAAI,CAAC,0CAA0C,UAAU,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC;QAC1C,UAAU;QACV,gBAAgB,EAAE,KAAK;QACvB,iBAAiB,EAAE,KAAK;QACxB,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,gBAAgB,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IAC9D,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACrC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC;YAC/C,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAEjD,MAAM,gBAAgB,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QACnD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;QAClF,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,0DAA0D,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAEvD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAEzC,MAAM,kBAAkB,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QACrD,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,EAC9D,KAAK,EACL,+DAA+D,CAChE,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,8BAA8B,CAAC,CAAC;QAChF,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,+BAA+B,CAAC,CAAC;IACpF,CAAC;YAAS,CAAC;QACT,KAAK,EAAE,CAAC;QACR,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;IACnE,MAAM,MAAM,CAAC,OAAO,CAClB,gBAAgB,CAAC,KAAK,CAAC;QACrB,UAAU,EAAE,wCAAwC;QACpD,gBAAgB,EAAE,KAAK;KACxB,CAAC,EACF,CAAC,KAAc,EAAE,EAAE;QACjB,OAAO,KAAK,YAAY,sBAAsB,IAAI,KAAK,YAAY,KAAK,CAAC;IAC3E,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uDAAuD,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACxE,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,CAAC,CAAC,IAAI,CAAC,0CAA0C,UAAU,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC;QACzC,UAAU;QACV,GAAG;QACH,gBAAgB,EAAE,KAAK;QACvB,iBAAiB,EAAE,KAAK;QACxB,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAClB,gBAAgB,CAAC,KAAK,CAAC;YACrB,UAAU;YACV,GAAG;YACH,gBAAgB,EAAE,KAAK;YACvB,iBAAiB,EAAE,KAAK;YACxB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,EACF,CAAC,KAAc,EAAE,EAAE;YACjB,MAAM,CAAC,EAAE,CAAC,KAAK,YAAY,sBAAsB,IAAI,KAAK,YAAY,KAAK,CAAC,CAAC;YAC7E,MAAM,CAAC,KAAK,CAAC,MAAM,CAAE,KAAe,CAAC,OAAO,CAAC,EAAE,6CAA6C,CAAC,CAAC;YAC9F,OAAO,IAAI,CAAC;QACd,CAAC,CACF,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;QACvB,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pty.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { cleanLines, stripAnsi } from "../pty.js";
|
|
4
|
+
test("stripAnsi: strips CSI/OSC sequences", () => {
|
|
5
|
+
assert.equal(stripAnsi("\x1b[32mgreen\x1b[0m"), "green");
|
|
6
|
+
assert.equal(stripAnsi("\x1b]0;title\x07text"), "text");
|
|
7
|
+
});
|
|
8
|
+
test("stripAnsi: preserves cursor-forward spacing for ANSI CSI", () => {
|
|
9
|
+
const input = "\x1b[1CYes,\x1b[2CI\x1b[1Caccept";
|
|
10
|
+
assert.equal(stripAnsi(input), " Yes, I accept");
|
|
11
|
+
});
|
|
12
|
+
test("stripAnsi: preserves cursor-forward spacing for orphaned CSI", () => {
|
|
13
|
+
const input = "[1CYes,[2CI[1Caccept";
|
|
14
|
+
assert.equal(stripAnsi(input), " Yes, I accept");
|
|
15
|
+
});
|
|
16
|
+
test("cleanLines: strips ANSI and keeps non-empty lines", () => {
|
|
17
|
+
const lines = cleanLines("\x1b[32mline-1\x1b[0m\n\nline-2\n");
|
|
18
|
+
assert.deepEqual(lines, ["line-1", "line-2"]);
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=pty.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty.test.js","sourceRoot":"","sources":["../../src/__tests__/pty.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAElD,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE;IAC/C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC,CAAC;IACzD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC,CAAC;AAC1D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0DAA0D,EAAE,GAAG,EAAE;IACpE,MAAM,KAAK,GAAG,kCAAkC,CAAC;IACjD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8DAA8D,EAAE,GAAG,EAAE;IACxE,MAAM,KAAK,GAAG,sBAAsB,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC7D,MAAM,KAAK,GAAG,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAC9D,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/quickstart.test.ts"],"names":[],"mappings":""}
|