@overaihq/cli 0.7.0 → 0.8.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.
|
@@ -362,6 +362,14 @@ var consoleLogsPayloadSchema = external_exports.object({
|
|
|
362
362
|
var runtimeErrorPayloadSchema = external_exports.object({
|
|
363
363
|
error: external_exports.string().nullable()
|
|
364
364
|
});
|
|
365
|
+
var pageInteractionPayloadSchema = external_exports.object({
|
|
366
|
+
clicks: external_exports.number().int().min(0),
|
|
367
|
+
keypresses: external_exports.number().int().min(0)
|
|
368
|
+
});
|
|
369
|
+
var pageErrorPayloadSchema = external_exports.object({
|
|
370
|
+
message: external_exports.string(),
|
|
371
|
+
stack: external_exports.string().optional()
|
|
372
|
+
});
|
|
365
373
|
|
|
366
374
|
// ../common/src/webPage.ts
|
|
367
375
|
var webPageLanguage = ["react"];
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
itemFilterExpressionRootSchema,
|
|
7
7
|
webPageConfigSchema
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2F4ZHHFG.js";
|
|
9
9
|
import {
|
|
10
10
|
external_exports
|
|
11
11
|
} from "./chunk-6YTIPJTD.js";
|
|
@@ -26360,11 +26360,6 @@ var require_lib2 = __commonJS({
|
|
|
26360
26360
|
}
|
|
26361
26361
|
});
|
|
26362
26362
|
|
|
26363
|
-
// src/auth.ts
|
|
26364
|
-
import { randomBytes as randomBytes2 } from "crypto";
|
|
26365
|
-
import { createServer } from "http";
|
|
26366
|
-
import { hostname } from "os";
|
|
26367
|
-
|
|
26368
26363
|
// src/config.ts
|
|
26369
26364
|
import {
|
|
26370
26365
|
chmodSync,
|
|
@@ -26401,6 +26396,7 @@ var clearConfig = () => {
|
|
|
26401
26396
|
var trimSlash = (url) => url.replace(/\/+$/, "");
|
|
26402
26397
|
var DEFAULT_API_BASE_URL = "https://api.overai.com";
|
|
26403
26398
|
var apiBaseUrlOverride = process.env.OVERAI_API_URL != null ? trimSlash(process.env.OVERAI_API_URL) : void 0;
|
|
26399
|
+
var orgIdOverride = process.env.OVERAI_ORG_ID != null && process.env.OVERAI_ORG_ID !== "" ? process.env.OVERAI_ORG_ID : void 0;
|
|
26404
26400
|
var appBaseUrl = trimSlash(
|
|
26405
26401
|
process.env.OVERAI_APP_URL ?? "https://app.overai.com"
|
|
26406
26402
|
);
|
|
@@ -26449,6 +26445,21 @@ var orgScopeOverride = null;
|
|
|
26449
26445
|
var setOrgScope = (organizationId) => {
|
|
26450
26446
|
orgScopeOverride = organizationId;
|
|
26451
26447
|
};
|
|
26448
|
+
var resolveOrgId = (config) => orgIdOverride ?? orgScopeOverride ?? config.organizationId;
|
|
26449
|
+
var scopedOrgId = () => {
|
|
26450
|
+
const config = readConfig();
|
|
26451
|
+
return config == null ? null : resolveOrgId(config);
|
|
26452
|
+
};
|
|
26453
|
+
var announceOrgScope = () => {
|
|
26454
|
+
const config = readConfig();
|
|
26455
|
+
if (config == null) return;
|
|
26456
|
+
const targetOrgId = resolveOrgId(config);
|
|
26457
|
+
if (targetOrgId === config.organizationId) return;
|
|
26458
|
+
process.stderr.write(
|
|
26459
|
+
`Using org ${targetOrgId} (${orgIdOverride != null ? "OVERAI_ORG_ID" : ".overai/manifest.json"}); the active org is ${config.organizationId}.
|
|
26460
|
+
`
|
|
26461
|
+
);
|
|
26462
|
+
};
|
|
26452
26463
|
var inFlightExchange = null;
|
|
26453
26464
|
var processToken = null;
|
|
26454
26465
|
var getAccessToken = async () => {
|
|
@@ -26456,7 +26467,7 @@ var getAccessToken = async () => {
|
|
|
26456
26467
|
if (config == null) {
|
|
26457
26468
|
throw new Error("Not signed in. Run `overai signin`.");
|
|
26458
26469
|
}
|
|
26459
|
-
const targetOrgId =
|
|
26470
|
+
const targetOrgId = resolveOrgId(config);
|
|
26460
26471
|
const skewMs = 6e4;
|
|
26461
26472
|
if (targetOrgId === config.organizationId && config.accessToken != null && config.accessTokenExpiresAt != null && config.accessTokenExpiresAt - skewMs > Date.now()) {
|
|
26462
26473
|
return { token: config.accessToken, organizationId: config.organizationId };
|
|
@@ -26498,6 +26509,45 @@ var v2Fetch = async (path, init) => {
|
|
|
26498
26509
|
headers.set("Authorization", `Bearer ${auth.token}`);
|
|
26499
26510
|
return fetch(`${apiBaseUrl()}${path}`, { ...init, headers });
|
|
26500
26511
|
};
|
|
26512
|
+
var STATUS_TEXT = {
|
|
26513
|
+
400: "Bad Request",
|
|
26514
|
+
401: "Unauthorized",
|
|
26515
|
+
403: "Forbidden",
|
|
26516
|
+
404: "Not Found",
|
|
26517
|
+
409: "Conflict",
|
|
26518
|
+
413: "Payload Too Large",
|
|
26519
|
+
429: "Too Many Requests",
|
|
26520
|
+
500: "Internal Server Error",
|
|
26521
|
+
503: "Service Unavailable"
|
|
26522
|
+
};
|
|
26523
|
+
var v2Error = (label, res, rawBody) => {
|
|
26524
|
+
const structured = (() => {
|
|
26525
|
+
try {
|
|
26526
|
+
return JSON.parse(rawBody);
|
|
26527
|
+
} catch {
|
|
26528
|
+
return null;
|
|
26529
|
+
}
|
|
26530
|
+
})();
|
|
26531
|
+
const field = structured?.error ?? structured?.message;
|
|
26532
|
+
const claimed = (typeof field === "string" ? field : rawBody).trim().slice(0, 500);
|
|
26533
|
+
const reason = claimed.length === 0 || claimed === "Error" || claimed === "null" || claimed === "undefined" || claimed.toLowerCase() === STATUS_TEXT[res.status]?.toLowerCase() ? null : claimed;
|
|
26534
|
+
const orgHint = res.status === 404 || res.status === 403 ? `
|
|
26535
|
+
If it lives in another org, prefix the command with OVERAI_ORG_ID=<orgId> (\`overai org list\` shows them).` : "";
|
|
26536
|
+
if (reason != null) return new Error(`${reason}${orgHint}`);
|
|
26537
|
+
const path = (() => {
|
|
26538
|
+
try {
|
|
26539
|
+
return new URL(res.url).pathname;
|
|
26540
|
+
} catch {
|
|
26541
|
+
return "";
|
|
26542
|
+
}
|
|
26543
|
+
})();
|
|
26544
|
+
const org = scopedOrgId();
|
|
26545
|
+
return new Error(
|
|
26546
|
+
`${label}: HTTP ${String(res.status)}, no reason given by the server.${path === "" ? "" : `
|
|
26547
|
+
${path}`}${org == null ? "" : `
|
|
26548
|
+
Asked as org ${org}.`}${orgHint}`
|
|
26549
|
+
);
|
|
26550
|
+
};
|
|
26501
26551
|
var userTrpcMutation = async (procedure, input) => {
|
|
26502
26552
|
const res = await v2Fetch(`/v1/utils/trpc/${procedure}`, {
|
|
26503
26553
|
method: "POST",
|
|
@@ -26507,6 +26557,11 @@ var userTrpcMutation = async (procedure, input) => {
|
|
|
26507
26557
|
return trpcResult(res, procedure);
|
|
26508
26558
|
};
|
|
26509
26559
|
|
|
26560
|
+
// src/auth.ts
|
|
26561
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
26562
|
+
import { createServer } from "http";
|
|
26563
|
+
import { hostname } from "os";
|
|
26564
|
+
|
|
26510
26565
|
// src/browser.ts
|
|
26511
26566
|
import { spawn } from "child_process";
|
|
26512
26567
|
import { platform } from "os";
|
|
@@ -26521,6 +26576,175 @@ var openBrowser = (url) => {
|
|
|
26521
26576
|
}
|
|
26522
26577
|
};
|
|
26523
26578
|
|
|
26579
|
+
// src/args.ts
|
|
26580
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
26581
|
+
var flagValue = (args, ...names) => {
|
|
26582
|
+
for (const name2 of names) {
|
|
26583
|
+
const i = args.indexOf(name2);
|
|
26584
|
+
if (i !== -1 && i + 1 < args.length) return args[i + 1];
|
|
26585
|
+
}
|
|
26586
|
+
return void 0;
|
|
26587
|
+
};
|
|
26588
|
+
var stdinClaimedBy = null;
|
|
26589
|
+
var readStdin = async (claimant = "stdin") => {
|
|
26590
|
+
if (stdinClaimedBy != null) {
|
|
26591
|
+
throw new Error(
|
|
26592
|
+
`Only one value can be read from stdin; ${stdinClaimedBy} already consumed it.`
|
|
26593
|
+
);
|
|
26594
|
+
}
|
|
26595
|
+
stdinClaimedBy = claimant;
|
|
26596
|
+
const chunks = [];
|
|
26597
|
+
for await (const chunk of process.stdin) {
|
|
26598
|
+
chunks.push(chunk);
|
|
26599
|
+
}
|
|
26600
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
26601
|
+
};
|
|
26602
|
+
var readValue = async (value, label) => {
|
|
26603
|
+
if (value?.startsWith("@") !== true) return value;
|
|
26604
|
+
if (value.startsWith("@@")) return value.slice(1);
|
|
26605
|
+
const path = value.slice(1);
|
|
26606
|
+
if (path === "-") return (await readStdin(`${label} @-`)).trim();
|
|
26607
|
+
try {
|
|
26608
|
+
return readFileSync2(path, "utf8").trim();
|
|
26609
|
+
} catch {
|
|
26610
|
+
throw new Error(
|
|
26611
|
+
`${label}: could not read file "${path}". Write "@@" to send a literal value starting with "@".`
|
|
26612
|
+
);
|
|
26613
|
+
}
|
|
26614
|
+
};
|
|
26615
|
+
|
|
26616
|
+
// src/output.ts
|
|
26617
|
+
var resolveFormat = (explicit) => {
|
|
26618
|
+
if (explicit === "json" || explicit === "csv" || explicit === "table") {
|
|
26619
|
+
return explicit;
|
|
26620
|
+
}
|
|
26621
|
+
if (explicit != null) {
|
|
26622
|
+
throw new Error(
|
|
26623
|
+
`Unknown output format "${explicit}". Use json, table, or csv.`
|
|
26624
|
+
);
|
|
26625
|
+
}
|
|
26626
|
+
return process.stdout.isTTY ? "table" : "json";
|
|
26627
|
+
};
|
|
26628
|
+
var cell = (value) => {
|
|
26629
|
+
if (value == null) return "";
|
|
26630
|
+
if (typeof value === "string") return value;
|
|
26631
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
26632
|
+
return String(value);
|
|
26633
|
+
}
|
|
26634
|
+
return JSON.stringify(value);
|
|
26635
|
+
};
|
|
26636
|
+
var formatResult = (data, format2) => {
|
|
26637
|
+
if (format2 === "json" || !Array.isArray(data)) {
|
|
26638
|
+
return JSON.stringify(data, null, 2);
|
|
26639
|
+
}
|
|
26640
|
+
const records = data.map(
|
|
26641
|
+
(row) => row != null && typeof row === "object" ? row : { value: row }
|
|
26642
|
+
);
|
|
26643
|
+
if (records.length === 0) return "(no rows)";
|
|
26644
|
+
const columns = [...new Set(records.flatMap((r) => Object.keys(r)))];
|
|
26645
|
+
if (format2 === "csv") {
|
|
26646
|
+
const escape2 = (value) => {
|
|
26647
|
+
const text = cell(value);
|
|
26648
|
+
return /[",\n\r]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
|
|
26649
|
+
};
|
|
26650
|
+
return [
|
|
26651
|
+
columns.join(","),
|
|
26652
|
+
...records.map((r) => columns.map((c) => escape2(r[c])).join(","))
|
|
26653
|
+
].join("\n");
|
|
26654
|
+
}
|
|
26655
|
+
const widths = columns.map(
|
|
26656
|
+
(c) => Math.max(c.length, ...records.map((r) => cell(r[c]).length))
|
|
26657
|
+
);
|
|
26658
|
+
const line = (cells) => cells.map((text, i) => text.padEnd(widths[i] ?? 0)).join(" ");
|
|
26659
|
+
return [
|
|
26660
|
+
line(columns),
|
|
26661
|
+
line(widths.map((w) => "-".repeat(w))),
|
|
26662
|
+
...records.map((r) => line(columns.map((c) => cell(r[c]))))
|
|
26663
|
+
].join("\n");
|
|
26664
|
+
};
|
|
26665
|
+
var printResult = (data, format2) => {
|
|
26666
|
+
process.stdout.write(`${formatResult(data, format2)}
|
|
26667
|
+
`);
|
|
26668
|
+
};
|
|
26669
|
+
|
|
26670
|
+
// src/commands/org.ts
|
|
26671
|
+
var USER_ORGS_QUERY = `
|
|
26672
|
+
query UserOrganizations($identityId: String!) {
|
|
26673
|
+
identityOrganizations(
|
|
26674
|
+
where: { identityId: { _eq: $identityId }, disabled: { _eq: false } }
|
|
26675
|
+
) {
|
|
26676
|
+
organization { id name }
|
|
26677
|
+
}
|
|
26678
|
+
}
|
|
26679
|
+
`;
|
|
26680
|
+
var fetchOrgNames = async () => {
|
|
26681
|
+
const orgs = await listOrgRows();
|
|
26682
|
+
return new Map(orgs.map((org) => [org.id, org.name ?? ""]));
|
|
26683
|
+
};
|
|
26684
|
+
var listOrgRows = async () => {
|
|
26685
|
+
const auth = await getAccessToken();
|
|
26686
|
+
const identityId = decodeJwtClaims(auth.token).user_id;
|
|
26687
|
+
if (identityId == null) {
|
|
26688
|
+
throw new Error("Could not read identity from the current session.");
|
|
26689
|
+
}
|
|
26690
|
+
const res = await v2Fetch("/v1/graphql", {
|
|
26691
|
+
method: "POST",
|
|
26692
|
+
headers: { "Content-Type": "application/json" },
|
|
26693
|
+
body: JSON.stringify({ query: USER_ORGS_QUERY, variables: { identityId } })
|
|
26694
|
+
});
|
|
26695
|
+
const body = await res.json().catch(() => null);
|
|
26696
|
+
if (body?.errors != null && body.errors.length > 0) {
|
|
26697
|
+
throw new Error(body.errors.map((e) => e.message).join("; "));
|
|
26698
|
+
}
|
|
26699
|
+
if (!res.ok || body == null) {
|
|
26700
|
+
throw new Error(`org list failed (${String(res.status)})`);
|
|
26701
|
+
}
|
|
26702
|
+
return (body.data?.identityOrganizations ?? []).map((edge) => edge.organization).filter((org) => org != null);
|
|
26703
|
+
};
|
|
26704
|
+
var listOrgs = async (args) => {
|
|
26705
|
+
const active = scopedOrgId();
|
|
26706
|
+
printResult(
|
|
26707
|
+
(await listOrgRows()).map((org) => ({
|
|
26708
|
+
id: org.id,
|
|
26709
|
+
name: org.name ?? "",
|
|
26710
|
+
active: org.id === active
|
|
26711
|
+
})),
|
|
26712
|
+
resolveFormat(flagValue(args, "-o", "--output"))
|
|
26713
|
+
);
|
|
26714
|
+
};
|
|
26715
|
+
var switchOrg = async (orgId) => {
|
|
26716
|
+
const config = readConfig();
|
|
26717
|
+
if (config == null) {
|
|
26718
|
+
process.stderr.write("Not signed in. Run `overai signin`.\n");
|
|
26719
|
+
process.exitCode = 1;
|
|
26720
|
+
return;
|
|
26721
|
+
}
|
|
26722
|
+
const result = await exchangeSessionToken(config.refreshToken, orgId);
|
|
26723
|
+
if (result.type === "redirect") {
|
|
26724
|
+
process.stdout.write(
|
|
26725
|
+
`This organization requires SSO. Complete sign-in in your browser, then run \`overai signin\`.
|
|
26726
|
+
${result.redirectUrl}
|
|
26727
|
+
`
|
|
26728
|
+
);
|
|
26729
|
+
openBrowser(result.redirectUrl);
|
|
26730
|
+
process.exitCode = 1;
|
|
26731
|
+
return;
|
|
26732
|
+
}
|
|
26733
|
+
writeConfig({
|
|
26734
|
+
...config,
|
|
26735
|
+
organizationId: orgId,
|
|
26736
|
+
email: decodeJwtClaims(result.token).email ?? config.email,
|
|
26737
|
+
accessToken: result.token,
|
|
26738
|
+
accessTokenExpiresAt: Date.now() + result.accessTokenValiditySeconds * 1e3,
|
|
26739
|
+
refreshToken: result.refreshToken
|
|
26740
|
+
});
|
|
26741
|
+
process.stdout.write(
|
|
26742
|
+
`Switched to org ${orgId}.
|
|
26743
|
+
This is machine-global \u2014 every shell and editor session on this machine now uses it. Prefix a command with OVERAI_ORG_ID=<orgId> to scope just one.
|
|
26744
|
+
`
|
|
26745
|
+
);
|
|
26746
|
+
};
|
|
26747
|
+
|
|
26524
26748
|
// src/pkce.ts
|
|
26525
26749
|
import { createHash, randomBytes } from "crypto";
|
|
26526
26750
|
var createPkcePair = () => {
|
|
@@ -26529,6 +26753,87 @@ var createPkcePair = () => {
|
|
|
26529
26753
|
return { verifier, challenge };
|
|
26530
26754
|
};
|
|
26531
26755
|
|
|
26756
|
+
// src/workspace/manifest.ts
|
|
26757
|
+
import { existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
26758
|
+
import { dirname, join as join2, resolve } from "path";
|
|
26759
|
+
var MANIFEST_DIR = ".overai";
|
|
26760
|
+
var MANIFEST_FILE = "manifest.json";
|
|
26761
|
+
var BASE_DIR = "base";
|
|
26762
|
+
var findWorkspaceRoot = (from = process.cwd()) => {
|
|
26763
|
+
let dir = resolve(from);
|
|
26764
|
+
for (; ; ) {
|
|
26765
|
+
if (existsSync(join2(dir, MANIFEST_DIR, MANIFEST_FILE))) return dir;
|
|
26766
|
+
const parent = dirname(dir);
|
|
26767
|
+
if (parent === dir) {
|
|
26768
|
+
throw new Error(
|
|
26769
|
+
"Not inside a cloned workspace (no .overai/manifest.json found). Run `overai clone <workspaceId>` first."
|
|
26770
|
+
);
|
|
26771
|
+
}
|
|
26772
|
+
dir = parent;
|
|
26773
|
+
}
|
|
26774
|
+
};
|
|
26775
|
+
var readManifest = (root) => JSON.parse(
|
|
26776
|
+
readFileSync3(join2(root, MANIFEST_DIR, MANIFEST_FILE), "utf8")
|
|
26777
|
+
);
|
|
26778
|
+
var openClone = () => {
|
|
26779
|
+
const root = findWorkspaceRoot();
|
|
26780
|
+
const manifest = readManifest(root);
|
|
26781
|
+
setOrgScope(manifest.organizationId);
|
|
26782
|
+
return { root, manifest };
|
|
26783
|
+
};
|
|
26784
|
+
var pinOrgFromClone = () => {
|
|
26785
|
+
try {
|
|
26786
|
+
setOrgScope(readManifest(findWorkspaceRoot()).organizationId);
|
|
26787
|
+
} catch {
|
|
26788
|
+
}
|
|
26789
|
+
};
|
|
26790
|
+
var writeManifest = (root, manifest) => {
|
|
26791
|
+
mkdirSync2(join2(root, MANIFEST_DIR), { recursive: true });
|
|
26792
|
+
writeFileSync2(
|
|
26793
|
+
join2(root, MANIFEST_DIR, MANIFEST_FILE),
|
|
26794
|
+
`${JSON.stringify(manifest, null, 2)}
|
|
26795
|
+
`
|
|
26796
|
+
);
|
|
26797
|
+
};
|
|
26798
|
+
var basePath = (root, relPath) => join2(root, MANIFEST_DIR, BASE_DIR, relPath);
|
|
26799
|
+
var writeSynced = (root, relPath, content) => {
|
|
26800
|
+
for (const abs2 of [join2(root, relPath), basePath(root, relPath)]) {
|
|
26801
|
+
mkdirSync2(dirname(abs2), { recursive: true });
|
|
26802
|
+
writeFileSync2(abs2, content);
|
|
26803
|
+
}
|
|
26804
|
+
};
|
|
26805
|
+
var readWorkingFile = (root, relPath) => {
|
|
26806
|
+
try {
|
|
26807
|
+
return readFileSync3(join2(root, relPath), "utf8");
|
|
26808
|
+
} catch {
|
|
26809
|
+
return null;
|
|
26810
|
+
}
|
|
26811
|
+
};
|
|
26812
|
+
var readBaseFile = (root, relPath) => {
|
|
26813
|
+
try {
|
|
26814
|
+
return readFileSync3(basePath(root, relPath), "utf8");
|
|
26815
|
+
} catch {
|
|
26816
|
+
return null;
|
|
26817
|
+
}
|
|
26818
|
+
};
|
|
26819
|
+
var slugify = (name2) => name2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60) || "untitled";
|
|
26820
|
+
var localState = (root, resource) => {
|
|
26821
|
+
const changedFiles = [];
|
|
26822
|
+
let missing = false;
|
|
26823
|
+
for (const relPath of resource.files) {
|
|
26824
|
+
const working = readWorkingFile(root, relPath);
|
|
26825
|
+
if (working == null) {
|
|
26826
|
+
missing = true;
|
|
26827
|
+
continue;
|
|
26828
|
+
}
|
|
26829
|
+
if (working !== readBaseFile(root, relPath)) changedFiles.push(relPath);
|
|
26830
|
+
}
|
|
26831
|
+
return {
|
|
26832
|
+
state: missing ? "missing" : changedFiles.length > 0 ? "modified" : "unchanged",
|
|
26833
|
+
changedFiles
|
|
26834
|
+
};
|
|
26835
|
+
};
|
|
26836
|
+
|
|
26532
26837
|
// src/auth.ts
|
|
26533
26838
|
var CALLBACK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
26534
26839
|
var startCallbackServer = (expectedState) => {
|
|
@@ -26640,108 +26945,33 @@ var signOut = async () => {
|
|
|
26640
26945
|
clearConfig();
|
|
26641
26946
|
process.stdout.write("Signed out.\n");
|
|
26642
26947
|
};
|
|
26643
|
-
var whoami = () => {
|
|
26948
|
+
var whoami = async () => {
|
|
26644
26949
|
const config = readConfig();
|
|
26645
26950
|
if (config == null) {
|
|
26646
26951
|
process.stderr.write("Not signed in. Run `overai signin`.\n");
|
|
26647
26952
|
process.exitCode = 1;
|
|
26648
26953
|
return;
|
|
26649
26954
|
}
|
|
26955
|
+
const cloneOrgId = (() => {
|
|
26956
|
+
try {
|
|
26957
|
+
return readManifest(findWorkspaceRoot()).organizationId;
|
|
26958
|
+
} catch {
|
|
26959
|
+
return null;
|
|
26960
|
+
}
|
|
26961
|
+
})();
|
|
26962
|
+
const effective = orgIdOverride ?? cloneOrgId ?? config.organizationId;
|
|
26963
|
+
const names = await fetchOrgNames().catch(() => null);
|
|
26964
|
+
const label = (id) => names?.get(id) == null ? id : `${id} \u2014 ${String(names.get(id))}`;
|
|
26650
26965
|
process.stdout.write(
|
|
26651
|
-
`Signed in${config.email != null ? ` as ${config.email}` : ""} (org ${
|
|
26966
|
+
`Signed in${config.email != null ? ` as ${config.email}` : ""} (org ${label(effective)}).
|
|
26652
26967
|
`
|
|
26653
26968
|
);
|
|
26654
|
-
|
|
26655
|
-
|
|
26656
|
-
|
|
26657
|
-
|
|
26658
|
-
var flagValue = (args, ...names) => {
|
|
26659
|
-
for (const name2 of names) {
|
|
26660
|
-
const i = args.indexOf(name2);
|
|
26661
|
-
if (i !== -1 && i + 1 < args.length) return args[i + 1];
|
|
26662
|
-
}
|
|
26663
|
-
return void 0;
|
|
26664
|
-
};
|
|
26665
|
-
var stdinClaimedBy = null;
|
|
26666
|
-
var readStdin = async (claimant = "stdin") => {
|
|
26667
|
-
if (stdinClaimedBy != null) {
|
|
26668
|
-
throw new Error(
|
|
26669
|
-
`Only one value can be read from stdin; ${stdinClaimedBy} already consumed it.`
|
|
26670
|
-
);
|
|
26671
|
-
}
|
|
26672
|
-
stdinClaimedBy = claimant;
|
|
26673
|
-
const chunks = [];
|
|
26674
|
-
for await (const chunk of process.stdin) {
|
|
26675
|
-
chunks.push(chunk);
|
|
26676
|
-
}
|
|
26677
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
26678
|
-
};
|
|
26679
|
-
var readValue = async (value, label) => {
|
|
26680
|
-
if (value?.startsWith("@") !== true) return value;
|
|
26681
|
-
if (value.startsWith("@@")) return value.slice(1);
|
|
26682
|
-
const path = value.slice(1);
|
|
26683
|
-
if (path === "-") return (await readStdin(`${label} @-`)).trim();
|
|
26684
|
-
try {
|
|
26685
|
-
return readFileSync2(path, "utf8").trim();
|
|
26686
|
-
} catch {
|
|
26687
|
-
throw new Error(
|
|
26688
|
-
`${label}: could not read file "${path}". Write "@@" to send a literal value starting with "@".`
|
|
26689
|
-
);
|
|
26690
|
-
}
|
|
26691
|
-
};
|
|
26692
|
-
|
|
26693
|
-
// src/output.ts
|
|
26694
|
-
var resolveFormat = (explicit) => {
|
|
26695
|
-
if (explicit === "json" || explicit === "csv" || explicit === "table") {
|
|
26696
|
-
return explicit;
|
|
26697
|
-
}
|
|
26698
|
-
if (explicit != null) {
|
|
26699
|
-
throw new Error(
|
|
26700
|
-
`Unknown output format "${explicit}". Use json, table, or csv.`
|
|
26969
|
+
if (effective !== config.organizationId) {
|
|
26970
|
+
process.stdout.write(
|
|
26971
|
+
`Scoped by ${orgIdOverride != null ? "OVERAI_ORG_ID" : ".overai/manifest.json"}; the machine-global active org is ${label(config.organizationId)}.
|
|
26972
|
+
`
|
|
26701
26973
|
);
|
|
26702
26974
|
}
|
|
26703
|
-
return process.stdout.isTTY ? "table" : "json";
|
|
26704
|
-
};
|
|
26705
|
-
var cell = (value) => {
|
|
26706
|
-
if (value == null) return "";
|
|
26707
|
-
if (typeof value === "string") return value;
|
|
26708
|
-
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
26709
|
-
return String(value);
|
|
26710
|
-
}
|
|
26711
|
-
return JSON.stringify(value);
|
|
26712
|
-
};
|
|
26713
|
-
var formatResult = (data, format2) => {
|
|
26714
|
-
if (format2 === "json" || !Array.isArray(data)) {
|
|
26715
|
-
return JSON.stringify(data, null, 2);
|
|
26716
|
-
}
|
|
26717
|
-
const records = data.map(
|
|
26718
|
-
(row) => row != null && typeof row === "object" ? row : { value: row }
|
|
26719
|
-
);
|
|
26720
|
-
if (records.length === 0) return "(no rows)";
|
|
26721
|
-
const columns = [...new Set(records.flatMap((r) => Object.keys(r)))];
|
|
26722
|
-
if (format2 === "csv") {
|
|
26723
|
-
const escape2 = (value) => {
|
|
26724
|
-
const text = cell(value);
|
|
26725
|
-
return /[",\n\r]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
|
|
26726
|
-
};
|
|
26727
|
-
return [
|
|
26728
|
-
columns.join(","),
|
|
26729
|
-
...records.map((r) => columns.map((c) => escape2(r[c])).join(","))
|
|
26730
|
-
].join("\n");
|
|
26731
|
-
}
|
|
26732
|
-
const widths = columns.map(
|
|
26733
|
-
(c) => Math.max(c.length, ...records.map((r) => cell(r[c]).length))
|
|
26734
|
-
);
|
|
26735
|
-
const line = (cells) => cells.map((text, i) => text.padEnd(widths[i] ?? 0)).join(" ");
|
|
26736
|
-
return [
|
|
26737
|
-
line(columns),
|
|
26738
|
-
line(widths.map((w) => "-".repeat(w))),
|
|
26739
|
-
...records.map((r) => line(columns.map((c) => cell(r[c]))))
|
|
26740
|
-
].join("\n");
|
|
26741
|
-
};
|
|
26742
|
-
var printResult = (data, format2) => {
|
|
26743
|
-
process.stdout.write(`${formatResult(data, format2)}
|
|
26744
|
-
`);
|
|
26745
26975
|
};
|
|
26746
26976
|
|
|
26747
26977
|
// src/commands/agent.ts
|
|
@@ -26756,8 +26986,9 @@ var runAgent = async (args) => {
|
|
|
26756
26986
|
headers: { "Content-Type": "application/json" },
|
|
26757
26987
|
body: JSON.stringify({ message })
|
|
26758
26988
|
});
|
|
26759
|
-
const
|
|
26760
|
-
if (!response.ok) throw
|
|
26989
|
+
const raw2 = await response.text();
|
|
26990
|
+
if (!response.ok) throw v2Error("agent generate", response, raw2);
|
|
26991
|
+
const body = JSON.parse(raw2);
|
|
26761
26992
|
printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
|
|
26762
26993
|
};
|
|
26763
26994
|
|
|
@@ -26771,12 +27002,20 @@ var gqlRequest = async (query, variables, options) => {
|
|
|
26771
27002
|
body: JSON.stringify({ query, variables })
|
|
26772
27003
|
}
|
|
26773
27004
|
);
|
|
26774
|
-
const
|
|
27005
|
+
const raw2 = await res.text();
|
|
27006
|
+
const body = (() => {
|
|
27007
|
+
try {
|
|
27008
|
+
return JSON.parse(raw2);
|
|
27009
|
+
} catch {
|
|
27010
|
+
return null;
|
|
27011
|
+
}
|
|
27012
|
+
})();
|
|
26775
27013
|
if (body?.errors != null && body.errors.length > 0) {
|
|
26776
27014
|
throw new Error(body.errors.map((e) => e.message).join("; "));
|
|
26777
27015
|
}
|
|
26778
|
-
if (!res.ok
|
|
26779
|
-
|
|
27016
|
+
if (!res.ok) throw v2Error("graphql", res, raw2);
|
|
27017
|
+
if (body?.data == null) {
|
|
27018
|
+
throw new Error("graphql returned no data and no errors.");
|
|
26780
27019
|
}
|
|
26781
27020
|
return body.data;
|
|
26782
27021
|
};
|
|
@@ -26852,12 +27091,9 @@ var runTrigger = async (automationId, args) => {
|
|
|
26852
27091
|
body: JSON.stringify(body)
|
|
26853
27092
|
}
|
|
26854
27093
|
);
|
|
26855
|
-
const
|
|
26856
|
-
if (!res.ok)
|
|
26857
|
-
|
|
26858
|
-
responseBody?.error ?? `run failed (${String(res.status)})`
|
|
26859
|
-
);
|
|
26860
|
-
}
|
|
27094
|
+
const raw2 = await res.text();
|
|
27095
|
+
if (!res.ok) throw v2Error("automation run", res, raw2);
|
|
27096
|
+
const responseBody = JSON.parse(raw2);
|
|
26861
27097
|
printResult(responseBody, resolveFormat(flagValue(args, "-o", "--output")));
|
|
26862
27098
|
};
|
|
26863
27099
|
var runAutomation = async (args) => {
|
|
@@ -26871,81 +27107,6 @@ var runAutomation = async (args) => {
|
|
|
26871
27107
|
process.exitCode = 1;
|
|
26872
27108
|
};
|
|
26873
27109
|
|
|
26874
|
-
// src/workspace/manifest.ts
|
|
26875
|
-
import { existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
26876
|
-
import { dirname, join as join2, resolve } from "path";
|
|
26877
|
-
var MANIFEST_DIR = ".overai";
|
|
26878
|
-
var MANIFEST_FILE = "manifest.json";
|
|
26879
|
-
var BASE_DIR = "base";
|
|
26880
|
-
var findWorkspaceRoot = (from = process.cwd()) => {
|
|
26881
|
-
let dir = resolve(from);
|
|
26882
|
-
for (; ; ) {
|
|
26883
|
-
if (existsSync(join2(dir, MANIFEST_DIR, MANIFEST_FILE))) return dir;
|
|
26884
|
-
const parent = dirname(dir);
|
|
26885
|
-
if (parent === dir) {
|
|
26886
|
-
throw new Error(
|
|
26887
|
-
"Not inside a cloned workspace (no .overai/manifest.json found). Run `overai clone <workspaceId>` first."
|
|
26888
|
-
);
|
|
26889
|
-
}
|
|
26890
|
-
dir = parent;
|
|
26891
|
-
}
|
|
26892
|
-
};
|
|
26893
|
-
var readManifest = (root) => JSON.parse(
|
|
26894
|
-
readFileSync3(join2(root, MANIFEST_DIR, MANIFEST_FILE), "utf8")
|
|
26895
|
-
);
|
|
26896
|
-
var openClone = () => {
|
|
26897
|
-
const root = findWorkspaceRoot();
|
|
26898
|
-
const manifest = readManifest(root);
|
|
26899
|
-
setOrgScope(manifest.organizationId);
|
|
26900
|
-
return { root, manifest };
|
|
26901
|
-
};
|
|
26902
|
-
var writeManifest = (root, manifest) => {
|
|
26903
|
-
mkdirSync2(join2(root, MANIFEST_DIR), { recursive: true });
|
|
26904
|
-
writeFileSync2(
|
|
26905
|
-
join2(root, MANIFEST_DIR, MANIFEST_FILE),
|
|
26906
|
-
`${JSON.stringify(manifest, null, 2)}
|
|
26907
|
-
`
|
|
26908
|
-
);
|
|
26909
|
-
};
|
|
26910
|
-
var basePath = (root, relPath) => join2(root, MANIFEST_DIR, BASE_DIR, relPath);
|
|
26911
|
-
var writeSynced = (root, relPath, content) => {
|
|
26912
|
-
for (const abs2 of [join2(root, relPath), basePath(root, relPath)]) {
|
|
26913
|
-
mkdirSync2(dirname(abs2), { recursive: true });
|
|
26914
|
-
writeFileSync2(abs2, content);
|
|
26915
|
-
}
|
|
26916
|
-
};
|
|
26917
|
-
var readWorkingFile = (root, relPath) => {
|
|
26918
|
-
try {
|
|
26919
|
-
return readFileSync3(join2(root, relPath), "utf8");
|
|
26920
|
-
} catch {
|
|
26921
|
-
return null;
|
|
26922
|
-
}
|
|
26923
|
-
};
|
|
26924
|
-
var readBaseFile = (root, relPath) => {
|
|
26925
|
-
try {
|
|
26926
|
-
return readFileSync3(basePath(root, relPath), "utf8");
|
|
26927
|
-
} catch {
|
|
26928
|
-
return null;
|
|
26929
|
-
}
|
|
26930
|
-
};
|
|
26931
|
-
var slugify = (name2) => name2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60) || "untitled";
|
|
26932
|
-
var localState = (root, resource) => {
|
|
26933
|
-
const changedFiles = [];
|
|
26934
|
-
let missing = false;
|
|
26935
|
-
for (const relPath of resource.files) {
|
|
26936
|
-
const working = readWorkingFile(root, relPath);
|
|
26937
|
-
if (working == null) {
|
|
26938
|
-
missing = true;
|
|
26939
|
-
continue;
|
|
26940
|
-
}
|
|
26941
|
-
if (working !== readBaseFile(root, relPath)) changedFiles.push(relPath);
|
|
26942
|
-
}
|
|
26943
|
-
return {
|
|
26944
|
-
state: missing ? "missing" : changedFiles.length > 0 ? "modified" : "unchanged",
|
|
26945
|
-
changedFiles
|
|
26946
|
-
};
|
|
26947
|
-
};
|
|
26948
|
-
|
|
26949
27110
|
// src/workspace/validateElements.ts
|
|
26950
27111
|
var findings = (parsed) => parsed.success ? [] : parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
|
|
26951
27112
|
var validateAutomationElements = async (elements) => {
|
|
@@ -26953,7 +27114,7 @@ var validateAutomationElements = async (elements) => {
|
|
|
26953
27114
|
return findings(automationNodesSchema.safeParse(elements));
|
|
26954
27115
|
};
|
|
26955
27116
|
var validateWebPageConfig = async (config) => {
|
|
26956
|
-
const { webPageConfigWriteSchema } = await import("./webPage-
|
|
27117
|
+
const { webPageConfigWriteSchema } = await import("./webPage-G5HIZM7Q.js");
|
|
26957
27118
|
return findings(webPageConfigWriteSchema.safeParse(config));
|
|
26958
27119
|
};
|
|
26959
27120
|
|
|
@@ -27553,10 +27714,9 @@ var enqueueAction = async (runnerId, actionId, inputs, args) => {
|
|
|
27553
27714
|
body: JSON.stringify({ actionId, inputs, actionRunnerId: runnerId })
|
|
27554
27715
|
}
|
|
27555
27716
|
);
|
|
27556
|
-
const
|
|
27557
|
-
if (!res.ok)
|
|
27558
|
-
|
|
27559
|
-
}
|
|
27717
|
+
const raw2 = await res.text();
|
|
27718
|
+
if (!res.ok) throw v2Error("runner run", res, raw2);
|
|
27719
|
+
const body = JSON.parse(raw2);
|
|
27560
27720
|
printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
|
|
27561
27721
|
};
|
|
27562
27722
|
var runRun = async (runnerId, args) => {
|
|
@@ -33361,14 +33521,14 @@ var runDataFile = async (args) => {
|
|
|
33361
33521
|
message: flagValue(args, "-m", "--message") ?? ""
|
|
33362
33522
|
});
|
|
33363
33523
|
const response2 = await fetch(url, { method: "PUT", body: readFileSync5(path) });
|
|
33364
|
-
if (!response2.ok) throw
|
|
33524
|
+
if (!response2.ok) throw v2Error("data-file upload", response2, await response2.text());
|
|
33365
33525
|
process.stdout.write(`${id}
|
|
33366
33526
|
`);
|
|
33367
33527
|
return;
|
|
33368
33528
|
}
|
|
33369
33529
|
const suffix = operation === "head" ? `/head?numLines=${encodeURIComponent(flagValue(args, "--lines") ?? "50")}` : "";
|
|
33370
33530
|
const response = await v2Fetch(`/v2/data-files/${organizationId}/${id}${suffix}`, { redirect: "follow" });
|
|
33371
|
-
if (!response.ok) throw
|
|
33531
|
+
if (!response.ok) throw v2Error(`data-file ${String(operation)}`, response, await response.text());
|
|
33372
33532
|
const bytes = Buffer.from(await response.arrayBuffer());
|
|
33373
33533
|
if (path != null && path !== "-") writeFileSync3(path, bytes);
|
|
33374
33534
|
else process.stdout.write(bytes);
|
|
@@ -33382,11 +33542,11 @@ var runDataStream = async (args) => {
|
|
|
33382
33542
|
}
|
|
33383
33543
|
const { organizationId } = await getAccessToken();
|
|
33384
33544
|
if (operation === "append") {
|
|
33385
|
-
const
|
|
33386
|
-
if (
|
|
33545
|
+
const raw3 = await readValue(args[2], "data stream input");
|
|
33546
|
+
if (raw3 == null) throw new Error("Data stream append requires JSON, @<file>, or @-.");
|
|
33387
33547
|
const parsed = (() => {
|
|
33388
33548
|
try {
|
|
33389
|
-
return JSON.parse(
|
|
33549
|
+
return JSON.parse(raw3);
|
|
33390
33550
|
} catch {
|
|
33391
33551
|
throw new Error("Data stream input must be valid JSON.");
|
|
33392
33552
|
}
|
|
@@ -33396,8 +33556,9 @@ var runDataStream = async (args) => {
|
|
|
33396
33556
|
headers: { "Content-Type": "application/json" },
|
|
33397
33557
|
body: JSON.stringify({ data: Array.isArray(parsed) ? parsed : [parsed] })
|
|
33398
33558
|
});
|
|
33399
|
-
const
|
|
33400
|
-
if (!response2.ok) throw
|
|
33559
|
+
const appended = await response2.text();
|
|
33560
|
+
if (!response2.ok) throw v2Error("data-stream append", response2, appended);
|
|
33561
|
+
const body2 = JSON.parse(appended);
|
|
33401
33562
|
printResult(body2, resolveFormat(flagValue(args, "-o", "--output")));
|
|
33402
33563
|
return;
|
|
33403
33564
|
}
|
|
@@ -33408,8 +33569,9 @@ var runDataStream = async (args) => {
|
|
|
33408
33569
|
const limit2 = flagValue(args, "--limit");
|
|
33409
33570
|
if (limit2 != null) query.set("limit", limit2);
|
|
33410
33571
|
const response = await v2Fetch(`/v1/data-streams/${organizationId}/${id}?${query.toString()}`);
|
|
33411
|
-
const
|
|
33412
|
-
if (!response.ok) throw
|
|
33572
|
+
const raw2 = await response.text();
|
|
33573
|
+
if (!response.ok) throw v2Error("data-stream query", response, raw2);
|
|
33574
|
+
const body = JSON.parse(raw2);
|
|
33413
33575
|
printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
|
|
33414
33576
|
};
|
|
33415
33577
|
|
|
@@ -34112,18 +34274,7 @@ var runFn = async (args) => {
|
|
|
34112
34274
|
`);
|
|
34113
34275
|
}
|
|
34114
34276
|
const body = await res.text();
|
|
34115
|
-
if (!res.ok)
|
|
34116
|
-
const structured = (() => {
|
|
34117
|
-
try {
|
|
34118
|
-
return JSON.parse(body);
|
|
34119
|
-
} catch {
|
|
34120
|
-
return null;
|
|
34121
|
-
}
|
|
34122
|
-
})();
|
|
34123
|
-
throw new Error(
|
|
34124
|
-
structured?.error ?? (body.trim() || `fn failed (${String(res.status)})`)
|
|
34125
|
-
);
|
|
34126
|
-
}
|
|
34277
|
+
if (!res.ok) throw v2Error("fn", res, body);
|
|
34127
34278
|
process.stdout.write(`${body}
|
|
34128
34279
|
`);
|
|
34129
34280
|
};
|
|
@@ -34165,12 +34316,20 @@ var runGraphql = async (args) => {
|
|
|
34165
34316
|
body: JSON.stringify({ query, variables })
|
|
34166
34317
|
}
|
|
34167
34318
|
);
|
|
34168
|
-
const
|
|
34319
|
+
const raw2 = await res.text();
|
|
34320
|
+
const body = (() => {
|
|
34321
|
+
try {
|
|
34322
|
+
return JSON.parse(raw2);
|
|
34323
|
+
} catch {
|
|
34324
|
+
return null;
|
|
34325
|
+
}
|
|
34326
|
+
})();
|
|
34169
34327
|
if (body?.errors != null && body.errors.length > 0) {
|
|
34170
34328
|
throw new Error(body.errors.map((e) => e.message).join("; "));
|
|
34171
34329
|
}
|
|
34172
|
-
if (!res.ok
|
|
34173
|
-
|
|
34330
|
+
if (!res.ok) throw v2Error("graphql", res, raw2);
|
|
34331
|
+
if (body == null) {
|
|
34332
|
+
throw new Error("graphql returned an unreadable body.");
|
|
34174
34333
|
}
|
|
34175
34334
|
printResult(body.data, resolveFormat(flagValue(args, "-o", "--output")));
|
|
34176
34335
|
};
|
|
@@ -34262,71 +34421,6 @@ var runOpen = async (args) => {
|
|
|
34262
34421
|
openBrowser(url);
|
|
34263
34422
|
};
|
|
34264
34423
|
|
|
34265
|
-
// src/commands/org.ts
|
|
34266
|
-
var USER_ORGS_QUERY = `
|
|
34267
|
-
query UserOrganizations($identityId: String!) {
|
|
34268
|
-
identityOrganizations(
|
|
34269
|
-
where: { identityId: { _eq: $identityId }, disabled: { _eq: false } }
|
|
34270
|
-
) {
|
|
34271
|
-
organization { id name }
|
|
34272
|
-
}
|
|
34273
|
-
}
|
|
34274
|
-
`;
|
|
34275
|
-
var listOrgs = async (args) => {
|
|
34276
|
-
const auth = await getAccessToken();
|
|
34277
|
-
const identityId = decodeJwtClaims(auth.token).user_id;
|
|
34278
|
-
if (identityId == null) {
|
|
34279
|
-
throw new Error("Could not read identity from the current session.");
|
|
34280
|
-
}
|
|
34281
|
-
const res = await v2Fetch("/v1/graphql", {
|
|
34282
|
-
method: "POST",
|
|
34283
|
-
headers: { "Content-Type": "application/json" },
|
|
34284
|
-
body: JSON.stringify({ query: USER_ORGS_QUERY, variables: { identityId } })
|
|
34285
|
-
});
|
|
34286
|
-
const body = await res.json().catch(() => null);
|
|
34287
|
-
if (body?.errors != null && body.errors.length > 0) {
|
|
34288
|
-
throw new Error(body.errors.map((e) => e.message).join("; "));
|
|
34289
|
-
}
|
|
34290
|
-
if (!res.ok || body == null) {
|
|
34291
|
-
throw new Error(`org list failed (${String(res.status)})`);
|
|
34292
|
-
}
|
|
34293
|
-
const orgs = (body.data?.identityOrganizations ?? []).map((edge) => edge.organization).filter((org) => org != null).map((org) => ({
|
|
34294
|
-
id: org.id,
|
|
34295
|
-
name: org.name ?? "",
|
|
34296
|
-
active: org.id === auth.organizationId
|
|
34297
|
-
}));
|
|
34298
|
-
printResult(orgs, resolveFormat(flagValue(args, "-o", "--output")));
|
|
34299
|
-
};
|
|
34300
|
-
var switchOrg = async (orgId) => {
|
|
34301
|
-
const config = readConfig();
|
|
34302
|
-
if (config == null) {
|
|
34303
|
-
process.stderr.write("Not signed in. Run `overai signin`.\n");
|
|
34304
|
-
process.exitCode = 1;
|
|
34305
|
-
return;
|
|
34306
|
-
}
|
|
34307
|
-
const result = await exchangeSessionToken(config.refreshToken, orgId);
|
|
34308
|
-
if (result.type === "redirect") {
|
|
34309
|
-
process.stdout.write(
|
|
34310
|
-
`This organization requires SSO. Complete sign-in in your browser, then run \`overai signin\`.
|
|
34311
|
-
${result.redirectUrl}
|
|
34312
|
-
`
|
|
34313
|
-
);
|
|
34314
|
-
openBrowser(result.redirectUrl);
|
|
34315
|
-
process.exitCode = 1;
|
|
34316
|
-
return;
|
|
34317
|
-
}
|
|
34318
|
-
writeConfig({
|
|
34319
|
-
...config,
|
|
34320
|
-
organizationId: orgId,
|
|
34321
|
-
email: decodeJwtClaims(result.token).email ?? config.email,
|
|
34322
|
-
accessToken: result.token,
|
|
34323
|
-
accessTokenExpiresAt: Date.now() + result.accessTokenValiditySeconds * 1e3,
|
|
34324
|
-
refreshToken: result.refreshToken
|
|
34325
|
-
});
|
|
34326
|
-
process.stdout.write(`Switched to org ${orgId}.
|
|
34327
|
-
`);
|
|
34328
|
-
};
|
|
34329
|
-
|
|
34330
34424
|
// src/commands/printablePage.ts
|
|
34331
34425
|
var runPrintablePage = async (args) => {
|
|
34332
34426
|
const [operation, id] = args;
|
|
@@ -34346,8 +34440,9 @@ var runPrintablePage = async (args) => {
|
|
|
34346
34440
|
body: JSON.stringify({ actionId: "PRINTABLE_PAGE_TO_PDF", inputs: { printablePageId: id, searchParams, includeDiagnostics: true } }),
|
|
34347
34441
|
signal: AbortSignal.timeout(timeoutMs)
|
|
34348
34442
|
});
|
|
34349
|
-
const
|
|
34350
|
-
if (!response.ok) throw
|
|
34443
|
+
const raw2 = await response.text();
|
|
34444
|
+
if (!response.ok) throw v2Error("printable-page render", response, raw2);
|
|
34445
|
+
const body = JSON.parse(raw2);
|
|
34351
34446
|
printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
|
|
34352
34447
|
};
|
|
34353
34448
|
|
|
@@ -34609,7 +34704,8 @@ deploy\` makes it live. Pick primitives by trigger:
|
|
|
34609
34704
|
- Awaitable server-side logic, callable from pages/automations/agents \u2192 a
|
|
34610
34705
|
**Function** (Deno sandbox, can import from esm.sh, full env SDK).
|
|
34611
34706
|
- Storage: **TableSpaces** (Postgres, via env.TBSxxx) for structured data;
|
|
34612
|
-
**Data Files** (env.DFxxx) for versioned single-file datasets
|
|
34707
|
+
**Data Files** (env.DFxxx) for versioned single-file datasets; **File
|
|
34708
|
+
Buckets** (env.FBxxx) for browsable file collections and SFTP. Prefer
|
|
34613
34709
|
first-class platform features over third-party integrations.
|
|
34614
34710
|
|
|
34615
34711
|
When broken or unexplained platform behavior blocks progress, send a detailed
|
|
@@ -34629,16 +34725,22 @@ column autocomplete; joins/aggregates/projections take a hand-written type or
|
|
|
34629
34725
|
Pick<...>), env.FNxxx.call()
|
|
34630
34726
|
(pass \`path\` to hit a sub-path of a function that routes internally),
|
|
34631
34727
|
env.ATxxx.start(inputs?) (fire-and-forget), env.DFxxx.read.json()/.saveVersion(),
|
|
34728
|
+
env.FBxxx.list()/read(entryId)/upload()/createFolder(),
|
|
34632
34729
|
env.STORAGE.fetch/upload/presign (upload shortens stored names over 128
|
|
34633
|
-
characters in the middle while preserving their ends),
|
|
34730
|
+
characters in the middle while preserving their ends), env.STORAGE.text
|
|
34731
|
+
(best-effort text representation of PDF, DOCX, Excel, HTML, and text files
|
|
34732
|
+
without AI; \`{ vision: true }\` uses AI to represent PDFs or images as text and
|
|
34733
|
+
is required for images), env.STORAGE.csv (one Excel worksheet selected by name
|
|
34734
|
+
or zero-based index), env.STORAGE.image (PNG representation of a raster image,
|
|
34735
|
+
SVG, or single-page PDF),
|
|
34634
34736
|
env.AI.generateText/generateObject,
|
|
34635
34737
|
env.GRAPHQL.request().
|
|
34636
34738
|
|
|
34637
34739
|
Not everything is available everywhere. Functions and automation code nodes
|
|
34638
34740
|
also get env.STORAGE.zipTree/zipExtract \u2014 list a zip without decompressing it,
|
|
34639
|
-
then extract only the entries you need, each into its own storage URL.
|
|
34640
|
-
|
|
34641
|
-
|
|
34741
|
+
then extract only the entries you need, each into its own storage URL. A web
|
|
34742
|
+
page does NOT have these server-side conversion and archive helpers: that work
|
|
34743
|
+
belongs in a function the page calls.`;
|
|
34642
34744
|
var automations = `# Automation best practices
|
|
34643
34745
|
|
|
34644
34746
|
An automation's elements document is the node graph: an array of nodes, each
|
|
@@ -35134,11 +35236,7 @@ var runQuery = async (organizationId, tableSpaceId, query, params) => {
|
|
|
35134
35236
|
return null;
|
|
35135
35237
|
}
|
|
35136
35238
|
})();
|
|
35137
|
-
if (!res.ok || body?.ok === false)
|
|
35138
|
-
throw new Error(
|
|
35139
|
-
body?.error ?? (raw2.trim().length > 0 ? raw2.trim() : res.status === 404 ? "table space not found or you lack access to it" : `HTTP ${String(res.status)}`)
|
|
35140
|
-
);
|
|
35141
|
-
}
|
|
35239
|
+
if (!res.ok || body?.ok === false) throw v2Error("sql", res, raw2);
|
|
35142
35240
|
return {
|
|
35143
35241
|
rows: body?.rows ?? [],
|
|
35144
35242
|
rowCount: body?.rowCount ?? 0,
|
|
@@ -35593,20 +35691,9 @@ var runDiff = async (args) => {
|
|
|
35593
35691
|
};
|
|
35594
35692
|
|
|
35595
35693
|
// src/commands/workspace.ts
|
|
35596
|
-
var workspaceIdFrom = (args) =>
|
|
35597
|
-
|
|
35598
|
-
|
|
35599
|
-
);
|
|
35600
|
-
if (workspaceId == null) return openClone().manifest.workspaceId;
|
|
35601
|
-
try {
|
|
35602
|
-
openClone();
|
|
35603
|
-
} catch (error) {
|
|
35604
|
-
if (!(error instanceof Error) || !error.message.startsWith("Not inside a cloned workspace")) {
|
|
35605
|
-
throw error;
|
|
35606
|
-
}
|
|
35607
|
-
}
|
|
35608
|
-
return workspaceId;
|
|
35609
|
-
};
|
|
35694
|
+
var workspaceIdFrom = (args) => args.find(
|
|
35695
|
+
(arg, index) => !arg.startsWith("-") && args[index - 1] !== "-o" && args[index - 1] !== "--output"
|
|
35696
|
+
) ?? openClone().manifest.workspaceId;
|
|
35610
35697
|
var listWorkspaces = async (args) => {
|
|
35611
35698
|
const archived = args.includes("--archived");
|
|
35612
35699
|
const limit2 = Number(flagValue(args, "--limit") ?? 200);
|
|
@@ -35646,10 +35733,7 @@ var showWorkspace = async (args) => {
|
|
|
35646
35733
|
`Workspace ${workspaceId} not found (or not visible to you).`
|
|
35647
35734
|
);
|
|
35648
35735
|
}
|
|
35649
|
-
printResult(
|
|
35650
|
-
data.workspace,
|
|
35651
|
-
resolveFormat(flagValue(args, "-o", "--output"))
|
|
35652
|
-
);
|
|
35736
|
+
printResult(data.workspace, resolveFormat(flagValue(args, "-o", "--output")));
|
|
35653
35737
|
};
|
|
35654
35738
|
var listWorkspaceUsers = async (args) => {
|
|
35655
35739
|
const workspaceId = workspaceIdFrom(args);
|
|
@@ -35685,9 +35769,7 @@ var listWorkspaceUsers = async (args) => {
|
|
|
35685
35769
|
parentWorkspaceRole: membership.parentWorkspaceRole ?? ""
|
|
35686
35770
|
}
|
|
35687
35771
|
]
|
|
35688
|
-
).sort(
|
|
35689
|
-
(a, b) => (a.name || a.email).localeCompare(b.name || b.email)
|
|
35690
|
-
),
|
|
35772
|
+
).sort((a, b) => (a.name || a.email).localeCompare(b.name || b.email)),
|
|
35691
35773
|
resolveFormat(flagValue(args, "-o", "--output"))
|
|
35692
35774
|
);
|
|
35693
35775
|
};
|
|
@@ -35803,16 +35885,43 @@ it from stdin. Prefer that for anything long or quote-heavy: an inline value is
|
|
|
35803
35885
|
parsed by your shell first, and one apostrophe inside it silently truncates the
|
|
35804
35886
|
rest. Write @@ to send a literal value that starts with "@".
|
|
35805
35887
|
|
|
35888
|
+
Organizations: commands run as the clone you're standing in (.overai/manifest.json),
|
|
35889
|
+
else the active org from \`org switch\`. The active org is machine-global \u2014 every
|
|
35890
|
+
shell shares it \u2014 so scope one command or one shell with OVERAI_ORG_ID=<orgId>
|
|
35891
|
+
instead. \`overai whoami\` says which org is in effect and why.
|
|
35892
|
+
|
|
35806
35893
|
Output: table on a TTY, JSON when piped; -o json|table|csv to force.
|
|
35807
35894
|
Aliases: login = signin, logout = signout, ws = workspace.
|
|
35808
35895
|
Env: OVERAI_API_URL, OVERAI_APP_URL override the target deployment.
|
|
35896
|
+
OVERAI_ORG_ID overrides the organization for this shell.
|
|
35809
35897
|
`;
|
|
35810
35898
|
process.stdout.on("error", (error) => {
|
|
35811
35899
|
if (error.code === "EPIPE") process.exit(0);
|
|
35812
35900
|
throw error;
|
|
35813
35901
|
});
|
|
35902
|
+
var ORG_AGNOSTIC_COMMANDS = /* @__PURE__ */ new Set([
|
|
35903
|
+
"signin",
|
|
35904
|
+
"login",
|
|
35905
|
+
"signout",
|
|
35906
|
+
"logout",
|
|
35907
|
+
"whoami",
|
|
35908
|
+
"org",
|
|
35909
|
+
"clone",
|
|
35910
|
+
"update",
|
|
35911
|
+
"upgrade",
|
|
35912
|
+
"version",
|
|
35913
|
+
"--version",
|
|
35914
|
+
"-v",
|
|
35915
|
+
"help",
|
|
35916
|
+
"--help",
|
|
35917
|
+
"-h"
|
|
35918
|
+
]);
|
|
35814
35919
|
var run = async () => {
|
|
35815
35920
|
const [command, ...rest] = process.argv.slice(2);
|
|
35921
|
+
if (command != null && !ORG_AGNOSTIC_COMMANDS.has(command)) {
|
|
35922
|
+
pinOrgFromClone();
|
|
35923
|
+
announceOrgScope();
|
|
35924
|
+
}
|
|
35816
35925
|
switch (command) {
|
|
35817
35926
|
case "signin":
|
|
35818
35927
|
case "login":
|
|
@@ -35823,7 +35932,7 @@ var run = async () => {
|
|
|
35823
35932
|
await signOut();
|
|
35824
35933
|
return;
|
|
35825
35934
|
case "whoami":
|
|
35826
|
-
whoami();
|
|
35935
|
+
await whoami();
|
|
35827
35936
|
return;
|
|
35828
35937
|
case "org":
|
|
35829
35938
|
if (rest[0] === "list") {
|