@overaihq/cli 0.14.5 → 0.14.7

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 +431 -146
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -27703,22 +27703,7 @@ var whoami = (args = []) => {
27703
27703
  };
27704
27704
 
27705
27705
  // src/commands/agent.ts
27706
- var runAgent = async (args) => {
27707
- const [operation, id] = args;
27708
- if (operation !== "generate" || id == null) throw new Error("Usage: overai agent generate <id> --message <text|@file|@->");
27709
- const message = await readValue(flagValue(args, "--message", "-m"), "--message");
27710
- if (message == null) throw new Error("Agent generate requires --message.");
27711
- const { organizationId } = await getAccessToken();
27712
- const response = await v2Fetch(`/v2/agents/${organizationId}/${id}/generate/text`, {
27713
- method: "POST",
27714
- headers: { "Content-Type": "application/json" },
27715
- body: JSON.stringify({ message })
27716
- });
27717
- const raw2 = await response.text();
27718
- if (!response.ok) throw v2Error("agent generate", response, raw2);
27719
- const body = JSON.parse(raw2);
27720
- printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
27721
- };
27706
+ import { createInterface } from "readline";
27722
27707
 
27723
27708
  // src/gql.ts
27724
27709
  var gqlRequest = async (query, variables) => {
@@ -27748,6 +27733,283 @@ var gqlRequest = async (query, variables) => {
27748
27733
  return body.data;
27749
27734
  };
27750
27735
 
27736
+ // src/commands/agent.ts
27737
+ var USAGE = [
27738
+ "Usage:",
27739
+ " overai agent generate <id> --message <text|@file|@->",
27740
+ " overai agent tools <id> [--version <n>] [-o json|table|csv]",
27741
+ " overai agent chat <id> [--conversation <id>] [--message <text>]"
27742
+ ].join("\n");
27743
+ var generate = async (args, id) => {
27744
+ const message = await readValue(
27745
+ flagValue(args, "--message", "-m"),
27746
+ "--message"
27747
+ );
27748
+ if (message == null) throw new Error("Agent generate requires --message.");
27749
+ const { organizationId } = await getAccessToken();
27750
+ const response = await v2Fetch(
27751
+ `/v2/agents/${organizationId}/${id}/generate/text`,
27752
+ {
27753
+ method: "POST",
27754
+ headers: { "Content-Type": "application/json" },
27755
+ body: JSON.stringify({ message })
27756
+ }
27757
+ );
27758
+ const raw2 = await response.text();
27759
+ if (!response.ok) throw v2Error("agent generate", response, raw2);
27760
+ printResult(
27761
+ JSON.parse(raw2),
27762
+ resolveFormat(flagValue(args, "-o", "--output"))
27763
+ );
27764
+ };
27765
+ var deployedVersionNumber = async (id) => {
27766
+ const deployed = await gqlRequest(
27767
+ `query CliAgentDeployedVersion($id: String!) {
27768
+ agentDeployedVersions(condition: { agentId: $id }) { nodes { versionNumber } }
27769
+ }`,
27770
+ { id }
27771
+ );
27772
+ const versionNumber = deployed.agentDeployedVersions?.nodes[0]?.versionNumber;
27773
+ if (versionNumber == null) {
27774
+ throw new Error(
27775
+ `Agent ${id} has no deployed version; pass --version <n> to inspect a saved one.`
27776
+ );
27777
+ }
27778
+ return versionNumber;
27779
+ };
27780
+ var tools = async (args, id) => {
27781
+ const versionFlag = flagValue(args, "--version", "-v");
27782
+ if (versionFlag != null && !Number.isInteger(Number(versionFlag))) {
27783
+ throw new Error("--version must be an integer.");
27784
+ }
27785
+ const version = versionFlag == null ? await deployedVersionNumber(id) : Number(versionFlag);
27786
+ const data = await gqlRequest(
27787
+ `query CliAgentTools($id: String!, $version: Int!) {
27788
+ agent(id: $id) {
27789
+ name
27790
+ agentVersions(first: 1, condition: { versionNumber: $version }) {
27791
+ nodes {
27792
+ versionNumber
27793
+ model
27794
+ agentVersionFunctionsByAgentIdAndVersionNumber(orderBy: [FUNCTION_ID_ASC]) {
27795
+ nodes { functionId function { name } }
27796
+ }
27797
+ agentVersionTableSpacesByAgentIdAndVersionNumber(orderBy: [TABLE_SPACE_ID_ASC]) {
27798
+ nodes { tableSpaceId accessMode }
27799
+ }
27800
+ agentVersionAgentsByAgentIdAndVersionNumber(orderBy: [ATTACHED_AGENT_ID_ASC]) {
27801
+ nodes { attachedAgentId }
27802
+ }
27803
+ agentVersionKnowledgeBasesByAgentIdAndVersionNumber(orderBy: [KNOWLEDGE_BASE_ID_ASC]) {
27804
+ nodes { knowledgeBaseId }
27805
+ }
27806
+ agentVersionBuiltinToolSetsByAgentIdAndVersionNumber(orderBy: [TOOL_SET_ASC]) {
27807
+ nodes { toolSet }
27808
+ }
27809
+ }
27810
+ }
27811
+ }
27812
+ }`,
27813
+ { id, version }
27814
+ );
27815
+ if (data.agent == null) throw new Error(`Agent ${id} not found.`);
27816
+ const agentVersion = data.agent.agentVersions.nodes[0];
27817
+ if (agentVersion == null) {
27818
+ throw new Error(`Agent ${id} has no version ${String(version)}.`);
27819
+ }
27820
+ const rows = [
27821
+ ...agentVersion.agentVersionFunctionsByAgentIdAndVersionNumber.nodes.map(
27822
+ (link) => ({
27823
+ kind: "function",
27824
+ name: link.function?.name ?? link.functionId,
27825
+ detail: link.functionId
27826
+ })
27827
+ ),
27828
+ ...agentVersion.agentVersionTableSpacesByAgentIdAndVersionNumber.nodes.map(
27829
+ (link) => ({
27830
+ kind: "table space",
27831
+ name: link.tableSpaceId,
27832
+ detail: link.accessMode
27833
+ })
27834
+ ),
27835
+ ...agentVersion.agentVersionAgentsByAgentIdAndVersionNumber.nodes.map(
27836
+ (link) => ({
27837
+ kind: "sub-agent",
27838
+ name: link.attachedAgentId,
27839
+ detail: ""
27840
+ })
27841
+ ),
27842
+ ...agentVersion.agentVersionKnowledgeBasesByAgentIdAndVersionNumber.nodes.map(
27843
+ (link) => ({
27844
+ kind: "knowledge base",
27845
+ name: link.knowledgeBaseId,
27846
+ detail: ""
27847
+ })
27848
+ ),
27849
+ ...agentVersion.agentVersionBuiltinToolSetsByAgentIdAndVersionNumber.nodes.map(
27850
+ (link) => ({ kind: "built-in", name: link.toolSet, detail: "" })
27851
+ )
27852
+ ];
27853
+ const format2 = resolveFormat(flagValue(args, "-o", "--output"));
27854
+ if (format2 === "json") {
27855
+ printResult(
27856
+ {
27857
+ agent: data.agent.name,
27858
+ version: agentVersion.versionNumber,
27859
+ model: agentVersion.model,
27860
+ tools: rows
27861
+ },
27862
+ format2
27863
+ );
27864
+ return;
27865
+ }
27866
+ if (format2 === "table") {
27867
+ process.stdout.write(
27868
+ `${data.agent.name} \xB7 version ${String(agentVersion.versionNumber)} \xB7 ${agentVersion.model}
27869
+ `
27870
+ );
27871
+ }
27872
+ printResult(rows, format2);
27873
+ };
27874
+ var printStreamLine = (line) => {
27875
+ if (!line.startsWith("data: ")) return;
27876
+ const payload = line.slice(6);
27877
+ if (payload === "[DONE]") return;
27878
+ let event;
27879
+ try {
27880
+ event = JSON.parse(payload);
27881
+ } catch {
27882
+ return;
27883
+ }
27884
+ if (event.type === "text-delta" && event.delta != null) {
27885
+ process.stdout.write(event.delta);
27886
+ }
27887
+ if (event.type === "error") {
27888
+ process.stderr.write(`
27889
+ ${event.errorText ?? "agent turn failed"}
27890
+ `);
27891
+ }
27892
+ };
27893
+ var streamReply = async (response) => {
27894
+ const body = response.body;
27895
+ if (body == null) return;
27896
+ const decoder = new TextDecoder();
27897
+ let buffer = "";
27898
+ for await (const chunk of body) {
27899
+ buffer += decoder.decode(chunk, { stream: true });
27900
+ const lines = buffer.split("\n");
27901
+ buffer = lines.pop() ?? "";
27902
+ lines.forEach(printStreamLine);
27903
+ }
27904
+ printStreamLine(buffer + decoder.decode());
27905
+ };
27906
+ var send = async (organizationId, id, message, conversationId) => {
27907
+ const response = await v2Fetch(`/v2/agents/${organizationId}/${id}`, {
27908
+ method: "POST",
27909
+ headers: { "Content-Type": "application/json" },
27910
+ body: JSON.stringify({
27911
+ messages: [{ role: "user", parts: [{ type: "text", text: message }] }],
27912
+ conversationId
27913
+ })
27914
+ });
27915
+ if (!response.ok) {
27916
+ throw v2Error("agent chat", response, await response.text());
27917
+ }
27918
+ await streamReply(response);
27919
+ process.stdout.write("\n");
27920
+ };
27921
+ var createConversation = async (id, firstMessage) => {
27922
+ const versionNumber = await deployedVersionNumber(id);
27923
+ const created = await gqlRequest(
27924
+ `mutation CliCreateAgentConversation($input: CreateAgentConversationInput!) {
27925
+ createAgentConversation(input: $input) { agentConversation { id } }
27926
+ }`,
27927
+ {
27928
+ input: {
27929
+ agentConversation: {
27930
+ agentId: id,
27931
+ versionNumber,
27932
+ title: firstMessage.length > 50 ? `${firstMessage.slice(0, 47)}...` : firstMessage
27933
+ }
27934
+ }
27935
+ }
27936
+ );
27937
+ const conversationId = created.createAgentConversation?.agentConversation?.id;
27938
+ if (conversationId == null)
27939
+ throw new Error("Failed to create a conversation.");
27940
+ return conversationId;
27941
+ };
27942
+ var chat = async (args, id) => {
27943
+ const { organizationId } = await getAccessToken();
27944
+ let conversationId = flagValue(args, "--conversation", "-c") ?? null;
27945
+ const single = await readValue(
27946
+ flagValue(args, "--message", "-m"),
27947
+ "--message"
27948
+ );
27949
+ if (single != null) {
27950
+ conversationId ??= await createConversation(id, single);
27951
+ try {
27952
+ await send(organizationId, id, single, conversationId);
27953
+ } finally {
27954
+ process.stderr.write(`Conversation: ${conversationId}
27955
+ `);
27956
+ }
27957
+ return;
27958
+ }
27959
+ const interactive = process.stdin.isTTY;
27960
+ const rl = createInterface({
27961
+ input: process.stdin,
27962
+ ...interactive ? { output: process.stdout, historySize: 1e3, terminal: true } : {}
27963
+ });
27964
+ if (interactive) {
27965
+ process.stdout.write(
27966
+ `Chatting with ${id}. Ctrl-C to leave; each reply prints as it streams.
27967
+ `
27968
+ );
27969
+ rl.setPrompt("> ");
27970
+ rl.prompt();
27971
+ }
27972
+ for await (const line of rl) {
27973
+ const message = line.trim();
27974
+ if (message.length === 0) {
27975
+ if (interactive) rl.prompt();
27976
+ continue;
27977
+ }
27978
+ try {
27979
+ conversationId ??= await createConversation(id, message);
27980
+ await send(organizationId, id, message, conversationId);
27981
+ } catch (error) {
27982
+ process.stderr.write(
27983
+ `${error instanceof Error ? error.message : String(error)}
27984
+ `
27985
+ );
27986
+ }
27987
+ if (interactive) rl.prompt();
27988
+ }
27989
+ if (conversationId != null) {
27990
+ process.stderr.write(`
27991
+ Conversation: ${conversationId}
27992
+ `);
27993
+ }
27994
+ };
27995
+ var runAgent = async (args) => {
27996
+ const [operation, id] = args;
27997
+ if (id == null) throw new Error(USAGE);
27998
+ switch (operation) {
27999
+ case "generate":
28000
+ await generate(args, id);
28001
+ return;
28002
+ case "tools":
28003
+ await tools(args, id);
28004
+ return;
28005
+ case "chat":
28006
+ await chat(args, id);
28007
+ return;
28008
+ default:
28009
+ throw new Error(USAGE);
28010
+ }
28011
+ };
28012
+
27751
28013
  // src/commands/automation.ts
27752
28014
  var runRuns = async (automationId, args) => {
27753
28015
  const limit2 = Number(flagValue(args, "--limit") ?? 20);
@@ -28693,7 +28955,7 @@ var runList = async (args) => {
28693
28955
  resolveFormat(flagValue(args, "-o", "--output"))
28694
28956
  );
28695
28957
  };
28696
- var USAGE = "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";
28958
+ 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";
28697
28959
  var runRunner = async (args) => {
28698
28960
  const [sub, id, ...rest] = args;
28699
28961
  if (sub === "create" && id != null) return runCreate(id, rest);
@@ -28701,7 +28963,7 @@ var runRunner = async (args) => {
28701
28963
  if (sub === "run" && id != null) return runRun(id, rest);
28702
28964
  if (sub === "upload" && id != null) return runUpload(id, rest);
28703
28965
  if (sub === "list") return runList([id, ...rest].filter((a) => a != null));
28704
- process.stderr.write(USAGE);
28966
+ process.stderr.write(USAGE2);
28705
28967
  process.exitCode = 1;
28706
28968
  };
28707
28969
 
@@ -35297,7 +35559,7 @@ var runGraphql = async (args) => {
35297
35559
  };
35298
35560
 
35299
35561
  // src/commands/integration.ts
35300
- var USAGE2 = "Usage: overai integration configure <id> --config <json|@file|@-> | integration config <id> | integration secret set <id> <KEY> --value <@file|@-> | integration secret unset <id> <KEY>";
35562
+ 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>";
35301
35563
  var setSecret = async (integrationId, key, rawValue) => {
35302
35564
  if (rawValue == null) {
35303
35565
  throw new Error("Integration secret set requires --value.");
@@ -35331,7 +35593,7 @@ var runIntegration = async (args) => {
35331
35593
  if (operation === "secret") {
35332
35594
  const [, action, id2, key] = args;
35333
35595
  if (action !== "set" && action !== "unset" || id2 == null || key == null || key.startsWith("-")) {
35334
- throw new Error(USAGE2);
35596
+ throw new Error(USAGE3);
35335
35597
  }
35336
35598
  if (action === "set") {
35337
35599
  await setSecret(id2, key, flagValue(args, "--value"));
@@ -35347,7 +35609,7 @@ var runIntegration = async (args) => {
35347
35609
  }
35348
35610
  const [, id] = args;
35349
35611
  if (id == null || operation !== "configure" && operation !== "config") {
35350
- throw new Error(USAGE2);
35612
+ throw new Error(USAGE3);
35351
35613
  }
35352
35614
  if (operation === "configure") {
35353
35615
  const raw2 = await readValue(flagValue(args, "--config"), "--config");
@@ -35471,6 +35733,7 @@ var ID_PREFIXES = {
35471
35733
  automation_email_address: { prefix: "aea", body: 10 },
35472
35734
  automation_email_alert: { prefix: "aes", body: 10 },
35473
35735
  automation_error_alert_queue: { prefix: "aeaq", body: 10 },
35736
+ billing_period: { prefix: "bpd", body: 12 },
35474
35737
  browser_automation: { prefix: "bra", body: 10 },
35475
35738
  browser_automation_run: { prefix: "brr", body: 20 },
35476
35739
  browser_session_usage: { prefix: "bsu", body: 12 },
@@ -35575,6 +35838,108 @@ var idTableByPrefix = (id) => {
35575
35838
  return best?.table ?? null;
35576
35839
  };
35577
35840
 
35841
+ // src/commands/resource.ts
35842
+ var resources = {
35843
+ workspace: { collection: "workspaces", mutation: "updateWorkspace", result: "workspace", patch: "WorkspacePatch", fields: "id name description isArchived", editable: ["name", "description", "isArchived"] },
35844
+ automation: { collection: "automations", mutation: "updateAutomation", result: "automation", patch: "AutomationPatch", fields: "id name description isArchived isActive workspaceId", editable: ["name", "description", "isArchived", "isActive"] },
35845
+ function: { collection: "functions", mutation: "updateFunction", result: "function", patch: "FunctionPatch", fields: "id name description isArchived isEnabled workspaceId", editable: ["name", "description", "isArchived", "isEnabled"] },
35846
+ web_page: { collection: "webPages", mutation: "updateWebPage", result: "webPage", patch: "WebPagePatch", fields: "id name isArchived workspaceId", editable: ["name", "isArchived"] },
35847
+ printable_page: { collection: "printablePages", mutation: "updatePrintablePage", result: "printablePage", patch: "PrintablePagePatch", fields: "id name isArchived workspaceId", editable: ["name", "isArchived"] },
35848
+ agent: { collection: "agents", mutation: "updateAgent", result: "agent", patch: "AgentPatch", fields: "id name description isArchived isEnabled workspaceId", editable: ["name", "description", "isArchived", "isEnabled"] },
35849
+ integration: { collection: "integrations", mutation: "updateIntegration", result: "integration", patch: "IntegrationPatch", fields: "id name description isArchived integrationTypeId workspaceId", editable: ["name", "description", "isArchived", "integrationTypeId"] },
35850
+ table_space: { collection: "tableSpaces", mutation: "updateTableSpace", result: "tableSpace", patch: "TableSpacePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
35851
+ data_stream: { collection: "dataStreams", mutation: "updateDataStream", result: "dataStream", patch: "DataStreamPatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
35852
+ knowledge_base: { collection: "knowledgeBases", mutation: "updateKnowledgeBase", result: "knowledgeBase", patch: "KnowledgeBasePatch", fields: "id name description isArchived embeddingModel workspaceId", editable: ["name", "description", "isArchived"] },
35853
+ data_file: { collection: "dataFiles", mutation: "updateDataFile", result: "dataFile", patch: "DataFilePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
35854
+ action_runner: { collection: "actionRunners", mutation: "updateActionRunner", result: "actionRunner", patch: "ActionRunnerPatch", fields: "id isArchived actionTimeoutSeconds config workspaceId identityId identity { name }", editable: ["isArchived", "actionTimeoutSeconds", "config"] }
35855
+ // Keyed by table so `idTableByPrefix` can index it; `satisfies` rejects a key
35856
+ // the registry does not know.
35857
+ };
35858
+ var resourceFor = (id) => {
35859
+ const table = idTableByPrefix(id);
35860
+ const resource = table == null ? void 0 : resources[table];
35861
+ if (resource == null) throw new Error(`Unsupported resource id: ${id}`);
35862
+ return resource;
35863
+ };
35864
+ var readResource = async (id, resource) => {
35865
+ const data = await gqlRequest(
35866
+ `query CliResource($id: String!) {
35867
+ ${resource.collection}(condition: { idIgnoringCase: $id }, includeArchived: YES, first: 1) {
35868
+ nodes { ${resource.fields} }
35869
+ }
35870
+ }`,
35871
+ { id }
35872
+ );
35873
+ const row = data[resource.collection]?.nodes[0];
35874
+ if (row == null) throw new Error(`Resource ${id} not found.`);
35875
+ return row;
35876
+ };
35877
+ var runResource = async (args) => {
35878
+ const [operation, id] = args;
35879
+ if (operation !== "show" && operation !== "update" || id == null) {
35880
+ throw new Error("Usage: overai resource show <id> | resource update <id> [--name <name>] [--description <text>] [--archive|--restore] [--enable|--disable] [--active|--inactive]");
35881
+ }
35882
+ const resource = resourceFor(id);
35883
+ if (operation === "show") {
35884
+ printResult(await readResource(id, resource), resolveFormat(flagValue(args, "-o", "--output")));
35885
+ return;
35886
+ }
35887
+ const patch = {};
35888
+ const scalarFlags = [
35889
+ ["name", "--name"],
35890
+ ["description", "--description"],
35891
+ ["integrationTypeId", "--type"],
35892
+ ["actionTimeoutSeconds", "--timeout"]
35893
+ ];
35894
+ scalarFlags.forEach(([field, flag]) => {
35895
+ const value = flagValue(args, flag);
35896
+ if (value != null && resource.editable.includes(field)) {
35897
+ patch[field] = field === "actionTimeoutSeconds" ? Number(value) : value;
35898
+ }
35899
+ });
35900
+ [
35901
+ ["isArchived", "--archive", true],
35902
+ ["isArchived", "--restore", false],
35903
+ ["isEnabled", "--enable", true],
35904
+ ["isEnabled", "--disable", false],
35905
+ ["isActive", "--active", true],
35906
+ ["isActive", "--inactive", false]
35907
+ ].forEach(([field, flag, value]) => {
35908
+ if (args.includes(flag) && resource.editable.includes(field)) patch[field] = value;
35909
+ });
35910
+ const config = await readValue(flagValue(args, "--config"), "--config");
35911
+ if (config != null && resource.editable.includes("config")) {
35912
+ try {
35913
+ patch.config = JSON.parse(config);
35914
+ } catch {
35915
+ throw new Error("--config must be valid JSON (or @<file> containing JSON).");
35916
+ }
35917
+ }
35918
+ const current = await readResource(id, resource);
35919
+ const name2 = flagValue(args, "--name");
35920
+ if (name2 != null && idTableByPrefix(id) === "action_runner") {
35921
+ const result = await gqlRequest(
35922
+ `mutation CliRenameRunner($id: String!, $name: String!) {
35923
+ updateIdentity(input: { id: $id, patch: { name: $name } }) { identity { id } }
35924
+ }`,
35925
+ { id: current.identityId, name: name2 }
35926
+ );
35927
+ if (result.updateIdentity?.identity == null) throw new Error(`Runner ${id} could not be renamed; check your workspace role.`);
35928
+ }
35929
+ if (Object.keys(patch).length > 0) {
35930
+ const result = await gqlRequest(
35931
+ `mutation CliUpdateResource($id: String!, $patch: ${resource.patch}!) {
35932
+ ${resource.mutation}(input: { id: $id, patch: $patch }) { updated: ${resource.result} { id } }
35933
+ }`,
35934
+ { id: current.id, patch }
35935
+ );
35936
+ if (result[resource.mutation]?.updated == null) throw new Error(`Resource ${id} was not updated; check that it exists and your workspace role allows editing.`);
35937
+ } else if (!(name2 != null && idTableByPrefix(id) === "action_runner")) {
35938
+ throw new Error(`No supported changes supplied for ${id}.`);
35939
+ }
35940
+ printResult(await readResource(current.id, resource), resolveFormat(flagValue(args, "-o", "--output")));
35941
+ };
35942
+
35578
35943
  // src/commands/open.ts
35579
35944
  var ROUTE_BY_TYPE = {
35580
35945
  automation: "automations",
@@ -35600,7 +35965,7 @@ var ROUTE_BY_TABLE = {
35600
35965
  var runOpen = async (args) => {
35601
35966
  const filter2 = args.find((a) => !a.startsWith("-"));
35602
35967
  const { organizationId } = await getAccessToken();
35603
- const url = (() => {
35968
+ const url = await (async () => {
35604
35969
  const manifest = (() => {
35605
35970
  try {
35606
35971
  return readManifest(findWorkspaceRoot());
@@ -35613,11 +35978,11 @@ var runOpen = async (args) => {
35613
35978
  return `${appBaseUrl(apiBaseUrl())}/${manifest.organizationId}/workspaces/${manifest.workspaceId}`;
35614
35979
  }
35615
35980
  const match = Object.entries(manifest.resources).find(
35616
- ([id, r]) => id === filter2 || r.name.toLowerCase().includes(filter2.toLowerCase()) || r.files.some((f) => f.includes(filter2))
35981
+ ([id2, r]) => id2.toLowerCase() === filter2.toLowerCase() || r.name.toLowerCase().includes(filter2.toLowerCase()) || r.files.some((f) => f.includes(filter2))
35617
35982
  );
35618
35983
  if (match != null) {
35619
- const [id, resource] = match;
35620
- return `${appBaseUrl(apiBaseUrl())}/${manifest.organizationId}/${ROUTE_BY_TYPE[resource.type]}/${id}`;
35984
+ const [id2, resource2] = match;
35985
+ return `${appBaseUrl(apiBaseUrl())}/${manifest.organizationId}/${ROUTE_BY_TYPE[resource2.type]}/${id2}`;
35621
35986
  }
35622
35987
  }
35623
35988
  if (filter2 == null) {
@@ -35632,7 +35997,9 @@ var runOpen = async (args) => {
35632
35997
  `Nothing matched "${filter2}" (not a tracked resource or a recognized id prefix).`
35633
35998
  );
35634
35999
  }
35635
- return `${appBaseUrl(apiBaseUrl())}/${organizationId}/${route}/${filter2}`;
36000
+ const resource = table == null ? void 0 : resources[table];
36001
+ const id = resource == null ? filter2 : (await readResource(filter2, resource)).id;
36002
+ return `${appBaseUrl(apiBaseUrl())}/${organizationId}/${route}/${id}`;
35636
36003
  })();
35637
36004
  process.stdout.write(`${url}
35638
36005
  `);
@@ -35640,7 +36007,7 @@ var runOpen = async (args) => {
35640
36007
  };
35641
36008
 
35642
36009
  // src/commands/org.ts
35643
- import { createInterface } from "readline/promises";
36010
+ import { createInterface as createInterface2 } from "readline/promises";
35644
36011
  var USER_ORGS_QUERY = `
35645
36012
  query UserOrganizations($identityId: String!) {
35646
36013
  identityOrganizations(condition: { identityId: $identityId }) {
@@ -35770,7 +36137,7 @@ var promptForOrg = async () => {
35770
36137
  `
35771
36138
  );
35772
36139
  });
35773
- const rl = createInterface({ input: process.stdin, output: process.stdout });
36140
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
35774
36141
  try {
35775
36142
  const answer = await rl.question("Switch to: ");
35776
36143
  const chosen = rows[Number(answer.trim()) - 1];
@@ -36577,108 +36944,6 @@ var runReport = async (args) => {
36577
36944
  );
36578
36945
  };
36579
36946
 
36580
- // src/commands/resource.ts
36581
- var resources = {
36582
- workspace: { collection: "workspaces", mutation: "updateWorkspace", result: "workspace", patch: "WorkspacePatch", fields: "id name description isArchived", editable: ["name", "description", "isArchived"] },
36583
- automation: { collection: "automations", mutation: "updateAutomation", result: "automation", patch: "AutomationPatch", fields: "id name description isArchived isActive workspaceId", editable: ["name", "description", "isArchived", "isActive"] },
36584
- function: { collection: "functions", mutation: "updateFunction", result: "function", patch: "FunctionPatch", fields: "id name description isArchived isEnabled workspaceId", editable: ["name", "description", "isArchived", "isEnabled"] },
36585
- web_page: { collection: "webPages", mutation: "updateWebPage", result: "webPage", patch: "WebPagePatch", fields: "id name isArchived workspaceId", editable: ["name", "isArchived"] },
36586
- printable_page: { collection: "printablePages", mutation: "updatePrintablePage", result: "printablePage", patch: "PrintablePagePatch", fields: "id name isArchived workspaceId", editable: ["name", "isArchived"] },
36587
- agent: { collection: "agents", mutation: "updateAgent", result: "agent", patch: "AgentPatch", fields: "id name description isArchived isEnabled workspaceId", editable: ["name", "description", "isArchived", "isEnabled"] },
36588
- integration: { collection: "integrations", mutation: "updateIntegration", result: "integration", patch: "IntegrationPatch", fields: "id name description isArchived integrationTypeId workspaceId", editable: ["name", "description", "isArchived", "integrationTypeId"] },
36589
- table_space: { collection: "tableSpaces", mutation: "updateTableSpace", result: "tableSpace", patch: "TableSpacePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
36590
- data_stream: { collection: "dataStreams", mutation: "updateDataStream", result: "dataStream", patch: "DataStreamPatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
36591
- knowledge_base: { collection: "knowledgeBases", mutation: "updateKnowledgeBase", result: "knowledgeBase", patch: "KnowledgeBasePatch", fields: "id name description isArchived embeddingModel workspaceId", editable: ["name", "description", "isArchived"] },
36592
- data_file: { collection: "dataFiles", mutation: "updateDataFile", result: "dataFile", patch: "DataFilePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
36593
- action_runner: { collection: "actionRunners", mutation: "updateActionRunner", result: "actionRunner", patch: "ActionRunnerPatch", fields: "id isArchived actionTimeoutSeconds config workspaceId identityId identity { name }", editable: ["isArchived", "actionTimeoutSeconds", "config"] }
36594
- // Keyed by table so `idTableByPrefix` can index it; `satisfies` rejects a key
36595
- // the registry does not know.
36596
- };
36597
- var resourceFor = (id) => {
36598
- const table = idTableByPrefix(id);
36599
- const resource = table == null ? void 0 : resources[table];
36600
- if (resource == null) throw new Error(`Unsupported resource id: ${id}`);
36601
- return resource;
36602
- };
36603
- var readResource = async (id, resource) => {
36604
- const data = await gqlRequest(
36605
- `query CliResource($id: String!) {
36606
- ${resource.collection}(condition: { id: $id }, includeArchived: YES, first: 1) {
36607
- nodes { ${resource.fields} }
36608
- }
36609
- }`,
36610
- { id }
36611
- );
36612
- const row = data[resource.collection]?.nodes[0];
36613
- if (row == null) throw new Error(`Resource ${id} not found.`);
36614
- return row;
36615
- };
36616
- var runResource = async (args) => {
36617
- const [operation, id] = args;
36618
- if (operation !== "show" && operation !== "update" || id == null) {
36619
- throw new Error("Usage: overai resource show <id> | resource update <id> [--name <name>] [--description <text>] [--archive|--restore] [--enable|--disable] [--active|--inactive]");
36620
- }
36621
- const resource = resourceFor(id);
36622
- if (operation === "show") {
36623
- printResult(await readResource(id, resource), resolveFormat(flagValue(args, "-o", "--output")));
36624
- return;
36625
- }
36626
- const patch = {};
36627
- const scalarFlags = [
36628
- ["name", "--name"],
36629
- ["description", "--description"],
36630
- ["integrationTypeId", "--type"],
36631
- ["actionTimeoutSeconds", "--timeout"]
36632
- ];
36633
- scalarFlags.forEach(([field, flag]) => {
36634
- const value = flagValue(args, flag);
36635
- if (value != null && resource.editable.includes(field)) {
36636
- patch[field] = field === "actionTimeoutSeconds" ? Number(value) : value;
36637
- }
36638
- });
36639
- [
36640
- ["isArchived", "--archive", true],
36641
- ["isArchived", "--restore", false],
36642
- ["isEnabled", "--enable", true],
36643
- ["isEnabled", "--disable", false],
36644
- ["isActive", "--active", true],
36645
- ["isActive", "--inactive", false]
36646
- ].forEach(([field, flag, value]) => {
36647
- if (args.includes(flag) && resource.editable.includes(field)) patch[field] = value;
36648
- });
36649
- const config = await readValue(flagValue(args, "--config"), "--config");
36650
- if (config != null && resource.editable.includes("config")) {
36651
- try {
36652
- patch.config = JSON.parse(config);
36653
- } catch {
36654
- throw new Error("--config must be valid JSON (or @<file> containing JSON).");
36655
- }
36656
- }
36657
- const name2 = flagValue(args, "--name");
36658
- if (name2 != null && idTableByPrefix(id) === "action_runner") {
36659
- const current = await readResource(id, resource);
36660
- const result = await gqlRequest(
36661
- `mutation CliRenameRunner($id: String!, $name: String!) {
36662
- updateIdentity(input: { id: $id, patch: { name: $name } }) { identity { id } }
36663
- }`,
36664
- { id: current.identityId, name: name2 }
36665
- );
36666
- if (result.updateIdentity?.identity == null) throw new Error(`Runner ${id} could not be renamed; check your workspace role.`);
36667
- }
36668
- if (Object.keys(patch).length > 0) {
36669
- const result = await gqlRequest(
36670
- `mutation CliUpdateResource($id: String!, $patch: ${resource.patch}!) {
36671
- ${resource.mutation}(input: { id: $id, patch: $patch }) { updated: ${resource.result} { id } }
36672
- }`,
36673
- { id, patch }
36674
- );
36675
- if (result[resource.mutation]?.updated == null) throw new Error(`Resource ${id} was not updated; check that it exists and your workspace role allows editing.`);
36676
- } else if (!(name2 != null && idTableByPrefix(id) === "action_runner")) {
36677
- throw new Error(`No supported changes supplied for ${id}.`);
36678
- }
36679
- printResult(await readResource(id, resource), resolveFormat(flagValue(args, "-o", "--output")));
36680
- };
36681
-
36682
36947
  // src/docs/bestPractices.ts
36683
36948
  var platform2 = `# OverAI platform primer
36684
36949
 
@@ -36794,7 +37059,20 @@ A page version's config JSON carries the code; the CLI splits it into
36794
37059
  language, customTitle, hideTopBar, ...). Push reassembles them.
36795
37060
 
36796
37061
  - Web pages are React (TSX). Printable pages are React or Liquid.
36797
- - Web page config authorizationMode defaults to "workspace" for shared access.
37062
+ - Web page config authorizationMode defaults to "workspace": every end user
37063
+ who opens the page gets a workspace token that can read AND write every
37064
+ table space in the workspace and any shared into it, call any function it
37065
+ reaches, trigger any of its automations, and call any agent visible to it.
37066
+ Four rules follow:
37067
+ 1. The workspace is the unit of trust. Everything in it trusts everything
37068
+ else, and a page's end users count as "in it."
37069
+ 2. A public workspace is public all the way down. Public (or
37070
+ password-protected) is a workspace setting, not a page setting; every table space, function, automation
37071
+ and agent in it is reachable by anyone who can open a page.
37072
+ 3. Sharing into a workspace extends its trust. A table space shared into a
37073
+ public or password-protected workspace is public.
37074
+ 4. Cross a trust line with a function, not a table. Keep data in a private
37075
+ workspace and share a function into the page's workspace.
36798
37076
  Opt into "viewer" for personal pages spanning the signed-in viewer's workspaces.
36799
37077
  Page code uses their permissions; results/access errors can differ by user.
36800
37078
  Public links require sign-in. Save and deploy publishes the mode with the code.
@@ -36840,8 +37118,9 @@ language, customTitle, hideTopBar, ...). Push reassembles them.
36840
37118
  null. Identity-scoped features degrade: useAgentChat streams but persists
36841
37119
  nothing (conversationId stays null, useAgentConversations is empty, the
36842
37120
  conversation helpers throw), and author-requiring writes like
36843
- env.DFxxx.saveVersion 401. Reads use the workspace's own access, so treat
36844
- anything the page can query as public.
37121
+ env.DFxxx.saveVersion 401. The page runs on the workspace token, so anyone
37122
+ with the link can read and write every table space and call every function,
37123
+ automation and agent the workspace reaches (rule 2 above).
36845
37124
  - meta.json \`runtime\`: "v2" serves the page from its own origin (separate
36846
37125
  process, real localStorage/cookies \u2014 no noSandbox needed); absent or "v1" is
36847
37126
  the sandboxed srcdoc iframe. Anything else is rejected on push.
@@ -36887,11 +37166,15 @@ esm.sh imports allowed. The CLI materializes <slug>.<id>.ts (code) and
36887
37166
  executionMemory MB, callerAccess).
36888
37167
 
36889
37168
  - New functions allow only callers with workspace access by default. Set
36890
- callerAccess to "public" in meta.json only when an unauthenticated endpoint is
36891
- intended. Existing functions retain their saved policy when older meta.json
36892
- files omit this field. The policy is versioned: deploy the saved version to
36893
- change who can call the live endpoint. Workspace uses Authorization for the
36894
- platform bearer token; put additional application credentials in another header.
37169
+ callerAccess to "organization" to accept members of the function's organization
37170
+ or tokens from any private workspace in that organization without a share.
37171
+ A public-workspace token does not qualify; when a token has both workspace and
37172
+ user claims, the workspace claim takes precedence. Set callerAccess to "public"
37173
+ only when an unauthenticated endpoint is intended. Existing functions retain
37174
+ their saved policy when older meta.json files omit this field. The policy is
37175
+ versioned: deploy the saved version to change live access. Use Authorization
37176
+ for the platform bearer token; put application credentials in another header.
37177
+ Test as a user, a workspace, and anonymous before deploying.
36895
37178
  - Functions are full HTTP apps: method + sub-path are forwarded to your code,
36896
37179
  and each execution records requestMethod/requestPath. Callers reach a route
36897
37180
  with env.FNxxx.call({ method, path: "/features/123" }) \u2014 path defaults to the
@@ -37172,7 +37455,7 @@ var runReview = async () => {
37172
37455
  };
37173
37456
 
37174
37457
  // src/commands/sql.ts
37175
- import { createInterface as createInterface2 } from "readline";
37458
+ import { createInterface as createInterface3 } from "readline";
37176
37459
 
37177
37460
  // src/commands/sqlCredential.ts
37178
37461
  var connectionString = async (tableSpaceId, secret) => {
@@ -37316,7 +37599,7 @@ transaction \u2014 BEGIN/SET/temp tables don't carry across statements.
37316
37599
  `;
37317
37600
  var runRepl = async (organizationId, tableSpaceId, format2) => {
37318
37601
  const interactive = process.stdin.isTTY;
37319
- const rl = createInterface2({
37602
+ const rl = createInterface3({
37320
37603
  input: process.stdin,
37321
37604
  ...interactive ? { output: process.stdout, historySize: 1e3, terminal: true } : {}
37322
37605
  });
@@ -37462,10 +37745,10 @@ var runSql = async (args) => {
37462
37745
 
37463
37746
  // src/commands/storage.ts
37464
37747
  import { openAsBlob, writeFileSync as writeFileSync6 } from "fs";
37465
- var USAGE3 = "Usage: overai storage upload <path> [--no-random-prefix] | storage download <key> [path|-] | storage exists <key> | storage head <key> [--lines N] | storage presign <key> [--expires-in <seconds>]";
37748
+ 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>]";
37466
37749
  var runStorage = async (args) => {
37467
37750
  const [operation, first2, second] = args;
37468
- if (operation == null) throw new Error(USAGE3);
37751
+ if (operation == null) throw new Error(USAGE4);
37469
37752
  const { organizationId } = await getAccessToken();
37470
37753
  const segment = (key) => encodeURIComponent(key);
37471
37754
  if (operation === "upload") {
@@ -37496,7 +37779,7 @@ var runStorage = async (args) => {
37496
37779
  `);
37497
37780
  return;
37498
37781
  }
37499
- if (first2 == null) throw new Error(USAGE3);
37782
+ if (first2 == null) throw new Error(USAGE4);
37500
37783
  if (operation === "download") {
37501
37784
  const response = await v2Fetch(
37502
37785
  `/v2/storage/${organizationId}/${segment(first2)}`,
@@ -37553,7 +37836,7 @@ var runStorage = async (args) => {
37553
37836
  `);
37554
37837
  return;
37555
37838
  }
37556
- throw new Error(USAGE3);
37839
+ throw new Error(USAGE4);
37557
37840
  };
37558
37841
 
37559
37842
  // src/commands/workspace.ts
@@ -37639,7 +37922,7 @@ var listWorkspaceUsers = async (args) => {
37639
37922
  resolveFormat(flagValue(args, "-o", "--output"))
37640
37923
  );
37641
37924
  };
37642
- var USAGE4 = `Usage:
37925
+ var USAGE5 = `Usage:
37643
37926
  overai workspace list [--archived] [--limit <n>]
37644
37927
  overai workspace show [workspaceId]
37645
37928
  overai workspace users [workspaceId]
@@ -37657,7 +37940,7 @@ var runWorkspace = async (args) => {
37657
37940
  await listWorkspaceUsers(args.slice(1));
37658
37941
  return;
37659
37942
  }
37660
- process.stderr.write(USAGE4);
37943
+ process.stderr.write(USAGE5);
37661
37944
  process.exitCode = 1;
37662
37945
  };
37663
37946
 
@@ -37815,6 +38098,8 @@ Automations:
37815
38098
 
37816
38099
  Other resources:
37817
38100
  overai agent generate <agentId> --message <text|@file|@->
38101
+ overai agent tools <agentId> [--version <n>]
38102
+ overai agent chat <agentId> [--conversation <id>] [--message <text>]
37818
38103
  overai data-stream append <id> <json|@file|@->
37819
38104
  overai data-stream query <id> --start <date> --end <date> [--query <filter>]
37820
38105
  overai data-file upload <id> <path> [-m <message>]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overaihq/cli",
3
- "version": "0.14.5",
3
+ "version": "0.14.7",
4
4
  "description": "Create, edit, deploy, and run OverAI workspace resources from the command line",
5
5
  "type": "module",
6
6
  "homepage": "https://overai.com",