@overaihq/cli 0.7.0 → 0.9.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,89 +27107,14 @@ 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) => {
|
|
26952
|
-
const { automationNodesSchema } = await import("./types-
|
|
27113
|
+
const { automationNodesSchema } = await import("./types-RJF53EMD.js");
|
|
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,11 +33569,72 @@ 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
|
|
|
33578
|
+
// src/commands/knowledgeBase.ts
|
|
33579
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
33580
|
+
import { basename } from "path";
|
|
33581
|
+
var runKnowledgeBase = async (args) => {
|
|
33582
|
+
const [operation, id] = args;
|
|
33583
|
+
if (id == null || operation !== "upload" && operation !== "search") {
|
|
33584
|
+
throw new Error(
|
|
33585
|
+
"Usage: overai knowledge-base upload <id> <file...> | knowledge-base search <id> <query> [--limit N]"
|
|
33586
|
+
);
|
|
33587
|
+
}
|
|
33588
|
+
const { organizationId } = await getAccessToken();
|
|
33589
|
+
if (operation === "upload") {
|
|
33590
|
+
const paths = args.slice(2).filter(
|
|
33591
|
+
(arg, i, all) => !arg.startsWith("-") && all[i - 1] !== "-o" && all[i - 1] !== "--output"
|
|
33592
|
+
);
|
|
33593
|
+
if (paths.length === 0)
|
|
33594
|
+
throw new Error("Knowledge base upload requires at least one file path.");
|
|
33595
|
+
const uploads = [];
|
|
33596
|
+
for (const path of paths) {
|
|
33597
|
+
const bytes = await readFile2(path);
|
|
33598
|
+
const formData = new FormData();
|
|
33599
|
+
formData.append(
|
|
33600
|
+
"file",
|
|
33601
|
+
new Blob([new Uint8Array(bytes)]),
|
|
33602
|
+
basename(path)
|
|
33603
|
+
);
|
|
33604
|
+
const response2 = await v2Fetch(
|
|
33605
|
+
`/v2/knowledge-bases/${organizationId}/${id}/upload`,
|
|
33606
|
+
{ method: "POST", body: formData }
|
|
33607
|
+
);
|
|
33608
|
+
const raw3 = await response2.text();
|
|
33609
|
+
if (!response2.ok) throw v2Error("knowledge-base upload", response2, raw3);
|
|
33610
|
+
uploads.push({ file: basename(path), ...JSON.parse(raw3) });
|
|
33611
|
+
}
|
|
33612
|
+
printResult(uploads, resolveFormat(flagValue(args, "-o", "--output")));
|
|
33613
|
+
return;
|
|
33614
|
+
}
|
|
33615
|
+
const query = args[2];
|
|
33616
|
+
if (query == null || query.startsWith("-"))
|
|
33617
|
+
throw new Error("Knowledge base search requires a query string.");
|
|
33618
|
+
const limit2 = flagValue(args, "--limit");
|
|
33619
|
+
const response = await v2Fetch(
|
|
33620
|
+
`/v2/knowledge-bases/${organizationId}/${id}/search`,
|
|
33621
|
+
{
|
|
33622
|
+
method: "POST",
|
|
33623
|
+
headers: { "Content-Type": "application/json" },
|
|
33624
|
+
body: JSON.stringify({
|
|
33625
|
+
query,
|
|
33626
|
+
...limit2 != null ? { limit: Number(limit2) } : {}
|
|
33627
|
+
})
|
|
33628
|
+
}
|
|
33629
|
+
);
|
|
33630
|
+
const raw2 = await response.text();
|
|
33631
|
+
if (!response.ok) throw v2Error("knowledge-base search", response, raw2);
|
|
33632
|
+
printResult(
|
|
33633
|
+
JSON.parse(raw2),
|
|
33634
|
+
resolveFormat(flagValue(args, "-o", "--output"))
|
|
33635
|
+
);
|
|
33636
|
+
};
|
|
33637
|
+
|
|
33416
33638
|
// src/commands/dev.ts
|
|
33417
33639
|
import { createHash as createHash3 } from "crypto";
|
|
33418
33640
|
import { watch } from "fs";
|
|
@@ -34112,18 +34334,7 @@ var runFn = async (args) => {
|
|
|
34112
34334
|
`);
|
|
34113
34335
|
}
|
|
34114
34336
|
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
|
-
}
|
|
34337
|
+
if (!res.ok) throw v2Error("fn", res, body);
|
|
34127
34338
|
process.stdout.write(`${body}
|
|
34128
34339
|
`);
|
|
34129
34340
|
};
|
|
@@ -34165,12 +34376,20 @@ var runGraphql = async (args) => {
|
|
|
34165
34376
|
body: JSON.stringify({ query, variables })
|
|
34166
34377
|
}
|
|
34167
34378
|
);
|
|
34168
|
-
const
|
|
34379
|
+
const raw2 = await res.text();
|
|
34380
|
+
const body = (() => {
|
|
34381
|
+
try {
|
|
34382
|
+
return JSON.parse(raw2);
|
|
34383
|
+
} catch {
|
|
34384
|
+
return null;
|
|
34385
|
+
}
|
|
34386
|
+
})();
|
|
34169
34387
|
if (body?.errors != null && body.errors.length > 0) {
|
|
34170
34388
|
throw new Error(body.errors.map((e) => e.message).join("; "));
|
|
34171
34389
|
}
|
|
34172
|
-
if (!res.ok
|
|
34173
|
-
|
|
34390
|
+
if (!res.ok) throw v2Error("graphql", res, raw2);
|
|
34391
|
+
if (body == null) {
|
|
34392
|
+
throw new Error("graphql returned an unreadable body.");
|
|
34174
34393
|
}
|
|
34175
34394
|
printResult(body.data, resolveFormat(flagValue(args, "-o", "--output")));
|
|
34176
34395
|
};
|
|
@@ -34262,71 +34481,6 @@ var runOpen = async (args) => {
|
|
|
34262
34481
|
openBrowser(url);
|
|
34263
34482
|
};
|
|
34264
34483
|
|
|
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
34484
|
// src/commands/printablePage.ts
|
|
34331
34485
|
var runPrintablePage = async (args) => {
|
|
34332
34486
|
const [operation, id] = args;
|
|
@@ -34346,8 +34500,9 @@ var runPrintablePage = async (args) => {
|
|
|
34346
34500
|
body: JSON.stringify({ actionId: "PRINTABLE_PAGE_TO_PDF", inputs: { printablePageId: id, searchParams, includeDiagnostics: true } }),
|
|
34347
34501
|
signal: AbortSignal.timeout(timeoutMs)
|
|
34348
34502
|
});
|
|
34349
|
-
const
|
|
34350
|
-
if (!response.ok) throw
|
|
34503
|
+
const raw2 = await response.text();
|
|
34504
|
+
if (!response.ok) throw v2Error("printable-page render", response, raw2);
|
|
34505
|
+
const body = JSON.parse(raw2);
|
|
34351
34506
|
printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
|
|
34352
34507
|
};
|
|
34353
34508
|
|
|
@@ -34510,6 +34665,7 @@ var resources = {
|
|
|
34510
34665
|
IN: { collection: "integrations", mutation: "updateIntegration", result: "integration", patch: "IntegrationPatch", fields: "id name description isArchived integrationTypeId workspaceId", editable: ["name", "description", "isArchived", "integrationTypeId"] },
|
|
34511
34666
|
TBS: { collection: "tableSpaces", mutation: "updateTableSpace", result: "tableSpace", patch: "TableSpacePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
|
|
34512
34667
|
DS: { collection: "dataStreams", mutation: "updateDataStream", result: "dataStream", patch: "DataStreamPatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
|
|
34668
|
+
KB: { collection: "knowledgeBases", mutation: "updateKnowledgeBase", result: "knowledgeBase", patch: "KnowledgeBasePatch", fields: "id name description isArchived embeddingModel workspaceId", editable: ["name", "description", "isArchived"] },
|
|
34513
34669
|
DF: { collection: "dataFiles", mutation: "updateDataFile", result: "dataFile", patch: "DataFilePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
|
|
34514
34670
|
AR: { collection: "actionRunners", mutation: "updateActionRunner", result: "actionRunner", patch: "ActionRunnerPatch", fields: "id isArchived actionTimeoutSeconds config workspaceId identityId identity { name }", editable: ["isArchived", "actionTimeoutSeconds", "config"] }
|
|
34515
34671
|
};
|
|
@@ -34609,7 +34765,8 @@ deploy\` makes it live. Pick primitives by trigger:
|
|
|
34609
34765
|
- Awaitable server-side logic, callable from pages/automations/agents \u2192 a
|
|
34610
34766
|
**Function** (Deno sandbox, can import from esm.sh, full env SDK).
|
|
34611
34767
|
- Storage: **TableSpaces** (Postgres, via env.TBSxxx) for structured data;
|
|
34612
|
-
**Data Files** (env.DFxxx) for versioned single-file datasets
|
|
34768
|
+
**Data Files** (env.DFxxx) for versioned single-file datasets; **File
|
|
34769
|
+
Buckets** (env.FBxxx) for browsable file collections and SFTP. Prefer
|
|
34613
34770
|
first-class platform features over third-party integrations.
|
|
34614
34771
|
|
|
34615
34772
|
When broken or unexplained platform behavior blocks progress, send a detailed
|
|
@@ -34629,16 +34786,22 @@ column autocomplete; joins/aggregates/projections take a hand-written type or
|
|
|
34629
34786
|
Pick<...>), env.FNxxx.call()
|
|
34630
34787
|
(pass \`path\` to hit a sub-path of a function that routes internally),
|
|
34631
34788
|
env.ATxxx.start(inputs?) (fire-and-forget), env.DFxxx.read.json()/.saveVersion(),
|
|
34789
|
+
env.FBxxx.list()/read(entryId)/upload()/createFolder(),
|
|
34632
34790
|
env.STORAGE.fetch/upload/presign (upload shortens stored names over 128
|
|
34633
|
-
characters in the middle while preserving their ends),
|
|
34791
|
+
characters in the middle while preserving their ends), env.STORAGE.text
|
|
34792
|
+
(best-effort text representation of PDF, DOCX, Excel, HTML, and text files
|
|
34793
|
+
without AI; \`{ vision: true }\` uses AI to represent PDFs or images as text and
|
|
34794
|
+
is required for images), env.STORAGE.csv (one Excel worksheet selected by name
|
|
34795
|
+
or zero-based index), env.STORAGE.image (PNG representation of a raster image,
|
|
34796
|
+
SVG, or single-page PDF),
|
|
34634
34797
|
env.AI.generateText/generateObject,
|
|
34635
34798
|
env.GRAPHQL.request().
|
|
34636
34799
|
|
|
34637
34800
|
Not everything is available everywhere. Functions and automation code nodes
|
|
34638
34801
|
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
|
-
|
|
34802
|
+
then extract only the entries you need, each into its own storage URL. A web
|
|
34803
|
+
page does NOT have these server-side conversion and archive helpers: that work
|
|
34804
|
+
belongs in a function the page calls.`;
|
|
34642
34805
|
var automations = `# Automation best practices
|
|
34643
34806
|
|
|
34644
34807
|
An automation's elements document is the node graph: an array of nodes, each
|
|
@@ -34721,6 +34884,9 @@ language, customTitle, hideTopBar, ...). Push reassembles them.
|
|
|
34721
34884
|
substituted into it (neither {x} nor Liquid {{ x }}). If the data depends on
|
|
34722
34885
|
a search param, fetch it in the page instead. To clear it use JSON null; the
|
|
34723
34886
|
string "null" is a four-character URL that fails at fetch time.
|
|
34887
|
+
- A printable page's print/save-to-PDF filename is the page's own title:
|
|
34888
|
+
customTitle if set, else "<name> - <date>"; page code can assign
|
|
34889
|
+
\`document.title\` at runtime to control it per render.
|
|
34724
34890
|
- Printable page PDFs render in a headless browser that waits for network idle,
|
|
34725
34891
|
so useEffect fetches DO resolve before capture. Load data in the page \u2014 you
|
|
34726
34892
|
don't need to pre-fetch it into searchParams or stage it in storage. A blank
|
|
@@ -35134,11 +35300,7 @@ var runQuery = async (organizationId, tableSpaceId, query, params) => {
|
|
|
35134
35300
|
return null;
|
|
35135
35301
|
}
|
|
35136
35302
|
})();
|
|
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
|
-
}
|
|
35303
|
+
if (!res.ok || body?.ok === false) throw v2Error("sql", res, raw2);
|
|
35142
35304
|
return {
|
|
35143
35305
|
rows: body?.rows ?? [],
|
|
35144
35306
|
rowCount: body?.rowCount ?? 0,
|
|
@@ -35593,20 +35755,9 @@ var runDiff = async (args) => {
|
|
|
35593
35755
|
};
|
|
35594
35756
|
|
|
35595
35757
|
// 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
|
-
};
|
|
35758
|
+
var workspaceIdFrom = (args) => args.find(
|
|
35759
|
+
(arg, index) => !arg.startsWith("-") && args[index - 1] !== "-o" && args[index - 1] !== "--output"
|
|
35760
|
+
) ?? openClone().manifest.workspaceId;
|
|
35610
35761
|
var listWorkspaces = async (args) => {
|
|
35611
35762
|
const archived = args.includes("--archived");
|
|
35612
35763
|
const limit2 = Number(flagValue(args, "--limit") ?? 200);
|
|
@@ -35646,10 +35797,7 @@ var showWorkspace = async (args) => {
|
|
|
35646
35797
|
`Workspace ${workspaceId} not found (or not visible to you).`
|
|
35647
35798
|
);
|
|
35648
35799
|
}
|
|
35649
|
-
printResult(
|
|
35650
|
-
data.workspace,
|
|
35651
|
-
resolveFormat(flagValue(args, "-o", "--output"))
|
|
35652
|
-
);
|
|
35800
|
+
printResult(data.workspace, resolveFormat(flagValue(args, "-o", "--output")));
|
|
35653
35801
|
};
|
|
35654
35802
|
var listWorkspaceUsers = async (args) => {
|
|
35655
35803
|
const workspaceId = workspaceIdFrom(args);
|
|
@@ -35685,9 +35833,7 @@ var listWorkspaceUsers = async (args) => {
|
|
|
35685
35833
|
parentWorkspaceRole: membership.parentWorkspaceRole ?? ""
|
|
35686
35834
|
}
|
|
35687
35835
|
]
|
|
35688
|
-
).sort(
|
|
35689
|
-
(a, b) => (a.name || a.email).localeCompare(b.name || b.email)
|
|
35690
|
-
),
|
|
35836
|
+
).sort((a, b) => (a.name || a.email).localeCompare(b.name || b.email)),
|
|
35691
35837
|
resolveFormat(flagValue(args, "-o", "--output"))
|
|
35692
35838
|
);
|
|
35693
35839
|
};
|
|
@@ -35786,6 +35932,8 @@ Other resources:
|
|
|
35786
35932
|
overai data-stream query <id> --start <date> --end <date> [--query <filter>]
|
|
35787
35933
|
overai data-file upload <id> <path> [-m <message>]
|
|
35788
35934
|
overai data-file download <id> [path|-] | data-file head <id>
|
|
35935
|
+
overai knowledge-base upload <id> <file...>
|
|
35936
|
+
overai knowledge-base search <id> <query> [--limit N]
|
|
35789
35937
|
overai integration configure <id> --config <json|@file|@->
|
|
35790
35938
|
overai integration config <id> Read its masked configuration
|
|
35791
35939
|
overai printable-page render <id> [--search-params <json|@file>]
|
|
@@ -35803,16 +35951,43 @@ it from stdin. Prefer that for anything long or quote-heavy: an inline value is
|
|
|
35803
35951
|
parsed by your shell first, and one apostrophe inside it silently truncates the
|
|
35804
35952
|
rest. Write @@ to send a literal value that starts with "@".
|
|
35805
35953
|
|
|
35954
|
+
Organizations: commands run as the clone you're standing in (.overai/manifest.json),
|
|
35955
|
+
else the active org from \`org switch\`. The active org is machine-global \u2014 every
|
|
35956
|
+
shell shares it \u2014 so scope one command or one shell with OVERAI_ORG_ID=<orgId>
|
|
35957
|
+
instead. \`overai whoami\` says which org is in effect and why.
|
|
35958
|
+
|
|
35806
35959
|
Output: table on a TTY, JSON when piped; -o json|table|csv to force.
|
|
35807
35960
|
Aliases: login = signin, logout = signout, ws = workspace.
|
|
35808
35961
|
Env: OVERAI_API_URL, OVERAI_APP_URL override the target deployment.
|
|
35962
|
+
OVERAI_ORG_ID overrides the organization for this shell.
|
|
35809
35963
|
`;
|
|
35810
35964
|
process.stdout.on("error", (error) => {
|
|
35811
35965
|
if (error.code === "EPIPE") process.exit(0);
|
|
35812
35966
|
throw error;
|
|
35813
35967
|
});
|
|
35968
|
+
var ORG_AGNOSTIC_COMMANDS = /* @__PURE__ */ new Set([
|
|
35969
|
+
"signin",
|
|
35970
|
+
"login",
|
|
35971
|
+
"signout",
|
|
35972
|
+
"logout",
|
|
35973
|
+
"whoami",
|
|
35974
|
+
"org",
|
|
35975
|
+
"clone",
|
|
35976
|
+
"update",
|
|
35977
|
+
"upgrade",
|
|
35978
|
+
"version",
|
|
35979
|
+
"--version",
|
|
35980
|
+
"-v",
|
|
35981
|
+
"help",
|
|
35982
|
+
"--help",
|
|
35983
|
+
"-h"
|
|
35984
|
+
]);
|
|
35814
35985
|
var run = async () => {
|
|
35815
35986
|
const [command, ...rest] = process.argv.slice(2);
|
|
35987
|
+
if (command != null && !ORG_AGNOSTIC_COMMANDS.has(command)) {
|
|
35988
|
+
pinOrgFromClone();
|
|
35989
|
+
announceOrgScope();
|
|
35990
|
+
}
|
|
35816
35991
|
switch (command) {
|
|
35817
35992
|
case "signin":
|
|
35818
35993
|
case "login":
|
|
@@ -35823,7 +35998,7 @@ var run = async () => {
|
|
|
35823
35998
|
await signOut();
|
|
35824
35999
|
return;
|
|
35825
36000
|
case "whoami":
|
|
35826
|
-
whoami();
|
|
36001
|
+
await whoami();
|
|
35827
36002
|
return;
|
|
35828
36003
|
case "org":
|
|
35829
36004
|
if (rest[0] === "list") {
|
|
@@ -35907,6 +36082,9 @@ var run = async () => {
|
|
|
35907
36082
|
case "data-stream":
|
|
35908
36083
|
await runDataStream(rest);
|
|
35909
36084
|
return;
|
|
36085
|
+
case "knowledge-base":
|
|
36086
|
+
await runKnowledgeBase(rest);
|
|
36087
|
+
return;
|
|
35910
36088
|
case "data-file":
|
|
35911
36089
|
await runDataFile(rest);
|
|
35912
36090
|
return;
|
|
@@ -59,6 +59,7 @@ var ServiceEnum = /* @__PURE__ */ ((ServiceEnum2) => {
|
|
|
59
59
|
ServiceEnum2["Http"] = "HTTP";
|
|
60
60
|
ServiceEnum2["HybridAnalysis"] = "HYBRID_ANALYSIS";
|
|
61
61
|
ServiceEnum2["Jira"] = "JIRA";
|
|
62
|
+
ServiceEnum2["KnowledgeBases"] = "KNOWLEDGE_BASES";
|
|
62
63
|
ServiceEnum2["Linkedin"] = "LINKEDIN";
|
|
63
64
|
ServiceEnum2["LocalNetwork"] = "LOCAL_NETWORK";
|
|
64
65
|
ServiceEnum2["MicrosoftDefender"] = "MICROSOFT_DEFENDER";
|
|
@@ -293,6 +294,7 @@ var NodeEnum = /* @__PURE__ */ ((NodeEnum2) => {
|
|
|
293
294
|
NodeEnum2["saveToDataFile"] = "SAVE_TO_DATA_FILE";
|
|
294
295
|
NodeEnum2["screenshotWebpage"] = "SCREENSHOT_WEBPAGE";
|
|
295
296
|
NodeEnum2["searchCisaKevs"] = "SEARCH_CISA_KEVS";
|
|
297
|
+
NodeEnum2["searchKnowledgeBase"] = "SEARCH_KNOWLEDGE_BASE";
|
|
296
298
|
NodeEnum2["sendEmail"] = "SEND_EMAIL";
|
|
297
299
|
NodeEnum2["sendRequest"] = "SEND_REQUEST";
|
|
298
300
|
NodeEnum2["sentinelOneAction"] = "SENTINEL_ONE_ACTION";
|