@realtimex/sdk 1.7.28 → 2.0.1
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/dist/chunk-ORAAYW4C.mjs +271 -0
- package/dist/errors-C98IGxYU.d.mts +168 -0
- package/dist/errors-C98IGxYU.d.ts +168 -0
- package/dist/index.d.mts +8 -2048
- package/dist/index.d.ts +8 -2048
- package/dist/index.js +168 -4723
- package/dist/index.mjs +7 -3783
- package/dist/v1/index.d.mts +3 -56
- package/dist/v1/index.d.ts +3 -56
- package/dist/v1/index.js +2 -756
- package/dist/v1/index.mjs +2 -42
- package/package.json +6 -7
- package/dist/chunk-Z5GAUBIM.mjs +0 -993
- package/dist/errors-NufsyIZ-.d.mts +0 -678
- package/dist/errors-NufsyIZ-.d.ts +0 -678
- package/skills/realtimex-moderator-sdk/SKILL.md +0 -102
- package/skills/realtimex-moderator-sdk/references/activities.md +0 -14
- package/skills/realtimex-moderator-sdk/references/agents.md +0 -13
- package/skills/realtimex-moderator-sdk/references/api-reference/acpagent.md +0 -105
- package/skills/realtimex-moderator-sdk/references/api-reference/activities.md +0 -24
- package/skills/realtimex-moderator-sdk/references/api-reference/agent.md +0 -27
- package/skills/realtimex-moderator-sdk/references/api-reference/api.md +0 -17
- package/skills/realtimex-moderator-sdk/references/api-reference/auth.md +0 -36
- package/skills/realtimex-moderator-sdk/references/api-reference/contract.md +0 -27
- package/skills/realtimex-moderator-sdk/references/api-reference/core.md +0 -40
- package/skills/realtimex-moderator-sdk/references/api-reference/database.md +0 -24
- package/skills/realtimex-moderator-sdk/references/api-reference/index.md +0 -43
- package/skills/realtimex-moderator-sdk/references/api-reference/llm.md +0 -176
- package/skills/realtimex-moderator-sdk/references/api-reference/mcp.md +0 -50
- package/skills/realtimex-moderator-sdk/references/api-reference/port.md +0 -21
- package/skills/realtimex-moderator-sdk/references/api-reference/stt.md +0 -15
- package/skills/realtimex-moderator-sdk/references/api-reference/task.md +0 -62
- package/skills/realtimex-moderator-sdk/references/api-reference/tts.md +0 -18
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-acpauth.md +0 -21
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-acpcommands.md +0 -15
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-admin.md +0 -48
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-auth.md +0 -18
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-channels.md +0 -78
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-credentials.md +0 -27
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-customthemes.md +0 -24
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-desktopbrowser.md +0 -39
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-desktopembed.md +0 -24
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-desktopruntimesessions.md +0 -33
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-document.md +0 -39
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-embed.md +0 -27
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-openai.md +0 -21
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-sttapi.md +0 -12
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-system.md +0 -36
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-thread.md +0 -26
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-users.md +0 -15
- package/skills/realtimex-moderator-sdk/references/api-reference/v1-workspace.md +0 -39
- package/skills/realtimex-moderator-sdk/references/api-reference/webhook.md +0 -13
- package/skills/realtimex-moderator-sdk/references/api-reference.md +0 -1330
- package/skills/realtimex-moderator-sdk/references/app-concepts.md +0 -1276
- package/skills/realtimex-moderator-sdk/references/browser.md +0 -27
- package/skills/realtimex-moderator-sdk/references/channels.md +0 -189
- package/skills/realtimex-moderator-sdk/references/credentials.md +0 -111
- package/skills/realtimex-moderator-sdk/references/known-issues.md +0 -237
- package/skills/realtimex-moderator-sdk/references/llm.md +0 -13
- package/skills/realtimex-moderator-sdk/references/mcp.md +0 -13
- package/skills/realtimex-moderator-sdk/references/permissions.md +0 -30
- package/skills/realtimex-moderator-sdk/references/quickstart.md +0 -16
- package/skills/realtimex-moderator-sdk/references/terminal-sessions.md +0 -34
- package/skills/realtimex-moderator-sdk/references/workspaces.md +0 -20
- package/skills/realtimex-moderator-sdk/scripts/lib/sdk-init.js +0 -171
- package/skills/realtimex-moderator-sdk/scripts/rtx.js +0 -1359
|
@@ -1,1359 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
/**
|
|
4
|
-
* rtx.js — RealTimeX SDK CLI (source-verified)
|
|
5
|
-
* AUTO-GENERATED by scripts/generate-skill.mjs — do not edit by hand.
|
|
6
|
-
*
|
|
7
|
-
* All method signatures derived from the @realtimex/sdk TypeScript source.
|
|
8
|
-
*
|
|
9
|
-
* Usage: node rtx.js <command> [args...] [--flags]
|
|
10
|
-
* Global flags:
|
|
11
|
-
* --api-key=<key> Override API key
|
|
12
|
-
* --env-dir=<path> Directory containing .env (default: cwd)
|
|
13
|
-
* --url=<url> RealTimeX server URL (default: http://localhost:3001)
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const path = require('path');
|
|
17
|
-
const fs = require('fs');
|
|
18
|
-
const { initSDK } = require('./lib/sdk-init');
|
|
19
|
-
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// Arg parsing
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
function parseArgs(argv) {
|
|
24
|
-
const flags = {}, positional = [];
|
|
25
|
-
for (const arg of argv) {
|
|
26
|
-
if (arg.startsWith('--')) {
|
|
27
|
-
const [k, ...rest] = arg.slice(2).split('=');
|
|
28
|
-
flags[k] = rest.length ? rest.join('=') : true;
|
|
29
|
-
} else { positional.push(arg); }
|
|
30
|
-
}
|
|
31
|
-
return { flags, positional };
|
|
32
|
-
}
|
|
33
|
-
const { flags, positional } = parseArgs(process.argv.slice(2));
|
|
34
|
-
const [command, ...cmdArgs] = positional;
|
|
35
|
-
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
// Helpers
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
|
-
function print(obj) { console.log(JSON.stringify(obj, null, 2)); }
|
|
40
|
-
function printTable(rows, cols) {
|
|
41
|
-
if (!rows?.length) { console.log('(no results)'); return; }
|
|
42
|
-
const keys = cols || Object.keys(rows[0]);
|
|
43
|
-
const widths = keys.map(k => Math.max(k.length, ...rows.map(r => String(r[k] ?? '').length)));
|
|
44
|
-
const pad = (s, w) => String(s ?? '').padEnd(w);
|
|
45
|
-
console.log(keys.map((k, i) => pad(k, widths[i])).join(' '));
|
|
46
|
-
console.log(widths.map(w => '-'.repeat(w)).join(' '));
|
|
47
|
-
for (const r of rows) console.log(keys.map((k, i) => pad(r[k], widths[i])).join(' '));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
let _sdk = null;
|
|
51
|
-
async function getSDK() {
|
|
52
|
-
if (_sdk) return _sdk;
|
|
53
|
-
_sdk = await initSDK({ envDir: flags['env-dir'] || process.cwd(), apiKey: flags['api-key'], url: flags['url'] });
|
|
54
|
-
return _sdk;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function applyWorkspaceThreadDefaults(body = {}, context = {}) {
|
|
58
|
-
const nextBody = { ...body };
|
|
59
|
-
if (!nextBody.workspaceSlug && context?.workspaceSlug) {
|
|
60
|
-
nextBody.workspaceSlug = context.workspaceSlug;
|
|
61
|
-
}
|
|
62
|
-
if (!nextBody.threadSlug && context?.threadSlug) {
|
|
63
|
-
nextBody.threadSlug = context.threadSlug;
|
|
64
|
-
}
|
|
65
|
-
return nextBody;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function resolveWorkspaceFlagOrContext(context = {}) {
|
|
69
|
-
return flags.workspace || context?.workspaceSlug || null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const SKILL_ROOT = path.resolve(__dirname, '..');
|
|
73
|
-
const REFERENCES_DIR = path.join(SKILL_ROOT, 'references');
|
|
74
|
-
|
|
75
|
-
const SKILL_DOCS = {
|
|
76
|
-
core: ['quickstart.md', 'permissions.md', 'workspaces.md'],
|
|
77
|
-
quickstart: ['quickstart.md'],
|
|
78
|
-
permissions: ['permissions.md'],
|
|
79
|
-
workspaces: ['workspaces.md'],
|
|
80
|
-
workspace: ['workspaces.md'],
|
|
81
|
-
threads: ['workspaces.md'],
|
|
82
|
-
agents: ['agents.md'],
|
|
83
|
-
agent: ['agents.md'],
|
|
84
|
-
terminal: ['terminal-sessions.md'],
|
|
85
|
-
terminals: ['terminal-sessions.md'],
|
|
86
|
-
'terminal-sessions': ['terminal-sessions.md'],
|
|
87
|
-
browser: ['browser.md'],
|
|
88
|
-
channels: ['channels.md'],
|
|
89
|
-
channel: ['channels.md'],
|
|
90
|
-
llm: ['llm.md'],
|
|
91
|
-
vectors: ['llm.md'],
|
|
92
|
-
'vector-store': ['llm.md'],
|
|
93
|
-
mcp: ['mcp.md'],
|
|
94
|
-
activities: ['activities.md'],
|
|
95
|
-
activity: ['activities.md'],
|
|
96
|
-
credentials: ['credentials.md'],
|
|
97
|
-
issues: ['known-issues.md'],
|
|
98
|
-
'known-issues': ['known-issues.md'],
|
|
99
|
-
concepts: ['app-concepts.md'],
|
|
100
|
-
api: ['api-reference/index.md'],
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
function readReferenceFile(relPath) {
|
|
104
|
-
const fullPath = path.resolve(REFERENCES_DIR, relPath);
|
|
105
|
-
if (!fullPath.startsWith(REFERENCES_DIR + path.sep)) {
|
|
106
|
-
throw new Error('Invalid skill reference path');
|
|
107
|
-
}
|
|
108
|
-
return fs.readFileSync(fullPath, 'utf-8');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function listApiReferenceSlugs() {
|
|
112
|
-
const apiDir = path.join(REFERENCES_DIR, 'api-reference');
|
|
113
|
-
if (!fs.existsSync(apiDir)) return [];
|
|
114
|
-
return fs.readdirSync(apiDir)
|
|
115
|
-
.filter((file) => file.endsWith('.md') && file !== 'index.md')
|
|
116
|
-
.map((file) => `api:${file.replace(/\.md$/, '')}`)
|
|
117
|
-
.sort();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function resolveSkillDoc(topic) {
|
|
121
|
-
const normalized = String(topic || 'core').trim().toLowerCase();
|
|
122
|
-
if (normalized.startsWith('api:')) {
|
|
123
|
-
const slug = normalized.slice(4);
|
|
124
|
-
if (!slug) return ['api-reference/index.md'];
|
|
125
|
-
return [`api-reference/${slug}.md`];
|
|
126
|
-
}
|
|
127
|
-
return SKILL_DOCS[normalized] || null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function printSkillDoc(topic, { full = false } = {}) {
|
|
131
|
-
const refs = resolveSkillDoc(topic);
|
|
132
|
-
if (!refs) {
|
|
133
|
-
console.error(`Unknown skill topic: ${topic}`);
|
|
134
|
-
console.error('Run: node rtx.js skills list');
|
|
135
|
-
process.exit(1);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const chunks = [];
|
|
139
|
-
for (const rel of refs) {
|
|
140
|
-
chunks.push(readReferenceFile(rel).trimEnd());
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (full && topic !== 'api' && !String(topic || '').startsWith('api:')) {
|
|
144
|
-
chunks.push(readReferenceFile('api-reference/index.md').trimEnd());
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
console.log(chunks.join('\n\n---\n\n'));
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// ---------------------------------------------------------------------------
|
|
151
|
-
// Commands
|
|
152
|
-
// ---------------------------------------------------------------------------
|
|
153
|
-
const CMD = {};
|
|
154
|
-
|
|
155
|
-
CMD.context = async () => {
|
|
156
|
-
const { context } = await getSDK();
|
|
157
|
-
print({
|
|
158
|
-
workspaceSlug: context?.workspaceSlug || null,
|
|
159
|
-
threadSlug: context?.threadSlug || null,
|
|
160
|
-
hasContext: Boolean(context?.workspaceSlug || context?.threadSlug),
|
|
161
|
-
});
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
CMD.skills = async () => {
|
|
165
|
-
const [subcommand, topic] = cmdArgs;
|
|
166
|
-
if (!subcommand || subcommand === 'list') {
|
|
167
|
-
console.log('Available skill topics:');
|
|
168
|
-
for (const key of Object.keys(SKILL_DOCS).sort()) {
|
|
169
|
-
console.log(` ${key}`);
|
|
170
|
-
}
|
|
171
|
-
const apiTopics = listApiReferenceSlugs();
|
|
172
|
-
if (apiTopics.length) {
|
|
173
|
-
console.log('');
|
|
174
|
-
console.log('Available API reference topics:');
|
|
175
|
-
for (const key of apiTopics) {
|
|
176
|
-
console.log(` ${key}`);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
console.log('');
|
|
180
|
-
console.log('Usage: node rtx.js skills get <topic> [--full]');
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (subcommand === 'get') {
|
|
185
|
-
printSkillDoc(topic || 'core', { full: flags.full === true || flags.full === 'true' });
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
console.error('Usage: node rtx.js skills list');
|
|
190
|
-
console.error(' or: node rtx.js skills get <topic> [--full]');
|
|
191
|
-
process.exit(1);
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
// -- ping -------------------------------------------------------------------
|
|
195
|
-
// Source: index.ts → sdk.ping() → { success, mode, appId, timestamp }
|
|
196
|
-
CMD.ping = async () => { const { sdk } = await getSDK(); print(await sdk.ping()); };
|
|
197
|
-
|
|
198
|
-
// -- info -------------------------------------------------------------------
|
|
199
|
-
CMD.info = async () => {
|
|
200
|
-
const { sdk, apiKey } = await getSDK();
|
|
201
|
-
console.log('API key: ' + apiKey.slice(0, 8) + '...');
|
|
202
|
-
try { console.log('Data dir: ' + await sdk.getAppDataDir()); } catch (_) {}
|
|
203
|
-
print(await sdk.ping());
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
// -- agents -----------------------------------------------------------------
|
|
207
|
-
// Source: modules/api.ts → ApiModule.getAgents() → Agent[]
|
|
208
|
-
// Agent: { slug, name, description?, hub_id? }
|
|
209
|
-
// NOTE: on sdk.api, NOT sdk directly
|
|
210
|
-
CMD.agents = async () => {
|
|
211
|
-
const { sdk } = await getSDK();
|
|
212
|
-
printTable(await sdk.api.getAgents(), ['slug', 'name', 'description']);
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
// -- workspaces -------------------------------------------------------------
|
|
216
|
-
// Source: ApiModule.getWorkspaces() → Workspace[] { id, slug, name, type }
|
|
217
|
-
CMD.workspaces = async () => {
|
|
218
|
-
const { sdk } = await getSDK();
|
|
219
|
-
printTable(await sdk.api.getWorkspaces(), ['id', 'slug', 'name', 'type']);
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
// -- threads ----------------------------------------------------------------
|
|
223
|
-
// Source: ApiModule.getThreads(workspaceSlug) → Thread[] { id, slug, name }
|
|
224
|
-
CMD.threads = async () => {
|
|
225
|
-
const [slugArg] = cmdArgs;
|
|
226
|
-
const { sdk, context } = await getSDK();
|
|
227
|
-
const slug = slugArg || resolveWorkspaceFlagOrContext(context);
|
|
228
|
-
if (!slug) { console.error('Usage: rtx.js threads <workspace-slug>'); process.exit(1); }
|
|
229
|
-
printTable(await sdk.api.getThreads(slug), ['id', 'slug', 'name']);
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
// -- task -------------------------------------------------------------------
|
|
233
|
-
// Source: ApiModule.getTask(taskUuid) → Task { uuid, title, status, ..., runs }
|
|
234
|
-
CMD.task = async () => {
|
|
235
|
-
const [uuid] = cmdArgs;
|
|
236
|
-
if (!uuid) { console.error('Usage: rtx.js task <uuid>'); process.exit(1); }
|
|
237
|
-
const { sdk } = await getSDK();
|
|
238
|
-
print(await sdk.api.getTask(uuid));
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
// -- activities -------------------------------------------------------------
|
|
242
|
-
// Source: ActivitiesModule.list(options?) → Activity[] (direct array, NOT { activities: [...] })
|
|
243
|
-
CMD.activities = async () => {
|
|
244
|
-
const { sdk } = await getSDK();
|
|
245
|
-
const opts = {};
|
|
246
|
-
if (flags.status) opts.status = flags.status;
|
|
247
|
-
if (flags.limit) opts.limit = Number(flags.limit);
|
|
248
|
-
if (flags.offset) opts.offset = Number(flags.offset);
|
|
249
|
-
print(await sdk.activities.list(opts));
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
// -- activity-get -----------------------------------------------------------
|
|
253
|
-
// Source: ActivitiesModule.get(id) → Activity | null
|
|
254
|
-
CMD['activity-get'] = async () => {
|
|
255
|
-
const [id] = cmdArgs;
|
|
256
|
-
if (!id) { console.error('Usage: rtx.js activity-get <id>'); process.exit(1); }
|
|
257
|
-
const { sdk } = await getSDK();
|
|
258
|
-
print(await sdk.activities.get(id));
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
// -- activity-create --------------------------------------------------------
|
|
262
|
-
// Source: ActivitiesModule.insert(rawData: Record<string,unknown>) → Activity
|
|
263
|
-
// rawData is your payload; SDK wraps it in { raw_data: rawData } automatically.
|
|
264
|
-
CMD['activity-create'] = async () => {
|
|
265
|
-
const [jsonStr] = cmdArgs;
|
|
266
|
-
if (!jsonStr) { console.error('Usage: rtx.js activity-create <json-payload>'); process.exit(1); }
|
|
267
|
-
const { sdk } = await getSDK();
|
|
268
|
-
print(await sdk.activities.insert(JSON.parse(jsonStr)));
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
// -- activity-update --------------------------------------------------------
|
|
272
|
-
// Source: ActivitiesModule.update(id, updates: Partial<Activity>) → Activity
|
|
273
|
-
CMD['activity-update'] = async () => {
|
|
274
|
-
const [id, jsonStr] = cmdArgs;
|
|
275
|
-
if (!id || !jsonStr) { console.error('Usage: rtx.js activity-update <id> <json-updates>'); process.exit(1); }
|
|
276
|
-
const { sdk } = await getSDK();
|
|
277
|
-
print(await sdk.activities.update(id, JSON.parse(jsonStr)));
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
// -- activity-delete --------------------------------------------------------
|
|
281
|
-
// Source: ActivitiesModule.delete(id) → void
|
|
282
|
-
CMD['activity-delete'] = async () => {
|
|
283
|
-
const [id] = cmdArgs;
|
|
284
|
-
if (!id) { console.error('Usage: rtx.js activity-delete <id>'); process.exit(1); }
|
|
285
|
-
const { sdk } = await getSDK();
|
|
286
|
-
await sdk.activities.delete(id);
|
|
287
|
-
console.log('Deleted.');
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
// -- task-start / task-complete / task-fail ---------------------------------
|
|
291
|
-
// Source: modules/task.ts
|
|
292
|
-
// CORRECT signatures (positional, NOT { task_uuid } object):
|
|
293
|
-
// start(taskUuid, machineIdOrOptions?)
|
|
294
|
-
// complete(taskUuid, result?, machineIdOrOptions?)
|
|
295
|
-
// fail(taskUuid, error: string, machineIdOrOptions?)
|
|
296
|
-
CMD['task-start'] = async () => {
|
|
297
|
-
const [uuid] = cmdArgs;
|
|
298
|
-
if (!uuid) { console.error('Usage: rtx.js task-start <uuid> [--machine=<id>]'); process.exit(1); }
|
|
299
|
-
const { sdk } = await getSDK();
|
|
300
|
-
print(await sdk.task.start(uuid, flags.machine ? { machineId: flags.machine } : undefined));
|
|
301
|
-
};
|
|
302
|
-
CMD['task-complete'] = async () => {
|
|
303
|
-
const [uuid, resultStr] = cmdArgs;
|
|
304
|
-
if (!uuid) { console.error('Usage: rtx.js task-complete <uuid> [<result-json>] [--machine=<id>]'); process.exit(1); }
|
|
305
|
-
const { sdk } = await getSDK();
|
|
306
|
-
print(await sdk.task.complete(uuid, resultStr ? JSON.parse(resultStr) : {}, flags.machine ? { machineId: flags.machine } : undefined));
|
|
307
|
-
};
|
|
308
|
-
CMD['task-fail'] = async () => {
|
|
309
|
-
const [uuid, ...errParts] = cmdArgs;
|
|
310
|
-
const errMsg = errParts.join(' ');
|
|
311
|
-
if (!uuid || !errMsg) { console.error('Usage: rtx.js task-fail <uuid> <error-message>'); process.exit(1); }
|
|
312
|
-
const { sdk } = await getSDK();
|
|
313
|
-
print(await sdk.task.fail(uuid, errMsg, flags.machine ? { machineId: flags.machine } : undefined));
|
|
314
|
-
};
|
|
315
|
-
CMD['task-progress'] = async () => {
|
|
316
|
-
const [uuid, dataStr] = cmdArgs;
|
|
317
|
-
if (!uuid) { console.error('Usage: rtx.js task-progress <uuid> [<progress-json>]'); process.exit(1); }
|
|
318
|
-
const { sdk } = await getSDK();
|
|
319
|
-
print(await sdk.task.progress(uuid, dataStr ? JSON.parse(dataStr) : {}));
|
|
320
|
-
};
|
|
321
|
-
CMD['task-cancel'] = async () => {
|
|
322
|
-
const [uuid, ...reasonParts] = cmdArgs;
|
|
323
|
-
if (!uuid) { console.error('Usage: rtx.js task-cancel <uuid> [<reason>]'); process.exit(1); }
|
|
324
|
-
const { sdk } = await getSDK();
|
|
325
|
-
print(await sdk.task.cancel(uuid, reasonParts.join(' ') || undefined));
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
// -- trigger-agent ----------------------------------------------------------
|
|
329
|
-
// IMPORTANT: sdk.webhook.triggerAgent() sends event "task.trigger" which the
|
|
330
|
-
// server rejects (expects "trigger-agent"). This command bypasses the SDK
|
|
331
|
-
// method and uses a direct fetch call with the correct event string.
|
|
332
|
-
// Source evidence: modules/webhook.ts hardcodes event: 'task.trigger'
|
|
333
|
-
// server/endpoints/sdk/webhook.js enum: ['trigger-agent',...]
|
|
334
|
-
CMD['trigger-agent'] = async () => {
|
|
335
|
-
const [agentName, workspaceSlug, ...promptParts] = cmdArgs;
|
|
336
|
-
const prompt = promptParts.join(' ');
|
|
337
|
-
if (!agentName || !workspaceSlug || !prompt) {
|
|
338
|
-
console.error('Usage: rtx.js trigger-agent <agent-name> <workspace-slug> <prompt> [--thread=<slug>] [--data=<json>]');
|
|
339
|
-
process.exit(1);
|
|
340
|
-
}
|
|
341
|
-
const { apiKey } = await getSDK();
|
|
342
|
-
const resp = await fetch('http://localhost:3001/webhooks/realtimex', {
|
|
343
|
-
method: 'POST',
|
|
344
|
-
headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + apiKey },
|
|
345
|
-
body: JSON.stringify({
|
|
346
|
-
event: 'trigger-agent',
|
|
347
|
-
payload: {
|
|
348
|
-
auto_run: true,
|
|
349
|
-
agent_name: agentName,
|
|
350
|
-
workspace_slug: workspaceSlug,
|
|
351
|
-
thread_slug: flags.thread || undefined,
|
|
352
|
-
prompt,
|
|
353
|
-
raw_data: flags.data ? JSON.parse(flags.data) : {},
|
|
354
|
-
},
|
|
355
|
-
}),
|
|
356
|
-
});
|
|
357
|
-
print(await resp.json());
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
// -- webhook-ping -----------------------------------------------------------
|
|
361
|
-
// Source: WebhookModule.ping() → sends event: 'system.ping' (accepted by server)
|
|
362
|
-
CMD['webhook-ping'] = async () => {
|
|
363
|
-
const { sdk } = await getSDK();
|
|
364
|
-
print(await sdk.webhook.ping());
|
|
365
|
-
};
|
|
366
|
-
|
|
367
|
-
// -- llm-providers ----------------------------------------------------------
|
|
368
|
-
// Source: LLMModule.chatProviders() → { success, providers: [{ provider, models }] }
|
|
369
|
-
CMD['llm-providers'] = async () => {
|
|
370
|
-
const { sdk } = await getSDK();
|
|
371
|
-
const { providers } = await sdk.llm.chatProviders();
|
|
372
|
-
for (const p of (providers || [])) {
|
|
373
|
-
console.log('\nProvider: ' + p.provider);
|
|
374
|
-
if (p.models?.length) printTable(p.models, ['id', 'name']);
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
CMD['embed-providers'] = async () => {
|
|
378
|
-
const { sdk } = await getSDK();
|
|
379
|
-
const { providers } = await sdk.llm.embedProviders();
|
|
380
|
-
for (const p of (providers || [])) {
|
|
381
|
-
console.log('\nProvider: ' + p.provider);
|
|
382
|
-
if (p.models?.length) printTable(p.models, ['id', 'name']);
|
|
383
|
-
}
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
// -- llm-chat ---------------------------------------------------------------
|
|
387
|
-
// Source: LLMModule.chat() → ChatResponse { success, response?: { content, model, metrics } }
|
|
388
|
-
// Access text via res.response?.content (NOT choices[0].message.content)
|
|
389
|
-
// Stream: yields StreamChunk { textResponse?, close?, error? } (NOT delta.content)
|
|
390
|
-
CMD['llm-chat'] = async () => {
|
|
391
|
-
const message = cmdArgs.join(' ');
|
|
392
|
-
if (!message) { console.error('Usage: rtx.js llm-chat <message> [--stream] [--model=<m>] [--provider=<p>]'); process.exit(1); }
|
|
393
|
-
const { sdk } = await getSDK();
|
|
394
|
-
const opts = {};
|
|
395
|
-
if (flags.model) opts.model = flags.model;
|
|
396
|
-
if (flags.provider) opts.provider = flags.provider;
|
|
397
|
-
if (flags.stream) {
|
|
398
|
-
for await (const chunk of sdk.llm.chatStream([{ role: 'user', content: message }], opts)) {
|
|
399
|
-
if (chunk.textResponse) process.stdout.write(chunk.textResponse);
|
|
400
|
-
if (chunk.close) break;
|
|
401
|
-
}
|
|
402
|
-
process.stdout.write('\n');
|
|
403
|
-
} else {
|
|
404
|
-
const res = await sdk.llm.chat([{ role: 'user', content: message }], opts);
|
|
405
|
-
console.log(res.response?.content ?? res.error ?? JSON.stringify(res));
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
// -- llm-embed --------------------------------------------------------------
|
|
410
|
-
// Source: LLMModule.embed(input: string | string[], options?)
|
|
411
|
-
// Returns: EmbedResponse { success, embeddings: number[][], model, dimensions }
|
|
412
|
-
CMD['llm-embed'] = async () => {
|
|
413
|
-
const text = cmdArgs.join(' ');
|
|
414
|
-
if (!text) { console.error('Usage: rtx.js llm-embed <text> [--model=<m>]'); process.exit(1); }
|
|
415
|
-
const { sdk } = await getSDK();
|
|
416
|
-
const res = await sdk.llm.embed(text, { model: flags.model, provider: flags.provider });
|
|
417
|
-
console.log('success: ' + res.success + ', model: ' + res.model + ', dimensions: ' + res.dimensions);
|
|
418
|
-
if (flags.vectors && res.embeddings?.[0]) print(res.embeddings[0].slice(0, 10));
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
// -- mcp-servers ------------------------------------------------------------
|
|
422
|
-
// Source: MCPModule.getServers(provider?: 'local'|'remote'|'all')
|
|
423
|
-
// CORRECT: plain string arg, NOT { provider: 'all' }
|
|
424
|
-
CMD['mcp-servers'] = async () => {
|
|
425
|
-
const { sdk } = await getSDK();
|
|
426
|
-
printTable(await sdk.mcp.getServers(flags.provider || 'all'), ['name', 'provider', 'status']);
|
|
427
|
-
};
|
|
428
|
-
CMD['mcp-tools'] = async () => {
|
|
429
|
-
const [name] = cmdArgs;
|
|
430
|
-
if (!name) { console.error('Usage: rtx.js mcp-tools <server-name> [--provider=local|remote]'); process.exit(1); }
|
|
431
|
-
const { sdk } = await getSDK();
|
|
432
|
-
printTable(await sdk.mcp.getTools(name, flags.provider), ['name', 'description']);
|
|
433
|
-
};
|
|
434
|
-
CMD['mcp-exec'] = async () => {
|
|
435
|
-
const [server, tool, argsStr] = cmdArgs;
|
|
436
|
-
if (!server || !tool) { console.error('Usage: rtx.js mcp-exec <server> <tool> [<args-json>] [--provider=local|remote]'); process.exit(1); }
|
|
437
|
-
const { sdk } = await getSDK();
|
|
438
|
-
print(await sdk.mcp.executeTool(server, tool, argsStr ? JSON.parse(argsStr) : {}, flags.provider));
|
|
439
|
-
};
|
|
440
|
-
|
|
441
|
-
// -- credentials ------------------------------------------------------------
|
|
442
|
-
CMD['credentials'] = async () => {
|
|
443
|
-
const { sdk } = await getSDK();
|
|
444
|
-
const list = await sdk.credentials.list();
|
|
445
|
-
printTable(list, ['name', 'type']);
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
function getDesktopRuntimeSessionsModule(sdk) {
|
|
449
|
-
const module = sdk?.desktopRuntimeSessions || sdk?.v1?.desktopRuntimeSessions;
|
|
450
|
-
if (!module) {
|
|
451
|
-
throw new Error('sdk.desktopRuntimeSessions is unavailable. Ensure the SDK was initialized with Developer API access.');
|
|
452
|
-
}
|
|
453
|
-
return module;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
function getDesktopBrowserModule(sdk) {
|
|
457
|
-
const module = sdk?.desktopBrowser || sdk?.v1?.desktopBrowser;
|
|
458
|
-
if (!module) {
|
|
459
|
-
throw new Error('sdk.desktopBrowser is unavailable. Ensure the SDK was initialized with Developer API access.');
|
|
460
|
-
}
|
|
461
|
-
return module;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// -- terminal-launcher / terminal sessions ----------------------------------
|
|
465
|
-
CMD['terminal-open-launcher'] = async () => {
|
|
466
|
-
const { sdk, context } = await getSDK();
|
|
467
|
-
const terminal = getDesktopRuntimeSessionsModule(sdk);
|
|
468
|
-
const body = applyWorkspaceThreadDefaults({}, context);
|
|
469
|
-
if (flags.workspace) body.workspaceSlug = flags.workspace;
|
|
470
|
-
if (flags.thread) body.threadSlug = flags.thread;
|
|
471
|
-
if (flags.presentation) body.presentationMode = flags.presentation;
|
|
472
|
-
if (flags.agent) body.preferredAgentName = flags.agent;
|
|
473
|
-
if (flags.provider) body.preferredAgentProviderId = flags.provider;
|
|
474
|
-
print(await terminal.openLauncher(body));
|
|
475
|
-
};
|
|
476
|
-
|
|
477
|
-
CMD['terminal-launch-shell'] = async () => {
|
|
478
|
-
const { sdk, context } = await getSDK();
|
|
479
|
-
const terminal = getDesktopRuntimeSessionsModule(sdk);
|
|
480
|
-
const body = applyWorkspaceThreadDefaults({}, context);
|
|
481
|
-
if (flags.workspace) body.workspaceSlug = flags.workspace;
|
|
482
|
-
if (flags.thread) body.threadSlug = flags.thread;
|
|
483
|
-
if (flags.presentation) body.presentationMode = flags.presentation;
|
|
484
|
-
if (flags.command) body.initialCommand = flags.command;
|
|
485
|
-
if (flags['command-mode']) {
|
|
486
|
-
body.initialCommandMode = flags['command-mode'];
|
|
487
|
-
} else if (flags.command) {
|
|
488
|
-
body.initialCommandMode = 'direct';
|
|
489
|
-
}
|
|
490
|
-
if (flags.title) body.title = flags.title;
|
|
491
|
-
if (flags.subtitle) body.subtitle = flags.subtitle;
|
|
492
|
-
print(await terminal.launchTerminalShell(body));
|
|
493
|
-
};
|
|
494
|
-
|
|
495
|
-
CMD['terminal-launch-cli-agent'] = async () => {
|
|
496
|
-
const [agentName, providerId, ...messageParts] = cmdArgs;
|
|
497
|
-
const message = messageParts.join(' ');
|
|
498
|
-
if (!agentName) {
|
|
499
|
-
console.error('Usage: rtx.js terminal-launch-cli-agent <agent-name> [<provider-id>] [<message>] [--workspace=<slug>] [--thread=<slug>] [--presentation=panel|tab] [--model=<id>]');
|
|
500
|
-
process.exit(1);
|
|
501
|
-
}
|
|
502
|
-
const { sdk, context } = await getSDK();
|
|
503
|
-
const terminal = getDesktopRuntimeSessionsModule(sdk);
|
|
504
|
-
const body = applyWorkspaceThreadDefaults({ agentName }, context);
|
|
505
|
-
if (providerId) body.providerId = providerId;
|
|
506
|
-
if (message) body.message = message;
|
|
507
|
-
if (flags.workspace) body.workspaceSlug = flags.workspace;
|
|
508
|
-
if (flags.thread) body.threadSlug = flags.thread;
|
|
509
|
-
if (flags.presentation) body.presentationMode = flags.presentation;
|
|
510
|
-
if (flags.model) body.modelId = flags.model;
|
|
511
|
-
print(await terminal.launchTerminalCliAgent(body));
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
CMD['terminal-sessions'] = async () => {
|
|
515
|
-
const { sdk } = await getSDK();
|
|
516
|
-
const terminal = getDesktopRuntimeSessionsModule(sdk);
|
|
517
|
-
const sessions = await terminal.listRuntimeSessions();
|
|
518
|
-
print(sessions);
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
CMD['terminal-session-get'] = async () => {
|
|
522
|
-
const [sessionId] = cmdArgs;
|
|
523
|
-
if (!sessionId) {
|
|
524
|
-
console.error('Usage: rtx.js terminal-session-get <session-id>');
|
|
525
|
-
process.exit(1);
|
|
526
|
-
}
|
|
527
|
-
const { sdk } = await getSDK();
|
|
528
|
-
const terminal = getDesktopRuntimeSessionsModule(sdk);
|
|
529
|
-
print(await terminal.getRuntimeSession(sessionId));
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
CMD['terminal-write'] = async () => {
|
|
533
|
-
const [sessionId, ...rest] = cmdArgs;
|
|
534
|
-
if (!sessionId || rest.length === 0) {
|
|
535
|
-
console.error('Usage: rtx.js terminal-write <session-id> <message> [--raw]');
|
|
536
|
-
process.exit(1);
|
|
537
|
-
}
|
|
538
|
-
const { sdk } = await getSDK();
|
|
539
|
-
const terminal = getDesktopRuntimeSessionsModule(sdk);
|
|
540
|
-
const payload = rest.join(' ');
|
|
541
|
-
print(await terminal.write(sessionId, flags.raw ? { input: payload } : { message: payload }));
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
CMD['terminal-permission'] = async () => {
|
|
545
|
-
const [sessionId, outcome, actionId] = cmdArgs;
|
|
546
|
-
if (!sessionId || !outcome) {
|
|
547
|
-
console.error('Usage: rtx.js terminal-permission <session-id> <approved|denied> [<action-id>] [--option-id=<id>] [--reason=<text>]');
|
|
548
|
-
process.exit(1);
|
|
549
|
-
}
|
|
550
|
-
const { sdk } = await getSDK();
|
|
551
|
-
const terminal = getDesktopRuntimeSessionsModule(sdk);
|
|
552
|
-
const body = { outcome };
|
|
553
|
-
if (actionId) body.actionId = actionId;
|
|
554
|
-
if (flags['option-id']) body.optionId = flags['option-id'];
|
|
555
|
-
if (flags.reason) body.reason = flags.reason;
|
|
556
|
-
print(await terminal.permission(sessionId, body));
|
|
557
|
-
};
|
|
558
|
-
|
|
559
|
-
CMD['terminal-close'] = async () => {
|
|
560
|
-
const [sessionId] = cmdArgs;
|
|
561
|
-
if (!sessionId) {
|
|
562
|
-
console.error('Usage: rtx.js terminal-close <session-id>');
|
|
563
|
-
process.exit(1);
|
|
564
|
-
}
|
|
565
|
-
const { sdk } = await getSDK();
|
|
566
|
-
const terminal = getDesktopRuntimeSessionsModule(sdk);
|
|
567
|
-
print(await terminal.deleteRuntimeSession(sessionId));
|
|
568
|
-
};
|
|
569
|
-
|
|
570
|
-
CMD['browser-sessions'] = async () => {
|
|
571
|
-
const { sdk } = await getSDK();
|
|
572
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
573
|
-
print(await browser.listSessions());
|
|
574
|
-
};
|
|
575
|
-
|
|
576
|
-
CMD['browser-session-create'] = async () => {
|
|
577
|
-
const [sessionName] = cmdArgs;
|
|
578
|
-
if (!sessionName) {
|
|
579
|
-
console.error('Usage: rtx.js browser-session-create <session-name> [--port=<n>]');
|
|
580
|
-
process.exit(1);
|
|
581
|
-
}
|
|
582
|
-
const { sdk } = await getSDK();
|
|
583
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
584
|
-
const body = {
|
|
585
|
-
sessionName,
|
|
586
|
-
...(flags.port ? { remoteDebugPort: Number(flags.port) } : {}),
|
|
587
|
-
};
|
|
588
|
-
print(await browser.createSession(body));
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
CMD['browser-session-get'] = async () => {
|
|
592
|
-
const [sessionName] = cmdArgs;
|
|
593
|
-
if (!sessionName) {
|
|
594
|
-
console.error('Usage: rtx.js browser-session-get <session-name>');
|
|
595
|
-
process.exit(1);
|
|
596
|
-
}
|
|
597
|
-
const { sdk } = await getSDK();
|
|
598
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
599
|
-
print(await browser.getSession(sessionName));
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
CMD['browser-session-delete'] = async () => {
|
|
603
|
-
const [sessionName] = cmdArgs;
|
|
604
|
-
if (!sessionName) {
|
|
605
|
-
console.error('Usage: rtx.js browser-session-delete <session-name>');
|
|
606
|
-
process.exit(1);
|
|
607
|
-
}
|
|
608
|
-
const { sdk } = await getSDK();
|
|
609
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
610
|
-
print(await browser.deleteSession(sessionName));
|
|
611
|
-
};
|
|
612
|
-
|
|
613
|
-
CMD['browser-tab-create'] = async () => {
|
|
614
|
-
const [url] = cmdArgs;
|
|
615
|
-
if (!url) {
|
|
616
|
-
console.error('Usage: rtx.js browser-tab-create <url> [--session=<name>] [--focus=true|false] [--focus-window=true|false]');
|
|
617
|
-
process.exit(1);
|
|
618
|
-
}
|
|
619
|
-
const { sdk } = await getSDK();
|
|
620
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
621
|
-
const body = {
|
|
622
|
-
url,
|
|
623
|
-
...(flags.session ? { sessionName: flags.session } : {}),
|
|
624
|
-
...(flags.focus !== undefined ? { focus: flags.focus !== 'false' } : {}),
|
|
625
|
-
...(flags['focus-window'] !== undefined ? { focusWindow: flags['focus-window'] !== 'false' } : {}),
|
|
626
|
-
};
|
|
627
|
-
print(await browser.createTab(body));
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
CMD['browser-tab-get'] = async () => {
|
|
631
|
-
const [tabRef] = cmdArgs;
|
|
632
|
-
if (!tabRef) {
|
|
633
|
-
console.error('Usage: rtx.js browser-tab-get <tab-ref>');
|
|
634
|
-
process.exit(1);
|
|
635
|
-
}
|
|
636
|
-
const { sdk } = await getSDK();
|
|
637
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
638
|
-
print(await browser.getTab(tabRef));
|
|
639
|
-
};
|
|
640
|
-
|
|
641
|
-
CMD['browser-tab-focus'] = async () => {
|
|
642
|
-
const [tabRef] = cmdArgs;
|
|
643
|
-
if (!tabRef) {
|
|
644
|
-
console.error('Usage: rtx.js browser-tab-focus <tab-ref> [--focus-window=true|false]');
|
|
645
|
-
process.exit(1);
|
|
646
|
-
}
|
|
647
|
-
const { sdk } = await getSDK();
|
|
648
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
649
|
-
const body = flags['focus-window'] !== undefined ? { focusWindow: flags['focus-window'] !== 'false' } : {};
|
|
650
|
-
print(await browser.focusTab(tabRef, body));
|
|
651
|
-
};
|
|
652
|
-
|
|
653
|
-
CMD['browser-tab-navigate'] = async () => {
|
|
654
|
-
const [tabRef, url] = cmdArgs;
|
|
655
|
-
if (!tabRef || !url) {
|
|
656
|
-
console.error('Usage: rtx.js browser-tab-navigate <tab-ref> <url> [--focus=true|false] [--focus-window=true|false]');
|
|
657
|
-
process.exit(1);
|
|
658
|
-
}
|
|
659
|
-
const { sdk } = await getSDK();
|
|
660
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
661
|
-
const body = {
|
|
662
|
-
url,
|
|
663
|
-
...(flags.focus !== undefined ? { focus: flags.focus !== 'false' } : {}),
|
|
664
|
-
...(flags['focus-window'] !== undefined ? { focusWindow: flags['focus-window'] !== 'false' } : {}),
|
|
665
|
-
};
|
|
666
|
-
print(await browser.navigateTab(tabRef, body));
|
|
667
|
-
};
|
|
668
|
-
|
|
669
|
-
CMD['browser-tab-evaluate'] = async () => {
|
|
670
|
-
const [tabRef, ...expressionParts] = cmdArgs;
|
|
671
|
-
if (!tabRef || expressionParts.length === 0) {
|
|
672
|
-
console.error('Usage: rtx.js browser-tab-evaluate <tab-ref> <expression> [--user-gesture=true|false]');
|
|
673
|
-
process.exit(1);
|
|
674
|
-
}
|
|
675
|
-
const { sdk } = await getSDK();
|
|
676
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
677
|
-
const body = {
|
|
678
|
-
expression: expressionParts.join(' '),
|
|
679
|
-
...(flags['user-gesture'] !== undefined ? { userGesture: flags['user-gesture'] !== 'false' } : {}),
|
|
680
|
-
};
|
|
681
|
-
print(await browser.evaluateTab(tabRef, body));
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
CMD['browser-tab-close'] = async () => {
|
|
685
|
-
const [tabRef] = cmdArgs;
|
|
686
|
-
if (!tabRef) {
|
|
687
|
-
console.error('Usage: rtx.js browser-tab-close <tab-ref>');
|
|
688
|
-
process.exit(1);
|
|
689
|
-
}
|
|
690
|
-
const { sdk } = await getSDK();
|
|
691
|
-
const browser = getDesktopBrowserModule(sdk);
|
|
692
|
-
print(await browser.deleteTab(tabRef));
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
// -- acp-agents -------------------------------------------------------------
|
|
696
|
-
// Source: AcpAgentModule.listAgents({ includeModels? })
|
|
697
|
-
// Returns: AcpAgentInfo[] { id, label, handles[], installed, authReady, status }
|
|
698
|
-
CMD['acp-agents'] = async () => {
|
|
699
|
-
const { sdk } = await getSDK();
|
|
700
|
-
printTable(await sdk.acpAgent.listAgents({ includeModels: flags.models === 'true' }), ['id', 'label', 'status', 'authReady', 'installed']);
|
|
701
|
-
};
|
|
702
|
-
|
|
703
|
-
// -- acp-sessions -----------------------------------------------------------
|
|
704
|
-
// Source: AcpAgentModule.listSessions() → AcpSessionStatus[]
|
|
705
|
-
CMD['acp-sessions'] = async () => {
|
|
706
|
-
const { sdk } = await getSDK();
|
|
707
|
-
print(await sdk.acpAgent.listSessions());
|
|
708
|
-
};
|
|
709
|
-
|
|
710
|
-
// -- acp-session-create -----------------------------------------------------
|
|
711
|
-
// Source: AcpAgentModule.createSession(options) → AcpSession { session_key, agent_id, state, ... }
|
|
712
|
-
// Prints session_key so callers can pass --session=<key> on subsequent calls.
|
|
713
|
-
CMD['acp-session-create'] = async () => {
|
|
714
|
-
const [agentId] = cmdArgs;
|
|
715
|
-
if (!agentId) {
|
|
716
|
-
console.error('Usage: rtx.js acp-session-create <agent-id> [--cwd=<path>] [--model=<m>] [--policy=approve-all|approve-reads|deny-all]');
|
|
717
|
-
process.exit(1);
|
|
718
|
-
}
|
|
719
|
-
const { sdk } = await getSDK();
|
|
720
|
-
const opts = {
|
|
721
|
-
agent_id: agentId,
|
|
722
|
-
cwd: flags.cwd || process.cwd(),
|
|
723
|
-
approvalPolicy: flags.policy || 'approve-all',
|
|
724
|
-
};
|
|
725
|
-
if (flags.model) opts.model = flags.model;
|
|
726
|
-
const session = await sdk.acpAgent.createSession(opts);
|
|
727
|
-
process.stderr.write('Session created.\n');
|
|
728
|
-
print(session);
|
|
729
|
-
};
|
|
730
|
-
|
|
731
|
-
// -- acp-session-get --------------------------------------------------------
|
|
732
|
-
// Source: AcpAgentModule.getSession(sessionKey) → AcpSessionStatus
|
|
733
|
-
CMD['acp-session-get'] = async () => {
|
|
734
|
-
const [sessionKey] = cmdArgs;
|
|
735
|
-
if (!sessionKey) { console.error('Usage: rtx.js acp-session-get <session-key>'); process.exit(1); }
|
|
736
|
-
const { sdk } = await getSDK();
|
|
737
|
-
print(await sdk.acpAgent.getSession(sessionKey));
|
|
738
|
-
};
|
|
739
|
-
|
|
740
|
-
// -- acp-session-patch ------------------------------------------------------
|
|
741
|
-
// Source: AcpAgentModule.patchSession(sessionKey, patch) → void
|
|
742
|
-
// patch fields: model?, cwd?, timeoutSeconds?, runtimeMode?, approvalPolicy?
|
|
743
|
-
CMD['acp-session-patch'] = async () => {
|
|
744
|
-
const [sessionKey] = cmdArgs;
|
|
745
|
-
if (!sessionKey) {
|
|
746
|
-
console.error('Usage: rtx.js acp-session-patch <session-key> [--cwd=<path>] [--model=<m>] [--policy=<p>] [--timeout=<s>]');
|
|
747
|
-
process.exit(1);
|
|
748
|
-
}
|
|
749
|
-
const { sdk } = await getSDK();
|
|
750
|
-
const patch = {};
|
|
751
|
-
if (flags.cwd) patch.cwd = flags.cwd;
|
|
752
|
-
if (flags.model) patch.model = flags.model;
|
|
753
|
-
if (flags.policy) patch.approvalPolicy = flags.policy;
|
|
754
|
-
if (flags.timeout) patch.timeoutSeconds = Number(flags.timeout);
|
|
755
|
-
await sdk.acpAgent.patchSession(sessionKey, patch);
|
|
756
|
-
console.log('Session patched.');
|
|
757
|
-
};
|
|
758
|
-
|
|
759
|
-
// -- acp-session-close ------------------------------------------------------
|
|
760
|
-
// Source: AcpAgentModule.closeSession(sessionKey, reason?) → void
|
|
761
|
-
CMD['acp-session-close'] = async () => {
|
|
762
|
-
const [sessionKey, ...reasonParts] = cmdArgs;
|
|
763
|
-
if (!sessionKey) { console.error('Usage: rtx.js acp-session-close <session-key> [<reason>]'); process.exit(1); }
|
|
764
|
-
const { sdk } = await getSDK();
|
|
765
|
-
await sdk.acpAgent.closeSession(sessionKey, reasonParts.join(' ') || undefined);
|
|
766
|
-
console.log('Session closed.');
|
|
767
|
-
};
|
|
768
|
-
|
|
769
|
-
// -- acp-cancel -------------------------------------------------------------
|
|
770
|
-
// Source: AcpAgentModule.cancelTurn(sessionKey, reason?) → void
|
|
771
|
-
CMD['acp-cancel'] = async () => {
|
|
772
|
-
const [sessionKey, ...reasonParts] = cmdArgs;
|
|
773
|
-
if (!sessionKey) { console.error('Usage: rtx.js acp-cancel <session-key> [<reason>]'); process.exit(1); }
|
|
774
|
-
const { sdk } = await getSDK();
|
|
775
|
-
await sdk.acpAgent.cancelTurn(sessionKey, reasonParts.join(' ') || undefined);
|
|
776
|
-
console.log('Turn cancelled.');
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
// -- acp-resolve ------------------------------------------------------------
|
|
780
|
-
// Source: AcpAgentModule.resolvePermission(sessionKey, { requestId, optionId, outcome? }) → void
|
|
781
|
-
// Must be called while streamChat SSE is still active for that session.
|
|
782
|
-
CMD['acp-resolve'] = async () => {
|
|
783
|
-
const [sessionKey, requestId, optionId] = cmdArgs;
|
|
784
|
-
if (!sessionKey || !requestId || !optionId) {
|
|
785
|
-
console.error('Usage: rtx.js acp-resolve <session-key> <request-id> <option-id> [--outcome=approved]');
|
|
786
|
-
process.exit(1);
|
|
787
|
-
}
|
|
788
|
-
const { sdk } = await getSDK();
|
|
789
|
-
await sdk.acpAgent.resolvePermission(sessionKey, {
|
|
790
|
-
requestId,
|
|
791
|
-
optionId,
|
|
792
|
-
outcome: flags.outcome || 'approved',
|
|
793
|
-
});
|
|
794
|
-
console.log('Permission resolved.');
|
|
795
|
-
};
|
|
796
|
-
|
|
797
|
-
// -- acp-send ---------------------------------------------------------------
|
|
798
|
-
// Source: AcpAgentModule.chat(sessionKey, message) → AcpChatResponse (sync, waits for full reply)
|
|
799
|
-
// Reuses existing session; never creates a new one.
|
|
800
|
-
CMD['acp-send'] = async () => {
|
|
801
|
-
const [sessionKey, ...msgParts] = cmdArgs;
|
|
802
|
-
const message = msgParts.join(' ');
|
|
803
|
-
if (!sessionKey || !message) {
|
|
804
|
-
console.error('Usage: rtx.js acp-send <session-key> <message>');
|
|
805
|
-
process.exit(1);
|
|
806
|
-
}
|
|
807
|
-
const { sdk } = await getSDK();
|
|
808
|
-
const res = await sdk.acpAgent.chat(sessionKey, message);
|
|
809
|
-
console.log(res.text ?? JSON.stringify(res));
|
|
810
|
-
};
|
|
811
|
-
|
|
812
|
-
// -- acp-stream -------------------------------------------------------------
|
|
813
|
-
// Source: AcpAgentModule.streamChat(sessionKey, message) — SSE stream on existing session.
|
|
814
|
-
// Handles permission_request events automatically via resolvePermission().
|
|
815
|
-
// Reuses existing session; never creates a new one.
|
|
816
|
-
CMD['acp-stream'] = async () => {
|
|
817
|
-
const [sessionKey, ...msgParts] = cmdArgs;
|
|
818
|
-
const message = msgParts.join(' ');
|
|
819
|
-
if (!sessionKey || !message) {
|
|
820
|
-
console.error('Usage: rtx.js acp-stream <session-key> <message> [--thoughts] [--quiet]');
|
|
821
|
-
process.exit(1);
|
|
822
|
-
}
|
|
823
|
-
const { sdk } = await getSDK();
|
|
824
|
-
await acpStreamWithPermissions(sdk, sessionKey, message);
|
|
825
|
-
};
|
|
826
|
-
|
|
827
|
-
// ---------------------------------------------------------------------------
|
|
828
|
-
// ACP helpers
|
|
829
|
-
// ---------------------------------------------------------------------------
|
|
830
|
-
|
|
831
|
-
/**
|
|
832
|
-
* Extract a stable string id from a permission option entry.
|
|
833
|
-
* Options can be raw numbers, strings, or objects with numeric/string id fields.
|
|
834
|
-
* IMPORTANT: must use != null (not ||) to handle id === 0 (falsy but valid).
|
|
835
|
-
*/
|
|
836
|
-
function optionId(opt, index) {
|
|
837
|
-
if (opt == null) return String(index);
|
|
838
|
-
if (typeof opt === 'number') return String(opt);
|
|
839
|
-
if (typeof opt === 'string') return opt;
|
|
840
|
-
if (opt.id != null) return String(opt.id);
|
|
841
|
-
if (opt.optionId != null) return String(opt.optionId);
|
|
842
|
-
if (opt.value != null) return String(opt.value);
|
|
843
|
-
return String(index);
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
/** Extract a human-readable label from a permission option entry. */
|
|
847
|
-
function optionLabel(opt, index) {
|
|
848
|
-
if (opt == null) return String(index);
|
|
849
|
-
if (typeof opt === 'number') return String(opt);
|
|
850
|
-
if (typeof opt === 'string') return opt;
|
|
851
|
-
return opt.label || opt.name || opt.description || optionId(opt, index);
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
/**
|
|
855
|
-
* Stream a chat turn on an existing session, auto-resolving permission_request
|
|
856
|
-
* events via sdk.acpAgent.resolvePermission().
|
|
857
|
-
*
|
|
858
|
-
* Permission resolution strategy (--policy-override flag):
|
|
859
|
-
* approve-all (default) — approve: label-match → last option (typically "Yes/Always")
|
|
860
|
-
* deny-all — deny: label-match → first option (typically "No/Cancel")
|
|
861
|
-
* prompt — pause and ask the user interactively via stdin
|
|
862
|
-
*
|
|
863
|
-
* Why last-option for approve-all fallback:
|
|
864
|
-
* Qwen/Claude-style dialogs are ordered [Deny=0, Approve-once=1, Approve-always=2].
|
|
865
|
-
* Picking options[0] = Deny. We want the last approve variant when no label matches.
|
|
866
|
-
*/
|
|
867
|
-
async function acpStreamWithPermissions(sdk, sessionKey, message) {
|
|
868
|
-
const policyOverride = flags['policy-override'] || 'approve-all';
|
|
869
|
-
|
|
870
|
-
for await (const event of sdk.acpAgent.streamChat(sessionKey, message)) {
|
|
871
|
-
switch (event.type) {
|
|
872
|
-
|
|
873
|
-
case 'text_delta': {
|
|
874
|
-
if (event.data && event.data.type === 'thinking') {
|
|
875
|
-
if (flags.thoughts) process.stderr.write('[thought] ' + String(event.data.text ?? '') + '\n');
|
|
876
|
-
} else {
|
|
877
|
-
process.stdout.write(String(event.data?.text ?? event.data ?? ''));
|
|
878
|
-
}
|
|
879
|
-
break;
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
case 'permission_request': {
|
|
883
|
-
const req = event.data || {};
|
|
884
|
-
const requestId = req.requestId || req.id || req.request_id;
|
|
885
|
-
const options = Array.isArray(req.options) ? req.options : [];
|
|
886
|
-
|
|
887
|
-
// Always show the full raw payload — critical for diagnosing option structure
|
|
888
|
-
if (!flags.quiet) {
|
|
889
|
-
process.stderr.write('\n[Permission Request] id=' + requestId + '\n');
|
|
890
|
-
if (req.title) process.stderr.write(' title: ' + req.title + '\n');
|
|
891
|
-
if (req.description) process.stderr.write(' details: ' + req.description + '\n');
|
|
892
|
-
options.forEach((o, i) => {
|
|
893
|
-
process.stderr.write(' [' + optionId(o, i) + '] ' + optionLabel(o, i) + '\n');
|
|
894
|
-
});
|
|
895
|
-
if (flags.debug) {
|
|
896
|
-
process.stderr.write(' raw: ' + JSON.stringify(req) + '\n');
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
let chosenId = null;
|
|
901
|
-
|
|
902
|
-
if (policyOverride === 'prompt') {
|
|
903
|
-
const readline = require('readline');
|
|
904
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
905
|
-
const answer = await new Promise(resolve => {
|
|
906
|
-
rl.question(' Choose option id (Enter = last/approve): ', ans => { rl.close(); resolve(ans.trim()); });
|
|
907
|
-
});
|
|
908
|
-
// Use typed answer, or fall back to last option (approve-always)
|
|
909
|
-
chosenId = answer || (options.length ? optionId(options[options.length - 1], options.length - 1) : null);
|
|
910
|
-
|
|
911
|
-
} else if (policyOverride === 'deny-all') {
|
|
912
|
-
// Label-match for deny keywords first, then fall back to first option (index 0 = No/Cancel)
|
|
913
|
-
const idx = options.findIndex(o => /deny|cancel|no|reject/i.test(optionLabel(o, 0)));
|
|
914
|
-
const pick = idx >= 0 ? options[idx] : options[0];
|
|
915
|
-
const pickIdx = idx >= 0 ? idx : 0;
|
|
916
|
-
if (pick != null) chosenId = optionId(pick, pickIdx);
|
|
917
|
-
|
|
918
|
-
} else {
|
|
919
|
-
// approve-all: label-match first, then LAST option (not first — first is typically Deny)
|
|
920
|
-
const idx = options.findIndex(o => /approve|allow|yes|confirm|ok|always/i.test(optionLabel(o, 0)));
|
|
921
|
-
if (idx >= 0) {
|
|
922
|
-
chosenId = optionId(options[idx], idx);
|
|
923
|
-
} else if (options.length > 0) {
|
|
924
|
-
// Last option is safest approve fallback (e.g. "Yes, don't ask again" / "Approve always")
|
|
925
|
-
const lastIdx = options.length - 1;
|
|
926
|
-
chosenId = optionId(options[lastIdx], lastIdx);
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
if (chosenId !== null && requestId) {
|
|
931
|
-
if (!flags.quiet) process.stderr.write(' → resolving with option: ' + chosenId + '\n');
|
|
932
|
-
await sdk.acpAgent.resolvePermission(sessionKey, {
|
|
933
|
-
requestId,
|
|
934
|
-
optionId: chosenId,
|
|
935
|
-
outcome: policyOverride === 'deny-all' ? 'denied' : 'approved',
|
|
936
|
-
});
|
|
937
|
-
} else {
|
|
938
|
-
if (!flags.quiet) process.stderr.write(' → no options to resolve\n');
|
|
939
|
-
}
|
|
940
|
-
break;
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
case 'tool_call': {
|
|
944
|
-
if (!flags.quiet) {
|
|
945
|
-
const tool = event.data?.tool || event.data?.name || JSON.stringify(event.data);
|
|
946
|
-
process.stderr.write('\n[tool: ' + tool + ']\n');
|
|
947
|
-
}
|
|
948
|
-
break;
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
case 'status': {
|
|
952
|
-
if (!flags.quiet && event.data?.message) {
|
|
953
|
-
process.stderr.write('[status] ' + event.data.message + '\n');
|
|
954
|
-
}
|
|
955
|
-
break;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
case 'error': {
|
|
959
|
-
process.stderr.write('\n[Error] ' + (event.data?.message || JSON.stringify(event.data)) + '\n');
|
|
960
|
-
break;
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
case 'done':
|
|
964
|
-
case 'close':
|
|
965
|
-
process.stdout.write('\n');
|
|
966
|
-
break;
|
|
967
|
-
|
|
968
|
-
default:
|
|
969
|
-
if (flags.debug) process.stderr.write('[event:' + event.type + '] ' + JSON.stringify(event.data) + '\n');
|
|
970
|
-
break;
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
/**
|
|
976
|
-
* Find a reusable session for agentId+cwd, or create a fresh one.
|
|
977
|
-
*
|
|
978
|
-
* Resolution order:
|
|
979
|
-
* 1. --session=<key> → validate it exists and is not closed/stale, use it
|
|
980
|
-
* 2. listSessions() → find first session matching agent_id (and cwd if --cwd given)
|
|
981
|
-
* whose state is not 'closed' or 'stale'
|
|
982
|
-
* 3. createSession() → spawn a new process
|
|
983
|
-
*
|
|
984
|
-
* Pass --new to always create a fresh session regardless.
|
|
985
|
-
*/
|
|
986
|
-
async function findOrCreateSession(sdk, agentId) {
|
|
987
|
-
const cwd = flags.cwd || process.cwd();
|
|
988
|
-
const policy = flags.policy || 'approve-all';
|
|
989
|
-
|
|
990
|
-
// Force-new
|
|
991
|
-
if (flags.new) {
|
|
992
|
-
process.stderr.write('Creating new ACP session for "' + agentId + '"...\n');
|
|
993
|
-
const s = await sdk.acpAgent.createSession({ agent_id: agentId, cwd, approvalPolicy: policy, ...(flags.model ? { model: flags.model } : {}) });
|
|
994
|
-
process.stderr.write('Session: ' + s.session_key + '\n');
|
|
995
|
-
return s.session_key;
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
// Explicit key
|
|
999
|
-
if (flags.session) {
|
|
1000
|
-
try {
|
|
1001
|
-
const status = await sdk.acpAgent.getSession(flags.session);
|
|
1002
|
-
const state = status?.state || status?.runtime_options?.state;
|
|
1003
|
-
if (state !== 'closed' && state !== 'stale') {
|
|
1004
|
-
process.stderr.write('Reusing session (--session): ' + flags.session + '\n');
|
|
1005
|
-
return flags.session;
|
|
1006
|
-
}
|
|
1007
|
-
process.stderr.write('Session ' + flags.session + ' is ' + state + ', will create new.\n');
|
|
1008
|
-
} catch (e) {
|
|
1009
|
-
process.stderr.write('Session lookup failed (' + (e.message || e) + '), will create new.\n');
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
// Search existing sessions
|
|
1014
|
-
try {
|
|
1015
|
-
const sessions = await sdk.acpAgent.listSessions();
|
|
1016
|
-
if (Array.isArray(sessions)) {
|
|
1017
|
-
for (const s of sessions) {
|
|
1018
|
-
const key = s.session_key || s.key;
|
|
1019
|
-
const sid = s.agent_id || s.agentId;
|
|
1020
|
-
const state = s.state || s.runtime_options?.state;
|
|
1021
|
-
const sCwd = s.cwd || s.runtime_options?.cwd;
|
|
1022
|
-
if (state === 'closed' || state === 'stale') continue;
|
|
1023
|
-
if (sid && sid !== agentId) continue;
|
|
1024
|
-
if (flags.cwd && sCwd && sCwd !== cwd) continue;
|
|
1025
|
-
if (key) {
|
|
1026
|
-
process.stderr.write('Reusing existing session: ' + key + (sid ? ' (' + sid + ')' : '') + '\n');
|
|
1027
|
-
return key;
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
} catch (_) { /* listSessions not supported or empty — fall through */ }
|
|
1032
|
-
|
|
1033
|
-
// Create new
|
|
1034
|
-
process.stderr.write('Creating new ACP session for "' + agentId + '"...\n');
|
|
1035
|
-
const session = await sdk.acpAgent.createSession({
|
|
1036
|
-
agent_id: agentId,
|
|
1037
|
-
cwd,
|
|
1038
|
-
approvalPolicy: policy,
|
|
1039
|
-
...(flags.model ? { model: flags.model } : {}),
|
|
1040
|
-
});
|
|
1041
|
-
process.stderr.write('Session: ' + session.session_key + '\n');
|
|
1042
|
-
return session.session_key;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
// -- acp-chat ---------------------------------------------------------------
|
|
1046
|
-
// Smart version: reuses existing sessions, handles permission_request via resolvePermission().
|
|
1047
|
-
//
|
|
1048
|
-
// Flags:
|
|
1049
|
-
// --session=<key> Reuse this specific session key
|
|
1050
|
-
// --new Always create a fresh session
|
|
1051
|
-
// --cwd=<path> Working directory (used for new session + matching)
|
|
1052
|
-
// --model=<m> Model override
|
|
1053
|
-
// --policy=approve-all approvalPolicy for new sessions
|
|
1054
|
-
// --policy-override=<p> Runtime permission decision: approve-all|deny-all|prompt
|
|
1055
|
-
// --close Close the session after this turn
|
|
1056
|
-
// --thoughts Print reasoning/thinking tokens to stderr
|
|
1057
|
-
// --quiet Suppress tool/status/permission stderr output
|
|
1058
|
-
// --debug Print all unhandled SSE event types
|
|
1059
|
-
CMD['acp-chat'] = async () => {
|
|
1060
|
-
const [agentId, ...msgParts] = cmdArgs;
|
|
1061
|
-
const message = msgParts.join(' ');
|
|
1062
|
-
if (!agentId || !message) {
|
|
1063
|
-
console.error('Usage: rtx.js acp-chat <agent-id> <message>\n' +
|
|
1064
|
-
' [--session=<key>] [--new] [--cwd=<path>] [--model=<m>]\n' +
|
|
1065
|
-
' [--policy=approve-all] [--policy-override=approve-all|deny-all|prompt]\n' +
|
|
1066
|
-
' [--close] [--thoughts] [--quiet] [--debug]');
|
|
1067
|
-
process.exit(1);
|
|
1068
|
-
}
|
|
1069
|
-
const { sdk } = await getSDK();
|
|
1070
|
-
const sessionKey = await findOrCreateSession(sdk, agentId);
|
|
1071
|
-
|
|
1072
|
-
try {
|
|
1073
|
-
await acpStreamWithPermissions(sdk, sessionKey, message);
|
|
1074
|
-
} finally {
|
|
1075
|
-
if (flags.close) {
|
|
1076
|
-
await sdk.acpAgent.closeSession(sessionKey, 'chat complete').catch(() => {});
|
|
1077
|
-
process.stderr.write('Session closed.\n');
|
|
1078
|
-
} else {
|
|
1079
|
-
process.stderr.write('Session key (reuse with --session=' + sessionKey + ')\n');
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
};
|
|
1083
|
-
|
|
1084
|
-
// -- tts-providers / stt-providers ------------------------------------------
|
|
1085
|
-
CMD['tts-providers'] = async () => { const { sdk } = await getSDK(); printTable(await sdk.tts.listProviders(), ['id', 'name', 'type', 'configured', 'supportsStreaming']); };
|
|
1086
|
-
CMD['stt-providers'] = async () => { const { sdk } = await getSDK(); print(await sdk.stt.listProviders()); };
|
|
1087
|
-
|
|
1088
|
-
// -- vectors ----------------------------------------------------------------
|
|
1089
|
-
// Source: LLMModule.vectors (VectorStore sub-module)
|
|
1090
|
-
CMD['vectors-workspaces'] = async () => { const { sdk } = await getSDK(); print(await sdk.llm.vectors.listWorkspaces()); };
|
|
1091
|
-
// llm.search() embeds query then calls vectors.query() — high-level helper
|
|
1092
|
-
CMD['vectors-query'] = async () => {
|
|
1093
|
-
const query = cmdArgs.join(' ');
|
|
1094
|
-
if (!query) { console.error('Usage: rtx.js vectors-query <query> [--workspace-id=<id>] [--top=5]'); process.exit(1); }
|
|
1095
|
-
const { sdk } = await getSDK();
|
|
1096
|
-
print(await sdk.llm.search(query, { topK: flags.top ? Number(flags.top) : 5, workspaceId: flags['workspace-id'] }));
|
|
1097
|
-
};
|
|
1098
|
-
// vectors.upsert: VectorRecord[] = { id, vector: number[], metadata? }
|
|
1099
|
-
CMD['vectors-upsert'] = async () => {
|
|
1100
|
-
const [jsonStr] = cmdArgs;
|
|
1101
|
-
if (!jsonStr) { console.error('Usage: rtx.js vectors-upsert <json-VectorRecord[]> [--workspace-id=<id>]'); process.exit(1); }
|
|
1102
|
-
const { sdk } = await getSDK();
|
|
1103
|
-
print(await sdk.llm.vectors.upsert(JSON.parse(jsonStr), { workspaceId: flags['workspace-id'] }));
|
|
1104
|
-
};
|
|
1105
|
-
// vectors.delete requires { deleteAll: true } — partial delete by ID not supported
|
|
1106
|
-
CMD['vectors-delete'] = async () => {
|
|
1107
|
-
if (!flags['workspace-id'] && !flags.all) { console.error('Usage: rtx.js vectors-delete --workspace-id=<id> OR --all'); process.exit(1); }
|
|
1108
|
-
const { sdk } = await getSDK();
|
|
1109
|
-
print(await sdk.llm.vectors.delete({ deleteAll: true, workspaceId: flags['workspace-id'] }));
|
|
1110
|
-
};
|
|
1111
|
-
|
|
1112
|
-
// -- contract ---------------------------------------------------------------
|
|
1113
|
-
CMD['contract-info'] = async () => { const { sdk } = await getSDK(); print(await sdk.contract.getLocalAppV1()); };
|
|
1114
|
-
CMD['contract-capabilities'] = async () => { const { sdk } = await getSDK(); print(await sdk.contract.listCapabilities()); };
|
|
1115
|
-
CMD['contract-search'] = async () => {
|
|
1116
|
-
const query = cmdArgs.join(' ');
|
|
1117
|
-
if (!query) { console.error('Usage: rtx.js contract-search <query>'); process.exit(1); }
|
|
1118
|
-
const { sdk } = await getSDK();
|
|
1119
|
-
print(await sdk.contract.searchCapabilities(query));
|
|
1120
|
-
};
|
|
1121
|
-
CMD['contract-invoke'] = async () => {
|
|
1122
|
-
const [capId, ...rest] = cmdArgs;
|
|
1123
|
-
if (!capId) { console.error('Usage: rtx.js contract-invoke <capability-id> [<args-json>]'); process.exit(1); }
|
|
1124
|
-
const { sdk } = await getSDK();
|
|
1125
|
-
print(await sdk.contract.invoke({ capability_id: capId, args: rest[0] ? JSON.parse(rest[0]) : {}, auto_run: true, agent_name: flags.agent, workspace_slug: flags.workspace, prompt: flags.prompt }));
|
|
1126
|
-
};
|
|
1127
|
-
|
|
1128
|
-
// -- database / auth --------------------------------------------------------
|
|
1129
|
-
CMD['db-config'] = async () => { const { sdk } = await getSDK(); print(await sdk.database.getConfig()); };
|
|
1130
|
-
CMD['auth-token'] = async () => { const { sdk } = await getSDK(); print(await sdk.auth.getAccessToken()); };
|
|
1131
|
-
|
|
1132
|
-
// -- help -------------------------------------------------------------------
|
|
1133
|
-
CMD.help = async () => {
|
|
1134
|
-
console.log(`
|
|
1135
|
-
RealTimeX SDK CLI (source-verified) — rtx.js
|
|
1136
|
-
============================================
|
|
1137
|
-
|
|
1138
|
-
Usage: node rtx.js <command> [args...] [--flags]
|
|
1139
|
-
|
|
1140
|
-
Global flags:
|
|
1141
|
-
--api-key=<key> Override API key (skips .env lookup)
|
|
1142
|
-
--env-dir=<path> Directory containing .env (default: cwd)
|
|
1143
|
-
--url=<url> RealTimeX server URL (default: http://localhost:3001)
|
|
1144
|
-
|
|
1145
|
-
Connection:
|
|
1146
|
-
ping / info
|
|
1147
|
-
|
|
1148
|
-
Skill docs:
|
|
1149
|
-
skills list
|
|
1150
|
-
List version-matched workflow/API skill topics bundled with this SDK.
|
|
1151
|
-
|
|
1152
|
-
skills get <topic> [--full]
|
|
1153
|
-
Print a focused skill guide from the installed SDK version.
|
|
1154
|
-
Examples:
|
|
1155
|
-
skills get core
|
|
1156
|
-
skills get channels
|
|
1157
|
-
skills get browser
|
|
1158
|
-
skills get api:v1-channels --full
|
|
1159
|
-
|
|
1160
|
-
sdk.api.*:
|
|
1161
|
-
agents / workspaces / threads <slug> / task <uuid>
|
|
1162
|
-
context
|
|
1163
|
-
|
|
1164
|
-
sdk.activities.*:
|
|
1165
|
-
activities [--status --limit --offset]
|
|
1166
|
-
activity-get <id>
|
|
1167
|
-
activity-create <json>
|
|
1168
|
-
activity-update <id> <json>
|
|
1169
|
-
activity-delete <id>
|
|
1170
|
-
|
|
1171
|
-
sdk.task.* (positional args — NOT { task_uuid }):
|
|
1172
|
-
task-start <uuid> [--machine=<id>]
|
|
1173
|
-
task-complete <uuid> [<result-json>] [--machine=<id>]
|
|
1174
|
-
task-fail <uuid> <error-message>
|
|
1175
|
-
task-progress <uuid> [<progress-json>]
|
|
1176
|
-
task-cancel <uuid> [<reason>]
|
|
1177
|
-
|
|
1178
|
-
Trigger (raw fetch — SDK method sends wrong event type):
|
|
1179
|
-
trigger-agent <agent-name> <workspace-slug> <prompt>
|
|
1180
|
-
[--thread=<slug>] [--data=<json>]
|
|
1181
|
-
|
|
1182
|
-
Webhook:
|
|
1183
|
-
webhook-ping
|
|
1184
|
-
|
|
1185
|
-
sdk.llm.*:
|
|
1186
|
-
llm-providers / embed-providers
|
|
1187
|
-
llm-chat <message> [--stream] [--model] [--provider]
|
|
1188
|
-
llm-embed <text> [--model] [--vectors]
|
|
1189
|
-
|
|
1190
|
-
sdk.llm.vectors.*:
|
|
1191
|
-
vectors-workspaces
|
|
1192
|
-
vectors-query <text> [--workspace-id] [--top=5]
|
|
1193
|
-
vectors-upsert <json-VectorRecord[]> [--workspace-id]
|
|
1194
|
-
vectors-delete --workspace-id=<id> | --all
|
|
1195
|
-
|
|
1196
|
-
sdk.mcp.*:
|
|
1197
|
-
mcp-servers [--provider=local|remote|all]
|
|
1198
|
-
mcp-tools <server> [--provider]
|
|
1199
|
-
mcp-exec <server> <tool> [<args-json>] [--provider]
|
|
1200
|
-
|
|
1201
|
-
sdk.credentials.*:
|
|
1202
|
-
credentials
|
|
1203
|
-
List available credentials (names and types, no values).
|
|
1204
|
-
|
|
1205
|
-
sdk.desktopRuntimeSessions.* — Desktop terminal sessions:
|
|
1206
|
-
terminal-open-launcher
|
|
1207
|
-
[--workspace=<slug>] [--thread=<slug>] [--presentation=panel|tab]
|
|
1208
|
-
Open the terminal launcher UI in the Electron app.
|
|
1209
|
-
|
|
1210
|
-
terminal-launch-shell
|
|
1211
|
-
[--workspace=<slug>] [--thread=<slug>] [--presentation=panel|tab]
|
|
1212
|
-
[--command="pwd"] [--command-mode=direct|prefill|shell]
|
|
1213
|
-
Launch a visible shell terminal.
|
|
1214
|
-
Default: when --command is provided, it runs in direct mode unless --command-mode is explicitly set.
|
|
1215
|
-
|
|
1216
|
-
terminal-launch-cli-agent <agent-name> [<provider-id>] [<message>]
|
|
1217
|
-
[--workspace=<slug>] [--thread=<slug>] [--presentation=panel|tab] [--model=<id>]
|
|
1218
|
-
Launch a visible CLI agent terminal.
|
|
1219
|
-
Example: terminal-launch-cli-agent claude claude-cli "what is current working dir"
|
|
1220
|
-
|
|
1221
|
-
terminal-sessions
|
|
1222
|
-
List desktop terminal sessions.
|
|
1223
|
-
|
|
1224
|
-
terminal-session-get <session-id>
|
|
1225
|
-
Fetch one desktop terminal session by runtime session id.
|
|
1226
|
-
|
|
1227
|
-
terminal-write <session-id> <message> [--raw]
|
|
1228
|
-
Send another message or raw PTY input to an existing terminal session.
|
|
1229
|
-
|
|
1230
|
-
terminal-permission <session-id> <approved|denied> [<action-id>] [--option-id=<id>] [--reason=<text>]
|
|
1231
|
-
Resolve a pending terminal approval request.
|
|
1232
|
-
|
|
1233
|
-
terminal-close <session-id>
|
|
1234
|
-
Close a desktop terminal session.
|
|
1235
|
-
|
|
1236
|
-
Compatibility:
|
|
1237
|
-
The SDK also exposes this module as sdk.v1.desktopRuntimeSessions.
|
|
1238
|
-
|
|
1239
|
-
sdk.desktopBrowser.* — RealTimeX Browser sessions and tabs:
|
|
1240
|
-
browser-sessions
|
|
1241
|
-
List named RealTimeX Browser sessions.
|
|
1242
|
-
|
|
1243
|
-
browser-session-create <session-name> [--port=<n>]
|
|
1244
|
-
Create a named browser session.
|
|
1245
|
-
|
|
1246
|
-
browser-session-get <session-name>
|
|
1247
|
-
Fetch one named browser session.
|
|
1248
|
-
|
|
1249
|
-
browser-session-delete <session-name>
|
|
1250
|
-
Delete a named browser session.
|
|
1251
|
-
|
|
1252
|
-
browser-tab-create <url> [--session=<name>] [--focus=true|false] [--focus-window=true|false]
|
|
1253
|
-
Create a managed browser tab.
|
|
1254
|
-
|
|
1255
|
-
browser-tab-get <tab-ref>
|
|
1256
|
-
Fetch one browser tab snapshot by tab ref.
|
|
1257
|
-
|
|
1258
|
-
browser-tab-focus <tab-ref> [--focus-window=true|false]
|
|
1259
|
-
Focus a managed browser tab.
|
|
1260
|
-
|
|
1261
|
-
browser-tab-navigate <tab-ref> <url> [--focus=true|false] [--focus-window=true|false]
|
|
1262
|
-
Navigate a managed browser tab.
|
|
1263
|
-
|
|
1264
|
-
browser-tab-evaluate <tab-ref> <expression> [--user-gesture=true|false]
|
|
1265
|
-
Evaluate JavaScript in a managed browser tab.
|
|
1266
|
-
|
|
1267
|
-
browser-tab-close <tab-ref>
|
|
1268
|
-
Close a managed browser tab.
|
|
1269
|
-
|
|
1270
|
-
Workflow note:
|
|
1271
|
-
Each session has seperated browser profile, use session's remoteDebugPort with the agent-browser skill
|
|
1272
|
-
over CDP for page interaction and automation.
|
|
1273
|
-
|
|
1274
|
-
Compatibility:
|
|
1275
|
-
The SDK also exposes this module as sdk.v1.desktopBrowser.
|
|
1276
|
-
|
|
1277
|
-
sdk.acpAgent.* — Session Management:
|
|
1278
|
-
acp-agents [--models=true]
|
|
1279
|
-
List available ACP CLI agents.
|
|
1280
|
-
|
|
1281
|
-
acp-sessions
|
|
1282
|
-
List all active sessions owned by this app.
|
|
1283
|
-
|
|
1284
|
-
acp-session-create <agent-id>
|
|
1285
|
-
[--cwd=<path>] [--model=<m>] [--policy=approve-all|approve-reads|deny-all]
|
|
1286
|
-
Spawn a new agent process. Prints session_key for reuse.
|
|
1287
|
-
|
|
1288
|
-
acp-session-get <session-key>
|
|
1289
|
-
Get session status and runtime options.
|
|
1290
|
-
|
|
1291
|
-
acp-session-patch <session-key>
|
|
1292
|
-
[--cwd=<path>] [--model=<m>] [--policy=<p>] [--timeout=<s>]
|
|
1293
|
-
Update runtime options (applied on next turn).
|
|
1294
|
-
|
|
1295
|
-
acp-session-close <session-key> [<reason>]
|
|
1296
|
-
Stop the agent process and close the session.
|
|
1297
|
-
|
|
1298
|
-
acp-cancel <session-key> [<reason>]
|
|
1299
|
-
Cancel the currently active turn on a session.
|
|
1300
|
-
|
|
1301
|
-
acp-resolve <session-key> <request-id> <option-id> [--outcome=approved]
|
|
1302
|
-
Manually resolve a pending permission request (while stream is active).
|
|
1303
|
-
|
|
1304
|
-
acp-send <session-key> <message>
|
|
1305
|
-
Synchronous chat on an existing session (waits for full reply).
|
|
1306
|
-
|
|
1307
|
-
acp-stream <session-key> <message>
|
|
1308
|
-
[--policy-override=approve-all|deny-all|prompt] [--thoughts] [--quiet] [--debug]
|
|
1309
|
-
Streaming chat on an existing session. Auto-resolves permission_request events.
|
|
1310
|
-
|
|
1311
|
-
acp-chat <agent-id> <message>
|
|
1312
|
-
[--session=<key>] Reuse a specific session key
|
|
1313
|
-
[--new] Force-create a new session
|
|
1314
|
-
[--cwd=<path>] Working directory (for new session and session matching)
|
|
1315
|
-
[--model=<m>] Model override
|
|
1316
|
-
[--policy=approve-all] approvalPolicy for newly created sessions
|
|
1317
|
-
[--policy-override=approve-all|deny-all|prompt] Runtime permission handling
|
|
1318
|
-
[--close] Close session after this turn
|
|
1319
|
-
[--thoughts] Print reasoning tokens to stderr
|
|
1320
|
-
[--quiet] Suppress tool/status/permission stderr output
|
|
1321
|
-
[--debug] Print all unhandled SSE events
|
|
1322
|
-
|
|
1323
|
-
Smart session reuse: checks --session flag → searches listSessions() for a
|
|
1324
|
-
compatible active session → creates new only if none found.
|
|
1325
|
-
Handles permission_request events inline via resolvePermission().
|
|
1326
|
-
|
|
1327
|
-
sdk.tts.* / sdk.stt.*:
|
|
1328
|
-
tts-providers / stt-providers
|
|
1329
|
-
|
|
1330
|
-
sdk.contract.*:
|
|
1331
|
-
contract-info / contract-capabilities
|
|
1332
|
-
contract-search <query>
|
|
1333
|
-
contract-invoke <capability-id> [<args-json>] [--agent] [--workspace] [--prompt]
|
|
1334
|
-
|
|
1335
|
-
sdk.database.* / sdk.auth.*:
|
|
1336
|
-
db-config / auth-token
|
|
1337
|
-
|
|
1338
|
-
help
|
|
1339
|
-
`);
|
|
1340
|
-
};
|
|
1341
|
-
|
|
1342
|
-
// ---------------------------------------------------------------------------
|
|
1343
|
-
// Entry point
|
|
1344
|
-
// ---------------------------------------------------------------------------
|
|
1345
|
-
(async () => {
|
|
1346
|
-
const handler = CMD[command];
|
|
1347
|
-
if (!handler) {
|
|
1348
|
-
console.error('Unknown command: ' + (command || '(none)') + '\nRun: node rtx.js help');
|
|
1349
|
-
process.exit(1);
|
|
1350
|
-
}
|
|
1351
|
-
try {
|
|
1352
|
-
await handler();
|
|
1353
|
-
process.exit(0);
|
|
1354
|
-
} catch (err) {
|
|
1355
|
-
console.error('Error:', err.message || err);
|
|
1356
|
-
if (flags.debug) console.error(err);
|
|
1357
|
-
process.exit(1);
|
|
1358
|
-
}
|
|
1359
|
-
})();
|