@rogeriq/cli 0.1.0 → 0.3.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/AGENTS.md +7 -1
- package/CHANGELOG.md +44 -0
- package/README.md +45 -4
- package/dist/index.mjs +340 -87
- package/package.json +7 -4
package/AGENTS.md
CHANGED
|
@@ -13,7 +13,13 @@ export RIQ_PROJECT_ID=prj_xxx # default project (per-command --project overri
|
|
|
13
13
|
export RIQ_ORG_ID=org_xxx # for org-level commands (orgs, projects, keys)
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
The CLI never prompts when these are set.
|
|
16
|
+
The CLI never prompts when these are set. `rogeriq auth login --api-key`
|
|
17
|
+
also works for one-time setup without a browser.
|
|
18
|
+
|
|
19
|
+
**Do not** invoke `rogeriq auth login` without `--api-key` from an agent —
|
|
20
|
+
the no-args form starts the browser-based device flow and will block for
|
|
21
|
+
up to 10 minutes waiting for a human to confirm. Use `--api-key` or env
|
|
22
|
+
vars instead.
|
|
17
23
|
|
|
18
24
|
## Output contract
|
|
19
25
|
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0 — 2026-05-17
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- KB articles + agent + integrations + forms + beacons now use the stable
|
|
7
|
+
`/api/v1/...` surface (joins projects + widget + conversations + contacts
|
|
8
|
+
+ webhooks already on v1). Internal routes remain as the unstable mirror.
|
|
9
|
+
- MCP server tools: `browse_integration_catalog`, `get_integration_install_url`,
|
|
10
|
+
`disconnect_integration`. Existing tools repointed to v1.
|
|
11
|
+
- **Granular scopes** on API keys. In addition to coarse `read`/`write`/`admin`,
|
|
12
|
+
you can now scope keys per-resource: `kb:write`, `agent:read`,
|
|
13
|
+
`integrations:write`, `projects:admin`, etc. See README for the full table.
|
|
14
|
+
- Audit log now captures `api_key_id` on mutations. `GET /api/projects/:pid/audit-log`
|
|
15
|
+
joins on `api_keys` and returns `api_key_name` + `api_key_prefix` so the
|
|
16
|
+
dashboard can show which key changed what.
|
|
17
|
+
|
|
18
|
+
## 0.2.0 — 2026-05-17
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- **Browser-based device authorization flow.** `rogeriq auth login` (no args)
|
|
22
|
+
now opens `rogeriq.com/device?code=XXXX-XXXX`, polls for confirmation, and
|
|
23
|
+
saves the API key automatically. Code is also printed to the terminal as a
|
|
24
|
+
fallback for SSH / headless environments. Pass `--no-browser` to suppress
|
|
25
|
+
the auto-open. `--api-key riq_xxx` still works for CI / scripting.
|
|
26
|
+
- KB articles + search now use the stable `/api/v1/...` surface.
|
|
27
|
+
- Agent status, config, respond, classify, suggest now use `/api/v1/...`.
|
|
28
|
+
- MCP server (`rogeriq mcp`) tools updated to point at v1 endpoints.
|
|
29
|
+
- Unit tests for argv parser, API client (incl. 429 auto-retry), and device
|
|
30
|
+
auth flow (happy path, denied, expired, slow-down backoff).
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- `--help` after a subcommand now correctly prints per-command help instead
|
|
34
|
+
of root help.
|
|
35
|
+
- `--json` / `--quiet` set at the top level now propagate into subcommand
|
|
36
|
+
flag parsing.
|
|
37
|
+
- API client now treats `retry_after: 0` as a valid retry hint (previously
|
|
38
|
+
the 0 was discarded as falsy and the request did not retry).
|
|
39
|
+
|
|
40
|
+
## 0.1.0 — 2026-05-17
|
|
41
|
+
|
|
42
|
+
Initial release. 18 command groups covering conversations, contacts,
|
|
43
|
+
projects, knowledge base, widget, integrations, webhooks, agent, plus an
|
|
44
|
+
MCP server subcommand for Claude Desktop / Claude Code.
|
package/README.md
CHANGED
|
@@ -14,18 +14,35 @@ npx @rogeriq/cli --help
|
|
|
14
14
|
|
|
15
15
|
## Auth
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
### Interactive (humans)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
rogeriq auth login
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Opens a browser to `rogeriq.com/device?code=XXXX-XXXX`. Confirm in the
|
|
24
|
+
browser. The CLI picks up the key automatically. Code is also printed to
|
|
25
|
+
the terminal as a fallback (SSH / no browser).
|
|
26
|
+
|
|
27
|
+
Flags:
|
|
28
|
+
- `--no-browser` — skip auto-open; print URL + code only.
|
|
29
|
+
- `--api-base https://...` — point at a different deployment.
|
|
30
|
+
|
|
31
|
+
### CI / agents / scripts
|
|
32
|
+
|
|
33
|
+
Use `--api-key` (or env var) to skip the browser flow entirely:
|
|
19
34
|
|
|
20
35
|
```bash
|
|
21
36
|
rogeriq auth login --api-key riq_xxx
|
|
37
|
+
# Or pass per-invocation:
|
|
38
|
+
RIQ_API_KEY=riq_xxx rogeriq conversations list
|
|
22
39
|
```
|
|
23
40
|
|
|
24
|
-
|
|
41
|
+
Recommended for CI / agents (no config file needed):
|
|
25
42
|
|
|
26
43
|
```bash
|
|
27
44
|
export RIQ_API_KEY=riq_xxx
|
|
28
|
-
export RIQ_PROJECT_ID=prj_xxx
|
|
45
|
+
export RIQ_PROJECT_ID=prj_xxx
|
|
29
46
|
```
|
|
30
47
|
|
|
31
48
|
## Quick start
|
|
@@ -110,6 +127,30 @@ for command-specific flags.
|
|
|
110
127
|
| orgId | `RIQ_ORG_ID` |
|
|
111
128
|
| projectId | `RIQ_PROJECT_ID` |
|
|
112
129
|
|
|
130
|
+
## Scopes
|
|
131
|
+
|
|
132
|
+
API keys can be coarse or granular:
|
|
133
|
+
|
|
134
|
+
| Scope | Grants |
|
|
135
|
+
|-----------------------|----------------------------------------------------------------|
|
|
136
|
+
| `admin` | Everything. |
|
|
137
|
+
| `write` | All `*:read` and `*:write`. Not `*:admin`. |
|
|
138
|
+
| `read` | All `*:read`. |
|
|
139
|
+
| `<resource>:admin` | `<resource>:read`, `:write`, `:admin`. |
|
|
140
|
+
| `<resource>:write` | `<resource>:read`, `:write`. |
|
|
141
|
+
| `<resource>:read` | `<resource>:read` only. |
|
|
142
|
+
|
|
143
|
+
Resources: `conversations`, `messages`, `contacts`, `kb`, `agent`, `widget`,
|
|
144
|
+
`integrations`, `forms`, `beacons`, `webhooks`, `projects`, `analytics`,
|
|
145
|
+
`audit`.
|
|
146
|
+
|
|
147
|
+
Examples — least privilege for an agent that only drafts KB articles + reads
|
|
148
|
+
conversations:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
rogeriq keys create kb-writer --scopes kb:write,conversations:read
|
|
152
|
+
```
|
|
153
|
+
|
|
113
154
|
## Exit codes
|
|
114
155
|
|
|
115
156
|
| Code | Meaning |
|
package/dist/index.mjs
CHANGED
|
@@ -275,7 +275,7 @@ var ApiClient = class {
|
|
|
275
275
|
const url = path.startsWith("http") ? path : `${this.apiBase}${path}`;
|
|
276
276
|
const headers = {
|
|
277
277
|
"X-API-Key": this.apiKey,
|
|
278
|
-
"User-Agent": `rogeriq-cli/0.
|
|
278
|
+
"User-Agent": `rogeriq-cli/0.3.0 node/${process.versions.node}`,
|
|
279
279
|
"Accept": "application/json",
|
|
280
280
|
...init.headers
|
|
281
281
|
};
|
|
@@ -318,7 +318,7 @@ var ApiClient = class {
|
|
|
318
318
|
const code = err?.code ?? `HTTP_${res.status}`;
|
|
319
319
|
const message = err?.error ?? `Request failed: ${res.status} ${res.statusText}`;
|
|
320
320
|
const exitCode = res.status === 401 || res.status === 403 ? 3 : res.status === 429 ? 4 : 2;
|
|
321
|
-
if (res.status === 429 && err?.retry_after && err.retry_after <= 30) {
|
|
321
|
+
if (res.status === 429 && typeof err?.retry_after === "number" && err.retry_after >= 0 && err.retry_after <= 30) {
|
|
322
322
|
await sleep(err.retry_after * 1e3);
|
|
323
323
|
return this.request(method, path, body, init);
|
|
324
324
|
}
|
|
@@ -371,39 +371,148 @@ function sleep(ms) {
|
|
|
371
371
|
return new Promise((r) => setTimeout(r, ms));
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
// src/lib/device-auth.ts
|
|
375
|
+
import { spawn } from "node:child_process";
|
|
376
|
+
import { hostname, userInfo } from "node:os";
|
|
377
|
+
async function runDeviceFlow(opts) {
|
|
378
|
+
const base = opts.apiBase.replace(/\/$/, "");
|
|
379
|
+
const clientName = opts.clientName ?? defaultClientName();
|
|
380
|
+
const codeRes = await fetch(`${base}/api/auth/device/code`, {
|
|
381
|
+
method: "POST",
|
|
382
|
+
headers: { "Content-Type": "application/json" },
|
|
383
|
+
body: JSON.stringify({ client_name: clientName })
|
|
384
|
+
});
|
|
385
|
+
if (!codeRes.ok) {
|
|
386
|
+
throw new CliError(
|
|
387
|
+
`Failed to start device flow: ${codeRes.status} ${codeRes.statusText}`,
|
|
388
|
+
"DEVICE_CODE_FAILED",
|
|
389
|
+
2
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
const codeBody = await codeRes.json();
|
|
393
|
+
opts.onPrompt?.({
|
|
394
|
+
userCode: codeBody.user_code,
|
|
395
|
+
verificationUri: codeBody.verification_uri,
|
|
396
|
+
verificationUriComplete: codeBody.verification_uri_complete
|
|
397
|
+
});
|
|
398
|
+
if (!opts.noBrowser) {
|
|
399
|
+
openBrowser(codeBody.verification_uri_complete);
|
|
400
|
+
}
|
|
401
|
+
const intervalMs = Math.max(1, opts.pollInterval ?? codeBody.interval) * 1e3;
|
|
402
|
+
const deadline = Date.now() + (opts.timeoutSeconds ?? 600) * 1e3;
|
|
403
|
+
let interval = intervalMs;
|
|
404
|
+
let attempt = 0;
|
|
405
|
+
while (Date.now() < deadline) {
|
|
406
|
+
attempt += 1;
|
|
407
|
+
opts.onPoll?.(attempt);
|
|
408
|
+
await sleep2(interval);
|
|
409
|
+
const res = await fetch(`${base}/api/auth/device/token`, {
|
|
410
|
+
method: "POST",
|
|
411
|
+
headers: { "Content-Type": "application/json" },
|
|
412
|
+
body: JSON.stringify({ device_code: codeBody.device_code })
|
|
413
|
+
});
|
|
414
|
+
if (res.status === 202) {
|
|
415
|
+
const pending = await safeJson(res);
|
|
416
|
+
if (pending?.interval) interval = Math.max(1, pending.interval) * 1e3;
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
if (res.status === 429) {
|
|
420
|
+
const body = await safeJson(res);
|
|
421
|
+
if (body?.interval) interval = Math.max(1, body.interval) * 1e3;
|
|
422
|
+
else interval = Math.min(6e4, interval * 2);
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
if (res.status === 410) {
|
|
426
|
+
throw new CliError(
|
|
427
|
+
"Device code expired. Run `rogeriq auth login` again.",
|
|
428
|
+
"DEVICE_CODE_EXPIRED",
|
|
429
|
+
3
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
if (res.status === 403) {
|
|
433
|
+
throw new CliError(
|
|
434
|
+
"Authorization denied.",
|
|
435
|
+
"ACCESS_DENIED",
|
|
436
|
+
3
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
if (!res.ok) {
|
|
440
|
+
const body = await safeJson(res);
|
|
441
|
+
throw new CliError(
|
|
442
|
+
body?.error ?? `Device flow failed: ${res.status} ${res.statusText}`,
|
|
443
|
+
body?.code ?? `HTTP_${res.status}`,
|
|
444
|
+
2
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
const token = await res.json();
|
|
448
|
+
const apiKey = token.access_token ?? token.api_key;
|
|
449
|
+
if (!apiKey) {
|
|
450
|
+
throw new CliError("Server returned no API key", "MISSING_API_KEY", 2);
|
|
451
|
+
}
|
|
452
|
+
return { apiKey, orgId: token.org_id, scopes: token.scopes };
|
|
453
|
+
}
|
|
454
|
+
throw new CliError(
|
|
455
|
+
"Timed out waiting for browser authorization (10 minutes).",
|
|
456
|
+
"DEVICE_FLOW_TIMEOUT",
|
|
457
|
+
3
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
function defaultClientName() {
|
|
461
|
+
try {
|
|
462
|
+
return `rogeriq-cli (${userInfo().username}@${hostname()})`.slice(0, 100);
|
|
463
|
+
} catch {
|
|
464
|
+
return "rogeriq-cli";
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function openBrowser(url) {
|
|
468
|
+
const platform = process.platform;
|
|
469
|
+
const cmd = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
|
|
470
|
+
const args = platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
471
|
+
try {
|
|
472
|
+
const child = spawn(cmd, args, { stdio: "ignore", detached: true });
|
|
473
|
+
child.on("error", () => {
|
|
474
|
+
});
|
|
475
|
+
child.unref();
|
|
476
|
+
} catch {
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
function sleep2(ms) {
|
|
480
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
481
|
+
}
|
|
482
|
+
async function safeJson(res) {
|
|
483
|
+
try {
|
|
484
|
+
return await res.json();
|
|
485
|
+
} catch {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
374
490
|
// src/commands/auth.ts
|
|
491
|
+
var DEFAULT_API_BASE2 = "https://api.rogeriq.com";
|
|
375
492
|
var auth = {
|
|
376
493
|
summary: "Manage CLI authentication",
|
|
377
494
|
subcommands: {
|
|
378
495
|
login: {
|
|
379
|
-
summary: "
|
|
380
|
-
usage: "rogeriq auth login --api-key riq_xxx [--api-base https://api.rogeriq.com]",
|
|
496
|
+
summary: "Browser-based login (or pass --api-key for CI / scripting)",
|
|
497
|
+
usage: "rogeriq auth login [--api-key riq_xxx] [--no-browser] [--api-base https://api.rogeriq.com]",
|
|
381
498
|
flags: [
|
|
382
499
|
{ name: "api-key", type: "string" },
|
|
383
|
-
{ name: "api-base", type: "string" }
|
|
500
|
+
{ name: "api-base", type: "string" },
|
|
501
|
+
{ name: "no-browser", type: "boolean" },
|
|
502
|
+
{ name: "client-name", type: "string" }
|
|
384
503
|
],
|
|
385
504
|
async run({ flags }) {
|
|
505
|
+
const apiBase = flags["api-base"] ?? loadConfig().apiBase ?? DEFAULT_API_BASE2;
|
|
386
506
|
const apiKey = flags["api-key"];
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
"Pass --api-key riq_xxx. Generate one with `rogeriq keys create <name>` (after a one-time browser login) or in the dashboard.",
|
|
391
|
-
"MISSING_API_KEY",
|
|
392
|
-
1
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
if (!apiKey.startsWith("riq_")) {
|
|
396
|
-
throw new CliError("API key must start with riq_", "INVALID_API_KEY", 1);
|
|
507
|
+
if (apiKey) {
|
|
508
|
+
await loginWithApiKey({ apiKey, apiBase });
|
|
509
|
+
return;
|
|
397
510
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const list = me.raw?.data ?? [];
|
|
404
|
-
if (list[0]?.id) saveConfig({ orgId: list[0].id });
|
|
405
|
-
logInfo(`Saved API key to ${configPath()}.`);
|
|
406
|
-
emit({ ok: true, org_id: list[0]?.id ?? null });
|
|
511
|
+
await loginWithBrowser({
|
|
512
|
+
apiBase,
|
|
513
|
+
noBrowser: flags["no-browser"] === true,
|
|
514
|
+
clientName: flags["client-name"]
|
|
515
|
+
});
|
|
407
516
|
}
|
|
408
517
|
},
|
|
409
518
|
logout: {
|
|
@@ -419,7 +528,11 @@ var auth = {
|
|
|
419
528
|
async run() {
|
|
420
529
|
const cfg = loadConfig();
|
|
421
530
|
if (!cfg.apiKey) {
|
|
422
|
-
throw new CliError(
|
|
531
|
+
throw new CliError(
|
|
532
|
+
"Not logged in. Run `rogeriq auth login`.",
|
|
533
|
+
"NOT_LOGGED_IN",
|
|
534
|
+
3
|
|
535
|
+
);
|
|
423
536
|
}
|
|
424
537
|
const client = new ApiClient();
|
|
425
538
|
const orgsRes = await client.get("/api/orgs");
|
|
@@ -435,6 +548,64 @@ var auth = {
|
|
|
435
548
|
}
|
|
436
549
|
}
|
|
437
550
|
};
|
|
551
|
+
async function loginWithApiKey({ apiKey, apiBase }) {
|
|
552
|
+
if (!apiKey.startsWith("riq_")) {
|
|
553
|
+
throw new CliError("API key must start with riq_", "INVALID_API_KEY", 1);
|
|
554
|
+
}
|
|
555
|
+
saveConfig({ apiKey, apiBase });
|
|
556
|
+
const client = new ApiClient();
|
|
557
|
+
const me = await client.get("/api/orgs");
|
|
558
|
+
const list = me.raw?.data ?? [];
|
|
559
|
+
if (list[0]?.id) saveConfig({ orgId: list[0].id });
|
|
560
|
+
logInfo(`Saved API key to ${configPath()}.`);
|
|
561
|
+
emit({ ok: true, org_id: list[0]?.id ?? null });
|
|
562
|
+
}
|
|
563
|
+
async function loginWithBrowser(opts) {
|
|
564
|
+
const result = await runDeviceFlow({
|
|
565
|
+
apiBase: opts.apiBase,
|
|
566
|
+
noBrowser: opts.noBrowser,
|
|
567
|
+
clientName: opts.clientName,
|
|
568
|
+
onPrompt: ({ userCode, verificationUri, verificationUriComplete }) => {
|
|
569
|
+
const sep = "\u2500".repeat(40);
|
|
570
|
+
process.stderr.write(`
|
|
571
|
+
${sep}
|
|
572
|
+
`);
|
|
573
|
+
process.stderr.write(` Open this URL in your browser:
|
|
574
|
+
`);
|
|
575
|
+
process.stderr.write(` ${verificationUriComplete}
|
|
576
|
+
|
|
577
|
+
`);
|
|
578
|
+
process.stderr.write(` Or visit ${verificationUri}
|
|
579
|
+
`);
|
|
580
|
+
process.stderr.write(` and enter code: ${userCode}
|
|
581
|
+
`);
|
|
582
|
+
process.stderr.write(`${sep}
|
|
583
|
+
|
|
584
|
+
`);
|
|
585
|
+
if (opts.noBrowser) {
|
|
586
|
+
process.stderr.write(" (Skipping browser open: --no-browser)\n\n");
|
|
587
|
+
} else {
|
|
588
|
+
process.stderr.write(" Opening browser\u2026\n\n");
|
|
589
|
+
}
|
|
590
|
+
},
|
|
591
|
+
onPoll: (attempt) => {
|
|
592
|
+
if (attempt === 1) process.stderr.write("Waiting for authorization\u2026\n");
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
saveConfig({
|
|
596
|
+
apiKey: result.apiKey,
|
|
597
|
+
apiBase: opts.apiBase,
|
|
598
|
+
orgId: result.orgId
|
|
599
|
+
});
|
|
600
|
+
logInfo(`
|
|
601
|
+
Authorized. Saved API key to ${configPath()}.`);
|
|
602
|
+
emit({
|
|
603
|
+
ok: true,
|
|
604
|
+
org_id: result.orgId ?? null,
|
|
605
|
+
scopes: result.scopes ?? null,
|
|
606
|
+
api_key_prefix: result.apiKey.slice(0, 12) + "..."
|
|
607
|
+
});
|
|
608
|
+
}
|
|
438
609
|
|
|
439
610
|
// src/commands/config.ts
|
|
440
611
|
var KEYS = ["apiKey", "apiBase", "orgId", "projectId"];
|
|
@@ -651,7 +822,7 @@ var keys = {
|
|
|
651
822
|
},
|
|
652
823
|
create: {
|
|
653
824
|
summary: "Create an API key. Raw key returned ONCE \u2014 copy it now.",
|
|
654
|
-
usage: "rogeriq keys create <name> [--scopes read,write,admin] [--expires-days 90]",
|
|
825
|
+
usage: "rogeriq keys create <name> [--scopes read,write,admin | --scopes kb:write,agent:read,...] [--expires-days 90]",
|
|
655
826
|
flags: [
|
|
656
827
|
{ name: "org", type: "string" },
|
|
657
828
|
{ name: "scopes", type: "string" },
|
|
@@ -1022,7 +1193,7 @@ var agent = {
|
|
|
1022
1193
|
async run({ flags }) {
|
|
1023
1194
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1024
1195
|
const pid = client.requireProject();
|
|
1025
|
-
const res = await client.get(`/api/projects/${pid}/agent/status`);
|
|
1196
|
+
const res = await client.get(`/api/v1/projects/${pid}/agent/status`);
|
|
1026
1197
|
emit(res.raw?.data ?? res.raw);
|
|
1027
1198
|
}
|
|
1028
1199
|
},
|
|
@@ -1044,11 +1215,11 @@ var agent = {
|
|
|
1044
1215
|
if (flags["persona"]) body["persona"] = flags["persona"];
|
|
1045
1216
|
if (flags["tone"]) body["tone"] = flags["tone"];
|
|
1046
1217
|
if (Object.keys(body).length === 0) {
|
|
1047
|
-
const res2 = await client.get(`/api/projects/${pid}/agent/config`);
|
|
1218
|
+
const res2 = await client.get(`/api/v1/projects/${pid}/agent/config`);
|
|
1048
1219
|
emit(res2.raw?.data ?? res2.raw);
|
|
1049
1220
|
return;
|
|
1050
1221
|
}
|
|
1051
|
-
const res = await client.patch(`/api/projects/${pid}/agent/config`, body);
|
|
1222
|
+
const res = await client.patch(`/api/v1/projects/${pid}/agent/config`, body);
|
|
1052
1223
|
emit(res.raw?.data ?? res.raw);
|
|
1053
1224
|
}
|
|
1054
1225
|
},
|
|
@@ -1068,7 +1239,7 @@ var agent = {
|
|
|
1068
1239
|
if (!conv) throw new CliError("Usage: rogeriq agent respond <conversation-id>", "BAD_USAGE", 1);
|
|
1069
1240
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1070
1241
|
const pid = client.requireProject();
|
|
1071
|
-
const res = await client.post(`/api/projects/${pid}/agent/respond`, {
|
|
1242
|
+
const res = await client.post(`/api/v1/projects/${pid}/agent/respond`, {
|
|
1072
1243
|
conversation_id: conv
|
|
1073
1244
|
});
|
|
1074
1245
|
emit(res.raw?.data ?? res.raw);
|
|
@@ -1082,7 +1253,7 @@ var agent = {
|
|
|
1082
1253
|
if (!conv) throw new CliError("Usage: rogeriq agent classify <conversation-id>", "BAD_USAGE", 1);
|
|
1083
1254
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1084
1255
|
const pid = client.requireProject();
|
|
1085
|
-
const res = await client.post(`/api/projects/${pid}/agent/classify`, {
|
|
1256
|
+
const res = await client.post(`/api/v1/projects/${pid}/agent/classify`, {
|
|
1086
1257
|
conversation_id: conv
|
|
1087
1258
|
});
|
|
1088
1259
|
emit(res.raw?.data ?? res.raw);
|
|
@@ -1096,7 +1267,7 @@ var agent = {
|
|
|
1096
1267
|
if (!conv) throw new CliError("Usage: rogeriq agent suggest <conversation-id>", "BAD_USAGE", 1);
|
|
1097
1268
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1098
1269
|
const pid = client.requireProject();
|
|
1099
|
-
const res = await client.post(`/api/projects/${pid}/agent/suggest`, {
|
|
1270
|
+
const res = await client.post(`/api/v1/projects/${pid}/agent/suggest`, {
|
|
1100
1271
|
conversation_id: conv
|
|
1101
1272
|
});
|
|
1102
1273
|
emit(res.raw?.data ?? res.raw);
|
|
@@ -1129,7 +1300,7 @@ var kb = {
|
|
|
1129
1300
|
if (flags["limit"]) qs.set("limit", flags["limit"]);
|
|
1130
1301
|
if (flags["cursor"]) qs.set("cursor", flags["cursor"]);
|
|
1131
1302
|
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1132
|
-
const res = await client.get(`/api/projects/${pid}/kb/articles${suffix}`);
|
|
1303
|
+
const res = await client.get(`/api/v1/projects/${pid}/kb/articles${suffix}`);
|
|
1133
1304
|
emit(res.raw?.data ?? res.raw);
|
|
1134
1305
|
}
|
|
1135
1306
|
},
|
|
@@ -1141,7 +1312,7 @@ var kb = {
|
|
|
1141
1312
|
if (!id) throw new CliError("Usage: rogeriq kb get <article-id>", "BAD_USAGE", 1);
|
|
1142
1313
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1143
1314
|
const pid = client.requireProject();
|
|
1144
|
-
const res = await client.get(`/api/projects/${pid}/kb/articles/${id}`);
|
|
1315
|
+
const res = await client.get(`/api/v1/projects/${pid}/kb/articles/${id}`);
|
|
1145
1316
|
emit(res.raw?.data ?? res.raw);
|
|
1146
1317
|
}
|
|
1147
1318
|
},
|
|
@@ -1166,7 +1337,7 @@ var kb = {
|
|
|
1166
1337
|
const body = { title, content };
|
|
1167
1338
|
if (flags["category-id"]) body["category_id"] = flags["category-id"];
|
|
1168
1339
|
if (flags["status"]) body["status"] = flags["status"];
|
|
1169
|
-
const res = await client.post(`/api/projects/${pid}/kb/articles`, body);
|
|
1340
|
+
const res = await client.post(`/api/v1/projects/${pid}/kb/articles`, body);
|
|
1170
1341
|
emit(res.raw?.data ?? res.raw);
|
|
1171
1342
|
}
|
|
1172
1343
|
},
|
|
@@ -1190,7 +1361,7 @@ var kb = {
|
|
|
1190
1361
|
else if (flags["content"]) body["content"] = flags["content"];
|
|
1191
1362
|
if (flags["status"]) body["status"] = flags["status"];
|
|
1192
1363
|
if (Object.keys(body).length === 0) throw new CliError("No updates provided", "NO_UPDATES", 1);
|
|
1193
|
-
const res = await client.patch(`/api/projects/${pid}/kb/articles/${id}`, body);
|
|
1364
|
+
const res = await client.patch(`/api/v1/projects/${pid}/kb/articles/${id}`, body);
|
|
1194
1365
|
emit(res.raw?.data ?? res.raw);
|
|
1195
1366
|
}
|
|
1196
1367
|
},
|
|
@@ -1202,7 +1373,7 @@ var kb = {
|
|
|
1202
1373
|
if (!id) throw new CliError("Usage: rogeriq kb delete <id>", "BAD_USAGE", 1);
|
|
1203
1374
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1204
1375
|
const pid = client.requireProject();
|
|
1205
|
-
await client.del(`/api/projects/${pid}/kb/articles/${id}`);
|
|
1376
|
+
await client.del(`/api/v1/projects/${pid}/kb/articles/${id}`);
|
|
1206
1377
|
emit({ ok: true, deleted: id });
|
|
1207
1378
|
}
|
|
1208
1379
|
},
|
|
@@ -1214,7 +1385,7 @@ var kb = {
|
|
|
1214
1385
|
if (!id) throw new CliError("Usage: rogeriq kb publish <id>", "BAD_USAGE", 1);
|
|
1215
1386
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1216
1387
|
const pid = client.requireProject();
|
|
1217
|
-
const res = await client.post(`/api/projects/${pid}/kb/articles/${id}/publish`);
|
|
1388
|
+
const res = await client.post(`/api/v1/projects/${pid}/kb/articles/${id}/publish`);
|
|
1218
1389
|
emit(res.raw?.data ?? res.raw);
|
|
1219
1390
|
}
|
|
1220
1391
|
},
|
|
@@ -1226,7 +1397,7 @@ var kb = {
|
|
|
1226
1397
|
if (!q) throw new CliError("Usage: rogeriq kb search <query>", "BAD_USAGE", 1);
|
|
1227
1398
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1228
1399
|
const pid = client.requireProject();
|
|
1229
|
-
const res = await client.get(`/api/projects/${pid}/kb/search?q=${encodeURIComponent(q)}`);
|
|
1400
|
+
const res = await client.get(`/api/v1/projects/${pid}/kb/search?q=${encodeURIComponent(q)}`);
|
|
1230
1401
|
emit(res.raw?.data ?? res.raw);
|
|
1231
1402
|
}
|
|
1232
1403
|
},
|
|
@@ -1246,7 +1417,7 @@ var kb = {
|
|
|
1246
1417
|
statSync(target);
|
|
1247
1418
|
const content = readFileSync2(target, "utf8");
|
|
1248
1419
|
const title = target.split("/").pop().replace(/\.[^.]+$/, "");
|
|
1249
|
-
const res = await client.post(`/api/projects/${pid}/kb/articles`, { title, content });
|
|
1420
|
+
const res = await client.post(`/api/v1/projects/${pid}/kb/articles`, { title, content });
|
|
1250
1421
|
emit(res.raw?.data ?? res.raw);
|
|
1251
1422
|
}
|
|
1252
1423
|
}
|
|
@@ -1357,68 +1528,97 @@ var integrations = {
|
|
|
1357
1528
|
summary: "Manage third-party integrations (Slack, Shopify, Stripe, Linear, GitHub, Discord)",
|
|
1358
1529
|
subcommands: {
|
|
1359
1530
|
list: {
|
|
1360
|
-
summary: "List integrations
|
|
1531
|
+
summary: "List integrations installed on the current project",
|
|
1361
1532
|
async run({ flags }) {
|
|
1362
1533
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1363
1534
|
const pid = client.requireProject();
|
|
1364
|
-
const res = await client.get(`/api/projects/${pid}/integrations`);
|
|
1535
|
+
const res = await client.get(`/api/v1/projects/${pid}/integrations`);
|
|
1536
|
+
emit(res.raw?.data ?? res.raw);
|
|
1537
|
+
}
|
|
1538
|
+
},
|
|
1539
|
+
catalog: {
|
|
1540
|
+
summary: "Browse the full integration catalog (installed + available)",
|
|
1541
|
+
flags: [
|
|
1542
|
+
{ name: "q", type: "string" },
|
|
1543
|
+
{ name: "category", type: "string" },
|
|
1544
|
+
{ name: "status", type: "string" }
|
|
1545
|
+
],
|
|
1546
|
+
async run({ flags }) {
|
|
1547
|
+
const client = new ApiClient({ projectId: flags["project"] });
|
|
1548
|
+
const pid = client.requireProject();
|
|
1549
|
+
const qs = new URLSearchParams();
|
|
1550
|
+
if (flags["q"]) qs.set("q", flags["q"]);
|
|
1551
|
+
if (flags["category"]) qs.set("category", flags["category"]);
|
|
1552
|
+
if (flags["status"]) qs.set("status", flags["status"]);
|
|
1553
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1554
|
+
const res = await client.get(`/api/v1/projects/${pid}/integrations/catalog${suffix}`);
|
|
1365
1555
|
emit(res.raw?.data ?? res.raw);
|
|
1366
1556
|
}
|
|
1367
1557
|
},
|
|
1368
1558
|
get: {
|
|
1369
|
-
summary: "Get one
|
|
1370
|
-
usage: "rogeriq integrations get <
|
|
1559
|
+
summary: "Get catalog entry + install state for one provider",
|
|
1560
|
+
usage: "rogeriq integrations get <provider>",
|
|
1371
1561
|
async run({ positional, flags }) {
|
|
1372
|
-
const [
|
|
1373
|
-
if (!
|
|
1562
|
+
const [provider] = positional;
|
|
1563
|
+
if (!provider) throw new CliError("Usage: rogeriq integrations get <provider>", "BAD_USAGE", 1);
|
|
1374
1564
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1375
1565
|
const pid = client.requireProject();
|
|
1376
|
-
const res = await client.get(`/api/projects/${pid}/integrations/${
|
|
1566
|
+
const res = await client.get(`/api/v1/projects/${pid}/integrations/catalog/${provider}`);
|
|
1377
1567
|
emit(res.raw?.data ?? res.raw);
|
|
1378
1568
|
}
|
|
1379
1569
|
},
|
|
1380
1570
|
connect: {
|
|
1381
|
-
summary: "Get
|
|
1382
|
-
usage: "rogeriq integrations connect <
|
|
1571
|
+
summary: "Get the install URL for a provider (open in browser to complete OAuth)",
|
|
1572
|
+
usage: "rogeriq integrations connect <provider>",
|
|
1383
1573
|
async run({ positional, flags }) {
|
|
1384
1574
|
const [provider] = positional;
|
|
1385
1575
|
if (!provider) throw new CliError("Usage: rogeriq integrations connect <provider>", "BAD_USAGE", 1);
|
|
1386
1576
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1387
1577
|
const pid = client.requireProject();
|
|
1388
|
-
const res = await client.
|
|
1578
|
+
const res = await client.post(`/api/v1/projects/${pid}/integrations/${provider}/install-url`);
|
|
1389
1579
|
emit(res.raw?.data ?? res.raw);
|
|
1390
1580
|
}
|
|
1391
1581
|
},
|
|
1392
|
-
|
|
1393
|
-
summary: "Update integration
|
|
1394
|
-
usage: "rogeriq integrations
|
|
1395
|
-
flags: [
|
|
1582
|
+
lifecycle: {
|
|
1583
|
+
summary: "Update integration lifecycle (status, display name, sidebar, settings)",
|
|
1584
|
+
usage: "rogeriq integrations lifecycle <provider> [--status active|paused] [--display-name ...] [--sidebar true|false] [--settings '{...}']",
|
|
1585
|
+
flags: [
|
|
1586
|
+
{ name: "status", type: "string" },
|
|
1587
|
+
{ name: "display-name", type: "string" },
|
|
1588
|
+
{ name: "sidebar", type: "string" },
|
|
1589
|
+
{ name: "settings", type: "string" }
|
|
1590
|
+
],
|
|
1396
1591
|
async run({ positional, flags }) {
|
|
1397
|
-
const [
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1592
|
+
const [provider] = positional;
|
|
1593
|
+
if (!provider) throw new CliError("Usage: rogeriq integrations lifecycle <provider>", "BAD_USAGE", 1);
|
|
1594
|
+
const body = {};
|
|
1595
|
+
if (flags["status"]) body["status"] = flags["status"];
|
|
1596
|
+
if (flags["display-name"]) body["display_name"] = flags["display-name"];
|
|
1597
|
+
if (flags["sidebar"]) body["sidebar_enabled"] = flags["sidebar"] === "true";
|
|
1598
|
+
if (flags["settings"]) {
|
|
1599
|
+
try {
|
|
1600
|
+
body["settings"] = JSON.parse(flags["settings"]);
|
|
1601
|
+
} catch {
|
|
1602
|
+
throw new CliError("--settings must be valid JSON", "BAD_JSON", 1);
|
|
1603
|
+
}
|
|
1405
1604
|
}
|
|
1605
|
+
if (Object.keys(body).length === 0) throw new CliError("No lifecycle changes provided", "NO_UPDATES", 1);
|
|
1406
1606
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1407
1607
|
const pid = client.requireProject();
|
|
1408
|
-
const res = await client.patch(`/api/projects/${pid}/integrations/${
|
|
1608
|
+
const res = await client.patch(`/api/v1/projects/${pid}/integrations/${provider}/lifecycle`, body);
|
|
1409
1609
|
emit(res.raw?.data ?? res.raw);
|
|
1410
1610
|
}
|
|
1411
1611
|
},
|
|
1412
1612
|
disconnect: {
|
|
1413
1613
|
summary: "Disconnect an integration",
|
|
1414
|
-
usage: "rogeriq integrations disconnect <
|
|
1614
|
+
usage: "rogeriq integrations disconnect <provider>",
|
|
1415
1615
|
async run({ positional, flags }) {
|
|
1416
|
-
const [
|
|
1417
|
-
if (!
|
|
1616
|
+
const [provider] = positional;
|
|
1617
|
+
if (!provider) throw new CliError("Usage: rogeriq integrations disconnect <provider>", "BAD_USAGE", 1);
|
|
1418
1618
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1419
1619
|
const pid = client.requireProject();
|
|
1420
|
-
await client.del(`/api/projects/${pid}/integrations/${
|
|
1421
|
-
emit({ ok: true, disconnected:
|
|
1620
|
+
await client.del(`/api/v1/projects/${pid}/integrations/${provider}`);
|
|
1621
|
+
emit({ ok: true, disconnected: provider });
|
|
1422
1622
|
}
|
|
1423
1623
|
}
|
|
1424
1624
|
}
|
|
@@ -1434,7 +1634,7 @@ var forms = {
|
|
|
1434
1634
|
async run({ flags }) {
|
|
1435
1635
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1436
1636
|
const pid = client.requireProject();
|
|
1437
|
-
const res = await client.get(`/api/projects/${pid}/forms`);
|
|
1637
|
+
const res = await client.get(`/api/v1/projects/${pid}/forms`);
|
|
1438
1638
|
emit(res.raw?.data ?? res.raw);
|
|
1439
1639
|
}
|
|
1440
1640
|
},
|
|
@@ -1446,7 +1646,7 @@ var forms = {
|
|
|
1446
1646
|
if (!id) throw new CliError("Usage: rogeriq forms get <id>", "BAD_USAGE", 1);
|
|
1447
1647
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1448
1648
|
const pid = client.requireProject();
|
|
1449
|
-
const res = await client.get(`/api/projects/${pid}/forms/${id}`);
|
|
1649
|
+
const res = await client.get(`/api/v1/projects/${pid}/forms/${id}`);
|
|
1450
1650
|
emit(res.raw?.data ?? res.raw);
|
|
1451
1651
|
}
|
|
1452
1652
|
},
|
|
@@ -1467,7 +1667,7 @@ var forms = {
|
|
|
1467
1667
|
else throw new CliError("--schema or --schema-file required", "MISSING_SCHEMA", 1);
|
|
1468
1668
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1469
1669
|
const pid = client.requireProject();
|
|
1470
|
-
const res = await client.post(`/api/projects/${pid}/forms`, { name, schema });
|
|
1670
|
+
const res = await client.post(`/api/v1/projects/${pid}/forms`, { name, schema });
|
|
1471
1671
|
emit(res.raw?.data ?? res.raw);
|
|
1472
1672
|
}
|
|
1473
1673
|
},
|
|
@@ -1489,7 +1689,7 @@ var forms = {
|
|
|
1489
1689
|
if (Object.keys(body).length === 0) throw new CliError("No updates provided", "NO_UPDATES", 1);
|
|
1490
1690
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1491
1691
|
const pid = client.requireProject();
|
|
1492
|
-
const res = await client.patch(`/api/projects/${pid}/forms/${id}`, body);
|
|
1692
|
+
const res = await client.patch(`/api/v1/projects/${pid}/forms/${id}`, body);
|
|
1493
1693
|
emit(res.raw?.data ?? res.raw);
|
|
1494
1694
|
}
|
|
1495
1695
|
},
|
|
@@ -1501,7 +1701,7 @@ var forms = {
|
|
|
1501
1701
|
if (!id) throw new CliError("Usage: rogeriq forms archive <id>", "BAD_USAGE", 1);
|
|
1502
1702
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1503
1703
|
const pid = client.requireProject();
|
|
1504
|
-
const res = await client.post(`/api/projects/${pid}/forms/${id}/archive`);
|
|
1704
|
+
const res = await client.post(`/api/v1/projects/${pid}/forms/${id}/archive`);
|
|
1505
1705
|
emit(res.raw?.data ?? res.raw);
|
|
1506
1706
|
}
|
|
1507
1707
|
},
|
|
@@ -1513,7 +1713,7 @@ var forms = {
|
|
|
1513
1713
|
if (!id) throw new CliError("Usage: rogeriq forms submissions <id>", "BAD_USAGE", 1);
|
|
1514
1714
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1515
1715
|
const pid = client.requireProject();
|
|
1516
|
-
const res = await client.get(`/api/projects/${pid}/forms/${id}/submissions`);
|
|
1716
|
+
const res = await client.get(`/api/v1/projects/${pid}/forms/${id}/submissions`);
|
|
1517
1717
|
emit(res.raw?.data ?? res.raw);
|
|
1518
1718
|
}
|
|
1519
1719
|
}
|
|
@@ -1529,7 +1729,7 @@ var beacons = {
|
|
|
1529
1729
|
async run({ flags }) {
|
|
1530
1730
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1531
1731
|
const pid = client.requireProject();
|
|
1532
|
-
const res = await client.get(`/api/projects/${pid}/beacons`);
|
|
1732
|
+
const res = await client.get(`/api/v1/projects/${pid}/beacons`);
|
|
1533
1733
|
emit(res.raw?.data ?? res.raw);
|
|
1534
1734
|
}
|
|
1535
1735
|
},
|
|
@@ -1541,7 +1741,7 @@ var beacons = {
|
|
|
1541
1741
|
if (!id) throw new CliError("Usage: rogeriq beacons get <id>", "BAD_USAGE", 1);
|
|
1542
1742
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1543
1743
|
const pid = client.requireProject();
|
|
1544
|
-
const res = await client.get(`/api/projects/${pid}/beacons/${id}`);
|
|
1744
|
+
const res = await client.get(`/api/v1/projects/${pid}/beacons/${id}`);
|
|
1545
1745
|
emit(res.raw?.data ?? res.raw);
|
|
1546
1746
|
}
|
|
1547
1747
|
},
|
|
@@ -1566,7 +1766,7 @@ var beacons = {
|
|
|
1566
1766
|
}
|
|
1567
1767
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1568
1768
|
const pid = client.requireProject();
|
|
1569
|
-
const res = await client.post(`/api/projects/${pid}/beacons`, body);
|
|
1769
|
+
const res = await client.post(`/api/v1/projects/${pid}/beacons`, body);
|
|
1570
1770
|
emit(res.raw?.data ?? res.raw);
|
|
1571
1771
|
}
|
|
1572
1772
|
},
|
|
@@ -1586,7 +1786,7 @@ var beacons = {
|
|
|
1586
1786
|
}
|
|
1587
1787
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1588
1788
|
const pid = client.requireProject();
|
|
1589
|
-
const res = await client.patch(`/api/projects/${pid}/beacons/${id}`, body);
|
|
1789
|
+
const res = await client.patch(`/api/v1/projects/${pid}/beacons/${id}`, body);
|
|
1590
1790
|
emit(res.raw?.data ?? res.raw);
|
|
1591
1791
|
}
|
|
1592
1792
|
},
|
|
@@ -1598,7 +1798,7 @@ var beacons = {
|
|
|
1598
1798
|
if (!id) throw new CliError("Usage: rogeriq beacons archive <id>", "BAD_USAGE", 1);
|
|
1599
1799
|
const client = new ApiClient({ projectId: flags["project"] });
|
|
1600
1800
|
const pid = client.requireProject();
|
|
1601
|
-
const res = await client.post(`/api/projects/${pid}/beacons/${id}/archive`);
|
|
1801
|
+
const res = await client.post(`/api/v1/projects/${pid}/beacons/${id}/archive`);
|
|
1602
1802
|
emit(res.raw?.data ?? res.raw);
|
|
1603
1803
|
}
|
|
1604
1804
|
}
|
|
@@ -1912,7 +2112,7 @@ var tools = [
|
|
|
1912
2112
|
},
|
|
1913
2113
|
async call(client, args) {
|
|
1914
2114
|
const pid = client.requireProject();
|
|
1915
|
-
const res = await client.get(`/api/projects/${pid}/kb/search?q=${encodeURIComponent(String(args["q"]))}`);
|
|
2115
|
+
const res = await client.get(`/api/v1/projects/${pid}/kb/search?q=${encodeURIComponent(String(args["q"]))}`);
|
|
1916
2116
|
return res.raw;
|
|
1917
2117
|
}
|
|
1918
2118
|
},
|
|
@@ -1922,7 +2122,7 @@ var tools = [
|
|
|
1922
2122
|
inputSchema: { type: "object", properties: {} },
|
|
1923
2123
|
async call(client) {
|
|
1924
2124
|
const pid = client.requireProject();
|
|
1925
|
-
const res = await client.get(`/api/projects/${pid}/kb/articles`);
|
|
2125
|
+
const res = await client.get(`/api/v1/projects/${pid}/kb/articles`);
|
|
1926
2126
|
return res.raw;
|
|
1927
2127
|
}
|
|
1928
2128
|
},
|
|
@@ -1941,7 +2141,7 @@ var tools = [
|
|
|
1941
2141
|
},
|
|
1942
2142
|
async call(client, args) {
|
|
1943
2143
|
const pid = client.requireProject();
|
|
1944
|
-
const res = await client.post(`/api/projects/${pid}/kb/articles`, args);
|
|
2144
|
+
const res = await client.post(`/api/v1/projects/${pid}/kb/articles`, args);
|
|
1945
2145
|
return res.raw;
|
|
1946
2146
|
}
|
|
1947
2147
|
},
|
|
@@ -1955,7 +2155,7 @@ var tools = [
|
|
|
1955
2155
|
},
|
|
1956
2156
|
async call(client, args) {
|
|
1957
2157
|
const pid = client.requireProject();
|
|
1958
|
-
const res = await client.post(`/api/projects/${pid}/agent/respond`, args);
|
|
2158
|
+
const res = await client.post(`/api/v1/projects/${pid}/agent/respond`, args);
|
|
1959
2159
|
return res.raw;
|
|
1960
2160
|
}
|
|
1961
2161
|
},
|
|
@@ -2021,7 +2221,57 @@ var tools = [
|
|
|
2021
2221
|
inputSchema: { type: "object", properties: {} },
|
|
2022
2222
|
async call(client) {
|
|
2023
2223
|
const pid = client.requireProject();
|
|
2024
|
-
const res = await client.get(`/api/projects/${pid}/integrations`);
|
|
2224
|
+
const res = await client.get(`/api/v1/projects/${pid}/integrations`);
|
|
2225
|
+
return res.raw;
|
|
2226
|
+
}
|
|
2227
|
+
},
|
|
2228
|
+
{
|
|
2229
|
+
name: "browse_integration_catalog",
|
|
2230
|
+
description: "Browse all available integrations with install state. Optional category/status/query filters.",
|
|
2231
|
+
inputSchema: {
|
|
2232
|
+
type: "object",
|
|
2233
|
+
properties: {
|
|
2234
|
+
q: { type: "string", description: "Free-text search" },
|
|
2235
|
+
category: { type: "string" },
|
|
2236
|
+
status: { type: "string" }
|
|
2237
|
+
}
|
|
2238
|
+
},
|
|
2239
|
+
async call(client, args) {
|
|
2240
|
+
const pid = client.requireProject();
|
|
2241
|
+
const qs = new URLSearchParams();
|
|
2242
|
+
for (const k of ["q", "category", "status"]) {
|
|
2243
|
+
const v = args[k];
|
|
2244
|
+
if (v !== void 0 && v !== null) qs.set(k, String(v));
|
|
2245
|
+
}
|
|
2246
|
+
const res = await client.get(`/api/v1/projects/${pid}/integrations/catalog?${qs}`);
|
|
2247
|
+
return res.raw;
|
|
2248
|
+
}
|
|
2249
|
+
},
|
|
2250
|
+
{
|
|
2251
|
+
name: "get_integration_install_url",
|
|
2252
|
+
description: "Return a browser URL the user should open to install or reconnect an integration.",
|
|
2253
|
+
inputSchema: {
|
|
2254
|
+
type: "object",
|
|
2255
|
+
properties: { provider: { type: "string", description: "e.g. slack, github, shopify" } },
|
|
2256
|
+
required: ["provider"]
|
|
2257
|
+
},
|
|
2258
|
+
async call(client, args) {
|
|
2259
|
+
const pid = client.requireProject();
|
|
2260
|
+
const res = await client.post(`/api/v1/projects/${pid}/integrations/${args["provider"]}/install-url`);
|
|
2261
|
+
return res.raw;
|
|
2262
|
+
}
|
|
2263
|
+
},
|
|
2264
|
+
{
|
|
2265
|
+
name: "disconnect_integration",
|
|
2266
|
+
description: "Disconnect an integration (status=disconnected, sidebar hidden).",
|
|
2267
|
+
inputSchema: {
|
|
2268
|
+
type: "object",
|
|
2269
|
+
properties: { provider: { type: "string" } },
|
|
2270
|
+
required: ["provider"]
|
|
2271
|
+
},
|
|
2272
|
+
async call(client, args) {
|
|
2273
|
+
const pid = client.requireProject();
|
|
2274
|
+
const res = await client.del(`/api/v1/projects/${pid}/integrations/${args["provider"]}`);
|
|
2025
2275
|
return res.raw;
|
|
2026
2276
|
}
|
|
2027
2277
|
},
|
|
@@ -2090,7 +2340,7 @@ async function runMcpServer() {
|
|
|
2090
2340
|
return {
|
|
2091
2341
|
protocolVersion: "2024-11-05",
|
|
2092
2342
|
capabilities: { tools: {} },
|
|
2093
|
-
serverInfo: { name: "rogeriq", version: "0.
|
|
2343
|
+
serverInfo: { name: "rogeriq", version: "0.3.0" }
|
|
2094
2344
|
};
|
|
2095
2345
|
case "notifications/initialized":
|
|
2096
2346
|
return void 0;
|
|
@@ -2213,7 +2463,7 @@ var GLOBAL_FLAGS = [
|
|
|
2213
2463
|
{ name: "version", alias: "v", type: "boolean" },
|
|
2214
2464
|
{ name: "project", type: "string" }
|
|
2215
2465
|
];
|
|
2216
|
-
var VERSION = "0.
|
|
2466
|
+
var VERSION = "0.3.0";
|
|
2217
2467
|
async function main() {
|
|
2218
2468
|
const argv = process.argv.slice(2);
|
|
2219
2469
|
const { positional, flags } = parseArgs(argv, GLOBAL_FLAGS);
|
|
@@ -2226,7 +2476,7 @@ async function main() {
|
|
|
2226
2476
|
`);
|
|
2227
2477
|
return;
|
|
2228
2478
|
}
|
|
2229
|
-
if (positional.length === 0
|
|
2479
|
+
if (positional.length === 0) {
|
|
2230
2480
|
printRootHelp();
|
|
2231
2481
|
return;
|
|
2232
2482
|
}
|
|
@@ -2252,6 +2502,9 @@ async function main() {
|
|
|
2252
2502
|
const cmdParsed = parseArgs(cmdArgsRaw, [...GLOBAL_FLAGS, ...cmd.flags ?? []]);
|
|
2253
2503
|
const project = flagString(cmdParsed.flags, "project") ?? flagString(flags, "project");
|
|
2254
2504
|
if (project) cmdParsed.flags["project"] = project;
|
|
2505
|
+
if (flagBool(flags, "help")) cmdParsed.flags["help"] = true;
|
|
2506
|
+
if (flagBool(flags, "json")) cmdParsed.flags["json"] = true;
|
|
2507
|
+
if (flagBool(flags, "quiet")) cmdParsed.flags["quiet"] = true;
|
|
2255
2508
|
if (flagBool(cmdParsed.flags, "help")) {
|
|
2256
2509
|
printCommandHelp(groupName, subName ?? "", cmd);
|
|
2257
2510
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rogeriq/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Command-line interface for RogerIQ. Manage conversations, projects, knowledge base, widget, integrations, and webhooks from your terminal or AI agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -10,18 +10,21 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"README.md",
|
|
13
|
-
"AGENTS.md"
|
|
13
|
+
"AGENTS.md",
|
|
14
|
+
"CHANGELOG.md"
|
|
14
15
|
],
|
|
15
16
|
"scripts": {
|
|
16
17
|
"build": "esbuild src/index.ts --bundle --platform=node --target=node18 --format=esm --outfile=dist/index.mjs --banner:js='#!/usr/bin/env node' --packages=external",
|
|
17
18
|
"dev": "esbuild src/index.ts --bundle --platform=node --target=node18 --format=esm --outfile=dist/index.mjs --banner:js='#!/usr/bin/env node' --watch",
|
|
18
|
-
"typecheck": "tsc --noEmit"
|
|
19
|
+
"typecheck": "tsc --noEmit",
|
|
20
|
+
"test": "vitest run"
|
|
19
21
|
},
|
|
20
22
|
"dependencies": {},
|
|
21
23
|
"devDependencies": {
|
|
22
24
|
"@types/node": "^22.10.0",
|
|
23
25
|
"esbuild": "^0.24.0",
|
|
24
|
-
"typescript": "^5.9.3"
|
|
26
|
+
"typescript": "^5.9.3",
|
|
27
|
+
"vitest": "^4.1.0"
|
|
25
28
|
},
|
|
26
29
|
"engines": {
|
|
27
30
|
"node": ">=18"
|