@overaihq/cli 0.14.0 → 0.14.2
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 +20 -0
- package/dist/index.js +147 -10
- package/dist/{types-3BS55ING.js → types-7JF7GZMJ.js} +0 -29
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -85,6 +85,26 @@ at once without changing anything shared. Inside a clone, commands use its
|
|
|
85
85
|
organization automatically. Precedence is `--org`, then `OVERAI_ORG_ID`, then the
|
|
86
86
|
clone, then the saved default.
|
|
87
87
|
|
|
88
|
+
If you belong to many organizations, name one every time. The saved default is
|
|
89
|
+
machine-global, so it is whichever organization some other shell, editor, or
|
|
90
|
+
agent last switched to — and a command that falls back to it reads the wrong
|
|
91
|
+
tenant rather than failing. Give the orgs you work in aliases and pass `--org`:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
overai org alias acme fcps:org_abc # once
|
|
95
|
+
overai org alias # what you have named
|
|
96
|
+
overai --org acme push # every time
|
|
97
|
+
export OVERAI_REQUIRE_EXPLICIT_ORG=1 # make forgetting an error
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`OVERAI_REQUIRE_EXPLICIT_ORG=1` refuses to run any command that acts on an
|
|
101
|
+
organization until one is named, whether by `--org`, `OVERAI_ORG_ID`, or the
|
|
102
|
+
clone you are standing in. That includes `clone`, which reaches into an org, and
|
|
103
|
+
bare `signout`, which revokes one — `signout <ref>` and `signout --all` are
|
|
104
|
+
explicit already. `signin`, `whoami`, `org`, `remote`, `best-practices`, `help`,
|
|
105
|
+
`version`, and `update` stay available: the first four are how you find the org
|
|
106
|
+
to name, and the rest touch none.
|
|
107
|
+
|
|
88
108
|
Missing org sessions are established from an eligible saved CLI login. SSO requires
|
|
89
109
|
browser authorization, and the prompt names the exact command to run. Ordinary
|
|
90
110
|
commands never launch a browser. `whoami` shows the remote, org, identity, session
|
package/dist/index.js
CHANGED
|
@@ -26665,6 +26665,7 @@ var leadingFlag = (name2) => {
|
|
|
26665
26665
|
return void 0;
|
|
26666
26666
|
};
|
|
26667
26667
|
var LEADING_FLAGS = ["--org"];
|
|
26668
|
+
var requireExplicitOrg = process.env.OVERAI_REQUIRE_EXPLICIT_ORG === "1";
|
|
26668
26669
|
var orgRefOverride = leadingFlag("--org") ?? (process.env.OVERAI_ORG_ID != null && process.env.OVERAI_ORG_ID !== "" ? process.env.OVERAI_ORG_ID : void 0);
|
|
26669
26670
|
var orgRefSource = leadingFlag("--org") != null ? "--org" : orgRefOverride != null ? "OVERAI_ORG_ID" : void 0;
|
|
26670
26671
|
var appBaseUrl = (backend) => {
|
|
@@ -26918,11 +26919,12 @@ var scopedOrgId = () => {
|
|
|
26918
26919
|
return null;
|
|
26919
26920
|
}
|
|
26920
26921
|
};
|
|
26922
|
+
var orgScopeSource = () => orgOverride()?.source ?? (orgScopeOverride != null ? ".overai/manifest.json" : "saved default");
|
|
26921
26923
|
var announceOrgScope = () => {
|
|
26922
26924
|
const org = scopedOrgId();
|
|
26923
26925
|
if (org == null) return;
|
|
26924
26926
|
process.stderr.write(
|
|
26925
|
-
`Using org ${org} on ${remoteName(apiBaseUrl())} (${
|
|
26927
|
+
`Using org ${org} on ${remoteName(apiBaseUrl())} (${orgScopeSource()}).
|
|
26926
26928
|
`
|
|
26927
26929
|
);
|
|
26928
26930
|
};
|
|
@@ -27131,7 +27133,7 @@ var v2Error = (label, res, rawBody) => {
|
|
|
27131
27133
|
const claimed = (typeof field === "string" ? field : rawBody).trim().slice(0, 500);
|
|
27132
27134
|
const reason = claimed.length === 0 || claimed === "Error" || claimed === "null" || claimed === "undefined" || claimed.toLowerCase() === STATUS_TEXT[res.status]?.toLowerCase() ? null : claimed;
|
|
27133
27135
|
const orgHint = res.status === 404 || res.status === 403 ? `
|
|
27134
|
-
If it lives in another org,
|
|
27136
|
+
If it lives in another org, name that org: overai --org <ref> ... (\`overai org list\` shows them, \`overai org alias\` your shorthands).` : "";
|
|
27135
27137
|
if (reason != null) return new Error(`${reason}${orgHint}`);
|
|
27136
27138
|
const path = (() => {
|
|
27137
27139
|
try {
|
|
@@ -27571,6 +27573,10 @@ var signOut = async (all = false, target) => {
|
|
|
27571
27573
|
setOrgScope(manifest.organizationId);
|
|
27572
27574
|
}
|
|
27573
27575
|
}
|
|
27576
|
+
if (requireExplicitOrg && !all && orgScopeSource() === "saved default")
|
|
27577
|
+
throw new Error(
|
|
27578
|
+
"OVERAI_REQUIRE_EXPLICIT_ORG is set and nothing named an org to sign out of. Name one: overai signout <ref>, or revoke every saved session with: overai signout --all"
|
|
27579
|
+
);
|
|
27574
27580
|
const baseUrl = apiBaseUrl();
|
|
27575
27581
|
const orgId = scopedOrgId();
|
|
27576
27582
|
await withStoreLock(async (store) => {
|
|
@@ -27808,7 +27814,7 @@ var runAutomation = async (args) => {
|
|
|
27808
27814
|
// src/workspace/validateElements.ts
|
|
27809
27815
|
var findings = (parsed) => parsed.success ? [] : parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
27810
27816
|
var validateAutomationElements = async (elements) => {
|
|
27811
|
-
const { automationNodesSchema } = await import("./types-
|
|
27817
|
+
const { automationNodesSchema } = await import("./types-7JF7GZMJ.js");
|
|
27812
27818
|
return findings(automationNodesSchema.safeParse(elements));
|
|
27813
27819
|
};
|
|
27814
27820
|
var validateWebPageConfig = async (config) => {
|
|
@@ -35348,6 +35354,7 @@ var generateRandomVariableName = customAlphabet(
|
|
|
35348
35354
|
|
|
35349
35355
|
// ../common/src/ids.ts
|
|
35350
35356
|
var ID_PREFIXES = {
|
|
35357
|
+
action: { prefix: "act", body: 20 },
|
|
35351
35358
|
action_runner: { prefix: "ar", body: 10 },
|
|
35352
35359
|
action_runner_email_alert: { prefix: "area", body: 10 },
|
|
35353
35360
|
action_runner_email_subscription: { prefix: "ares", body: 10 },
|
|
@@ -36589,7 +36596,11 @@ Organization context: Commands in a clone select its org automatically. Outside
|
|
|
36589
36596
|
put --org <ref> before the command (overai --org acme sql ...), or set OVERAI_ORG_ID for a
|
|
36590
36597
|
whole shell. A ref is an org id, a local alias, or <remote>:<orgId>, and a named org
|
|
36591
36598
|
selects its own deployment \u2014 never switch the machine-global default to reach another org,
|
|
36592
|
-
because every other session on the machine shares it.
|
|
36599
|
+
because every other session on the machine shares it. Prefer naming the org on every
|
|
36600
|
+
command rather than relying on the saved default: the default is whatever another session
|
|
36601
|
+
last switched to, so falling back to it reads the wrong tenant instead of failing.
|
|
36602
|
+
OVERAI_REQUIRE_EXPLICIT_ORG=1 turns that fallback into an error for every command
|
|
36603
|
+
that acts on an org. Each remote/org has an independent
|
|
36593
36604
|
saved session. Use whoami to inspect the effective scope. If browser authorization is
|
|
36594
36605
|
required, ask the user to run the suggested signin command. Never change org to work
|
|
36595
36606
|
around a clone-sync mismatch; use the correct workspace folder.
|
|
@@ -37343,6 +37354,102 @@ var runSql = async (args) => {
|
|
|
37343
37354
|
}
|
|
37344
37355
|
};
|
|
37345
37356
|
|
|
37357
|
+
// src/commands/storage.ts
|
|
37358
|
+
import { openAsBlob, writeFileSync as writeFileSync6 } from "fs";
|
|
37359
|
+
var USAGE3 = "Usage: overai storage upload <path> [--no-random-prefix] | storage download <key> [path|-] | storage exists <key> | storage head <key> [--lines N] | storage presign <key> [--expires-in <seconds>]";
|
|
37360
|
+
var runStorage = async (args) => {
|
|
37361
|
+
const [operation, first2, second] = args;
|
|
37362
|
+
if (operation == null) throw new Error(USAGE3);
|
|
37363
|
+
const { organizationId } = await getAccessToken();
|
|
37364
|
+
const segment = (key) => encodeURIComponent(key);
|
|
37365
|
+
if (operation === "upload") {
|
|
37366
|
+
if (first2 == null || first2 === "-") {
|
|
37367
|
+
throw new Error("Upload requires a file path (stdin uploads need a filename to build the key).");
|
|
37368
|
+
}
|
|
37369
|
+
const randomPrefix = !args.includes("--no-random-prefix");
|
|
37370
|
+
const query = randomPrefix ? "" : "?disableRandomPrefix=true";
|
|
37371
|
+
const response = await v2Fetch(
|
|
37372
|
+
`/v2/storage/${organizationId}/stream${query}`,
|
|
37373
|
+
{
|
|
37374
|
+
method: "POST",
|
|
37375
|
+
headers: {
|
|
37376
|
+
"Content-Type": "application/octet-stream",
|
|
37377
|
+
"x-file-name": first2.split("/").pop() ?? first2
|
|
37378
|
+
},
|
|
37379
|
+
body: await openAsBlob(first2)
|
|
37380
|
+
}
|
|
37381
|
+
);
|
|
37382
|
+
if (!response.ok) {
|
|
37383
|
+
throw v2Error("storage upload", response, await response.text());
|
|
37384
|
+
}
|
|
37385
|
+
const { path } = await response.json();
|
|
37386
|
+
const key = path.startsWith(`${organizationId}/`) ? path.slice(organizationId.length + 1) : path;
|
|
37387
|
+
const format2 = resolveFormat(flagValue(args, "-o", "--output"));
|
|
37388
|
+
if (format2 === "json") printResult({ key, path }, format2);
|
|
37389
|
+
else process.stdout.write(`${key}
|
|
37390
|
+
`);
|
|
37391
|
+
return;
|
|
37392
|
+
}
|
|
37393
|
+
if (first2 == null) throw new Error(USAGE3);
|
|
37394
|
+
if (operation === "download") {
|
|
37395
|
+
const response = await v2Fetch(
|
|
37396
|
+
`/v2/storage/${organizationId}/${segment(first2)}`,
|
|
37397
|
+
{ redirect: "follow" }
|
|
37398
|
+
);
|
|
37399
|
+
if (!response.ok) {
|
|
37400
|
+
throw v2Error("storage download", response, await response.text());
|
|
37401
|
+
}
|
|
37402
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
37403
|
+
if (second != null && second !== "-") writeFileSync6(second, bytes);
|
|
37404
|
+
else process.stdout.write(bytes);
|
|
37405
|
+
return;
|
|
37406
|
+
}
|
|
37407
|
+
if (operation === "exists") {
|
|
37408
|
+
const response = await v2Fetch(
|
|
37409
|
+
`/v2/storage/${organizationId}/${segment(first2)}/exists`
|
|
37410
|
+
);
|
|
37411
|
+
if (response.status === 404) {
|
|
37412
|
+
if (resolveFormat(flagValue(args, "-o", "--output")) === "json") {
|
|
37413
|
+
printResult({ exists: false }, "json");
|
|
37414
|
+
}
|
|
37415
|
+
process.exitCode = 1;
|
|
37416
|
+
return;
|
|
37417
|
+
}
|
|
37418
|
+
if (!response.ok) {
|
|
37419
|
+
throw v2Error("storage exists", response, await response.text());
|
|
37420
|
+
}
|
|
37421
|
+
printResult(
|
|
37422
|
+
{ exists: true, ...await response.json() },
|
|
37423
|
+
resolveFormat(flagValue(args, "-o", "--output"))
|
|
37424
|
+
);
|
|
37425
|
+
return;
|
|
37426
|
+
}
|
|
37427
|
+
if (operation === "head") {
|
|
37428
|
+
const lines = flagValue(args, "--lines") ?? "50";
|
|
37429
|
+
const response = await v2Fetch(
|
|
37430
|
+
`/v2/storage/${organizationId}/${segment(first2)}/head?numLines=${encodeURIComponent(lines)}`
|
|
37431
|
+
);
|
|
37432
|
+
if (!response.ok) {
|
|
37433
|
+
throw v2Error("storage head", response, await response.text());
|
|
37434
|
+
}
|
|
37435
|
+
process.stdout.write(await response.text());
|
|
37436
|
+
return;
|
|
37437
|
+
}
|
|
37438
|
+
if (operation === "presign") {
|
|
37439
|
+
const expiresIn2 = flagValue(args, "--expires-in") ?? String(60 * 60 * 24 * 7);
|
|
37440
|
+
const response = await v2Fetch(
|
|
37441
|
+
`/v2/storage/${organizationId}/${segment(first2)}/presign?expiresIn=${encodeURIComponent(expiresIn2)}`
|
|
37442
|
+
);
|
|
37443
|
+
if (!response.ok) {
|
|
37444
|
+
throw v2Error("storage presign", response, await response.text());
|
|
37445
|
+
}
|
|
37446
|
+
process.stdout.write(`${(await response.text()).trim()}
|
|
37447
|
+
`);
|
|
37448
|
+
return;
|
|
37449
|
+
}
|
|
37450
|
+
throw new Error(USAGE3);
|
|
37451
|
+
};
|
|
37452
|
+
|
|
37346
37453
|
// src/commands/workspace.ts
|
|
37347
37454
|
var workspaceIdFrom = (args) => args.find(
|
|
37348
37455
|
(arg, index) => !arg.startsWith("-") && args[index - 1] !== "-o" && args[index - 1] !== "--output"
|
|
@@ -37426,7 +37533,7 @@ var listWorkspaceUsers = async (args) => {
|
|
|
37426
37533
|
resolveFormat(flagValue(args, "-o", "--output"))
|
|
37427
37534
|
);
|
|
37428
37535
|
};
|
|
37429
|
-
var
|
|
37536
|
+
var USAGE4 = `Usage:
|
|
37430
37537
|
overai workspace list [--archived] [--limit <n>]
|
|
37431
37538
|
overai workspace show [workspaceId]
|
|
37432
37539
|
overai workspace users [workspaceId]
|
|
@@ -37444,7 +37551,7 @@ var runWorkspace = async (args) => {
|
|
|
37444
37551
|
await listWorkspaceUsers(args.slice(1));
|
|
37445
37552
|
return;
|
|
37446
37553
|
}
|
|
37447
|
-
process.stderr.write(
|
|
37554
|
+
process.stderr.write(USAGE4);
|
|
37448
37555
|
process.exitCode = 1;
|
|
37449
37556
|
};
|
|
37450
37557
|
|
|
@@ -37606,6 +37713,9 @@ Other resources:
|
|
|
37606
37713
|
overai data-stream query <id> --start <date> --end <date> [--query <filter>]
|
|
37607
37714
|
overai data-file upload <id> <path> [-m <message>]
|
|
37608
37715
|
overai data-file download <id> [path|-] | data-file head <id>
|
|
37716
|
+
overai storage upload <path> [--no-random-prefix]
|
|
37717
|
+
overai storage download <key> [path|-] | storage exists <key>
|
|
37718
|
+
overai storage head <key> [--lines N] | storage presign <key> [--expires-in <seconds>]
|
|
37609
37719
|
overai knowledge-base upload <id> <file...>
|
|
37610
37720
|
overai knowledge-base search <id> <query> [--limit N]
|
|
37611
37721
|
overai integration configure <id> --config <json|@file|@->
|
|
@@ -37644,6 +37754,9 @@ Output: table on a TTY, JSON when piped; -o json|table|csv to force.
|
|
|
37644
37754
|
Aliases: login = signin, logout = signout, ws = workspace.
|
|
37645
37755
|
Env: OVERAI_API_URL, OVERAI_APP_URL override the target deployment.
|
|
37646
37756
|
OVERAI_ORG_ID overrides the organization for this shell.
|
|
37757
|
+
OVERAI_REQUIRE_EXPLICIT_ORG=1 refuses to fall back to the saved default
|
|
37758
|
+
org, so every command that acts on one must name it with --org or stand in
|
|
37759
|
+
a clone.
|
|
37647
37760
|
Global flags (before the command): --org <ref>
|
|
37648
37761
|
`;
|
|
37649
37762
|
process.stdout.on("error", (error) => {
|
|
@@ -37668,6 +37781,24 @@ var ORG_AGNOSTIC_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
37668
37781
|
"--help",
|
|
37669
37782
|
"-h"
|
|
37670
37783
|
]);
|
|
37784
|
+
var ORG_OPTIONAL_COMMANDS = /* @__PURE__ */ new Set([
|
|
37785
|
+
"signin",
|
|
37786
|
+
"login",
|
|
37787
|
+
"signout",
|
|
37788
|
+
"logout",
|
|
37789
|
+
"whoami",
|
|
37790
|
+
"org",
|
|
37791
|
+
"remote",
|
|
37792
|
+
"best-practices",
|
|
37793
|
+
"update",
|
|
37794
|
+
"upgrade",
|
|
37795
|
+
"version",
|
|
37796
|
+
"--version",
|
|
37797
|
+
"-v",
|
|
37798
|
+
"help",
|
|
37799
|
+
"--help",
|
|
37800
|
+
"-h"
|
|
37801
|
+
]);
|
|
37671
37802
|
var SKIP_UPDATE_CHECK = /* @__PURE__ */ new Set([
|
|
37672
37803
|
void 0,
|
|
37673
37804
|
"update",
|
|
@@ -37696,10 +37827,13 @@ var run = async () => {
|
|
|
37696
37827
|
throw new Error(
|
|
37697
37828
|
`${misplaced} goes before the command: overai ${misplaced} <ref> ${command2 ?? "<command>"} ...`
|
|
37698
37829
|
);
|
|
37699
|
-
|
|
37700
|
-
|
|
37701
|
-
|
|
37702
|
-
|
|
37830
|
+
const orgFromFolder = command2 != null && !ORG_AGNOSTIC_COMMANDS.has(command2);
|
|
37831
|
+
if (orgFromFolder) pinOrgFromClone();
|
|
37832
|
+
if (requireExplicitOrg && command2 != null && !ORG_OPTIONAL_COMMANDS.has(command2) && orgScopeSource() === "saved default")
|
|
37833
|
+
throw new Error(
|
|
37834
|
+
`OVERAI_REQUIRE_EXPLICIT_ORG is set and nothing named an org for "${command2}". Put --org <ref> before the command, or run it inside a clone. See your shorthands with: overai org alias`
|
|
37835
|
+
);
|
|
37836
|
+
if (orgFromFolder) announceOrgScope();
|
|
37703
37837
|
if (rest.includes("--recursive")) {
|
|
37704
37838
|
if (command2 !== "status" && command2 !== "diff" && command2 !== "pull" && command2 !== "push")
|
|
37705
37839
|
throw new Error(
|
|
@@ -37827,6 +37961,9 @@ var run = async () => {
|
|
|
37827
37961
|
case "data-file":
|
|
37828
37962
|
await runDataFile(rest);
|
|
37829
37963
|
return;
|
|
37964
|
+
case "storage":
|
|
37965
|
+
await runStorage(rest);
|
|
37966
|
+
return;
|
|
37830
37967
|
case "integration":
|
|
37831
37968
|
await runIntegration(rest);
|
|
37832
37969
|
return;
|
|
@@ -643,31 +643,6 @@ var automationStateSchema = external_exports.record(
|
|
|
643
643
|
external_exports.string(),
|
|
644
644
|
automationNodeStateSchema
|
|
645
645
|
);
|
|
646
|
-
var automationNodePathSchema = external_exports.tuple([
|
|
647
|
-
external_exports.array(
|
|
648
|
-
external_exports.tuple([
|
|
649
|
-
external_exports.string().describe("The variableId of the loop node"),
|
|
650
|
-
external_exports.number().min(0).describe("The iteration number of the loop node")
|
|
651
|
-
])
|
|
652
|
-
).describe(
|
|
653
|
-
"An array of loop variableIds and iterations, ordered from outermost to innermost"
|
|
654
|
-
),
|
|
655
|
-
external_exports.string().describe(
|
|
656
|
-
"The variableId of the terminal (innermost) node in the automation"
|
|
657
|
-
)
|
|
658
|
-
]);
|
|
659
|
-
var emptyAutomationNodePath = [[], ""];
|
|
660
|
-
var addAutomationNodePathLoop = (currentPath, iteration) => {
|
|
661
|
-
const result = [
|
|
662
|
-
[...currentPath[0], [currentPath[1], iteration]],
|
|
663
|
-
""
|
|
664
|
-
];
|
|
665
|
-
return result;
|
|
666
|
-
};
|
|
667
|
-
var setAutomationNodePathTerminal = (currentPath, node) => {
|
|
668
|
-
const result = [[...currentPath[0]], node];
|
|
669
|
-
return result;
|
|
670
|
-
};
|
|
671
646
|
var runStepPayloadSchema = external_exports.object({
|
|
672
647
|
runId: external_exports.string(),
|
|
673
648
|
automationId: external_exports.string(),
|
|
@@ -679,16 +654,13 @@ export {
|
|
|
679
654
|
MacAddressComparatorOptions,
|
|
680
655
|
NodeEnum,
|
|
681
656
|
ServiceEnum,
|
|
682
|
-
addAutomationNodePathLoop,
|
|
683
657
|
automationFileTypesSchema,
|
|
684
|
-
automationNodePathSchema,
|
|
685
658
|
automationNodeSchema,
|
|
686
659
|
automationNodeStateSchema,
|
|
687
660
|
automationNodesSchema,
|
|
688
661
|
automationStateSchema,
|
|
689
662
|
conditionalNodeTypeIds,
|
|
690
663
|
doesNodeRequireExecutionContext,
|
|
691
|
-
emptyAutomationNodePath,
|
|
692
664
|
httpMethodSchema,
|
|
693
665
|
integrationHttpActionEditableSchema,
|
|
694
666
|
integrationHttpActionOutputs,
|
|
@@ -701,7 +673,6 @@ export {
|
|
|
701
673
|
jsonStringSchema,
|
|
702
674
|
monthsSchema,
|
|
703
675
|
runStepPayloadSchema,
|
|
704
|
-
setAutomationNodePathTerminal,
|
|
705
676
|
timeZoneOffset,
|
|
706
677
|
timeZonesSchema,
|
|
707
678
|
transformationSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@overaihq/cli",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Create, edit, deploy, and run OverAI workspace resources from the command line",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://overai.com",
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@perygee/common": "0.0.0",
|
|
24
|
-
"@types/node": "^24.13.
|
|
24
|
+
"@types/node": "^24.13.5",
|
|
25
25
|
"@types/proper-lockfile": "^4.1.4",
|
|
26
26
|
"tsup": "^8.5.1",
|
|
27
27
|
"typescript": "^7.0.2",
|
|
28
28
|
"vitest": "^4.1.11",
|
|
29
|
-
"zod": "^4.5
|
|
29
|
+
"zod": "^4.6.5"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"proper-lockfile": "^4.1.2"
|