@wave-ai-os/wave-cli 0.1.63 → 0.1.65

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 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","organizationId":"42","agentName":"atlas"}' \
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. The
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 organizationCandidates = [
2287
- { organizationId: normalize3(options.organizationId), source: "flag" },
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: resolvedOrganization.source,
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 organization = status.organization;
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
  }
@@ -15840,7 +15828,9 @@ async function resolveDoctorAuthOrganization(params) {
15840
15828
  if (!status || typeof status !== "object" || Array.isArray(status)) {
15841
15829
  return null;
15842
15830
  }
15843
- const organization = status.organization;
15831
+ const cliAuthStatus = status;
15832
+ if (cliAuthStatus.authenticated !== true) return null;
15833
+ const organization = cliAuthStatus.organization;
15844
15834
  if (!organization || typeof organization !== "object" || Array.isArray(organization)) {
15845
15835
  return null;
15846
15836
  }
@@ -15881,7 +15871,7 @@ async function runDoctor(cmd, opts) {
15881
15871
  name: "organization_id",
15882
15872
  ok: Boolean(organizationId || authOrganization?.id || authOrganization?.slug),
15883
15873
  status: organizationId || authOrganization?.id || authOrganization?.slug ? "resolved" : "missing",
15884
- source: organizationId ? "flag/stdin/env" : authOrganization ? "auth_token" : "unresolved",
15874
+ source: organizationId ? "explicit_flag" : authOrganization ? "auth_token" : "unresolved",
15885
15875
  ...authOrganization?.id ? { id: authOrganization.id } : {},
15886
15876
  ...authOrganization?.slug ? { slug: authOrganization.slug } : {}
15887
15877
  },
@@ -16134,20 +16124,20 @@ function attachDiscoveryHelp(program) {
16134
16124
  }
16135
16125
 
16136
16126
  // src/version.ts
16137
- var CLI_VERSION = "0.1.63";
16127
+ var CLI_VERSION = "0.1.65";
16138
16128
 
16139
16129
  // src/cli.ts
16140
16130
  function buildCli(options) {
16141
16131
  const program = new import_commander.Command();
16142
16132
  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
16133
  "--auth-json-stdin",
16144
- "Read auth/runtime context JSON from stdin (token, baseUrl, organizationId, ...)"
16134
+ "Read auth/runtime context JSON from stdin (token, baseUrl, tracing fields, ...)"
16145
16135
  ).option(
16146
16136
  "--base-url <baseUrl>",
16147
16137
  "API base URL (prefer WAVE_API_BASE_URL env var)"
16148
16138
  ).option(
16149
16139
  "--organization-id <organizationId>",
16150
- "Organization ID (prefer WAVE_ORGANIZATION_ID env var)"
16140
+ "Explicit organization ID override"
16151
16141
  ).option(
16152
16142
  "--config <configPath>",
16153
16143
  "Optional JSON config file (default: WAVE_CONFIG_PATH or ~/.wave/config.json when present)"
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 organizationCandidates = [
2286
- { organizationId: normalize3(options.organizationId), source: "flag" },
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: resolvedOrganization.source,
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 organization = status.organization;
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
  }
@@ -15839,7 +15827,9 @@ async function resolveDoctorAuthOrganization(params) {
15839
15827
  if (!status || typeof status !== "object" || Array.isArray(status)) {
15840
15828
  return null;
15841
15829
  }
15842
- const organization = status.organization;
15830
+ const cliAuthStatus = status;
15831
+ if (cliAuthStatus.authenticated !== true) return null;
15832
+ const organization = cliAuthStatus.organization;
15843
15833
  if (!organization || typeof organization !== "object" || Array.isArray(organization)) {
15844
15834
  return null;
15845
15835
  }
@@ -15880,7 +15870,7 @@ async function runDoctor(cmd, opts) {
15880
15870
  name: "organization_id",
15881
15871
  ok: Boolean(organizationId || authOrganization?.id || authOrganization?.slug),
15882
15872
  status: organizationId || authOrganization?.id || authOrganization?.slug ? "resolved" : "missing",
15883
- source: organizationId ? "flag/stdin/env" : authOrganization ? "auth_token" : "unresolved",
15873
+ source: organizationId ? "explicit_flag" : authOrganization ? "auth_token" : "unresolved",
15884
15874
  ...authOrganization?.id ? { id: authOrganization.id } : {},
15885
15875
  ...authOrganization?.slug ? { slug: authOrganization.slug } : {}
15886
15876
  },
@@ -16133,20 +16123,20 @@ function attachDiscoveryHelp(program) {
16133
16123
  }
16134
16124
 
16135
16125
  // src/version.ts
16136
- var CLI_VERSION = "0.1.63";
16126
+ var CLI_VERSION = "0.1.65";
16137
16127
 
16138
16128
  // src/cli.ts
16139
16129
  function buildCli(options) {
16140
16130
  const program = new Command();
16141
16131
  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
16132
  "--auth-json-stdin",
16143
- "Read auth/runtime context JSON from stdin (token, baseUrl, organizationId, ...)"
16133
+ "Read auth/runtime context JSON from stdin (token, baseUrl, tracing fields, ...)"
16144
16134
  ).option(
16145
16135
  "--base-url <baseUrl>",
16146
16136
  "API base URL (prefer WAVE_API_BASE_URL env var)"
16147
16137
  ).option(
16148
16138
  "--organization-id <organizationId>",
16149
- "Organization ID (prefer WAVE_ORGANIZATION_ID env var)"
16139
+ "Explicit organization ID override"
16150
16140
  ).option(
16151
16141
  "--config <configPath>",
16152
16142
  "Optional JSON config file (default: WAVE_CONFIG_PATH or ~/.wave/config.json when present)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wave-ai-os/wave-cli",
3
- "version": "0.1.63",
3
+ "version": "0.1.65",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "wave": "dist/index.js"
@@ -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 = ["WAVE_API_BASE_URL", "WAVE_API_TOKEN", "WAVE_ORGANIZATION_ID"].filter((key) => !baseEnv[key]);
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;