@wave-ai-os/wave-cli 0.1.67 → 0.1.68

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.cjs CHANGED
@@ -15030,6 +15030,649 @@ function registerAtlasAuthoringCommands(program) {
15030
15030
  // src/commands/discovery.ts
15031
15031
  var import_node_fs4 = require("fs");
15032
15032
  var import_node_path4 = require("path");
15033
+
15034
+ // src/operationManifest.ts
15035
+ var import_node_crypto3 = require("crypto");
15036
+
15037
+ // src/version.ts
15038
+ var CLI_VERSION = "0.1.68";
15039
+
15040
+ // src/operationMetadata.ts
15041
+ var DISCOVERY_OPERATION_IDS = [
15042
+ "accountability.examples",
15043
+ "accountability.schema",
15044
+ "agents.examples",
15045
+ "agents.schema",
15046
+ "api.examples",
15047
+ "api.ls",
15048
+ "api.schema",
15049
+ "auth.examples",
15050
+ "auth.schema",
15051
+ "automations.examples",
15052
+ "automations.schema",
15053
+ "broadcast.examples",
15054
+ "broadcast.schema",
15055
+ "capabilities.examples",
15056
+ "capabilities.list",
15057
+ "capabilities.schema",
15058
+ "capabilities.tools",
15059
+ "contacts.examples",
15060
+ "contacts.schema",
15061
+ "content.examples",
15062
+ "content.schema",
15063
+ "customers.examples",
15064
+ "customers.schema",
15065
+ "datasheets.examples",
15066
+ "datasheets.schema",
15067
+ "doctor",
15068
+ "doctor.examples",
15069
+ "doctor.schema",
15070
+ "feedbacks.examples",
15071
+ "feedbacks.schema",
15072
+ "foundation.examples",
15073
+ "foundation.schema",
15074
+ "issue-groups.examples",
15075
+ "issue-groups.schema",
15076
+ "issues.examples",
15077
+ "issues.schema",
15078
+ "knowledge.examples",
15079
+ "knowledge.schema",
15080
+ "kpis.examples",
15081
+ "kpis.schema",
15082
+ "list-items.examples",
15083
+ "list-items.schema",
15084
+ "lists.examples",
15085
+ "lists.schema",
15086
+ "mail.examples",
15087
+ "mail.schema",
15088
+ "markdown-tree.examples",
15089
+ "markdown-tree.schema",
15090
+ "meetings.examples",
15091
+ "meetings.schema",
15092
+ "members.examples",
15093
+ "members.schema",
15094
+ "milestones.examples",
15095
+ "milestones.schema",
15096
+ "news.examples",
15097
+ "news.schema",
15098
+ "organizations.examples",
15099
+ "organizations.schema",
15100
+ "osmd.examples",
15101
+ "osmd.schema",
15102
+ "planner.examples",
15103
+ "planner.schema",
15104
+ "project-content.examples",
15105
+ "project-content.schema",
15106
+ "projects.examples",
15107
+ "projects.schema",
15108
+ "pulse.examples",
15109
+ "pulse.schema",
15110
+ "questions.examples",
15111
+ "questions.schema",
15112
+ "recognition.examples",
15113
+ "recognition.schema",
15114
+ "rock-collections.examples",
15115
+ "rock-collections.schema",
15116
+ "rocks.examples",
15117
+ "rocks.schema",
15118
+ "scorecard-groups.examples",
15119
+ "scorecard-groups.schema",
15120
+ "scorecards.examples",
15121
+ "scorecards.schema",
15122
+ "skills.examples",
15123
+ "skills.schema",
15124
+ "stand-ups.examples",
15125
+ "stand-ups.schema",
15126
+ "subissues.examples",
15127
+ "subissues.schema",
15128
+ "subitems.examples",
15129
+ "subitems.schema",
15130
+ "subtasks.examples",
15131
+ "subtasks.schema",
15132
+ "subtodos.examples",
15133
+ "subtodos.schema",
15134
+ "support.examples",
15135
+ "support.schema",
15136
+ "surveys.examples",
15137
+ "surveys.schema",
15138
+ "talking-points.examples",
15139
+ "talking-points.schema",
15140
+ "tasks.examples",
15141
+ "tasks.schema",
15142
+ "teams.examples",
15143
+ "teams.schema",
15144
+ "time-tracking.examples",
15145
+ "time-tracking.schema",
15146
+ "todo-groups.examples",
15147
+ "todo-groups.schema",
15148
+ "todos.examples",
15149
+ "todos.schema",
15150
+ "whiteboards.examples",
15151
+ "whiteboards.schema"
15152
+ ];
15153
+ var READ_OPERATION_IDS = [
15154
+ "accountability.list",
15155
+ "accountability.search",
15156
+ "accountability.show",
15157
+ "agents.show",
15158
+ "auth.status",
15159
+ "automations.show",
15160
+ "broadcast.community",
15161
+ "broadcast.list",
15162
+ "broadcast.open",
15163
+ "broadcast.workspace",
15164
+ "cat",
15165
+ "contacts.list",
15166
+ "contacts.search",
15167
+ "contacts.show",
15168
+ "content.list",
15169
+ "content.show",
15170
+ "customers.list",
15171
+ "customers.search",
15172
+ "customers.show",
15173
+ "datasheets.list",
15174
+ "datasheets.open",
15175
+ "datasheets.show",
15176
+ "feedbacks.list",
15177
+ "feedbacks.search",
15178
+ "feedbacks.show",
15179
+ "find",
15180
+ "foundation.annual-objectives.list",
15181
+ "foundation.annual-objectives.search",
15182
+ "foundation.annual-objectives.show",
15183
+ "foundation.quarterly-objectives.list",
15184
+ "foundation.quarterly-objectives.search",
15185
+ "foundation.quarterly-objectives.show",
15186
+ "foundation.strategic-objectives.show",
15187
+ "foundation.strategic-plans.show",
15188
+ "issue-groups.list",
15189
+ "issue-groups.search",
15190
+ "issue-groups.show",
15191
+ "issues.list",
15192
+ "issues.search",
15193
+ "issues.show",
15194
+ "knowledge.list",
15195
+ "knowledge.search",
15196
+ "knowledge.show",
15197
+ "kpis.list",
15198
+ "kpis.search",
15199
+ "kpis.show",
15200
+ "list-items.list",
15201
+ "list-items.search",
15202
+ "list-items.show",
15203
+ "lists.list",
15204
+ "lists.search",
15205
+ "lists.show",
15206
+ "ls",
15207
+ "mail.accounts",
15208
+ "mail.conversation",
15209
+ "mail.conversations",
15210
+ "mail.labels",
15211
+ "mail.message",
15212
+ "mail.messages",
15213
+ "mail.open",
15214
+ "mail.settings",
15215
+ "mail.snippets",
15216
+ "mail.sync-status",
15217
+ "mail.unread-count",
15218
+ "mail.validate-provider",
15219
+ "mail.workspace",
15220
+ "markdown-tree.children",
15221
+ "markdown-tree.resolve",
15222
+ "markdown-tree.root",
15223
+ "markdown-tree.subtree",
15224
+ "meetings.list",
15225
+ "meetings.search",
15226
+ "meetings.show",
15227
+ "members.list",
15228
+ "members.meta-profile",
15229
+ "members.search",
15230
+ "members.show",
15231
+ "milestones.list",
15232
+ "milestones.search",
15233
+ "news.list",
15234
+ "news.search",
15235
+ "news.show",
15236
+ "open",
15237
+ "organizations.key-metric-meta-profile.show",
15238
+ "organizations.meta-profile.show",
15239
+ "organizations.show",
15240
+ "osmd.agent.children",
15241
+ "osmd.agent.read",
15242
+ "osmd.agent.status",
15243
+ "osmd.children",
15244
+ "osmd.lint",
15245
+ "osmd.memory-quality",
15246
+ "osmd.read",
15247
+ "osmd.search",
15248
+ "osmd.status",
15249
+ "osmd.tree",
15250
+ "osmd.wiki.read",
15251
+ "osmd.wiki.status",
15252
+ "phantom.apply-operation",
15253
+ "phantom.apply-operations",
15254
+ "phantom.candidate",
15255
+ "phantom.candidates",
15256
+ "phantom.evidence",
15257
+ "phantom.evidences",
15258
+ "phantom.inventory",
15259
+ "phantom.observation",
15260
+ "phantom.observations",
15261
+ "phantom.report",
15262
+ "phantom.validation",
15263
+ "phantom.validations",
15264
+ "planner.booking-links",
15265
+ "planner.events",
15266
+ "planner.open",
15267
+ "planner.preferences",
15268
+ "planner.public-booking-link",
15269
+ "planner.state",
15270
+ "projects.list",
15271
+ "projects.search",
15272
+ "projects.show",
15273
+ "pulse.list",
15274
+ "pulse.search",
15275
+ "pulse.show",
15276
+ "questions.list",
15277
+ "questions.search",
15278
+ "questions.show",
15279
+ "recognition.list",
15280
+ "recognition.open",
15281
+ "recognition.point-balance",
15282
+ "recognition.show",
15283
+ "recognition.top-value",
15284
+ "rock-collections.list",
15285
+ "rock-collections.search",
15286
+ "rock-collections.show",
15287
+ "rocks.list",
15288
+ "rocks.search",
15289
+ "rocks.show",
15290
+ "scorecard-groups.list",
15291
+ "scorecard-groups.search",
15292
+ "scorecard-groups.show",
15293
+ "scorecards.list",
15294
+ "scorecards.search",
15295
+ "scorecards.show",
15296
+ "skills.list",
15297
+ "skills.show",
15298
+ "stand-ups.list",
15299
+ "stand-ups.search",
15300
+ "stand-ups.show",
15301
+ "subissues.list",
15302
+ "subissues.search",
15303
+ "subitems.list",
15304
+ "subitems.search",
15305
+ "subtasks.list",
15306
+ "subtasks.search",
15307
+ "subtodos.list",
15308
+ "subtodos.search",
15309
+ "support.counts",
15310
+ "support.inbox",
15311
+ "support.knowledge-articles",
15312
+ "support.knowledge-collections",
15313
+ "support.labels",
15314
+ "support.open",
15315
+ "support.settings",
15316
+ "support.ticket-counts",
15317
+ "support.tickets",
15318
+ "surveys.list",
15319
+ "surveys.search",
15320
+ "surveys.show",
15321
+ "talking-points.list",
15322
+ "talking-points.search",
15323
+ "tasks.list",
15324
+ "tasks.search",
15325
+ "tasks.show",
15326
+ "teams.list",
15327
+ "teams.show",
15328
+ "time-tracking.entries",
15329
+ "time-tracking.open",
15330
+ "time-tracking.projects",
15331
+ "time-tracking.report",
15332
+ "time-tracking.show",
15333
+ "time-tracking.timer",
15334
+ "time-tracking.timesheet",
15335
+ "todo-groups.list",
15336
+ "todo-groups.search",
15337
+ "todo-groups.show",
15338
+ "todos.list",
15339
+ "todos.search",
15340
+ "todos.show",
15341
+ "tree",
15342
+ "whiteboards.list",
15343
+ "whiteboards.open",
15344
+ "whiteboards.show"
15345
+ ];
15346
+ var WRITE_OPERATION_IDS = [
15347
+ "accountability.create",
15348
+ "accountability.update",
15349
+ "agents.create",
15350
+ "automations.create",
15351
+ "contacts.create",
15352
+ "contacts.update",
15353
+ "content.create-contact",
15354
+ "content.create-customer",
15355
+ "content.create-manager",
15356
+ "content.create-member",
15357
+ "content.create-project",
15358
+ "content.create-team",
15359
+ "content.destroy",
15360
+ "content.update",
15361
+ "customers.create",
15362
+ "customers.update",
15363
+ "datasheets.archive",
15364
+ "datasheets.cell.upsert",
15365
+ "datasheets.column.archive",
15366
+ "datasheets.column.create",
15367
+ "datasheets.column.delete",
15368
+ "datasheets.column.reorder",
15369
+ "datasheets.column.update",
15370
+ "datasheets.create",
15371
+ "datasheets.export.create",
15372
+ "datasheets.favorite",
15373
+ "datasheets.form.archive",
15374
+ "datasheets.form.close",
15375
+ "datasheets.form.create",
15376
+ "datasheets.form.delete",
15377
+ "datasheets.form.publish",
15378
+ "datasheets.form.submit",
15379
+ "datasheets.form.update",
15380
+ "datasheets.import.commit",
15381
+ "datasheets.row.archive",
15382
+ "datasheets.row.create",
15383
+ "datasheets.row.delete",
15384
+ "datasheets.row.reorder",
15385
+ "datasheets.row.update",
15386
+ "datasheets.update",
15387
+ "datasheets.view.archive",
15388
+ "datasheets.view.create",
15389
+ "datasheets.view.delete",
15390
+ "datasheets.view.reorder",
15391
+ "datasheets.view.update",
15392
+ "feedbacks.create",
15393
+ "feedbacks.update",
15394
+ "foundation.annual-objectives.create",
15395
+ "foundation.annual-objectives.update",
15396
+ "foundation.quarterly-objectives.create",
15397
+ "foundation.quarterly-objectives.update",
15398
+ "foundation.strategic-objectives.update",
15399
+ "foundation.strategic-plans.update",
15400
+ "issue-groups.create",
15401
+ "issue-groups.update",
15402
+ "issues.create",
15403
+ "issues.update",
15404
+ "knowledge.create",
15405
+ "knowledge.update",
15406
+ "kpis.create",
15407
+ "kpis.update",
15408
+ "list-items.create",
15409
+ "list-items.update",
15410
+ "lists.create",
15411
+ "lists.update",
15412
+ "meetings.create",
15413
+ "meetings.notes",
15414
+ "meetings.update",
15415
+ "members.create",
15416
+ "members.update",
15417
+ "milestones.create",
15418
+ "milestones.destroy",
15419
+ "milestones.update",
15420
+ "news.create",
15421
+ "news.update",
15422
+ "organizations.key-metric-meta-profile.update",
15423
+ "organizations.meta-profile.update",
15424
+ "organizations.update",
15425
+ "osmd.agent.create",
15426
+ "osmd.agent.init",
15427
+ "osmd.agent.update",
15428
+ "osmd.ingest.file",
15429
+ "osmd.ingest.text",
15430
+ "osmd.ingest.transcript",
15431
+ "osmd.ingest.url",
15432
+ "osmd.phantom.run",
15433
+ "osmd.wiki.append-log",
15434
+ "osmd.wiki.create",
15435
+ "osmd.wiki.index-upsert",
15436
+ "osmd.wiki.update",
15437
+ "project-content.create",
15438
+ "project-content.destroy",
15439
+ "project-content.update",
15440
+ "projects.create",
15441
+ "projects.update",
15442
+ "pulse.create",
15443
+ "pulse.update",
15444
+ "questions.create",
15445
+ "questions.update",
15446
+ "rock-collections.create",
15447
+ "rock-collections.update",
15448
+ "rocks.create",
15449
+ "rocks.update",
15450
+ "rocks.update-status",
15451
+ "scorecard-groups.create",
15452
+ "scorecard-groups.update",
15453
+ "scorecards.create",
15454
+ "scorecards.update",
15455
+ "skills.create",
15456
+ "smart-kpi-views.create",
15457
+ "stand-ups.create",
15458
+ "stand-ups.update",
15459
+ "subissues.create",
15460
+ "subissues.destroy",
15461
+ "subissues.update",
15462
+ "subitems.create",
15463
+ "subitems.destroy",
15464
+ "subitems.update",
15465
+ "subtasks.create",
15466
+ "subtasks.destroy",
15467
+ "subtasks.update",
15468
+ "subtodos.create",
15469
+ "subtodos.destroy",
15470
+ "subtodos.update",
15471
+ "surveys.create",
15472
+ "surveys.update",
15473
+ "talking-points.create",
15474
+ "talking-points.destroy",
15475
+ "talking-points.update",
15476
+ "tasks.create",
15477
+ "tasks.destroy",
15478
+ "tasks.update",
15479
+ "teams.create",
15480
+ "teams.update",
15481
+ "todo-groups.create",
15482
+ "todo-groups.update",
15483
+ "todos.create",
15484
+ "todos.update"
15485
+ ];
15486
+ var AUTH_OPERATION_IDS = ["login", "logout"];
15487
+ var DESTRUCTIVE_OPERATION_IDS = /* @__PURE__ */ new Set([
15488
+ "content.destroy",
15489
+ "datasheets.archive",
15490
+ "datasheets.column.archive",
15491
+ "datasheets.column.delete",
15492
+ "datasheets.form.archive",
15493
+ "datasheets.form.close",
15494
+ "datasheets.form.delete",
15495
+ "datasheets.form.publish",
15496
+ "datasheets.form.submit",
15497
+ "datasheets.import.commit",
15498
+ "datasheets.row.archive",
15499
+ "datasheets.row.delete",
15500
+ "datasheets.view.archive",
15501
+ "datasheets.view.delete",
15502
+ "milestones.destroy",
15503
+ "project-content.destroy",
15504
+ "subissues.destroy",
15505
+ "subitems.destroy",
15506
+ "subtasks.destroy",
15507
+ "subtodos.destroy",
15508
+ "talking-points.destroy",
15509
+ "tasks.destroy"
15510
+ ]);
15511
+ var OPERATION_IDS_BY_CLASSIFICATION = {
15512
+ discovery: DISCOVERY_OPERATION_IDS,
15513
+ read: READ_OPERATION_IDS,
15514
+ write: WRITE_OPERATION_IDS,
15515
+ auth: AUTH_OPERATION_IDS
15516
+ };
15517
+ var metadataByOperationId = /* @__PURE__ */ new Map();
15518
+ for (const [classification, operationIds] of Object.entries(OPERATION_IDS_BY_CLASSIFICATION)) {
15519
+ for (const id of operationIds) {
15520
+ if (metadataByOperationId.has(id)) {
15521
+ throw new Error(`Duplicate Wave CLI operation metadata: ${id}`);
15522
+ }
15523
+ const atlasSafetyClass = classification === "discovery" ? "discovery" : classification === "read" ? "read_only" : classification === "auth" ? "auth" : DESTRUCTIVE_OPERATION_IDS.has(id) ? "destructive" : "mutation";
15524
+ if (DESTRUCTIVE_OPERATION_IDS.has(id) && classification !== "write") {
15525
+ throw new Error(`Destructive Wave CLI operation must be a write: ${id}`);
15526
+ }
15527
+ metadataByOperationId.set(id, {
15528
+ classification,
15529
+ requiresApproval: classification === "write",
15530
+ atlasSafetyClass,
15531
+ machine: {
15532
+ supportsValidate: true,
15533
+ supportsPreview: classification === "write",
15534
+ supportsExecute: true,
15535
+ executionMode: "sync"
15536
+ }
15537
+ });
15538
+ }
15539
+ }
15540
+ function registeredOperationMetadata(id) {
15541
+ return metadataByOperationId.get(id);
15542
+ }
15543
+
15544
+ // src/operationManifest.ts
15545
+ var MACHINE_PRESENTATION_OPTIONS = /* @__PURE__ */ new Set(["json", "readable"]);
15546
+ function hasAction(command) {
15547
+ return Boolean(command._actionHandler);
15548
+ }
15549
+ function commandPath(command) {
15550
+ const path = [];
15551
+ let current = command;
15552
+ while (current) {
15553
+ const name = current.name();
15554
+ if (name) path.unshift(name);
15555
+ current = current.parent ?? null;
15556
+ }
15557
+ return path;
15558
+ }
15559
+ function operationId(path) {
15560
+ return path.slice(1).join(".");
15561
+ }
15562
+ function inputKeyForArgument(argument) {
15563
+ return argument.name().replace(/<|>|\[|\]|\.\.\./g, "");
15564
+ }
15565
+ function inputSchemaFor(command) {
15566
+ const properties = {};
15567
+ const required = [];
15568
+ for (const argument of command.registeredArguments) {
15569
+ const key = inputKeyForArgument(argument);
15570
+ properties[key] = {
15571
+ type: argument.variadic ? "array" : "string",
15572
+ ...argument.description ? { description: argument.description } : {}
15573
+ };
15574
+ if (argument.required) required.push(key);
15575
+ }
15576
+ for (const option of command.options) {
15577
+ const key = option.attributeName();
15578
+ if (MACHINE_PRESENTATION_OPTIONS.has(key)) continue;
15579
+ properties[key] = {
15580
+ type: option.required ? "string" : option.optional ? ["boolean", "string"] : "boolean",
15581
+ ...option.description ? { description: option.description } : {}
15582
+ };
15583
+ if (option.mandatory) required.push(key);
15584
+ }
15585
+ return {
15586
+ type: "object",
15587
+ additionalProperties: false,
15588
+ properties,
15589
+ required: required.sort()
15590
+ };
15591
+ }
15592
+ function exampleFor(inputSchema) {
15593
+ const input = {};
15594
+ for (const key of inputSchema.required) {
15595
+ const propertyType = inputSchema.properties[key]?.type;
15596
+ const types = Array.isArray(propertyType) ? propertyType : [propertyType];
15597
+ input[key] = types.includes("array") ? ["example"] : types.includes("boolean") ? true : "example";
15598
+ }
15599
+ return [{ name: "minimal valid input", input }];
15600
+ }
15601
+ function outputSchema() {
15602
+ return {
15603
+ $schema: "https://json-schema.org/draft/2020-12/schema",
15604
+ type: "object",
15605
+ additionalProperties: false,
15606
+ properties: {
15607
+ ok: { type: "boolean" },
15608
+ command: { type: "string" },
15609
+ status: { type: "number" },
15610
+ data: { type: ["object", "array", "string", "number", "boolean", "null"] },
15611
+ error: { type: ["object", "null"] },
15612
+ meta: { type: "object" }
15613
+ },
15614
+ required: ["ok", "command", "status", "data", "error", "meta"]
15615
+ };
15616
+ }
15617
+ function listInvocableCommands(program) {
15618
+ const result = [];
15619
+ const visit = (command) => {
15620
+ if (command.name() !== "help" && hasAction(command)) result.push(command);
15621
+ for (const child of command.commands) visit(child);
15622
+ };
15623
+ for (const command of program.commands) visit(command);
15624
+ return result;
15625
+ }
15626
+ function entryFor(command, metadata) {
15627
+ const path = commandPath(command);
15628
+ const inputSchema = inputSchemaFor(command);
15629
+ const summary = command.description() || `Run ${path.join(" ")}.`;
15630
+ return {
15631
+ id: operationId(path),
15632
+ path,
15633
+ command: path.join(" "),
15634
+ summary,
15635
+ description: summary,
15636
+ classification: metadata.classification,
15637
+ requiresApproval: metadata.requiresApproval,
15638
+ atlasSafetyClass: metadata.atlasSafetyClass,
15639
+ inputSchema,
15640
+ outputSchema: outputSchema(),
15641
+ examples: exampleFor(inputSchema),
15642
+ machine: metadata.machine
15643
+ };
15644
+ }
15645
+ function digestFor(operations) {
15646
+ const canonical = JSON.stringify(operations);
15647
+ return `sha256:${(0, import_node_crypto3.createHash)("sha256").update(canonical).digest("hex")}`;
15648
+ }
15649
+ function buildOperationManifest(program) {
15650
+ const operations = listInvocableCommands(program).map((command) => {
15651
+ const path = commandPath(command);
15652
+ const id = operationId(path);
15653
+ const metadata = registeredOperationMetadata(id);
15654
+ if (!metadata) {
15655
+ throw new Error(`Missing explicit Wave CLI operation metadata: ${id}`);
15656
+ }
15657
+ return entryFor(command, metadata);
15658
+ }).sort((left, right) => left.id.localeCompare(right.id));
15659
+ const seen = /* @__PURE__ */ new Set();
15660
+ for (const operation of operations) {
15661
+ if (seen.has(operation.id)) {
15662
+ throw new Error(`Duplicate Wave CLI operation id: ${operation.id}`);
15663
+ }
15664
+ seen.add(operation.id);
15665
+ }
15666
+ return {
15667
+ manifestVersion: "1",
15668
+ cli: { package: "@wave-ai-os/wave-cli", version: CLI_VERSION },
15669
+ registryDigest: digestFor(operations),
15670
+ operationCount: operations.length,
15671
+ operations
15672
+ };
15673
+ }
15674
+
15675
+ // src/commands/discovery.ts
15033
15676
  var PRIMARY_NAMESPACES = [
15034
15677
  "osmd",
15035
15678
  "broadcast",
@@ -15638,13 +16281,6 @@ function readableToolSupport(key) {
15638
16281
  ].join("\n");
15639
16282
  }).join("\n\n");
15640
16283
  }
15641
- function commandPaths(command, prefix = command.name()) {
15642
- const children = command.commands.filter((child) => !child.name().startsWith("help"));
15643
- if (children.length === 0) {
15644
- return [prefix];
15645
- }
15646
- return children.flatMap((child) => commandPaths(child, `${prefix} ${child.name()}`));
15647
- }
15648
16284
  function commandSummary(command) {
15649
16285
  return {
15650
16286
  name: command.name(),
@@ -15889,12 +16525,16 @@ function registerDiscoveryCommands(program) {
15889
16525
  });
15890
16526
  const api = program.command("api").description("Discover Wave API-backed CLI operations");
15891
16527
  api.command("ls").description("List scriptable command paths").option("--readable", "Print command paths as plain lines").option("--json", "Emit the stable JSON envelope").action((opts) => {
15892
- const paths = commandPaths(program).filter((path) => path !== "wave");
16528
+ const manifest = buildOperationManifest(program);
16529
+ const paths = manifest.operations.map((operation) => operation.command);
15893
16530
  if (opts.readable && !opts.json) {
15894
16531
  return printTextAndExit({ text: paths.join("\n") });
15895
16532
  }
15896
16533
  return printEnvelopeAndExit({
15897
16534
  envelope: buildEnvelope2("api.ls", {
16535
+ ...manifest,
16536
+ // Retained as a derived compatibility projection for existing CLI
16537
+ // callers. The manifest above is the sole inventory source.
15898
16538
  commands: paths,
15899
16539
  examples: ["wave api ls --json"]
15900
16540
  })
@@ -15991,9 +16631,6 @@ function attachDiscoveryHelp(program) {
15991
16631
  }
15992
16632
  }
15993
16633
 
15994
- // src/version.ts
15995
- var CLI_VERSION = "0.1.67";
15996
-
15997
16634
  // src/cli.ts
15998
16635
  function buildCli(options) {
15999
16636
  const program = new import_commander.Command();
@@ -16075,6 +16712,371 @@ function buildCli(options) {
16075
16712
  return program;
16076
16713
  }
16077
16714
 
16715
+ // src/machine.ts
16716
+ var import_node_crypto4 = require("crypto");
16717
+ var MACHINE_FLAGS = /* @__PURE__ */ new Set([
16718
+ "--machine",
16719
+ "--operation",
16720
+ "--phase",
16721
+ "--input-json"
16722
+ ]);
16723
+ function machineEnvelope(params) {
16724
+ return {
16725
+ ok: params.ok,
16726
+ command: params.command,
16727
+ status: params.status,
16728
+ data: params.data ?? null,
16729
+ error: params.error ?? null,
16730
+ meta: { requestId: "machine" }
16731
+ };
16732
+ }
16733
+ function isPlainObject(value) {
16734
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
16735
+ }
16736
+ function hasAction2(command) {
16737
+ return Boolean(command._actionHandler);
16738
+ }
16739
+ function commandId(command) {
16740
+ const path = [];
16741
+ let current = command;
16742
+ while (current) {
16743
+ if (current.name()) path.unshift(current.name());
16744
+ current = current.parent;
16745
+ }
16746
+ return path.slice(1).join(".");
16747
+ }
16748
+ function parseMachineArgs(argv) {
16749
+ const values = {};
16750
+ for (let index = 0; index < argv.length; index += 1) {
16751
+ const flag = argv[index];
16752
+ if (!MACHINE_FLAGS.has(flag)) {
16753
+ return { error: `Unsupported machine flag: ${flag}` };
16754
+ }
16755
+ const value = argv[index + 1];
16756
+ if (!value || value.startsWith("--")) {
16757
+ return { error: `Missing value for ${flag}` };
16758
+ }
16759
+ if (flag in values) return { error: `Machine flag may be supplied only once: ${flag}` };
16760
+ values[flag] = value;
16761
+ index += 1;
16762
+ }
16763
+ if (values["--machine"] !== "execute") {
16764
+ return { error: '--machine must be "execute".' };
16765
+ }
16766
+ return {
16767
+ operation: values["--operation"],
16768
+ phase: values["--phase"],
16769
+ inputJson: values["--input-json"]
16770
+ };
16771
+ }
16772
+ async function readMachineInput(location) {
16773
+ if (location !== "-") {
16774
+ throw new Error('Machine input must be supplied with "--input-json -".');
16775
+ }
16776
+ let raw = "";
16777
+ process.stdin.setEncoding("utf8");
16778
+ for await (const chunk of process.stdin) raw += chunk;
16779
+ if (!raw.trim()) throw new Error("Machine input JSON is required.");
16780
+ const parsed = JSON.parse(raw);
16781
+ if (!isPlainObject(parsed)) throw new Error("Machine input must be a JSON object.");
16782
+ return parsed;
16783
+ }
16784
+ function inputDigest(input) {
16785
+ return `sha256:${(0, import_node_crypto4.createHash)("sha256").update(canonicalJson(input)).digest("hex")}`;
16786
+ }
16787
+ function canonicalJson(value) {
16788
+ if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
16789
+ if (isPlainObject(value)) {
16790
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
16791
+ }
16792
+ return JSON.stringify(value);
16793
+ }
16794
+ function normalizeInput(input) {
16795
+ return Object.fromEntries(
16796
+ Object.keys(input).sort().map((key) => [key, input[key]])
16797
+ );
16798
+ }
16799
+ function parseTrustedJson(name, predicate) {
16800
+ const raw = process.env[name];
16801
+ if (!raw) return null;
16802
+ try {
16803
+ const parsed = JSON.parse(raw);
16804
+ return predicate(parsed) ? parsed : null;
16805
+ } catch {
16806
+ return null;
16807
+ }
16808
+ }
16809
+ function isTrustedAuth(value) {
16810
+ return isPlainObject(value) && typeof value.token === "string" && value.token.trim() !== "" && typeof value.baseUrl === "string" && value.baseUrl.trim() !== "" && typeof value.organizationId === "string" && value.organizationId.trim() !== "" && typeof value.actorId === "string" && value.actorId.trim() !== "";
16811
+ }
16812
+ function isTrustedApproval(value) {
16813
+ return isPlainObject(value) && typeof value.operation === "string" && typeof value.inputDigest === "string" && typeof value.cliVersion === "string" && typeof value.registryDigest === "string" && typeof value.organizationId === "string" && value.organizationId.trim() !== "" && typeof value.actorId === "string" && value.actorId.trim() !== "";
16814
+ }
16815
+ function operationCommand(program, id) {
16816
+ return listInvocableCommands(program).find((command) => commandId(command) === id);
16817
+ }
16818
+ function typeMatches(value, type) {
16819
+ if (type === "array") return Array.isArray(value);
16820
+ if (type === "null") return value === null;
16821
+ if (type === "object") return isPlainObject(value);
16822
+ return typeof value === type;
16823
+ }
16824
+ function validateInput(operation, input) {
16825
+ const allowed = new Set(Object.keys(operation.inputSchema.properties));
16826
+ const unknown = Object.keys(input).filter((key) => !allowed.has(key));
16827
+ const missing = operation.inputSchema.required.filter(
16828
+ (key) => input[key] === void 0 || input[key] === null || input[key] === ""
16829
+ );
16830
+ const typeErrors = Object.entries(input).flatMap(([key, value]) => {
16831
+ const property = operation.inputSchema.properties[key];
16832
+ if (!property) return [];
16833
+ const types = Array.isArray(property.type) ? property.type : [property.type];
16834
+ return types.some((type) => typeMatches(value, type)) ? [] : [`Invalid input type for ${key}: expected ${types.join(" or ")}.`];
16835
+ });
16836
+ return [
16837
+ ...unknown.map((key) => `Unknown input property: ${key}`),
16838
+ ...missing.map((key) => `Missing required input property: ${key}`),
16839
+ ...typeErrors
16840
+ ];
16841
+ }
16842
+ function optionValue(value) {
16843
+ return typeof value === "string" ? value : JSON.stringify(value);
16844
+ }
16845
+ function commandArgs(command, input) {
16846
+ const path = [];
16847
+ let current = command;
16848
+ while (current) {
16849
+ if (current.name()) path.unshift(current.name());
16850
+ current = current.parent;
16851
+ }
16852
+ const args = path.slice(1);
16853
+ for (const argument of command.registeredArguments) {
16854
+ const key = argument.name().replace(/<|>|\[|\]|\.\.\./g, "");
16855
+ const value = input[key];
16856
+ if (value === void 0) continue;
16857
+ if (Array.isArray(value)) args.push(...value.map(optionValue));
16858
+ else args.push(optionValue(value));
16859
+ }
16860
+ for (const option of command.options) {
16861
+ const key = option.attributeName();
16862
+ const value = input[key];
16863
+ if (value === void 0 || value === false) continue;
16864
+ const long = option.long;
16865
+ if (!long) continue;
16866
+ if (value === true) args.push(long);
16867
+ else args.push(long, optionValue(value));
16868
+ }
16869
+ return args;
16870
+ }
16871
+ function withTrustedMachineAuth(auth, callback) {
16872
+ const previousWaveEnvironment = Object.fromEntries(
16873
+ Object.entries(process.env).filter(([key]) => key.startsWith("WAVE_"))
16874
+ );
16875
+ for (const key of Object.keys(process.env)) {
16876
+ if (key.startsWith("WAVE_")) delete process.env[key];
16877
+ }
16878
+ if (auth) {
16879
+ process.env.WAVE_API_TOKEN = auth.token;
16880
+ process.env.WAVE_API_BASE_URL = auth.baseUrl;
16881
+ }
16882
+ process.env.WAVE_CLI_AUTH_STORAGE = "disabled";
16883
+ process.env.WAVE_CLI_HOME = "/dev/null";
16884
+ return callback().finally(() => {
16885
+ for (const key of Object.keys(process.env)) {
16886
+ if (key.startsWith("WAVE_")) delete process.env[key];
16887
+ }
16888
+ Object.assign(process.env, previousWaveEnvironment);
16889
+ });
16890
+ }
16891
+ function needsTrustedAuth(operation) {
16892
+ return operation.classification === "read" || operation.classification === "write" || operation.classification === "auth";
16893
+ }
16894
+ function resolveMachineOperation(program, id) {
16895
+ const manifest = buildOperationManifest(program);
16896
+ const operation = manifest.operations.find((candidate) => candidate.id === id);
16897
+ const command = operation ? operationCommand(program, id) : void 0;
16898
+ return operation && command && hasAction2(command) ? { operation, command } : null;
16899
+ }
16900
+ async function maybeRunMachineExecute(argv, program) {
16901
+ if (argv[0] !== "--machine") return false;
16902
+ const parsed = parseMachineArgs(argv);
16903
+ if (parsed.error || !parsed.operation || !parsed.phase) {
16904
+ return printEnvelopeAndExit({
16905
+ envelope: machineEnvelope({
16906
+ ok: false,
16907
+ status: 400,
16908
+ command: "machine.execute",
16909
+ error: { code: "invalid_args", message: parsed.error ?? "operation and phase are required." }
16910
+ }),
16911
+ exitCode: EXIT_CODES.invalidArgs
16912
+ });
16913
+ }
16914
+ if (!["validate", "preview", "execute"].includes(parsed.phase)) {
16915
+ return printEnvelopeAndExit({
16916
+ envelope: machineEnvelope({
16917
+ ok: false,
16918
+ status: 400,
16919
+ command: "machine.execute",
16920
+ error: { code: "invalid_phase", message: `Unsupported machine phase: ${parsed.phase}` }
16921
+ }),
16922
+ exitCode: EXIT_CODES.invalidArgs
16923
+ });
16924
+ }
16925
+ let input;
16926
+ try {
16927
+ input = await readMachineInput(parsed.inputJson);
16928
+ } catch (error) {
16929
+ return printEnvelopeAndExit({
16930
+ envelope: machineEnvelope({
16931
+ ok: false,
16932
+ status: 400,
16933
+ command: "machine.execute",
16934
+ error: { code: "invalid_input", message: error instanceof Error ? error.message : "Invalid machine input." }
16935
+ }),
16936
+ exitCode: EXIT_CODES.invalidArgs
16937
+ });
16938
+ }
16939
+ const resolved = resolveMachineOperation(program, parsed.operation);
16940
+ if (!resolved) {
16941
+ return printEnvelopeAndExit({
16942
+ envelope: machineEnvelope({
16943
+ ok: false,
16944
+ status: 404,
16945
+ command: "machine.execute",
16946
+ error: { code: "unknown_operation", message: `Unknown operation: ${parsed.operation}` }
16947
+ }),
16948
+ exitCode: EXIT_CODES.notFound
16949
+ });
16950
+ }
16951
+ const normalizedInput = normalizeInput(input);
16952
+ const errors = validateInput(resolved.operation, normalizedInput);
16953
+ const digest = inputDigest(normalizedInput);
16954
+ if (errors.length > 0) {
16955
+ return printEnvelopeAndExit({
16956
+ envelope: machineEnvelope({
16957
+ ok: false,
16958
+ status: 400,
16959
+ command: "machine.execute",
16960
+ error: { code: "invalid_input", message: "Machine input did not match the operation schema.", details: { errors } },
16961
+ data: {
16962
+ operation: resolved.operation.id,
16963
+ normalizedInput,
16964
+ inputDigest: digest
16965
+ }
16966
+ }),
16967
+ exitCode: EXIT_CODES.invalidArgs
16968
+ });
16969
+ }
16970
+ const manifest = buildOperationManifest(program);
16971
+ if (parsed.phase === "validate") {
16972
+ return printEnvelopeAndExit({
16973
+ envelope: machineEnvelope({
16974
+ ok: true,
16975
+ status: 200,
16976
+ command: "machine.execute",
16977
+ data: {
16978
+ status: "validated",
16979
+ operation: resolved.operation.id,
16980
+ normalizedInput,
16981
+ inputDigest: digest,
16982
+ cliVersion: manifest.cli.version,
16983
+ registryDigest: manifest.registryDigest
16984
+ }
16985
+ })
16986
+ });
16987
+ }
16988
+ if (parsed.phase === "preview") {
16989
+ if (resolved.operation.classification !== "write") {
16990
+ return printEnvelopeAndExit({
16991
+ envelope: machineEnvelope({
16992
+ ok: false,
16993
+ status: 400,
16994
+ command: "machine.execute",
16995
+ error: { code: "preview_not_supported", message: `${resolved.operation.id} is not a write operation.` }
16996
+ }),
16997
+ exitCode: EXIT_CODES.invalidArgs
16998
+ });
16999
+ }
17000
+ return printEnvelopeAndExit({
17001
+ envelope: machineEnvelope({
17002
+ ok: true,
17003
+ status: 200,
17004
+ command: "machine.execute",
17005
+ data: {
17006
+ status: "preview",
17007
+ operation: resolved.operation.id,
17008
+ normalizedInput,
17009
+ preview: {
17010
+ title: resolved.operation.summary,
17011
+ command: resolved.operation.command,
17012
+ requestedInput: normalizedInput,
17013
+ summary: `Execute ${resolved.operation.command} with the validated input.`
17014
+ },
17015
+ inputDigest: digest,
17016
+ cliVersion: manifest.cli.version,
17017
+ registryDigest: manifest.registryDigest
17018
+ }
17019
+ })
17020
+ });
17021
+ }
17022
+ if (resolved.operation.classification === "auth") {
17023
+ return printEnvelopeAndExit({
17024
+ envelope: machineEnvelope({
17025
+ ok: true,
17026
+ status: 202,
17027
+ command: "machine.execute",
17028
+ data: {
17029
+ status: "continuation_required",
17030
+ operation: resolved.operation.id,
17031
+ message: "Interactive authentication is not run in machine mode. Continue through the MCP OAuth flow."
17032
+ }
17033
+ })
17034
+ });
17035
+ }
17036
+ const auth = parseTrustedJson("WAVE_MACHINE_AUTH_JSON", isTrustedAuth);
17037
+ if (needsTrustedAuth(resolved.operation) && !auth) {
17038
+ return printEnvelopeAndExit({
17039
+ envelope: machineEnvelope({
17040
+ ok: false,
17041
+ status: 401,
17042
+ command: "machine.execute",
17043
+ error: {
17044
+ code: "missing_machine_auth",
17045
+ message: "Machine execution requires trusted OAuth-bound auth context."
17046
+ }
17047
+ }),
17048
+ exitCode: EXIT_CODES.missingOrInvalidAuth
17049
+ });
17050
+ }
17051
+ if (resolved.operation.classification === "write") {
17052
+ const approval = parseTrustedJson("WAVE_MACHINE_APPROVAL_JSON", isTrustedApproval);
17053
+ if (!approval || approval.operation !== resolved.operation.id || approval.inputDigest !== digest || approval.cliVersion !== manifest.cli.version || approval.registryDigest !== manifest.registryDigest || approval.organizationId !== auth?.organizationId || approval.actorId !== auth?.actorId) {
17054
+ return printEnvelopeAndExit({
17055
+ envelope: machineEnvelope({
17056
+ ok: false,
17057
+ status: 403,
17058
+ command: "machine.execute",
17059
+ error: {
17060
+ code: "approval_required",
17061
+ message: "A matching server-managed approval is required before write execution.",
17062
+ details: { operation: resolved.operation.id, inputDigest: digest }
17063
+ }
17064
+ }),
17065
+ exitCode: EXIT_CODES.forbidden
17066
+ });
17067
+ }
17068
+ }
17069
+ try {
17070
+ await withTrustedMachineAuth(auth, async () => {
17071
+ await program.parseAsync([process.execPath, "wave", ...commandArgs(resolved.command, normalizedInput)]);
17072
+ });
17073
+ } catch (error) {
17074
+ if (isEnvelopeEmittedSignal(error)) return true;
17075
+ throw error;
17076
+ }
17077
+ return true;
17078
+ }
17079
+
16078
17080
  // src/index.ts
16079
17081
  function printCliFailure(params) {
16080
17082
  printEnvelope({
@@ -16096,6 +17098,7 @@ function printCliFailure(params) {
16096
17098
  }
16097
17099
  async function main() {
16098
17100
  const program = buildCli();
17101
+ if (await maybeRunMachineExecute(process.argv.slice(2), program)) return;
16099
17102
  await program.parseAsync(process.argv);
16100
17103
  }
16101
17104
  main().catch((error) => {