@withone/cli 1.18.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -162,6 +162,21 @@ one list
|
|
|
162
162
|
|
|
163
163
|
You need the connection key (rightmost column) when executing actions.
|
|
164
164
|
|
|
165
|
+
### `one connection delete <connection-key>`
|
|
166
|
+
|
|
167
|
+
Remove a connection by its key.
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
one connection delete live::gmail::default::abc123
|
|
171
|
+
one connection rm live::gmail::default::abc123 # alias
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Shows the connection details and asks for confirmation before deleting. Use `--force` to skip the confirmation prompt.
|
|
175
|
+
|
|
176
|
+
| Option | What it does |
|
|
177
|
+
|--------|-------------|
|
|
178
|
+
| `-f, --force` | Skip confirmation prompt |
|
|
179
|
+
|
|
165
180
|
### `one platforms`
|
|
166
181
|
|
|
167
182
|
Browse all 200+ available platforms.
|
|
@@ -10,7 +10,6 @@ import { exec } from "child_process";
|
|
|
10
10
|
import { promisify } from "util";
|
|
11
11
|
|
|
12
12
|
// src/lib/api.ts
|
|
13
|
-
var API_BASE = "https://api.withone.ai/v1";
|
|
14
13
|
var ApiError = class extends Error {
|
|
15
14
|
constructor(status, message) {
|
|
16
15
|
super(message);
|
|
@@ -19,14 +18,16 @@ var ApiError = class extends Error {
|
|
|
19
18
|
}
|
|
20
19
|
};
|
|
21
20
|
var OneApi = class {
|
|
22
|
-
constructor(apiKey) {
|
|
21
|
+
constructor(apiKey, apiBase) {
|
|
23
22
|
this.apiKey = apiKey;
|
|
23
|
+
this.apiBase = apiBase ?? "https://api.withone.ai/v1";
|
|
24
24
|
}
|
|
25
|
+
apiBase;
|
|
25
26
|
async request(path3) {
|
|
26
27
|
return this.requestFull({ path: path3 });
|
|
27
28
|
}
|
|
28
29
|
async requestFull(opts) {
|
|
29
|
-
let url = `${
|
|
30
|
+
let url = `${this.apiBase}${opts.path}`;
|
|
30
31
|
if (opts.queryParams && Object.keys(opts.queryParams).length > 0) {
|
|
31
32
|
const params = new URLSearchParams(opts.queryParams);
|
|
32
33
|
url += `?${params.toString()}`;
|
|
@@ -75,6 +76,9 @@ var OneApi = class {
|
|
|
75
76
|
} while (page <= totalPages);
|
|
76
77
|
return allConnections;
|
|
77
78
|
}
|
|
79
|
+
async deleteConnection(id) {
|
|
80
|
+
await this.requestFull({ path: `/vault/connections/${id}`, method: "DELETE" });
|
|
81
|
+
}
|
|
78
82
|
async listPlatforms() {
|
|
79
83
|
const allPlatforms = [];
|
|
80
84
|
let page = 1;
|
|
@@ -129,7 +133,7 @@ var OneApi = class {
|
|
|
129
133
|
};
|
|
130
134
|
}
|
|
131
135
|
async requestWithMeta(opts) {
|
|
132
|
-
let url = `${
|
|
136
|
+
let url = `${this.apiBase}${opts.path}`;
|
|
133
137
|
if (opts.queryParams && Object.keys(opts.queryParams).length > 0) {
|
|
134
138
|
const params = new URLSearchParams(opts.queryParams);
|
|
135
139
|
url += `?${params.toString()}`;
|
|
@@ -216,7 +220,7 @@ var OneApi = class {
|
|
|
216
220
|
};
|
|
217
221
|
const finalActionPath = args.pathVariables ? replacePathVariables(action.path, args.pathVariables) : action.path;
|
|
218
222
|
const normalizedPath = finalActionPath.startsWith("/") ? finalActionPath : `/${finalActionPath}`;
|
|
219
|
-
const url = `${
|
|
223
|
+
const url = `${this.apiBase.replace("/v1", "")}/v1/passthrough${normalizedPath}`;
|
|
220
224
|
const isCustomAction = action.tags?.includes("custom");
|
|
221
225
|
let requestData = args.data;
|
|
222
226
|
if (isCustomAction && method?.toLowerCase() !== "get") {
|
|
@@ -778,7 +782,7 @@ async function executeSubflowStep(step, context, api, permissions, allowedAction
|
|
|
778
782
|
if (flowStack.includes(resolvedKey)) {
|
|
779
783
|
throw new Error(`Circular flow detected: ${[...flowStack, resolvedKey].join(" \u2192 ")}`);
|
|
780
784
|
}
|
|
781
|
-
const { loadFlow: loadFlow2 } = await import("./flow-runner-
|
|
785
|
+
const { loadFlow: loadFlow2 } = await import("./flow-runner-RFLXA3YY.js");
|
|
782
786
|
const subFlow = loadFlow2(resolvedKey);
|
|
783
787
|
const subContext = await executeFlow(
|
|
784
788
|
subFlow,
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
loadFlow,
|
|
12
12
|
resolveFlowPath,
|
|
13
13
|
saveFlow
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-CJBJQPHS.js";
|
|
15
15
|
|
|
16
16
|
// src/index.ts
|
|
17
17
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -101,6 +101,22 @@ function getAccessControlFromAllSources() {
|
|
|
101
101
|
function getAccessControl() {
|
|
102
102
|
return readConfig()?.accessControl ?? {};
|
|
103
103
|
}
|
|
104
|
+
var DEFAULT_API_BASE = "https://api.withone.ai/v1";
|
|
105
|
+
function getApiBase() {
|
|
106
|
+
const config = readConfig();
|
|
107
|
+
if (config?.apiBase) return `${config.apiBase}/v1`;
|
|
108
|
+
return DEFAULT_API_BASE;
|
|
109
|
+
}
|
|
110
|
+
function updateApiBase(url) {
|
|
111
|
+
const config = readConfig();
|
|
112
|
+
if (!config) return;
|
|
113
|
+
if (url) {
|
|
114
|
+
config.apiBase = url;
|
|
115
|
+
} else {
|
|
116
|
+
delete config.apiBase;
|
|
117
|
+
}
|
|
118
|
+
writeConfig(config);
|
|
119
|
+
}
|
|
104
120
|
function getCacheTtl() {
|
|
105
121
|
if (process.env.ONE_CACHE_TTL) {
|
|
106
122
|
const val = parseInt(process.env.ONE_CACHE_TTL, 10);
|
|
@@ -465,6 +481,113 @@ async function configCommand() {
|
|
|
465
481
|
p2.outro("No changes made.");
|
|
466
482
|
return;
|
|
467
483
|
}
|
|
484
|
+
const currentBase = getApiBase();
|
|
485
|
+
const isCustomBase = !!readConfig()?.apiBase;
|
|
486
|
+
const baseUrlMode = await p2.select({
|
|
487
|
+
message: "API base URL",
|
|
488
|
+
options: [
|
|
489
|
+
{ value: "default", label: "Default", hint: "https://api.withone.ai" },
|
|
490
|
+
{ value: "custom", label: "Custom", hint: "Use a different API endpoint" }
|
|
491
|
+
],
|
|
492
|
+
initialValue: isCustomBase ? "custom" : "default"
|
|
493
|
+
});
|
|
494
|
+
if (p2.isCancel(baseUrlMode)) {
|
|
495
|
+
p2.outro("No changes made.");
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
let newApiKey = config.apiKey;
|
|
499
|
+
if (baseUrlMode === "custom") {
|
|
500
|
+
const customUrl = await p2.text({
|
|
501
|
+
message: "Enter API base URL:",
|
|
502
|
+
placeholder: "https://development-api.withone.ai",
|
|
503
|
+
initialValue: isCustomBase ? currentBase.replace(/\/v1$/, "") : "",
|
|
504
|
+
validate: (value) => {
|
|
505
|
+
if (!value) return "URL is required";
|
|
506
|
+
try {
|
|
507
|
+
new URL(value);
|
|
508
|
+
} catch {
|
|
509
|
+
return "Invalid URL";
|
|
510
|
+
}
|
|
511
|
+
return void 0;
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
if (p2.isCancel(customUrl)) {
|
|
515
|
+
p2.outro("No changes made.");
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const normalized = customUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
|
|
519
|
+
const apiKey = await p2.text({
|
|
520
|
+
message: `Enter your API key for ${pc.cyan(normalized)}:`,
|
|
521
|
+
placeholder: "sk_live_...",
|
|
522
|
+
validate: (value) => {
|
|
523
|
+
if (!value) return "API key is required";
|
|
524
|
+
if (!value.startsWith("sk_live_") && !value.startsWith("sk_test_")) {
|
|
525
|
+
return "API key should start with sk_live_ or sk_test_";
|
|
526
|
+
}
|
|
527
|
+
return void 0;
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
if (p2.isCancel(apiKey)) {
|
|
531
|
+
p2.outro("No changes made.");
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
const spinner5 = p2.spinner();
|
|
535
|
+
spinner5.start("Validating API key...");
|
|
536
|
+
let isValid = false;
|
|
537
|
+
try {
|
|
538
|
+
const api = new OneApi(apiKey, `${normalized}/v1`);
|
|
539
|
+
isValid = await api.validateApiKey();
|
|
540
|
+
} catch (err) {
|
|
541
|
+
spinner5.stop("Connection failed");
|
|
542
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
543
|
+
p2.log.error(`Could not reach ${pc.cyan(normalized)}: ${msg}`);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (!isValid) {
|
|
547
|
+
spinner5.stop("Invalid API key");
|
|
548
|
+
p2.log.error(`Invalid API key for ${pc.cyan(normalized)}.`);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
spinner5.stop("API key validated");
|
|
552
|
+
updateApiBase(normalized);
|
|
553
|
+
newApiKey = apiKey;
|
|
554
|
+
} else if (isCustomBase) {
|
|
555
|
+
const apiKey = await p2.text({
|
|
556
|
+
message: `Enter your API key for ${pc.cyan("https://api.withone.ai")}:`,
|
|
557
|
+
placeholder: "sk_live_...",
|
|
558
|
+
validate: (value) => {
|
|
559
|
+
if (!value) return "API key is required";
|
|
560
|
+
if (!value.startsWith("sk_live_") && !value.startsWith("sk_test_")) {
|
|
561
|
+
return "API key should start with sk_live_ or sk_test_";
|
|
562
|
+
}
|
|
563
|
+
return void 0;
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
if (p2.isCancel(apiKey)) {
|
|
567
|
+
p2.outro("No changes made.");
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const spinner5 = p2.spinner();
|
|
571
|
+
spinner5.start("Validating API key...");
|
|
572
|
+
let isValid = false;
|
|
573
|
+
try {
|
|
574
|
+
const api = new OneApi(apiKey, "https://api.withone.ai/v1");
|
|
575
|
+
isValid = await api.validateApiKey();
|
|
576
|
+
} catch (err) {
|
|
577
|
+
spinner5.stop("Connection failed");
|
|
578
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
579
|
+
p2.log.error(`Could not reach ${pc.cyan("https://api.withone.ai")}: ${msg}`);
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
if (!isValid) {
|
|
583
|
+
spinner5.stop("Invalid API key");
|
|
584
|
+
p2.log.error(`Invalid API key. Get a valid key at ${getApiKeyUrl()}`);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
spinner5.stop("API key validated");
|
|
588
|
+
updateApiBase(null);
|
|
589
|
+
newApiKey = apiKey;
|
|
590
|
+
}
|
|
468
591
|
const settings = {
|
|
469
592
|
permissions,
|
|
470
593
|
connectionKeys: connectionKeys ?? ["*"],
|
|
@@ -472,30 +595,35 @@ async function configCommand() {
|
|
|
472
595
|
knowledgeAgent
|
|
473
596
|
};
|
|
474
597
|
updateAccessControl(settings);
|
|
598
|
+
const updatedConfig = readConfig();
|
|
599
|
+
if (updatedConfig && newApiKey !== config.apiKey) {
|
|
600
|
+
updatedConfig.apiKey = newApiKey;
|
|
601
|
+
writeConfig(updatedConfig);
|
|
602
|
+
}
|
|
475
603
|
const ac = getAccessControl();
|
|
476
604
|
const statuses = getAgentStatuses();
|
|
477
605
|
const reinstalled = [];
|
|
478
606
|
for (const s of statuses) {
|
|
479
607
|
if (s.globalMcp) {
|
|
480
|
-
installMcpConfig(s.agent,
|
|
608
|
+
installMcpConfig(s.agent, newApiKey, "global", ac);
|
|
481
609
|
reinstalled.push(`${s.agent.name} (global)`);
|
|
482
610
|
}
|
|
483
611
|
if (s.projectMcp) {
|
|
484
|
-
installMcpConfig(s.agent,
|
|
612
|
+
installMcpConfig(s.agent, newApiKey, "project", ac);
|
|
485
613
|
reinstalled.push(`${s.agent.name} (project)`);
|
|
486
614
|
}
|
|
487
615
|
}
|
|
488
616
|
if (reinstalled.length > 0) {
|
|
489
617
|
p2.log.success(`Updated MCP configs: ${reinstalled.join(", ")}`);
|
|
490
618
|
}
|
|
491
|
-
p2.outro("
|
|
619
|
+
p2.outro("Configuration updated.");
|
|
492
620
|
}
|
|
493
621
|
async function selectConnections(apiKey) {
|
|
494
622
|
const spinner5 = p2.spinner();
|
|
495
623
|
spinner5.start("Fetching connections...");
|
|
496
624
|
let connections;
|
|
497
625
|
try {
|
|
498
|
-
const api = new OneApi(apiKey);
|
|
626
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
499
627
|
const rawConnections = await api.listConnections();
|
|
500
628
|
connections = rawConnections.map((c) => ({ platform: c.platform, key: c.key }));
|
|
501
629
|
spinner5.stop(`Found ${connections.length} connection(s)`);
|
|
@@ -665,7 +793,7 @@ ${pc2.cyan(getApiKeyUrl())}`, "API Key");
|
|
|
665
793
|
}
|
|
666
794
|
const spinner5 = p3.spinner();
|
|
667
795
|
spinner5.start("Validating API key...");
|
|
668
|
-
const api = new OneApi(newKey);
|
|
796
|
+
const api = new OneApi(newKey, getApiBase());
|
|
669
797
|
const isValid = await api.validateApiKey();
|
|
670
798
|
if (!isValid) {
|
|
671
799
|
spinner5.stop("Invalid API key");
|
|
@@ -884,7 +1012,7 @@ ${pc2.cyan(getApiKeyUrl())}`, "API Key");
|
|
|
884
1012
|
}
|
|
885
1013
|
const spinner5 = p3.spinner();
|
|
886
1014
|
spinner5.start("Validating API key...");
|
|
887
|
-
const api = new OneApi(apiKey);
|
|
1015
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
888
1016
|
const isValid = await api.validateApiKey();
|
|
889
1017
|
if (!isValid) {
|
|
890
1018
|
spinner5.stop("Invalid API key");
|
|
@@ -928,7 +1056,7 @@ var TOP_INTEGRATIONS = [
|
|
|
928
1056
|
{ value: "notion", label: "Notion", hint: "Access pages, databases, and docs" }
|
|
929
1057
|
];
|
|
930
1058
|
async function promptConnectIntegrations(apiKey) {
|
|
931
|
-
const api = new OneApi(apiKey);
|
|
1059
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
932
1060
|
const connected = [];
|
|
933
1061
|
try {
|
|
934
1062
|
const existing = await api.listConnections();
|
|
@@ -1090,7 +1218,7 @@ async function connectionAddCommand(platformArg) {
|
|
|
1090
1218
|
p4.cancel("Not configured. Run `one init` first.");
|
|
1091
1219
|
process.exit(1);
|
|
1092
1220
|
}
|
|
1093
|
-
const api = new OneApi(apiKey);
|
|
1221
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
1094
1222
|
const spinner5 = p4.spinner();
|
|
1095
1223
|
spinner5.start("Loading platforms...");
|
|
1096
1224
|
let platforms;
|
|
@@ -1194,7 +1322,7 @@ async function connectionListCommand(options) {
|
|
|
1194
1322
|
if (!apiKey) {
|
|
1195
1323
|
error("Not configured. Run `one init` first.");
|
|
1196
1324
|
}
|
|
1197
|
-
const api = new OneApi(apiKey);
|
|
1325
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
1198
1326
|
const spinner5 = createSpinner();
|
|
1199
1327
|
spinner5.start("Loading connections...");
|
|
1200
1328
|
try {
|
|
@@ -1266,6 +1394,65 @@ Add one with: ${pc4.cyan("one connection add gmail")}`,
|
|
|
1266
1394
|
error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
|
|
1267
1395
|
}
|
|
1268
1396
|
}
|
|
1397
|
+
async function connectionDeleteCommand(connectionKey, options) {
|
|
1398
|
+
const apiKey = getApiKey();
|
|
1399
|
+
if (!apiKey) {
|
|
1400
|
+
error("Not configured. Run `one init` first.");
|
|
1401
|
+
}
|
|
1402
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
1403
|
+
const spinner5 = createSpinner();
|
|
1404
|
+
spinner5.start("Finding connection...");
|
|
1405
|
+
let allConnections;
|
|
1406
|
+
try {
|
|
1407
|
+
allConnections = await api.listConnections();
|
|
1408
|
+
} catch (error2) {
|
|
1409
|
+
spinner5.stop("Failed to load connections");
|
|
1410
|
+
error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
|
|
1411
|
+
return;
|
|
1412
|
+
}
|
|
1413
|
+
const ac = getAccessControlFromAllSources();
|
|
1414
|
+
const allowedKeys = ac.connectionKeys || ["*"];
|
|
1415
|
+
const connections = allowedKeys.includes("*") ? allConnections : allConnections.filter((conn) => allowedKeys.includes(conn.key));
|
|
1416
|
+
const match = connections.find((conn) => conn.key === connectionKey);
|
|
1417
|
+
if (!match) {
|
|
1418
|
+
spinner5.stop("Connection not found");
|
|
1419
|
+
error(`No connection found with key: ${connectionKey}`);
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
const connection2 = match;
|
|
1423
|
+
spinner5.stop(`Found ${connection2.platform} (${connection2.state})`);
|
|
1424
|
+
if (!isAgentMode() && !options?.force) {
|
|
1425
|
+
console.log();
|
|
1426
|
+
console.log(` ${getStatusIndicator(connection2.state)} ${connection2.platform} ${pc4.dim(connection2.key)}`);
|
|
1427
|
+
console.log();
|
|
1428
|
+
const confirmed = await p4.confirm({
|
|
1429
|
+
message: "Are you sure you want to delete this connection?",
|
|
1430
|
+
initialValue: false
|
|
1431
|
+
});
|
|
1432
|
+
if (p4.isCancel(confirmed) || !confirmed) {
|
|
1433
|
+
p4.cancel("Deletion cancelled.");
|
|
1434
|
+
process.exit(0);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
const deleteSpinner = createSpinner();
|
|
1438
|
+
deleteSpinner.start("Deleting connection...");
|
|
1439
|
+
try {
|
|
1440
|
+
await api.deleteConnection(connection2.id);
|
|
1441
|
+
deleteSpinner.stop("Connection deleted");
|
|
1442
|
+
if (isAgentMode()) {
|
|
1443
|
+
json({
|
|
1444
|
+
deleted: true,
|
|
1445
|
+
platform: connection2.platform,
|
|
1446
|
+
key: connection2.key
|
|
1447
|
+
});
|
|
1448
|
+
return;
|
|
1449
|
+
}
|
|
1450
|
+
p4.log.success(`${pc4.green("\u2713")} ${connection2.platform} connection removed.`);
|
|
1451
|
+
} catch (error2) {
|
|
1452
|
+
deleteSpinner.stop("Failed to delete connection");
|
|
1453
|
+
error(`Error: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1269
1456
|
function getStatusIndicator(state) {
|
|
1270
1457
|
switch (state) {
|
|
1271
1458
|
case "operational":
|
|
@@ -1290,7 +1477,7 @@ async function platformsCommand(options) {
|
|
|
1290
1477
|
if (isAgentMode()) {
|
|
1291
1478
|
options.json = true;
|
|
1292
1479
|
}
|
|
1293
|
-
const api = new OneApi(apiKey);
|
|
1480
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
1294
1481
|
const spinner5 = createSpinner();
|
|
1295
1482
|
spinner5.start("Loading platforms...");
|
|
1296
1483
|
try {
|
|
@@ -1498,7 +1685,7 @@ function parseJsonArg(value, argName) {
|
|
|
1498
1685
|
async function actionsSearchCommand(platform, query, options) {
|
|
1499
1686
|
intro2(pc6.bgCyan(pc6.black(" One ")));
|
|
1500
1687
|
const { apiKey, permissions, actionIds, knowledgeAgent } = getConfig();
|
|
1501
|
-
const api = new OneApi(apiKey);
|
|
1688
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
1502
1689
|
const spinner5 = createSpinner();
|
|
1503
1690
|
spinner5.start(`Searching actions on ${pc6.cyan(platform)} for "${query}"...`);
|
|
1504
1691
|
try {
|
|
@@ -1640,7 +1827,7 @@ async function actionsKnowledgeCommand(platform, actionId, options) {
|
|
|
1640
1827
|
}
|
|
1641
1828
|
intro2(pc6.bgCyan(pc6.black(" One ")));
|
|
1642
1829
|
const { apiKey, actionIds, connectionKeys } = getConfig();
|
|
1643
|
-
const api = new OneApi(apiKey);
|
|
1830
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
1644
1831
|
if (!isActionAllowed(actionId, actionIds)) {
|
|
1645
1832
|
error(`Action "${actionId}" is not in the allowed action list.`);
|
|
1646
1833
|
}
|
|
@@ -1747,7 +1934,7 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
|
|
|
1747
1934
|
if (!connectionKeys.includes("*") && !connectionKeys.includes(connectionKey)) {
|
|
1748
1935
|
error(`Connection key "${connectionKey}" is not allowed.`);
|
|
1749
1936
|
}
|
|
1750
|
-
const api = new OneApi(apiKey);
|
|
1937
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
1751
1938
|
const spinner5 = createSpinner();
|
|
1752
1939
|
spinner5.start("Loading action details...");
|
|
1753
1940
|
try {
|
|
@@ -2746,7 +2933,7 @@ Execute: ${pc7.cyan(`one flow execute ${flow2.key}`)}`);
|
|
|
2746
2933
|
async function flowExecuteCommand(keyOrPath, options) {
|
|
2747
2934
|
intro2(pc7.bgCyan(pc7.black(" One Workflow ")));
|
|
2748
2935
|
const { apiKey, permissions, actionIds } = getConfig2();
|
|
2749
|
-
const api = new OneApi(apiKey);
|
|
2936
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
2750
2937
|
const spinner5 = createSpinner();
|
|
2751
2938
|
spinner5.start(`Loading workflow "${keyOrPath}"...`);
|
|
2752
2939
|
let flow2;
|
|
@@ -2918,7 +3105,7 @@ async function flowResumeCommand(runId) {
|
|
|
2918
3105
|
error(`Run "${runId}" is ${state.status} \u2014 can only resume paused or failed runs`);
|
|
2919
3106
|
}
|
|
2920
3107
|
const { apiKey, permissions, actionIds } = getConfig2();
|
|
2921
|
-
const api = new OneApi(apiKey);
|
|
3108
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
2922
3109
|
let flow2;
|
|
2923
3110
|
try {
|
|
2924
3111
|
flow2 = loadFlow(state.flowKey);
|
|
@@ -3236,7 +3423,7 @@ async function relayCreateCommand(options) {
|
|
|
3236
3423
|
if (!connectionKeys.includes("*") && !connectionKeys.includes(options.connectionKey)) {
|
|
3237
3424
|
error(`Connection key "${options.connectionKey}" is not allowed.`);
|
|
3238
3425
|
}
|
|
3239
|
-
const api = new OneApi(apiKey);
|
|
3426
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3240
3427
|
const spinner5 = createSpinner();
|
|
3241
3428
|
spinner5.start("Creating relay endpoint...");
|
|
3242
3429
|
try {
|
|
@@ -3268,7 +3455,7 @@ async function relayCreateCommand(options) {
|
|
|
3268
3455
|
}
|
|
3269
3456
|
async function relayListCommand(options) {
|
|
3270
3457
|
const { apiKey } = getConfig3();
|
|
3271
|
-
const api = new OneApi(apiKey);
|
|
3458
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3272
3459
|
const spinner5 = createSpinner();
|
|
3273
3460
|
spinner5.start("Loading relay endpoints...");
|
|
3274
3461
|
try {
|
|
@@ -3315,7 +3502,7 @@ async function relayListCommand(options) {
|
|
|
3315
3502
|
}
|
|
3316
3503
|
async function relayGetCommand(id) {
|
|
3317
3504
|
const { apiKey } = getConfig3();
|
|
3318
|
-
const api = new OneApi(apiKey);
|
|
3505
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3319
3506
|
const spinner5 = createSpinner();
|
|
3320
3507
|
spinner5.start("Loading relay endpoint...");
|
|
3321
3508
|
try {
|
|
@@ -3346,7 +3533,7 @@ async function relayGetCommand(id) {
|
|
|
3346
3533
|
}
|
|
3347
3534
|
async function relayUpdateCommand(id, options) {
|
|
3348
3535
|
const { apiKey } = getConfig3();
|
|
3349
|
-
const api = new OneApi(apiKey);
|
|
3536
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3350
3537
|
const spinner5 = createSpinner();
|
|
3351
3538
|
spinner5.start("Updating relay endpoint...");
|
|
3352
3539
|
try {
|
|
@@ -3373,7 +3560,7 @@ async function relayUpdateCommand(id, options) {
|
|
|
3373
3560
|
}
|
|
3374
3561
|
async function relayDeleteCommand(id) {
|
|
3375
3562
|
const { apiKey } = getConfig3();
|
|
3376
|
-
const api = new OneApi(apiKey);
|
|
3563
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3377
3564
|
const spinner5 = createSpinner();
|
|
3378
3565
|
spinner5.start("Deleting relay endpoint...");
|
|
3379
3566
|
try {
|
|
@@ -3392,7 +3579,7 @@ async function relayDeleteCommand(id) {
|
|
|
3392
3579
|
}
|
|
3393
3580
|
async function relayActivateCommand(id, options) {
|
|
3394
3581
|
const { apiKey } = getConfig3();
|
|
3395
|
-
const api = new OneApi(apiKey);
|
|
3582
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3396
3583
|
const spinner5 = createSpinner();
|
|
3397
3584
|
spinner5.start("Activating relay endpoint...");
|
|
3398
3585
|
try {
|
|
@@ -3416,7 +3603,7 @@ async function relayActivateCommand(id, options) {
|
|
|
3416
3603
|
}
|
|
3417
3604
|
async function relayEventsCommand(options) {
|
|
3418
3605
|
const { apiKey } = getConfig3();
|
|
3419
|
-
const api = new OneApi(apiKey);
|
|
3606
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3420
3607
|
const spinner5 = createSpinner();
|
|
3421
3608
|
spinner5.start("Loading relay events...");
|
|
3422
3609
|
try {
|
|
@@ -3463,7 +3650,7 @@ async function relayEventsCommand(options) {
|
|
|
3463
3650
|
}
|
|
3464
3651
|
async function relayEventGetCommand(id) {
|
|
3465
3652
|
const { apiKey } = getConfig3();
|
|
3466
|
-
const api = new OneApi(apiKey);
|
|
3653
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3467
3654
|
const spinner5 = createSpinner();
|
|
3468
3655
|
spinner5.start("Loading relay event...");
|
|
3469
3656
|
try {
|
|
@@ -3491,7 +3678,7 @@ async function relayDeliveriesCommand(options) {
|
|
|
3491
3678
|
error("Provide either --endpoint-id or --event-id");
|
|
3492
3679
|
}
|
|
3493
3680
|
const { apiKey } = getConfig3();
|
|
3494
|
-
const api = new OneApi(apiKey);
|
|
3681
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3495
3682
|
const spinner5 = createSpinner();
|
|
3496
3683
|
spinner5.start("Loading deliveries...");
|
|
3497
3684
|
try {
|
|
@@ -3523,7 +3710,7 @@ async function relayDeliveriesCommand(options) {
|
|
|
3523
3710
|
}
|
|
3524
3711
|
async function relayEventTypesCommand(platform) {
|
|
3525
3712
|
const { apiKey } = getConfig3();
|
|
3526
|
-
const api = new OneApi(apiKey);
|
|
3713
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3527
3714
|
const spinner5 = createSpinner();
|
|
3528
3715
|
spinner5.start(`Loading event types for ${pc8.cyan(platform)}...`);
|
|
3529
3716
|
try {
|
|
@@ -3616,7 +3803,7 @@ async function cacheUpdateAllCommand() {
|
|
|
3616
3803
|
if (!apiKey) {
|
|
3617
3804
|
error("Not configured. Run `one init` first.");
|
|
3618
3805
|
}
|
|
3619
|
-
const api = new OneApi(apiKey);
|
|
3806
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
3620
3807
|
const entries = listCacheEntries();
|
|
3621
3808
|
if (entries.length === 0) {
|
|
3622
3809
|
if (isAgentMode()) {
|
|
@@ -3698,6 +3885,7 @@ Search for actions, read their docs, and execute them. This is the core workflow
|
|
|
3698
3885
|
**Quick start:**
|
|
3699
3886
|
\`\`\`bash
|
|
3700
3887
|
one --agent connection list # See connected platforms
|
|
3888
|
+
one --agent connection delete <connection-key> # Remove a connection
|
|
3701
3889
|
one --agent actions search <platform> "<query>" -t execute # Find an action
|
|
3702
3890
|
one --agent actions knowledge <platform> <actionId> # Read docs (REQUIRED)
|
|
3703
3891
|
one --agent actions execute <platform> <actionId> <key> -d '{}' # Execute it
|
|
@@ -3781,6 +3969,14 @@ one --agent connection list
|
|
|
3781
3969
|
|
|
3782
3970
|
Returns platforms, status, connection keys, and tags.
|
|
3783
3971
|
|
|
3972
|
+
### 1b. Delete a Connection
|
|
3973
|
+
|
|
3974
|
+
\`\`\`bash
|
|
3975
|
+
one --agent connection delete <connection-key>
|
|
3976
|
+
\`\`\`
|
|
3977
|
+
|
|
3978
|
+
Removes a connection by its key. In agent mode, returns \`{"deleted": true, "platform": "...", "key": "..."}\`. The connection key comes from \`one connection list\`.
|
|
3979
|
+
|
|
3784
3980
|
### 2. Search Actions
|
|
3785
3981
|
|
|
3786
3982
|
\`\`\`bash
|
|
@@ -4119,7 +4315,7 @@ async function onboardCommand(step) {
|
|
|
4119
4315
|
let connections = [];
|
|
4120
4316
|
if (currentStep >= 2) {
|
|
4121
4317
|
try {
|
|
4122
|
-
const api = new OneApi(apiKey);
|
|
4318
|
+
const api = new OneApi(apiKey, getApiBase());
|
|
4123
4319
|
connections = await api.listConnections();
|
|
4124
4320
|
} catch {
|
|
4125
4321
|
}
|
|
@@ -4452,6 +4648,14 @@ async function updateCommand() {
|
|
|
4452
4648
|
error("Update failed \u2014 try running: npm install -g @withone/cli@latest");
|
|
4453
4649
|
}
|
|
4454
4650
|
}
|
|
4651
|
+
function isNewerVersion(latest, current) {
|
|
4652
|
+
const parse = (v) => v.split(".").map(Number);
|
|
4653
|
+
const [lMaj, lMin, lPat] = parse(latest);
|
|
4654
|
+
const [cMaj, cMin, cPat] = parse(current);
|
|
4655
|
+
if (lMaj !== cMaj) return lMaj > cMaj;
|
|
4656
|
+
if (lMin !== cMin) return lMin > cMin;
|
|
4657
|
+
return lPat > cPat;
|
|
4658
|
+
}
|
|
4455
4659
|
function autoUpdate(targetVersion, publishedAt) {
|
|
4456
4660
|
if (publishedAt) {
|
|
4457
4661
|
const age = Date.now() - new Date(publishedAt).getTime();
|
|
@@ -4474,6 +4678,7 @@ program.name("one").option("--agent", "Machine-readable JSON output (no colors,
|
|
|
4474
4678
|
Setup:
|
|
4475
4679
|
one init Set up API key and install MCP server
|
|
4476
4680
|
one add <platform> Connect a platform via OAuth (e.g. gmail, slack, shopify)
|
|
4681
|
+
one connection delete <key> Remove a connection (alias: one connection rm)
|
|
4477
4682
|
one config Configure access control (permissions, scoping)
|
|
4478
4683
|
|
|
4479
4684
|
Workflow (use these in order):
|
|
@@ -4535,7 +4740,7 @@ program.hook("postAction", async () => {
|
|
|
4535
4740
|
const info = await updateCheckPromise;
|
|
4536
4741
|
if (!info) return;
|
|
4537
4742
|
const current = getCurrentVersion();
|
|
4538
|
-
if (
|
|
4743
|
+
if (!isNewerVersion(info.version, current)) return;
|
|
4539
4744
|
autoUpdate(info.version, info.publishedAt);
|
|
4540
4745
|
});
|
|
4541
4746
|
program.command("init").description("Set up One and install MCP to your AI agents").option("-y, --yes", "Skip confirmations").option("-g, --global", "Install MCP globally (available in all projects)").option("-p, --project", "Install MCP for this project only (creates .mcp.json)").action(async (options) => {
|
|
@@ -4551,6 +4756,9 @@ connection.command("add [platform]").alias("a").description("Add a new connectio
|
|
|
4551
4756
|
connection.command("list").alias("ls").description("List your connections").option("-s, --search <query>", "Filter connections by platform name").option("-l, --limit <n>", "Max connections to return (agent mode default: 20)").action(async (options) => {
|
|
4552
4757
|
await connectionListCommand(options);
|
|
4553
4758
|
});
|
|
4759
|
+
connection.command("delete <connection-key>").alias("rm").description("Delete a connection").option("-f, --force", "Skip confirmation prompt").action(async (connectionKey, options) => {
|
|
4760
|
+
await connectionDeleteCommand(connectionKey, options);
|
|
4761
|
+
});
|
|
4554
4762
|
program.command("platforms").alias("p").description("List available platforms").option("-c, --category <category>", "Filter by category").option("--json", "Output as JSON").action(async (options) => {
|
|
4555
4763
|
await platformsCommand(options);
|
|
4556
4764
|
});
|
package/package.json
CHANGED
package/skills/one/SKILL.md
CHANGED
|
@@ -34,6 +34,14 @@ one --agent connection list
|
|
|
34
34
|
|
|
35
35
|
Returns connected platforms with their connection keys (needed for execution) and platform names in kebab-case (needed for searching).
|
|
36
36
|
|
|
37
|
+
### 1b. Delete a connection
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
one --agent connection delete <connection-key>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Removes a connection. Returns `{"deleted": true, "platform": "...", "key": "..."}` on success. Use the connection key from `one --agent connection list`.
|
|
44
|
+
|
|
37
45
|
### 2. Search for the right action
|
|
38
46
|
|
|
39
47
|
```bash
|
|
@@ -126,3 +134,11 @@ If the user needs a platform that isn't connected yet, tell them to run:
|
|
|
126
134
|
one add <platform>
|
|
127
135
|
```
|
|
128
136
|
This is interactive and opens the browser for OAuth. After connecting, the platform will appear in `one --agent connection list`.
|
|
137
|
+
|
|
138
|
+
## Removing Connections
|
|
139
|
+
|
|
140
|
+
To delete a connection that is no longer needed:
|
|
141
|
+
```bash
|
|
142
|
+
one --agent connection delete <connection-key>
|
|
143
|
+
```
|
|
144
|
+
The connection key comes from `one --agent connection list`. Returns `{"deleted": true, "platform": "...", "key": "..."}` on success.
|