@elevasis/sdk 1.35.1 → 1.36.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/cli.cjs +165 -1
- package/dist/test-utils/index.d.ts +1 -1
- package/dist/test-utils/index.js +10 -10
- package/dist/types/worker/index.d.ts +1 -1
- package/dist/worker/index.js +10 -10
- package/package.json +4 -4
- package/reference/claude-config/registries/skill-coverage.json +1 -0
- package/reference/claude-config/sync-notes/2026-06-12-agent-grants-visualizer-operations.md +30 -0
package/dist/cli.cjs
CHANGED
|
@@ -45807,7 +45807,7 @@ function wrapAction(commandName, fn) {
|
|
|
45807
45807
|
// package.json
|
|
45808
45808
|
var package_default = {
|
|
45809
45809
|
name: "@elevasis/sdk",
|
|
45810
|
-
version: "1.
|
|
45810
|
+
version: "1.36.0",
|
|
45811
45811
|
description: "SDK for building Elevasis organization resources",
|
|
45812
45812
|
type: "module",
|
|
45813
45813
|
bin: {
|
|
@@ -52198,6 +52198,166 @@ function registerSessionCommands(program3) {
|
|
|
52198
52198
|
registerSessionEnd(program3);
|
|
52199
52199
|
}
|
|
52200
52200
|
|
|
52201
|
+
// src/cli/commands/grant/grant.ts
|
|
52202
|
+
init_source();
|
|
52203
|
+
init_config();
|
|
52204
|
+
function printJson8(value) {
|
|
52205
|
+
console.log(JSON.stringify(value, null, 2));
|
|
52206
|
+
}
|
|
52207
|
+
function appendQuery7(params, key, value) {
|
|
52208
|
+
if (value === void 0 || value === null || value === "" || value === false) return;
|
|
52209
|
+
params.set(key, String(value));
|
|
52210
|
+
}
|
|
52211
|
+
function endpointWithQuery7(endpoint, params) {
|
|
52212
|
+
const query = params.toString();
|
|
52213
|
+
return query ? `${endpoint}?${query}` : endpoint;
|
|
52214
|
+
}
|
|
52215
|
+
function parseJson2(value, label) {
|
|
52216
|
+
if (value === void 0) return void 0;
|
|
52217
|
+
try {
|
|
52218
|
+
return JSON.parse(value);
|
|
52219
|
+
} catch (error46) {
|
|
52220
|
+
const message = error46 instanceof Error ? error46.message : String(error46);
|
|
52221
|
+
throw new Error(`Invalid JSON for ${label}: ${message}`);
|
|
52222
|
+
}
|
|
52223
|
+
}
|
|
52224
|
+
function parsePositiveInt(value, label) {
|
|
52225
|
+
if (value === void 0) return void 0;
|
|
52226
|
+
const parsed = Number(value);
|
|
52227
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
52228
|
+
throw new Error(`${label} must be a positive integer`);
|
|
52229
|
+
}
|
|
52230
|
+
return parsed;
|
|
52231
|
+
}
|
|
52232
|
+
function parseOrigins(value) {
|
|
52233
|
+
if (value === void 0) return void 0;
|
|
52234
|
+
const origins = value.split(",").map((origin) => origin.trim()).filter(Boolean);
|
|
52235
|
+
return origins.length > 0 ? origins : void 0;
|
|
52236
|
+
}
|
|
52237
|
+
function deriveSlugFromResourceId(resourceId) {
|
|
52238
|
+
const slug = resourceId.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
52239
|
+
if (!slug) {
|
|
52240
|
+
throw new Error("--resource must contain at least one alphanumeric character when --slug is omitted");
|
|
52241
|
+
}
|
|
52242
|
+
return slug;
|
|
52243
|
+
}
|
|
52244
|
+
function getPublicPath(slug) {
|
|
52245
|
+
return `/public/agents/${encodeURIComponent(slug)}`;
|
|
52246
|
+
}
|
|
52247
|
+
function resolvePublicUrl(slug, publicBaseUrl) {
|
|
52248
|
+
const path3 = getPublicPath(slug);
|
|
52249
|
+
const baseUrl = publicBaseUrl ?? process.env.ELEVASIS_PUBLIC_BASE_URL ?? process.env.ELEVASIS_PUBLIC_APP_URL;
|
|
52250
|
+
if (!baseUrl) return path3;
|
|
52251
|
+
try {
|
|
52252
|
+
return new URL(path3, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`).toString();
|
|
52253
|
+
} catch {
|
|
52254
|
+
throw new Error("--public-base-url must be a valid URL");
|
|
52255
|
+
}
|
|
52256
|
+
}
|
|
52257
|
+
function printGrant(grant) {
|
|
52258
|
+
const status = grant.isDisabled ? "disabled" : "active";
|
|
52259
|
+
console.log(source_default.white(` ${source_default.bold(grant.slug)} ${source_default.gray(status)}`));
|
|
52260
|
+
console.log(source_default.gray(` Agent: ${grant.resourceId}`));
|
|
52261
|
+
console.log(source_default.gray(` Mode: ${grant.mode}${grant.requiresCode ? " (code required)" : ""}`));
|
|
52262
|
+
console.log(source_default.gray(` Origins: ${grant.allowedOrigins.length > 0 ? grant.allowedOrigins.join(", ") : "any"}`));
|
|
52263
|
+
console.log(source_default.gray(` Limits: turns=${grant.maxTurnsPerSession}, sessions/visitor=${grant.maxSessionsPerVisitor}`));
|
|
52264
|
+
if (grant.expiresAt) console.log(source_default.gray(` Expires: ${new Date(grant.expiresAt).toLocaleString()}`));
|
|
52265
|
+
if (grant.disabledAt) console.log(source_default.gray(` Disabled: ${new Date(grant.disabledAt).toLocaleString()}`));
|
|
52266
|
+
}
|
|
52267
|
+
function registerGrantList(program3) {
|
|
52268
|
+
program3.command("grant:list").description("List public/code-gated agent access grants").option("--resource-id <id>", "Filter by agent resource ID").option("--include-disabled", "Include disabled grants").option("--api-url <url>", "API base URL").option("--json", "Output as JSON").action(
|
|
52269
|
+
wrapAction("grant:list", async (options) => {
|
|
52270
|
+
const apiUrl = resolveApiUrl(options.apiUrl);
|
|
52271
|
+
const params = new URLSearchParams();
|
|
52272
|
+
appendQuery7(params, "resourceId", options.resourceId);
|
|
52273
|
+
appendQuery7(params, "includeDisabled", options.includeDisabled ? "true" : void 0);
|
|
52274
|
+
const result = await apiGet(
|
|
52275
|
+
endpointWithQuery7("/api/external/agent-access-grants", params),
|
|
52276
|
+
apiUrl
|
|
52277
|
+
);
|
|
52278
|
+
if (options.json) {
|
|
52279
|
+
printJson8(result);
|
|
52280
|
+
return;
|
|
52281
|
+
}
|
|
52282
|
+
if (result.grants.length === 0) {
|
|
52283
|
+
console.log(source_default.yellow("No agent access grants found."));
|
|
52284
|
+
return;
|
|
52285
|
+
}
|
|
52286
|
+
console.log(source_default.cyan(`Agent access grants (${result.grants.length} of ${result.total}):`));
|
|
52287
|
+
for (const grant of result.grants) {
|
|
52288
|
+
printGrant(grant);
|
|
52289
|
+
console.log();
|
|
52290
|
+
}
|
|
52291
|
+
})
|
|
52292
|
+
);
|
|
52293
|
+
}
|
|
52294
|
+
function registerGrantCreate(program3) {
|
|
52295
|
+
program3.command("grant:create").description("Create a public/code-gated agent access grant").requiredOption("--resource <id>", "Agent resource ID to expose").option("--slug <slug>", "Public slug; defaults to normalized --resource").option("--mode <mode>", "Access mode: public | code", "public").option("--code <code>", "Access code for --mode code").option("--origins <origins>", "Comma-separated allowed origins; omit for any origin").option("--expires-at <iso>", "ISO timestamp when the grant expires").option("--max-turns <number>", "Maximum turns per public session").option("--max-sessions <number>", "Maximum sessions per visitor").option("--branding <json>", "Branding metadata JSON object").option("--capture-fields <json>", "Capture fields JSON array").option("--tool-policy <json>", "Tool policy JSON object").option("--public-base-url <url>", "Client public app base URL for printed public URL").option("--api-url <url>", "API base URL").option("--json", "Output as JSON").action(
|
|
52296
|
+
wrapAction("grant:create", async (options) => {
|
|
52297
|
+
const mode = options.mode ?? "public";
|
|
52298
|
+
if (mode !== "public" && mode !== "code") {
|
|
52299
|
+
throw new Error("--mode must be public or code");
|
|
52300
|
+
}
|
|
52301
|
+
if (mode === "code" && !options.code) {
|
|
52302
|
+
throw new Error("--code is required when --mode code");
|
|
52303
|
+
}
|
|
52304
|
+
const slug = options.slug ?? deriveSlugFromResourceId(options.resource);
|
|
52305
|
+
const body = {
|
|
52306
|
+
resourceId: options.resource,
|
|
52307
|
+
slug,
|
|
52308
|
+
mode
|
|
52309
|
+
};
|
|
52310
|
+
if (options.code) body.code = options.code;
|
|
52311
|
+
if (options.expiresAt) body.expiresAt = options.expiresAt;
|
|
52312
|
+
const allowedOrigins = parseOrigins(options.origins);
|
|
52313
|
+
if (allowedOrigins) body.allowedOrigins = allowedOrigins;
|
|
52314
|
+
const maxTurns = parsePositiveInt(options.maxTurns, "--max-turns");
|
|
52315
|
+
if (maxTurns !== void 0) body.maxTurnsPerSession = maxTurns;
|
|
52316
|
+
const maxSessions = parsePositiveInt(options.maxSessions, "--max-sessions");
|
|
52317
|
+
if (maxSessions !== void 0) body.maxSessionsPerVisitor = maxSessions;
|
|
52318
|
+
const branding = parseJson2(options.branding, "--branding");
|
|
52319
|
+
if (branding !== void 0) body.branding = branding;
|
|
52320
|
+
const captureFields = parseJson2(options.captureFields, "--capture-fields");
|
|
52321
|
+
if (captureFields !== void 0) body.captureFields = captureFields;
|
|
52322
|
+
const toolPolicy = parseJson2(options.toolPolicy, "--tool-policy");
|
|
52323
|
+
if (toolPolicy !== void 0) body.toolPolicy = toolPolicy;
|
|
52324
|
+
const apiUrl = resolveApiUrl(options.apiUrl);
|
|
52325
|
+
const result = await apiPost("/api/external/agent-access-grants", body, apiUrl);
|
|
52326
|
+
if (options.json) {
|
|
52327
|
+
printJson8(result.grant);
|
|
52328
|
+
return;
|
|
52329
|
+
}
|
|
52330
|
+
console.log(source_default.green(`Created agent access grant ${result.grant.slug}.`));
|
|
52331
|
+
console.log(source_default.gray(` Public URL: ${resolvePublicUrl(result.grant.slug, options.publicBaseUrl)}`));
|
|
52332
|
+
printGrant(result.grant);
|
|
52333
|
+
})
|
|
52334
|
+
);
|
|
52335
|
+
}
|
|
52336
|
+
function registerGrantDisable(program3) {
|
|
52337
|
+
program3.command("grant:disable <slug>").description("Disable an agent access grant without deleting it").option("--api-url <url>", "API base URL").option("--json", "Output as JSON").action(
|
|
52338
|
+
wrapAction("grant:disable", async (slug, options) => {
|
|
52339
|
+
const apiUrl = resolveApiUrl(options.apiUrl);
|
|
52340
|
+
const result = await apiPost(
|
|
52341
|
+
`/api/external/agent-access-grants/${encodeURIComponent(slug)}/disable`,
|
|
52342
|
+
{},
|
|
52343
|
+
apiUrl
|
|
52344
|
+
);
|
|
52345
|
+
if (options.json) {
|
|
52346
|
+
printJson8(result.grant);
|
|
52347
|
+
return;
|
|
52348
|
+
}
|
|
52349
|
+
console.log(source_default.green(`Disabled agent access grant ${result.grant.slug}.`));
|
|
52350
|
+
})
|
|
52351
|
+
);
|
|
52352
|
+
}
|
|
52353
|
+
|
|
52354
|
+
// src/cli/commands/grant/index.ts
|
|
52355
|
+
function registerGrantCommands(program3) {
|
|
52356
|
+
registerGrantList(program3);
|
|
52357
|
+
registerGrantCreate(program3);
|
|
52358
|
+
registerGrantDisable(program3);
|
|
52359
|
+
}
|
|
52360
|
+
|
|
52201
52361
|
// src/cli/commands/om/index.ts
|
|
52202
52362
|
function registerOmScaffoldCommands(program3) {
|
|
52203
52363
|
program3.command("om:scaffold:system").description("Guide creation of a new system entry in core/config/organization-model/systems.ts").option("--id <path>", "dot-notated system path, e.g. sales.crm (prompted if absent)").option("--title <title>", "display title (prompted if absent)").option("--kind <kind>", "system kind: operational | analytical | support (prompted if absent)").option("--api-backed", "emit apiInterface block and remind to add resource IDs").option("--dry-run", "print proposed TypeScript block without writing").action(async (opts) => {
|
|
@@ -52450,6 +52610,9 @@ Commands:
|
|
|
52450
52610
|
elevasis-sdk session:list List agent sessions
|
|
52451
52611
|
elevasis-sdk session:get <id> Get session details
|
|
52452
52612
|
elevasis-sdk session:end <id> End an active agent session
|
|
52613
|
+
elevasis-sdk grant:list List public/code-gated agent access grants
|
|
52614
|
+
elevasis-sdk grant:create --resource <id> Create an agent access grant
|
|
52615
|
+
elevasis-sdk grant:disable <slug> Disable an agent access grant
|
|
52453
52616
|
elevasis-sdk acquisition:list:list List acquisition lists
|
|
52454
52617
|
elevasis-sdk acquisition:deal:list List acquisition deals
|
|
52455
52618
|
elevasis-sdk knowledge:generate Generate knowledge nodes from MDX files
|
|
@@ -52487,6 +52650,7 @@ registerQueueCommands(program2);
|
|
|
52487
52650
|
registerScheduleCommands(program2);
|
|
52488
52651
|
registerAgentCommands(program2);
|
|
52489
52652
|
registerSessionCommands(program2);
|
|
52653
|
+
registerGrantCommands(program2);
|
|
52490
52654
|
registerAcquisitionCommands(program2);
|
|
52491
52655
|
registerKnowledgeCommands(program2);
|
|
52492
52656
|
registerRequestCommands(program2);
|
|
@@ -10797,7 +10797,7 @@ type TypedAdapter<TMap extends ToolMethodMap$1> = {
|
|
|
10797
10797
|
*
|
|
10798
10798
|
* Parent -> Worker: { type: 'abort' } (graceful abort before terminate)
|
|
10799
10799
|
*
|
|
10800
|
-
* Worker -> Parent: { type: 'log', entry: { level, message, timestamp, executionId } }
|
|
10800
|
+
* Worker -> Parent: { type: 'log', entry: { level, message, timestamp, executionId, context? } }
|
|
10801
10801
|
*
|
|
10802
10802
|
* Worker -> Parent: { type: 'tool-call', id, tool, method, params, credential? }
|
|
10803
10803
|
* Parent -> Worker: { type: 'tool-result', id, result?, error?, code? }
|
package/dist/test-utils/index.js
CHANGED
|
@@ -10203,10 +10203,10 @@ async function executeWorkflow(workflow, input, context) {
|
|
|
10203
10203
|
}
|
|
10204
10204
|
function buildWorkerExecutionContext(params) {
|
|
10205
10205
|
const { executionId } = params;
|
|
10206
|
-
const postLog = (level, message) => {
|
|
10206
|
+
const postLog = (level, message, logContext) => {
|
|
10207
10207
|
parentPort.postMessage({
|
|
10208
10208
|
type: "log",
|
|
10209
|
-
entry: { level, message, timestamp: (/* @__PURE__ */ new Date()).toISOString(), executionId }
|
|
10209
|
+
entry: { level, message, timestamp: (/* @__PURE__ */ new Date()).toISOString(), executionId, context: logContext }
|
|
10210
10210
|
});
|
|
10211
10211
|
};
|
|
10212
10212
|
return {
|
|
@@ -10221,21 +10221,21 @@ function buildWorkerExecutionContext(params) {
|
|
|
10221
10221
|
signal: params.signal,
|
|
10222
10222
|
store: /* @__PURE__ */ new Map(),
|
|
10223
10223
|
logger: {
|
|
10224
|
-
debug: (msg) => {
|
|
10224
|
+
debug: (msg, logContext) => {
|
|
10225
10225
|
console.log(`[debug] ${msg}`);
|
|
10226
|
-
postLog("info", msg);
|
|
10226
|
+
postLog("info", msg, logContext);
|
|
10227
10227
|
},
|
|
10228
|
-
info: (msg) => {
|
|
10228
|
+
info: (msg, logContext) => {
|
|
10229
10229
|
console.log(`[info] ${msg}`);
|
|
10230
|
-
postLog("info", msg);
|
|
10230
|
+
postLog("info", msg, logContext);
|
|
10231
10231
|
},
|
|
10232
|
-
warn: (msg) => {
|
|
10232
|
+
warn: (msg, logContext) => {
|
|
10233
10233
|
console.warn(`[warn] ${msg}`);
|
|
10234
|
-
postLog("warn", msg);
|
|
10234
|
+
postLog("warn", msg, logContext);
|
|
10235
10235
|
},
|
|
10236
|
-
error: (msg) => {
|
|
10236
|
+
error: (msg, logContext) => {
|
|
10237
10237
|
console.error(`[error] ${msg}`);
|
|
10238
|
-
postLog("error", msg);
|
|
10238
|
+
postLog("error", msg, logContext);
|
|
10239
10239
|
}
|
|
10240
10240
|
},
|
|
10241
10241
|
onMessageEvent: async (event) => {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*
|
|
17
17
|
* Parent -> Worker: { type: 'abort' } (graceful abort before terminate)
|
|
18
18
|
*
|
|
19
|
-
* Worker -> Parent: { type: 'log', entry: { level, message, timestamp, executionId } }
|
|
19
|
+
* Worker -> Parent: { type: 'log', entry: { level, message, timestamp, executionId, context? } }
|
|
20
20
|
*
|
|
21
21
|
* Worker -> Parent: { type: 'tool-call', id, tool, method, params, credential? }
|
|
22
22
|
* Parent -> Worker: { type: 'tool-result', id, result?, error?, code? }
|
package/dist/worker/index.js
CHANGED
|
@@ -6874,10 +6874,10 @@ async function executeWorkflow(workflow, input, context) {
|
|
|
6874
6874
|
}
|
|
6875
6875
|
function buildWorkerExecutionContext(params) {
|
|
6876
6876
|
const { executionId } = params;
|
|
6877
|
-
const postLog = (level, message) => {
|
|
6877
|
+
const postLog = (level, message, logContext) => {
|
|
6878
6878
|
parentPort.postMessage({
|
|
6879
6879
|
type: "log",
|
|
6880
|
-
entry: { level, message, timestamp: (/* @__PURE__ */ new Date()).toISOString(), executionId }
|
|
6880
|
+
entry: { level, message, timestamp: (/* @__PURE__ */ new Date()).toISOString(), executionId, context: logContext }
|
|
6881
6881
|
});
|
|
6882
6882
|
};
|
|
6883
6883
|
return {
|
|
@@ -6892,21 +6892,21 @@ function buildWorkerExecutionContext(params) {
|
|
|
6892
6892
|
signal: params.signal,
|
|
6893
6893
|
store: /* @__PURE__ */ new Map(),
|
|
6894
6894
|
logger: {
|
|
6895
|
-
debug: (msg) => {
|
|
6895
|
+
debug: (msg, logContext) => {
|
|
6896
6896
|
console.log(`[debug] ${msg}`);
|
|
6897
|
-
postLog("info", msg);
|
|
6897
|
+
postLog("info", msg, logContext);
|
|
6898
6898
|
},
|
|
6899
|
-
info: (msg) => {
|
|
6899
|
+
info: (msg, logContext) => {
|
|
6900
6900
|
console.log(`[info] ${msg}`);
|
|
6901
|
-
postLog("info", msg);
|
|
6901
|
+
postLog("info", msg, logContext);
|
|
6902
6902
|
},
|
|
6903
|
-
warn: (msg) => {
|
|
6903
|
+
warn: (msg, logContext) => {
|
|
6904
6904
|
console.warn(`[warn] ${msg}`);
|
|
6905
|
-
postLog("warn", msg);
|
|
6905
|
+
postLog("warn", msg, logContext);
|
|
6906
6906
|
},
|
|
6907
|
-
error: (msg) => {
|
|
6907
|
+
error: (msg, logContext) => {
|
|
6908
6908
|
console.error(`[error] ${msg}`);
|
|
6909
|
-
postLog("error", msg);
|
|
6909
|
+
postLog("error", msg, logContext);
|
|
6910
6910
|
}
|
|
6911
6911
|
},
|
|
6912
6912
|
onMessageEvent: async (event) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elevasis/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.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.
|
|
62
|
-
"@repo/
|
|
63
|
-
"@repo/
|
|
61
|
+
"@repo/core": "0.49.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",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"agent": "operator-facing deployed-agent introspection",
|
|
12
12
|
"session": "operator-facing session introspection",
|
|
13
13
|
"queue": "HITL approval queue — surfaced in the UI",
|
|
14
|
+
"grant": "operator-facing public agent access management",
|
|
14
15
|
"schedule": "operator-facing scheduler control",
|
|
15
16
|
"note": "CLI-only in tenant context; /notes is monorepo-internal, not propagated",
|
|
16
17
|
"ui": "infra-only dev toggle (ui:use-local / ui:use-published)",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Agent grants, execution visualizer, and Operations sidebar release train
|
|
2
|
+
|
|
3
|
+
This train publishes coordinated platform updates across `@elevasis/core`, `@elevasis/ui`,
|
|
4
|
+
and `@elevasis/sdk`, then syncs the external template baseline.
|
|
5
|
+
|
|
6
|
+
## What changes for tenant projects
|
|
7
|
+
|
|
8
|
+
1. `@elevasis/sdk` adds `grant:list`, `grant:create`, and `grant:disable` for
|
|
9
|
+
managing public/code-gated agent access grants through the platform API.
|
|
10
|
+
2. `@elevasis/ui` adds shared agent public/private controls and improves the
|
|
11
|
+
agent execution visualizer with per-iteration tool activity.
|
|
12
|
+
3. `@elevasis/core` adds the grant audit activity contract used by platform
|
|
13
|
+
activity feeds.
|
|
14
|
+
4. The template `.claude/registries/skill-coverage.json` now explicitly waives
|
|
15
|
+
the `grant` CLI domain as operator-facing access-management tooling.
|
|
16
|
+
|
|
17
|
+
## Operator action
|
|
18
|
+
|
|
19
|
+
- Run the prepared external sync manifest from the SDK ship artifact.
|
|
20
|
+
- Verify each derived project updates `.claude/registries/skill-coverage.json`.
|
|
21
|
+
- After package baselines are bumped, verify derived package manifests point at
|
|
22
|
+
the newly published `@elevasis/core`, `@elevasis/ui`, and `@elevasis/sdk`
|
|
23
|
+
versions selected by the release steps.
|
|
24
|
+
|
|
25
|
+
## Manual-review exclusions
|
|
26
|
+
|
|
27
|
+
Operations sidebar root-route parity for `external/nirvana-marketing` and
|
|
28
|
+
`external/ZentaraHQ` is intentionally excluded from this ship train. Their
|
|
29
|
+
root routes are project-specific merge-managed surfaces and should be reviewed
|
|
30
|
+
manually before adopting the template Operations manifest mount.
|