@overaihq/cli 0.14.6 → 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 +136 -115
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -35733,6 +35733,7 @@ var ID_PREFIXES = {
35733
35733
  automation_email_address: { prefix: "aea", body: 10 },
35734
35734
  automation_email_alert: { prefix: "aes", body: 10 },
35735
35735
  automation_error_alert_queue: { prefix: "aeaq", body: 10 },
35736
+ billing_period: { prefix: "bpd", body: 12 },
35736
35737
  browser_automation: { prefix: "bra", body: 10 },
35737
35738
  browser_automation_run: { prefix: "brr", body: 20 },
35738
35739
  browser_session_usage: { prefix: "bsu", body: 12 },
@@ -35837,6 +35838,108 @@ var idTableByPrefix = (id) => {
35837
35838
  return best?.table ?? null;
35838
35839
  };
35839
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
+
35840
35943
  // src/commands/open.ts
35841
35944
  var ROUTE_BY_TYPE = {
35842
35945
  automation: "automations",
@@ -35862,7 +35965,7 @@ var ROUTE_BY_TABLE = {
35862
35965
  var runOpen = async (args) => {
35863
35966
  const filter2 = args.find((a) => !a.startsWith("-"));
35864
35967
  const { organizationId } = await getAccessToken();
35865
- const url = (() => {
35968
+ const url = await (async () => {
35866
35969
  const manifest = (() => {
35867
35970
  try {
35868
35971
  return readManifest(findWorkspaceRoot());
@@ -35875,11 +35978,11 @@ var runOpen = async (args) => {
35875
35978
  return `${appBaseUrl(apiBaseUrl())}/${manifest.organizationId}/workspaces/${manifest.workspaceId}`;
35876
35979
  }
35877
35980
  const match = Object.entries(manifest.resources).find(
35878
- ([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))
35879
35982
  );
35880
35983
  if (match != null) {
35881
- const [id, resource] = match;
35882
- 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}`;
35883
35986
  }
35884
35987
  }
35885
35988
  if (filter2 == null) {
@@ -35894,7 +35997,9 @@ var runOpen = async (args) => {
35894
35997
  `Nothing matched "${filter2}" (not a tracked resource or a recognized id prefix).`
35895
35998
  );
35896
35999
  }
35897
- 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}`;
35898
36003
  })();
35899
36004
  process.stdout.write(`${url}
35900
36005
  `);
@@ -36839,108 +36944,6 @@ var runReport = async (args) => {
36839
36944
  );
36840
36945
  };
36841
36946
 
36842
- // src/commands/resource.ts
36843
- var resources = {
36844
- workspace: { collection: "workspaces", mutation: "updateWorkspace", result: "workspace", patch: "WorkspacePatch", fields: "id name description isArchived", editable: ["name", "description", "isArchived"] },
36845
- automation: { collection: "automations", mutation: "updateAutomation", result: "automation", patch: "AutomationPatch", fields: "id name description isArchived isActive workspaceId", editable: ["name", "description", "isArchived", "isActive"] },
36846
- function: { collection: "functions", mutation: "updateFunction", result: "function", patch: "FunctionPatch", fields: "id name description isArchived isEnabled workspaceId", editable: ["name", "description", "isArchived", "isEnabled"] },
36847
- web_page: { collection: "webPages", mutation: "updateWebPage", result: "webPage", patch: "WebPagePatch", fields: "id name isArchived workspaceId", editable: ["name", "isArchived"] },
36848
- printable_page: { collection: "printablePages", mutation: "updatePrintablePage", result: "printablePage", patch: "PrintablePagePatch", fields: "id name isArchived workspaceId", editable: ["name", "isArchived"] },
36849
- agent: { collection: "agents", mutation: "updateAgent", result: "agent", patch: "AgentPatch", fields: "id name description isArchived isEnabled workspaceId", editable: ["name", "description", "isArchived", "isEnabled"] },
36850
- integration: { collection: "integrations", mutation: "updateIntegration", result: "integration", patch: "IntegrationPatch", fields: "id name description isArchived integrationTypeId workspaceId", editable: ["name", "description", "isArchived", "integrationTypeId"] },
36851
- table_space: { collection: "tableSpaces", mutation: "updateTableSpace", result: "tableSpace", patch: "TableSpacePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
36852
- data_stream: { collection: "dataStreams", mutation: "updateDataStream", result: "dataStream", patch: "DataStreamPatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
36853
- knowledge_base: { collection: "knowledgeBases", mutation: "updateKnowledgeBase", result: "knowledgeBase", patch: "KnowledgeBasePatch", fields: "id name description isArchived embeddingModel workspaceId", editable: ["name", "description", "isArchived"] },
36854
- data_file: { collection: "dataFiles", mutation: "updateDataFile", result: "dataFile", patch: "DataFilePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
36855
- action_runner: { collection: "actionRunners", mutation: "updateActionRunner", result: "actionRunner", patch: "ActionRunnerPatch", fields: "id isArchived actionTimeoutSeconds config workspaceId identityId identity { name }", editable: ["isArchived", "actionTimeoutSeconds", "config"] }
36856
- // Keyed by table so `idTableByPrefix` can index it; `satisfies` rejects a key
36857
- // the registry does not know.
36858
- };
36859
- var resourceFor = (id) => {
36860
- const table = idTableByPrefix(id);
36861
- const resource = table == null ? void 0 : resources[table];
36862
- if (resource == null) throw new Error(`Unsupported resource id: ${id}`);
36863
- return resource;
36864
- };
36865
- var readResource = async (id, resource) => {
36866
- const data = await gqlRequest(
36867
- `query CliResource($id: String!) {
36868
- ${resource.collection}(condition: { id: $id }, includeArchived: YES, first: 1) {
36869
- nodes { ${resource.fields} }
36870
- }
36871
- }`,
36872
- { id }
36873
- );
36874
- const row = data[resource.collection]?.nodes[0];
36875
- if (row == null) throw new Error(`Resource ${id} not found.`);
36876
- return row;
36877
- };
36878
- var runResource = async (args) => {
36879
- const [operation, id] = args;
36880
- if (operation !== "show" && operation !== "update" || id == null) {
36881
- throw new Error("Usage: overai resource show <id> | resource update <id> [--name <name>] [--description <text>] [--archive|--restore] [--enable|--disable] [--active|--inactive]");
36882
- }
36883
- const resource = resourceFor(id);
36884
- if (operation === "show") {
36885
- printResult(await readResource(id, resource), resolveFormat(flagValue(args, "-o", "--output")));
36886
- return;
36887
- }
36888
- const patch = {};
36889
- const scalarFlags = [
36890
- ["name", "--name"],
36891
- ["description", "--description"],
36892
- ["integrationTypeId", "--type"],
36893
- ["actionTimeoutSeconds", "--timeout"]
36894
- ];
36895
- scalarFlags.forEach(([field, flag]) => {
36896
- const value = flagValue(args, flag);
36897
- if (value != null && resource.editable.includes(field)) {
36898
- patch[field] = field === "actionTimeoutSeconds" ? Number(value) : value;
36899
- }
36900
- });
36901
- [
36902
- ["isArchived", "--archive", true],
36903
- ["isArchived", "--restore", false],
36904
- ["isEnabled", "--enable", true],
36905
- ["isEnabled", "--disable", false],
36906
- ["isActive", "--active", true],
36907
- ["isActive", "--inactive", false]
36908
- ].forEach(([field, flag, value]) => {
36909
- if (args.includes(flag) && resource.editable.includes(field)) patch[field] = value;
36910
- });
36911
- const config = await readValue(flagValue(args, "--config"), "--config");
36912
- if (config != null && resource.editable.includes("config")) {
36913
- try {
36914
- patch.config = JSON.parse(config);
36915
- } catch {
36916
- throw new Error("--config must be valid JSON (or @<file> containing JSON).");
36917
- }
36918
- }
36919
- const name2 = flagValue(args, "--name");
36920
- if (name2 != null && idTableByPrefix(id) === "action_runner") {
36921
- const current = await readResource(id, resource);
36922
- const result = await gqlRequest(
36923
- `mutation CliRenameRunner($id: String!, $name: String!) {
36924
- updateIdentity(input: { id: $id, patch: { name: $name } }) { identity { id } }
36925
- }`,
36926
- { id: current.identityId, name: name2 }
36927
- );
36928
- if (result.updateIdentity?.identity == null) throw new Error(`Runner ${id} could not be renamed; check your workspace role.`);
36929
- }
36930
- if (Object.keys(patch).length > 0) {
36931
- const result = await gqlRequest(
36932
- `mutation CliUpdateResource($id: String!, $patch: ${resource.patch}!) {
36933
- ${resource.mutation}(input: { id: $id, patch: $patch }) { updated: ${resource.result} { id } }
36934
- }`,
36935
- { id, patch }
36936
- );
36937
- if (result[resource.mutation]?.updated == null) throw new Error(`Resource ${id} was not updated; check that it exists and your workspace role allows editing.`);
36938
- } else if (!(name2 != null && idTableByPrefix(id) === "action_runner")) {
36939
- throw new Error(`No supported changes supplied for ${id}.`);
36940
- }
36941
- printResult(await readResource(id, resource), resolveFormat(flagValue(args, "-o", "--output")));
36942
- };
36943
-
36944
36947
  // src/docs/bestPractices.ts
36945
36948
  var platform2 = `# OverAI platform primer
36946
36949
 
@@ -37056,7 +37059,20 @@ A page version's config JSON carries the code; the CLI splits it into
37056
37059
  language, customTitle, hideTopBar, ...). Push reassembles them.
37057
37060
 
37058
37061
  - Web pages are React (TSX). Printable pages are React or Liquid.
37059
- - 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.
37060
37076
  Opt into "viewer" for personal pages spanning the signed-in viewer's workspaces.
37061
37077
  Page code uses their permissions; results/access errors can differ by user.
37062
37078
  Public links require sign-in. Save and deploy publishes the mode with the code.
@@ -37102,8 +37118,9 @@ language, customTitle, hideTopBar, ...). Push reassembles them.
37102
37118
  null. Identity-scoped features degrade: useAgentChat streams but persists
37103
37119
  nothing (conversationId stays null, useAgentConversations is empty, the
37104
37120
  conversation helpers throw), and author-requiring writes like
37105
- env.DFxxx.saveVersion 401. Reads use the workspace's own access, so treat
37106
- 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).
37107
37124
  - meta.json \`runtime\`: "v2" serves the page from its own origin (separate
37108
37125
  process, real localStorage/cookies \u2014 no noSandbox needed); absent or "v1" is
37109
37126
  the sandboxed srcdoc iframe. Anything else is rejected on push.
@@ -37149,11 +37166,15 @@ esm.sh imports allowed. The CLI materializes <slug>.<id>.ts (code) and
37149
37166
  executionMemory MB, callerAccess).
37150
37167
 
37151
37168
  - New functions allow only callers with workspace access by default. Set
37152
- callerAccess to "public" in meta.json only when an unauthenticated endpoint is
37153
- intended. Existing functions retain their saved policy when older meta.json
37154
- files omit this field. The policy is versioned: deploy the saved version to
37155
- change who can call the live endpoint. Workspace uses Authorization for the
37156
- 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.
37157
37178
  - Functions are full HTTP apps: method + sub-path are forwarded to your code,
37158
37179
  and each execution records requestMethod/requestPath. Callers reach a route
37159
37180
  with env.FNxxx.call({ method, path: "/features/123" }) \u2014 path defaults to the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overaihq/cli",
3
- "version": "0.14.6",
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",