@openengio/cli 0.24.4 → 0.27.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.
@@ -289,6 +289,11 @@ function doc(does, refuses) {
289
289
  return Object.freeze({ does, refuses: Object.freeze([...refuses]) });
290
290
  }
291
291
  var ROUTE_DOCS = Object.freeze({
292
+ createObjectSet: doc("Saves a named set of 1 to 200 object addresses in the caller's organisation. Concurrent retries with one key return the same saved set and revision.", [...SCOPED, "head-moved"]),
293
+ listObjectSets: doc("Lists the organisation's saved sets, newest update first, without members or counts.", SIGNED_IN),
294
+ readObjectSet: doc("Reads a saved set's visible objects on the selected ref, a count of missing visible members and one bit for members outside the caller's scope.", [...SCOPED, "head-moved"]),
295
+ updateObjectSet: doc("Renames a saved set or replaces its readable members at the expected revision. Members outside the caller's scope remain. A success raises the revision by one.", [...SCOPED, "stale-revision", "head-moved"]),
296
+ deleteObjectSet: doc("Deletes a saved set and every member at the expected revision.", [...SCOPED, "stale-revision"]),
292
297
  health: doc("Answers whether the host is running.", PUBLIC),
293
298
  signInStart: doc("Starts a sign-in with the identity provider and redirects the browser to it.", PUBLIC),
294
299
  signInCallback: doc("Receives the identity provider's answer and returns a one-time code for the client.", [...PUBLIC, "kind", "lifecycle", "invitation", "token-shape", "signature", "issuer", "audience", "expiry", "algorithm", "claims"]),
@@ -472,6 +477,11 @@ function deepFreeze(value) {
472
477
  return value;
473
478
  }
474
479
  var SCHEMAS = {
480
+ createObjectSet: { "type": "object", "properties": { "name": { "type": "string" }, "members": { "type": "array", "items": { "type": "object", "properties": { "objectId": { "type": "string" }, "projectId": { "type": "string" } }, "required": ["objectId", "projectId"], "additionalProperties": false } } }, "required": ["name", "members"], "additionalProperties": false },
481
+ listObjectSets: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
482
+ readObjectSet: { "type": "object", "properties": { "setId": { "type": "string" } }, "required": ["setId"], "additionalProperties": false },
483
+ updateObjectSet: { "type": "object", "properties": { "setId": { "type": "string" }, "revision": { "type": "number" }, "name": { "type": "string" }, "members": { "type": "array", "items": { "type": "object", "properties": { "objectId": { "type": "string" }, "projectId": { "type": "string" } }, "required": ["objectId", "projectId"], "additionalProperties": false } } }, "required": ["setId", "revision"], "additionalProperties": false },
484
+ deleteObjectSet: { "type": "object", "properties": { "setId": { "type": "string" }, "revision": { "type": "number" } }, "required": ["setId", "revision"], "additionalProperties": false },
475
485
  health: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
476
486
  signInStart: { "type": "object", "properties": { "state": { "type": "string" }, "loopback": { "type": "string" }, "code_challenge": { "type": "string" }, "code_challenge_method": { "const": "S256" } }, "required": ["state", "loopback", "code_challenge", "code_challenge_method"], "additionalProperties": false },
477
487
  signInCallback: { "oneOf": [{ "type": "object", "properties": { "state": { "type": "string" }, "code": { "type": "string" } }, "required": ["state", "code"], "additionalProperties": false }, { "type": "object", "properties": { "state": { "type": "string" }, "error": { "type": "string" } }, "required": ["state", "error"], "additionalProperties": false }] },
@@ -613,6 +623,11 @@ var SELECTORS = {
613
623
  };
614
624
  var SELECTOR_SCHEMAS = deepFreeze(SELECTORS);
615
625
  var EXAMPLES = {
626
+ createObjectSet: { "name": "Saved set", "members": [{ "objectId": "obj_aaaaaaaaaaaaaaaaaaaaaaaaaa", "projectId": "<projectId>" }] },
627
+ listObjectSets: {},
628
+ readObjectSet: { "setId": "ost_aaaaaaaaaaaaaaaaaaaaaaaaaa" },
629
+ updateObjectSet: { "setId": "ost_aaaaaaaaaaaaaaaaaaaaaaaaaa", "revision": 1, "name": "Renamed set" },
630
+ deleteObjectSet: { "setId": "ost_aaaaaaaaaaaaaaaaaaaaaaaaaa", "revision": 1 },
616
631
  health: {},
617
632
  signInStart: { "state": "<state>", "loopback": "<loopback>", "code_challenge": "<code_challenge>", "code_challenge_method": "S256" },
618
633
  signInCallback: { "state": "<state>", "code": "<code>" },
@@ -749,7 +764,7 @@ var EXAMPLES = {
749
764
  var ROUTE_INPUT_EXAMPLES = deepFreeze(EXAMPLES);
750
765
 
751
766
  // packages/api-contract/dist/routes.js
752
- var PROTOCOL_VERSION = 24;
767
+ var PROTOCOL_VERSION = 27;
753
768
  var VERSION_HEADER = "oe2-protocol-version";
754
769
  var TOKEN_HEADER = "authorization";
755
770
  var IDEMPOTENCY_HEADER = "oe2-idempotency-key";
@@ -775,6 +790,11 @@ function route(entry2) {
775
790
  return Object.freeze({ ...entry2, doc: documented });
776
791
  }
777
792
  var ROUTES = Object.freeze({
793
+ createObjectSet: route({ name: "createObjectSet", method: "POST", path: "/object-sets", group: "write", selector: "object", subject: "project", idempotent: true, admission: admitting("user"), versioned: true, module: "objects-sdk", capability: "objects.createObjectSet" }),
794
+ listObjectSets: route({ name: "listObjectSets", method: "POST", path: "/object-sets/list", group: "read", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "objects-sdk", capability: "objects.listObjectSets" }),
795
+ readObjectSet: route({ name: "readObjectSet", method: "POST", path: "/object-sets/read", group: "read", selector: "object", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "objects-sdk", capability: "objects.readObjectSet" }),
796
+ updateObjectSet: route({ name: "updateObjectSet", method: "POST", path: "/object-sets/update", group: "write", selector: "object", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "objects-sdk", capability: "objects.updateObjectSet" }),
797
+ deleteObjectSet: route({ name: "deleteObjectSet", method: "POST", path: "/object-sets/delete", group: "write", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "objects-sdk", capability: "objects.deleteObjectSet" }),
778
798
  health: route({ name: "health", method: "GET", path: "/health", group: "platform", selector: "none", subject: "platform", idempotent: false, admission: NO_ACCESS_TOKEN, versioned: false, module: "sdk-core", capability: "core.health" }),
779
799
  signInStart: route({ name: "signInStart", method: "GET", path: "/auth/sign-in", group: "platform", selector: "none", subject: "platform", idempotent: false, admission: NO_ACCESS_TOKEN, versioned: false, module: "sdk-core", capability: "core.signInStart" }),
780
800
  signInCallback: route({ name: "signInCallback", method: "GET", path: "/auth/callback", group: "platform", selector: "none", subject: "platform", idempotent: false, admission: NO_ACCESS_TOKEN, versioned: false, module: "sdk-core", capability: "core.signInCallback" }),
@@ -909,6 +929,11 @@ var ROUTES = Object.freeze({
909
929
  closeImportRun: route({ name: "closeImportRun", method: "POST", path: "/import-run-closes", group: "write", selector: "connection", subject: "connection", idempotent: false, admission: admitting("service", "user"), versioned: true, module: "admin-sdk", capability: "admin.importRunClose" })
910
930
  });
911
931
  var ROUTE_CARRIES_CREDENTIAL = Object.freeze({
932
+ createObjectSet: false,
933
+ listObjectSets: false,
934
+ readObjectSet: false,
935
+ updateObjectSet: false,
936
+ deleteObjectSet: false,
912
937
  health: false,
913
938
  signInStart: false,
914
939
  signInCallback: true,
@@ -1887,6 +1912,9 @@ function exploreViewAddress(address, state) {
1887
1912
  const split = subject.indexOf("?");
1888
1913
  const path = split === -1 ? subject : subject.slice(0, split);
1889
1914
  const query2 = new URLSearchParams(split === -1 ? "" : subject.slice(split + 1));
1915
+ if (state.setId !== void 0 && state.setId !== null && state.setId.length > 0) {
1916
+ query2.set("set", state.setId);
1917
+ }
1890
1918
  if (state.typeKey !== null) {
1891
1919
  query2.set("type", state.typeKey);
1892
1920
  }
@@ -2021,6 +2049,11 @@ function linkPath(organisationId, projectId, subject, ref) {
2021
2049
  // packages/objects-sdk/dist/transport-client.js
2022
2050
  var OBJECTS_ROUTE_ENTRIES = routeEntriesOf("objects-sdk");
2023
2051
  var OBJECTS_ROUTE_NAMES = [
2052
+ "createObjectSet",
2053
+ "listObjectSets",
2054
+ "readObjectSet",
2055
+ "updateObjectSet",
2056
+ "deleteObjectSet",
2024
2057
  "readObject",
2025
2058
  "queryObjects",
2026
2059
  "aggregateObjects",
@@ -9701,12 +9734,13 @@ var IDENTIFIER_FIELD = Object.freeze({
9701
9734
  "app-draft": "appKey"
9702
9735
  });
9703
9736
  var PROJECT_REF_USAGE = "openeng link <explore|branch-diff|project> --project <id> --ref <ref>";
9737
+ var SET_USAGE = "openeng link explore --project <id> --ref <ref> --object-set <id>";
9704
9738
  var REF_USAGE = "openeng link <ontology|change-set> --ref <ref>";
9705
9739
  var DRAFT_USAGE = "openeng link app-draft <appKey> --ref <ref>";
9706
9740
  var IDENTIFIED_USAGE = "openeng link <object|type|proposal|app> <identifier> --project <id> --ref <ref>";
9707
9741
  var APP_PAGE_USAGE = "openeng link app-page <appKey> <pageKey> --project <id> --ref <ref>";
9708
9742
  var PAGE_USAGE = "openeng link organisation-page <page>";
9709
- var LINK_HELP = [PROJECT_REF_USAGE, REF_USAGE, DRAFT_USAGE, IDENTIFIED_USAGE, APP_PAGE_USAGE, PAGE_USAGE];
9743
+ var LINK_HELP = [PROJECT_REF_USAGE, SET_USAGE, REF_USAGE, DRAFT_USAGE, IDENTIFIED_USAGE, APP_PAGE_USAGE, PAGE_USAGE];
9710
9744
  var refusal = (message) => ({ kind: "client-refusal", message });
9711
9745
  var SCOPE_OF_KIND = Object.freeze({
9712
9746
  object: "project-and-ref",
@@ -9837,12 +9871,21 @@ async function link(context) {
9837
9871
  if (typeof scope === "string") {
9838
9872
  return refusal(`openeng link ${subject.kind} ${scope}`);
9839
9873
  }
9840
- const path = linkPath(organisation.id, scope.project, subject, scope.ref);
9874
+ if (options.objectSet !== void 0 && (subject.kind !== "explore" || options.objectSet.length === 0)) {
9875
+ return refusal("--object-set needs a saved set identifier and the explore page");
9876
+ }
9877
+ const objectSet = options.objectSet;
9878
+ const path = options.objectSet === void 0 ? linkPath(organisation.id, scope.project, subject, scope.ref) : exploreViewAddress({ organisationId: organisation.id, projectId: scope.project, ref: scope.ref, q: null }, { typeKey: null, objectId: null, setId: options.objectSet });
9841
9879
  const run2 = await runAuthenticated(host, deps, async (clients) => {
9842
- const [origin, checks] = await Promise.all([
9880
+ const [origin, checks, saved] = await Promise.all([
9843
9881
  clients.admin.readWebOrigin({ input: {} }),
9844
- Promise.all(subjectReads(clients, subject, scope))
9882
+ Promise.all(subjectReads(clients, subject, scope)),
9883
+ objectSet === void 0 ? Promise.resolve(null) : clients.objects.readObjectSet({
9884
+ selector: { projectId: scope.project, ref: scope.ref },
9885
+ input: { setId: objectSet }
9886
+ })
9845
9887
  ]);
9888
+ if (saved !== null && ("refusal" in saved || saved.replayed === true)) return saved;
9846
9889
  const blocked = checks.find((check) => check.missing === null && ("refusal" in check.answer || check.answer.replayed === true));
9847
9890
  if (blocked !== void 0) return blocked.answer;
9848
9891
  if ("refusal" in origin) {
@@ -10876,6 +10919,7 @@ import { parseArgs } from "node:util";
10876
10919
 
10877
10920
  // packages/cli/src/cli-options.ts
10878
10921
  var CLI_OPTIONS = {
10922
+ "object-set": { type: "string" },
10879
10923
  host: { type: "string" },
10880
10924
  "sign-in-origin": { type: "string" },
10881
10925
  json: { type: "boolean" },
@@ -10912,7 +10956,7 @@ var CLI_OPTIONS = {
10912
10956
  };
10913
10957
 
10914
10958
  // packages/cli/src/cli-version.ts
10915
- var PATCH_VERSION = 4;
10959
+ var PATCH_VERSION = 1;
10916
10960
  var CLI_VERSION = `0.${PROTOCOL_VERSION}.${PATCH_VERSION}`;
10917
10961
 
10918
10962
  // packages/cli/src/environment.ts
@@ -11026,6 +11070,7 @@ function parseInvocation(argv) {
11026
11070
  json: values.json === true,
11027
11071
  open: values["no-open"] !== true,
11028
11072
  project: values.project,
11073
+ objectSet: values["object-set"],
11029
11074
  organisation: values.organisation === true,
11030
11075
  readOnly: values["read-only"] === true,
11031
11076
  object: values.object,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openengio/cli",
3
- "version": "0.24.4",
3
+ "version": "0.27.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "engines": {
@@ -7,12 +7,21 @@ description: Use when a person new to OpenEngineering wants a hands-on tour, or
7
7
 
8
8
  ## 1. Offer three paths
9
9
 
10
+ At every decision in sections 1–3 (path, workflow, next story or step), use your harness's
11
+ multiple-choice question tool if your tool set has one; otherwise ask as a short numbered list.
12
+ Make the first option the happy path: a named next step the person can select to move forward
13
+ without more typing. Offer two or three other real options, never filler. Say once, early, that
14
+ they can always skip a question or type their own answer. Ask every question a step needs together,
15
+ in one multiple-choice call where your tool allows several, so the person answers them in one go;
16
+ run routine commands without permission questions. Each stop point
17
+ asks its own question; an offered option never replaces the person's required words.
18
+
10
19
  After sign-in, when the person has no task of their own, offer once:
11
20
 
12
- - **Seed demo**: create a project, run `openeng demo seed --project <id>`, then follow the
13
- [Quickstart](https://docs.openeng.io/get-started/quickstart/) together.
14
21
  - **Free-form tour** (the main path): build a small example around their work and explore its
15
22
  capabilities together in the app.
23
+ - **Seed demo**: create a project, run `openeng demo seed --project <id>`, then follow the
24
+ [Quickstart](https://docs.openeng.io/get-started/quickstart/) together.
16
25
  - **Something else**: follow the task the person names. They may decline the tour.
17
26
 
18
27
  Before the tour starts, load every capability below into your own native task or plan tool,
@@ -74,7 +83,6 @@ Ask what the person designs or manages and where the work gets hard. Offer a fit
74
83
  or use their own vocabulary. Agree a small story with a visible result. Create a demo organisation
75
84
  with `openeng org create` unless asked to use an existing one; say which data is invented.
76
85
  Ask before touching existing data, inviting anyone, connecting Onshape or registering an app.
77
- Ask at most two questions at a time; do not turn routine commands into permission questions.
78
86
 
79
87
  Whenever the tour designs types, read `openeng skill new-use-case` and follow every stop point
80
88
  in order: show the person the work and wait for agreement at each one. Do not skip a stop point
@@ -263,6 +263,18 @@ project. `openeng link ontology --ref <ref>` and `openeng link change-set --ref
263
263
  project, and `openeng link organisation-page <page>` takes neither flag. The organisation is the one
264
264
  your session is attached to.
265
265
 
266
+ ### Save an object set and link to its canvas
267
+
268
+ 1. Run `openeng help objects-sdk createObjectSet` and `openeng help objects-sdk readObjectSet`.
269
+ 2. Query the objects you need with `openeng objects-sdk queryObjects --json`. Keep each object's
270
+ project with its identifier; one set may contain objects of several projects in your organisation.
271
+ 3. Call `openeng objects-sdk createObjectSet` with a name and the selected addresses, following its
272
+ help. Keep the returned set identifier and revision. Retrying with the same idempotency key
273
+ returns that original answer.
274
+ 4. Run `openeng link explore --project <page project> --ref <ref> --object-set <set id>` and give the
275
+ person the address it prints. It reads the set first; a refused read prints no link. The set
276
+ stores no ref, so the link's ref chooses which version of its objects opens.
277
+
266
278
  Every kind with `--ref`, including `ontology` and `change-set`, takes `main` or
267
279
  `<projectId>/<branch>`, the ref the platform returns. A bare branch name or change-set id is
268
280
  refused by `openeng link`. Before printing, the command reads the ref and the page's own subject;