@overaihq/cli 0.12.1 → 0.13.1

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.
@@ -370,12 +370,22 @@ var pageErrorPayloadSchema = external_exports.object({
370
370
  message: external_exports.string(),
371
371
  stack: external_exports.string().optional()
372
372
  });
373
+ var screenshotResultPayloadSchema = external_exports.object({
374
+ requestId: external_exports.string(),
375
+ error: external_exports.string().optional(),
376
+ mediaType: external_exports.string().optional(),
377
+ data: external_exports.string().optional(),
378
+ width: external_exports.number().optional(),
379
+ height: external_exports.number().optional()
380
+ });
373
381
 
374
382
  // ../common/src/webPage.ts
375
383
  var webPageLanguage = ["react"];
376
384
  var configFlag = external_exports.union([external_exports.boolean(), external_exports.string()]).nullish().transform((value) => value === true || value === "true").catch(false);
377
385
  var webPageConfigSchema = external_exports.object({
378
386
  language: external_exports.enum(["react"]).catch("react"),
387
+ /* Missing on legacy versions; invalid modes fail closed instead of granting workspace access. */
388
+ authorizationMode: external_exports.enum(["workspace", "viewer"]).default("workspace"),
379
389
  customTitle: external_exports.string().nullish(),
380
390
  code: external_exports.string().default(reactDefaultTemplate),
381
391
  dataSourceUrl: external_exports.string().nullish(),
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  itemFilterExpressionRootSchema,
7
7
  webPageConfigSchema
8
- } from "./chunk-KIHU74V6.js";
8
+ } from "./chunk-56E4CWBE.js";
9
9
  import {
10
10
  external_exports
11
11
  } from "./chunk-XCJJTK3H.js";
@@ -26821,7 +26821,10 @@ var gqlRequest = async (query, variables) => {
26821
26821
  }
26822
26822
  })();
26823
26823
  if (body?.errors != null && body.errors.length > 0) {
26824
- throw new Error(body.errors.map((e) => e.message).join("; "));
26824
+ throw Object.assign(
26825
+ new Error(body.errors.map((e) => e.message).join("; ")),
26826
+ { errors: body.errors }
26827
+ );
26825
26828
  }
26826
26829
  if (!res.ok) throw v2Error("graphql", res, raw2);
26827
26830
  if (body?.data == null) {
@@ -27083,7 +27086,7 @@ var validateAutomationElements = async (elements) => {
27083
27086
  return findings(automationNodesSchema.safeParse(elements));
27084
27087
  };
27085
27088
  var validateWebPageConfig = async (config) => {
27086
- const { webPageConfigWriteSchema } = await import("./webPage-675DU764.js");
27089
+ const { webPageConfigWriteSchema } = await import("./webPage-4HUHD7FS.js");
27087
27090
  return findings(webPageConfigWriteSchema.safeParse(config));
27088
27091
  };
27089
27092
 
@@ -27116,7 +27119,7 @@ var functionAdapter = {
27116
27119
  functions(condition: { workspaceId: $workspaceId }, includeArchived: NO) {
27117
27120
  nodes {
27118
27121
  id name
27119
- functionVersions(orderBy: [CREATED_AT_DESC], first: 1) {
27122
+ functionVersions(orderBy: [VERSION_NUMBER_DESC], first: 1) {
27120
27123
  nodes { versionNumber code inputSchema outputSchema executionTimeout executionCpu executionMemory }
27121
27124
  }
27122
27125
  functionDeployedVersion { versionNumber }
@@ -27143,7 +27146,7 @@ var functionAdapter = {
27143
27146
  const data = await gqlRequest(
27144
27147
  `query CliFunctionHead($id: String!) {
27145
27148
  function(id: $id) {
27146
- functionVersions(orderBy: [CREATED_AT_DESC], first: 1) { nodes { versionNumber } }
27149
+ functionVersions(orderBy: [VERSION_NUMBER_DESC], first: 1) { nodes { versionNumber } }
27147
27150
  functionDeployedVersion { versionNumber }
27148
27151
  }
27149
27152
  }`,
@@ -27171,11 +27174,11 @@ var functionAdapter = {
27171
27174
  }
27172
27175
  return functionFiles(id, name2, data.functionVersion);
27173
27176
  },
27174
- push: async (id, files, message) => {
27177
+ push: async (id, files, message, expectedLatestVersion) => {
27175
27178
  const meta = JSON.parse(fileBySuffix(files, ".meta.json"));
27176
27179
  const data = await gqlRequest(
27177
- `mutation CliCreateFunctionVersion($functionId: String!, $code: String!, $message: String, $inputSchema: String, $outputSchema: String, $executionTimeout: Int, $executionCpu: Int, $executionMemory: Int) {
27178
- createFunctionVersion(input: { functionVersion: {
27180
+ `mutation CliCreateFunctionVersion($expectedLatestVersion: Int, $functionId: String!, $code: String!, $message: String, $inputSchema: String, $outputSchema: String, $executionTimeout: Int, $executionCpu: Int, $executionMemory: Int) {
27181
+ createFunctionVersion(input: { expectedLatestVersion: $expectedLatestVersion, functionVersion: {
27179
27182
  functionId: $functionId, code: $code, message: $message,
27180
27183
  inputSchema: $inputSchema, outputSchema: $outputSchema,
27181
27184
  executionTimeout: $executionTimeout, executionCpu: $executionCpu,
@@ -27183,6 +27186,7 @@ var functionAdapter = {
27183
27186
  }}) { functionVersion { versionNumber } }
27184
27187
  }`,
27185
27188
  {
27189
+ expectedLatestVersion,
27186
27190
  functionId: id,
27187
27191
  code: fileBySuffix(files, ".ts"),
27188
27192
  message,
@@ -27301,7 +27305,7 @@ var pageAdapter = (opts) => {
27301
27305
  }
27302
27306
  return pageFiles(opts.dir, id, name2, version.config);
27303
27307
  },
27304
- push: async (id, files, message) => {
27308
+ push: async (id, files, message, expectedLatestVersion) => {
27305
27309
  const config = pageConfigFromFiles(files);
27306
27310
  const findings2 = await opts.validateConfig?.(config) ?? [];
27307
27311
  if (findings2.length > 0) {
@@ -27311,12 +27315,12 @@ ${findings2.map((f) => ` ${f}`).join("\n")}`
27311
27315
  );
27312
27316
  }
27313
27317
  const data = await gqlRequest(
27314
- `mutation CliCreatePageVersion($id: String!, $message: String, $config: JSON!) {
27315
- create${capitalized}Version(input: { ${gqlName}Version: { ${idArg}: $id, message: $message, config: $config } }) {
27318
+ `mutation CliCreatePageVersion($expectedLatestVersion: Int, $id: String!, $message: String, $config: JSON!) {
27319
+ create${capitalized}Version(input: { expectedLatestVersion: $expectedLatestVersion, ${gqlName}Version: { ${idArg}: $id, message: $message, config: $config } }) {
27316
27320
  ${gqlName}Version { versionNumber }
27317
27321
  }
27318
27322
  }`,
27319
- { id, message, config }
27323
+ { id, message, config, expectedLatestVersion }
27320
27324
  );
27321
27325
  const versionNumber = data[`create${capitalized}Version`]?.[`${gqlName}Version`]?.versionNumber;
27322
27326
  if (versionNumber == null) {
@@ -27411,7 +27415,7 @@ var automationAdapter = {
27411
27415
  })
27412
27416
  };
27413
27417
  },
27414
- push: async (id, files, message) => {
27418
+ push: async (id, files, message, expectedLatestVersion) => {
27415
27419
  const doc = JSON.parse(fileBySuffix(files, ".json"));
27416
27420
  const findings2 = await validateAutomationElements(doc.elements);
27417
27421
  if (findings2.length > 0) {
@@ -27421,12 +27425,13 @@ ${findings2.map((f) => ` ${f}`).join("\n")}`
27421
27425
  );
27422
27426
  }
27423
27427
  const data = await gqlRequest(
27424
- `mutation CliCreateAutomationVersion($automationId: String!, $elements: JSON!, $message: String, $maxConcurrentRuns: Int) {
27425
- createAutomationVersion(input: { automationVersion: {
27428
+ `mutation CliCreateAutomationVersion($expectedLatestVersion: Int, $automationId: String!, $elements: JSON!, $message: String, $maxConcurrentRuns: Int) {
27429
+ createAutomationVersion(input: { expectedLatestVersion: $expectedLatestVersion, automationVersion: {
27426
27430
  automationId: $automationId, elements: $elements, message: $message, maxConcurrentRuns: $maxConcurrentRuns
27427
27431
  }}) { automationVersion { num } }
27428
27432
  }`,
27429
27433
  {
27434
+ expectedLatestVersion,
27430
27435
  automationId: id,
27431
27436
  elements: doc.elements,
27432
27437
  message,
@@ -27536,22 +27541,20 @@ var agentAdapter = {
27536
27541
  { agentId: id, versionNumber }
27537
27542
  );
27538
27543
  if (data.agentVersion == null) {
27539
- throw new Error(
27540
- `Agent ${id} has no version ${String(versionNumber)}.`
27541
- );
27544
+ throw new Error(`Agent ${id} has no version ${String(versionNumber)}.`);
27542
27545
  }
27543
27546
  return agentFiles(id, name2, data.agentVersion);
27544
27547
  },
27545
- push: async (id, files, message) => {
27548
+ push: async (id, files, message, expectedLatestVersion) => {
27546
27549
  const config = JSON.parse(fileBySuffix(files, ".json"));
27547
27550
  const data = await gqlRequest(
27548
- `mutation CliCreateAgentVersion(
27551
+ `mutation CliCreateAgentVersion($expectedLatestVersion: Int,
27549
27552
  $agentId: String!, $message: String!, $systemPrompt: String!,
27550
27553
  $model: String!, $temperature: Float!, $maxTokens: Int!,
27551
27554
  $rateLimitRequestsPerMinute: Int!, $rateLimitTokensPerMinute: Int!,
27552
27555
  $functionIds: [String]
27553
27556
  ) {
27554
- createAgentVersionWithFunctions(input: {
27557
+ createAgentVersionWithFunctions(input: { expectedLatestVersion: $expectedLatestVersion,
27555
27558
  agentId: $agentId, message: $message, systemPrompt: $systemPrompt,
27556
27559
  model: $model, temperature: $temperature, maxTokens: $maxTokens,
27557
27560
  rateLimitRequestsPerMinute: $rateLimitRequestsPerMinute,
@@ -27559,7 +27562,7 @@ var agentAdapter = {
27559
27562
  functionIds: $functionIds
27560
27563
  }) { result { versionNumber } }
27561
27564
  }`,
27562
- { agentId: id, message, ...config }
27565
+ { agentId: id, message, ...config, expectedLatestVersion }
27563
27566
  );
27564
27567
  const versionNumber = data.createAgentVersionWithFunctions?.result?.versionNumber;
27565
27568
  if (versionNumber == null) {
@@ -27931,7 +27934,12 @@ var runPush = async (args, clone) => {
27931
27934
  if (content == null) throw new Error(`${relPath} is missing locally.`);
27932
27935
  files[relPath] = content;
27933
27936
  }
27934
- const versionNumber = await adapter.push(id, files, message);
27937
+ const versionNumber = await adapter.push(
27938
+ id,
27939
+ files,
27940
+ message,
27941
+ force ? void 0 : resource.baseVersion
27942
+ );
27935
27943
  for (const relPath of changedFiles) {
27936
27944
  const content = files[relPath];
27937
27945
  if (content == null) continue;
@@ -35077,14 +35085,50 @@ var runGraphql = async (args) => {
35077
35085
  };
35078
35086
 
35079
35087
  // src/commands/integration.ts
35088
+ var USAGE2 = "Usage: overai integration configure <id> --config <json|@file|@-> | integration config <id> | integration secret set <id> <KEY> --value <@file|@->";
35089
+ var setSecret = async (integrationId, key, rawValue) => {
35090
+ if (rawValue == null) {
35091
+ throw new Error("Integration secret set requires --value.");
35092
+ }
35093
+ if (!rawValue.startsWith("@")) {
35094
+ throw new Error(
35095
+ "--value must be @- (stdin) or @<file>, so the secret stays out of your shell history."
35096
+ );
35097
+ }
35098
+ const value = await readValue(rawValue, "--value");
35099
+ if (value == null || value === "") {
35100
+ throw new Error("--value resolved to an empty string.");
35101
+ }
35102
+ await gqlRequest(
35103
+ `mutation SetIntegrationSecret($input: UpdateIntegrationConfigInput!) {
35104
+ updateIntegrationConfig(input: $input) { success }
35105
+ }`,
35106
+ { input: { integrationId, partialConfig: { [key]: value } } }
35107
+ );
35108
+ };
35080
35109
  var runIntegration = async (args) => {
35081
- const [operation, id] = args;
35110
+ const [operation] = args;
35111
+ if (operation === "secret") {
35112
+ const [, action, id2, key] = args;
35113
+ if (action !== "set" || id2 == null || key == null || key.startsWith("-")) {
35114
+ throw new Error(USAGE2);
35115
+ }
35116
+ await setSecret(id2, key, flagValue(args, "--value"));
35117
+ const result2 = await userTrpcMutation(
35118
+ "getMaskedIntegrationConfig",
35119
+ { id: id2 }
35120
+ );
35121
+ printResult(result2, resolveFormat(flagValue(args, "-o", "--output")));
35122
+ return;
35123
+ }
35124
+ const [, id] = args;
35082
35125
  if (id == null || operation !== "configure" && operation !== "config") {
35083
- throw new Error("Usage: overai integration configure <id> --config <json|@file|@-> | integration config <id>");
35126
+ throw new Error(USAGE2);
35084
35127
  }
35085
35128
  if (operation === "configure") {
35086
35129
  const raw2 = await readValue(flagValue(args, "--config"), "--config");
35087
- if (raw2 == null) throw new Error("Integration configure requires --config.");
35130
+ if (raw2 == null)
35131
+ throw new Error("Integration configure requires --config.");
35088
35132
  const value = (() => {
35089
35133
  try {
35090
35134
  return JSON.parse(raw2);
@@ -35094,7 +35138,9 @@ var runIntegration = async (args) => {
35094
35138
  })();
35095
35139
  await userTrpcMutation("putIntegrationConfig", { id, value });
35096
35140
  }
35097
- const result = await userTrpcMutation("getMaskedIntegrationConfig", { id });
35141
+ const result = await userTrpcMutation("getMaskedIntegrationConfig", {
35142
+ id
35143
+ });
35098
35144
  printResult(result, resolveFormat(flagValue(args, "-o", "--output")));
35099
35145
  };
35100
35146
 
@@ -35559,6 +35605,8 @@ var runResource = async (args) => {
35559
35605
  // src/docs/bestPractices.ts
35560
35606
  var platform2 = `# OverAI platform primer
35561
35607
 
35608
+ Saves reject a stale editing base without discarding your draft. Incorporate the latest saved changes before retrying; never retry with a newer base unless those changes have been reconciled. A save conflict does not deploy anything. Normal push sends the manifest base to an atomic server check. Only explicit --force omits it; never use --force as automatic conflict recovery.
35609
+
35562
35610
  Organization context: Commands in a clone select its org automatically. Outside a clone,
35563
35611
  use OVERAI_ORG_ID=<orgId>. Each backend/org has an independent saved session; org switch
35564
35612
  changes only the machine-global default. Use whoami to inspect the effective scope.
@@ -35589,11 +35637,13 @@ The env SDK is mostly shared across pages, functions, and automation code
35589
35637
  nodes:
35590
35638
  env.TBSxxx.sql\`...\` (postgres.js tagged template \u2014 interpolations are
35591
35639
  auto-parameterized, never string-concatenate user input; each table space also
35592
- gets a generated global TBSxxx.Tables interface, so annotate the row element
35593
- type \u2014 env.TBSxxx.sql<TBSxxx.Tables["users"]>\`...\` \u2014 for typed rows and
35640
+ gets a generated Env.TBSxxx.Tables interface, so annotate the row element
35641
+ type \u2014 env.TBSxxx.sql<Env.TBSxxx.Tables["users"]>\`...\` \u2014 for typed rows and
35594
35642
  column autocomplete; joins/aggregates/projections take a hand-written type or
35595
35643
  Pick<...>), env.FNxxx.call()
35596
- (pass \`path\` to hit a sub-path of a function that routes internally),
35644
+ (pass \`path\` to hit a sub-path of a function that routes internally; a
35645
+ function with declared schemas also gets Env.FNxxx.Input / Env.FNxxx.Output
35646
+ types for annotating payloads and results),
35597
35647
  env.ATxxx.start(inputs?) (fire-and-forget), env.DFxxx.read.json()/.saveVersion(),
35598
35648
  env.FBxxx.list()/read(entryId)/upload()/createFolder(),
35599
35649
  env.STORAGE.fetch/upload/presign (upload shortens stored names over 128
@@ -35651,12 +35701,24 @@ A page version's config JSON carries the code; the CLI splits it into
35651
35701
  language, customTitle, hideTopBar, ...). Push reassembles them.
35652
35702
 
35653
35703
  - Web pages are React (TSX). Printable pages are React or Liquid.
35704
+ - Web page config authorizationMode defaults to "workspace" for shared access.
35705
+ Opt into "viewer" for personal pages spanning the signed-in viewer's workspaces.
35706
+ Page code uses their permissions; results/access errors can differ by user.
35707
+ Public links require sign-in. Save and deploy publishes the mode with the code.
35708
+ Called functions retain their own execution permissions.
35654
35709
  - Web page code is concatenated with an SDK that already provides React and
35655
35710
  its hooks, then appends the <App /> render call. Declare a plain
35656
35711
  \`function App() { ... }\` \u2014 no \`export default\`, no
35657
35712
  \`import ... from "react"\` (redeclaring hooks is a SyntaxError \u2192 blank
35658
35713
  page). Imports must be https URLs (\`https://esm.sh/...\`) \u2014 the sandbox
35659
35714
  cannot resolve bare or relative specifiers.
35715
+ - In a React page, HTML from somewhere else (an exported dashboard, a mockup,
35716
+ a page from another tool) gets rebuilt as native React, preserving the
35717
+ original styling closely. Don't load a foreign HTML file into a \`srcDoc\`
35718
+ iframe or inject it into the DOM: embedded HTML is opaque to the outline and
35719
+ patchable only by blind string replacement that silently no-ops when the
35720
+ source drifts. A Liquid printable page is the exception \u2014 Liquid is HTML
35721
+ templating, so imported markup becomes the template body directly.
35660
35722
  - Pages run sandboxed in an iframe with the env SDK plus hooks: useCurrentUser,
35661
35723
  useSearchParam, useTheme, useLLMText/Object/Chat, useAgentChat, useDataFile
35662
35724
  (legacy \u2014 prefer env.DFxxx), navigateToPage, openPrintablePage.
@@ -36368,7 +36430,7 @@ var listWorkspaceUsers = async (args) => {
36368
36430
  resolveFormat(flagValue(args, "-o", "--output"))
36369
36431
  );
36370
36432
  };
36371
- var USAGE2 = `Usage:
36433
+ var USAGE3 = `Usage:
36372
36434
  overai workspace list [--archived] [--limit <n>]
36373
36435
  overai workspace show [workspaceId]
36374
36436
  overai workspace users [workspaceId]
@@ -36386,7 +36448,7 @@ var runWorkspace = async (args) => {
36386
36448
  await listWorkspaceUsers(args.slice(1));
36387
36449
  return;
36388
36450
  }
36389
- process.stderr.write(USAGE2);
36451
+ process.stderr.write(USAGE3);
36390
36452
  process.exitCode = 1;
36391
36453
  };
36392
36454
 
@@ -36468,6 +36530,9 @@ Other resources:
36468
36530
  overai knowledge-base search <id> <query> [--limit N]
36469
36531
  overai integration configure <id> --config <json|@file|@->
36470
36532
  overai integration config <id> Read its masked configuration
36533
+ overai integration secret set <id> <KEY> --value <@file|@->
36534
+ Set one credential, leaving the rest of
36535
+ the config alone
36471
36536
  overai printable-page render <id> [--search-params <json|@file>]
36472
36537
 
36473
36538
  Self-hosted runners (enabling remote access stays on-device \u2014 not a CLI action):
@@ -3,7 +3,7 @@ import {
3
3
  webPageConfigSchema,
4
4
  webPageConfigWriteSchema,
5
5
  webPageLanguage
6
- } from "./chunk-KIHU74V6.js";
6
+ } from "./chunk-56E4CWBE.js";
7
7
  import "./chunk-XCJJTK3H.js";
8
8
  import "./chunk-U67V476Y.js";
9
9
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overaihq/cli",
3
- "version": "0.12.1",
3
+ "version": "0.13.1",
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",