@elevasis/sdk 1.33.1 → 1.34.0

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.d.ts CHANGED
@@ -6546,7 +6546,7 @@ declare const OntologyGroupSchema: z.ZodObject<{
6546
6546
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
6547
6547
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
6548
6548
  }, z.core.$loose>;
6549
- declare const OntologySurfaceTypeSchema: z.ZodObject<{
6549
+ declare const OntologyEndpointTypeSchema: z.ZodObject<{
6550
6550
  id: z.ZodString;
6551
6551
  label: z.ZodOptional<z.ZodString>;
6552
6552
  description: z.ZodOptional<z.ZodString>;
@@ -6637,7 +6637,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
6637
6637
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
6638
6638
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
6639
6639
  }, z.core.$loose>>>>;
6640
- surfaces: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
6640
+ endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
6641
6641
  id: z.ZodString;
6642
6642
  label: z.ZodOptional<z.ZodString>;
6643
6643
  description: z.ZodOptional<z.ZodString>;
@@ -6655,7 +6655,7 @@ type OntologyInterfaceType = z.infer<typeof OntologyInterfaceTypeSchema>;
6655
6655
  type OntologyValueType = z.infer<typeof OntologyValueTypeSchema>;
6656
6656
  type OntologySharedProperty = z.infer<typeof OntologySharedPropertySchema>;
6657
6657
  type OntologyGroup = z.infer<typeof OntologyGroupSchema>;
6658
- type OntologySurfaceType = z.infer<typeof OntologySurfaceTypeSchema>;
6658
+ type OntologyEndpointType = z.infer<typeof OntologyEndpointTypeSchema>;
6659
6659
  type OntologyScope = z.infer<typeof OntologyScopeSchema>;
6660
6660
  type ResolvedOntologyIndex = {
6661
6661
  objectTypes: Record<OntologyId, ResolvedOntologyRecord<OntologyObjectType>>;
@@ -6667,7 +6667,7 @@ type ResolvedOntologyIndex = {
6667
6667
  valueTypes: Record<OntologyId, ResolvedOntologyRecord<OntologyValueType>>;
6668
6668
  sharedProperties: Record<OntologyId, ResolvedOntologyRecord<OntologySharedProperty>>;
6669
6669
  groups: Record<OntologyId, ResolvedOntologyRecord<OntologyGroup>>;
6670
- surfaces: Record<OntologyId, ResolvedOntologyRecord<OntologySurfaceType>>;
6670
+ endpoints: Record<OntologyId, ResolvedOntologyRecord<OntologyEndpointType>>;
6671
6671
  };
6672
6672
  type OntologyRecordOrigin = {
6673
6673
  kind: 'authored' | 'projected';
@@ -7334,7 +7334,7 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
7334
7334
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
7335
7335
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
7336
7336
  }, z.core.$loose>>>>;
7337
- surfaces: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
7337
+ endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
7338
7338
  id: z.ZodString;
7339
7339
  label: z.ZodOptional<z.ZodString>;
7340
7340
  description: z.ZodOptional<z.ZodString>;
package/dist/index.js CHANGED
@@ -31,16 +31,13 @@ var OntologyKindSchema = z.enum([
31
31
  "value-type",
32
32
  "property",
33
33
  "group",
34
- "surface"
34
+ "endpoint"
35
35
  ]);
36
36
  var SYSTEM_PATH_PATTERN = "[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)*";
37
37
  var LOCAL_ID_PATTERN = "[a-z0-9][a-z0-9._-]*";
38
38
  var ONTOLOGY_ID_PATTERN = `^(global|${SYSTEM_PATH_PATTERN}):(${OntologyKindSchema.options.join("|")})\\/(${LOCAL_ID_PATTERN})$`;
39
39
  var ONTOLOGY_ID_REGEX = new RegExp(ONTOLOGY_ID_PATTERN);
40
- var OntologyIdSchema = z.string().trim().min(1).max(300).regex(
41
- ONTOLOGY_ID_REGEX,
42
- "Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
43
- );
40
+ var OntologyIdSchema = z.string().trim().min(1).max(300).regex(ONTOLOGY_ID_REGEX, "Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>");
44
41
  function parseOntologyId(id) {
45
42
  const normalized = OntologyIdSchema.parse(id);
46
43
  const match = ONTOLOGY_ID_REGEX.exec(normalized);
@@ -103,7 +100,7 @@ var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
103
100
  var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
104
101
  members: OntologyReferenceListSchema
105
102
  });
106
- var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
103
+ var OntologyEndpointTypeSchema = OntologyRecordBaseSchema.extend({
107
104
  route: z.string().trim().min(1).max(500).optional()
108
105
  });
109
106
  var OntologyScopeSchema = z.object({
@@ -116,7 +113,7 @@ var OntologyScopeSchema = z.object({
116
113
  valueTypes: z.record(OntologyIdSchema, OntologyValueTypeSchema).default({}).optional(),
117
114
  sharedProperties: z.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
118
115
  groups: z.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
119
- surfaces: z.record(OntologyIdSchema, OntologySurfaceTypeSchema).default({}).optional()
116
+ endpoints: z.record(OntologyIdSchema, OntologyEndpointTypeSchema).default({}).optional()
120
117
  }).default({});
121
118
  var SCOPE_KIND = {
122
119
  objectTypes: "object",
@@ -128,7 +125,7 @@ var SCOPE_KIND = {
128
125
  valueTypes: "value-type",
129
126
  sharedProperties: "property",
130
127
  groups: "group",
131
- surfaces: "surface"
128
+ endpoints: "endpoint"
132
129
  };
133
130
  var SCOPE_KEYS = Object.keys(SCOPE_KIND);
134
131
  function originFromContext(context) {
@@ -151,7 +148,7 @@ function createEmptyIndex() {
151
148
  valueTypes: {},
152
149
  sharedProperties: {},
153
150
  groups: {},
154
- surfaces: {}
151
+ endpoints: {}
155
152
  };
156
153
  }
157
154
  function sortResolvedOntologyIndex(index) {
@@ -2252,8 +2249,8 @@ function ontologyIndexForKind(index, kind) {
2252
2249
  return index.sharedProperties;
2253
2250
  case "group":
2254
2251
  return index.groups;
2255
- case "surface":
2256
- return index.surfaces;
2252
+ case "endpoint":
2253
+ return index.endpoints;
2257
2254
  }
2258
2255
  }
2259
2256
  function sameJson(left, right) {
@@ -1377,7 +1377,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
1377
1377
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
1378
1378
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
1379
1379
  }, z.core.$loose>>>>;
1380
- surfaces: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1380
+ endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1381
1381
  id: z.ZodString;
1382
1382
  label: z.ZodOptional<z.ZodString>;
1383
1383
  description: z.ZodOptional<z.ZodString>;
@@ -2042,7 +2042,7 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2042
2042
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
2043
2043
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
2044
2044
  }, z.core.$loose>>>>;
2045
- surfaces: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
2045
+ endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
2046
2046
  id: z.ZodString;
2047
2047
  label: z.ZodOptional<z.ZodString>;
2048
2048
  description: z.ZodOptional<z.ZodString>;
@@ -5864,7 +5864,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
5864
5864
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
5865
5865
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
5866
5866
  }, z.core.$loose>>>>;
5867
- surfaces: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
5867
+ endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
5868
5868
  id: z.ZodString;
5869
5869
  label: z.ZodOptional<z.ZodString>;
5870
5870
  description: z.ZodOptional<z.ZodString>;
@@ -6529,7 +6529,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
6529
6529
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
6530
6530
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
6531
6531
  }, z.core.$loose>>>>;
6532
- surfaces: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
6532
+ endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
6533
6533
  id: z.ZodString;
6534
6534
  label: z.ZodOptional<z.ZodString>;
6535
6535
  description: z.ZodOptional<z.ZodString>;
@@ -8325,16 +8325,13 @@ var OntologyKindSchema = z.enum([
8325
8325
  "value-type",
8326
8326
  "property",
8327
8327
  "group",
8328
- "surface"
8328
+ "endpoint"
8329
8329
  ]);
8330
8330
  var SYSTEM_PATH_PATTERN = "[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)*";
8331
8331
  var LOCAL_ID_PATTERN = "[a-z0-9][a-z0-9._-]*";
8332
8332
  var ONTOLOGY_ID_PATTERN = `^(global|${SYSTEM_PATH_PATTERN}):(${OntologyKindSchema.options.join("|")})\\/(${LOCAL_ID_PATTERN})$`;
8333
8333
  var ONTOLOGY_ID_REGEX = new RegExp(ONTOLOGY_ID_PATTERN);
8334
- var OntologyIdSchema = z.string().trim().min(1).max(300).regex(
8335
- ONTOLOGY_ID_REGEX,
8336
- "Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
8337
- );
8334
+ var OntologyIdSchema = z.string().trim().min(1).max(300).regex(ONTOLOGY_ID_REGEX, "Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>");
8338
8335
  function parseOntologyId(id) {
8339
8336
  const normalized = OntologyIdSchema.parse(id);
8340
8337
  const match = ONTOLOGY_ID_REGEX.exec(normalized);
@@ -8397,7 +8394,7 @@ var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
8397
8394
  var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
8398
8395
  members: OntologyReferenceListSchema
8399
8396
  });
8400
- var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
8397
+ var OntologyEndpointTypeSchema = OntologyRecordBaseSchema.extend({
8401
8398
  route: z.string().trim().min(1).max(500).optional()
8402
8399
  });
8403
8400
  var OntologyScopeSchema = z.object({
@@ -8410,7 +8407,7 @@ var OntologyScopeSchema = z.object({
8410
8407
  valueTypes: z.record(OntologyIdSchema, OntologyValueTypeSchema).default({}).optional(),
8411
8408
  sharedProperties: z.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
8412
8409
  groups: z.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
8413
- surfaces: z.record(OntologyIdSchema, OntologySurfaceTypeSchema).default({}).optional()
8410
+ endpoints: z.record(OntologyIdSchema, OntologyEndpointTypeSchema).default({}).optional()
8414
8411
  }).default({});
8415
8412
  var SCOPE_KIND = {
8416
8413
  objectTypes: "object",
@@ -8422,7 +8419,7 @@ var SCOPE_KIND = {
8422
8419
  valueTypes: "value-type",
8423
8420
  sharedProperties: "property",
8424
8421
  groups: "group",
8425
- surfaces: "surface"
8422
+ endpoints: "endpoint"
8426
8423
  };
8427
8424
  var SCOPE_KEYS = Object.keys(SCOPE_KIND);
8428
8425
  function originFromContext(context) {
@@ -8445,7 +8442,7 @@ function createEmptyIndex() {
8445
8442
  valueTypes: {},
8446
8443
  sharedProperties: {},
8447
8444
  groups: {},
8448
- surfaces: {}
8445
+ endpoints: {}
8449
8446
  };
8450
8447
  }
8451
8448
  function sortResolvedOntologyIndex(index2) {
@@ -9386,8 +9383,8 @@ function ontologyIndexForKind(index2, kind) {
9386
9383
  return index2.sharedProperties;
9387
9384
  case "group":
9388
9385
  return index2.groups;
9389
- case "surface":
9390
- return index2.surfaces;
9386
+ case "endpoint":
9387
+ return index2.endpoints;
9391
9388
  }
9392
9389
  }
9393
9390
  function sameJson(left, right) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "1.33.1",
3
+ "version": "1.34.0",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,9 +58,9 @@
58
58
  "tsup": "^8.0.0",
59
59
  "typescript": "5.9.2",
60
60
  "zod": "^4.1.0",
61
- "@repo/core": "0.43.0",
62
- "@repo/eslint-config": "0.0.0",
63
- "@repo/typescript-config": "0.0.0"
61
+ "@repo/core": "0.46.0",
62
+ "@repo/typescript-config": "0.0.0",
63
+ "@repo/eslint-config": "0.0.0"
64
64
  },
65
65
  "scripts": {
66
66
  "lint": "eslint src --max-warnings 0",
@@ -119,5 +119,5 @@ Use the owning skill instead of guessing from the name alone:
119
119
  | Refresh the Skills + Rules lists above | `pnpm gen:overview` (run from the monorepo) |
120
120
 
121
121
  The Skills section is generated from `external/_template/.claude/skills/*/SKILL.md` frontmatter, and
122
- the Rules section from the bundled rule source `packages/sdk/docs/agent-rules/*.md`, both by
123
- `.claude/_gen/sync-overview.ts`. Do not hand-edit the generated blocks.
122
+ the Rules section from the bundled rule source `packages/sdk/docs/agent-rules/*.md`, both by the
123
+ monorepo `pnpm gen:overview` generator. Do not hand-edit the generated blocks.
@@ -92,13 +92,13 @@ Auto-invocation is driven by frontmatter `description`, `metadata.pathPatterns`,
92
92
  Once invoked, classify the user's input into ONE of these buckets and dispatch the matching
93
93
  primitive. When two buckets fit, prefer the higher one (more specific → more general).
94
94
 
95
- | # | Bucket | Trigger | Dispatch |
96
- | --- | ------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- |
97
- | 1 | Named knowledge/role/policy id | User names `knowledge.<id>`, `role.<id>`, `policy.<id>` directly | `om:cat <id>` for body, `om:describe <id>` for neighborhood |
98
- | 2 | Named system | User names a system path (`sales.crm`, `sales.lead-gen`) | `om:describe <id>` |
99
- | 3 | Named ontology id | Id contains `:object/`, `:action/`, `:event/`, `:catalog/`, `:interface/`, `:link/`, `:surface/` | `om:describe <id>` (or `om:ls /by-ontology/<id> --ids-only` then `om:cat` each) |
100
- | 4 | Kind keyword | "playbooks", "strategies", "all references", "list policies" | `om:ls /by-kind/<kind> --ids-only` then `om:cat` each |
101
- | 5 | Free-text discovery | Anything else ("lead gen", "outreach", "what governs X?") | `om:search "<query>"` then drill into top hit with `om:describe` |
95
+ | # | Bucket | Trigger | Dispatch |
96
+ | --- | ------------------------------ | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
97
+ | 1 | Named knowledge/role/policy id | User names `knowledge.<id>`, `role.<id>`, `policy.<id>` directly | `om:cat <id>` for body, `om:describe <id>` for neighborhood |
98
+ | 2 | Named system | User names a system path (`sales.crm`, `sales.lead-gen`) | `om:describe <id>` |
99
+ | 3 | Named ontology id | Id contains `:object/`, `:action/`, `:event/`, `:catalog/`, `:interface/`, `:link/`, `:endpoint/` | `om:describe <id>` (or `om:ls /by-ontology/<id> --ids-only` then `om:cat` each) |
100
+ | 4 | Kind keyword | "playbooks", "strategies", "all references", "list policies" | `om:ls /by-kind/<kind> --ids-only` then `om:cat` each |
101
+ | 5 | Free-text discovery | Anything else ("lead gen", "outreach", "what governs X?") | `om:search "<query>"` then drill into top hit with `om:describe` |
102
102
 
103
103
  On ambiguous input, default to **bucket 5 (search)** and surface the top hits. Codify and Toggle
104
104
  intents are write paths -- see "Write Power" below.
@@ -107,17 +107,20 @@ intents are write paths -- see "Write Power" below.
107
107
 
108
108
  ## CLI Surface
109
109
 
110
- All commands run with `pnpm exec elevasis-sdk <cmd>` (or the `om:` alias of the legacy `knowledge:` name).
111
-
112
- | Command | Alias | Purpose |
113
- | ------------------ | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
114
- | `om:search <q>` | `knowledge:search` | Universal keyword search across all 6 OM surfaces |
115
- | `om:describe <id>` | `knowledge:describe` | Structured neighborhood view; kind auto-detected from id shape |
116
- | `om:cat <id>` | `knowledge:cat` | Raw MDX body of a knowledge node |
117
- | `om:ls <path>` | `knowledge:ls` | List by mount path. Enumeration: `/all-systems`, `/all-resources`, `/all-roles`. Scoped: `/by-system/`, `/by-kind/`, `/by-ontology/`, `/by-owner/`, `/graph/<id>/{governs,governed-by}` |
118
- | `om:graph <id>` | `knowledge:graph` | Show outgoing + incoming graph edges |
119
- | `om:skills <id>` | `knowledge:skills` | Show callable invocations on graph neighbors |
120
- | `om:generate` | `knowledge:generate` | Regenerate `_generated/nodes.ts` from MDX sources |
110
+ All commands run with `pnpm elevasis-sdk <cmd>` from the tenant project root (uses the root script
111
+ alias). Alternatively, use `pnpm -C operations exec elevasis-sdk <cmd>` from the monorepo root.
112
+ Do NOT use `pnpm exec elevasis-sdk <cmd>` at the project root -- `@elevasis/sdk` is a dependency of
113
+ `operations/` only; the binary is not found from the project root without the alias.
114
+
115
+ | Command | Alias | Purpose |
116
+ | ------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
117
+ | `om:search <q>` | `knowledge:search` | Universal keyword search across all 6 OM surfaces |
118
+ | `om:describe <id>` | `knowledge:describe` | Structured neighborhood view; kind auto-detected from id shape; also resolves `item:<domain>:<id>` and bare `<prefix>:<uuid>` domain-item forms |
119
+ | `om:cat <id>` | `knowledge:cat` | Raw MDX body of a knowledge node |
120
+ | `om:ls <path>` | `knowledge:ls` | List by mount path. Enumeration: `/all-systems`, `/all-resources`, `/all-roles`. Scoped: `/by-system/`, `/by-kind/`, `/by-ontology/`, `/by-owner/`, `/by-domain/`, `/by-item/`, `/graph/<id>/{governs,governed-by}` |
121
+ | `om:graph <id>` | `knowledge:graph` | Show outgoing + incoming graph edges |
122
+ | `om:skills <id>` | `knowledge:skills` | Show callable invocations on graph neighbors |
123
+ | `om:generate` | `knowledge:generate` | Regenerate `_generated/nodes.ts` from MDX sources |
121
124
 
122
125
  Common flags: `--json`, `--ids-only`, `--limit <n>`, `--kinds <list>`.
123
126
 
@@ -128,23 +131,42 @@ Common flags: `--json`, `--ids-only`, `--limit <n>`, `--kinds <list>`.
128
131
  ### Free-text discovery (default for natural-language queries)
129
132
 
130
133
  ```bash
131
- pnpm exec elevasis-sdk om:search "lead gen"
132
- pnpm exec elevasis-sdk om:search outreach --kinds knowledge --limit 5
133
- pnpm exec elevasis-sdk om:search apollo --ids-only
134
+ pnpm elevasis-sdk om:search "lead gen"
135
+ pnpm elevasis-sdk om:search outreach --kinds knowledge --limit 5
136
+ pnpm elevasis-sdk om:search apollo --ids-only
134
137
  ```
135
138
 
136
139
  ### Neighborhood view for any OM node
137
140
 
138
141
  ```bash
139
- pnpm exec elevasis-sdk om:describe sales.crm
140
- pnpm exec elevasis-sdk om:describe knowledge.outreach-playbook
141
- pnpm exec elevasis-sdk om:describe sales.crm:object/deal
142
+ pnpm elevasis-sdk om:describe sales.crm
143
+ pnpm elevasis-sdk om:describe knowledge.outreach-playbook
144
+ pnpm elevasis-sdk om:describe sales.crm:object/deal
145
+ ```
146
+
147
+ ### Domain-item profile (clients, roles, policies, customers, offerings, goals)
148
+
149
+ Use `om:describe item:<domain>:<id>` to read a rich domain-item profile -- identity, branding,
150
+ location, and governing knowledge. The bare `<prefix>:<uuid>` form (e.g. `client:<uuid>`) is
151
+ accepted as a back-compat alias and resolves identically.
152
+
153
+ ```bash
154
+ pnpm elevasis-sdk om:describe item:clients:<uuid> # full ClientProfile + location + governing knowledge
155
+ pnpm elevasis-sdk om:describe item:roles:<id>
156
+ pnpm elevasis-sdk om:describe item:policies:<id>
157
+ pnpm elevasis-sdk om:describe item:customers:<id>
158
+ pnpm elevasis-sdk om:describe item:offerings:<id>
159
+ pnpm elevasis-sdk om:describe item:goals:<id>
142
160
  ```
143
161
 
162
+ Do not confuse this with `client:get <uuid>` (the portfolio/DB surface for status, lineage, and
163
+ deals). `om:describe item:clients:<uuid>` returns the org-model `ClientProfile`; `client:get`
164
+ returns a sparse DB record. They share the same `id` and can be cross-linked by it.
165
+
144
166
  ### Read a single knowledge node body
145
167
 
146
168
  ```bash
147
- pnpm exec elevasis-sdk om:cat knowledge.outreach-playbook
169
+ pnpm elevasis-sdk om:cat knowledge.outreach-playbook
148
170
  ```
149
171
 
150
172
  ### Top-level enumeration (drill-down entry point)
@@ -153,10 +175,10 @@ Start here when an agent needs to discover what this tenant's custom OM contains
153
175
  building on it -- list everything in a domain, then narrow with `om:describe` / `om:cat`:
154
176
 
155
177
  ```bash
156
- pnpm exec elevasis-sdk om:ls /all-systems # every System (path + label)
157
- pnpm exec elevasis-sdk om:ls /all-resources # every resource (id, kind, title)
158
- pnpm exec elevasis-sdk om:ls /all-roles # every role (id, title)
159
- pnpm exec elevasis-sdk om:ls /all-systems --ids-only # pipe paths into om:describe
178
+ pnpm elevasis-sdk om:ls /all-systems # every System (path + label)
179
+ pnpm elevasis-sdk om:ls /all-resources # every resource (id, kind, title)
180
+ pnpm elevasis-sdk om:ls /all-roles # every role (id, title)
181
+ pnpm elevasis-sdk om:ls /all-systems --ids-only # pipe paths into om:describe
160
182
  ```
161
183
 
162
184
  These resolve against this tenant's resolved model -- they enumerate the project's own custom
@@ -165,11 +187,13 @@ OM, not the platform's. Use `--json` for the wrapped envelope or `--ids-only` fo
165
187
  ### Scoped mount-path listings
166
188
 
167
189
  ```bash
168
- pnpm exec elevasis-sdk om:ls /by-system/sales.crm
169
- pnpm exec elevasis-sdk om:ls /by-kind/playbook --ids-only
170
- pnpm exec elevasis-sdk om:ls /by-ontology/sales.crm:object/deal --ids-only
171
- pnpm exec elevasis-sdk om:ls /by-owner/role.ops-lead --ids-only
172
- pnpm exec elevasis-sdk om:graph knowledge.outreach-playbook
190
+ pnpm elevasis-sdk om:ls /by-system/sales.crm
191
+ pnpm elevasis-sdk om:ls /by-kind/playbook --ids-only
192
+ pnpm elevasis-sdk om:ls /by-ontology/sales.crm:object/deal --ids-only
193
+ pnpm elevasis-sdk om:ls /by-owner/role.ops-lead --ids-only
194
+ pnpm elevasis-sdk om:ls /by-domain/clients # enumerate all client domain items
195
+ pnpm elevasis-sdk om:ls /by-item/clients/<uuid> # single item record (same as om:describe item:clients:<uuid>)
196
+ pnpm elevasis-sdk om:graph knowledge.outreach-playbook
173
197
  ```
174
198
 
175
199
  When a query clearly names an ontology id such as `sales.crm:object/deal`, route through
@@ -179,17 +203,31 @@ When a query clearly names an ontology id such as `sales.crm:object/deal`, route
179
203
 
180
204
  ### `/om read-folder` (chat shorthand from the Knowledge Browser)
181
205
 
182
- The Knowledge Browser's copy button on a top-level system or kind group emits a single
183
- `/om read-folder <axis>:<id>` line (or the legacy `/knowledge read-folder ...` form) instead of
184
- N per-node `read` lines. Resolve it by listing the folder via `om:ls` and reading each child:
206
+ The Knowledge Browser's copy button on a top-level system, kind group, or domain-item node
207
+ emits a single `/om read-folder <axis>:<id>` line (or the legacy `/knowledge read-folder ...`
208
+ form) instead of N per-node `read` lines. Resolve it by the table below:
209
+
210
+ | Copy form | Resolution |
211
+ | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
212
+ | `/om read-folder system:<id>` | `pnpm elevasis-sdk om:ls /by-system/<id> --ids-only`, then `om:cat` each |
213
+ | `/om read-folder kind:<kind>` | `pnpm elevasis-sdk om:ls /by-kind/<kind> --ids-only`, then `om:cat` each |
214
+ | `/om read-folder owner:<id>` | `pnpm elevasis-sdk om:ls /by-owner/<id> --ids-only`, then `om:cat` each |
215
+ | `/om read-folder ontology:<id>` | `pnpm elevasis-sdk om:ls /by-ontology/<id> --ids-only`, then `om:cat` each |
216
+ | `/om read-folder item:<domain>:<id>` | `pnpm elevasis-sdk om:describe item:<domain>:<id>` -- returns profile + location + governing knowledge |
217
+ | `/om read-folder graph:<id>` | inspect `/graph/<id>/governs` and `/graph/<id>/governed-by`; read returned knowledge ids |
218
+ | `/om read-folder group:<id>` | browser overview reference only; resolve by visible children -- `pnpm elevasis-sdk om:ls /by-system/<id> --ids-only` |
219
+ | `/om read-folder domain:<domain>` | browser overview reference only; resolve by enumerating domain -- `pnpm elevasis-sdk om:ls /by-domain/<domain> --ids-only` |
220
+ | `/om read-folder folder:<id>` | browser overview reference only; treat as `domain:<id>` and enumerate with `/by-domain/<id>` |
221
+
222
+ **Legacy bridge -- `graph:client:<uuid>` and other `graph:<prefix>:<uuid>` domain-item forms:**
223
+ Older Knowledge Browser builds emitted `graph:client:<uuid>` for client items. This is a
224
+ graph-neighborhood shorthand, not a profile read. When you receive such a reference:
225
+
226
+ 1. Resolve the graph neighborhood: `pnpm elevasis-sdk om:graph client:<uuid>` (may return empty or only `contains` edges -- that is expected; no `ClientProfile` is accessible this way).
227
+ 2. For the rich profile, pivot to: `pnpm elevasis-sdk om:describe item:clients:<uuid>`.
185
228
 
186
- | Copy form | Resolution |
187
- | ------------------------------- | ---------------------------------------------------------------------------------------- |
188
- | `/om read-folder system:<id>` | `pnpm exec elevasis-sdk om:ls /by-system/<id> --ids-only`, then `om:cat` each |
189
- | `/om read-folder kind:<kind>` | `pnpm exec elevasis-sdk om:ls /by-kind/<kind> --ids-only`, then `om:cat` each |
190
- | `/om read-folder owner:<id>` | `pnpm exec elevasis-sdk om:ls /by-owner/<id> --ids-only`, then `om:cat` each |
191
- | `/om read-folder ontology:<id>` | `pnpm exec elevasis-sdk om:ls /by-ontology/<id> --ids-only`, then `om:cat` each |
192
- | `/om read-folder graph:<id>` | inspect `/graph/<id>/governs` and `/graph/<id>/governed-by`; read returned knowledge ids |
229
+ In short: `graph:client:<uuid>` points to the graph node; `item:clients:<uuid>` resolves the
230
+ full org-model profile. Always use `item:` for profile reads going forward.
193
231
 
194
232
  Dotted system ids may use either dots or slashes (`sales.crm` and `sales/crm` both work).
195
233
  Legacy `feature:<id>` copy lines from older browser builds are compatibility aliases for
@@ -261,8 +299,8 @@ Placement examples:
261
299
 
262
300
  Before adding a System:
263
301
 
264
- 1. Run `pnpm exec elevasis-sdk om:ls /all-systems`.
265
- 2. Run `pnpm exec elevasis-sdk om:describe <candidate-parent-or-owner>`.
302
+ 1. Run `pnpm elevasis-sdk om:ls /all-systems`.
303
+ 2. Run `pnpm elevasis-sdk om:describe <candidate-parent-or-owner>`.
266
304
  3. If the proposed System name is a resource kind, shell group, or catch-all, do not create it;
267
305
  attach or create a Resource under the real owning System.
268
306
  4. Create a new System only when no existing System owns the capability and the new System has
@@ -414,4 +452,4 @@ classification names a specific domain.
414
452
 
415
453
  ---
416
454
 
417
- **Last Updated:** 2026-05-14
455
+ **Last Updated:** 2026-06-06
@@ -115,9 +115,11 @@ Agents that need to pass structured JSON to `request:submit` or `exec` should wr
115
115
  pnpm elevasis-sdk exec my-workflow -f tmp/exec-payload.json --cleanup-input
116
116
  ```
117
117
 
118
- 3. The `--cleanup-input` flag deletes the file automatically after a successful command. On failure the file is left intact for inspection.
118
+ 3. The `--cleanup-input` flag deletes request/exec input files automatically after a successful command. On failure the file is left intact for inspection.
119
119
 
120
- **Safety guard:** `--cleanup-input` only deletes files that are under `<projectRoot>/tmp/`. If the resolved path is outside `tmp/`, the CLI prints a warning to stderr and leaves the file untouched. Files passed via `--input <json>` (inline JSON, no file) are never affected.
120
+ **Safety guard:** `--cleanup-input` only deletes files that are under `<projectRoot>/tmp/`. If the resolved path is outside `tmp/`, the CLI prints a warning to stderr and leaves the file untouched. Files passed via inline JSON flags are never affected.
121
+
122
+ Checklist commands in the currently published SDK use inline `--checklist` JSON only. In Windows PowerShell 5.1, inline JSON is not reliable; use bash/PowerShell 7 for those updates, or update the checklist through the UI.
121
123
 
122
124
  ---
123
125
 
@@ -298,11 +300,11 @@ Both `prj_milestones.checklist` and `prj_tasks.checklist` store a JSONB array of
298
300
  ]
299
301
  ```
300
302
 
301
- The CLI `--checklist` flag on both `project:milestone:update` and `project:task:update` performs a **full replace** the entire array is replaced with the JSON you supply. There are no item-level add/toggle/remove flags. To mutate a single item:
303
+ The CLI `--checklist` flag on `project:task:create`, `project:task:update`, and `project:milestone:update` performs a **full replace** where the command accepts checklist data. The entire array is replaced with the JSON you supply. There are no item-level add/toggle/remove flags. In Windows PowerShell 5.1, inline JSON is not reliable; use bash/PowerShell 7 for checklist CLI updates, or update the checklist through the UI. To mutate a single item:
302
304
 
303
305
  1. Read the current checklist (via psql or `project:task:get` / `project:milestone:list`)
304
306
  2. Mutate the array in memory (append, flip `completed`, filter out)
305
- 3. Write the entire array back via `--checklist '<json>'`
307
+ 3. Write the entire array back via `--checklist '<json-array>'`
306
308
 
307
309
  To clear a checklist: `--checklist '[]'`.
308
310
 
@@ -668,7 +670,7 @@ pnpm elevasis-sdk project:milestone:update <milestone-id> --status completed
668
670
 
669
671
  # Update checklist (full replace)
670
672
  pnpm elevasis-sdk project:milestone:update <milestone-id> \
671
- --checklist '[{"id":"uuid","label":"Item label","completed":false}]'
673
+ --checklist '[{"id":"1","label":"Review scope doc","completed":false}]'
672
674
  ```
673
675
 
674
676
  If status changes to `completed`, the API auto-sets `completed_at`.
@@ -679,7 +681,7 @@ If status changes to `completed`, the API auto-sets `completed_at`.
679
681
 
680
682
  1. Read the current checklist via psql or `project:milestone:list`
681
683
  2. Mutate the array in memory
682
- 3. Write back the full array via `--checklist '<json>'`
684
+ 3. Write back the full array via `--checklist '<json-array>'`
683
685
 
684
686
  ### `checklist <client> "<milestone>"` — View Checklist
685
687
 
@@ -741,7 +743,7 @@ pnpm elevasis-sdk project:task:create \
741
743
  pnpm elevasis-sdk project:task:create \
742
744
  --project <project-id> \
743
745
  --title "<name>" \
744
- --checklist '[{"id":"1","label":"Step one","completed":false}]'
746
+ --checklist '[{"id":"1","label":"Review scope doc","completed":false}]'
745
747
  ```
746
748
 
747
749
  ### `task update <client> "<task>" [options]` — Update Task
@@ -757,7 +759,7 @@ pnpm elevasis-sdk project:task:update <task-id> --status <status>
757
759
 
758
760
  # Update checklist (full replace)
759
761
  pnpm elevasis-sdk project:task:update <task-id> \
760
- --checklist '[{"id":"uuid","label":"Step","completed":false}]'
762
+ --checklist '[{"id":"1","label":"Review scope doc","completed":false}]'
761
763
 
762
764
  # Clear checklist
763
765
  pnpm elevasis-sdk project:task:update <task-id> --checklist '[]'
@@ -773,7 +775,7 @@ If status changes to `approved`, the API auto-sets `completed_at`.
773
775
 
774
776
  1. Read the current task via `project:task:get <task-id>`
775
777
  2. Mutate the checklist array in memory
776
- 3. Write back the full array via `project:task:update <task-id> --checklist '<json>'`
778
+ 3. Write back the full array via `project:task:update <task-id> --checklist '<json-array>'`
777
779
 
778
780
  ### `note <client> "<content>" [options]` — Add Note
779
781
 
@@ -964,15 +966,15 @@ When args don't match any command pattern, infer intent from natural language:
964
966
  | "what's overdue?" | List milestones where `due_date < now() AND status != 'completed'` |
965
967
  | "block acme, waiting on client credentials" | `update acme --status blocked` |
966
968
  | "show checklist for phase 2" | Read and display checklist for milestone "phase 2" via psql or `project:milestone:list` |
967
- | "add 'deploy staging' to task X's checklist" | Read task X's checklist → append `{id: uuid, label: "deploy staging", completed: false}` → `project:task:update <id> --checklist '<json>'` |
968
- | "mark 'deploy staging' done on task X" | Read task X's checklist → flip `completed` on matching item → `project:task:update <id> --checklist '<json>'` |
969
+ | "add 'deploy staging' to task X's checklist" | Read task X's checklist → append `{id: uuid, label: "deploy staging", completed: false}` → `project:task:update <id> --checklist '<json-array>'` |
970
+ | "mark 'deploy staging' done on task X" | Read task X's checklist → flip `completed` on matching item → `project:task:update <id> --checklist '<json-array>'` |
969
971
  | "clear the checklist on task X" | `project:task:update <task-id> --checklist '[]'` |
970
- | "add checklist item to onboarding milestone: review scope doc" | Read milestone checklist → append item → `project:milestone:update <id> --checklist '<json>'` |
972
+ | "add checklist item to onboarding milestone: review scope doc" | Read milestone checklist → append item → `project:milestone:update <id> --checklist '<json-array>'` |
971
973
  | "I'm done" / "task complete" / "done with this" | Resolve active task → confirm → `project:task:update <task-id> --status completed` |
972
974
  | "save: Apify actor X rate-limits at 20rps" | Resolve active project/task → `project:note:create --project <id> --type agent_learning --task <task-id> "Apify actor X rate-limits at 20rps"` |
973
975
  | "remember: client requires ISO dates, not timestamps" | Resolve active project/task → `project:note:create --project <id> --type agent_learning --task <task-id> "client requires ISO dates, not timestamps"` |
974
976
 
975
- **Checklist note:** all checklist mutations use the read-modify-write pattern. The CLI has no item-level flags (`--add-item`, `--toggle`, `--remove-item` do not exist). Always read the current state, mutate the array, then write the full array back.
977
+ **Checklist note:** all checklist mutations use the read-modify-write pattern. The CLI has no item-level flags (`--add-item`, `--toggle`, `--remove-item` do not exist). Always read the current state, mutate the array, then write the full array back. Use bash/PowerShell 7 for generated checklist JSON; Windows PowerShell 5.1 native argument passing is not reliable for inline JSON.
976
978
 
977
979
  ---
978
980
 
@@ -1078,7 +1080,7 @@ The full `client:*` surface (list, get, status, resolve) is available via `eleva
1078
1080
  6. **Template project assumption** — the template is a single-organization project. All
1079
1081
  `/project` operations operate within the organization scoped by `ELEVASIS_PLATFORM_KEY`.
1080
1082
  There is no cross-org capability.
1081
- 7. **Checklist full-replace** — the `--checklist` flag replaces the entire array. Always read
1083
+ 7. **Checklist full-replace** — `--checklist` replaces the entire array. Always read
1082
1084
  the current checklist before writing to avoid losing existing items.
1083
1085
  8. **Confirm task completion** — always ask once before marking a task `completed` via "I'm done"
1084
1086
  recognition. This status is semantically significant and warrants a confirmation step.
@@ -0,0 +1,29 @@
1
+ # Appearance Page Decoupled From App-Mode
2
+
3
+ ## Why this note exists
4
+
5
+ The Settings → Appearance page used to be hard-coupled to `dev-centric` app-mode: scaffold removed it under `--client-centric`, every `/external sync` actively deleted it (planner `delete` special-case), and verify forbade it for `client-centric` projects. That made the page silently vanish on every sync for client-centric tenants.
6
+
7
+ This train decouples Appearance from app-mode. Appearance is now an optional standalone page available in any mode. The only remaining app-mode difference is the `OrganizationSwitcher` in the topbar.
8
+
9
+ No npm publish is involved: the page renders the already-published `@elevasis/ui@2.46.0` `AppearanceSettings` component. The substrate changes (`scripts/external/*`) and the `_template` route are monorepo-internal and propagate through `/external sync`.
10
+
11
+ ## Applies to
12
+
13
+ - All template-derived projects under `external/` that lack `ui/src/routes/settings/appearance.tsx`.
14
+ - Confirmed pending at prep time: `nirvana-marketing` (sync planner `writes=1` for the appearance route). `contemplative-records` already restored it; `ZentaraHQ` shows no pending write.
15
+
16
+ ## Required actions
17
+
18
+ 1. The new template route `ui/src/routes/settings/appearance.tsx` propagates automatically via `/external sync` (registry entry `external-sync-feature-route-baseline`, `sync-preservation`). No manual file copy needed — running the prepared sync applies it.
19
+ 2. **Per-tenant nav entry is NOT propagated.** `core/config/organization-model/navigation.ts` is project-owned (sync-preservation). For any tenant that should surface Appearance in its sidebar, manually add a `settings-appearance` entry to `navigation.sidebar.bottom.settings.children` (order `50`, after `settings-webhooks`), pointing at the appearance route.
20
+
21
+ ## Verification
22
+
23
+ - After sync: `pnpm -C external/<project>/ui check-types` passes with the new route present.
24
+ - `pnpm sync:verify` reports `writes=0` for the synced project's `sync-plan`.
25
+ - The Appearance entry renders in the Settings sidebar only after the per-tenant `navigation.ts` entry is added (step 2).
26
+
27
+ ## Not handled by /git-sync
28
+
29
+ `/git-sync` does not author the per-tenant `navigation.ts` nav entry — it is project-owned business content and must be added by hand per tenant. `/git-sync` also will not retroactively restore the route for tenants that were previously stripped by the old delete special-case; run the prepared `/external sync --all` to apply the new non-deleting baseline.