@wave-ai-os/wave-cli 0.1.63 → 0.1.66
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/README.md +2 -6
- package/dist/index.cjs +20 -159
- package/dist/index.js +20 -159
- package/package.json +1 -1
- package/scripts/benchmark-cli.mjs +2 -1
- package/scripts/cli-token-scope.mjs +10 -0
- package/scripts/verify-dev-api.mjs +9 -3
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Secure stdin auth/context examples:
|
|
|
39
39
|
```bash
|
|
40
40
|
printf '%s' "token-value" | wave --token-stdin --base-url https://api.example.com --organization-id 42 tasks list --page 1 --per 10
|
|
41
41
|
|
|
42
|
-
printf '%s' '{"token":"token-value","baseUrl":"https://api.example.com","
|
|
42
|
+
printf '%s' '{"token":"token-value","baseUrl":"https://api.example.com","agentName":"atlas"}' \
|
|
43
43
|
| wave --auth-json-stdin tasks list --page 1 --per 10
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -72,10 +72,7 @@ Required (from flags, stdin, env, config, or stored credentials):
|
|
|
72
72
|
- `WAVE_API_BASE_URL`
|
|
73
73
|
|
|
74
74
|
Organization-scoped data commands use the organization certified by the
|
|
75
|
-
authenticated CLI token. `--organization-id` is the only local override.
|
|
76
|
-
CLI intentionally ignores `WAVE_ORGANIZATION_ID`, `WAVE_ORG_ID`, stdin, and
|
|
77
|
-
stored config organization values as automatic scopes so a stale local value
|
|
78
|
-
cannot select a different organization.
|
|
75
|
+
authenticated CLI token. `--organization-id` is the only local override.
|
|
79
76
|
|
|
80
77
|
Optional env:
|
|
81
78
|
|
|
@@ -103,7 +100,6 @@ Config files are JSON objects using the same keys accepted by `--auth-json-stdin
|
|
|
103
100
|
{
|
|
104
101
|
"token": "token-value",
|
|
105
102
|
"baseUrl": "https://api.example.com",
|
|
106
|
-
"organizationId": "42",
|
|
107
103
|
"agentName": "atlas"
|
|
108
104
|
}
|
|
109
105
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -128,9 +128,7 @@ function getConfig(options) {
|
|
|
128
128
|
const parsed = configSchema.safeParse({
|
|
129
129
|
baseUrl,
|
|
130
130
|
token,
|
|
131
|
-
organizationId: toOptionalNonEmpty(
|
|
132
|
-
options.organizationId ?? process.env.WAVE_ORGANIZATION_ID ?? process.env.WAVE_ORG_ID
|
|
133
|
-
),
|
|
131
|
+
organizationId: toOptionalNonEmpty(options.organizationId),
|
|
134
132
|
timeoutMs: parseTimeoutMs(options.timeoutMs ?? process.env.WAVE_TIMEOUT_MS),
|
|
135
133
|
debug: options.debug ?? parseDebug(process.env.WAVE_DEBUG),
|
|
136
134
|
agentName: toOptionalNonEmpty(options.agentName ?? process.env.WAVE_AGENT_NAME),
|
|
@@ -2187,7 +2185,6 @@ function parseAuthJson(raw) {
|
|
|
2187
2185
|
return {
|
|
2188
2186
|
token: normalize3(obj.token),
|
|
2189
2187
|
baseUrl: normalize3(obj.baseUrl ?? obj.base_url),
|
|
2190
|
-
organizationId: normalize3(obj.organizationId ?? obj.organization_id),
|
|
2191
2188
|
timeoutMs: typeof obj.timeoutMs === "number" || typeof obj.timeoutMs === "string" ? obj.timeoutMs : typeof obj.timeout_ms === "number" || typeof obj.timeout_ms === "string" ? obj.timeout_ms : void 0,
|
|
2192
2189
|
debug: parseBool(obj.debug),
|
|
2193
2190
|
agentName: normalize3(obj.agentName ?? obj.agent_name),
|
|
@@ -2270,7 +2267,6 @@ function resolveAuthToken(options, stdin, config, env) {
|
|
|
2270
2267
|
{ token: normalize3(options.token), source: "flag" },
|
|
2271
2268
|
{ token: normalize3(stdin.token), source: "stdin" },
|
|
2272
2269
|
{ token: normalize3(env.WAVE_API_TOKEN), source: "env" },
|
|
2273
|
-
{ token: normalize3(config.token), source: "config" },
|
|
2274
2270
|
{ token: normalize3(config.token), source: "config" }
|
|
2275
2271
|
];
|
|
2276
2272
|
return candidates.find((candidate) => candidate.token) ?? { source: "none" };
|
|
@@ -2283,18 +2279,8 @@ function resolveFromSources(options, stdin, config, env) {
|
|
|
2283
2279
|
normalize3(env.WAVE_API_URL),
|
|
2284
2280
|
normalize3(config.baseUrl)
|
|
2285
2281
|
);
|
|
2286
|
-
const
|
|
2287
|
-
|
|
2288
|
-
{ organizationId: normalize3(stdin.organizationId), source: "stdin" },
|
|
2289
|
-
{ organizationId: normalize3(env.WAVE_ORGANIZATION_ID), source: "env" },
|
|
2290
|
-
{ organizationId: normalize3(env.WAVE_ORG_ID), source: "env" },
|
|
2291
|
-
{ organizationId: normalize3(config.organizationId), source: "config" }
|
|
2292
|
-
];
|
|
2293
|
-
const resolvedOrganization = organizationCandidates.find((candidate) => candidate.organizationId) ?? {
|
|
2294
|
-
organizationId: void 0,
|
|
2295
|
-
source: "none"
|
|
2296
|
-
};
|
|
2297
|
-
const organizationId = resolvedOrganization.organizationId;
|
|
2282
|
+
const organizationId = normalize3(options.organizationId);
|
|
2283
|
+
const organizationIdSource = organizationId ? "flag" : "none";
|
|
2298
2284
|
const timeoutMs = firstDefined(options.timeoutMs, stdin.timeoutMs, env.WAVE_TIMEOUT_MS, config.timeoutMs);
|
|
2299
2285
|
const debug = firstDefined(
|
|
2300
2286
|
options.debug,
|
|
@@ -2383,7 +2369,7 @@ function resolveFromSources(options, stdin, config, env) {
|
|
|
2383
2369
|
const resolvedAuth = resolveAuthToken(options, stdin, config, env);
|
|
2384
2370
|
return {
|
|
2385
2371
|
organizationId,
|
|
2386
|
-
organizationIdSource
|
|
2372
|
+
organizationIdSource,
|
|
2387
2373
|
runtimeOptions: {
|
|
2388
2374
|
token: resolvedAuth.token,
|
|
2389
2375
|
tokenSource: resolvedAuth.token ? resolvedAuth.source : "none",
|
|
@@ -2523,7 +2509,9 @@ async function resolveCommandContext(options) {
|
|
|
2523
2509
|
function organizationIdFromCliAuthStatus(data) {
|
|
2524
2510
|
const status = data.cliAuthStatus;
|
|
2525
2511
|
if (!status || typeof status !== "object" || Array.isArray(status)) return void 0;
|
|
2526
|
-
const
|
|
2512
|
+
const cliAuthStatus = status;
|
|
2513
|
+
if (cliAuthStatus.authenticated !== true) return void 0;
|
|
2514
|
+
const organization = cliAuthStatus.organization;
|
|
2527
2515
|
if (!organization || typeof organization !== "object" || Array.isArray(organization)) return void 0;
|
|
2528
2516
|
return normalize3(organization.id);
|
|
2529
2517
|
}
|
|
@@ -14460,7 +14448,7 @@ async function runDatasheetsQuery(cmd, config) {
|
|
|
14460
14448
|
});
|
|
14461
14449
|
}
|
|
14462
14450
|
async function runDatasheetsMutation(cmd, opts, config) {
|
|
14463
|
-
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
14451
|
+
const context = config.organizationContext === "optional" ? await resolveUnscopedCommandContext(cmd.optsWithGlobals()) : await resolveCommandContext(cmd.optsWithGlobals());
|
|
14464
14452
|
const variables = config.organizationContext === "optional" ? context.organizationId ? { organization_id: context.organizationId } : {} : { organization_id: resolveOrganizationId(context.organizationId) };
|
|
14465
14453
|
for (const id of config.requiredIds ?? []) {
|
|
14466
14454
|
variables[id.variable] = requireNonEmpty(opts[id.option], id.label, config.command);
|
|
@@ -14497,7 +14485,7 @@ async function runDatasheetsMutation(cmd, opts, config) {
|
|
|
14497
14485
|
runtimeOptions: context.runtimeOptions,
|
|
14498
14486
|
field: config.field,
|
|
14499
14487
|
variables: normalizeGraphqlVariables2(variables),
|
|
14500
|
-
variableTypes: { organization_id: "ID!" },
|
|
14488
|
+
variableTypes: config.organizationContext === "optional" && !context.organizationId ? {} : { organization_id: "ID!" },
|
|
14501
14489
|
selectionSet: DATASHEET_MUTATION_SELECTION
|
|
14502
14490
|
});
|
|
14503
14491
|
}
|
|
@@ -14789,115 +14777,6 @@ function registerDatasheetsCommands(program) {
|
|
|
14789
14777
|
});
|
|
14790
14778
|
}
|
|
14791
14779
|
|
|
14792
|
-
// src/commands/aiNotes.ts
|
|
14793
|
-
var AI_NOTE_SAFE_FIELDS = [
|
|
14794
|
-
"id",
|
|
14795
|
-
"slug",
|
|
14796
|
-
"title",
|
|
14797
|
-
"status",
|
|
14798
|
-
"visibility",
|
|
14799
|
-
"sourceType",
|
|
14800
|
-
"sourceReference",
|
|
14801
|
-
"ownerMemberId",
|
|
14802
|
-
"scheduledStartAt",
|
|
14803
|
-
"scheduledEndAt",
|
|
14804
|
-
"createdAt",
|
|
14805
|
-
"updatedAt"
|
|
14806
|
-
];
|
|
14807
|
-
var AI_NOTE_SELECTION = `{ ${AI_NOTE_SAFE_FIELDS.join(" ")} }`;
|
|
14808
|
-
var AI_NOTES_SELECTION = AI_NOTE_SELECTION;
|
|
14809
|
-
function pickSafeAiNoteFields(value) {
|
|
14810
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
14811
|
-
return null;
|
|
14812
|
-
}
|
|
14813
|
-
const record = value;
|
|
14814
|
-
const safe = {};
|
|
14815
|
-
for (const field of AI_NOTE_SAFE_FIELDS) {
|
|
14816
|
-
if (Object.prototype.hasOwnProperty.call(record, field)) {
|
|
14817
|
-
safe[field] = record[field];
|
|
14818
|
-
}
|
|
14819
|
-
}
|
|
14820
|
-
return safe;
|
|
14821
|
-
}
|
|
14822
|
-
function projectAiNotesPayload(payload) {
|
|
14823
|
-
if (Array.isArray(payload)) {
|
|
14824
|
-
return payload.map((item) => pickSafeAiNoteFields(item)).filter(Boolean);
|
|
14825
|
-
}
|
|
14826
|
-
if (!payload || typeof payload !== "object") {
|
|
14827
|
-
return payload;
|
|
14828
|
-
}
|
|
14829
|
-
return pickSafeAiNoteFields(payload);
|
|
14830
|
-
}
|
|
14831
|
-
function showVariables(opts) {
|
|
14832
|
-
const id = typeof opts.id === "string" && opts.id.trim() !== "" ? opts.id.trim() : void 0;
|
|
14833
|
-
const slug = typeof opts.slug === "string" && opts.slug.trim() !== "" ? opts.slug.trim() : void 0;
|
|
14834
|
-
if (!id && !slug || id && slug) {
|
|
14835
|
-
throw new CliError({
|
|
14836
|
-
message: "Provide exactly one AI Note identifier: --id or --slug.",
|
|
14837
|
-
kind: "invalid_args",
|
|
14838
|
-
status: 400,
|
|
14839
|
-
exitCode: EXIT_CODES.invalidArgs,
|
|
14840
|
-
details: { requiredOneOf: ["--id", "--slug"] }
|
|
14841
|
-
});
|
|
14842
|
-
}
|
|
14843
|
-
return id ? { id } : { slug };
|
|
14844
|
-
}
|
|
14845
|
-
async function runAiNotesQuery(cmd, config) {
|
|
14846
|
-
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
14847
|
-
await runGraphqlQueryCommand({
|
|
14848
|
-
command: config.command,
|
|
14849
|
-
operationName: config.operationName,
|
|
14850
|
-
runtimeOptions: context.runtimeOptions,
|
|
14851
|
-
field: config.field,
|
|
14852
|
-
variables: normalizeGraphqlVariables2({
|
|
14853
|
-
organization_id: resolveOrganizationId(context.organizationId),
|
|
14854
|
-
...config.variables
|
|
14855
|
-
}),
|
|
14856
|
-
variableTypes: config.variableTypes,
|
|
14857
|
-
selectionSet: config.selectionSet,
|
|
14858
|
-
isList: config.isList,
|
|
14859
|
-
isShow: config.isShow,
|
|
14860
|
-
transformData: projectAiNotesPayload
|
|
14861
|
-
});
|
|
14862
|
-
}
|
|
14863
|
-
function registerAiNotesCommands(program) {
|
|
14864
|
-
const aiNotes = program.command("ai-notes").description("AI Notes read-only list and detail metadata");
|
|
14865
|
-
aiNotes.command("list").description("Read safe AI Note metadata without transcripts or provider payloads").option("--page <page>").option("--per <per>").action(async (opts, cmd) => {
|
|
14866
|
-
await runAiNotesQuery(cmd, {
|
|
14867
|
-
command: "ai-notes.list",
|
|
14868
|
-
operationName: "AiNotes",
|
|
14869
|
-
field: "ai_notes",
|
|
14870
|
-
variables: {
|
|
14871
|
-
page: opts.page,
|
|
14872
|
-
per: opts.per
|
|
14873
|
-
},
|
|
14874
|
-
variableTypes: {
|
|
14875
|
-
organization_id: "ID!",
|
|
14876
|
-
page: "Int",
|
|
14877
|
-
per: "Int"
|
|
14878
|
-
},
|
|
14879
|
-
selectionSet: AI_NOTES_SELECTION,
|
|
14880
|
-
isList: true
|
|
14881
|
-
});
|
|
14882
|
-
});
|
|
14883
|
-
aiNotes.command("show").description("Read safe AI Note detail metadata by id or slug").option("--id <id>").option("--slug <slug>").action(async (opts, cmd) => {
|
|
14884
|
-
const variables = showVariables(opts);
|
|
14885
|
-
await runAiNotesQuery(cmd, {
|
|
14886
|
-
command: "ai-notes.show",
|
|
14887
|
-
operationName: "AiNote",
|
|
14888
|
-
field: "ai_note",
|
|
14889
|
-
variables,
|
|
14890
|
-
variableTypes: {
|
|
14891
|
-
organization_id: "ID!",
|
|
14892
|
-
...variables.id ? { id: "ID!" } : {},
|
|
14893
|
-
...variables.slug ? { slug: "String!" } : {}
|
|
14894
|
-
},
|
|
14895
|
-
selectionSet: AI_NOTE_SELECTION,
|
|
14896
|
-
isShow: true
|
|
14897
|
-
});
|
|
14898
|
-
});
|
|
14899
|
-
}
|
|
14900
|
-
|
|
14901
14780
|
// src/commands/atlasAuthoring.ts
|
|
14902
14781
|
var import_zod19 = require("zod");
|
|
14903
14782
|
var idSchema14 = import_zod19.z.string().trim().min(1);
|
|
@@ -15072,7 +14951,7 @@ function registerAtlasAuthoringCommands(program) {
|
|
|
15072
14951
|
});
|
|
15073
14952
|
});
|
|
15074
14953
|
const automations = program.command("automations").description("Bounded Automation authoring operations");
|
|
15075
|
-
automations.command("create").description("Create an Automation through the API-owned createAutomation contract").requiredOption("--summary <summary>").requiredOption("--ai-task-config <json>", "Valid JSON for the API-owned ai_task_config field").requiredOption("--idempotency-key <key>", "Required create idempotency key").option("--description <description>").option("--notes <notes>").option("--member-id <memberId>").option("--status <status>").option("--priority <priority>").option("--due-date <date>", "ISO-8601 date (YYYY-MM-DD)").action(async (opts, cmd) => {
|
|
14954
|
+
automations.command("create").description("Create an Automation through the API-owned createAutomation contract").requiredOption("--summary <summary>").requiredOption("--ai-task-config <json>", "Valid JSON for the API-owned ai_task_config field").requiredOption("--idempotency-key <key>", "Required create idempotency key").option("--description <description>").option("--notes <notes>").option("--member-id <memberId>").option("--agent-id <agentId>", "Optional executor Agent id for a repeat Automation").option("--status <status>").option("--priority <priority>").option("--due-date <date>", "ISO-8601 date (YYYY-MM-DD)").action(async (opts, cmd) => {
|
|
15076
14955
|
const idempotencyKey = idempotencyKeySchema.parse(opts.idempotencyKey);
|
|
15077
14956
|
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
15078
14957
|
const organizationId = resolveOrganizationId(context.organizationId);
|
|
@@ -15094,6 +14973,7 @@ function registerAtlasAuthoringCommands(program) {
|
|
|
15094
14973
|
...opts.description !== void 0 ? { description: String(opts.description) } : {},
|
|
15095
14974
|
...opts.notes !== void 0 ? { notes: String(opts.notes) } : {},
|
|
15096
14975
|
...opts.memberId !== void 0 ? { member_id: idSchema14.parse(opts.memberId) } : {},
|
|
14976
|
+
...opts.agentId !== void 0 ? { agentId: idSchema14.parse(opts.agentId) } : {},
|
|
15097
14977
|
...opts.status !== void 0 ? { status: String(opts.status) } : {},
|
|
15098
14978
|
...opts.priority !== void 0 ? { priority: String(opts.priority) } : {},
|
|
15099
14979
|
...opts.dueDate !== void 0 ? { due_date: isoDateSchema.parse(opts.dueDate) } : {}
|
|
@@ -15164,7 +15044,6 @@ var PRIMARY_NAMESPACES = [
|
|
|
15164
15044
|
"planner",
|
|
15165
15045
|
"mail",
|
|
15166
15046
|
"datasheets",
|
|
15167
|
-
"ai-notes",
|
|
15168
15047
|
"phantom",
|
|
15169
15048
|
"tasks",
|
|
15170
15049
|
"projects",
|
|
@@ -15329,7 +15208,7 @@ var NAMESPACE_DOCS = {
|
|
|
15329
15208
|
tier: "primary",
|
|
15330
15209
|
description: "Bounded Automation create and persisted readback operations.",
|
|
15331
15210
|
examples: [
|
|
15332
|
-
`wave automations create --summary "Weekly review" --ai-task-config '{"
|
|
15211
|
+
`wave automations create --summary "Weekly review" --agent-id 123 --ai-task-config '{"cycle":"repeat","repeatSchedule":{"interval":1,"frequency":"week","weekdays":[1,3],"at":"2:30 PM","starting":"2026-07-20T00:00:00.000Z","ending":"never","endingRuns":1,"endingDate":null,"timezone":"America/Phoenix"}}' --idempotency-key automation-create-001`,
|
|
15333
15212
|
"wave automations show --id 123"
|
|
15334
15213
|
],
|
|
15335
15214
|
schema: {
|
|
@@ -15338,6 +15217,7 @@ var NAMESPACE_DOCS = {
|
|
|
15338
15217
|
safety: [
|
|
15339
15218
|
"Create calls only createAutomation with an explicit idempotency key.",
|
|
15340
15219
|
"Only the API-defined ai_task_config field accepts validated JSON.",
|
|
15220
|
+
"Optional executor Agent linkage is sent only through the API-defined top-level agentId input.",
|
|
15341
15221
|
"Does not create a project Task, run an Automation, or invoke AI OS actions.",
|
|
15342
15222
|
"Show uses the API-owned automation query by id; no slug fallback is implemented."
|
|
15343
15223
|
],
|
|
@@ -15599,26 +15479,6 @@ var NAMESPACE_DOCS = {
|
|
|
15599
15479
|
]
|
|
15600
15480
|
}
|
|
15601
15481
|
},
|
|
15602
|
-
"ai-notes": {
|
|
15603
|
-
name: "ai-notes",
|
|
15604
|
-
tier: "primary",
|
|
15605
|
-
description: "AI Notes read-only list and detail metadata for CLI-backed Atlas and harness inspection.",
|
|
15606
|
-
examples: [
|
|
15607
|
-
"wave ai-notes list --page 1 --per 20",
|
|
15608
|
-
"wave ai-notes show --id note_123",
|
|
15609
|
-
"wave ai-notes show --slug weekly-summary"
|
|
15610
|
-
],
|
|
15611
|
-
schema: {
|
|
15612
|
-
output: "json-envelope-default",
|
|
15613
|
-
readOnly: true,
|
|
15614
|
-
safety: [
|
|
15615
|
-
"Uses API-owned GraphQL read fields aiNotes and aiNote.",
|
|
15616
|
-
"List/show output is limited to safe AI Note identifiers, title, status, visibility, source reference, owner member id, schedule timestamps, and record timestamps.",
|
|
15617
|
-
"Does not expose transcript upload, transcription finalize, consent grant, create, update, delete, transcript text, segment text, client secrets, unsafe metadata, raw provider payloads, credentials, tokens, or secrets by default."
|
|
15618
|
-
],
|
|
15619
|
-
commands: ["list", "show"]
|
|
15620
|
-
}
|
|
15621
|
-
},
|
|
15622
15482
|
"markdown-tree": {
|
|
15623
15483
|
name: "markdown-tree",
|
|
15624
15484
|
tier: "advanced",
|
|
@@ -15840,7 +15700,9 @@ async function resolveDoctorAuthOrganization(params) {
|
|
|
15840
15700
|
if (!status || typeof status !== "object" || Array.isArray(status)) {
|
|
15841
15701
|
return null;
|
|
15842
15702
|
}
|
|
15843
|
-
const
|
|
15703
|
+
const cliAuthStatus = status;
|
|
15704
|
+
if (cliAuthStatus.authenticated !== true) return null;
|
|
15705
|
+
const organization = cliAuthStatus.organization;
|
|
15844
15706
|
if (!organization || typeof organization !== "object" || Array.isArray(organization)) {
|
|
15845
15707
|
return null;
|
|
15846
15708
|
}
|
|
@@ -15881,7 +15743,7 @@ async function runDoctor(cmd, opts) {
|
|
|
15881
15743
|
name: "organization_id",
|
|
15882
15744
|
ok: Boolean(organizationId || authOrganization?.id || authOrganization?.slug),
|
|
15883
15745
|
status: organizationId || authOrganization?.id || authOrganization?.slug ? "resolved" : "missing",
|
|
15884
|
-
source: organizationId ? "
|
|
15746
|
+
source: organizationId ? "explicit_flag" : authOrganization ? "auth_token" : "unresolved",
|
|
15885
15747
|
...authOrganization?.id ? { id: authOrganization.id } : {},
|
|
15886
15748
|
...authOrganization?.slug ? { slug: authOrganization.slug } : {}
|
|
15887
15749
|
},
|
|
@@ -16134,20 +15996,20 @@ function attachDiscoveryHelp(program) {
|
|
|
16134
15996
|
}
|
|
16135
15997
|
|
|
16136
15998
|
// src/version.ts
|
|
16137
|
-
var CLI_VERSION = "0.1.
|
|
15999
|
+
var CLI_VERSION = "0.1.66";
|
|
16138
16000
|
|
|
16139
16001
|
// src/cli.ts
|
|
16140
16002
|
function buildCli(options) {
|
|
16141
16003
|
const program = new import_commander.Command();
|
|
16142
16004
|
program.name("wave").description("Wave agent CLI").version(CLI_VERSION, "-V, --version", "output the version number").showHelpAfterError(false).allowExcessArguments(false).option("--token <token>", "API token (prefer WAVE_API_TOKEN env var)").option("--token-stdin", "Read API token from stdin").option(
|
|
16143
16005
|
"--auth-json-stdin",
|
|
16144
|
-
"Read auth/runtime context JSON from stdin (token, baseUrl,
|
|
16006
|
+
"Read auth/runtime context JSON from stdin (token, baseUrl, tracing fields, ...)"
|
|
16145
16007
|
).option(
|
|
16146
16008
|
"--base-url <baseUrl>",
|
|
16147
16009
|
"API base URL (prefer WAVE_API_BASE_URL env var)"
|
|
16148
16010
|
).option(
|
|
16149
16011
|
"--organization-id <organizationId>",
|
|
16150
|
-
"
|
|
16012
|
+
"Explicit organization ID override"
|
|
16151
16013
|
).option(
|
|
16152
16014
|
"--config <configPath>",
|
|
16153
16015
|
"Optional JSON config file (default: WAVE_CONFIG_PATH or ~/.wave/config.json when present)"
|
|
@@ -16210,7 +16072,6 @@ function buildCli(options) {
|
|
|
16210
16072
|
registerMailCommands(program);
|
|
16211
16073
|
registerPhantomCommands(program);
|
|
16212
16074
|
registerDatasheetsCommands(program);
|
|
16213
|
-
registerAiNotesCommands(program);
|
|
16214
16075
|
registerAuthCommands(program);
|
|
16215
16076
|
registerDiscoveryCommands(program);
|
|
16216
16077
|
attachNamespaceDiscovery(program);
|
package/dist/index.js
CHANGED
|
@@ -127,9 +127,7 @@ function getConfig(options) {
|
|
|
127
127
|
const parsed = configSchema.safeParse({
|
|
128
128
|
baseUrl,
|
|
129
129
|
token,
|
|
130
|
-
organizationId: toOptionalNonEmpty(
|
|
131
|
-
options.organizationId ?? process.env.WAVE_ORGANIZATION_ID ?? process.env.WAVE_ORG_ID
|
|
132
|
-
),
|
|
130
|
+
organizationId: toOptionalNonEmpty(options.organizationId),
|
|
133
131
|
timeoutMs: parseTimeoutMs(options.timeoutMs ?? process.env.WAVE_TIMEOUT_MS),
|
|
134
132
|
debug: options.debug ?? parseDebug(process.env.WAVE_DEBUG),
|
|
135
133
|
agentName: toOptionalNonEmpty(options.agentName ?? process.env.WAVE_AGENT_NAME),
|
|
@@ -2186,7 +2184,6 @@ function parseAuthJson(raw) {
|
|
|
2186
2184
|
return {
|
|
2187
2185
|
token: normalize3(obj.token),
|
|
2188
2186
|
baseUrl: normalize3(obj.baseUrl ?? obj.base_url),
|
|
2189
|
-
organizationId: normalize3(obj.organizationId ?? obj.organization_id),
|
|
2190
2187
|
timeoutMs: typeof obj.timeoutMs === "number" || typeof obj.timeoutMs === "string" ? obj.timeoutMs : typeof obj.timeout_ms === "number" || typeof obj.timeout_ms === "string" ? obj.timeout_ms : void 0,
|
|
2191
2188
|
debug: parseBool(obj.debug),
|
|
2192
2189
|
agentName: normalize3(obj.agentName ?? obj.agent_name),
|
|
@@ -2269,7 +2266,6 @@ function resolveAuthToken(options, stdin, config, env) {
|
|
|
2269
2266
|
{ token: normalize3(options.token), source: "flag" },
|
|
2270
2267
|
{ token: normalize3(stdin.token), source: "stdin" },
|
|
2271
2268
|
{ token: normalize3(env.WAVE_API_TOKEN), source: "env" },
|
|
2272
|
-
{ token: normalize3(config.token), source: "config" },
|
|
2273
2269
|
{ token: normalize3(config.token), source: "config" }
|
|
2274
2270
|
];
|
|
2275
2271
|
return candidates.find((candidate) => candidate.token) ?? { source: "none" };
|
|
@@ -2282,18 +2278,8 @@ function resolveFromSources(options, stdin, config, env) {
|
|
|
2282
2278
|
normalize3(env.WAVE_API_URL),
|
|
2283
2279
|
normalize3(config.baseUrl)
|
|
2284
2280
|
);
|
|
2285
|
-
const
|
|
2286
|
-
|
|
2287
|
-
{ organizationId: normalize3(stdin.organizationId), source: "stdin" },
|
|
2288
|
-
{ organizationId: normalize3(env.WAVE_ORGANIZATION_ID), source: "env" },
|
|
2289
|
-
{ organizationId: normalize3(env.WAVE_ORG_ID), source: "env" },
|
|
2290
|
-
{ organizationId: normalize3(config.organizationId), source: "config" }
|
|
2291
|
-
];
|
|
2292
|
-
const resolvedOrganization = organizationCandidates.find((candidate) => candidate.organizationId) ?? {
|
|
2293
|
-
organizationId: void 0,
|
|
2294
|
-
source: "none"
|
|
2295
|
-
};
|
|
2296
|
-
const organizationId = resolvedOrganization.organizationId;
|
|
2281
|
+
const organizationId = normalize3(options.organizationId);
|
|
2282
|
+
const organizationIdSource = organizationId ? "flag" : "none";
|
|
2297
2283
|
const timeoutMs = firstDefined(options.timeoutMs, stdin.timeoutMs, env.WAVE_TIMEOUT_MS, config.timeoutMs);
|
|
2298
2284
|
const debug = firstDefined(
|
|
2299
2285
|
options.debug,
|
|
@@ -2382,7 +2368,7 @@ function resolveFromSources(options, stdin, config, env) {
|
|
|
2382
2368
|
const resolvedAuth = resolveAuthToken(options, stdin, config, env);
|
|
2383
2369
|
return {
|
|
2384
2370
|
organizationId,
|
|
2385
|
-
organizationIdSource
|
|
2371
|
+
organizationIdSource,
|
|
2386
2372
|
runtimeOptions: {
|
|
2387
2373
|
token: resolvedAuth.token,
|
|
2388
2374
|
tokenSource: resolvedAuth.token ? resolvedAuth.source : "none",
|
|
@@ -2522,7 +2508,9 @@ async function resolveCommandContext(options) {
|
|
|
2522
2508
|
function organizationIdFromCliAuthStatus(data) {
|
|
2523
2509
|
const status = data.cliAuthStatus;
|
|
2524
2510
|
if (!status || typeof status !== "object" || Array.isArray(status)) return void 0;
|
|
2525
|
-
const
|
|
2511
|
+
const cliAuthStatus = status;
|
|
2512
|
+
if (cliAuthStatus.authenticated !== true) return void 0;
|
|
2513
|
+
const organization = cliAuthStatus.organization;
|
|
2526
2514
|
if (!organization || typeof organization !== "object" || Array.isArray(organization)) return void 0;
|
|
2527
2515
|
return normalize3(organization.id);
|
|
2528
2516
|
}
|
|
@@ -14459,7 +14447,7 @@ async function runDatasheetsQuery(cmd, config) {
|
|
|
14459
14447
|
});
|
|
14460
14448
|
}
|
|
14461
14449
|
async function runDatasheetsMutation(cmd, opts, config) {
|
|
14462
|
-
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
14450
|
+
const context = config.organizationContext === "optional" ? await resolveUnscopedCommandContext(cmd.optsWithGlobals()) : await resolveCommandContext(cmd.optsWithGlobals());
|
|
14463
14451
|
const variables = config.organizationContext === "optional" ? context.organizationId ? { organization_id: context.organizationId } : {} : { organization_id: resolveOrganizationId(context.organizationId) };
|
|
14464
14452
|
for (const id of config.requiredIds ?? []) {
|
|
14465
14453
|
variables[id.variable] = requireNonEmpty(opts[id.option], id.label, config.command);
|
|
@@ -14496,7 +14484,7 @@ async function runDatasheetsMutation(cmd, opts, config) {
|
|
|
14496
14484
|
runtimeOptions: context.runtimeOptions,
|
|
14497
14485
|
field: config.field,
|
|
14498
14486
|
variables: normalizeGraphqlVariables2(variables),
|
|
14499
|
-
variableTypes: { organization_id: "ID!" },
|
|
14487
|
+
variableTypes: config.organizationContext === "optional" && !context.organizationId ? {} : { organization_id: "ID!" },
|
|
14500
14488
|
selectionSet: DATASHEET_MUTATION_SELECTION
|
|
14501
14489
|
});
|
|
14502
14490
|
}
|
|
@@ -14788,115 +14776,6 @@ function registerDatasheetsCommands(program) {
|
|
|
14788
14776
|
});
|
|
14789
14777
|
}
|
|
14790
14778
|
|
|
14791
|
-
// src/commands/aiNotes.ts
|
|
14792
|
-
var AI_NOTE_SAFE_FIELDS = [
|
|
14793
|
-
"id",
|
|
14794
|
-
"slug",
|
|
14795
|
-
"title",
|
|
14796
|
-
"status",
|
|
14797
|
-
"visibility",
|
|
14798
|
-
"sourceType",
|
|
14799
|
-
"sourceReference",
|
|
14800
|
-
"ownerMemberId",
|
|
14801
|
-
"scheduledStartAt",
|
|
14802
|
-
"scheduledEndAt",
|
|
14803
|
-
"createdAt",
|
|
14804
|
-
"updatedAt"
|
|
14805
|
-
];
|
|
14806
|
-
var AI_NOTE_SELECTION = `{ ${AI_NOTE_SAFE_FIELDS.join(" ")} }`;
|
|
14807
|
-
var AI_NOTES_SELECTION = AI_NOTE_SELECTION;
|
|
14808
|
-
function pickSafeAiNoteFields(value) {
|
|
14809
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
14810
|
-
return null;
|
|
14811
|
-
}
|
|
14812
|
-
const record = value;
|
|
14813
|
-
const safe = {};
|
|
14814
|
-
for (const field of AI_NOTE_SAFE_FIELDS) {
|
|
14815
|
-
if (Object.prototype.hasOwnProperty.call(record, field)) {
|
|
14816
|
-
safe[field] = record[field];
|
|
14817
|
-
}
|
|
14818
|
-
}
|
|
14819
|
-
return safe;
|
|
14820
|
-
}
|
|
14821
|
-
function projectAiNotesPayload(payload) {
|
|
14822
|
-
if (Array.isArray(payload)) {
|
|
14823
|
-
return payload.map((item) => pickSafeAiNoteFields(item)).filter(Boolean);
|
|
14824
|
-
}
|
|
14825
|
-
if (!payload || typeof payload !== "object") {
|
|
14826
|
-
return payload;
|
|
14827
|
-
}
|
|
14828
|
-
return pickSafeAiNoteFields(payload);
|
|
14829
|
-
}
|
|
14830
|
-
function showVariables(opts) {
|
|
14831
|
-
const id = typeof opts.id === "string" && opts.id.trim() !== "" ? opts.id.trim() : void 0;
|
|
14832
|
-
const slug = typeof opts.slug === "string" && opts.slug.trim() !== "" ? opts.slug.trim() : void 0;
|
|
14833
|
-
if (!id && !slug || id && slug) {
|
|
14834
|
-
throw new CliError({
|
|
14835
|
-
message: "Provide exactly one AI Note identifier: --id or --slug.",
|
|
14836
|
-
kind: "invalid_args",
|
|
14837
|
-
status: 400,
|
|
14838
|
-
exitCode: EXIT_CODES.invalidArgs,
|
|
14839
|
-
details: { requiredOneOf: ["--id", "--slug"] }
|
|
14840
|
-
});
|
|
14841
|
-
}
|
|
14842
|
-
return id ? { id } : { slug };
|
|
14843
|
-
}
|
|
14844
|
-
async function runAiNotesQuery(cmd, config) {
|
|
14845
|
-
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
14846
|
-
await runGraphqlQueryCommand({
|
|
14847
|
-
command: config.command,
|
|
14848
|
-
operationName: config.operationName,
|
|
14849
|
-
runtimeOptions: context.runtimeOptions,
|
|
14850
|
-
field: config.field,
|
|
14851
|
-
variables: normalizeGraphqlVariables2({
|
|
14852
|
-
organization_id: resolveOrganizationId(context.organizationId),
|
|
14853
|
-
...config.variables
|
|
14854
|
-
}),
|
|
14855
|
-
variableTypes: config.variableTypes,
|
|
14856
|
-
selectionSet: config.selectionSet,
|
|
14857
|
-
isList: config.isList,
|
|
14858
|
-
isShow: config.isShow,
|
|
14859
|
-
transformData: projectAiNotesPayload
|
|
14860
|
-
});
|
|
14861
|
-
}
|
|
14862
|
-
function registerAiNotesCommands(program) {
|
|
14863
|
-
const aiNotes = program.command("ai-notes").description("AI Notes read-only list and detail metadata");
|
|
14864
|
-
aiNotes.command("list").description("Read safe AI Note metadata without transcripts or provider payloads").option("--page <page>").option("--per <per>").action(async (opts, cmd) => {
|
|
14865
|
-
await runAiNotesQuery(cmd, {
|
|
14866
|
-
command: "ai-notes.list",
|
|
14867
|
-
operationName: "AiNotes",
|
|
14868
|
-
field: "ai_notes",
|
|
14869
|
-
variables: {
|
|
14870
|
-
page: opts.page,
|
|
14871
|
-
per: opts.per
|
|
14872
|
-
},
|
|
14873
|
-
variableTypes: {
|
|
14874
|
-
organization_id: "ID!",
|
|
14875
|
-
page: "Int",
|
|
14876
|
-
per: "Int"
|
|
14877
|
-
},
|
|
14878
|
-
selectionSet: AI_NOTES_SELECTION,
|
|
14879
|
-
isList: true
|
|
14880
|
-
});
|
|
14881
|
-
});
|
|
14882
|
-
aiNotes.command("show").description("Read safe AI Note detail metadata by id or slug").option("--id <id>").option("--slug <slug>").action(async (opts, cmd) => {
|
|
14883
|
-
const variables = showVariables(opts);
|
|
14884
|
-
await runAiNotesQuery(cmd, {
|
|
14885
|
-
command: "ai-notes.show",
|
|
14886
|
-
operationName: "AiNote",
|
|
14887
|
-
field: "ai_note",
|
|
14888
|
-
variables,
|
|
14889
|
-
variableTypes: {
|
|
14890
|
-
organization_id: "ID!",
|
|
14891
|
-
...variables.id ? { id: "ID!" } : {},
|
|
14892
|
-
...variables.slug ? { slug: "String!" } : {}
|
|
14893
|
-
},
|
|
14894
|
-
selectionSet: AI_NOTE_SELECTION,
|
|
14895
|
-
isShow: true
|
|
14896
|
-
});
|
|
14897
|
-
});
|
|
14898
|
-
}
|
|
14899
|
-
|
|
14900
14779
|
// src/commands/atlasAuthoring.ts
|
|
14901
14780
|
import { z as z19 } from "zod";
|
|
14902
14781
|
var idSchema14 = z19.string().trim().min(1);
|
|
@@ -15071,7 +14950,7 @@ function registerAtlasAuthoringCommands(program) {
|
|
|
15071
14950
|
});
|
|
15072
14951
|
});
|
|
15073
14952
|
const automations = program.command("automations").description("Bounded Automation authoring operations");
|
|
15074
|
-
automations.command("create").description("Create an Automation through the API-owned createAutomation contract").requiredOption("--summary <summary>").requiredOption("--ai-task-config <json>", "Valid JSON for the API-owned ai_task_config field").requiredOption("--idempotency-key <key>", "Required create idempotency key").option("--description <description>").option("--notes <notes>").option("--member-id <memberId>").option("--status <status>").option("--priority <priority>").option("--due-date <date>", "ISO-8601 date (YYYY-MM-DD)").action(async (opts, cmd) => {
|
|
14953
|
+
automations.command("create").description("Create an Automation through the API-owned createAutomation contract").requiredOption("--summary <summary>").requiredOption("--ai-task-config <json>", "Valid JSON for the API-owned ai_task_config field").requiredOption("--idempotency-key <key>", "Required create idempotency key").option("--description <description>").option("--notes <notes>").option("--member-id <memberId>").option("--agent-id <agentId>", "Optional executor Agent id for a repeat Automation").option("--status <status>").option("--priority <priority>").option("--due-date <date>", "ISO-8601 date (YYYY-MM-DD)").action(async (opts, cmd) => {
|
|
15075
14954
|
const idempotencyKey = idempotencyKeySchema.parse(opts.idempotencyKey);
|
|
15076
14955
|
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
15077
14956
|
const organizationId = resolveOrganizationId(context.organizationId);
|
|
@@ -15093,6 +14972,7 @@ function registerAtlasAuthoringCommands(program) {
|
|
|
15093
14972
|
...opts.description !== void 0 ? { description: String(opts.description) } : {},
|
|
15094
14973
|
...opts.notes !== void 0 ? { notes: String(opts.notes) } : {},
|
|
15095
14974
|
...opts.memberId !== void 0 ? { member_id: idSchema14.parse(opts.memberId) } : {},
|
|
14975
|
+
...opts.agentId !== void 0 ? { agentId: idSchema14.parse(opts.agentId) } : {},
|
|
15096
14976
|
...opts.status !== void 0 ? { status: String(opts.status) } : {},
|
|
15097
14977
|
...opts.priority !== void 0 ? { priority: String(opts.priority) } : {},
|
|
15098
14978
|
...opts.dueDate !== void 0 ? { due_date: isoDateSchema.parse(opts.dueDate) } : {}
|
|
@@ -15163,7 +15043,6 @@ var PRIMARY_NAMESPACES = [
|
|
|
15163
15043
|
"planner",
|
|
15164
15044
|
"mail",
|
|
15165
15045
|
"datasheets",
|
|
15166
|
-
"ai-notes",
|
|
15167
15046
|
"phantom",
|
|
15168
15047
|
"tasks",
|
|
15169
15048
|
"projects",
|
|
@@ -15328,7 +15207,7 @@ var NAMESPACE_DOCS = {
|
|
|
15328
15207
|
tier: "primary",
|
|
15329
15208
|
description: "Bounded Automation create and persisted readback operations.",
|
|
15330
15209
|
examples: [
|
|
15331
|
-
`wave automations create --summary "Weekly review" --ai-task-config '{"
|
|
15210
|
+
`wave automations create --summary "Weekly review" --agent-id 123 --ai-task-config '{"cycle":"repeat","repeatSchedule":{"interval":1,"frequency":"week","weekdays":[1,3],"at":"2:30 PM","starting":"2026-07-20T00:00:00.000Z","ending":"never","endingRuns":1,"endingDate":null,"timezone":"America/Phoenix"}}' --idempotency-key automation-create-001`,
|
|
15332
15211
|
"wave automations show --id 123"
|
|
15333
15212
|
],
|
|
15334
15213
|
schema: {
|
|
@@ -15337,6 +15216,7 @@ var NAMESPACE_DOCS = {
|
|
|
15337
15216
|
safety: [
|
|
15338
15217
|
"Create calls only createAutomation with an explicit idempotency key.",
|
|
15339
15218
|
"Only the API-defined ai_task_config field accepts validated JSON.",
|
|
15219
|
+
"Optional executor Agent linkage is sent only through the API-defined top-level agentId input.",
|
|
15340
15220
|
"Does not create a project Task, run an Automation, or invoke AI OS actions.",
|
|
15341
15221
|
"Show uses the API-owned automation query by id; no slug fallback is implemented."
|
|
15342
15222
|
],
|
|
@@ -15598,26 +15478,6 @@ var NAMESPACE_DOCS = {
|
|
|
15598
15478
|
]
|
|
15599
15479
|
}
|
|
15600
15480
|
},
|
|
15601
|
-
"ai-notes": {
|
|
15602
|
-
name: "ai-notes",
|
|
15603
|
-
tier: "primary",
|
|
15604
|
-
description: "AI Notes read-only list and detail metadata for CLI-backed Atlas and harness inspection.",
|
|
15605
|
-
examples: [
|
|
15606
|
-
"wave ai-notes list --page 1 --per 20",
|
|
15607
|
-
"wave ai-notes show --id note_123",
|
|
15608
|
-
"wave ai-notes show --slug weekly-summary"
|
|
15609
|
-
],
|
|
15610
|
-
schema: {
|
|
15611
|
-
output: "json-envelope-default",
|
|
15612
|
-
readOnly: true,
|
|
15613
|
-
safety: [
|
|
15614
|
-
"Uses API-owned GraphQL read fields aiNotes and aiNote.",
|
|
15615
|
-
"List/show output is limited to safe AI Note identifiers, title, status, visibility, source reference, owner member id, schedule timestamps, and record timestamps.",
|
|
15616
|
-
"Does not expose transcript upload, transcription finalize, consent grant, create, update, delete, transcript text, segment text, client secrets, unsafe metadata, raw provider payloads, credentials, tokens, or secrets by default."
|
|
15617
|
-
],
|
|
15618
|
-
commands: ["list", "show"]
|
|
15619
|
-
}
|
|
15620
|
-
},
|
|
15621
15481
|
"markdown-tree": {
|
|
15622
15482
|
name: "markdown-tree",
|
|
15623
15483
|
tier: "advanced",
|
|
@@ -15839,7 +15699,9 @@ async function resolveDoctorAuthOrganization(params) {
|
|
|
15839
15699
|
if (!status || typeof status !== "object" || Array.isArray(status)) {
|
|
15840
15700
|
return null;
|
|
15841
15701
|
}
|
|
15842
|
-
const
|
|
15702
|
+
const cliAuthStatus = status;
|
|
15703
|
+
if (cliAuthStatus.authenticated !== true) return null;
|
|
15704
|
+
const organization = cliAuthStatus.organization;
|
|
15843
15705
|
if (!organization || typeof organization !== "object" || Array.isArray(organization)) {
|
|
15844
15706
|
return null;
|
|
15845
15707
|
}
|
|
@@ -15880,7 +15742,7 @@ async function runDoctor(cmd, opts) {
|
|
|
15880
15742
|
name: "organization_id",
|
|
15881
15743
|
ok: Boolean(organizationId || authOrganization?.id || authOrganization?.slug),
|
|
15882
15744
|
status: organizationId || authOrganization?.id || authOrganization?.slug ? "resolved" : "missing",
|
|
15883
|
-
source: organizationId ? "
|
|
15745
|
+
source: organizationId ? "explicit_flag" : authOrganization ? "auth_token" : "unresolved",
|
|
15884
15746
|
...authOrganization?.id ? { id: authOrganization.id } : {},
|
|
15885
15747
|
...authOrganization?.slug ? { slug: authOrganization.slug } : {}
|
|
15886
15748
|
},
|
|
@@ -16133,20 +15995,20 @@ function attachDiscoveryHelp(program) {
|
|
|
16133
15995
|
}
|
|
16134
15996
|
|
|
16135
15997
|
// src/version.ts
|
|
16136
|
-
var CLI_VERSION = "0.1.
|
|
15998
|
+
var CLI_VERSION = "0.1.66";
|
|
16137
15999
|
|
|
16138
16000
|
// src/cli.ts
|
|
16139
16001
|
function buildCli(options) {
|
|
16140
16002
|
const program = new Command();
|
|
16141
16003
|
program.name("wave").description("Wave agent CLI").version(CLI_VERSION, "-V, --version", "output the version number").showHelpAfterError(false).allowExcessArguments(false).option("--token <token>", "API token (prefer WAVE_API_TOKEN env var)").option("--token-stdin", "Read API token from stdin").option(
|
|
16142
16004
|
"--auth-json-stdin",
|
|
16143
|
-
"Read auth/runtime context JSON from stdin (token, baseUrl,
|
|
16005
|
+
"Read auth/runtime context JSON from stdin (token, baseUrl, tracing fields, ...)"
|
|
16144
16006
|
).option(
|
|
16145
16007
|
"--base-url <baseUrl>",
|
|
16146
16008
|
"API base URL (prefer WAVE_API_BASE_URL env var)"
|
|
16147
16009
|
).option(
|
|
16148
16010
|
"--organization-id <organizationId>",
|
|
16149
|
-
"
|
|
16011
|
+
"Explicit organization ID override"
|
|
16150
16012
|
).option(
|
|
16151
16013
|
"--config <configPath>",
|
|
16152
16014
|
"Optional JSON config file (default: WAVE_CONFIG_PATH or ~/.wave/config.json when present)"
|
|
@@ -16209,7 +16071,6 @@ function buildCli(options) {
|
|
|
16209
16071
|
registerMailCommands(program);
|
|
16210
16072
|
registerPhantomCommands(program);
|
|
16211
16073
|
registerDatasheetsCommands(program);
|
|
16212
|
-
registerAiNotesCommands(program);
|
|
16213
16074
|
registerAuthCommands(program);
|
|
16214
16075
|
registerDiscoveryCommands(program);
|
|
16215
16076
|
attachNamespaceDiscovery(program);
|
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { REQUIRED_WAVE_RUNTIME_INPUTS } from "./cli-token-scope.mjs";
|
|
5
6
|
|
|
6
7
|
const DEFAULTS = {
|
|
7
8
|
runs: 10,
|
|
@@ -479,7 +480,7 @@ function main() {
|
|
|
479
480
|
};
|
|
480
481
|
|
|
481
482
|
const waveEntryAbs = resolve(cwd, options.waveEntry);
|
|
482
|
-
const waveMissing =
|
|
483
|
+
const waveMissing = REQUIRED_WAVE_RUNTIME_INPUTS.filter((key) => !baseEnv[key]);
|
|
483
484
|
const waveReady = existsSync(waveEntryAbs) && waveMissing.length === 0;
|
|
484
485
|
|
|
485
486
|
const obsidian = resolveObsidianBinary(options.obsidianBin);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const REQUIRED_WAVE_RUNTIME_INPUTS = ["WAVE_API_BASE_URL", "WAVE_API_TOKEN"];
|
|
2
|
+
|
|
3
|
+
export function organizationIdFromAuthenticatedStatus(envelope) {
|
|
4
|
+
if (!envelope || envelope.ok !== true) return undefined;
|
|
5
|
+
if (envelope.data?.authenticated !== true) return undefined;
|
|
6
|
+
const organizationId = envelope.data?.organization?.id;
|
|
7
|
+
return typeof organizationId === "string" && organizationId.trim() !== ""
|
|
8
|
+
? organizationId
|
|
9
|
+
: undefined;
|
|
10
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
|
+
import { organizationIdFromAuthenticatedStatus } from "./cli-token-scope.mjs";
|
|
5
6
|
|
|
6
7
|
function loadDotEnv(filePath) {
|
|
7
8
|
const raw = readFileSync(filePath, "utf8");
|
|
@@ -348,12 +349,18 @@ const dot = loadDotEnv(envFile);
|
|
|
348
349
|
const env = {
|
|
349
350
|
WAVE_API_BASE_URL: dot.WAVE_API_BASE_URL,
|
|
350
351
|
WAVE_API_TOKEN: dot.WAVE_API_TOKEN,
|
|
351
|
-
WAVE_ORGANIZATION_ID: dot.WAVE_ORGANIZATION_ID,
|
|
352
352
|
WAVE_AGENT_NAME: dot.WAVE_AGENT_NAME || "cli-verifier",
|
|
353
353
|
WAVE_AGENT_RUN_ID: `verify-${Date.now()}`,
|
|
354
354
|
WAVE_TIMEOUT_MS: dot.WAVE_TIMEOUT_MS || "10000"
|
|
355
355
|
};
|
|
356
356
|
|
|
357
|
+
const authStatus = runWave(["auth", "status"], env);
|
|
358
|
+
const orgId = organizationIdFromAuthenticatedStatus(authStatus.parsed);
|
|
359
|
+
if (!orgId) {
|
|
360
|
+
console.error("verify-dev-api failed: authenticated CLI token status did not return an organization id.");
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
|
|
357
364
|
const idLookup = {};
|
|
358
365
|
const listSeeds = [
|
|
359
366
|
["projects", ["projects", "list", "--page", "1", "--per", "2"]],
|
|
@@ -386,7 +393,7 @@ const listSeeds = [
|
|
|
386
393
|
["quarterlyObjectives", ["foundation", "quarterly-objectives", "list", "--page", "1", "--per", "2"]]
|
|
387
394
|
];
|
|
388
395
|
|
|
389
|
-
const results = [];
|
|
396
|
+
const results = [authStatus];
|
|
390
397
|
for (const [key, args] of listSeeds) {
|
|
391
398
|
const res = runWave(args, env);
|
|
392
399
|
results.push(res);
|
|
@@ -413,7 +420,6 @@ for (const [key, args] of listSeeds) {
|
|
|
413
420
|
}
|
|
414
421
|
}
|
|
415
422
|
|
|
416
|
-
const orgId = env.WAVE_ORGANIZATION_ID;
|
|
417
423
|
const projectId = idLookup.projects;
|
|
418
424
|
const taskId = idLookup.tasks;
|
|
419
425
|
const rockId = idLookup.rocks;
|