@wave-ai-os/wave-cli 0.1.60 → 0.1.62
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 +583 -222
- package/dist/index.js +580 -219
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1758,6 +1758,21 @@ async function runGraphqlMutationCommand(input) {
|
|
|
1758
1758
|
variableTypes: input.variableTypes,
|
|
1759
1759
|
selectionSet: input.selectionSet ?? "{ ok status errorCode data errors }"
|
|
1760
1760
|
});
|
|
1761
|
+
if (result.envelope.ok && input.transformMutationPayload) {
|
|
1762
|
+
const envelopeData = result.envelope.data;
|
|
1763
|
+
if (!isRecord(envelopeData) || !Object.prototype.hasOwnProperty.call(envelopeData, input.field)) {
|
|
1764
|
+
throw new CliError({
|
|
1765
|
+
message: "Mutation response was missing its expected payload.",
|
|
1766
|
+
kind: "malformed_response",
|
|
1767
|
+
status: 502,
|
|
1768
|
+
exitCode: EXIT_CODES.networkOrUpstream
|
|
1769
|
+
});
|
|
1770
|
+
}
|
|
1771
|
+
result.envelope.data = {
|
|
1772
|
+
...envelopeData,
|
|
1773
|
+
[input.field]: input.transformMutationPayload(envelopeData[input.field])
|
|
1774
|
+
};
|
|
1775
|
+
}
|
|
1761
1776
|
printEnvelopeAndExit(result);
|
|
1762
1777
|
} catch (error) {
|
|
1763
1778
|
if (isEnvelopeEmittedSignal(error)) {
|
|
@@ -2136,13 +2151,18 @@ function resolveFromSources(options, stdin, config, env) {
|
|
|
2136
2151
|
normalize3(env.WAVE_API_URL),
|
|
2137
2152
|
normalize3(config.baseUrl)
|
|
2138
2153
|
);
|
|
2139
|
-
const
|
|
2140
|
-
normalize3(options.organizationId),
|
|
2141
|
-
normalize3(stdin.organizationId),
|
|
2142
|
-
normalize3(env.WAVE_ORGANIZATION_ID),
|
|
2143
|
-
normalize3(env.WAVE_ORG_ID),
|
|
2144
|
-
normalize3(config.organizationId)
|
|
2145
|
-
|
|
2154
|
+
const organizationCandidates = [
|
|
2155
|
+
{ organizationId: normalize3(options.organizationId), source: "flag" },
|
|
2156
|
+
{ organizationId: normalize3(stdin.organizationId), source: "stdin" },
|
|
2157
|
+
{ organizationId: normalize3(env.WAVE_ORGANIZATION_ID), source: "env" },
|
|
2158
|
+
{ organizationId: normalize3(env.WAVE_ORG_ID), source: "env" },
|
|
2159
|
+
{ organizationId: normalize3(config.organizationId), source: "config" }
|
|
2160
|
+
];
|
|
2161
|
+
const resolvedOrganization = organizationCandidates.find((candidate) => candidate.organizationId) ?? {
|
|
2162
|
+
organizationId: void 0,
|
|
2163
|
+
source: "none"
|
|
2164
|
+
};
|
|
2165
|
+
const organizationId = resolvedOrganization.organizationId;
|
|
2146
2166
|
const timeoutMs = firstDefined(options.timeoutMs, stdin.timeoutMs, env.WAVE_TIMEOUT_MS, config.timeoutMs);
|
|
2147
2167
|
const debug = firstDefined(
|
|
2148
2168
|
options.debug,
|
|
@@ -2231,6 +2251,7 @@ function resolveFromSources(options, stdin, config, env) {
|
|
|
2231
2251
|
const resolvedAuth = resolveAuthToken(options, stdin, config, env);
|
|
2232
2252
|
return {
|
|
2233
2253
|
organizationId,
|
|
2254
|
+
organizationIdSource: resolvedOrganization.source,
|
|
2234
2255
|
runtimeOptions: {
|
|
2235
2256
|
token: resolvedAuth.token,
|
|
2236
2257
|
tokenSource: resolvedAuth.token ? resolvedAuth.source : "none",
|
|
@@ -2440,6 +2461,140 @@ function registerGraphqlSearchCommand(command, config) {
|
|
|
2440
2461
|
});
|
|
2441
2462
|
}
|
|
2442
2463
|
|
|
2464
|
+
// src/authClient.ts
|
|
2465
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
2466
|
+
|
|
2467
|
+
// src/redaction.ts
|
|
2468
|
+
var TOKENISH_PATTERNS = [
|
|
2469
|
+
/\b(?:cli|wave|token|secret|bearer)[A-Za-z0-9._~+/=-]{8,}\b/gi,
|
|
2470
|
+
/\b[A-Za-z0-9._~+/=-]{24,}\b/g
|
|
2471
|
+
];
|
|
2472
|
+
function redactOne(value) {
|
|
2473
|
+
if (value.length <= 8) {
|
|
2474
|
+
return "[redacted]";
|
|
2475
|
+
}
|
|
2476
|
+
return `${value.slice(0, 4)}...[redacted]...${value.slice(-4)}`;
|
|
2477
|
+
}
|
|
2478
|
+
function redactSecrets(input, knownSecrets = []) {
|
|
2479
|
+
let output = input;
|
|
2480
|
+
for (const secret of knownSecrets) {
|
|
2481
|
+
if (!secret) continue;
|
|
2482
|
+
output = output.split(secret).join(redactOne(secret));
|
|
2483
|
+
}
|
|
2484
|
+
for (const pattern of TOKENISH_PATTERNS) {
|
|
2485
|
+
output = output.replace(pattern, (match) => redactOne(match));
|
|
2486
|
+
}
|
|
2487
|
+
return output;
|
|
2488
|
+
}
|
|
2489
|
+
function redactUnknown(input, knownSecrets = []) {
|
|
2490
|
+
if (typeof input === "string") {
|
|
2491
|
+
return redactSecrets(input, knownSecrets);
|
|
2492
|
+
}
|
|
2493
|
+
if (Array.isArray(input)) {
|
|
2494
|
+
return input.map((entry2) => redactUnknown(entry2, knownSecrets));
|
|
2495
|
+
}
|
|
2496
|
+
if (!input || typeof input !== "object") {
|
|
2497
|
+
return input;
|
|
2498
|
+
}
|
|
2499
|
+
const output = {};
|
|
2500
|
+
for (const [key, value] of Object.entries(input)) {
|
|
2501
|
+
if (/token|secret|authorization|bearer/i.test(key)) {
|
|
2502
|
+
output[key] = typeof value === "string" ? redactSecrets(value, knownSecrets) : "[redacted]";
|
|
2503
|
+
continue;
|
|
2504
|
+
}
|
|
2505
|
+
output[key] = redactUnknown(value, knownSecrets);
|
|
2506
|
+
}
|
|
2507
|
+
return output;
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
// src/authClient.ts
|
|
2511
|
+
function parseJsonSafely2(input) {
|
|
2512
|
+
try {
|
|
2513
|
+
return JSON.parse(input);
|
|
2514
|
+
} catch {
|
|
2515
|
+
return null;
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
function graphqlErrors(payload, knownSecrets) {
|
|
2519
|
+
const errors = payload.errors;
|
|
2520
|
+
if (!Array.isArray(errors) || errors.length === 0) return null;
|
|
2521
|
+
return {
|
|
2522
|
+
code: "upstream_error",
|
|
2523
|
+
message: "GraphQL request failed.",
|
|
2524
|
+
status: 400,
|
|
2525
|
+
details: {
|
|
2526
|
+
errors: redactUnknown(errors, knownSecrets)
|
|
2527
|
+
}
|
|
2528
|
+
};
|
|
2529
|
+
}
|
|
2530
|
+
async function authGraphqlRequest(params) {
|
|
2531
|
+
const requestId = randomUUID2();
|
|
2532
|
+
const controller = new AbortController();
|
|
2533
|
+
const timeoutId = setTimeout(() => controller.abort(), params.timeoutMs);
|
|
2534
|
+
const knownSecrets = [params.token, ...params.knownSecrets ?? []].filter(
|
|
2535
|
+
(secret) => typeof secret === "string" && secret.length > 0
|
|
2536
|
+
);
|
|
2537
|
+
try {
|
|
2538
|
+
const url = new URL("/graphql", params.baseUrl);
|
|
2539
|
+
const response = await fetch(url, {
|
|
2540
|
+
method: "POST",
|
|
2541
|
+
headers: {
|
|
2542
|
+
Accept: "application/json",
|
|
2543
|
+
"Content-Type": "application/json",
|
|
2544
|
+
"X-Origin": "wave-cli",
|
|
2545
|
+
"X-Request-Id": requestId,
|
|
2546
|
+
...params.token ? { Authorization: `Bearer ${params.token}` } : {}
|
|
2547
|
+
},
|
|
2548
|
+
body: JSON.stringify({ query: params.query, variables: params.variables ?? {} }),
|
|
2549
|
+
signal: controller.signal
|
|
2550
|
+
});
|
|
2551
|
+
const responseRequestId = response.headers.get("x-request-id") ?? requestId;
|
|
2552
|
+
const text = await response.text();
|
|
2553
|
+
const payload = text ? parseJsonSafely2(text) : null;
|
|
2554
|
+
const graph = payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
2555
|
+
const gqlError = graphqlErrors(graph, knownSecrets);
|
|
2556
|
+
if (gqlError) {
|
|
2557
|
+
return { ok: false, error: gqlError, requestId: responseRequestId };
|
|
2558
|
+
}
|
|
2559
|
+
if (!response.ok) {
|
|
2560
|
+
return {
|
|
2561
|
+
ok: false,
|
|
2562
|
+
requestId: responseRequestId,
|
|
2563
|
+
error: {
|
|
2564
|
+
code: `http_${response.status}`,
|
|
2565
|
+
message: "Auth request failed.",
|
|
2566
|
+
status: response.status,
|
|
2567
|
+
details: { body: redactUnknown(graph, knownSecrets) }
|
|
2568
|
+
}
|
|
2569
|
+
};
|
|
2570
|
+
}
|
|
2571
|
+
const data = graph.data && typeof graph.data === "object" && !Array.isArray(graph.data) ? graph.data : {};
|
|
2572
|
+
return {
|
|
2573
|
+
ok: true,
|
|
2574
|
+
result: {
|
|
2575
|
+
status: response.status,
|
|
2576
|
+
requestId: responseRequestId,
|
|
2577
|
+
data
|
|
2578
|
+
}
|
|
2579
|
+
};
|
|
2580
|
+
} catch (error) {
|
|
2581
|
+
const message = error instanceof Error ? error.message : "Network error.";
|
|
2582
|
+
const timedOut = error instanceof Error && error.name === "AbortError";
|
|
2583
|
+
return {
|
|
2584
|
+
ok: false,
|
|
2585
|
+
requestId,
|
|
2586
|
+
error: {
|
|
2587
|
+
code: timedOut ? "timeout" : "network_error",
|
|
2588
|
+
message: redactSecrets(timedOut ? "Auth request timed out." : message, knownSecrets),
|
|
2589
|
+
status: timedOut ? 408 : 503,
|
|
2590
|
+
details: {}
|
|
2591
|
+
}
|
|
2592
|
+
};
|
|
2593
|
+
} finally {
|
|
2594
|
+
clearTimeout(timeoutId);
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2443
2598
|
// src/commands/tasks.ts
|
|
2444
2599
|
var projectIdSchema = z2.string().min(1);
|
|
2445
2600
|
var idSchema = z2.string().min(1);
|
|
@@ -2468,6 +2623,44 @@ function parseTaskUpdateJson(raw) {
|
|
|
2468
2623
|
function parseLabelIds(raw) {
|
|
2469
2624
|
return raw.split(",").map((labelId) => labelId.trim()).filter((labelId) => labelId.length > 0);
|
|
2470
2625
|
}
|
|
2626
|
+
function asRecord3(value) {
|
|
2627
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2628
|
+
return null;
|
|
2629
|
+
}
|
|
2630
|
+
return value;
|
|
2631
|
+
}
|
|
2632
|
+
function asNonEmptyString2(value) {
|
|
2633
|
+
if (typeof value !== "string") {
|
|
2634
|
+
return void 0;
|
|
2635
|
+
}
|
|
2636
|
+
const trimmed = value.trim();
|
|
2637
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
2638
|
+
}
|
|
2639
|
+
async function resolveTaskReadOrganizationId(params) {
|
|
2640
|
+
const resolvedOrganizationId = asNonEmptyString2(params.organizationId);
|
|
2641
|
+
if (params.organizationIdSource === "flag" && resolvedOrganizationId) {
|
|
2642
|
+
return resolvedOrganizationId;
|
|
2643
|
+
}
|
|
2644
|
+
const baseUrl = asNonEmptyString2(params.runtimeOptions.baseUrl);
|
|
2645
|
+
const token = asNonEmptyString2(params.runtimeOptions.token);
|
|
2646
|
+
if (baseUrl && token) {
|
|
2647
|
+
const result = await authGraphqlRequest({
|
|
2648
|
+
baseUrl,
|
|
2649
|
+
token,
|
|
2650
|
+
timeoutMs: typeof params.runtimeOptions.timeoutMs === "number" ? params.runtimeOptions.timeoutMs : 1e4,
|
|
2651
|
+
query: "query WaveCliTaskReadOrganization { cliAuthStatus { authenticated baseAuthStatus organization { id slug } } }"
|
|
2652
|
+
});
|
|
2653
|
+
if (result.ok) {
|
|
2654
|
+
const status = asRecord3(result.result.data.cliAuthStatus);
|
|
2655
|
+
const organization = status ? asRecord3(status.organization) : null;
|
|
2656
|
+
const organizationId = organization ? asNonEmptyString2(organization.id) : void 0;
|
|
2657
|
+
if (organizationId) {
|
|
2658
|
+
return organizationId;
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
return resolveOrganizationId(resolvedOrganizationId);
|
|
2663
|
+
}
|
|
2471
2664
|
function registerTaskCommands(program) {
|
|
2472
2665
|
const tasks = program.command("tasks").description("Task operations");
|
|
2473
2666
|
tasks.command("list").option("--project-id <projectId>").option("--page <page>").option("--per <per>").option("--team-id <teamId>").option("--team-ids <teamIds>").option("--member-id <memberId>").option("--meeting-id <meetingId>").option("--field-name <fieldName>").option("--field-value <fieldValue>").option("--field-blank <fieldBlank>").option("--open <open>").option("--rank-direction <rankDirection>").option("--include-archived <includeArchived>").action(async (opts, cmd) => {
|
|
@@ -2504,7 +2697,11 @@ function registerTaskCommands(program) {
|
|
|
2504
2697
|
tasks.command("show").requiredOption("--id <id>").action(async (opts, cmd) => {
|
|
2505
2698
|
const parsed = idSchema.parse(opts.id);
|
|
2506
2699
|
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
2507
|
-
const organizationId =
|
|
2700
|
+
const organizationId = await resolveTaskReadOrganizationId({
|
|
2701
|
+
organizationId: context.organizationId,
|
|
2702
|
+
organizationIdSource: context.organizationIdSource,
|
|
2703
|
+
runtimeOptions: context.runtimeOptions
|
|
2704
|
+
});
|
|
2508
2705
|
await runGraphqlQueryCommand({
|
|
2509
2706
|
command: "tasks.show",
|
|
2510
2707
|
runtimeOptions: context.runtimeOptions,
|
|
@@ -3406,16 +3603,16 @@ var displayPreferenceAttributesSelectionSet = "attributes { id viewType favorite
|
|
|
3406
3603
|
var filterPreferenceAttributesSelectionSet = "attributes { id filterType filter memberId focusMemberId focusTeamId filterableId filterableType preferenceType agendaItemId }";
|
|
3407
3604
|
var healthUpdateSummarySelectionSet = "id type value memberId status createdAt updatedAt updatableType updatableId parentUpdateId emojis { id name memberId } resources { ...ResourceSummaryFull }";
|
|
3408
3605
|
var projectShowFullSelectionSet = `{ id type name slug description status priority createdAt updatedAt startDate targetDate archivedAt memberId organizationId teamIds emoji { id name memberId } backgroundImage { backgroundType gradientStart gradientEnd gradientDegrees color imageUrl image { url lowUrl } } favorites { id memberId } resources { ...ResourceSummaryFull } displayPreference { id type ${displayPreferenceAttributesSelectionSet} viewType favorite groupingField groupToggleState memberId focusMemberId focusTeamId displayableId displayableType preferenceType agendaItemId } filterPreferences { id type ${filterPreferenceAttributesSelectionSet} filterType filter memberId focusMemberId focusTeamId filterableId filterableType preferenceType agendaItemId } healthUpdates { ${healthUpdateSummarySelectionSet} replies { ${healthUpdateSummarySelectionSet} replies { id type } } } } fragment ResourceSummaryFull on ResourceSummary { id resourceType slug url skillId skill { id name slug emoji scope description } metadata { urlName imageUrl siteName providerName mediaType skillId skillName skillSlug skillScope skillEmoji skillDescription } attachment { id fileKey filename url } content { id name slug type firstChildSlug childCount } }`;
|
|
3409
|
-
function
|
|
3606
|
+
function asRecord4(value) {
|
|
3410
3607
|
return value && typeof value === "object" ? value : null;
|
|
3411
3608
|
}
|
|
3412
3609
|
function toNonEmptyString(value) {
|
|
3413
3610
|
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
3414
3611
|
}
|
|
3415
3612
|
function normalizeProjectRowForDisplay(row) {
|
|
3416
|
-
const record =
|
|
3613
|
+
const record = asRecord4(row);
|
|
3417
3614
|
if (!record) return row;
|
|
3418
|
-
const attributes =
|
|
3615
|
+
const attributes = asRecord4(record.attributes);
|
|
3419
3616
|
const topLevelName = toNonEmptyString(record.name);
|
|
3420
3617
|
const topLevelTitle = toNonEmptyString(record.title);
|
|
3421
3618
|
const attributeName = toNonEmptyString(attributes?.name);
|
|
@@ -3430,7 +3627,7 @@ function normalizeProjectRowForDisplay(row) {
|
|
|
3430
3627
|
};
|
|
3431
3628
|
}
|
|
3432
3629
|
function normalizeProjectsListForDisplay(payload) {
|
|
3433
|
-
const record =
|
|
3630
|
+
const record = asRecord4(payload);
|
|
3434
3631
|
if (!record || !Array.isArray(record.data)) return payload;
|
|
3435
3632
|
return {
|
|
3436
3633
|
...record,
|
|
@@ -3638,7 +3835,7 @@ var MEETING_STATUSES = /* @__PURE__ */ new Set(["upcoming", "active", "completed
|
|
|
3638
3835
|
var MEETING_REPEATS = /* @__PURE__ */ new Set(["never", "weekly", "biweekly", "monthly", "quarterly"]);
|
|
3639
3836
|
var createHelp2 = buildDataJsonHelp("meeting", "create") ?? 'JSON object for meeting or {"meeting": {...}}';
|
|
3640
3837
|
var updateHelp2 = buildDataJsonHelp("meeting", "update") ?? 'JSON object for meeting or {"meeting": {...}}';
|
|
3641
|
-
function
|
|
3838
|
+
function asNonEmptyString3(value) {
|
|
3642
3839
|
if (typeof value !== "string") {
|
|
3643
3840
|
return void 0;
|
|
3644
3841
|
}
|
|
@@ -3696,7 +3893,7 @@ function normalizeMeetingCreateBody(body) {
|
|
|
3696
3893
|
});
|
|
3697
3894
|
}
|
|
3698
3895
|
const meeting = { ...entity };
|
|
3699
|
-
const type =
|
|
3896
|
+
const type = asNonEmptyString3(meeting.type);
|
|
3700
3897
|
if (!type || !MEETING_TYPES.has(type)) {
|
|
3701
3898
|
throw new CliError({
|
|
3702
3899
|
message: "Invalid meeting.type. Use one of: TeamMeeting, OneOnOneMeeting.",
|
|
@@ -3706,8 +3903,8 @@ function normalizeMeetingCreateBody(body) {
|
|
|
3706
3903
|
details: { field: "meeting.type", allowed: Array.from(MEETING_TYPES) }
|
|
3707
3904
|
});
|
|
3708
3905
|
}
|
|
3709
|
-
const memberId =
|
|
3710
|
-
const date =
|
|
3906
|
+
const memberId = asNonEmptyString3(meeting.member_id);
|
|
3907
|
+
const date = asNonEmptyString3(meeting.date);
|
|
3711
3908
|
const startTime = toFiniteNumber(meeting.start_time, "meeting.start_time");
|
|
3712
3909
|
const missingRequired = [];
|
|
3713
3910
|
if (!memberId) missingRequired.push("member_id");
|
|
@@ -3722,7 +3919,7 @@ function normalizeMeetingCreateBody(body) {
|
|
|
3722
3919
|
details: { requiredFields: ["member_id", "date", "start_time"], rootKey: "meeting" }
|
|
3723
3920
|
});
|
|
3724
3921
|
}
|
|
3725
|
-
const status =
|
|
3922
|
+
const status = asNonEmptyString3(meeting.status);
|
|
3726
3923
|
if (status && !MEETING_STATUSES.has(status)) {
|
|
3727
3924
|
throw new CliError({
|
|
3728
3925
|
message: "Invalid meeting.status. Use one of: upcoming, active, completed.",
|
|
@@ -3732,7 +3929,7 @@ function normalizeMeetingCreateBody(body) {
|
|
|
3732
3929
|
details: { field: "meeting.status", allowed: Array.from(MEETING_STATUSES) }
|
|
3733
3930
|
});
|
|
3734
3931
|
}
|
|
3735
|
-
const repeats =
|
|
3932
|
+
const repeats = asNonEmptyString3(meeting.repeats) ?? "never";
|
|
3736
3933
|
if (!MEETING_REPEATS.has(repeats)) {
|
|
3737
3934
|
throw new CliError({
|
|
3738
3935
|
message: "Invalid meeting.repeats. Use one of: never, weekly, biweekly, monthly, quarterly.",
|
|
@@ -4021,7 +4218,7 @@ var SKILL_SELECTION = `{
|
|
|
4021
4218
|
createdAt
|
|
4022
4219
|
updatedAt
|
|
4023
4220
|
}`;
|
|
4024
|
-
function
|
|
4221
|
+
function asRecord5(value) {
|
|
4025
4222
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
4026
4223
|
}
|
|
4027
4224
|
function findSkillById(id) {
|
|
@@ -4029,11 +4226,11 @@ function findSkillById(id) {
|
|
|
4029
4226
|
if (!Array.isArray(payload)) {
|
|
4030
4227
|
return null;
|
|
4031
4228
|
}
|
|
4032
|
-
return payload.find((entry2) => String(
|
|
4229
|
+
return payload.find((entry2) => String(asRecord5(entry2)?.id ?? "") === id) ?? null;
|
|
4033
4230
|
};
|
|
4034
4231
|
}
|
|
4035
4232
|
function registerSkillCommands(program) {
|
|
4036
|
-
const skills = program.command("skills").description("
|
|
4233
|
+
const skills = program.command("skills").description("Skill record operations");
|
|
4037
4234
|
skills.command("list").description("List Skill records").option("--scope <scope>", "Filter skills by scope").option("--query <query>", "Filter skills by search query").option("--limit <limit>", "Limit skills returned").requiredOption("--json", "Emit the stable JSON envelope").action(async (opts, cmd) => {
|
|
4038
4235
|
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
4039
4236
|
const organizationId = resolveOrganizationId(context.organizationId);
|
|
@@ -4059,7 +4256,7 @@ function registerSkillCommands(program) {
|
|
|
4059
4256
|
isList: true
|
|
4060
4257
|
});
|
|
4061
4258
|
});
|
|
4062
|
-
skills.command("show").description("Read one Skill record by id").requiredOption("--id <id>", "Skill id").requiredOption("--json", "Emit the stable JSON envelope").action(async (opts, cmd) => {
|
|
4259
|
+
skills.command("show").description("Read one persisted Skill record by id").requiredOption("--id <id>", "Skill id").requiredOption("--json", "Emit the stable JSON envelope").action(async (opts, cmd) => {
|
|
4063
4260
|
const id = idSchema7.parse(opts.id);
|
|
4064
4261
|
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
4065
4262
|
const organizationId = resolveOrganizationId(context.organizationId);
|
|
@@ -4421,7 +4618,7 @@ function normalizeTodosCreateBody(body) {
|
|
|
4421
4618
|
}
|
|
4422
4619
|
return { ...body, todo };
|
|
4423
4620
|
}
|
|
4424
|
-
function
|
|
4621
|
+
function asNonEmptyString4(value) {
|
|
4425
4622
|
if (typeof value !== "string") {
|
|
4426
4623
|
return void 0;
|
|
4427
4624
|
}
|
|
@@ -4429,7 +4626,7 @@ function asNonEmptyString3(value) {
|
|
|
4429
4626
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
4430
4627
|
}
|
|
4431
4628
|
function validateEnumField(params) {
|
|
4432
|
-
const value =
|
|
4629
|
+
const value = asNonEmptyString4(params.rawValue);
|
|
4433
4630
|
if (!value) {
|
|
4434
4631
|
return void 0;
|
|
4435
4632
|
}
|
|
@@ -4463,7 +4660,7 @@ function normalizeKnowledgeCreateBody(body) {
|
|
|
4463
4660
|
message: "Invalid content.status. Use one of: draft, published."
|
|
4464
4661
|
});
|
|
4465
4662
|
content.status = status ?? "draft";
|
|
4466
|
-
const memberId =
|
|
4663
|
+
const memberId = asNonEmptyString4(content.member_id);
|
|
4467
4664
|
if (!memberId) {
|
|
4468
4665
|
throwMissingRequiredCreateFields("content", ["member_id"]);
|
|
4469
4666
|
}
|
|
@@ -4472,7 +4669,7 @@ function normalizeKnowledgeCreateBody(body) {
|
|
|
4472
4669
|
}
|
|
4473
4670
|
function normalizeNewsCreateBody(body) {
|
|
4474
4671
|
const headline = ensureEntityObject(body, "headline");
|
|
4475
|
-
const memberId =
|
|
4672
|
+
const memberId = asNonEmptyString4(headline.member_id);
|
|
4476
4673
|
if (!memberId) {
|
|
4477
4674
|
throwMissingRequiredCreateFields("headline", ["member_id"]);
|
|
4478
4675
|
}
|
|
@@ -4501,14 +4698,14 @@ function normalizeNewsCreateBody(body) {
|
|
|
4501
4698
|
}
|
|
4502
4699
|
function normalizeQuestionsCreateBody(body) {
|
|
4503
4700
|
const question = ensureEntityObject(body, "question");
|
|
4504
|
-
const summary =
|
|
4505
|
-
const currentName =
|
|
4701
|
+
const summary = asNonEmptyString4(question.summary);
|
|
4702
|
+
const currentName = asNonEmptyString4(question.name);
|
|
4506
4703
|
if (!currentName && summary) {
|
|
4507
4704
|
question.name = summary;
|
|
4508
4705
|
}
|
|
4509
4706
|
delete question.summary;
|
|
4510
|
-
const name =
|
|
4511
|
-
const memberId =
|
|
4707
|
+
const name = asNonEmptyString4(question.name);
|
|
4708
|
+
const memberId = asNonEmptyString4(question.member_id);
|
|
4512
4709
|
const missing = [];
|
|
4513
4710
|
if (!name) missing.push("name");
|
|
4514
4711
|
if (!memberId) missing.push("member_id");
|
|
@@ -4530,13 +4727,13 @@ function normalizeQuestionsCreateBody(body) {
|
|
|
4530
4727
|
}
|
|
4531
4728
|
function normalizeQuestionsUpdateBody(body) {
|
|
4532
4729
|
const question = ensureEntityObject(body, "question");
|
|
4533
|
-
const summary =
|
|
4534
|
-
const currentName =
|
|
4730
|
+
const summary = asNonEmptyString4(question.summary);
|
|
4731
|
+
const currentName = asNonEmptyString4(question.name);
|
|
4535
4732
|
if (!currentName && summary) {
|
|
4536
4733
|
question.name = summary;
|
|
4537
4734
|
}
|
|
4538
4735
|
delete question.summary;
|
|
4539
|
-
const name =
|
|
4736
|
+
const name = asNonEmptyString4(question.name);
|
|
4540
4737
|
if (name) {
|
|
4541
4738
|
question.name = name;
|
|
4542
4739
|
}
|
|
@@ -4553,9 +4750,9 @@ function normalizeQuestionsUpdateBody(body) {
|
|
|
4553
4750
|
}
|
|
4554
4751
|
function normalizePulseCreateBody(body) {
|
|
4555
4752
|
const healthUpdate = ensureEntityObject(body, "health_update");
|
|
4556
|
-
const healthUpdatableId =
|
|
4557
|
-
const healthUpdatableType =
|
|
4558
|
-
const memberId =
|
|
4753
|
+
const healthUpdatableId = asNonEmptyString4(healthUpdate.health_updatable_id) ?? asNonEmptyString4(healthUpdate.updatable_id);
|
|
4754
|
+
const healthUpdatableType = asNonEmptyString4(healthUpdate.health_updatable_type) ?? asNonEmptyString4(healthUpdate.updatable_type);
|
|
4755
|
+
const memberId = asNonEmptyString4(healthUpdate.member_id);
|
|
4559
4756
|
const status = validateEnumField({
|
|
4560
4757
|
rawValue: healthUpdate.status,
|
|
4561
4758
|
field: "health_update.status",
|
|
@@ -4580,8 +4777,8 @@ function normalizePulseCreateBody(body) {
|
|
|
4580
4777
|
}
|
|
4581
4778
|
function normalizeSurveysCreateBody(body) {
|
|
4582
4779
|
const survey = ensureEntityObject(body, "survey");
|
|
4583
|
-
const title =
|
|
4584
|
-
const currentName =
|
|
4780
|
+
const title = asNonEmptyString4(survey.title);
|
|
4781
|
+
const currentName = asNonEmptyString4(survey.name);
|
|
4585
4782
|
if (!currentName && title) {
|
|
4586
4783
|
survey.name = title;
|
|
4587
4784
|
}
|
|
@@ -4610,8 +4807,8 @@ function normalizeSurveysCreateBody(body) {
|
|
|
4610
4807
|
}
|
|
4611
4808
|
function normalizeSurveysUpdateBody(body) {
|
|
4612
4809
|
const survey = ensureEntityObject(body, "survey");
|
|
4613
|
-
const title =
|
|
4614
|
-
const currentName =
|
|
4810
|
+
const title = asNonEmptyString4(survey.title);
|
|
4811
|
+
const currentName = asNonEmptyString4(survey.name);
|
|
4615
4812
|
if (!currentName && title) {
|
|
4616
4813
|
survey.name = title;
|
|
4617
4814
|
}
|
|
@@ -4638,8 +4835,8 @@ function normalizeSurveysUpdateBody(body) {
|
|
|
4638
4835
|
}
|
|
4639
4836
|
function normalizeFeedbacksCreateBody(body) {
|
|
4640
4837
|
const feedback = ensureEntityObject(body, "feedback");
|
|
4641
|
-
const title =
|
|
4642
|
-
const currentName =
|
|
4838
|
+
const title = asNonEmptyString4(feedback.title);
|
|
4839
|
+
const currentName = asNonEmptyString4(feedback.name);
|
|
4643
4840
|
if (!currentName && title) {
|
|
4644
4841
|
feedback.name = title;
|
|
4645
4842
|
}
|
|
@@ -4656,7 +4853,7 @@ function normalizeFeedbacksCreateBody(body) {
|
|
|
4656
4853
|
allowed: FEEDBACK_QUARTERS,
|
|
4657
4854
|
message: "Invalid feedback.quarter. Use one of: q1, q2, q3, q4."
|
|
4658
4855
|
});
|
|
4659
|
-
const year =
|
|
4856
|
+
const year = asNonEmptyString4(feedback.year);
|
|
4660
4857
|
const missing = [];
|
|
4661
4858
|
if (!name) missing.push("name");
|
|
4662
4859
|
if (!quarter) missing.push("quarter");
|
|
@@ -4671,8 +4868,8 @@ function normalizeFeedbacksCreateBody(body) {
|
|
|
4671
4868
|
}
|
|
4672
4869
|
function normalizeFeedbacksUpdateBody(body) {
|
|
4673
4870
|
const feedback = ensureEntityObject(body, "feedback");
|
|
4674
|
-
const title =
|
|
4675
|
-
const currentName =
|
|
4871
|
+
const title = asNonEmptyString4(feedback.title);
|
|
4872
|
+
const currentName = asNonEmptyString4(feedback.name);
|
|
4676
4873
|
if (!currentName && title) {
|
|
4677
4874
|
feedback.name = title;
|
|
4678
4875
|
}
|
|
@@ -4699,14 +4896,14 @@ function normalizeFeedbacksUpdateBody(body) {
|
|
|
4699
4896
|
}
|
|
4700
4897
|
function normalizeAccountabilityCreateBody(body) {
|
|
4701
4898
|
const responsibility = ensureEntityObject(body, "responsibility");
|
|
4702
|
-
const summary =
|
|
4703
|
-
const currentName =
|
|
4899
|
+
const summary = asNonEmptyString4(responsibility.summary);
|
|
4900
|
+
const currentName = asNonEmptyString4(responsibility.name);
|
|
4704
4901
|
if (!currentName && summary) {
|
|
4705
4902
|
responsibility.name = summary;
|
|
4706
4903
|
}
|
|
4707
4904
|
delete responsibility.summary;
|
|
4708
|
-
const name =
|
|
4709
|
-
const memberId =
|
|
4905
|
+
const name = asNonEmptyString4(responsibility.name);
|
|
4906
|
+
const memberId = asNonEmptyString4(responsibility.member_id);
|
|
4710
4907
|
const missing = [];
|
|
4711
4908
|
if (!name) missing.push("name");
|
|
4712
4909
|
if (!memberId) missing.push("member_id");
|
|
@@ -4721,8 +4918,8 @@ function normalizeAccountabilityCreateBody(body) {
|
|
|
4721
4918
|
}
|
|
4722
4919
|
function normalizeAccountabilityUpdateBody(body) {
|
|
4723
4920
|
const responsibility = ensureEntityObject(body, "responsibility");
|
|
4724
|
-
const summary =
|
|
4725
|
-
const currentName =
|
|
4921
|
+
const summary = asNonEmptyString4(responsibility.summary);
|
|
4922
|
+
const currentName = asNonEmptyString4(responsibility.name);
|
|
4726
4923
|
if (!currentName && summary) {
|
|
4727
4924
|
responsibility.name = summary;
|
|
4728
4925
|
}
|
|
@@ -4754,7 +4951,7 @@ function parseSmartKpiViewCreateBody(raw) {
|
|
|
4754
4951
|
}
|
|
4755
4952
|
function normalizeSmartKpiViewCreateBody(body) {
|
|
4756
4953
|
const smartKpiView = ensureEntityObject(body, "smart_kpi_view");
|
|
4757
|
-
const name =
|
|
4954
|
+
const name = asNonEmptyString4(smartKpiView.name);
|
|
4758
4955
|
if (!name) {
|
|
4759
4956
|
throwMissingRequiredCreateFields("smart_kpi_view", ["name"]);
|
|
4760
4957
|
}
|
|
@@ -4792,9 +4989,9 @@ function buildKpisCreateMutation(params) {
|
|
|
4792
4989
|
});
|
|
4793
4990
|
}
|
|
4794
4991
|
const smartKpi = { ...entity };
|
|
4795
|
-
const name =
|
|
4796
|
-
const smartKpiViewId =
|
|
4797
|
-
const measurableGroupId =
|
|
4992
|
+
const name = asNonEmptyString4(smartKpi.name);
|
|
4993
|
+
const smartKpiViewId = asNonEmptyString4(smartKpi.smart_kpi_view_id);
|
|
4994
|
+
const measurableGroupId = asNonEmptyString4(smartKpi.measurable_group_id);
|
|
4798
4995
|
const hasAllowedName = typeof name === "string" && SMART_KPI_NAME_SET.has(name);
|
|
4799
4996
|
if (!name) {
|
|
4800
4997
|
throw new CliError({
|
|
@@ -4814,7 +5011,7 @@ function buildKpisCreateMutation(params) {
|
|
|
4814
5011
|
measurable_type: "number",
|
|
4815
5012
|
condition: "greater_than_or_equal_to"
|
|
4816
5013
|
};
|
|
4817
|
-
const notes =
|
|
5014
|
+
const notes = asNonEmptyString4(smartKpi.notes);
|
|
4818
5015
|
if (notes) {
|
|
4819
5016
|
measurable.notes = notes;
|
|
4820
5017
|
}
|
|
@@ -5217,7 +5414,7 @@ function ensureRootObject(body, rootKey) {
|
|
|
5217
5414
|
}
|
|
5218
5415
|
return { ...root };
|
|
5219
5416
|
}
|
|
5220
|
-
function
|
|
5417
|
+
function asNonEmptyString5(value) {
|
|
5221
5418
|
if (typeof value !== "string") {
|
|
5222
5419
|
return void 0;
|
|
5223
5420
|
}
|
|
@@ -5227,7 +5424,7 @@ function asNonEmptyString4(value) {
|
|
|
5227
5424
|
function normalizeOrganizationUpdateBody(body) {
|
|
5228
5425
|
const organization = ensureRootObject(body, "organization");
|
|
5229
5426
|
const detail = isRecord3(organization.organization_detail_attributes) ? { ...organization.organization_detail_attributes } : {};
|
|
5230
|
-
const workspaceName =
|
|
5427
|
+
const workspaceName = asNonEmptyString5(organization.workspace_name);
|
|
5231
5428
|
if (workspaceName) {
|
|
5232
5429
|
detail.workspace_name = workspaceName;
|
|
5233
5430
|
}
|
|
@@ -5240,7 +5437,7 @@ function normalizeOrganizationUpdateBody(body) {
|
|
|
5240
5437
|
function normalizeOrganizationMetaProfileUpdateBody(body) {
|
|
5241
5438
|
const root = ensureRootObject(body, "organization_meta_profile");
|
|
5242
5439
|
const profile = isRecord3(root.profile) ? { ...root.profile } : {};
|
|
5243
|
-
const title =
|
|
5440
|
+
const title = asNonEmptyString5(root.title);
|
|
5244
5441
|
if (title) {
|
|
5245
5442
|
const companyIdentity = isRecord3(profile.company_identity) ? { ...profile.company_identity } : {};
|
|
5246
5443
|
companyIdentity.one_sentence_summary = title;
|
|
@@ -5270,7 +5467,7 @@ function normalizeOrganizationMetaProfileUpdateBody(body) {
|
|
|
5270
5467
|
function normalizeKeyMetricMetaProfileUpdateBody(body) {
|
|
5271
5468
|
const root = ensureRootObject(body, "key_metric_meta_profile");
|
|
5272
5469
|
const profile = isRecord3(root.profile) ? { ...root.profile } : {};
|
|
5273
|
-
const annualRevenue =
|
|
5470
|
+
const annualRevenue = asNonEmptyString5(root.annual_revenue);
|
|
5274
5471
|
if (annualRevenue) {
|
|
5275
5472
|
const financial = isRecord3(profile.financial) ? { ...profile.financial } : {};
|
|
5276
5473
|
financial.revenue = annualRevenue;
|
|
@@ -5441,7 +5638,7 @@ function ensureRootObject2(body, rootKey) {
|
|
|
5441
5638
|
}
|
|
5442
5639
|
return { ...root };
|
|
5443
5640
|
}
|
|
5444
|
-
function
|
|
5641
|
+
function asNonEmptyString6(value) {
|
|
5445
5642
|
if (typeof value !== "string") {
|
|
5446
5643
|
return void 0;
|
|
5447
5644
|
}
|
|
@@ -5469,8 +5666,8 @@ function normalizeStrategicPlanUpdateBody(body) {
|
|
|
5469
5666
|
}
|
|
5470
5667
|
function normalizeStrategicObjectiveUpdateBody(body) {
|
|
5471
5668
|
const strategicObjective = ensureRootObject2(body, "strategic_objective");
|
|
5472
|
-
const title =
|
|
5473
|
-
if (!
|
|
5669
|
+
const title = asNonEmptyString6(strategicObjective.title);
|
|
5670
|
+
if (!asNonEmptyString6(strategicObjective.summary) && title) {
|
|
5474
5671
|
strategicObjective.summary = title;
|
|
5475
5672
|
}
|
|
5476
5673
|
delete strategicObjective.title;
|
|
@@ -5493,8 +5690,8 @@ function normalizeStrategicObjectiveUpdateBody(body) {
|
|
|
5493
5690
|
}
|
|
5494
5691
|
function normalizeAnnualObjectiveCreateBody(body) {
|
|
5495
5692
|
const annualObjective = ensureRootObject2(body, "annual_objective");
|
|
5496
|
-
const title =
|
|
5497
|
-
if (!
|
|
5693
|
+
const title = asNonEmptyString6(annualObjective.title);
|
|
5694
|
+
if (!asNonEmptyString6(annualObjective.name) && title) {
|
|
5498
5695
|
annualObjective.name = title;
|
|
5499
5696
|
}
|
|
5500
5697
|
delete annualObjective.title;
|
|
@@ -5502,8 +5699,8 @@ function normalizeAnnualObjectiveCreateBody(body) {
|
|
|
5502
5699
|
}
|
|
5503
5700
|
function normalizeQuarterlyObjectiveCreateBody(body) {
|
|
5504
5701
|
const quarterlyObjective = ensureRootObject2(body, "quarterly_objective");
|
|
5505
|
-
const title =
|
|
5506
|
-
if (!
|
|
5702
|
+
const title = asNonEmptyString6(quarterlyObjective.title);
|
|
5703
|
+
if (!asNonEmptyString6(quarterlyObjective.name) && title) {
|
|
5507
5704
|
quarterlyObjective.name = title;
|
|
5508
5705
|
}
|
|
5509
5706
|
delete quarterlyObjective.title;
|
|
@@ -6304,7 +6501,7 @@ import { z as z16 } from "zod";
|
|
|
6304
6501
|
|
|
6305
6502
|
// src/internalOptions.ts
|
|
6306
6503
|
var INTERNAL_OPTIONS_KEY = "__waveInternalOptions";
|
|
6307
|
-
function
|
|
6504
|
+
function asRecord6(value) {
|
|
6308
6505
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6309
6506
|
return null;
|
|
6310
6507
|
}
|
|
@@ -6318,7 +6515,7 @@ function setInternalCliOptions(program, options) {
|
|
|
6318
6515
|
function getInternalCliOptions(command) {
|
|
6319
6516
|
let current = command;
|
|
6320
6517
|
while (current) {
|
|
6321
|
-
const record =
|
|
6518
|
+
const record = asRecord6(current[INTERNAL_OPTIONS_KEY]);
|
|
6322
6519
|
if (record) {
|
|
6323
6520
|
return {
|
|
6324
6521
|
enableRetryOnEmptyPhrase: record.enableRetryOnEmptyPhrase === true
|
|
@@ -9963,142 +10160,6 @@ function registerOsmdCommands(program) {
|
|
|
9963
10160
|
|
|
9964
10161
|
// src/commands/auth.ts
|
|
9965
10162
|
import { spawn } from "child_process";
|
|
9966
|
-
|
|
9967
|
-
// src/authClient.ts
|
|
9968
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
9969
|
-
|
|
9970
|
-
// src/redaction.ts
|
|
9971
|
-
var TOKENISH_PATTERNS = [
|
|
9972
|
-
/\b(?:cli|wave|token|secret|bearer)[A-Za-z0-9._~+/=-]{8,}\b/gi,
|
|
9973
|
-
/\b[A-Za-z0-9._~+/=-]{24,}\b/g
|
|
9974
|
-
];
|
|
9975
|
-
function redactOne(value) {
|
|
9976
|
-
if (value.length <= 8) {
|
|
9977
|
-
return "[redacted]";
|
|
9978
|
-
}
|
|
9979
|
-
return `${value.slice(0, 4)}...[redacted]...${value.slice(-4)}`;
|
|
9980
|
-
}
|
|
9981
|
-
function redactSecrets(input, knownSecrets = []) {
|
|
9982
|
-
let output = input;
|
|
9983
|
-
for (const secret of knownSecrets) {
|
|
9984
|
-
if (!secret) continue;
|
|
9985
|
-
output = output.split(secret).join(redactOne(secret));
|
|
9986
|
-
}
|
|
9987
|
-
for (const pattern of TOKENISH_PATTERNS) {
|
|
9988
|
-
output = output.replace(pattern, (match) => redactOne(match));
|
|
9989
|
-
}
|
|
9990
|
-
return output;
|
|
9991
|
-
}
|
|
9992
|
-
function redactUnknown(input, knownSecrets = []) {
|
|
9993
|
-
if (typeof input === "string") {
|
|
9994
|
-
return redactSecrets(input, knownSecrets);
|
|
9995
|
-
}
|
|
9996
|
-
if (Array.isArray(input)) {
|
|
9997
|
-
return input.map((entry2) => redactUnknown(entry2, knownSecrets));
|
|
9998
|
-
}
|
|
9999
|
-
if (!input || typeof input !== "object") {
|
|
10000
|
-
return input;
|
|
10001
|
-
}
|
|
10002
|
-
const output = {};
|
|
10003
|
-
for (const [key, value] of Object.entries(input)) {
|
|
10004
|
-
if (/token|secret|authorization|bearer/i.test(key)) {
|
|
10005
|
-
output[key] = typeof value === "string" ? redactSecrets(value, knownSecrets) : "[redacted]";
|
|
10006
|
-
continue;
|
|
10007
|
-
}
|
|
10008
|
-
output[key] = redactUnknown(value, knownSecrets);
|
|
10009
|
-
}
|
|
10010
|
-
return output;
|
|
10011
|
-
}
|
|
10012
|
-
|
|
10013
|
-
// src/authClient.ts
|
|
10014
|
-
function parseJsonSafely2(input) {
|
|
10015
|
-
try {
|
|
10016
|
-
return JSON.parse(input);
|
|
10017
|
-
} catch {
|
|
10018
|
-
return null;
|
|
10019
|
-
}
|
|
10020
|
-
}
|
|
10021
|
-
function graphqlErrors(payload, knownSecrets) {
|
|
10022
|
-
const errors = payload.errors;
|
|
10023
|
-
if (!Array.isArray(errors) || errors.length === 0) return null;
|
|
10024
|
-
return {
|
|
10025
|
-
code: "upstream_error",
|
|
10026
|
-
message: "GraphQL request failed.",
|
|
10027
|
-
status: 400,
|
|
10028
|
-
details: {
|
|
10029
|
-
errors: redactUnknown(errors, knownSecrets)
|
|
10030
|
-
}
|
|
10031
|
-
};
|
|
10032
|
-
}
|
|
10033
|
-
async function authGraphqlRequest(params) {
|
|
10034
|
-
const requestId = randomUUID2();
|
|
10035
|
-
const controller = new AbortController();
|
|
10036
|
-
const timeoutId = setTimeout(() => controller.abort(), params.timeoutMs);
|
|
10037
|
-
const knownSecrets = [params.token, ...params.knownSecrets ?? []].filter(
|
|
10038
|
-
(secret) => typeof secret === "string" && secret.length > 0
|
|
10039
|
-
);
|
|
10040
|
-
try {
|
|
10041
|
-
const url = new URL("/graphql", params.baseUrl);
|
|
10042
|
-
const response = await fetch(url, {
|
|
10043
|
-
method: "POST",
|
|
10044
|
-
headers: {
|
|
10045
|
-
Accept: "application/json",
|
|
10046
|
-
"Content-Type": "application/json",
|
|
10047
|
-
"X-Origin": "wave-cli",
|
|
10048
|
-
"X-Request-Id": requestId,
|
|
10049
|
-
...params.token ? { Authorization: `Bearer ${params.token}` } : {}
|
|
10050
|
-
},
|
|
10051
|
-
body: JSON.stringify({ query: params.query, variables: params.variables ?? {} }),
|
|
10052
|
-
signal: controller.signal
|
|
10053
|
-
});
|
|
10054
|
-
const responseRequestId = response.headers.get("x-request-id") ?? requestId;
|
|
10055
|
-
const text = await response.text();
|
|
10056
|
-
const payload = text ? parseJsonSafely2(text) : null;
|
|
10057
|
-
const graph = payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
10058
|
-
const gqlError = graphqlErrors(graph, knownSecrets);
|
|
10059
|
-
if (gqlError) {
|
|
10060
|
-
return { ok: false, error: gqlError, requestId: responseRequestId };
|
|
10061
|
-
}
|
|
10062
|
-
if (!response.ok) {
|
|
10063
|
-
return {
|
|
10064
|
-
ok: false,
|
|
10065
|
-
requestId: responseRequestId,
|
|
10066
|
-
error: {
|
|
10067
|
-
code: `http_${response.status}`,
|
|
10068
|
-
message: "Auth request failed.",
|
|
10069
|
-
status: response.status,
|
|
10070
|
-
details: { body: redactUnknown(graph, knownSecrets) }
|
|
10071
|
-
}
|
|
10072
|
-
};
|
|
10073
|
-
}
|
|
10074
|
-
const data = graph.data && typeof graph.data === "object" && !Array.isArray(graph.data) ? graph.data : {};
|
|
10075
|
-
return {
|
|
10076
|
-
ok: true,
|
|
10077
|
-
result: {
|
|
10078
|
-
status: response.status,
|
|
10079
|
-
requestId: responseRequestId,
|
|
10080
|
-
data
|
|
10081
|
-
}
|
|
10082
|
-
};
|
|
10083
|
-
} catch (error) {
|
|
10084
|
-
const message = error instanceof Error ? error.message : "Network error.";
|
|
10085
|
-
const timedOut = error instanceof Error && error.name === "AbortError";
|
|
10086
|
-
return {
|
|
10087
|
-
ok: false,
|
|
10088
|
-
requestId,
|
|
10089
|
-
error: {
|
|
10090
|
-
code: timedOut ? "timeout" : "network_error",
|
|
10091
|
-
message: redactSecrets(timedOut ? "Auth request timed out." : message, knownSecrets),
|
|
10092
|
-
status: timedOut ? 408 : 503,
|
|
10093
|
-
details: {}
|
|
10094
|
-
}
|
|
10095
|
-
};
|
|
10096
|
-
} finally {
|
|
10097
|
-
clearTimeout(timeoutId);
|
|
10098
|
-
}
|
|
10099
|
-
}
|
|
10100
|
-
|
|
10101
|
-
// src/commands/auth.ts
|
|
10102
10163
|
var DEFAULT_LOGIN_TIMEOUT_MS = 12e4;
|
|
10103
10164
|
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
10104
10165
|
function envelope(params) {
|
|
@@ -10126,7 +10187,7 @@ function positiveInt2(raw, fallback) {
|
|
|
10126
10187
|
function requestTimeoutMs(totalTimeoutMs) {
|
|
10127
10188
|
return Math.max(1e3, Math.min(totalTimeoutMs, 1e4));
|
|
10128
10189
|
}
|
|
10129
|
-
function
|
|
10190
|
+
function asRecord7(value) {
|
|
10130
10191
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
10131
10192
|
}
|
|
10132
10193
|
function asString(value) {
|
|
@@ -10173,9 +10234,9 @@ function cliTokenFromPoll(payload) {
|
|
|
10173
10234
|
return asString(payload.cliToken) ?? asString(payload.cli_token) ?? asString(payload.token);
|
|
10174
10235
|
}
|
|
10175
10236
|
function unwrapMutationResult(value) {
|
|
10176
|
-
const record =
|
|
10237
|
+
const record = asRecord7(value);
|
|
10177
10238
|
if (!record) return null;
|
|
10178
|
-
const data =
|
|
10239
|
+
const data = asRecord7(record.data);
|
|
10179
10240
|
if (data && (Object.prototype.hasOwnProperty.call(record, "ok") || Object.prototype.hasOwnProperty.call(record, "errors") || Object.prototype.hasOwnProperty.call(record, "errorCode") || Object.prototype.hasOwnProperty.call(record, "error_code"))) {
|
|
10180
10241
|
return data;
|
|
10181
10242
|
}
|
|
@@ -10239,7 +10300,7 @@ async function runTokenLogin(cmd, opts) {
|
|
|
10239
10300
|
exitCode: mapStatusToExitCode(status.error.status)
|
|
10240
10301
|
});
|
|
10241
10302
|
}
|
|
10242
|
-
const statusData =
|
|
10303
|
+
const statusData = asRecord7(status.result.data.cliAuthStatus) ?? {};
|
|
10243
10304
|
const storage = await writeStoredToken(token, baseUrl);
|
|
10244
10305
|
const configPath2 = opts.saveBaseUrl ? await persistBaseUrl(baseUrl) : void 0;
|
|
10245
10306
|
return printEnvelopeAndExit({
|
|
@@ -10456,7 +10517,7 @@ async function runLogout(cmd) {
|
|
|
10456
10517
|
});
|
|
10457
10518
|
if (result.ok) {
|
|
10458
10519
|
requestId = result.result.requestId;
|
|
10459
|
-
const payload =
|
|
10520
|
+
const payload = asRecord7(result.result.data.revokeCliToken) ?? {};
|
|
10460
10521
|
revokedRemote = payload.ok !== false;
|
|
10461
10522
|
} else {
|
|
10462
10523
|
requestId = result.requestId;
|
|
@@ -10519,7 +10580,8 @@ async function runAuthStatus(cmd) {
|
|
|
10519
10580
|
exitCode: mapStatusToExitCode(result.error.status)
|
|
10520
10581
|
});
|
|
10521
10582
|
}
|
|
10522
|
-
const status =
|
|
10583
|
+
const status = asRecord7(result.result.data.cliAuthStatus) ?? {};
|
|
10584
|
+
const baseAuthStatus = status.baseAuthStatus;
|
|
10523
10585
|
return printEnvelopeAndExit({
|
|
10524
10586
|
envelope: envelope({
|
|
10525
10587
|
ok: true,
|
|
@@ -10528,6 +10590,7 @@ async function runAuthStatus(cmd) {
|
|
|
10528
10590
|
requestId: result.result.requestId,
|
|
10529
10591
|
data: {
|
|
10530
10592
|
authenticated: Boolean(status.authenticated),
|
|
10593
|
+
baseAuthStatus: typeof baseAuthStatus === "string" ? baseAuthStatus : null,
|
|
10531
10594
|
baseUrl,
|
|
10532
10595
|
tokenSource,
|
|
10533
10596
|
member: redactUnknown(status.member, [token]) ?? null,
|
|
@@ -12168,11 +12231,11 @@ function sanitizePlannerJson(value) {
|
|
|
12168
12231
|
}
|
|
12169
12232
|
return output;
|
|
12170
12233
|
}
|
|
12171
|
-
function
|
|
12234
|
+
function asRecord8(value) {
|
|
12172
12235
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
12173
12236
|
}
|
|
12174
12237
|
function readPlannerStateKey(value, keys) {
|
|
12175
|
-
const record =
|
|
12238
|
+
const record = asRecord8(value);
|
|
12176
12239
|
if (!record) {
|
|
12177
12240
|
return null;
|
|
12178
12241
|
}
|
|
@@ -14837,6 +14900,259 @@ function registerAiNotesCommands(program) {
|
|
|
14837
14900
|
});
|
|
14838
14901
|
}
|
|
14839
14902
|
|
|
14903
|
+
// src/commands/atlasAuthoring.ts
|
|
14904
|
+
import { z as z19 } from "zod";
|
|
14905
|
+
var idSchema14 = z19.string().trim().min(1);
|
|
14906
|
+
var idempotencyKeySchema = z19.string().min(1).refine((value) => value.trim() === value, "Idempotency key must not have leading or trailing whitespace.");
|
|
14907
|
+
var skillScopeSchema = z19.enum(["ADMIN_GLOBAL", "MEMBER_PERSONAL"]);
|
|
14908
|
+
var isoDateSchema = z19.iso.date();
|
|
14909
|
+
var AGENT_SELECTION = `{
|
|
14910
|
+
id
|
|
14911
|
+
type
|
|
14912
|
+
name
|
|
14913
|
+
slug
|
|
14914
|
+
description
|
|
14915
|
+
notes
|
|
14916
|
+
status
|
|
14917
|
+
visibility
|
|
14918
|
+
model
|
|
14919
|
+
runWhenMentioned
|
|
14920
|
+
webAccessEnabled
|
|
14921
|
+
organizationId
|
|
14922
|
+
memberId
|
|
14923
|
+
createdAt
|
|
14924
|
+
updatedAt
|
|
14925
|
+
}`;
|
|
14926
|
+
var AUTOMATION_SELECTION = `{
|
|
14927
|
+
id
|
|
14928
|
+
type
|
|
14929
|
+
summary
|
|
14930
|
+
slug
|
|
14931
|
+
description
|
|
14932
|
+
notes
|
|
14933
|
+
status
|
|
14934
|
+
priority
|
|
14935
|
+
taskType
|
|
14936
|
+
aiTaskConfig
|
|
14937
|
+
organizationId
|
|
14938
|
+
memberId
|
|
14939
|
+
createdAt
|
|
14940
|
+
updatedAt
|
|
14941
|
+
}`;
|
|
14942
|
+
function asRecord9(value) {
|
|
14943
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
14944
|
+
}
|
|
14945
|
+
function asRequiredString(value) {
|
|
14946
|
+
if (typeof value !== "string") return null;
|
|
14947
|
+
const trimmed = value.trim();
|
|
14948
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
14949
|
+
}
|
|
14950
|
+
function parseBooleanOption(value, optionName) {
|
|
14951
|
+
if (value === void 0) return void 0;
|
|
14952
|
+
if (value === "true") return true;
|
|
14953
|
+
if (value === "false") return false;
|
|
14954
|
+
throw new CliError({
|
|
14955
|
+
message: `Invalid ${optionName}: expected true or false.`,
|
|
14956
|
+
kind: "invalid_args",
|
|
14957
|
+
status: 400,
|
|
14958
|
+
exitCode: EXIT_CODES.invalidArgs
|
|
14959
|
+
});
|
|
14960
|
+
}
|
|
14961
|
+
function parseCommaSeparatedStrings(value) {
|
|
14962
|
+
if (value === void 0) return void 0;
|
|
14963
|
+
const entries = String(value).split(",").map((entry2) => entry2.trim()).filter((entry2) => entry2.length > 0);
|
|
14964
|
+
if (entries.length === 0) {
|
|
14965
|
+
throw new CliError({
|
|
14966
|
+
message: "--trusted-urls must include at least one URL.",
|
|
14967
|
+
kind: "invalid_args",
|
|
14968
|
+
status: 400,
|
|
14969
|
+
exitCode: EXIT_CODES.invalidArgs
|
|
14970
|
+
});
|
|
14971
|
+
}
|
|
14972
|
+
return entries;
|
|
14973
|
+
}
|
|
14974
|
+
function parseJson(value, optionName) {
|
|
14975
|
+
try {
|
|
14976
|
+
return JSON.parse(value);
|
|
14977
|
+
} catch (error) {
|
|
14978
|
+
throw new CliError({
|
|
14979
|
+
message: error instanceof Error ? `Invalid ${optionName}: ${error.message}` : `Invalid ${optionName}.`,
|
|
14980
|
+
kind: "invalid_args",
|
|
14981
|
+
status: 400,
|
|
14982
|
+
exitCode: EXIT_CODES.invalidArgs
|
|
14983
|
+
});
|
|
14984
|
+
}
|
|
14985
|
+
}
|
|
14986
|
+
function normalizePersistedCreatePayload(payload) {
|
|
14987
|
+
const mutation = asRecord9(payload);
|
|
14988
|
+
const mutationData = asRecord9(mutation?.data);
|
|
14989
|
+
const persisted = asRecord9(mutationData?.data) ?? mutationData;
|
|
14990
|
+
const attributes = asRecord9(persisted?.attributes);
|
|
14991
|
+
const meta = asRecord9(mutationData?.meta);
|
|
14992
|
+
const idempotency = asRecord9(meta?.atlas_idempotency);
|
|
14993
|
+
const id = asRequiredString(persisted?.id);
|
|
14994
|
+
const slug = asRequiredString(persisted?.slug) ?? asRequiredString(attributes?.slug);
|
|
14995
|
+
const replay = idempotency?.replay;
|
|
14996
|
+
if (!mutation || !mutationData || !persisted || !id || !slug || !idempotency || typeof replay !== "boolean") {
|
|
14997
|
+
throw new CliError({
|
|
14998
|
+
message: "Create response did not include persisted id/slug and idempotency metadata.",
|
|
14999
|
+
kind: "malformed_response",
|
|
15000
|
+
status: 502,
|
|
15001
|
+
exitCode: EXIT_CODES.networkOrUpstream
|
|
15002
|
+
});
|
|
15003
|
+
}
|
|
15004
|
+
return {
|
|
15005
|
+
ok: mutation.ok,
|
|
15006
|
+
status: mutation.status,
|
|
15007
|
+
errorCode: mutation.errorCode ?? null,
|
|
15008
|
+
errors: mutation.errors ?? null,
|
|
15009
|
+
persisted: { id, slug },
|
|
15010
|
+
idempotency: {
|
|
15011
|
+
object_type: asRequiredString(idempotency.object_type),
|
|
15012
|
+
id: asRequiredString(idempotency.id),
|
|
15013
|
+
slug: asRequiredString(idempotency.slug),
|
|
15014
|
+
idempotency_key: asRequiredString(idempotency.idempotency_key),
|
|
15015
|
+
fingerprint: asRequiredString(idempotency.fingerprint),
|
|
15016
|
+
replay,
|
|
15017
|
+
action: asRequiredString(idempotency.action)
|
|
15018
|
+
}
|
|
15019
|
+
};
|
|
15020
|
+
}
|
|
15021
|
+
function registerAtlasAuthoringCommands(program) {
|
|
15022
|
+
const agents = program.command("agents").description("Bounded Agent authoring operations");
|
|
15023
|
+
agents.command("create").description("Create an Agent through the API-owned createAgent contract").requiredOption("--idempotency-key <key>", "Required create idempotency key").option("--name <name>").option("--description <description>").option("--notes <notes>").option("--member-id <memberId>").option("--status <status>").option("--visibility <visibility>").option("--model <model>").option("--run-when-mentioned <boolean>", "true or false").option("--web-access-enabled <boolean>", "true or false").option("--trusted-urls <urls>", "Comma-separated trusted URLs").action(async (opts, cmd) => {
|
|
15024
|
+
const idempotencyKey = idempotencyKeySchema.parse(opts.idempotencyKey);
|
|
15025
|
+
const runWhenMentioned = parseBooleanOption(opts.runWhenMentioned, "--run-when-mentioned");
|
|
15026
|
+
const webAccessEnabled = parseBooleanOption(opts.webAccessEnabled, "--web-access-enabled");
|
|
15027
|
+
const trustedUrls = parseCommaSeparatedStrings(opts.trustedUrls);
|
|
15028
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
15029
|
+
const organizationId = resolveOrganizationId(context.organizationId);
|
|
15030
|
+
await runGraphqlMutationCommand({
|
|
15031
|
+
command: "agents.create",
|
|
15032
|
+
operationName: "AgentsCreate",
|
|
15033
|
+
runtimeOptions: context.runtimeOptions,
|
|
15034
|
+
field: "create_agent",
|
|
15035
|
+
variableTypes: {
|
|
15036
|
+
organization_id: "ID!",
|
|
15037
|
+
params: "CreateAgentParamsInput!",
|
|
15038
|
+
idempotency_key: "String!"
|
|
15039
|
+
},
|
|
15040
|
+
variables: {
|
|
15041
|
+
organization_id: organizationId,
|
|
15042
|
+
params: {
|
|
15043
|
+
agent: {
|
|
15044
|
+
...opts.name !== void 0 ? { name: String(opts.name) } : {},
|
|
15045
|
+
...opts.description !== void 0 ? { description: String(opts.description) } : {},
|
|
15046
|
+
...opts.notes !== void 0 ? { notes: String(opts.notes) } : {},
|
|
15047
|
+
...opts.memberId !== void 0 ? { member_id: idSchema14.parse(opts.memberId) } : {},
|
|
15048
|
+
...opts.status !== void 0 ? { status: String(opts.status) } : {},
|
|
15049
|
+
...opts.visibility !== void 0 ? { visibility: String(opts.visibility) } : {},
|
|
15050
|
+
...opts.model !== void 0 ? { model: String(opts.model) } : {},
|
|
15051
|
+
...runWhenMentioned !== void 0 ? { run_when_mentioned: runWhenMentioned } : {},
|
|
15052
|
+
...webAccessEnabled !== void 0 ? { web_access_enabled: webAccessEnabled } : {},
|
|
15053
|
+
...trustedUrls !== void 0 ? { trusted_urls: trustedUrls } : {}
|
|
15054
|
+
}
|
|
15055
|
+
},
|
|
15056
|
+
idempotency_key: idempotencyKey
|
|
15057
|
+
},
|
|
15058
|
+
transformMutationPayload: normalizePersistedCreatePayload
|
|
15059
|
+
});
|
|
15060
|
+
});
|
|
15061
|
+
agents.command("show").description("Read one persisted Agent by id").requiredOption("--id <id>", "Agent id").action(async (opts, cmd) => {
|
|
15062
|
+
const id = idSchema14.parse(opts.id);
|
|
15063
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
15064
|
+
const organizationId = resolveOrganizationId(context.organizationId);
|
|
15065
|
+
await runGraphqlQueryCommand({
|
|
15066
|
+
command: "agents.show",
|
|
15067
|
+
operationName: "AgentsShow",
|
|
15068
|
+
runtimeOptions: context.runtimeOptions,
|
|
15069
|
+
field: "agent",
|
|
15070
|
+
variables: { organization_id: organizationId, id },
|
|
15071
|
+
variableTypes: { organization_id: "ID!", id: "ID!" },
|
|
15072
|
+
selectionSet: AGENT_SELECTION,
|
|
15073
|
+
isShow: true
|
|
15074
|
+
});
|
|
15075
|
+
});
|
|
15076
|
+
const automations = program.command("automations").description("Bounded Automation authoring operations");
|
|
15077
|
+
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) => {
|
|
15078
|
+
const idempotencyKey = idempotencyKeySchema.parse(opts.idempotencyKey);
|
|
15079
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
15080
|
+
const organizationId = resolveOrganizationId(context.organizationId);
|
|
15081
|
+
await runGraphqlMutationCommand({
|
|
15082
|
+
command: "automations.create",
|
|
15083
|
+
operationName: "AutomationsCreate",
|
|
15084
|
+
runtimeOptions: context.runtimeOptions,
|
|
15085
|
+
field: "create_automation",
|
|
15086
|
+
variableTypes: {
|
|
15087
|
+
organization_id: "ID!",
|
|
15088
|
+
input: "CreateAutomationInput!",
|
|
15089
|
+
idempotency_key: "String!"
|
|
15090
|
+
},
|
|
15091
|
+
variables: {
|
|
15092
|
+
organization_id: organizationId,
|
|
15093
|
+
input: {
|
|
15094
|
+
summary: idSchema14.parse(opts.summary),
|
|
15095
|
+
ai_task_config: parseJson(String(opts.aiTaskConfig), "--ai-task-config"),
|
|
15096
|
+
...opts.description !== void 0 ? { description: String(opts.description) } : {},
|
|
15097
|
+
...opts.notes !== void 0 ? { notes: String(opts.notes) } : {},
|
|
15098
|
+
...opts.memberId !== void 0 ? { member_id: idSchema14.parse(opts.memberId) } : {},
|
|
15099
|
+
...opts.status !== void 0 ? { status: String(opts.status) } : {},
|
|
15100
|
+
...opts.priority !== void 0 ? { priority: String(opts.priority) } : {},
|
|
15101
|
+
...opts.dueDate !== void 0 ? { due_date: isoDateSchema.parse(opts.dueDate) } : {}
|
|
15102
|
+
},
|
|
15103
|
+
idempotency_key: idempotencyKey
|
|
15104
|
+
},
|
|
15105
|
+
transformMutationPayload: normalizePersistedCreatePayload
|
|
15106
|
+
});
|
|
15107
|
+
});
|
|
15108
|
+
automations.command("show").description("Read one persisted Automation by id").requiredOption("--id <id>", "Automation id").action(async (opts, cmd) => {
|
|
15109
|
+
const id = idSchema14.parse(opts.id);
|
|
15110
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
15111
|
+
const organizationId = resolveOrganizationId(context.organizationId);
|
|
15112
|
+
await runGraphqlQueryCommand({
|
|
15113
|
+
command: "automations.show",
|
|
15114
|
+
operationName: "AutomationsShow",
|
|
15115
|
+
runtimeOptions: context.runtimeOptions,
|
|
15116
|
+
field: "automation",
|
|
15117
|
+
variables: { organization_id: organizationId, id },
|
|
15118
|
+
variableTypes: { organization_id: "ID!", id: "ID!" },
|
|
15119
|
+
selectionSet: AUTOMATION_SELECTION,
|
|
15120
|
+
isShow: true
|
|
15121
|
+
});
|
|
15122
|
+
});
|
|
15123
|
+
const skills = program.commands.find((command) => command.name() === "skills");
|
|
15124
|
+
if (!skills) {
|
|
15125
|
+
throw new Error("Skills command must be registered before Atlas authoring commands.");
|
|
15126
|
+
}
|
|
15127
|
+
skills.command("create").description("Create a Skill through the API-owned createSkill contract").requiredOption("--name <name>").requiredOption("--scope <scope>", "ADMIN_GLOBAL or MEMBER_PERSONAL").requiredOption("--idempotency-key <key>", "Required create idempotency key").option("--emoji <emoji>").option("--description <description>").action(async (opts, cmd) => {
|
|
15128
|
+
const idempotencyKey = idempotencyKeySchema.parse(opts.idempotencyKey);
|
|
15129
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
15130
|
+
const organizationId = resolveOrganizationId(context.organizationId);
|
|
15131
|
+
await runGraphqlMutationCommand({
|
|
15132
|
+
command: "skills.create",
|
|
15133
|
+
operationName: "SkillsCreate",
|
|
15134
|
+
runtimeOptions: context.runtimeOptions,
|
|
15135
|
+
field: "create_skill",
|
|
15136
|
+
variableTypes: {
|
|
15137
|
+
organization_id: "ID!",
|
|
15138
|
+
input: "CreateSkillInput!",
|
|
15139
|
+
idempotency_key: "String!"
|
|
15140
|
+
},
|
|
15141
|
+
variables: {
|
|
15142
|
+
organization_id: organizationId,
|
|
15143
|
+
input: {
|
|
15144
|
+
name: idSchema14.parse(opts.name),
|
|
15145
|
+
scope: skillScopeSchema.parse(opts.scope),
|
|
15146
|
+
...opts.emoji !== void 0 ? { emoji: String(opts.emoji) } : {},
|
|
15147
|
+
...opts.description !== void 0 ? { description: String(opts.description) } : {}
|
|
15148
|
+
},
|
|
15149
|
+
idempotency_key: idempotencyKey
|
|
15150
|
+
},
|
|
15151
|
+
transformMutationPayload: normalizePersistedCreatePayload
|
|
15152
|
+
});
|
|
15153
|
+
});
|
|
15154
|
+
}
|
|
15155
|
+
|
|
14840
15156
|
// src/commands/discovery.ts
|
|
14841
15157
|
import { existsSync as existsSync3, readFileSync } from "fs";
|
|
14842
15158
|
import { join as join3 } from "path";
|
|
@@ -14857,6 +15173,8 @@ var PRIMARY_NAMESPACES = [
|
|
|
14857
15173
|
"rocks",
|
|
14858
15174
|
"meetings",
|
|
14859
15175
|
"members",
|
|
15176
|
+
"agents",
|
|
15177
|
+
"automations",
|
|
14860
15178
|
"skills",
|
|
14861
15179
|
"teams",
|
|
14862
15180
|
"issues",
|
|
@@ -14970,20 +15288,62 @@ var NAMESPACE_DOCS = {
|
|
|
14970
15288
|
skills: {
|
|
14971
15289
|
name: "skills",
|
|
14972
15290
|
tier: "primary",
|
|
14973
|
-
description: "
|
|
15291
|
+
description: "Skill record readback and bounded create operations.",
|
|
14974
15292
|
examples: [
|
|
14975
15293
|
"wave skills list --json",
|
|
14976
15294
|
"wave skills list --scope ADMIN_GLOBAL --json",
|
|
14977
|
-
"wave skills show --id 123 --json"
|
|
15295
|
+
"wave skills show --id 123 --json",
|
|
15296
|
+
'wave skills create --name "Weekly planning" --scope MEMBER_PERSONAL --idempotency-key skill-create-001'
|
|
14978
15297
|
],
|
|
14979
15298
|
schema: {
|
|
14980
15299
|
output: "json-envelope-default",
|
|
14981
|
-
|
|
15300
|
+
mutates: true,
|
|
14982
15301
|
safety: [
|
|
14983
15302
|
"Uses API-owned Skill GraphQL read fields only.",
|
|
14984
|
-
"
|
|
15303
|
+
"Create calls only createSkill with an explicit idempotency key.",
|
|
15304
|
+
"Skill create supports the API-defined ADMIN_GLOBAL and MEMBER_PERSONAL scopes.",
|
|
15305
|
+
"Does not update, destroy, archive, approve, or apply Skill records."
|
|
14985
15306
|
],
|
|
14986
|
-
commands: ["list", "show"]
|
|
15307
|
+
commands: ["list", "show", "create"]
|
|
15308
|
+
}
|
|
15309
|
+
},
|
|
15310
|
+
agents: {
|
|
15311
|
+
name: "agents",
|
|
15312
|
+
tier: "primary",
|
|
15313
|
+
description: "Bounded Agent create and persisted readback operations.",
|
|
15314
|
+
examples: [
|
|
15315
|
+
'wave agents create --name "Planning helper" --idempotency-key agent-create-001',
|
|
15316
|
+
"wave agents show --id 123"
|
|
15317
|
+
],
|
|
15318
|
+
schema: {
|
|
15319
|
+
output: "json-envelope-default",
|
|
15320
|
+
mutates: true,
|
|
15321
|
+
safety: [
|
|
15322
|
+
"Create calls only createAgent with an explicit idempotency key.",
|
|
15323
|
+
"Create preserves API-owned defaults by sending only supplied typed Agent fields.",
|
|
15324
|
+
"Show uses the API-owned agent query by id; no slug fallback is implemented."
|
|
15325
|
+
],
|
|
15326
|
+
commands: ["create", "show"]
|
|
15327
|
+
}
|
|
15328
|
+
},
|
|
15329
|
+
automations: {
|
|
15330
|
+
name: "automations",
|
|
15331
|
+
tier: "primary",
|
|
15332
|
+
description: "Bounded Automation create and persisted readback operations.",
|
|
15333
|
+
examples: [
|
|
15334
|
+
`wave automations create --summary "Weekly review" --ai-task-config '{"prompt":"Review tasks"}' --idempotency-key automation-create-001`,
|
|
15335
|
+
"wave automations show --id 123"
|
|
15336
|
+
],
|
|
15337
|
+
schema: {
|
|
15338
|
+
output: "json-envelope-default",
|
|
15339
|
+
mutates: true,
|
|
15340
|
+
safety: [
|
|
15341
|
+
"Create calls only createAutomation with an explicit idempotency key.",
|
|
15342
|
+
"Only the API-defined ai_task_config field accepts validated JSON.",
|
|
15343
|
+
"Does not create a project Task, run an Automation, or invoke AI OS actions.",
|
|
15344
|
+
"Show uses the API-owned automation query by id; no slug fallback is implemented."
|
|
15345
|
+
],
|
|
15346
|
+
commands: ["create", "show"]
|
|
14987
15347
|
}
|
|
14988
15348
|
},
|
|
14989
15349
|
broadcast: {
|
|
@@ -15797,7 +16157,7 @@ function attachDiscoveryHelp(program) {
|
|
|
15797
16157
|
}
|
|
15798
16158
|
|
|
15799
16159
|
// src/version.ts
|
|
15800
|
-
var CLI_VERSION = "0.1.
|
|
16160
|
+
var CLI_VERSION = "0.1.62";
|
|
15801
16161
|
|
|
15802
16162
|
// src/cli.ts
|
|
15803
16163
|
function buildCli(options) {
|
|
@@ -15852,6 +16212,7 @@ function buildCli(options) {
|
|
|
15852
16212
|
registerMeetingCommands(program);
|
|
15853
16213
|
registerMemberCommands(program);
|
|
15854
16214
|
registerSkillCommands(program);
|
|
16215
|
+
registerAtlasAuthoringCommands(program);
|
|
15855
16216
|
registerTeamCommands(program);
|
|
15856
16217
|
registerOrganizationCommands(program);
|
|
15857
16218
|
registerIssueCommands(program);
|