@overaihq/cli 0.8.0 → 0.9.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.
package/dist/index.js CHANGED
@@ -5,10 +5,10 @@ import {
5
5
  import {
6
6
  itemFilterExpressionRootSchema,
7
7
  webPageConfigSchema
8
- } from "./chunk-2F4ZHHFG.js";
8
+ } from "./chunk-KIHU74V6.js";
9
9
  import {
10
10
  external_exports
11
- } from "./chunk-6YTIPJTD.js";
11
+ } from "./chunk-XCJJTK3H.js";
12
12
  import {
13
13
  __commonJS,
14
14
  __toESM
@@ -26613,6 +26613,31 @@ var readValue = async (value, label) => {
26613
26613
  }
26614
26614
  };
26615
26615
 
26616
+ // src/gql.ts
26617
+ var gqlRequest = async (query, variables) => {
26618
+ const res = await v2Fetch("/v2/graphql", {
26619
+ method: "POST",
26620
+ headers: { "Content-Type": "application/json" },
26621
+ body: JSON.stringify({ query, variables })
26622
+ });
26623
+ const raw2 = await res.text();
26624
+ const body = (() => {
26625
+ try {
26626
+ return JSON.parse(raw2);
26627
+ } catch {
26628
+ return null;
26629
+ }
26630
+ })();
26631
+ if (body?.errors != null && body.errors.length > 0) {
26632
+ throw new Error(body.errors.map((e) => e.message).join("; "));
26633
+ }
26634
+ if (!res.ok) throw v2Error("graphql", res, raw2);
26635
+ if (body?.data == null) {
26636
+ throw new Error("graphql returned no data and no errors.");
26637
+ }
26638
+ return body.data;
26639
+ };
26640
+
26616
26641
  // src/output.ts
26617
26642
  var resolveFormat = (explicit) => {
26618
26643
  if (explicit === "json" || explicit === "csv" || explicit === "table") {
@@ -26670,10 +26695,11 @@ var printResult = (data, format2) => {
26670
26695
  // src/commands/org.ts
26671
26696
  var USER_ORGS_QUERY = `
26672
26697
  query UserOrganizations($identityId: String!) {
26673
- identityOrganizations(
26674
- where: { identityId: { _eq: $identityId }, disabled: { _eq: false } }
26675
- ) {
26676
- organization { id name }
26698
+ identityOrganizations(condition: { identityId: $identityId }) {
26699
+ nodes {
26700
+ disabled
26701
+ organization { id name }
26702
+ }
26677
26703
  }
26678
26704
  }
26679
26705
  `;
@@ -26687,19 +26713,8 @@ var listOrgRows = async () => {
26687
26713
  if (identityId == null) {
26688
26714
  throw new Error("Could not read identity from the current session.");
26689
26715
  }
26690
- const res = await v2Fetch("/v1/graphql", {
26691
- method: "POST",
26692
- headers: { "Content-Type": "application/json" },
26693
- body: JSON.stringify({ query: USER_ORGS_QUERY, variables: { identityId } })
26694
- });
26695
- const body = await res.json().catch(() => null);
26696
- if (body?.errors != null && body.errors.length > 0) {
26697
- throw new Error(body.errors.map((e) => e.message).join("; "));
26698
- }
26699
- if (!res.ok || body == null) {
26700
- throw new Error(`org list failed (${String(res.status)})`);
26701
- }
26702
- return (body.data?.identityOrganizations ?? []).map((edge) => edge.organization).filter((org) => org != null);
26716
+ const data = await gqlRequest(USER_ORGS_QUERY, { identityId });
26717
+ return data.identityOrganizations.nodes.filter((node) => node != null && !node.disabled).map((node) => node?.organization).filter((org) => org != null);
26703
26718
  };
26704
26719
  var listOrgs = async (args) => {
26705
26720
  const active = scopedOrgId();
@@ -26992,34 +27007,6 @@ var runAgent = async (args) => {
26992
27007
  printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
26993
27008
  };
26994
27009
 
26995
- // src/gql.ts
26996
- var gqlRequest = async (query, variables, options) => {
26997
- const res = await v2Fetch(
26998
- options?.v1 === true ? "/v1/graphql" : "/v2/graphql",
26999
- {
27000
- method: "POST",
27001
- headers: { "Content-Type": "application/json" },
27002
- body: JSON.stringify({ query, variables })
27003
- }
27004
- );
27005
- const raw2 = await res.text();
27006
- const body = (() => {
27007
- try {
27008
- return JSON.parse(raw2);
27009
- } catch {
27010
- return null;
27011
- }
27012
- })();
27013
- if (body?.errors != null && body.errors.length > 0) {
27014
- throw new Error(body.errors.map((e) => e.message).join("; "));
27015
- }
27016
- if (!res.ok) throw v2Error("graphql", res, raw2);
27017
- if (body?.data == null) {
27018
- throw new Error("graphql returned no data and no errors.");
27019
- }
27020
- return body.data;
27021
- };
27022
-
27023
27010
  // src/commands/automation.ts
27024
27011
  var runRuns = async (automationId, args) => {
27025
27012
  const limit2 = Number(flagValue(args, "--limit") ?? 20);
@@ -27110,11 +27097,11 @@ var runAutomation = async (args) => {
27110
27097
  // src/workspace/validateElements.ts
27111
27098
  var findings = (parsed) => parsed.success ? [] : parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
27112
27099
  var validateAutomationElements = async (elements) => {
27113
- const { automationNodesSchema } = await import("./types-VTXVZF4K.js");
27100
+ const { automationNodesSchema } = await import("./types-QDEUVRZP.js");
27114
27101
  return findings(automationNodesSchema.safeParse(elements));
27115
27102
  };
27116
27103
  var validateWebPageConfig = async (config) => {
27117
- const { webPageConfigWriteSchema } = await import("./webPage-G5HIZM7Q.js");
27104
+ const { webPageConfigWriteSchema } = await import("./webPage-675DU764.js");
27118
27105
  return findings(webPageConfigWriteSchema.safeParse(config));
27119
27106
  };
27120
27107
 
@@ -27637,21 +27624,14 @@ var adapterFor = (type) => {
27637
27624
  var createActionRunner = async (workspaceId, name2) => {
27638
27625
  const identityResult = await gqlRequest(
27639
27626
  `mutation CliCreateMachineIdentity($name: String!) {
27640
- identityInsert(object: { name: $name, type: "machine" }) { id }
27627
+ createMachineIdentity(input: { name: $name }) {
27628
+ identity { id }
27629
+ }
27641
27630
  }`,
27642
- { name: name2 },
27643
- { v1: true }
27631
+ { name: name2 }
27644
27632
  );
27645
- const identityId = identityResult.identityInsert?.id;
27633
+ const identityId = identityResult.createMachineIdentity?.identity?.id;
27646
27634
  if (identityId == null) throw new Error("Failed to create machine identity");
27647
- await gqlRequest(
27648
- `mutation CliCreateIdentityOrganization($identityId: String!) {
27649
- createIdentityOrganization(
27650
- input: { identityOrganization: { identityId: $identityId } }
27651
- ) { identityOrganization { identityId } }
27652
- }`,
27653
- { identityId }
27654
- );
27655
27635
  const runnerResult = await gqlRequest(
27656
27636
  `mutation CliCreateActionRunner($identityId: String!, $workspaceId: String!) {
27657
27637
  createActionRunner(
@@ -27880,7 +27860,7 @@ var defaultAgentFunctionInputSchema = `{
27880
27860
  // ../common/src/liquidjs/liquidjs.ts
27881
27861
  var import_jmespath = __toESM(require_jmespath(), 1);
27882
27862
 
27883
- // ../../node_modules/.pnpm/liquidjs@10.28.0/node_modules/liquidjs/dist/liquid.node.mjs
27863
+ // ../../node_modules/.pnpm/liquidjs@10.29.0/node_modules/liquidjs/dist/liquid.node.mjs
27884
27864
  import { PassThrough } from "stream";
27885
27865
  import { sep, extname, resolve as resolve$1, dirname as dirname$1 } from "path";
27886
27866
  import { statSync, readFileSync as readFileSync$1, realpathSync, stat, readFile as readFile$1, realpath } from "fs";
@@ -31495,6 +31475,11 @@ function strip_newlines(v) {
31495
31475
  this.context.memoryLimit.use(str.length);
31496
31476
  return str.replace(/\r?\n/gm, "");
31497
31477
  }
31478
+ function squish(v) {
31479
+ const str = stringify(v);
31480
+ this.context.memoryLimit.use(str.length);
31481
+ return str.replace(/\s+/g, " ").trim();
31482
+ }
31498
31483
  function capitalize(str) {
31499
31484
  str = stringify(str);
31500
31485
  this.context.memoryLimit.use(str.length);
@@ -31597,6 +31582,7 @@ var stringFilters = /* @__PURE__ */ Object.freeze({
31597
31582
  split,
31598
31583
  strip,
31599
31584
  strip_newlines,
31585
+ squish,
31600
31586
  capitalize,
31601
31587
  replace,
31602
31588
  replace_first,
@@ -32634,6 +32620,9 @@ var Liquid = class _Liquid {
32634
32620
  registerFilter(name2, filter2) {
32635
32621
  this.filters[name2] = filter2;
32636
32622
  }
32623
+ unregisterFilter(name2) {
32624
+ delete this.filters[name2];
32625
+ }
32637
32626
  registerTag(name2, tag) {
32638
32627
  this.tags[name2] = isFunction(tag) ? tag : createTagClass(tag);
32639
32628
  }
@@ -33575,6 +33564,66 @@ var runDataStream = async (args) => {
33575
33564
  printResult(body, resolveFormat(flagValue(args, "-o", "--output")));
33576
33565
  };
33577
33566
 
33567
+ // src/commands/knowledgeBase.ts
33568
+ import { readFile as readFile2 } from "fs/promises";
33569
+ import { basename } from "path";
33570
+ var runKnowledgeBase = async (args) => {
33571
+ const [operation, id] = args;
33572
+ if (id == null || operation !== "upload" && operation !== "search") {
33573
+ throw new Error(
33574
+ "Usage: overai knowledge-base upload <id> <file...> | knowledge-base search <id> <query> [--limit N]"
33575
+ );
33576
+ }
33577
+ const { organizationId } = await getAccessToken();
33578
+ if (operation === "upload") {
33579
+ const paths = args.slice(2).filter(
33580
+ (arg, i, all) => !arg.startsWith("-") && all[i - 1] !== "-o" && all[i - 1] !== "--output"
33581
+ );
33582
+ if (paths.length === 0)
33583
+ throw new Error("Knowledge base upload requires at least one file path.");
33584
+ const uploads = [];
33585
+ for (const path of paths) {
33586
+ const bytes = await readFile2(path);
33587
+ const formData = new FormData();
33588
+ formData.append(
33589
+ "file",
33590
+ new Blob([new Uint8Array(bytes)]),
33591
+ basename(path)
33592
+ );
33593
+ const response2 = await v2Fetch(
33594
+ `/v2/knowledge-bases/${organizationId}/${id}/upload`,
33595
+ { method: "POST", body: formData }
33596
+ );
33597
+ const raw3 = await response2.text();
33598
+ if (!response2.ok) throw v2Error("knowledge-base upload", response2, raw3);
33599
+ uploads.push({ file: basename(path), ...JSON.parse(raw3) });
33600
+ }
33601
+ printResult(uploads, resolveFormat(flagValue(args, "-o", "--output")));
33602
+ return;
33603
+ }
33604
+ const query = args[2];
33605
+ if (query == null || query.startsWith("-"))
33606
+ throw new Error("Knowledge base search requires a query string.");
33607
+ const limit2 = flagValue(args, "--limit");
33608
+ const response = await v2Fetch(
33609
+ `/v2/knowledge-bases/${organizationId}/${id}/search`,
33610
+ {
33611
+ method: "POST",
33612
+ headers: { "Content-Type": "application/json" },
33613
+ body: JSON.stringify({
33614
+ query,
33615
+ ...limit2 != null ? { limit: Number(limit2) } : {}
33616
+ })
33617
+ }
33618
+ );
33619
+ const raw2 = await response.text();
33620
+ if (!response.ok) throw v2Error("knowledge-base search", response, raw2);
33621
+ printResult(
33622
+ JSON.parse(raw2),
33623
+ resolveFormat(flagValue(args, "-o", "--output"))
33624
+ );
33625
+ };
33626
+
33578
33627
  // src/commands/dev.ts
33579
33628
  import { createHash as createHash3 } from "crypto";
33580
33629
  import { watch } from "fs";
@@ -34605,6 +34654,7 @@ var resources = {
34605
34654
  IN: { collection: "integrations", mutation: "updateIntegration", result: "integration", patch: "IntegrationPatch", fields: "id name description isArchived integrationTypeId workspaceId", editable: ["name", "description", "isArchived", "integrationTypeId"] },
34606
34655
  TBS: { collection: "tableSpaces", mutation: "updateTableSpace", result: "tableSpace", patch: "TableSpacePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
34607
34656
  DS: { collection: "dataStreams", mutation: "updateDataStream", result: "dataStream", patch: "DataStreamPatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
34657
+ KB: { collection: "knowledgeBases", mutation: "updateKnowledgeBase", result: "knowledgeBase", patch: "KnowledgeBasePatch", fields: "id name description isArchived embeddingModel workspaceId", editable: ["name", "description", "isArchived"] },
34608
34658
  DF: { collection: "dataFiles", mutation: "updateDataFile", result: "dataFile", patch: "DataFilePatch", fields: "id name description isArchived workspaceId", editable: ["name", "description", "isArchived"] },
34609
34659
  AR: { collection: "actionRunners", mutation: "updateActionRunner", result: "actionRunner", patch: "ActionRunnerPatch", fields: "id isArchived actionTimeoutSeconds config workspaceId identityId identity { name }", editable: ["isArchived", "actionTimeoutSeconds", "config"] }
34610
34660
  };
@@ -34823,6 +34873,9 @@ language, customTitle, hideTopBar, ...). Push reassembles them.
34823
34873
  substituted into it (neither {x} nor Liquid {{ x }}). If the data depends on
34824
34874
  a search param, fetch it in the page instead. To clear it use JSON null; the
34825
34875
  string "null" is a four-character URL that fails at fetch time.
34876
+ - A printable page's print/save-to-PDF filename is the page's own title:
34877
+ customTitle if set, else "<name> - <date>"; page code can assign
34878
+ \`document.title\` at runtime to control it per render.
34826
34879
  - Printable page PDFs render in a headless browser that waits for network idle,
34827
34880
  so useEffect fetches DO resolve before capture. Load data in the page \u2014 you
34828
34881
  don't need to pre-fetch it into searchParams or stage it in storage. A blank
@@ -35868,6 +35921,8 @@ Other resources:
35868
35921
  overai data-stream query <id> --start <date> --end <date> [--query <filter>]
35869
35922
  overai data-file upload <id> <path> [-m <message>]
35870
35923
  overai data-file download <id> [path|-] | data-file head <id>
35924
+ overai knowledge-base upload <id> <file...>
35925
+ overai knowledge-base search <id> <query> [--limit N]
35871
35926
  overai integration configure <id> --config <json|@file|@->
35872
35927
  overai integration config <id> Read its masked configuration
35873
35928
  overai printable-page render <id> [--search-params <json|@file>]
@@ -36016,6 +36071,9 @@ var run = async () => {
36016
36071
  case "data-stream":
36017
36072
  await runDataStream(rest);
36018
36073
  return;
36074
+ case "knowledge-base":
36075
+ await runKnowledgeBase(rest);
36076
+ return;
36019
36077
  case "data-file":
36020
36078
  await runDataFile(rest);
36021
36079
  return;
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-WGPBYGU6.js";
4
4
  import {
5
5
  external_exports
6
- } from "./chunk-6YTIPJTD.js";
6
+ } from "./chunk-XCJJTK3H.js";
7
7
  import "./chunk-U67V476Y.js";
8
8
 
9
9
  // ../common/src/automations/types.ts
@@ -59,6 +59,7 @@ var ServiceEnum = /* @__PURE__ */ ((ServiceEnum2) => {
59
59
  ServiceEnum2["Http"] = "HTTP";
60
60
  ServiceEnum2["HybridAnalysis"] = "HYBRID_ANALYSIS";
61
61
  ServiceEnum2["Jira"] = "JIRA";
62
+ ServiceEnum2["KnowledgeBases"] = "KNOWLEDGE_BASES";
62
63
  ServiceEnum2["Linkedin"] = "LINKEDIN";
63
64
  ServiceEnum2["LocalNetwork"] = "LOCAL_NETWORK";
64
65
  ServiceEnum2["MicrosoftDefender"] = "MICROSOFT_DEFENDER";
@@ -293,6 +294,7 @@ var NodeEnum = /* @__PURE__ */ ((NodeEnum2) => {
293
294
  NodeEnum2["saveToDataFile"] = "SAVE_TO_DATA_FILE";
294
295
  NodeEnum2["screenshotWebpage"] = "SCREENSHOT_WEBPAGE";
295
296
  NodeEnum2["searchCisaKevs"] = "SEARCH_CISA_KEVS";
297
+ NodeEnum2["searchKnowledgeBase"] = "SEARCH_KNOWLEDGE_BASE";
296
298
  NodeEnum2["sendEmail"] = "SEND_EMAIL";
297
299
  NodeEnum2["sendRequest"] = "SEND_REQUEST";
298
300
  NodeEnum2["sentinelOneAction"] = "SENTINEL_ONE_ACTION";
@@ -3,8 +3,8 @@ import {
3
3
  webPageConfigSchema,
4
4
  webPageConfigWriteSchema,
5
5
  webPageLanguage
6
- } from "./chunk-2F4ZHHFG.js";
7
- import "./chunk-6YTIPJTD.js";
6
+ } from "./chunk-KIHU74V6.js";
7
+ import "./chunk-XCJJTK3H.js";
8
8
  import "./chunk-U67V476Y.js";
9
9
  export {
10
10
  defaultWebPageTemplate,
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@overaihq/cli",
3
- "version": "0.8.0",
3
+ "version": "0.9.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",
7
7
  "engines": {
8
- "node": ">=24.19.0"
8
+ "node": ">=24.20.0"
9
9
  },
10
10
  "bin": {
11
11
  "overai": "./dist/index.js"
@@ -20,11 +20,11 @@
20
20
  "access": "public"
21
21
  },
22
22
  "devDependencies": {
23
+ "@perygee/common": "0.0.0",
23
24
  "@types/node": "^24.13.3",
24
25
  "tsup": "^8.5.1",
25
26
  "typescript": "7.0.2",
26
- "vitest": "^4.1.10",
27
- "@perygee/common": "0.0.0"
27
+ "vitest": "^4.1.10"
28
28
  },
29
29
  "scripts": {
30
30
  "lint": "echo 'Run lint from the root of the repo'",