@overaihq/cli 0.14.11 → 0.14.12

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.
Files changed (2) hide show
  1. package/dist/index.js +1187 -772
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -52345,6 +52345,317 @@ var exchangeSessionToken = (baseUrl, refreshToken, destinationOrgId) => unauthen
52345
52345
  destinationOrgId
52346
52346
  });
52347
52347
 
52348
+ // ../sdk/src/error.ts
52349
+ var OverAIError = class extends Error {
52350
+ /** HTTP status; 200 for a GraphQL errors-array failure. */
52351
+ status;
52352
+ /** URL pathname of the request, "" when unknown. */
52353
+ path;
52354
+ /** Parsed JSON body, the raw string when not JSON, or null. */
52355
+ body;
52356
+ /** The org the request ran as, when known. */
52357
+ organizationId;
52358
+ /** GraphQL errors array, when that is the cause. */
52359
+ errors;
52360
+ constructor(message, fields) {
52361
+ super(message);
52362
+ this.status = fields.status;
52363
+ this.path = fields.path;
52364
+ this.body = fields.body;
52365
+ this.organizationId = fields.organizationId;
52366
+ if (fields.errors != null) this.errors = fields.errors;
52367
+ }
52368
+ };
52369
+ var responsePath = (res) => {
52370
+ try {
52371
+ return new URL(res.url).pathname;
52372
+ } catch {
52373
+ return "";
52374
+ }
52375
+ };
52376
+ var STATUS_TEXT = {
52377
+ 400: "Bad Request",
52378
+ 401: "Unauthorized",
52379
+ 403: "Forbidden",
52380
+ 404: "Not Found",
52381
+ 409: "Conflict",
52382
+ 413: "Payload Too Large",
52383
+ 429: "Too Many Requests",
52384
+ 500: "Internal Server Error",
52385
+ 503: "Service Unavailable"
52386
+ };
52387
+ var apiError = (label, res, rawBody, organizationId) => {
52388
+ const body = (() => {
52389
+ try {
52390
+ return JSON.parse(rawBody);
52391
+ } catch {
52392
+ return rawBody;
52393
+ }
52394
+ })();
52395
+ const structured = typeof body === "object" && body != null ? body : null;
52396
+ const field = structured?.error ?? structured?.message;
52397
+ const claimed = (typeof field === "string" ? field : rawBody).trim().slice(0, 500);
52398
+ const reason = claimed.length === 0 || claimed === "Error" || claimed === "null" || claimed === "undefined" || claimed.toLowerCase() === STATUS_TEXT[res.status]?.toLowerCase() ? null : claimed;
52399
+ const path = responsePath(res);
52400
+ const fields = { status: res.status, path, body, organizationId };
52401
+ if (reason != null) return new OverAIError(reason, fields);
52402
+ return new OverAIError(
52403
+ `${label}: HTTP ${String(res.status)}, no reason given by the server.${path === "" ? "" : `
52404
+ ${path}`}${organizationId == null ? "" : `
52405
+ Asked as org ${organizationId}.`}`,
52406
+ fields
52407
+ );
52408
+ };
52409
+
52410
+ // ../sdk/src/agentRun.ts
52411
+ var agentRun = (client, id) => {
52412
+ const deployedVersionNumber = async () => {
52413
+ const deployed = await client.graphql(
52414
+ `query SdkAgentDeployedVersion($id: String!) {
52415
+ agentDeployedVersions(condition: { agentId: $id }) { nodes { versionNumber } }
52416
+ }`,
52417
+ { id }
52418
+ );
52419
+ const versionNumber = deployed.agentDeployedVersions?.nodes[0]?.versionNumber;
52420
+ if (versionNumber == null) {
52421
+ throw new Error(
52422
+ `Agent ${id} has no deployed version; pass --version <n> to inspect a saved one.`
52423
+ );
52424
+ }
52425
+ return versionNumber;
52426
+ };
52427
+ return {
52428
+ generate: async (message) => {
52429
+ const organizationId = await client.organizationId();
52430
+ const res = await client.fetch(
52431
+ `/v2/agents/${organizationId}/${id}/generate/text`,
52432
+ {
52433
+ method: "POST",
52434
+ headers: { "Content-Type": "application/json" },
52435
+ body: JSON.stringify({ message })
52436
+ }
52437
+ );
52438
+ const raw2 = await res.text();
52439
+ if (!res.ok) throw apiError("agent generate", res, raw2, organizationId);
52440
+ return JSON.parse(raw2);
52441
+ },
52442
+ /*
52443
+ * What an agent can actually do is spread over five bindings and a model,
52444
+ * and nothing in the product shows it in one place.
52445
+ */
52446
+ tools: async (ref = "deployed") => {
52447
+ const version2 = typeof ref === "number" ? ref : ref === "latest" ? (await client.agent(id).head()).latestVersion : await deployedVersionNumber();
52448
+ const data = await client.graphql(
52449
+ `query SdkAgentTools($id: String!, $version: Int!) {
52450
+ agent(id: $id) {
52451
+ name
52452
+ agentVersions(first: 1, condition: { versionNumber: $version }) {
52453
+ nodes {
52454
+ versionNumber
52455
+ model
52456
+ agentVersionFunctionsByAgentIdAndVersionNumber(orderBy: [FUNCTION_ID_ASC]) {
52457
+ nodes { functionId function { name } }
52458
+ }
52459
+ agentVersionTableSpacesByAgentIdAndVersionNumber(orderBy: [TABLE_SPACE_ID_ASC]) {
52460
+ nodes { tableSpaceId accessMode }
52461
+ }
52462
+ agentVersionAgentsByAgentIdAndVersionNumber(orderBy: [ATTACHED_AGENT_ID_ASC]) {
52463
+ nodes { attachedAgentId }
52464
+ }
52465
+ agentVersionKnowledgeBasesByAgentIdAndVersionNumber(orderBy: [KNOWLEDGE_BASE_ID_ASC]) {
52466
+ nodes { knowledgeBaseId }
52467
+ }
52468
+ agentVersionBuiltinToolSetsByAgentIdAndVersionNumber(orderBy: [TOOL_SET_ASC]) {
52469
+ nodes { toolSet }
52470
+ }
52471
+ }
52472
+ }
52473
+ }
52474
+ }`,
52475
+ { id, version: version2 }
52476
+ );
52477
+ if (data.agent == null) throw new Error(`Agent ${id} not found.`);
52478
+ const agentVersion = data.agent.agentVersions.nodes[0];
52479
+ if (agentVersion == null) {
52480
+ throw new Error(`Agent ${id} has no version ${String(version2)}.`);
52481
+ }
52482
+ return {
52483
+ agent: data.agent.name,
52484
+ version: agentVersion.versionNumber,
52485
+ model: agentVersion.model,
52486
+ tools: [
52487
+ ...agentVersion.agentVersionFunctionsByAgentIdAndVersionNumber.nodes.map(
52488
+ (link) => ({
52489
+ kind: "function",
52490
+ name: link.function?.name ?? link.functionId,
52491
+ detail: link.functionId
52492
+ })
52493
+ ),
52494
+ ...agentVersion.agentVersionTableSpacesByAgentIdAndVersionNumber.nodes.map(
52495
+ (link) => ({
52496
+ kind: "table space",
52497
+ name: link.tableSpaceId,
52498
+ detail: link.accessMode
52499
+ })
52500
+ ),
52501
+ ...agentVersion.agentVersionAgentsByAgentIdAndVersionNumber.nodes.map(
52502
+ (link) => ({
52503
+ kind: "sub-agent",
52504
+ name: link.attachedAgentId,
52505
+ detail: ""
52506
+ })
52507
+ ),
52508
+ ...agentVersion.agentVersionKnowledgeBasesByAgentIdAndVersionNumber.nodes.map(
52509
+ (link) => ({
52510
+ kind: "knowledge base",
52511
+ name: link.knowledgeBaseId,
52512
+ detail: ""
52513
+ })
52514
+ ),
52515
+ ...agentVersion.agentVersionBuiltinToolSetsByAgentIdAndVersionNumber.nodes.map(
52516
+ (link) => ({
52517
+ kind: "built-in",
52518
+ name: link.toolSet,
52519
+ detail: ""
52520
+ })
52521
+ )
52522
+ ]
52523
+ };
52524
+ },
52525
+ /* A caller that wants a second turn must create the conversation first — as the webapp does. */
52526
+ createConversation: async (title) => {
52527
+ const versionNumber = await deployedVersionNumber();
52528
+ const created = await client.graphql(
52529
+ `mutation SdkCreateAgentConversation($input: CreateAgentConversationInput!) {
52530
+ createAgentConversation(input: $input) { agentConversation { id } }
52531
+ }`,
52532
+ {
52533
+ input: {
52534
+ agentConversation: {
52535
+ agentId: id,
52536
+ versionNumber,
52537
+ title: title.length > 50 ? `${title.slice(0, 47)}...` : title
52538
+ }
52539
+ }
52540
+ }
52541
+ );
52542
+ const conversationId = created.createAgentConversation?.agentConversation?.id;
52543
+ if (conversationId == null)
52544
+ throw new Error("Failed to create a conversation.");
52545
+ return conversationId;
52546
+ },
52547
+ chat: async (messages, options) => {
52548
+ const organizationId = await client.organizationId();
52549
+ const res = await client.fetch(`/v2/agents/${organizationId}/${id}`, {
52550
+ method: "POST",
52551
+ headers: { "Content-Type": "application/json" },
52552
+ body: JSON.stringify({
52553
+ messages,
52554
+ conversationId: options.conversationId
52555
+ })
52556
+ });
52557
+ if (!res.ok)
52558
+ throw apiError("agent chat", res, await res.text(), organizationId);
52559
+ return res;
52560
+ }
52561
+ };
52562
+ };
52563
+ var agentStreamEvents = (response) => {
52564
+ const parse4 = (line) => {
52565
+ if (!line.startsWith("data: ")) return null;
52566
+ const payload = line.slice(6);
52567
+ if (payload === "[DONE]") return "done";
52568
+ const event = (() => {
52569
+ try {
52570
+ return JSON.parse(payload);
52571
+ } catch {
52572
+ return null;
52573
+ }
52574
+ })();
52575
+ if (event?.type === "text-delta" && event.delta != null)
52576
+ return { type: "text-delta", delta: event.delta };
52577
+ if (event?.type === "error")
52578
+ return event.errorText == null ? { type: "error" } : { type: "error", errorText: event.errorText };
52579
+ return null;
52580
+ };
52581
+ return (async function* () {
52582
+ const body = response.body;
52583
+ if (body == null) return;
52584
+ const decoder = new TextDecoder();
52585
+ const reader = body.getReader();
52586
+ let buffer = "";
52587
+ for (; ; ) {
52588
+ const { value, done } = await reader.read();
52589
+ if (done) break;
52590
+ buffer += decoder.decode(value, { stream: true });
52591
+ const lines = buffer.split("\n");
52592
+ buffer = lines.pop() ?? "";
52593
+ for (const line of lines) {
52594
+ const event = parse4(line);
52595
+ if (event === "done") return;
52596
+ if (event != null) yield event;
52597
+ }
52598
+ }
52599
+ const last2 = parse4(buffer + decoder.decode());
52600
+ if (last2 != null && last2 !== "done") yield last2;
52601
+ })();
52602
+ };
52603
+
52604
+ // ../sdk/src/automationRun.ts
52605
+ var automationRunApi = (client, id) => ({
52606
+ run: async (inputs) => {
52607
+ const organizationId = await client.organizationId();
52608
+ const res = await client.fetch(
52609
+ `/v2/automations/${organizationId}/${id}/run`,
52610
+ {
52611
+ method: "POST",
52612
+ headers: { "Content-Type": "application/json" },
52613
+ body: JSON.stringify(inputs ?? {})
52614
+ }
52615
+ );
52616
+ const raw2 = await res.text();
52617
+ if (!res.ok) throw apiError("automation run", res, raw2, organizationId);
52618
+ return JSON.parse(raw2);
52619
+ },
52620
+ /*
52621
+ * The v2 condition filters only by automationId; status filters apply
52622
+ * here (the condition type has no errored/isCancelled fields), so a
52623
+ * filtered read over-fetches to still fill the limit.
52624
+ */
52625
+ runs: async (options) => {
52626
+ const limit2 = options?.limit ?? 20;
52627
+ const filtered = options?.failed === true || options?.running === true;
52628
+ const data = await client.graphql(
52629
+ `query SdkAutomationRuns($automationId: String!, $first: Int!) {
52630
+ automationRuns(condition: { automationId: $automationId }, orderBy: [STARTED_AT_DESC], first: $first) {
52631
+ nodes { id startedAt endedAt errored isCancelled manuallyTriggered version { num } }
52632
+ }
52633
+ }`,
52634
+ { automationId: id, first: filtered ? limit2 * 5 : limit2 }
52635
+ );
52636
+ return data.automationRuns.nodes.filter((r) => options?.failed !== true || r.errored).filter(
52637
+ (r) => options?.running !== true || r.endedAt == null && !r.isCancelled
52638
+ ).slice(0, limit2).map((r) => ({
52639
+ id: r.id,
52640
+ version: r.version?.num,
52641
+ startedAt: r.startedAt,
52642
+ endedAt: r.endedAt,
52643
+ status: r.errored ? "errored" : r.isCancelled ? "cancelled" : r.endedAt == null ? "running" : "ok",
52644
+ manual: r.manuallyTriggered
52645
+ }));
52646
+ }
52647
+ });
52648
+ var automationRunState = async (client, runId) => {
52649
+ const data = await client.graphql(
52650
+ `query SdkAutomationRunState($id: String!) {
52651
+ automationRun(id: $id) { state }
52652
+ }`,
52653
+ { id: runId }
52654
+ );
52655
+ if (data.automationRun == null) throw new Error(`Run ${runId} not found.`);
52656
+ return data.automationRun.state ?? {};
52657
+ };
52658
+
52348
52659
  // ../common/src/agent.ts
52349
52660
  var agentVersionConfigSchema = external_exports.object({
52350
52661
  systemPrompt: external_exports.string(),
@@ -58547,6 +58858,81 @@ var createDataFile = async (client, input2) => {
58547
58858
  return { id };
58548
58859
  };
58549
58860
 
58861
+ // ../sdk/src/dataFiles.ts
58862
+ var dataFileResource = (client, id) => ({
58863
+ read: async () => {
58864
+ const organizationId = await client.organizationId();
58865
+ const res = await client.fetch(`/v2/data-files/${organizationId}/${id}`, {
58866
+ redirect: "follow"
58867
+ });
58868
+ if (!res.ok)
58869
+ throw apiError(
58870
+ "data-file download",
58871
+ res,
58872
+ await res.text(),
58873
+ organizationId
58874
+ );
58875
+ return res;
58876
+ },
58877
+ head: async (options) => {
58878
+ const organizationId = await client.organizationId();
58879
+ const res = await client.fetch(
58880
+ `/v2/data-files/${organizationId}/${id}/head?numLines=${String(options?.lines ?? 50)}`,
58881
+ { redirect: "follow" }
58882
+ );
58883
+ if (!res.ok)
58884
+ throw apiError("data-file head", res, await res.text(), organizationId);
58885
+ return res;
58886
+ },
58887
+ upload: async (content, options) => {
58888
+ const url2 = await client.trpc("dataFiles.getDataFileUploadUrl", {
58889
+ dataFileId: id,
58890
+ fileSize: content.size,
58891
+ message: options?.message ?? ""
58892
+ });
58893
+ const res = await fetch(url2, { method: "PUT", body: content });
58894
+ if (!res.ok)
58895
+ throw apiError(
58896
+ "data-file upload",
58897
+ res,
58898
+ await res.text(),
58899
+ await client.organizationId()
58900
+ );
58901
+ }
58902
+ });
58903
+
58904
+ // ../sdk/src/dataStreams.ts
58905
+ var dataStreamResource = (client, id) => ({
58906
+ append: async (records) => {
58907
+ const organizationId = await client.organizationId();
58908
+ const res = await client.fetch(`/v1/data-streams/${organizationId}/${id}`, {
58909
+ method: "POST",
58910
+ headers: { "Content-Type": "application/json" },
58911
+ body: JSON.stringify({
58912
+ data: Array.isArray(records) ? records : [records]
58913
+ })
58914
+ });
58915
+ const raw2 = await res.text();
58916
+ if (!res.ok) throw apiError("data-stream append", res, raw2, organizationId);
58917
+ return JSON.parse(raw2);
58918
+ },
58919
+ query: async (options) => {
58920
+ const organizationId = await client.organizationId();
58921
+ const search2 = new URLSearchParams({
58922
+ startAt: options.startAt,
58923
+ endAt: options.endAt,
58924
+ query: options.query ?? ""
58925
+ });
58926
+ if (options.limit != null) search2.set("limit", String(options.limit));
58927
+ const res = await client.fetch(
58928
+ `/v1/data-streams/${organizationId}/${id}?${search2.toString()}`
58929
+ );
58930
+ const raw2 = await res.text();
58931
+ if (!res.ok) throw apiError("data-stream query", res, raw2, organizationId);
58932
+ return JSON.parse(raw2);
58933
+ }
58934
+ });
58935
+
58550
58936
  // ../../node_modules/.pnpm/diff@9.0.0/node_modules/diff/libesm/diff/base.js
58551
58937
  var Diff = class {
58552
58938
  diff(oldStr, newStr, options = {}) {
@@ -60392,67 +60778,106 @@ var functionResource = (client, id) => {
60392
60778
  };
60393
60779
  };
60394
60780
 
60395
- // ../sdk/src/error.ts
60396
- var OverAIError = class extends Error {
60397
- /** HTTP status; 200 for a GraphQL errors-array failure. */
60398
- status;
60399
- /** URL pathname of the request, "" when unknown. */
60400
- path;
60401
- /** Parsed JSON body, the raw string when not JSON, or null. */
60402
- body;
60403
- /** The org the request ran as, when known. */
60404
- organizationId;
60405
- /** GraphQL errors array, when that is the cause. */
60406
- errors;
60407
- constructor(message, fields) {
60408
- super(message);
60409
- this.status = fields.status;
60410
- this.path = fields.path;
60411
- this.body = fields.body;
60412
- this.organizationId = fields.organizationId;
60413
- if (fields.errors != null) this.errors = fields.errors;
60414
- }
60415
- };
60416
- var responsePath = (res) => {
60417
- try {
60418
- return new URL(res.url).pathname;
60419
- } catch {
60420
- return "";
60781
+ // ../sdk/src/functionRun.ts
60782
+ var functionRun = (client, id) => ({
60783
+ /*
60784
+ * Mirrors `env.FNxxx.call` (common-server envProxy `__callFunction`), so a
60785
+ * caller moving between the sandbox and the SDK keeps one mental model.
60786
+ */
60787
+ call: async (init) => {
60788
+ const { path: rawPath = "", query = {}, body, ...rest } = init ?? {};
60789
+ const queryStart = rawPath.indexOf("?");
60790
+ const pathOnly = queryStart === -1 ? rawPath : rawPath.slice(0, queryStart);
60791
+ const subPath = pathOnly === "" || pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
60792
+ const params = new URLSearchParams(
60793
+ queryStart === -1 ? "" : rawPath.slice(queryStart + 1)
60794
+ );
60795
+ Object.entries(query).forEach(([name2, value]) => {
60796
+ params.set(name2, value);
60797
+ });
60798
+ const search2 = params.toString();
60799
+ const headers = new Headers(rest.headers);
60800
+ const isNativeBody = typeof body === "string" || body instanceof Blob || body instanceof FormData || body instanceof URLSearchParams || body instanceof ArrayBuffer || ArrayBuffer.isView(body) || body instanceof ReadableStream;
60801
+ if (body != null && !isNativeBody && !headers.has("Content-Type"))
60802
+ headers.set("Content-Type", "application/json");
60803
+ return client.fetch(
60804
+ `/v2/functions/${await client.organizationId()}/${id}${subPath}${search2 === "" ? "" : `?${search2}`}`,
60805
+ {
60806
+ ...rest,
60807
+ method: rest.method ?? "POST",
60808
+ headers,
60809
+ body: body == null ? void 0 : isNativeBody ? body : JSON.stringify(body)
60810
+ }
60811
+ );
60812
+ },
60813
+ executions: async (options) => (await client.graphql(
60814
+ `query SdkFunctionExecutions($functionId: String!, $first: Int!) {
60815
+ functionExecutions(condition: { functionId: $functionId }, orderBy: [CREATED_AT_DESC], first: $first) {
60816
+ nodes { id createdAt httpStatusCode executionTime requestMethod requestPath versionNumber }
60817
+ }
60818
+ }`,
60819
+ { functionId: id, first: options?.limit ?? 20 }
60820
+ )).functionExecutions.nodes,
60821
+ // Logs and bodies live behind presigned S3 URLs (valid ~1h); they carry
60822
+ // their own auth, so they go through the global fetch with no token.
60823
+ execution: async (executionId) => {
60824
+ const data = await client.graphql(
60825
+ `query SdkFunctionExecution($functionId: String!, $id: String!) {
60826
+ functionExecutions(condition: { functionId: $functionId, id: $id }, first: 1) {
60827
+ nodes { id summary createdAt httpStatusCode executionTime versionNumber logsUrl inputBodyUrl outputBodyUrl }
60828
+ }
60829
+ }`,
60830
+ { functionId: id, id: executionId }
60831
+ );
60832
+ const execution = data.functionExecutions.nodes[0];
60833
+ if (execution == null)
60834
+ throw new Error(`Execution ${executionId} not found.`);
60835
+ const [logs, input2, output2] = await Promise.all(
60836
+ [execution.logsUrl, execution.inputBodyUrl, execution.outputBodyUrl].map(
60837
+ async (url2) => url2 == null ? null : await fetch(url2).then((r) => r.ok ? r.text() : null)
60838
+ )
60839
+ );
60840
+ return {
60841
+ id: execution.id,
60842
+ createdAt: execution.createdAt,
60843
+ httpStatusCode: execution.httpStatusCode,
60844
+ executionTime: execution.executionTime,
60845
+ versionNumber: execution.versionNumber,
60846
+ summary: execution.summary,
60847
+ input: input2 ?? null,
60848
+ output: output2 ?? null,
60849
+ logs: logs ?? null
60850
+ };
60421
60851
  }
60422
- };
60423
- var STATUS_TEXT = {
60424
- 400: "Bad Request",
60425
- 401: "Unauthorized",
60426
- 403: "Forbidden",
60427
- 404: "Not Found",
60428
- 409: "Conflict",
60429
- 413: "Payload Too Large",
60430
- 429: "Too Many Requests",
60431
- 500: "Internal Server Error",
60432
- 503: "Service Unavailable"
60433
- };
60434
- var apiError = (label, res, rawBody, organizationId) => {
60435
- const body = (() => {
60436
- try {
60437
- return JSON.parse(rawBody);
60438
- } catch {
60439
- return rawBody;
60440
- }
60441
- })();
60442
- const structured = typeof body === "object" && body != null ? body : null;
60443
- const field = structured?.error ?? structured?.message;
60444
- const claimed = (typeof field === "string" ? field : rawBody).trim().slice(0, 500);
60445
- const reason = claimed.length === 0 || claimed === "Error" || claimed === "null" || claimed === "undefined" || claimed.toLowerCase() === STATUS_TEXT[res.status]?.toLowerCase() ? null : claimed;
60446
- const path = responsePath(res);
60447
- const fields = { status: res.status, path, body, organizationId };
60448
- if (reason != null) return new OverAIError(reason, fields);
60449
- return new OverAIError(
60450
- `${label}: HTTP ${String(res.status)}, no reason given by the server.${path === "" ? "" : `
60451
- ${path}`}${organizationId == null ? "" : `
60452
- Asked as org ${organizationId}.`}`,
60453
- fields
60454
- );
60455
- };
60852
+ });
60853
+
60854
+ // ../sdk/src/integrations.ts
60855
+ var integrationResource = (client, id) => ({
60856
+ configure: async (value) => {
60857
+ await client.trpc("putIntegrationConfig", { id, value });
60858
+ },
60859
+ // Config reads are for inspection, not secret export; keep credentials out
60860
+ // of terminals, shell history captures, and agent transcripts.
60861
+ config: () => client.trpc("getMaskedIntegrationConfig", { id }),
60862
+ setSecret: async (key, value) => {
60863
+ await client.graphql(
60864
+ `mutation SdkSetIntegrationSecret($input: UpdateIntegrationConfigInput!) {
60865
+ updateIntegrationConfig(input: $input) { success }
60866
+ }`,
60867
+ { input: { integrationId: id, partialConfig: { [key]: value } } }
60868
+ );
60869
+ },
60870
+ // The merge mutation stores a JSON null for `{key: null}`, so removal is its
60871
+ // own mutation server-side.
60872
+ unsetSecret: async (key) => {
60873
+ await client.graphql(
60874
+ `mutation SdkUnsetIntegrationSecret($input: DeleteIntegrationConfigKeyInput!) {
60875
+ deleteIntegrationConfigKey(input: $input) { success }
60876
+ }`,
60877
+ { input: { integrationId: id, key } }
60878
+ );
60879
+ }
60880
+ });
60456
60881
 
60457
60882
  // ../sdk/src/jwt.ts
60458
60883
  var decodeJwtClaims = (token) => {
@@ -60470,6 +60895,112 @@ var decodeJwtClaims = (token) => {
60470
60895
  }
60471
60896
  };
60472
60897
 
60898
+ // ../sdk/src/knowledgeBases.ts
60899
+ var knowledgeBaseResource = (client, id) => ({
60900
+ upload: async (file2, name2) => {
60901
+ const organizationId = await client.organizationId();
60902
+ const formData = new FormData();
60903
+ formData.append("file", file2, name2);
60904
+ const res = await client.fetch(
60905
+ `/v2/knowledge-bases/${organizationId}/${id}/upload`,
60906
+ { method: "POST", body: formData }
60907
+ );
60908
+ const raw2 = await res.text();
60909
+ if (!res.ok)
60910
+ throw apiError("knowledge-base upload", res, raw2, organizationId);
60911
+ return JSON.parse(raw2);
60912
+ },
60913
+ search: async (query, options) => {
60914
+ const organizationId = await client.organizationId();
60915
+ const res = await client.fetch(
60916
+ `/v2/knowledge-bases/${organizationId}/${id}/search`,
60917
+ {
60918
+ method: "POST",
60919
+ headers: { "Content-Type": "application/json" },
60920
+ body: JSON.stringify({
60921
+ query,
60922
+ ...options?.limit != null ? { limit: options.limit } : {}
60923
+ })
60924
+ }
60925
+ );
60926
+ const raw2 = await res.text();
60927
+ if (!res.ok)
60928
+ throw apiError("knowledge-base search", res, raw2, organizationId);
60929
+ return JSON.parse(raw2);
60930
+ }
60931
+ });
60932
+
60933
+ // ../sdk/src/lint.ts
60934
+ var lint = async (client, input2) => {
60935
+ const res = await client.fetch("/v2/architect/lint", {
60936
+ method: "POST",
60937
+ headers: { "Content-Type": "application/json" },
60938
+ body: JSON.stringify(input2)
60939
+ });
60940
+ const raw2 = await res.text();
60941
+ if (!res.ok) throw apiError("lint", res, raw2, await client.organizationId());
60942
+ const parsed = lintResponseSchema.safeParse(
60943
+ (() => {
60944
+ try {
60945
+ return JSON.parse(raw2);
60946
+ } catch {
60947
+ return null;
60948
+ }
60949
+ })()
60950
+ );
60951
+ if (!parsed.success)
60952
+ throw new OverAIError("lint: invalid response from lint service", {
60953
+ status: res.status,
60954
+ path: responsePath(res),
60955
+ body: raw2,
60956
+ organizationId: await client.organizationId()
60957
+ });
60958
+ return parsed.data;
60959
+ };
60960
+
60961
+ // ../sdk/src/printablePageRender.ts
60962
+ var printablePageRender = (client, id) => ({
60963
+ render: async (options) => {
60964
+ const data = await client.graphql(
60965
+ `query SdkPrintablePageWorkspace($id: String!) { printablePage(id: $id) { workspaceId } }`,
60966
+ { id }
60967
+ );
60968
+ if (data.printablePage == null)
60969
+ throw new Error(`Printable page ${id} not found.`);
60970
+ const organizationId = await client.organizationId();
60971
+ const res = await client.fetch(
60972
+ `/v2/actions/${organizationId}/${data.printablePage.workspaceId}/run`,
60973
+ {
60974
+ method: "POST",
60975
+ headers: { "Content-Type": "application/json" },
60976
+ body: JSON.stringify({
60977
+ actionId: "PRINTABLE_PAGE_TO_PDF",
60978
+ inputs: {
60979
+ printablePageId: id,
60980
+ searchParams: options?.searchParams ?? "{}",
60981
+ includeDiagnostics: true
60982
+ }
60983
+ }),
60984
+ signal: AbortSignal.timeout(options?.timeoutMs ?? 6e4)
60985
+ }
60986
+ );
60987
+ const raw2 = await res.text();
60988
+ if (!res.ok)
60989
+ throw apiError("printable-page render", res, raw2, organizationId);
60990
+ return JSON.parse(raw2);
60991
+ }
60992
+ });
60993
+
60994
+ // ../sdk/src/report.ts
60995
+ var report = async (client, kind, details, options) => {
60996
+ await client.trpc("architectIssues.report", {
60997
+ feedbackType: kind,
60998
+ detailedBugReport: details,
60999
+ source: options?.source ?? "cli",
61000
+ cliContext: options?.cliContext
61001
+ });
61002
+ };
61003
+
60473
61004
  // ../common/src/random/index.ts
60474
61005
  var UNMISTAKABLE_CHARS = "0123456789abcdefghjkmnpqrstvwxyz";
60475
61006
  var nanoid4 = customAlphabet(UNMISTAKABLE_CHARS, 12);
@@ -60514,6 +61045,7 @@ var ID_PREFIXES = {
60514
61045
  automation_email_alert: { prefix: "aes", body: 10 },
60515
61046
  automation_error_alert_queue: { prefix: "aeaq", body: 10 },
60516
61047
  billing_period: { prefix: "bpd", body: 12 },
61048
+ billing_term: { prefix: "btm", body: 12 },
60517
61049
  browser_automation: { prefix: "bra", body: 10 },
60518
61050
  browser_automation_run: { prefix: "brr", body: 20 },
60519
61051
  browser_session_usage: { prefix: "bsu", body: 12 },
@@ -60785,6 +61317,301 @@ var genericResource = (client, id) => {
60785
61317
  };
60786
61318
  };
60787
61319
 
61320
+ // ../sdk/src/runners.ts
61321
+ var runnerCollection = (client) => ({
61322
+ /*
61323
+ * Two steps, same as the webapp: createMachineIdentity mints the identity
61324
+ * and binds it to the active org atomically — a plain createIdentity cannot
61325
+ * RETURN a row not yet in the caller's org — then the runner is created in
61326
+ * the workspace.
61327
+ */
61328
+ create: async (input2) => {
61329
+ const identityResult = await client.graphql(
61330
+ `mutation SdkCreateMachineIdentity($name: String!) {
61331
+ createMachineIdentity(input: { name: $name }) {
61332
+ identity { id }
61333
+ }
61334
+ }`,
61335
+ { name: input2.name ?? "Action Runner" }
61336
+ );
61337
+ const identityId = identityResult.createMachineIdentity?.identity?.id;
61338
+ if (identityId == null)
61339
+ throw new Error("Failed to create machine identity");
61340
+ const runnerResult = await client.graphql(
61341
+ `mutation SdkCreateActionRunner($identityId: String!, $workspaceId: String!) {
61342
+ createActionRunner(
61343
+ input: { actionRunner: { identityId: $identityId, workspaceId: $workspaceId } }
61344
+ ) { actionRunner { id } }
61345
+ }`,
61346
+ { identityId, workspaceId: input2.workspaceId }
61347
+ );
61348
+ const actionRunnerId = runnerResult.createActionRunner?.actionRunner?.id;
61349
+ if (actionRunnerId == null)
61350
+ throw new Error("Failed to create action runner");
61351
+ return { actionRunnerId, identityId };
61352
+ },
61353
+ // An explicit null in a PostGraphile condition means IS NULL, so the key is
61354
+ // left out when no workspace is given and the whole org lists.
61355
+ list: async (options) => {
61356
+ const data = await client.graphql(
61357
+ `query SdkRunnerList($condition: ActionRunnerCondition!, $first: Int!) {
61358
+ actionRunners(condition: $condition, first: $first) {
61359
+ nodes { id identity { name } workspaceId isCloud isArchived createdAt }
61360
+ }
61361
+ }`,
61362
+ {
61363
+ condition: options?.workspaceId == null ? {} : { workspaceId: options.workspaceId },
61364
+ first: options?.limit ?? 50
61365
+ }
61366
+ );
61367
+ return data.actionRunners.nodes.map((r) => ({
61368
+ id: r.id,
61369
+ name: r.identity?.name ?? null,
61370
+ workspaceId: r.workspaceId,
61371
+ kind: r.isCloud ? "cloud" : "self-hosted",
61372
+ archived: r.isArchived,
61373
+ createdAt: r.createdAt
61374
+ }));
61375
+ }
61376
+ });
61377
+ var runnerResource = (client, id) => {
61378
+ const enqueueAction = async (actionId, inputs) => {
61379
+ const organizationId = await client.organizationId();
61380
+ const data = await client.graphql(
61381
+ `query SdkResolveRunner($id: String!) {
61382
+ actionRunners(condition: { id: $id }, first: 1) { nodes { workspaceId } }
61383
+ }`,
61384
+ { id }
61385
+ );
61386
+ const workspaceId = data.actionRunners.nodes[0]?.workspaceId;
61387
+ if (workspaceId == null) {
61388
+ throw new Error(
61389
+ `Unknown runner ${id} (or it has no workspace). Try: overai runner list`
61390
+ );
61391
+ }
61392
+ const res = await client.fetch(
61393
+ `/v2/actions/${organizationId}/${workspaceId}/run`,
61394
+ {
61395
+ method: "POST",
61396
+ headers: { "Content-Type": "application/json" },
61397
+ body: JSON.stringify({ actionId, inputs, actionRunnerId: id })
61398
+ }
61399
+ );
61400
+ const raw2 = await res.text();
61401
+ if (!res.ok) throw apiError("runner run", res, raw2, organizationId);
61402
+ return JSON.parse(raw2);
61403
+ };
61404
+ return {
61405
+ token: async (options) => {
61406
+ const result = await client.graphql(
61407
+ `mutation SdkCreateActionRunnerToken($actionRunnerId: String!, $note: String) {
61408
+ createActionRunnerToken(
61409
+ input: { actionRunnerId: $actionRunnerId, note: $note }
61410
+ ) { result }
61411
+ }`,
61412
+ { actionRunnerId: id, note: options?.note ?? "cli" }
61413
+ );
61414
+ const secret = result.createActionRunnerToken?.result;
61415
+ if (secret == null) throw new Error("Failed to mint runner token");
61416
+ return secret;
61417
+ },
61418
+ run: (input2) => enqueueAction("RUNNER_RUN_COMMAND", {
61419
+ actionRunnerId: id,
61420
+ interpreter: input2.interpreter ?? "shell",
61421
+ code: input2.code
61422
+ }),
61423
+ upload: (path) => enqueueAction("RUNNER_UPLOAD_FILE", {
61424
+ actionRunnerId: id,
61425
+ filePath: path
61426
+ })
61427
+ };
61428
+ };
61429
+
61430
+ // ../sdk/src/storage.ts
61431
+ var storageApi = (client) => ({
61432
+ upload: async (file2, options) => {
61433
+ const organizationId = await client.organizationId();
61434
+ const query = options.randomPrefix === false ? "?disableRandomPrefix=true" : "";
61435
+ const res = await client.fetch(
61436
+ `/v2/storage/${organizationId}/stream${query}`,
61437
+ {
61438
+ method: "POST",
61439
+ headers: {
61440
+ "Content-Type": "application/octet-stream",
61441
+ "x-file-name": options.name
61442
+ },
61443
+ body: file2
61444
+ }
61445
+ );
61446
+ if (!res.ok)
61447
+ throw apiError("storage upload", res, await res.text(), organizationId);
61448
+ const { path } = await res.json();
61449
+ const key = path.startsWith(`${organizationId}/`) ? path.slice(organizationId.length + 1) : path;
61450
+ return { key, path };
61451
+ },
61452
+ download: async (key) => {
61453
+ const organizationId = await client.organizationId();
61454
+ const res = await client.fetch(
61455
+ `/v2/storage/${organizationId}/${encodeURIComponent(key)}`,
61456
+ { redirect: "follow" }
61457
+ );
61458
+ if (!res.ok)
61459
+ throw apiError("storage download", res, await res.text(), organizationId);
61460
+ return res;
61461
+ },
61462
+ exists: async (key) => {
61463
+ const organizationId = await client.organizationId();
61464
+ const res = await client.fetch(
61465
+ `/v2/storage/${organizationId}/${encodeURIComponent(key)}/exists`
61466
+ );
61467
+ if (res.status === 404) return null;
61468
+ if (!res.ok)
61469
+ throw apiError("storage exists", res, await res.text(), organizationId);
61470
+ return await res.json();
61471
+ },
61472
+ head: async (key, options) => {
61473
+ const organizationId = await client.organizationId();
61474
+ const res = await client.fetch(
61475
+ `/v2/storage/${organizationId}/${encodeURIComponent(key)}/head?numLines=${String(options?.lines ?? 50)}`
61476
+ );
61477
+ const raw2 = await res.text();
61478
+ if (!res.ok) throw apiError("storage head", res, raw2, organizationId);
61479
+ return raw2;
61480
+ },
61481
+ presign: async (key, options) => {
61482
+ const organizationId = await client.organizationId();
61483
+ const res = await client.fetch(
61484
+ `/v2/storage/${organizationId}/${encodeURIComponent(key)}/presign?expiresIn=${String(options?.expiresIn ?? 60 * 60 * 24 * 7)}`
61485
+ );
61486
+ const raw2 = await res.text();
61487
+ if (!res.ok) throw apiError("storage presign", res, raw2, organizationId);
61488
+ return raw2.trim();
61489
+ }
61490
+ });
61491
+
61492
+ // ../sdk/src/tableSpaceRun.ts
61493
+ var clusterInfo = async (client) => {
61494
+ const res = await client.fetch("/v2/cluster-info");
61495
+ const raw2 = await res.text();
61496
+ if (!res.ok)
61497
+ throw apiError("cluster-info", res, raw2, await client.organizationId());
61498
+ return JSON.parse(raw2);
61499
+ };
61500
+ var connectionString = async (client, tableSpaceId, secret) => {
61501
+ const { postgres } = await clusterInfo(client);
61502
+ return `postgresql://overai:${encodeURIComponent(secret)}@${postgres.host}:${String(postgres.port)}/${tableSpaceId}?sslmode=${postgres.sslMode}${postgres.sslMode === "verify-full" ? "&sslrootcert=system" : ""}`;
61503
+ };
61504
+ var tableSpaceResource = (client, id) => ({
61505
+ /*
61506
+ * The controlled /run endpoint (our auth + audit). `params` switches to the
61507
+ * parameterized `unsafe` shape so identifiers stay injection-safe;
61508
+ * ignoreCamelCase keeps real column names.
61509
+ */
61510
+ sql: async (query, options) => {
61511
+ const organizationId = await client.organizationId();
61512
+ const res = await client.fetch(
61513
+ `/v2/table-spaces/${organizationId}/${id}/run`,
61514
+ {
61515
+ method: "POST",
61516
+ headers: { "Content-Type": "application/json" },
61517
+ body: JSON.stringify(
61518
+ options?.params == null ? { query, ignoreCamelCase: true } : { unsafe: { query, params: options.params } }
61519
+ )
61520
+ }
61521
+ );
61522
+ const raw2 = await res.text();
61523
+ const body = (() => {
61524
+ try {
61525
+ return JSON.parse(raw2);
61526
+ } catch {
61527
+ return null;
61528
+ }
61529
+ })();
61530
+ if (!res.ok || body?.ok === false)
61531
+ throw apiError("sql", res, raw2, organizationId);
61532
+ return {
61533
+ rows: body?.rows ?? [],
61534
+ rowCount: body?.rowCount ?? 0,
61535
+ resultSetCount: body?.resultSetCount ?? 1,
61536
+ durationMs: body?.durationMs ?? 0
61537
+ };
61538
+ },
61539
+ credentials: {
61540
+ create: async (input2) => {
61541
+ const data = await client.graphql(
61542
+ `mutation SdkCreateTableSpaceCredential($tableSpaceId: String!, $name: String!, $validUntil: Datetime) {
61543
+ createTableSpaceCredential(input: { tableSpaceId: $tableSpaceId, name: $name, validUntil: $validUntil }) { result }
61544
+ }`,
61545
+ {
61546
+ tableSpaceId: id,
61547
+ name: input2.name,
61548
+ validUntil: input2.validUntil?.toISOString() ?? null
61549
+ }
61550
+ );
61551
+ const result = data.createTableSpaceCredential?.result;
61552
+ if (!result) throw new Error("The server did not return a credential");
61553
+ return {
61554
+ id: result.id,
61555
+ secret: result.secret,
61556
+ connectionString: await connectionString(client, id, result.secret)
61557
+ };
61558
+ },
61559
+ list: async () => (await client.graphql(
61560
+ `query SdkTableSpaceCredentials($tableSpaceId: String!) {
61561
+ tableSpaceCredentials(condition: { tableSpaceId: $tableSpaceId }) {
61562
+ nodes { id name validUntil lastUsedAt createdAt }
61563
+ }
61564
+ }`,
61565
+ { tableSpaceId: id }
61566
+ )).tableSpaceCredentials?.nodes ?? []
61567
+ }
61568
+ });
61569
+ var tableSpaceCredentialResource = (client, credentialId) => {
61570
+ const tableSpaceId = async () => {
61571
+ const data = await client.graphql(
61572
+ `query SdkTableSpaceCredential($id: String!) {
61573
+ tableSpaceCredential(id: $id) { tableSpaceId }
61574
+ }`,
61575
+ { id: credentialId }
61576
+ );
61577
+ if (!data.tableSpaceCredential)
61578
+ throw new Error("Credential not found or you lack access to it");
61579
+ return data.tableSpaceCredential.tableSpaceId;
61580
+ };
61581
+ return {
61582
+ rotate: async () => {
61583
+ const resolvedTableSpaceId = await tableSpaceId();
61584
+ const data = await client.graphql(
61585
+ `mutation SdkRotateTableSpaceCredential($credentialId: String!) {
61586
+ rotateTableSpaceCredential(input: { credentialId: $credentialId }) { result }
61587
+ }`,
61588
+ { credentialId }
61589
+ );
61590
+ const secret = data.rotateTableSpaceCredential?.result;
61591
+ if (!secret) throw new Error("The server did not return a credential");
61592
+ return {
61593
+ secret,
61594
+ connectionString: await connectionString(
61595
+ client,
61596
+ resolvedTableSpaceId,
61597
+ secret
61598
+ )
61599
+ };
61600
+ },
61601
+ revoke: async () => {
61602
+ await tableSpaceId();
61603
+ await client.graphql(
61604
+ `mutation SdkRevokeTableSpaceCredential($id: String!, $validUntil: Datetime!) {
61605
+ updateTableSpaceCredential(input: { id: $id, patch: { validUntil: $validUntil } }) {
61606
+ tableSpaceCredential { id }
61607
+ }
61608
+ }`,
61609
+ { id: credentialId, validUntil: (/* @__PURE__ */ new Date()).toISOString() }
61610
+ );
61611
+ }
61612
+ };
61613
+ };
61614
+
60788
61615
  // ../sdk/src/tokens.ts
60789
61616
  var exchangeSchema = external_exports.object({ token: external_exports.string(), expiresIn: external_exports.number() });
60790
61617
  var staticToken = (jwt2) => () => jwt2;
@@ -60885,6 +61712,17 @@ var OverAIClient = class {
60885
61712
  headers.set("Authorization", `Bearer ${token}`);
60886
61713
  return fetch(`${this.baseUrl}${path}`, { ...init, headers });
60887
61714
  }
61715
+ /** The bearer the next request would send. For hosts that build their own requests, like `createEnv`. */
61716
+ token() {
61717
+ return Promise.resolve(this.#token());
61718
+ }
61719
+ /** The org the token source's JWT names; every org-scoped REST path takes it. */
61720
+ async organizationId() {
61721
+ const org = (this.#claims ?? decodeJwtClaims(await this.#token())).org;
61722
+ if (org == null || org === "")
61723
+ throw new Error("The token carries no organization claim.");
61724
+ return org;
61725
+ }
60888
61726
  /**
60889
61727
  * POST /v2/graphql. Throws with the server's error messages — callers (and
60890
61728
  * agents driving them) need the actual reason, not a status code.
@@ -60971,21 +61809,68 @@ var OverAIClient = class {
60971
61809
  create: (input2) => createDataFile(this, input2)
60972
61810
  };
60973
61811
  workspaces = workspaceCollection(this);
61812
+ runners = runnerCollection(this);
61813
+ storage = storageApi(this);
60974
61814
  /** Its `deploy` checks deployed callers first; see `FunctionResource`. */
60975
61815
  fn(id) {
60976
- return functionResource(this, id);
61816
+ return { ...functionResource(this, id), ...functionRun(this, id) };
60977
61817
  }
60978
61818
  page(id) {
60979
61819
  return codeResource(webPageSource(this), id);
60980
61820
  }
60981
61821
  printablePage(id) {
60982
- return codeResource(printablePageSource(this), id);
61822
+ return {
61823
+ ...codeResource(printablePageSource(this), id),
61824
+ ...printablePageRender(this, id)
61825
+ };
60983
61826
  }
60984
61827
  automation(id) {
60985
- return versionedResource(automationSource(this), id);
61828
+ return {
61829
+ ...versionedResource(automationSource(this), id),
61830
+ ...automationRunApi(this, id)
61831
+ };
60986
61832
  }
60987
61833
  agent(id) {
60988
- return versionedResource(agentSource(this), id);
61834
+ return {
61835
+ ...versionedResource(agentSource(this), id),
61836
+ ...agentRun(this, id)
61837
+ };
61838
+ }
61839
+ /** A run addresses no automation, so its state is read by run id alone. */
61840
+ automationRunState(runId) {
61841
+ return automationRunState(this, runId);
61842
+ }
61843
+ tableSpace(id) {
61844
+ return tableSpaceResource(this, id);
61845
+ }
61846
+ tableSpaceCredential(credentialId) {
61847
+ return tableSpaceCredentialResource(this, credentialId);
61848
+ }
61849
+ dataFile(id) {
61850
+ return dataFileResource(this, id);
61851
+ }
61852
+ dataStream(id) {
61853
+ return dataStreamResource(this, id);
61854
+ }
61855
+ knowledgeBase(id) {
61856
+ return knowledgeBaseResource(this, id);
61857
+ }
61858
+ integration(id) {
61859
+ return integrationResource(this, id);
61860
+ }
61861
+ runner(id) {
61862
+ return runnerResource(this, id);
61863
+ }
61864
+ clusterInfo() {
61865
+ return clusterInfo(this);
61866
+ }
61867
+ /** The platform's authenticated lint, which knows the workspace's resources. */
61868
+ lint(input2) {
61869
+ return lint(this, input2);
61870
+ }
61871
+ /** Files a bug report or feature request with OverAI. */
61872
+ report(kind, details, options) {
61873
+ return report(this, kind, details, options);
60989
61874
  }
60990
61875
  workspace(id) {
60991
61876
  return workspaceResource(this, id);
@@ -61279,7 +62164,6 @@ var cliClient = () => createClient({
61279
62164
  baseUrl: apiBaseUrl(),
61280
62165
  token: async () => (await getAccessToken()).token
61281
62166
  });
61282
- var v2Fetch = async (path, init) => cliClient().fetch(path, init);
61283
62167
  var v2Error = (label, res, rawBody) => withOrgHint(apiError(label, res, rawBody, scopedOrgId()));
61284
62168
  var ORG_HINT = "\n If it lives in another org, name that org: overai --org <ref> ... (`overai org list` shows them, `overai org alias` your shorthands).";
61285
62169
  var withOrgHint = (error62) => {
@@ -61287,7 +62171,6 @@ var withOrgHint = (error62) => {
61287
62171
  error62.message = `${error62.message}${ORG_HINT}`;
61288
62172
  return error62;
61289
62173
  };
61290
- var userTrpcMutation = async (procedure, input2) => cliClient().trpc(procedure, input2);
61291
62174
 
61292
62175
  // src/args.ts
61293
62176
  import { readFileSync as readFileSync3 } from "fs";
@@ -61321,6 +62204,15 @@ var flagValue = (args, ...names) => {
61321
62204
  }
61322
62205
  return void 0;
61323
62206
  };
62207
+ function integerFlag(args, name2, fallback2) {
62208
+ const names = typeof name2 === "string" ? [name2] : [...name2];
62209
+ const raw2 = flagValue(args, ...names);
62210
+ if (raw2 == null) return fallback2;
62211
+ const value = Number(raw2);
62212
+ if (!Number.isInteger(value))
62213
+ throw new Error(`${names[0] ?? ""} must be a whole number.`);
62214
+ return value;
62215
+ }
61324
62216
  var stdinClaimedBy = null;
61325
62217
  var readStdin = async (claimant = "stdin") => {
61326
62218
  if (stdinClaimedBy != null) {
@@ -61834,17 +62726,6 @@ var whoami = (args = []) => {
61834
62726
 
61835
62727
  // src/commands/agent.ts
61836
62728
  import { createInterface } from "readline";
61837
-
61838
- // src/gql.ts
61839
- var gqlRequest = async (query, variables) => {
61840
- try {
61841
- return await cliClient().graphql(query, variables);
61842
- } catch (error62) {
61843
- throw withOrgHint(error62);
61844
- }
61845
- };
61846
-
61847
- // src/commands/agent.ts
61848
62729
  var USAGE = [
61849
62730
  "Usage:",
61850
62731
  " overai agent generate <id> --message <text|@file|@->",
@@ -61857,210 +62738,51 @@ var generate = async (args, id) => {
61857
62738
  "--message"
61858
62739
  );
61859
62740
  if (message == null) throw new Error("Agent generate requires --message.");
61860
- const { organizationId } = await getAccessToken();
61861
- const response = await v2Fetch(
61862
- `/v2/agents/${organizationId}/${id}/generate/text`,
61863
- {
61864
- method: "POST",
61865
- headers: { "Content-Type": "application/json" },
61866
- body: JSON.stringify({ message })
61867
- }
61868
- );
61869
- const raw2 = await response.text();
61870
- if (!response.ok) throw v2Error("agent generate", response, raw2);
61871
62741
  printResult(
61872
- JSON.parse(raw2),
62742
+ await cliClient().agent(id).generate(message),
61873
62743
  resolveFormat(flagValue(args, "-o", "--output"))
61874
62744
  );
61875
62745
  };
61876
- var deployedVersionNumber = async (id) => {
61877
- const deployed = await gqlRequest(
61878
- `query CliAgentDeployedVersion($id: String!) {
61879
- agentDeployedVersions(condition: { agentId: $id }) { nodes { versionNumber } }
61880
- }`,
61881
- { id }
61882
- );
61883
- const versionNumber = deployed.agentDeployedVersions?.nodes[0]?.versionNumber;
61884
- if (versionNumber == null) {
61885
- throw new Error(
61886
- `Agent ${id} has no deployed version; pass --version <n> to inspect a saved one.`
61887
- );
61888
- }
61889
- return versionNumber;
61890
- };
61891
62746
  var tools = async (args, id) => {
61892
- const versionFlag = flagValue(args, "--version", "-v");
61893
- if (versionFlag != null && !Number.isInteger(Number(versionFlag))) {
61894
- throw new Error("--version must be an integer.");
61895
- }
61896
- const version2 = versionFlag == null ? await deployedVersionNumber(id) : Number(versionFlag);
61897
- const data = await gqlRequest(
61898
- `query CliAgentTools($id: String!, $version: Int!) {
61899
- agent(id: $id) {
61900
- name
61901
- agentVersions(first: 1, condition: { versionNumber: $version }) {
61902
- nodes {
61903
- versionNumber
61904
- model
61905
- agentVersionFunctionsByAgentIdAndVersionNumber(orderBy: [FUNCTION_ID_ASC]) {
61906
- nodes { functionId function { name } }
61907
- }
61908
- agentVersionTableSpacesByAgentIdAndVersionNumber(orderBy: [TABLE_SPACE_ID_ASC]) {
61909
- nodes { tableSpaceId accessMode }
61910
- }
61911
- agentVersionAgentsByAgentIdAndVersionNumber(orderBy: [ATTACHED_AGENT_ID_ASC]) {
61912
- nodes { attachedAgentId }
61913
- }
61914
- agentVersionKnowledgeBasesByAgentIdAndVersionNumber(orderBy: [KNOWLEDGE_BASE_ID_ASC]) {
61915
- nodes { knowledgeBaseId }
61916
- }
61917
- agentVersionBuiltinToolSetsByAgentIdAndVersionNumber(orderBy: [TOOL_SET_ASC]) {
61918
- nodes { toolSet }
61919
- }
61920
- }
61921
- }
61922
- }
61923
- }`,
61924
- { id, version: version2 }
61925
- );
61926
- if (data.agent == null) throw new Error(`Agent ${id} not found.`);
61927
- const agentVersion = data.agent.agentVersions.nodes[0];
61928
- if (agentVersion == null) {
61929
- throw new Error(`Agent ${id} has no version ${String(version2)}.`);
61930
- }
61931
- const rows = [
61932
- ...agentVersion.agentVersionFunctionsByAgentIdAndVersionNumber.nodes.map(
61933
- (link) => ({
61934
- kind: "function",
61935
- name: link.function?.name ?? link.functionId,
61936
- detail: link.functionId
61937
- })
61938
- ),
61939
- ...agentVersion.agentVersionTableSpacesByAgentIdAndVersionNumber.nodes.map(
61940
- (link) => ({
61941
- kind: "table space",
61942
- name: link.tableSpaceId,
61943
- detail: link.accessMode
61944
- })
61945
- ),
61946
- ...agentVersion.agentVersionAgentsByAgentIdAndVersionNumber.nodes.map(
61947
- (link) => ({
61948
- kind: "sub-agent",
61949
- name: link.attachedAgentId,
61950
- detail: ""
61951
- })
61952
- ),
61953
- ...agentVersion.agentVersionKnowledgeBasesByAgentIdAndVersionNumber.nodes.map(
61954
- (link) => ({
61955
- kind: "knowledge base",
61956
- name: link.knowledgeBaseId,
61957
- detail: ""
61958
- })
61959
- ),
61960
- ...agentVersion.agentVersionBuiltinToolSetsByAgentIdAndVersionNumber.nodes.map(
61961
- (link) => ({ kind: "built-in", name: link.toolSet, detail: "" })
61962
- )
61963
- ];
62747
+ const version2 = integerFlag(args, ["--version", "-v"]);
62748
+ const result = await cliClient().agent(id).tools(version2 ?? "deployed");
61964
62749
  const format2 = resolveFormat(flagValue(args, "-o", "--output"));
61965
62750
  if (format2 === "json") {
61966
- printResult(
61967
- {
61968
- agent: data.agent.name,
61969
- version: agentVersion.versionNumber,
61970
- model: agentVersion.model,
61971
- tools: rows
61972
- },
61973
- format2
61974
- );
62751
+ printResult(result, format2);
61975
62752
  return;
61976
62753
  }
61977
62754
  if (format2 === "table") {
61978
62755
  process.stdout.write(
61979
- `${data.agent.name} \xB7 version ${String(agentVersion.versionNumber)} \xB7 ${agentVersion.model}
62756
+ `${result.agent} \xB7 version ${String(result.version)} \xB7 ${result.model}
61980
62757
  `
61981
62758
  );
61982
62759
  }
61983
- printResult(rows, format2);
62760
+ printResult(result.tools, format2);
61984
62761
  };
61985
- var printStreamLine = (line) => {
61986
- if (!line.startsWith("data: ")) return;
61987
- const payload = line.slice(6);
61988
- if (payload === "[DONE]") return;
61989
- let event;
61990
- try {
61991
- event = JSON.parse(payload);
61992
- } catch {
61993
- return;
61994
- }
61995
- if (event.type === "text-delta" && event.delta != null) {
61996
- process.stdout.write(event.delta);
61997
- }
61998
- if (event.type === "error") {
61999
- process.stderr.write(`
62762
+ var send = async (agent, message, conversationId) => {
62763
+ const response = await agent.chat(
62764
+ [{ role: "user", parts: [{ type: "text", text: message }] }],
62765
+ { conversationId }
62766
+ );
62767
+ for await (const event of agentStreamEvents(response)) {
62768
+ if (event.type === "text-delta") process.stdout.write(event.delta);
62769
+ else process.stderr.write(`
62000
62770
  ${event.errorText ?? "agent turn failed"}
62001
62771
  `);
62002
62772
  }
62003
- };
62004
- var streamReply = async (response) => {
62005
- const body = response.body;
62006
- if (body == null) return;
62007
- const decoder = new TextDecoder();
62008
- let buffer = "";
62009
- for await (const chunk of body) {
62010
- buffer += decoder.decode(chunk, { stream: true });
62011
- const lines = buffer.split("\n");
62012
- buffer = lines.pop() ?? "";
62013
- lines.forEach(printStreamLine);
62014
- }
62015
- printStreamLine(buffer + decoder.decode());
62016
- };
62017
- var send = async (organizationId, id, message, conversationId) => {
62018
- const response = await v2Fetch(`/v2/agents/${organizationId}/${id}`, {
62019
- method: "POST",
62020
- headers: { "Content-Type": "application/json" },
62021
- body: JSON.stringify({
62022
- messages: [{ role: "user", parts: [{ type: "text", text: message }] }],
62023
- conversationId
62024
- })
62025
- });
62026
- if (!response.ok) {
62027
- throw v2Error("agent chat", response, await response.text());
62028
- }
62029
- await streamReply(response);
62030
62773
  process.stdout.write("\n");
62031
62774
  };
62032
- var createConversation = async (id, firstMessage) => {
62033
- const versionNumber = await deployedVersionNumber(id);
62034
- const created = await gqlRequest(
62035
- `mutation CliCreateAgentConversation($input: CreateAgentConversationInput!) {
62036
- createAgentConversation(input: $input) { agentConversation { id } }
62037
- }`,
62038
- {
62039
- input: {
62040
- agentConversation: {
62041
- agentId: id,
62042
- versionNumber,
62043
- title: firstMessage.length > 50 ? `${firstMessage.slice(0, 47)}...` : firstMessage
62044
- }
62045
- }
62046
- }
62047
- );
62048
- const conversationId = created.createAgentConversation?.agentConversation?.id;
62049
- if (conversationId == null)
62050
- throw new Error("Failed to create a conversation.");
62051
- return conversationId;
62052
- };
62053
62775
  var chat = async (args, id) => {
62054
- const { organizationId } = await getAccessToken();
62776
+ const agent = cliClient().agent(id);
62055
62777
  let conversationId = flagValue(args, "--conversation", "-c") ?? null;
62056
62778
  const single = await readValue(
62057
62779
  flagValue(args, "--message", "-m"),
62058
62780
  "--message"
62059
62781
  );
62060
62782
  if (single != null) {
62061
- conversationId ??= await createConversation(id, single);
62783
+ conversationId ??= await agent.createConversation(single);
62062
62784
  try {
62063
- await send(organizationId, id, single, conversationId);
62785
+ await send(agent, single, conversationId);
62064
62786
  } finally {
62065
62787
  process.stderr.write(`Conversation: ${conversationId}
62066
62788
  `);
@@ -62087,11 +62809,12 @@ var chat = async (args, id) => {
62087
62809
  continue;
62088
62810
  }
62089
62811
  try {
62090
- conversationId ??= await createConversation(id, message);
62091
- await send(organizationId, id, message, conversationId);
62812
+ conversationId ??= await agent.createConversation(message);
62813
+ await send(agent, message, conversationId);
62092
62814
  } catch (error62) {
62815
+ const hinted = withOrgHint(error62);
62093
62816
  process.stderr.write(
62094
- `${error62 instanceof Error ? error62.message : String(error62)}
62817
+ `${hinted instanceof Error ? hinted.message : String(hinted)}
62095
62818
  `
62096
62819
  );
62097
62820
  }
@@ -62123,53 +62846,24 @@ var runAgent = async (args) => {
62123
62846
 
62124
62847
  // src/commands/automation.ts
62125
62848
  var runRuns = async (automationId, args) => {
62126
- const limit2 = Number(flagValue(args, "--limit") ?? 20);
62127
- const data = await gqlRequest(
62128
- `query CliAutomationRuns($automationId: String!, $first: Int!) {
62129
- automationRuns(condition: { automationId: $automationId }, orderBy: [STARTED_AT_DESC], first: $first) {
62130
- nodes { id startedAt endedAt errored isCancelled manuallyTriggered version { num } }
62131
- }
62132
- }`,
62133
- // Over-fetch when status-filtering so --failed still fills the limit.
62134
- {
62135
- automationId,
62136
- first: args.includes("--failed") || args.includes("--running") ? limit2 * 5 : limit2
62137
- }
62138
- );
62139
- let runs = data.automationRuns.nodes;
62140
- if (args.includes("--failed")) runs = runs.filter((r) => r.errored);
62141
- if (args.includes("--running")) {
62142
- runs = runs.filter((r) => r.endedAt == null && !r.isCancelled);
62143
- }
62144
62849
  printResult(
62145
- runs.slice(0, limit2).map((r) => ({
62146
- id: r.id,
62147
- version: r.version?.num,
62148
- startedAt: r.startedAt,
62149
- endedAt: r.endedAt,
62150
- status: r.errored ? "errored" : r.isCancelled ? "cancelled" : r.endedAt == null ? "running" : "ok",
62151
- manual: r.manuallyTriggered
62152
- })),
62850
+ await cliClient().automation(automationId).runs({
62851
+ limit: integerFlag(args, "--limit", 20),
62852
+ failed: args.includes("--failed"),
62853
+ running: args.includes("--running")
62854
+ }),
62153
62855
  resolveFormat(flagValue(args, "-o", "--output"))
62154
62856
  );
62155
62857
  };
62156
62858
  var runState = async (runId, args) => {
62157
- const data = await gqlRequest(
62158
- `query CliAutomationRunState($id: String!) {
62159
- automationRun(id: $id) { state }
62160
- }`,
62161
- { id: runId }
62162
- );
62163
- if (data.automationRun == null) throw new Error(`Run ${runId} not found.`);
62859
+ const state = await cliClient().automationRunState(runId);
62164
62860
  const node2 = flagValue(args, "--node");
62165
- const state = data.automationRun.state ?? {};
62166
62861
  printResult(
62167
62862
  node2 != null ? { [node2]: state[node2] ?? "(no state for this node)" } : state,
62168
62863
  resolveFormat(flagValue(args, "-o", "--output"))
62169
62864
  );
62170
62865
  };
62171
62866
  var runTrigger = async (automationId, args) => {
62172
- const { organizationId } = await getAccessToken();
62173
62867
  const body = {};
62174
62868
  if (args.includes("-")) {
62175
62869
  Object.assign(
@@ -62184,18 +62878,10 @@ var runTrigger = async (automationId, args) => {
62184
62878
  if (eq > 0) body[pair.slice(0, eq)] = pair.slice(eq + 1);
62185
62879
  }
62186
62880
  }
62187
- const res = await v2Fetch(
62188
- `/v2/automations/${organizationId}/${automationId}/run`,
62189
- {
62190
- method: "POST",
62191
- headers: { "Content-Type": "application/json" },
62192
- body: JSON.stringify(body)
62193
- }
62881
+ printResult(
62882
+ await cliClient().automation(automationId).run(body),
62883
+ resolveFormat(flagValue(args, "-o", "--output"))
62194
62884
  );
62195
- const raw2 = await res.text();
62196
- if (!res.ok) throw v2Error("automation run", res, raw2);
62197
- const responseBody = JSON.parse(raw2);
62198
- printResult(responseBody, resolveFormat(flagValue(args, "-o", "--output")));
62199
62885
  };
62200
62886
  var runAutomation = async (args) => {
62201
62887
  const [sub, id, ...rest] = args;
@@ -62294,35 +62980,13 @@ var allAdapters = [
62294
62980
  agentAdapter
62295
62981
  ];
62296
62982
  var adapterFor = (type) => {
62297
- const adapter = allAdapters.find((a) => a.type === type);
62298
- if (adapter == null) throw new Error(`No adapter for resource type ${type}.`);
62299
- return adapter;
62300
- };
62301
-
62302
- // src/commands/runner.ts
62303
- var createActionRunner = async (workspaceId, name2) => {
62304
- const identityResult = await gqlRequest(
62305
- `mutation CliCreateMachineIdentity($name: String!) {
62306
- createMachineIdentity(input: { name: $name }) {
62307
- identity { id }
62308
- }
62309
- }`,
62310
- { name: name2 }
62311
- );
62312
- const identityId = identityResult.createMachineIdentity?.identity?.id;
62313
- if (identityId == null) throw new Error("Failed to create machine identity");
62314
- const runnerResult = await gqlRequest(
62315
- `mutation CliCreateActionRunner($identityId: String!, $workspaceId: String!) {
62316
- createActionRunner(
62317
- input: { actionRunner: { identityId: $identityId, workspaceId: $workspaceId } }
62318
- ) { actionRunner { id } }
62319
- }`,
62320
- { identityId, workspaceId }
62321
- );
62322
- const actionRunnerId = runnerResult.createActionRunner?.actionRunner?.id;
62323
- if (actionRunnerId == null) throw new Error("Failed to create action runner");
62324
- return { actionRunnerId, identityId };
62983
+ const adapter = allAdapters.find((a) => a.type === type);
62984
+ if (adapter == null) throw new Error(`No adapter for resource type ${type}.`);
62985
+ return adapter;
62325
62986
  };
62987
+
62988
+ // src/commands/runner.ts
62989
+ var createActionRunner = (workspaceId, name2) => cliClient().runners.create({ workspaceId, name: name2 });
62326
62990
  var runCreate = async (workspaceId, args) => {
62327
62991
  const name2 = flagValue(args, "--name") ?? "Action Runner";
62328
62992
  printResult(
@@ -62331,53 +62995,12 @@ var runCreate = async (workspaceId, args) => {
62331
62995
  );
62332
62996
  };
62333
62997
  var runToken = async (runnerId, args) => {
62334
- const note = flagValue(args, "--note") ?? "cli";
62335
- const result = await gqlRequest(
62336
- `mutation CliCreateActionRunnerToken($actionRunnerId: String!, $note: String) {
62337
- createActionRunnerToken(
62338
- input: { actionRunnerId: $actionRunnerId, note: $note }
62339
- ) { result }
62340
- }`,
62341
- { actionRunnerId: runnerId, note }
62342
- );
62343
- const secret = result.createActionRunnerToken?.result;
62344
- if (secret == null) throw new Error("Failed to mint runner token");
62998
+ const secret = await cliClient().runner(runnerId).token({ note: flagValue(args, "--note") ?? "cli" });
62345
62999
  printResult(
62346
63000
  { runnerId, secret },
62347
63001
  resolveFormat(flagValue(args, "-o", "--output"))
62348
63002
  );
62349
63003
  };
62350
- var resolveWorkspaceId = async (runnerId) => {
62351
- const data = await gqlRequest(
62352
- `query CliResolveRunner($id: String!) {
62353
- actionRunners(condition: { id: $id }, first: 1) { nodes { workspaceId } }
62354
- }`,
62355
- { id: runnerId }
62356
- );
62357
- const workspaceId = data.actionRunners.nodes[0]?.workspaceId;
62358
- if (workspaceId == null) {
62359
- throw new Error(
62360
- `Unknown runner ${runnerId} (or it has no workspace). Try: overai runner list`
62361
- );
62362
- }
62363
- return workspaceId;
62364
- };
62365
- var enqueueAction = async (runnerId, actionId, inputs, args) => {
62366
- const { organizationId } = await getAccessToken();
62367
- const workspaceId = await resolveWorkspaceId(runnerId);
62368
- const res = await v2Fetch(
62369
- `/v2/actions/${organizationId}/${workspaceId}/run`,
62370
- {
62371
- method: "POST",
62372
- headers: { "Content-Type": "application/json" },
62373
- body: JSON.stringify({ actionId, inputs, actionRunnerId: runnerId })
62374
- }
62375
- );
62376
- const raw2 = await res.text();
62377
- if (!res.ok) throw v2Error("runner run", res, raw2);
62378
- const body = JSON.parse(raw2);
62379
- printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
62380
- };
62381
63004
  var runRun = async (runnerId, args) => {
62382
63005
  const code = await readValue(flagValue(args, "--code"), "--code") ?? (process.stdin.isTTY ? "" : (await readStdin("the code")).trim());
62383
63006
  if (code.length === 0) {
@@ -62389,11 +63012,9 @@ var runRun = async (runnerId, args) => {
62389
63012
  if (interpreter !== "shell" && interpreter !== "powershell") {
62390
63013
  throw new Error("--interpreter must be 'shell' or 'powershell'.");
62391
63014
  }
62392
- await enqueueAction(
62393
- runnerId,
62394
- "RUNNER_RUN_COMMAND",
62395
- { actionRunnerId: runnerId, interpreter, code },
62396
- args
63015
+ printResult(
63016
+ await cliClient().runner(runnerId).run({ code, interpreter }),
63017
+ resolveFormat(flagValue(args, "-o", "--output"))
62397
63018
  );
62398
63019
  };
62399
63020
  var runUpload = async (runnerId, args) => {
@@ -62401,35 +63022,19 @@ var runUpload = async (runnerId, args) => {
62401
63022
  if (path == null || path.length === 0) {
62402
63023
  throw new Error("Provide a file with --path '<path>'.");
62403
63024
  }
62404
- await enqueueAction(
62405
- runnerId,
62406
- "RUNNER_UPLOAD_FILE",
62407
- { actionRunnerId: runnerId, filePath: path },
62408
- args
63025
+ printResult(
63026
+ await cliClient().runner(runnerId).upload(path),
63027
+ resolveFormat(flagValue(args, "-o", "--output"))
62409
63028
  );
62410
63029
  };
62411
63030
  var runList = async (args) => {
62412
63031
  const workspaceId = args.find((a) => !a.startsWith("-"));
62413
- const limit2 = Number(flagValue(args, "--limit") ?? 50);
62414
- const data = await gqlRequest(
62415
- `query CliRunnerList($workspaceId: String, $first: Int!) {
62416
- actionRunners(condition: { workspaceId: $workspaceId }, first: $first) {
62417
- nodes { id identity { name } workspaceId isCloud isArchived createdAt }
62418
- }
62419
- }`,
62420
- { workspaceId: workspaceId ?? null, first: limit2 }
62421
- );
62422
- printResult(
62423
- data.actionRunners.nodes.map((r) => ({
62424
- id: r.id,
62425
- name: r.identity?.name ?? null,
62426
- workspaceId: r.workspaceId,
62427
- kind: r.isCloud ? "cloud" : "self-hosted",
62428
- archived: r.isArchived,
62429
- createdAt: r.createdAt
62430
- })),
62431
- resolveFormat(flagValue(args, "-o", "--output"))
62432
- );
63032
+ const limit2 = integerFlag(args, "--limit", 50);
63033
+ const runners = await cliClient().runners.list({
63034
+ ...workspaceId != null ? { workspaceId } : {},
63035
+ limit: limit2
63036
+ });
63037
+ printResult(runners, resolveFormat(flagValue(args, "-o", "--output")));
62433
63038
  };
62434
63039
  var USAGE2 = "Usage: overai runner create <workspaceId> [--name <name>]\n overai runner token <runnerId> [--note <note>]\n overai runner run <runnerId> [--interpreter shell|powershell] --code '<code>'\n overai runner upload <runnerId> --path '<path>'\n overai runner list [workspaceId] [--limit <n>]\n";
62435
63040
  var runRunner = async (args) => {
@@ -62574,29 +63179,26 @@ var runCreate2 = async (args) => {
62574
63179
  };
62575
63180
 
62576
63181
  // src/commands/dataFile.ts
62577
- import { readFileSync as readFileSync5, statSync as statSync2, writeFileSync as writeFileSync3 } from "fs";
63182
+ import { openAsBlob, writeFileSync as writeFileSync3 } from "fs";
62578
63183
  var runDataFile = async (args) => {
62579
63184
  const [operation, id, path] = args;
62580
63185
  if (id == null || !["upload", "download", "head"].includes(operation ?? "")) {
62581
- throw new Error("Usage: overai data-file upload <id> <path> [-m <message>] | data-file download <id> [path|-] | data-file head <id> [--lines N]");
63186
+ throw new Error(
63187
+ "Usage: overai data-file upload <id> <path> [-m <message>] | data-file download <id> [path|-] | data-file head <id> [--lines N]"
63188
+ );
62582
63189
  }
62583
- const { organizationId } = await getAccessToken();
63190
+ const dataFile = cliClient().dataFile(id);
62584
63191
  if (operation === "upload") {
62585
- if (path == null || path === "-") throw new Error("Upload requires a file path.");
62586
- const url2 = await userTrpcMutation("dataFiles.getDataFileUploadUrl", {
62587
- dataFileId: id,
62588
- fileSize: statSync2(path).size,
63192
+ if (path == null || path === "-")
63193
+ throw new Error("Upload requires a file path.");
63194
+ await dataFile.upload(await openAsBlob(path), {
62589
63195
  message: flagValue(args, "-m", "--message") ?? ""
62590
63196
  });
62591
- const response2 = await fetch(url2, { method: "PUT", body: readFileSync5(path) });
62592
- if (!response2.ok) throw v2Error("data-file upload", response2, await response2.text());
62593
63197
  process.stdout.write(`${id}
62594
63198
  `);
62595
63199
  return;
62596
63200
  }
62597
- const suffix = operation === "head" ? `/head?numLines=${encodeURIComponent(flagValue(args, "--lines") ?? "50")}` : "";
62598
- const response = await v2Fetch(`/v2/data-files/${organizationId}/${id}${suffix}`, { redirect: "follow" });
62599
- if (!response.ok) throw v2Error(`data-file ${String(operation)}`, response, await response.text());
63201
+ const response = operation === "head" ? await dataFile.head({ lines: integerFlag(args, "--lines", 50) }) : await dataFile.read();
62600
63202
  const bytes = Buffer.from(await response.arrayBuffer());
62601
63203
  if (path != null && path !== "-") writeFileSync3(path, bytes);
62602
63204
  else process.stdout.write(bytes);
@@ -62606,40 +63208,39 @@ var runDataFile = async (args) => {
62606
63208
  var runDataStream = async (args) => {
62607
63209
  const [operation, id] = args;
62608
63210
  if (id == null || operation !== "append" && operation !== "query") {
62609
- throw new Error("Usage: overai data-stream append <id> <json|@file|@-> | data-stream query <id> --start <date> --end <date> [--query <filter>] [--limit N]");
63211
+ throw new Error(
63212
+ "Usage: overai data-stream append <id> <json|@file|@-> | data-stream query <id> --start <date> --end <date> [--query <filter>] [--limit N]"
63213
+ );
62610
63214
  }
62611
- const { organizationId } = await getAccessToken();
63215
+ const dataStream = cliClient().dataStream(id);
62612
63216
  if (operation === "append") {
62613
- const raw3 = await readValue(args[2], "data stream input");
62614
- if (raw3 == null) throw new Error("Data stream append requires JSON, @<file>, or @-.");
63217
+ const raw2 = await readValue(args[2], "data stream input");
63218
+ if (raw2 == null)
63219
+ throw new Error("Data stream append requires JSON, @<file>, or @-.");
62615
63220
  const parsed = (() => {
62616
63221
  try {
62617
- return JSON.parse(raw3);
63222
+ return JSON.parse(raw2);
62618
63223
  } catch {
62619
63224
  throw new Error("Data stream input must be valid JSON.");
62620
63225
  }
62621
63226
  })();
62622
- const response2 = await v2Fetch(`/v1/data-streams/${organizationId}/${id}`, {
62623
- method: "POST",
62624
- headers: { "Content-Type": "application/json" },
62625
- body: JSON.stringify({ data: Array.isArray(parsed) ? parsed : [parsed] })
62626
- });
62627
- const appended = await response2.text();
62628
- if (!response2.ok) throw v2Error("data-stream append", response2, appended);
62629
- const body2 = JSON.parse(appended);
62630
- printResult(body2, resolveFormat(flagValue(args, "-o", "--output")));
63227
+ printResult(
63228
+ await dataStream.append(parsed),
63229
+ resolveFormat(flagValue(args, "-o", "--output"))
63230
+ );
62631
63231
  return;
62632
63232
  }
62633
63233
  const start = flagValue(args, "--start");
62634
63234
  const end = flagValue(args, "--end");
62635
- if (start == null || end == null) throw new Error("Data stream query requires --start and --end.");
62636
- const query = new URLSearchParams({ startAt: start, endAt: end, query: flagValue(args, "--query") ?? "" });
62637
- const limit2 = flagValue(args, "--limit");
62638
- if (limit2 != null) query.set("limit", limit2);
62639
- const response = await v2Fetch(`/v1/data-streams/${organizationId}/${id}?${query.toString()}`);
62640
- const raw2 = await response.text();
62641
- if (!response.ok) throw v2Error("data-stream query", response, raw2);
62642
- const body = JSON.parse(raw2);
63235
+ if (start == null || end == null)
63236
+ throw new Error("Data stream query requires --start and --end.");
63237
+ const limit2 = integerFlag(args, "--limit");
63238
+ const body = await dataStream.query({
63239
+ startAt: start,
63240
+ endAt: end,
63241
+ query: flagValue(args, "--query") ?? "",
63242
+ ...limit2 != null ? { limit: limit2 } : {}
63243
+ });
62643
63244
  printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
62644
63245
  };
62645
63246
 
@@ -62654,12 +63255,21 @@ import {
62654
63255
  existsSync as existsSync3,
62655
63256
  lstatSync,
62656
63257
  mkdirSync as mkdirSync3,
62657
- readFileSync as readFileSync6,
63258
+ readFileSync as readFileSync5,
62658
63259
  unlinkSync,
62659
63260
  writeFileSync as writeFileSync4
62660
63261
  } from "fs";
62661
63262
  import { join as join4, resolve as resolve3 } from "path";
62662
63263
 
63264
+ // src/gql.ts
63265
+ var gqlRequest = async (query, variables) => {
63266
+ try {
63267
+ return await cliClient().graphql(query, variables);
63268
+ } catch (error62) {
63269
+ throw withOrgHint(error62);
63270
+ }
63271
+ };
63272
+
62663
63273
  // src/workspace/tree.ts
62664
63274
  var fetchWorkspaceChildren = async (id) => {
62665
63275
  const children = [];
@@ -62724,7 +63334,7 @@ var runClone = async (args, isShallow = false) => {
62724
63334
  `${root} is already a cloned workspace. Use \`overai pull\` to refresh.`
62725
63335
  );
62726
63336
  }
62727
- const partialCloneWorkspaceId = existsSync3(cloneMarker) ? readFileSync6(cloneMarker, "utf8").trim() : null;
63337
+ const partialCloneWorkspaceId = existsSync3(cloneMarker) ? readFileSync5(cloneMarker, "utf8").trim() : null;
62728
63338
  if (partialCloneWorkspaceId != null && partialCloneWorkspaceId !== workspaceId) {
62729
63339
  throw new Error(
62730
63340
  `${root} contains an incomplete clone of ${partialCloneWorkspaceId}. Retry that workspace or choose another directory.`
@@ -62742,7 +63352,7 @@ var runClone = async (args, isShallow = false) => {
62742
63352
  if (entry.root !== root && existsSync3(entry.root)) {
62743
63353
  if (lstatSync(entry.root).isSymbolicLink())
62744
63354
  throw new Error(`Refusing to clone into symbolic link ${entry.root}.`);
62745
- const savedId = completed ? readManifest(entry.root).workspaceId : existsSync3(marker) ? readFileSync6(marker, "utf8").trim() : null;
63355
+ const savedId = completed ? readManifest(entry.root).workspaceId : existsSync3(marker) ? readFileSync5(marker, "utf8").trim() : null;
62746
63356
  if (partialCloneWorkspaceId !== workspaceId || savedId !== entry.workspace.id)
62747
63357
  throw new Error(
62748
63358
  `${entry.root} already exists. Choose another clone directory.`
@@ -63261,7 +63871,7 @@ var runDev = async (args) => {
63261
63871
  clearTimeout(timer);
63262
63872
  });
63263
63873
  });
63264
- const port = Number(flagValue(args, "--port") ?? 4820);
63874
+ const port = integerFlag(args, "--port", 4820);
63265
63875
  await new Promise((resolve4, reject2) => {
63266
63876
  server.once("error", reject2);
63267
63877
  server.listen(port, "127.0.0.1", resolve4);
@@ -63309,54 +63919,16 @@ var runLogs = async (args) => {
63309
63919
  );
63310
63920
  }
63311
63921
  const executionId = flagValue(args, "--execution");
63922
+ const fn2 = cliClient().fn(functionId);
63923
+ const fmt = resolveFormat(flagValue(args, "-o", "--output"));
63312
63924
  if (executionId == null) {
63313
- const limit2 = Number(flagValue(args, "--limit") ?? 20);
63314
- const data2 = await gqlRequest(
63315
- `query CliFunctionExecutions($functionId: String!, $first: Int!) {
63316
- functionExecutions(condition: { functionId: $functionId }, orderBy: [CREATED_AT_DESC], first: $first) {
63317
- nodes { id createdAt httpStatusCode executionTime requestMethod requestPath versionNumber }
63318
- }
63319
- }`,
63320
- { functionId, first: limit2 }
63321
- );
63322
63925
  printResult(
63323
- data2.functionExecutions.nodes,
63324
- resolveFormat(flagValue(args, "-o", "--output"))
63926
+ await fn2.executions({ limit: integerFlag(args, "--limit", 20) }),
63927
+ fmt
63325
63928
  );
63326
63929
  return;
63327
63930
  }
63328
- const data = await gqlRequest(
63329
- `query CliFunctionExecution($functionId: String!, $id: String!) {
63330
- functionExecutions(condition: { functionId: $functionId, id: $id }, first: 1) {
63331
- nodes { id summary createdAt httpStatusCode executionTime versionNumber logsUrl inputBodyUrl outputBodyUrl }
63332
- }
63333
- }`,
63334
- { functionId, id: executionId }
63335
- );
63336
- const execution = data.functionExecutions.nodes[0];
63337
- if (execution == null) throw new Error(`Execution ${executionId} not found.`);
63338
- const fetchText = async (url2) => url2 == null ? null : await fetch(url2).then((r) => r.ok ? r.text() : null);
63339
- const [logs, input2, output2] = await Promise.all([
63340
- fetchText(execution.logsUrl),
63341
- fetchText(execution.inputBodyUrl),
63342
- fetchText(execution.outputBodyUrl)
63343
- ]);
63344
- const fmt = resolveFormat(flagValue(args, "-o", "--output"));
63345
- printResult(
63346
- {
63347
- id: execution.id,
63348
- createdAt: execution.createdAt,
63349
- httpStatusCode: execution.httpStatusCode,
63350
- executionTime: execution.executionTime,
63351
- versionNumber: execution.versionNumber,
63352
- summary: execution.summary,
63353
- input: input2,
63354
- output: output2,
63355
- logs
63356
- },
63357
- // A single nested record reads better as JSON than a 1-row table.
63358
- fmt === "table" ? "json" : fmt
63359
- );
63931
+ printResult(await fn2.execution(executionId), fmt === "table" ? "json" : fmt);
63360
63932
  };
63361
63933
  var runFn = async (args) => {
63362
63934
  if (args[0] === "logs") return runLogs(args.slice(1));
@@ -63367,8 +63939,6 @@ var runFn = async (args) => {
63367
63939
  );
63368
63940
  }
63369
63941
  const method = (flagValue(args, "--method") ?? "POST").toUpperCase();
63370
- const rawPath = flagValue(args, "--path") ?? "";
63371
- const subPath = rawPath && !rawPath.startsWith("/") ? `/${rawPath}` : rawPath;
63372
63942
  const sendsBody = !["GET", "HEAD", "DELETE"].includes(method);
63373
63943
  if (!sendsBody && (args.includes("--input") || args.includes("-"))) {
63374
63944
  process.stderr.write(
@@ -63376,16 +63946,12 @@ var runFn = async (args) => {
63376
63946
  `
63377
63947
  );
63378
63948
  }
63379
- const input2 = sendsBody ? await collectInput(args) : void 0;
63380
- const { organizationId } = await getAccessToken();
63381
- const res = await v2Fetch(
63382
- `/v2/functions/${organizationId}/${functionId}${subPath}`,
63383
- {
63384
- method,
63385
- headers: sendsBody ? { "Content-Type": "application/json" } : {},
63386
- body: sendsBody ? JSON.stringify(input2) : void 0
63387
- }
63388
- );
63949
+ const res = await cliClient().fn(functionId).call({
63950
+ method,
63951
+ path: flagValue(args, "--path"),
63952
+ headers: sendsBody ? { "Content-Type": "application/json" } : {},
63953
+ body: sendsBody ? JSON.stringify(await collectInput(args)) : void 0
63954
+ });
63389
63955
  const executionId = res.headers.get("x-execution-id");
63390
63956
  if (executionId != null) {
63391
63957
  process.stderr.write(`execution: ${executionId}
@@ -63398,11 +63964,11 @@ var runFn = async (args) => {
63398
63964
  };
63399
63965
 
63400
63966
  // src/commands/graphql.ts
63401
- import { readFileSync as readFileSync7 } from "fs";
63967
+ import { readFileSync as readFileSync6 } from "fs";
63402
63968
  var runGraphql = async (args) => {
63403
63969
  const inline = await readValue(flagValue(args, "-q", "--query"), "-q");
63404
63970
  const file2 = flagValue(args, "-f", "--file");
63405
- const query = inline ?? (file2 != null ? readFileSync7(file2, "utf8") : process.stdin.isTTY ? "" : (await readStdin("the query")).trim());
63971
+ const query = inline ?? (file2 != null ? readFileSync6(file2, "utf8") : process.stdin.isTTY ? "" : (await readStdin("the query")).trim());
63406
63972
  if (query.length === 0) {
63407
63973
  throw new Error(
63408
63974
  "Provide a query with -q '<query>', -q @<file>, -f <file>, or stdin."
@@ -63426,14 +63992,19 @@ var runGraphql = async (args) => {
63426
63992
  );
63427
63993
  }
63428
63994
  })();
63429
- const res = await v2Fetch(
63430
- args.includes("--v1") ? "/v1/graphql" : "/v2/graphql",
63431
- {
63432
- method: "POST",
63433
- headers: { "Content-Type": "application/json" },
63434
- body: JSON.stringify({ query, variables })
63435
- }
63436
- );
63995
+ const format2 = resolveFormat(flagValue(args, "-o", "--output"));
63996
+ if (!args.includes("--v1")) {
63997
+ printResult(
63998
+ await gqlRequest(query, variables),
63999
+ format2
64000
+ );
64001
+ return;
64002
+ }
64003
+ const res = await cliClient().fetch("/v1/graphql", {
64004
+ method: "POST",
64005
+ headers: { "Content-Type": "application/json" },
64006
+ body: JSON.stringify({ query, variables })
64007
+ });
63437
64008
  const raw2 = await res.text();
63438
64009
  const body = (() => {
63439
64010
  try {
@@ -63449,39 +64020,11 @@ var runGraphql = async (args) => {
63449
64020
  if (body == null) {
63450
64021
  throw new Error("graphql returned an unreadable body.");
63451
64022
  }
63452
- printResult(body.data, resolveFormat(flagValue(args, "-o", "--output")));
64023
+ printResult(body.data, format2);
63453
64024
  };
63454
64025
 
63455
64026
  // src/commands/integration.ts
63456
64027
  var USAGE3 = "Usage: overai integration configure <id> --config <json|@file|@-> | integration config <id> | integration secret set <id> <KEY> --value <@file|@-> | integration secret unset <id> <KEY>";
63457
- var setSecret = async (integrationId, key, rawValue) => {
63458
- if (rawValue == null) {
63459
- throw new Error("Integration secret set requires --value.");
63460
- }
63461
- if (!rawValue.startsWith("@")) {
63462
- throw new Error(
63463
- "--value must be @- (stdin) or @<file>, so the secret stays out of your shell history."
63464
- );
63465
- }
63466
- const value = await readValue(rawValue, "--value");
63467
- if (value == null || value === "") {
63468
- throw new Error("--value resolved to an empty string.");
63469
- }
63470
- await gqlRequest(
63471
- `mutation SetIntegrationSecret($input: UpdateIntegrationConfigInput!) {
63472
- updateIntegrationConfig(input: $input) { success }
63473
- }`,
63474
- { input: { integrationId, partialConfig: { [key]: value } } }
63475
- );
63476
- };
63477
- var unsetSecret = async (integrationId, key) => {
63478
- await gqlRequest(
63479
- `mutation UnsetIntegrationSecret($input: DeleteIntegrationConfigKeyInput!) {
63480
- deleteIntegrationConfigKey(input: $input) { success }
63481
- }`,
63482
- { input: { integrationId, key } }
63483
- );
63484
- };
63485
64028
  var runIntegration = async (args) => {
63486
64029
  const [operation] = args;
63487
64030
  if (operation === "secret") {
@@ -63489,22 +64032,36 @@ var runIntegration = async (args) => {
63489
64032
  if (action !== "set" && action !== "unset" || id2 == null || key == null || key.startsWith("-")) {
63490
64033
  throw new Error(USAGE3);
63491
64034
  }
64035
+ const integration2 = cliClient().integration(id2);
63492
64036
  if (action === "set") {
63493
- await setSecret(id2, key, flagValue(args, "--value"));
64037
+ const rawValue = flagValue(args, "--value");
64038
+ if (rawValue == null) {
64039
+ throw new Error("Integration secret set requires --value.");
64040
+ }
64041
+ if (!rawValue.startsWith("@")) {
64042
+ throw new Error(
64043
+ "--value must be @- (stdin) or @<file>, so the secret stays out of your shell history."
64044
+ );
64045
+ }
64046
+ const value = await readValue(rawValue, "--value");
64047
+ if (value == null || value === "") {
64048
+ throw new Error("--value resolved to an empty string.");
64049
+ }
64050
+ await integration2.setSecret(key, value);
63494
64051
  } else {
63495
- await unsetSecret(id2, key);
64052
+ await integration2.unsetSecret(key);
63496
64053
  }
63497
- const result2 = await userTrpcMutation(
63498
- "getMaskedIntegrationConfig",
63499
- { id: id2 }
64054
+ printResult(
64055
+ await integration2.config(),
64056
+ resolveFormat(flagValue(args, "-o", "--output"))
63500
64057
  );
63501
- printResult(result2, resolveFormat(flagValue(args, "-o", "--output")));
63502
64058
  return;
63503
64059
  }
63504
64060
  const [, id] = args;
63505
64061
  if (id == null || operation !== "configure" && operation !== "config") {
63506
64062
  throw new Error(USAGE3);
63507
64063
  }
64064
+ const integration = cliClient().integration(id);
63508
64065
  if (operation === "configure") {
63509
64066
  const raw2 = await readValue(flagValue(args, "--config"), "--config");
63510
64067
  if (raw2 == null)
@@ -63516,16 +64073,16 @@ var runIntegration = async (args) => {
63516
64073
  throw new Error("--config must be valid JSON.");
63517
64074
  }
63518
64075
  })();
63519
- await userTrpcMutation("putIntegrationConfig", { id, value });
64076
+ await integration.configure(value);
63520
64077
  }
63521
- const result = await userTrpcMutation("getMaskedIntegrationConfig", {
63522
- id
63523
- });
63524
- printResult(result, resolveFormat(flagValue(args, "-o", "--output")));
64078
+ printResult(
64079
+ await integration.config(),
64080
+ resolveFormat(flagValue(args, "-o", "--output"))
64081
+ );
63525
64082
  };
63526
64083
 
63527
64084
  // src/commands/knowledgeBase.ts
63528
- import { readFile as readFile2 } from "fs/promises";
64085
+ import { openAsBlob as openAsBlob2 } from "fs";
63529
64086
  import { basename } from "path";
63530
64087
  var runKnowledgeBase = async (args) => {
63531
64088
  const [operation, id] = args;
@@ -63534,7 +64091,7 @@ var runKnowledgeBase = async (args) => {
63534
64091
  "Usage: overai knowledge-base upload <id> <file...> | knowledge-base search <id> <query> [--limit N]"
63535
64092
  );
63536
64093
  }
63537
- const { organizationId } = await getAccessToken();
64094
+ const knowledgeBase = cliClient().knowledgeBase(id);
63538
64095
  if (operation === "upload") {
63539
64096
  const paths = args.slice(2).filter(
63540
64097
  (arg, i, all) => !arg.startsWith("-") && all[i - 1] !== "-o" && all[i - 1] !== "--output"
@@ -63543,20 +64100,11 @@ var runKnowledgeBase = async (args) => {
63543
64100
  throw new Error("Knowledge base upload requires at least one file path.");
63544
64101
  const uploads = [];
63545
64102
  for (const path of paths) {
63546
- const bytes = await readFile2(path);
63547
- const formData = new FormData();
63548
- formData.append(
63549
- "file",
63550
- new Blob([new Uint8Array(bytes)]),
64103
+ const result = await knowledgeBase.upload(
64104
+ await openAsBlob2(path),
63551
64105
  basename(path)
63552
64106
  );
63553
- const response2 = await v2Fetch(
63554
- `/v2/knowledge-bases/${organizationId}/${id}/upload`,
63555
- { method: "POST", body: formData }
63556
- );
63557
- const raw3 = await response2.text();
63558
- if (!response2.ok) throw v2Error("knowledge-base upload", response2, raw3);
63559
- uploads.push({ file: basename(path), ...JSON.parse(raw3) });
64107
+ uploads.push({ file: basename(path), ...result });
63560
64108
  }
63561
64109
  printResult(uploads, resolveFormat(flagValue(args, "-o", "--output")));
63562
64110
  return;
@@ -63564,22 +64112,9 @@ var runKnowledgeBase = async (args) => {
63564
64112
  const query = args[2];
63565
64113
  if (query == null || query.startsWith("-"))
63566
64114
  throw new Error("Knowledge base search requires a query string.");
63567
- const limit2 = flagValue(args, "--limit");
63568
- const response = await v2Fetch(
63569
- `/v2/knowledge-bases/${organizationId}/${id}/search`,
63570
- {
63571
- method: "POST",
63572
- headers: { "Content-Type": "application/json" },
63573
- body: JSON.stringify({
63574
- query,
63575
- ...limit2 != null ? { limit: Number(limit2) } : {}
63576
- })
63577
- }
63578
- );
63579
- const raw2 = await response.text();
63580
- if (!response.ok) throw v2Error("knowledge-base search", response, raw2);
64115
+ const limit2 = integerFlag(args, "--limit");
63581
64116
  printResult(
63582
- JSON.parse(raw2),
64117
+ await knowledgeBase.search(query, limit2 != null ? { limit: limit2 } : {}),
63583
64118
  resolveFormat(flagValue(args, "-o", "--output"))
63584
64119
  );
63585
64120
  };
@@ -63872,25 +64407,16 @@ var unaliasOrg = async (alias) => {
63872
64407
  // src/commands/printablePage.ts
63873
64408
  var runPrintablePage = async (args) => {
63874
64409
  const [operation, id] = args;
63875
- if (operation !== "render" || id == null) throw new Error("Usage: overai printable-page render <id> [--search-params <json|@file>] [--timeout <ms>]");
63876
- const data = await gqlRequest(
63877
- `query CliPrintablePageWorkspace($id: String!) { printablePage(id: $id) { workspaceId } }`,
63878
- { id }
63879
- );
63880
- if (data.printablePage == null) throw new Error(`Printable page ${id} not found.`);
64410
+ if (operation !== "render" || id == null)
64411
+ throw new Error(
64412
+ "Usage: overai printable-page render <id> [--search-params <json|@file>] [--timeout <ms>]"
64413
+ );
63881
64414
  const searchParams = await readValue(flagValue(args, "--search-params"), "--search-params") ?? "{}";
63882
64415
  JSON.parse(searchParams);
63883
- const { organizationId } = await getAccessToken();
63884
- const timeoutMs = Number(flagValue(args, "--timeout") ?? 6e4);
63885
- const response = await v2Fetch(`/v2/actions/${organizationId}/${data.printablePage.workspaceId}/run`, {
63886
- method: "POST",
63887
- headers: { "Content-Type": "application/json" },
63888
- body: JSON.stringify({ actionId: "PRINTABLE_PAGE_TO_PDF", inputs: { printablePageId: id, searchParams, includeDiagnostics: true } }),
63889
- signal: AbortSignal.timeout(timeoutMs)
64416
+ const body = await cliClient().printablePage(id).render({
64417
+ searchParams,
64418
+ timeoutMs: integerFlag(args, "--timeout", 6e4)
63890
64419
  });
63891
- const raw2 = await response.text();
63892
- if (!response.ok) throw v2Error("printable-page render", response, raw2);
63893
- const body = JSON.parse(raw2);
63894
64420
  printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
63895
64421
  };
63896
64422
 
@@ -64313,7 +64839,7 @@ var runRemote = async (args) => {
64313
64839
 
64314
64840
  // src/commands/update.ts
64315
64841
  import { spawnSync as spawnSync2 } from "child_process";
64316
- import { existsSync as existsSync5, readFileSync as readFileSync8 } from "fs";
64842
+ import { existsSync as existsSync5, readFileSync as readFileSync7 } from "fs";
64317
64843
  import { fileURLToPath } from "url";
64318
64844
  var PACKAGE_NAME = "@overaihq/cli";
64319
64845
  var packageRootUrl = () => {
@@ -64331,7 +64857,7 @@ var compareVersions = (a, b) => {
64331
64857
  };
64332
64858
  var cliVersion = () => {
64333
64859
  const pkg = JSON.parse(
64334
- readFileSync8(new URL("package.json", packageRootUrl()), "utf8")
64860
+ readFileSync7(new URL("package.json", packageRootUrl()), "utf8")
64335
64861
  );
64336
64862
  return pkg.version;
64337
64863
  };
@@ -64438,8 +64964,7 @@ var runReport = async (args) => {
64438
64964
  }
64439
64965
  })();
64440
64966
  const resources = manifest ? Object.entries(manifest.resources) : [];
64441
- await userTrpcMutation("architectIssues.report", {
64442
- ...input2,
64967
+ await cliClient().report(input2.feedbackType, input2.detailedBugReport, {
64443
64968
  source: "cli",
64444
64969
  cliContext: {
64445
64970
  cliVersion: cliVersion(),
@@ -64478,12 +65003,12 @@ var runResource = async (args) => {
64478
65003
  );
64479
65004
  return;
64480
65005
  }
64481
- const timeout = flagValue(args, "--timeout");
65006
+ const timeout = integerFlag(args, "--timeout");
64482
65007
  const patch = {
64483
65008
  name: flagValue(args, "--name"),
64484
65009
  description: flagValue(args, "--description"),
64485
65010
  integrationTypeId: flagValue(args, "--type"),
64486
- actionTimeoutSeconds: timeout == null ? void 0 : Number(timeout)
65011
+ actionTimeoutSeconds: timeout
64487
65012
  };
64488
65013
  [
64489
65014
  ["isArchived", "--archive", true],
@@ -64617,6 +65142,19 @@ around a clone-sync mismatch; use the correct workspace folder.
64617
65142
  - Give each service its own credential. List, rotate, or revoke it with
64618
65143
  \`overai sql credential list|rotate|revoke\`.
64619
65144
 
65145
+ ## From a script
65146
+
65147
+ - The CLI is a shell over \`@overaihq/sdk\`. A Node script or a long-running
65148
+ program uses the package directly: \`createClient({ baseUrl, token: patToken(secret, baseUrl) })\`
65149
+ gives \`client.fn(id).call()\`, \`client.tableSpace(id).sql()\`,
65150
+ \`client.page(id).save()\`/\`.deploy()\`, \`client.workspaces.list()\`, and the
65151
+ rest of what the commands do, with the same errors. \`overai\` stays the right
65152
+ tool at a terminal; the SDK is for code.
65153
+ - \`@overaihq/sdk/env\` exports \`createEnv\`: \`await createEnv(client)\` is the \`env\` object function
65154
+ code already uses, outside the platform. Everything HTTP-backed is there
65155
+ (\`env.FNxxx.call\`, \`env.TBSxxx.sql\`, \`env.DFxxx.read\`, \`env.STORAGE\`,
65156
+ \`env.AI\`); \`env.BROWSER\` and \`env.CALLER\` exist only inside a function.
65157
+
64620
65158
  ## Reporting platform problems
64621
65159
 
64622
65160
  When broken or unexplained platform behavior blocks progress, send a detailed
@@ -65266,6 +65804,12 @@ Built-in variables:
65266
65804
  - \`env.CALLER\` (verified JWT claims from the request, or null \u2014 useful for identifying the calling user from a web page)
65267
65805
  - Any custom secrets/environment variables configured on the function
65268
65806
 
65807
+ The same \`env\` is importable outside the platform: \`import { createEnv } from "@overaihq/sdk/env"\` and \`const env = await createEnv(client)\`
65808
+ gives a Node script every HTTP-backed member above with the same names and
65809
+ shapes. \`env.BROWSER\` and \`env.CALLER\` exist only inside a function, and
65810
+ \`env.TBSxxx.sql\` there returns \`{ rows, rowCount }\` over HTTP instead of a
65811
+ direct database connection.
65812
+
65269
65813
  ## AI Access
65270
65814
 
65271
65815
  Generate text or structured objects using LLMs:
@@ -66683,38 +67227,17 @@ var runReview = async () => {
66683
67227
  process.stdout.write("Nothing modified locally \u2014 nothing to review.\n");
66684
67228
  return;
66685
67229
  }
67230
+ const client = cliClient();
66686
67231
  for (const target of lintTargets) {
66687
67232
  try {
66688
- const response = await v2Fetch("/v2/architect/lint", {
66689
- method: "POST",
66690
- headers: { "Content-Type": "application/json" },
66691
- body: JSON.stringify({
66692
- code: target.code,
66693
- surface: target.surface,
66694
- workspaceId: manifest.workspaceId,
66695
- functionOutputSchema: target.functionOutputSchema
66696
- })
67233
+ const response = await client.lint({
67234
+ code: target.code,
67235
+ surface: target.surface,
67236
+ workspaceId: manifest.workspaceId,
67237
+ functionOutputSchema: target.functionOutputSchema
66697
67238
  });
66698
- const responseText = await response.text();
66699
- if (!response.ok) {
66700
- throw new Error(
66701
- `${target.label}: HTTP ${String(response.status)}${responseText ? ` \u2014 ${responseText}` : ""}`
66702
- );
66703
- }
66704
- const parsed = lintResponseSchema.safeParse(
66705
- (() => {
66706
- try {
66707
- return JSON.parse(responseText);
66708
- } catch {
66709
- return null;
66710
- }
66711
- })()
66712
- );
66713
- if (!parsed.success) {
66714
- throw new Error(`${target.label}: invalid response from lint service`);
66715
- }
66716
67239
  findings2.push(
66717
- ...parsed.data.diagnostics.map(
67240
+ ...response.diagnostics.map(
66718
67241
  (diagnostic) => `${target.label}:${String(diagnostic.line)}:${String(diagnostic.column)}: ${diagnostic.severity}: ${diagnostic.message}${diagnostic.ruleId == null ? "" : ` (${diagnostic.ruleId})`}`
66719
67242
  )
66720
67243
  );
@@ -66749,23 +67272,6 @@ var runReview = async () => {
66749
67272
  import { createInterface as createInterface3 } from "readline";
66750
67273
 
66751
67274
  // src/commands/sqlCredential.ts
66752
- var connectionString = async (tableSpaceId, secret) => {
66753
- const response = await v2Fetch("/v2/cluster-info");
66754
- const body = await response.json();
66755
- return `postgresql://overai:${encodeURIComponent(secret)}@${body.postgres.host}:${String(body.postgres.port)}/${tableSpaceId}?sslmode=${body.postgres.sslMode}${body.postgres.sslMode === "verify-full" ? "&sslrootcert=system" : ""}`;
66756
- };
66757
- var credentialTableSpaceId = async (credentialId) => {
66758
- const data = await gqlRequest(
66759
- `query TableSpaceCredential($id: String!) {
66760
- tableSpaceCredential(id: $id) { tableSpaceId }
66761
- }`,
66762
- { id: credentialId }
66763
- );
66764
- if (!data.tableSpaceCredential) {
66765
- throw new Error("Credential not found or you lack access to it");
66766
- }
66767
- return data.tableSpaceCredential.tableSpaceId;
66768
- };
66769
67275
  var runSqlCredential = async (args) => {
66770
67276
  const [action, id] = args;
66771
67277
  if (!action || !id) {
@@ -66785,67 +67291,31 @@ var runSqlCredential = async (args) => {
66785
67291
  if (!args.includes("--never") && (!Number.isInteger(days) || days < 1)) {
66786
67292
  throw new Error("--expires-in must be a positive whole number of days");
66787
67293
  }
66788
- const data = await gqlRequest(
66789
- `mutation CreateTableSpaceCredential($tableSpaceId: String!, $name: String!, $validUntil: Datetime) {
66790
- createTableSpaceCredential(input: { tableSpaceId: $tableSpaceId, name: $name, validUntil: $validUntil }) { result }
66791
- }`,
66792
- {
66793
- tableSpaceId,
66794
- name: name2,
66795
- validUntil: args.includes("--never") ? null : new Date(Date.now() + days * 864e5).toISOString()
66796
- }
66797
- );
66798
- const result = data.createTableSpaceCredential?.result;
66799
- if (!result) throw new Error("The server did not return a credential");
66800
- process.stdout.write(
66801
- `${await connectionString(tableSpaceId, result.secret)}
66802
- `
66803
- );
67294
+ const credential = await cliClient().tableSpace(tableSpaceId).credentials.create({
67295
+ name: name2,
67296
+ validUntil: args.includes("--never") ? null : new Date(Date.now() + days * 864e5)
67297
+ });
67298
+ process.stdout.write(`${credential.connectionString}
67299
+ `);
66804
67300
  return;
66805
67301
  }
66806
67302
  if (action === "list") {
66807
67303
  const tableSpaceId = id;
66808
- const data = await gqlRequest(
66809
- `query TableSpaceCredentials($tableSpaceId: String!) {
66810
- tableSpaceCredentials(condition: { tableSpaceId: $tableSpaceId }) {
66811
- nodes { id name validUntil lastUsedAt createdAt }
66812
- }
66813
- }`,
66814
- { tableSpaceId }
66815
- );
66816
67304
  printResult(
66817
- data.tableSpaceCredentials?.nodes ?? [],
67305
+ await cliClient().tableSpace(tableSpaceId).credentials.list(),
66818
67306
  resolveFormat(flagValue(args, "-o", "--output"))
66819
67307
  );
66820
67308
  return;
66821
67309
  }
66822
67310
  if (action === "rotate") {
66823
- const credentialId = id;
66824
- const tableSpaceId = await credentialTableSpaceId(credentialId);
66825
- const data = await gqlRequest(
66826
- `mutation RotateTableSpaceCredential($credentialId: String!) {
66827
- rotateTableSpaceCredential(input: { credentialId: $credentialId }) { result }
66828
- }`,
66829
- { credentialId }
66830
- );
66831
- const secret = data.rotateTableSpaceCredential?.result;
66832
- if (!secret) throw new Error("The server did not return a credential");
66833
- process.stdout.write(`${await connectionString(tableSpaceId, secret)}
67311
+ const { connectionString: connectionString2 } = await cliClient().tableSpaceCredential(id).rotate();
67312
+ process.stdout.write(`${connectionString2}
66834
67313
  `);
66835
67314
  return;
66836
67315
  }
66837
67316
  if (action === "revoke") {
66838
- const credentialId = id;
66839
- await credentialTableSpaceId(credentialId);
66840
- await gqlRequest(
66841
- `mutation RevokeTableSpaceCredential($id: String!, $validUntil: Datetime!) {
66842
- updateTableSpaceCredential(input: { id: $id, patch: { validUntil: $validUntil } }) {
66843
- tableSpaceCredential { id }
66844
- }
66845
- }`,
66846
- { id: credentialId, validUntil: (/* @__PURE__ */ new Date()).toISOString() }
66847
- );
66848
- process.stdout.write(`${credentialId} revoked
67317
+ await cliClient().tableSpaceCredential(id).revoke();
67318
+ process.stdout.write(`${id} revoked
66849
67319
  `);
66850
67320
  return;
66851
67321
  }
@@ -66853,32 +67323,12 @@ var runSqlCredential = async (args) => {
66853
67323
  };
66854
67324
 
66855
67325
  // src/commands/sql.ts
66856
- var runQuery = async (organizationId, tableSpaceId, query, params) => {
66857
- const res = await v2Fetch(
66858
- `/v2/table-spaces/${organizationId}/${tableSpaceId}/run`,
66859
- {
66860
- method: "POST",
66861
- headers: { "Content-Type": "application/json" },
66862
- body: JSON.stringify(
66863
- params == null ? { query, ignoreCamelCase: true } : { unsafe: { query, params } }
66864
- )
66865
- }
66866
- );
66867
- const raw2 = await res.text();
66868
- const body = (() => {
66869
- try {
66870
- return JSON.parse(raw2);
66871
- } catch {
66872
- return null;
66873
- }
66874
- })();
66875
- if (!res.ok || body?.ok === false) throw v2Error("sql", res, raw2);
66876
- return {
66877
- rows: body?.rows ?? [],
66878
- rowCount: body?.rowCount ?? 0,
66879
- resultSetCount: body?.resultSetCount ?? 1,
66880
- durationMs: body?.durationMs ?? 0
66881
- };
67326
+ var runQuery = async (tableSpaceId, query, params) => {
67327
+ try {
67328
+ return await cliClient().tableSpace(tableSpaceId).sql(query, { params });
67329
+ } catch (error62) {
67330
+ throw withOrgHint(error62);
67331
+ }
66882
67332
  };
66883
67333
  var summarize = (result) => `(${String(result.rowCount)} row${result.rowCount === 1 ? "" : "s"}, ${String(result.durationMs)}ms)`;
66884
67334
  var REPL_HELP = ` \\dt list tables
@@ -66888,7 +67338,7 @@ var REPL_HELP = ` \\dt list tables
66888
67338
  Statements run when a line ends with ";". Each statement runs in its own
66889
67339
  transaction \u2014 BEGIN/SET/temp tables don't carry across statements.
66890
67340
  `;
66891
- var runRepl = async (organizationId, tableSpaceId, format2) => {
67341
+ var runRepl = async (tableSpaceId, format2) => {
66892
67342
  const interactive = process.stdin.isTTY;
66893
67343
  const rl = createInterface3({
66894
67344
  input: process.stdin,
@@ -66904,7 +67354,7 @@ var runRepl = async (organizationId, tableSpaceId, format2) => {
66904
67354
  };
66905
67355
  const execute = async (sql, params) => {
66906
67356
  try {
66907
- const result = await runQuery(organizationId, tableSpaceId, sql, params);
67357
+ const result = await runQuery(tableSpaceId, sql, params);
66908
67358
  if (result.rows.length > 0) {
66909
67359
  process.stdout.write(`${formatResult(result.rows, format2)}
66910
67360
  `);
@@ -67008,7 +67458,7 @@ var runSql = async (args) => {
67008
67458
  );
67009
67459
  }
67010
67460
  const format2 = resolveFormat(flagValue(args, "-o", "--output"));
67011
- const { organizationId } = await getAccessToken();
67461
+ await cliClient().organizationId();
67012
67462
  const query = (() => {
67013
67463
  const rest = args.slice(1);
67014
67464
  for (let i = 0; i < rest.length; i++) {
@@ -67021,9 +67471,8 @@ var runSql = async (args) => {
67021
67471
  }
67022
67472
  return void 0;
67023
67473
  })();
67024
- if (query == null) return runRepl(organizationId, tableSpaceId, format2);
67474
+ if (query == null) return runRepl(tableSpaceId, format2);
67025
67475
  const result = await runQuery(
67026
- organizationId,
67027
67476
  tableSpaceId,
67028
67477
  await readValue(query, "the query") ?? query
67029
67478
  );
@@ -67035,35 +67484,22 @@ var runSql = async (args) => {
67035
67484
  };
67036
67485
 
67037
67486
  // src/commands/storage.ts
67038
- import { openAsBlob, writeFileSync as writeFileSync5 } from "fs";
67487
+ import { openAsBlob as openAsBlob3, writeFileSync as writeFileSync5 } from "fs";
67039
67488
  var USAGE4 = "Usage: overai storage upload <path> [--no-random-prefix] | storage download <key> [path|-] | storage exists <key> | storage head <key> [--lines N] | storage presign <key> [--expires-in <seconds>]";
67040
67489
  var runStorage = async (args) => {
67041
67490
  const [operation, first2, second] = args;
67042
67491
  if (operation == null) throw new Error(USAGE4);
67043
- const { organizationId } = await getAccessToken();
67044
- const segment = (key) => encodeURIComponent(key);
67492
+ const storage = cliClient().storage;
67045
67493
  if (operation === "upload") {
67046
67494
  if (first2 == null || first2 === "-") {
67047
- throw new Error("Upload requires a file path (stdin uploads need a filename to build the key).");
67048
- }
67049
- const randomPrefix = !args.includes("--no-random-prefix");
67050
- const query = randomPrefix ? "" : "?disableRandomPrefix=true";
67051
- const response = await v2Fetch(
67052
- `/v2/storage/${organizationId}/stream${query}`,
67053
- {
67054
- method: "POST",
67055
- headers: {
67056
- "Content-Type": "application/octet-stream",
67057
- "x-file-name": first2.split("/").pop() ?? first2
67058
- },
67059
- body: await openAsBlob(first2)
67060
- }
67061
- );
67062
- if (!response.ok) {
67063
- throw v2Error("storage upload", response, await response.text());
67495
+ throw new Error(
67496
+ "Upload requires a file path (stdin uploads need a filename to build the key)."
67497
+ );
67064
67498
  }
67065
- const { path } = await response.json();
67066
- const key = path.startsWith(`${organizationId}/`) ? path.slice(organizationId.length + 1) : path;
67499
+ const { key, path } = await storage.upload(await openAsBlob3(first2), {
67500
+ name: first2.split("/").pop() ?? first2,
67501
+ randomPrefix: !args.includes("--no-random-prefix")
67502
+ });
67067
67503
  const format2 = resolveFormat(flagValue(args, "-o", "--output"));
67068
67504
  if (format2 === "json") printResult({ key, path }, format2);
67069
67505
  else process.stdout.write(`${key}
@@ -67072,59 +67508,38 @@ var runStorage = async (args) => {
67072
67508
  }
67073
67509
  if (first2 == null) throw new Error(USAGE4);
67074
67510
  if (operation === "download") {
67075
- const response = await v2Fetch(
67076
- `/v2/storage/${organizationId}/${segment(first2)}`,
67077
- { redirect: "follow" }
67078
- );
67079
- if (!response.ok) {
67080
- throw v2Error("storage download", response, await response.text());
67081
- }
67511
+ const response = await storage.download(first2);
67082
67512
  const bytes = Buffer.from(await response.arrayBuffer());
67083
67513
  if (second != null && second !== "-") writeFileSync5(second, bytes);
67084
67514
  else process.stdout.write(bytes);
67085
67515
  return;
67086
67516
  }
67087
67517
  if (operation === "exists") {
67088
- const response = await v2Fetch(
67089
- `/v2/storage/${organizationId}/${segment(first2)}/exists`
67090
- );
67091
- if (response.status === 404) {
67518
+ const meta3 = await storage.exists(first2);
67519
+ if (meta3 == null) {
67092
67520
  if (resolveFormat(flagValue(args, "-o", "--output")) === "json") {
67093
67521
  printResult({ exists: false }, "json");
67094
67522
  }
67095
67523
  process.exitCode = 1;
67096
67524
  return;
67097
67525
  }
67098
- if (!response.ok) {
67099
- throw v2Error("storage exists", response, await response.text());
67100
- }
67101
67526
  printResult(
67102
- { exists: true, ...await response.json() },
67527
+ { exists: true, ...meta3 },
67103
67528
  resolveFormat(flagValue(args, "-o", "--output"))
67104
67529
  );
67105
67530
  return;
67106
67531
  }
67107
67532
  if (operation === "head") {
67108
- const lines = flagValue(args, "--lines") ?? "50";
67109
- const response = await v2Fetch(
67110
- `/v2/storage/${organizationId}/${segment(first2)}/head?numLines=${encodeURIComponent(lines)}`
67533
+ process.stdout.write(
67534
+ await storage.head(first2, { lines: integerFlag(args, "--lines", 50) })
67111
67535
  );
67112
- if (!response.ok) {
67113
- throw v2Error("storage head", response, await response.text());
67114
- }
67115
- process.stdout.write(await response.text());
67116
67536
  return;
67117
67537
  }
67118
67538
  if (operation === "presign") {
67119
- const expiresIn2 = flagValue(args, "--expires-in") ?? String(60 * 60 * 24 * 7);
67120
- const response = await v2Fetch(
67121
- `/v2/storage/${organizationId}/${segment(first2)}/presign?expiresIn=${encodeURIComponent(expiresIn2)}`
67539
+ process.stdout.write(
67540
+ `${await storage.presign(first2, { expiresIn: integerFlag(args, "--expires-in", 60 * 60 * 24 * 7) })}
67541
+ `
67122
67542
  );
67123
- if (!response.ok) {
67124
- throw v2Error("storage presign", response, await response.text());
67125
- }
67126
- process.stdout.write(`${(await response.text()).trim()}
67127
- `);
67128
67543
  return;
67129
67544
  }
67130
67545
  throw new Error(USAGE4);
@@ -67136,7 +67551,7 @@ var workspaceIdFrom = (args) => args.find(
67136
67551
  ) ?? openClone().manifest.workspaceId;
67137
67552
  var listWorkspaces = async (args) => {
67138
67553
  const archived = args.includes("--archived");
67139
- const limit2 = Number(flagValue(args, "--limit") ?? 200);
67554
+ const limit2 = integerFlag(args, "--limit", 200);
67140
67555
  printResult(
67141
67556
  (await cliClient().workspaces.list({
67142
67557
  first: limit2,