@wave-ai-os/wave-cli 0.1.87 → 0.1.88
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 +1 -15
- package/dist/index.cjs +793 -686
- package/dist/index.js +792 -685
- package/package.json +5 -1
- package/scripts/verify-dev-api.mjs +0 -151
- package/scripts/verify-reminder-artifact.mjs +34 -0
package/dist/index.cjs
CHANGED
|
@@ -8,6 +8,225 @@ var import_zod22 = require("zod");
|
|
|
8
8
|
// src/cli.ts
|
|
9
9
|
var import_commander2 = require("commander");
|
|
10
10
|
|
|
11
|
+
// src/authStorage.ts
|
|
12
|
+
var import_node_child_process = require("child_process");
|
|
13
|
+
var import_node_fs = require("fs");
|
|
14
|
+
var import_promises = require("fs/promises");
|
|
15
|
+
var import_node_os = require("os");
|
|
16
|
+
var import_node_path = require("path");
|
|
17
|
+
var import_node_util = require("util");
|
|
18
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
19
|
+
var KEYCHAIN_SERVICE = "wave-cli";
|
|
20
|
+
var FILE_NAME = "auth-token.json";
|
|
21
|
+
var DEFAULT_STORAGE_MODE = "auto";
|
|
22
|
+
var activeOptions = {};
|
|
23
|
+
function configureAuthStorage(options) {
|
|
24
|
+
activeOptions = { ...options };
|
|
25
|
+
}
|
|
26
|
+
async function withAuthStorageOptions(options, callback) {
|
|
27
|
+
const previous = activeOptions;
|
|
28
|
+
activeOptions = { ...options };
|
|
29
|
+
try {
|
|
30
|
+
return await callback();
|
|
31
|
+
} finally {
|
|
32
|
+
activeOptions = previous;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function normalize(raw) {
|
|
36
|
+
if (typeof raw !== "string") return void 0;
|
|
37
|
+
const trimmed = raw.trim();
|
|
38
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
39
|
+
}
|
|
40
|
+
function authHome() {
|
|
41
|
+
return normalize(activeOptions.home) ?? (0, import_node_path.join)((0, import_node_os.homedir)(), ".wave");
|
|
42
|
+
}
|
|
43
|
+
function tokenPath() {
|
|
44
|
+
return (0, import_node_path.join)(authHome(), FILE_NAME);
|
|
45
|
+
}
|
|
46
|
+
function configPath() {
|
|
47
|
+
return normalize(activeOptions.configPath) ?? (0, import_node_path.join)(authHome(), "config.json");
|
|
48
|
+
}
|
|
49
|
+
function storageMode() {
|
|
50
|
+
return activeOptions.mode ?? DEFAULT_STORAGE_MODE;
|
|
51
|
+
}
|
|
52
|
+
function accountForBaseUrl(baseUrl) {
|
|
53
|
+
return normalize(baseUrl) ?? "default";
|
|
54
|
+
}
|
|
55
|
+
async function commandExists(command) {
|
|
56
|
+
try {
|
|
57
|
+
await (0, import_promises.access)(command, import_node_fs.constants.X_OK);
|
|
58
|
+
return true;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function keychainAvailable() {
|
|
64
|
+
if (process.platform !== "darwin") return false;
|
|
65
|
+
if (storageMode() === "file" || storageMode() === "disabled") return false;
|
|
66
|
+
return commandExists("/usr/bin/security");
|
|
67
|
+
}
|
|
68
|
+
async function preferredStorage() {
|
|
69
|
+
const mode = storageMode();
|
|
70
|
+
if (mode === "disabled") return "disabled";
|
|
71
|
+
if (mode === "file") return "file";
|
|
72
|
+
if (mode === "keychain") return await keychainAvailable() ? "keychain" : "file";
|
|
73
|
+
return await keychainAvailable() ? "keychain" : "file";
|
|
74
|
+
}
|
|
75
|
+
async function readKeychainToken(baseUrl) {
|
|
76
|
+
try {
|
|
77
|
+
const { stdout } = await execFileAsync("/usr/bin/security", [
|
|
78
|
+
"find-generic-password",
|
|
79
|
+
"-a",
|
|
80
|
+
accountForBaseUrl(baseUrl),
|
|
81
|
+
"-s",
|
|
82
|
+
KEYCHAIN_SERVICE,
|
|
83
|
+
"-w"
|
|
84
|
+
], { encoding: "utf8" });
|
|
85
|
+
return normalize(String(stdout)) ?? null;
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function writeKeychainToken(token, baseUrl) {
|
|
91
|
+
await execFileAsync("/usr/bin/security", [
|
|
92
|
+
"add-generic-password",
|
|
93
|
+
"-a",
|
|
94
|
+
accountForBaseUrl(baseUrl),
|
|
95
|
+
"-s",
|
|
96
|
+
KEYCHAIN_SERVICE,
|
|
97
|
+
"-w",
|
|
98
|
+
token,
|
|
99
|
+
"-U"
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
async function deleteKeychainToken(baseUrl) {
|
|
103
|
+
try {
|
|
104
|
+
await execFileAsync("/usr/bin/security", [
|
|
105
|
+
"delete-generic-password",
|
|
106
|
+
"-a",
|
|
107
|
+
accountForBaseUrl(baseUrl),
|
|
108
|
+
"-s",
|
|
109
|
+
KEYCHAIN_SERVICE
|
|
110
|
+
]);
|
|
111
|
+
return true;
|
|
112
|
+
} catch {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async function readFileToken(baseUrl) {
|
|
117
|
+
const path = tokenPath();
|
|
118
|
+
if (!(0, import_node_fs.existsSync)(path)) return null;
|
|
119
|
+
try {
|
|
120
|
+
const raw = await (0, import_promises.readFile)(path, "utf8");
|
|
121
|
+
const payload = JSON.parse(raw);
|
|
122
|
+
const token = normalize(payload.token);
|
|
123
|
+
const storedBaseUrl = normalize(payload.baseUrl);
|
|
124
|
+
const requestedBaseUrl = normalize(baseUrl);
|
|
125
|
+
if (!token) return null;
|
|
126
|
+
if (storedBaseUrl !== requestedBaseUrl) return null;
|
|
127
|
+
return token;
|
|
128
|
+
} catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async function writeFileToken(token, baseUrl) {
|
|
133
|
+
const home = authHome();
|
|
134
|
+
const path = tokenPath();
|
|
135
|
+
await (0, import_promises.mkdir)(home, { recursive: true, mode: 448 });
|
|
136
|
+
await (0, import_promises.writeFile)(
|
|
137
|
+
path,
|
|
138
|
+
`${JSON.stringify({ token, baseUrl: baseUrl ?? null, updatedAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
139
|
+
`,
|
|
140
|
+
{ mode: 384 }
|
|
141
|
+
);
|
|
142
|
+
await (0, import_promises.chmod)(path, 384);
|
|
143
|
+
}
|
|
144
|
+
async function deleteFileToken() {
|
|
145
|
+
const path = tokenPath();
|
|
146
|
+
if (!(0, import_node_fs.existsSync)(path)) return false;
|
|
147
|
+
await (0, import_promises.rm)(path, { force: true });
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
async function readStoredToken(baseUrl) {
|
|
151
|
+
const mode = await preferredStorage();
|
|
152
|
+
if (mode === "disabled") return null;
|
|
153
|
+
if (mode === "keychain") {
|
|
154
|
+
const keychainToken = await readKeychainToken(baseUrl);
|
|
155
|
+
if (keychainToken) return { token: keychainToken, source: "keychain" };
|
|
156
|
+
}
|
|
157
|
+
const fileToken = await readFileToken(baseUrl);
|
|
158
|
+
return fileToken ? { token: fileToken, source: "file" } : null;
|
|
159
|
+
}
|
|
160
|
+
async function writeStoredToken(token, baseUrl) {
|
|
161
|
+
const mode = await preferredStorage();
|
|
162
|
+
if (mode === "disabled") {
|
|
163
|
+
return { kind: "disabled", available: false };
|
|
164
|
+
}
|
|
165
|
+
if (mode === "keychain") {
|
|
166
|
+
try {
|
|
167
|
+
await writeKeychainToken(token, baseUrl);
|
|
168
|
+
return {
|
|
169
|
+
kind: "keychain",
|
|
170
|
+
available: true,
|
|
171
|
+
service: KEYCHAIN_SERVICE,
|
|
172
|
+
account: accountForBaseUrl(baseUrl)
|
|
173
|
+
};
|
|
174
|
+
} catch {
|
|
175
|
+
await writeFileToken(token, baseUrl);
|
|
176
|
+
return { kind: "file", available: true, path: tokenPath() };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
await writeFileToken(token, baseUrl);
|
|
180
|
+
return { kind: "file", available: true, path: tokenPath() };
|
|
181
|
+
}
|
|
182
|
+
async function persistBaseUrl(baseUrl) {
|
|
183
|
+
const path = configPath();
|
|
184
|
+
let existing = {};
|
|
185
|
+
if ((0, import_node_fs.existsSync)(path)) {
|
|
186
|
+
const raw = await (0, import_promises.readFile)(path, "utf8");
|
|
187
|
+
const parsed = JSON.parse(raw);
|
|
188
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
189
|
+
throw new Error(`Wave config file must contain a JSON object: ${path}`);
|
|
190
|
+
}
|
|
191
|
+
existing = parsed;
|
|
192
|
+
}
|
|
193
|
+
await (0, import_promises.mkdir)((0, import_node_path.dirname)(path), { recursive: true, mode: 448 });
|
|
194
|
+
await (0, import_promises.writeFile)(path, `${JSON.stringify({ ...existing, baseUrl }, null, 2)}
|
|
195
|
+
`, {
|
|
196
|
+
mode: 384
|
|
197
|
+
});
|
|
198
|
+
await (0, import_promises.chmod)(path, 384);
|
|
199
|
+
return path;
|
|
200
|
+
}
|
|
201
|
+
async function removeStoredToken(baseUrl) {
|
|
202
|
+
const removedKeychain = await deleteKeychainToken(baseUrl);
|
|
203
|
+
const removedFile = await deleteFileToken();
|
|
204
|
+
return removedKeychain || removedFile;
|
|
205
|
+
}
|
|
206
|
+
async function getAuthStorageInfo(baseUrl) {
|
|
207
|
+
const mode = await preferredStorage();
|
|
208
|
+
if (mode === "disabled") return { kind: "disabled", available: false };
|
|
209
|
+
if (mode === "keychain") {
|
|
210
|
+
return {
|
|
211
|
+
kind: "keychain",
|
|
212
|
+
available: true,
|
|
213
|
+
service: KEYCHAIN_SERVICE,
|
|
214
|
+
account: accountForBaseUrl(baseUrl)
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const path = tokenPath();
|
|
218
|
+
let available = true;
|
|
219
|
+
if ((0, import_node_fs.existsSync)(path)) {
|
|
220
|
+
try {
|
|
221
|
+
const modeBits = (await (0, import_promises.stat)(path)).mode & 511;
|
|
222
|
+
available = modeBits === 384;
|
|
223
|
+
} catch {
|
|
224
|
+
available = false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return { kind: "file", available, path };
|
|
228
|
+
}
|
|
229
|
+
|
|
11
230
|
// src/commands/tasks.ts
|
|
12
231
|
var import_zod3 = require("zod");
|
|
13
232
|
|
|
@@ -192,7 +411,7 @@ var ATLAS_LEDGER_VARIABLE_TYPES = {
|
|
|
192
411
|
};
|
|
193
412
|
var SECRET_KEY_PATTERN = /(authorization|password|passwd|secret|token|jwt|credential|api[_-]?key)/i;
|
|
194
413
|
var MAX_EVIDENCE_DEPTH = 5;
|
|
195
|
-
function
|
|
414
|
+
function normalize2(raw) {
|
|
196
415
|
if (typeof raw !== "string") {
|
|
197
416
|
return void 0;
|
|
198
417
|
}
|
|
@@ -200,12 +419,12 @@ function normalize(raw) {
|
|
|
200
419
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
201
420
|
}
|
|
202
421
|
function atlasContextFromConfig(config) {
|
|
203
|
-
const organizationId =
|
|
204
|
-
const memberId =
|
|
205
|
-
const chatId =
|
|
206
|
-
const assistantMessageId =
|
|
207
|
-
const activeTool =
|
|
208
|
-
const targetTool =
|
|
422
|
+
const organizationId = normalize2(config.organizationId);
|
|
423
|
+
const memberId = normalize2(config.atlasMemberId);
|
|
424
|
+
const chatId = normalize2(config.atlasChatId);
|
|
425
|
+
const assistantMessageId = normalize2(config.atlasAssistantMessageId);
|
|
426
|
+
const activeTool = normalize2(config.atlasActiveTool);
|
|
427
|
+
const targetTool = normalize2(config.atlasTargetTool);
|
|
209
428
|
if (!organizationId || !memberId || !chatId || !assistantMessageId || !activeTool || !targetTool) {
|
|
210
429
|
return null;
|
|
211
430
|
}
|
|
@@ -216,8 +435,8 @@ function atlasContextFromConfig(config) {
|
|
|
216
435
|
assistantMessageId,
|
|
217
436
|
activeTool,
|
|
218
437
|
targetTool,
|
|
219
|
-
routeReason:
|
|
220
|
-
actionId:
|
|
438
|
+
routeReason: normalize2(config.atlasRouteReason),
|
|
439
|
+
actionId: normalize2(config.atlasActionId)
|
|
221
440
|
};
|
|
222
441
|
}
|
|
223
442
|
function summarizeVariableShape(value, key = void 0, depth = 0) {
|
|
@@ -253,7 +472,7 @@ function shouldReportAtlasActionLedgerEvent(input) {
|
|
|
253
472
|
return input.operationType === "mutation" && input.field !== ATLAS_LEDGER_FIELD;
|
|
254
473
|
}
|
|
255
474
|
function deterministicAtlasActionId(input, config) {
|
|
256
|
-
const requestSegment =
|
|
475
|
+
const requestSegment = normalize2(config.requestId) ? `:${config.requestId}` : "";
|
|
257
476
|
return `cli:${input.command}:${input.field}${requestSegment}`;
|
|
258
477
|
}
|
|
259
478
|
function buildAtlasEvidenceRefs(params) {
|
|
@@ -584,118 +803,6 @@ function buildSparse422Diagnostic(input) {
|
|
|
584
803
|
}
|
|
585
804
|
};
|
|
586
805
|
}
|
|
587
|
-
function isFeedbackCreateCommand(input) {
|
|
588
|
-
return input.operationType === "mutation" && input.command === "feedbacks.create";
|
|
589
|
-
}
|
|
590
|
-
function asRecord(value) {
|
|
591
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
592
|
-
return null;
|
|
593
|
-
}
|
|
594
|
-
return value;
|
|
595
|
-
}
|
|
596
|
-
function asNonEmptyString(value) {
|
|
597
|
-
if (typeof value !== "string") {
|
|
598
|
-
return null;
|
|
599
|
-
}
|
|
600
|
-
const trimmed = value.trim();
|
|
601
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
602
|
-
}
|
|
603
|
-
function extractFeedbackIdentity(variables) {
|
|
604
|
-
const organizationId = asNonEmptyString(variables.organization_id) ?? asNonEmptyString(variables.organizationId);
|
|
605
|
-
const params = asRecord(variables.params);
|
|
606
|
-
const feedback = params ? asRecord(params.feedback) : null;
|
|
607
|
-
const name = feedback ? asNonEmptyString(feedback.name) : null;
|
|
608
|
-
const quarter = feedback ? asNonEmptyString(feedback.quarter) : null;
|
|
609
|
-
const year = feedback ? asNonEmptyString(feedback.year) : null;
|
|
610
|
-
if (!organizationId || !name || !quarter || !year) {
|
|
611
|
-
return null;
|
|
612
|
-
}
|
|
613
|
-
return {
|
|
614
|
-
organizationId,
|
|
615
|
-
name,
|
|
616
|
-
quarter,
|
|
617
|
-
year
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
function collectMessageStrings(value) {
|
|
621
|
-
if (typeof value === "string") {
|
|
622
|
-
return [value];
|
|
623
|
-
}
|
|
624
|
-
if (Array.isArray(value)) {
|
|
625
|
-
return value.flatMap((entry2) => collectMessageStrings(entry2));
|
|
626
|
-
}
|
|
627
|
-
if (!value || typeof value !== "object") {
|
|
628
|
-
return [];
|
|
629
|
-
}
|
|
630
|
-
return Object.values(value).flatMap(
|
|
631
|
-
(entry2) => collectMessageStrings(entry2)
|
|
632
|
-
);
|
|
633
|
-
}
|
|
634
|
-
function isDuplicateFeedbackMutationError(mutationPayload) {
|
|
635
|
-
const messages = collectMessageStrings(mutationPayload.errors);
|
|
636
|
-
return messages.some(
|
|
637
|
-
(message) => message.toLowerCase().includes("already been taken")
|
|
638
|
-
);
|
|
639
|
-
}
|
|
640
|
-
function extractFeedbackListNode(graph) {
|
|
641
|
-
const data = asRecord(graph.data);
|
|
642
|
-
const feedbacks = data ? asRecord(data.feedbacks) : null;
|
|
643
|
-
if (!feedbacks) {
|
|
644
|
-
return null;
|
|
645
|
-
}
|
|
646
|
-
const rows = Array.isArray(feedbacks.data) ? feedbacks.data : [];
|
|
647
|
-
const first = rows.find((entry2) => asRecord(entry2));
|
|
648
|
-
return first ? first : null;
|
|
649
|
-
}
|
|
650
|
-
function buildFeedbackReuseEnvelope(params) {
|
|
651
|
-
return {
|
|
652
|
-
envelope: buildEnvelope({
|
|
653
|
-
ok: true,
|
|
654
|
-
command: params.command,
|
|
655
|
-
status: params.status,
|
|
656
|
-
data: {
|
|
657
|
-
[params.field]: {
|
|
658
|
-
ok: true,
|
|
659
|
-
status: params.status,
|
|
660
|
-
errorCode: null,
|
|
661
|
-
data: {
|
|
662
|
-
data: params.feedbackNode
|
|
663
|
-
},
|
|
664
|
-
errors: null,
|
|
665
|
-
reusedExisting: true,
|
|
666
|
-
idempotency: {
|
|
667
|
-
reason: params.reason
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
},
|
|
671
|
-
error: null,
|
|
672
|
-
requestId: params.requestId
|
|
673
|
-
}),
|
|
674
|
-
exitCode: EXIT_CODES.success
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
function buildFeedbackFindRequestBody(command, identity) {
|
|
678
|
-
return buildGraphqlBody({
|
|
679
|
-
config: {
|
|
680
|
-
baseUrl: "http://localhost",
|
|
681
|
-
token: "placeholder",
|
|
682
|
-
timeoutMs: 1e3,
|
|
683
|
-
debug: false
|
|
684
|
-
},
|
|
685
|
-
command,
|
|
686
|
-
operationType: "query",
|
|
687
|
-
field: "feedbacks",
|
|
688
|
-
variables: {
|
|
689
|
-
organization_id: identity.organizationId,
|
|
690
|
-
name: identity.name,
|
|
691
|
-
quarter: identity.quarter,
|
|
692
|
-
year: identity.year,
|
|
693
|
-
page: 1,
|
|
694
|
-
per: 1
|
|
695
|
-
},
|
|
696
|
-
selectionSet: "{ data { id type attributes { id name slug year quarter organizationId memberIds } } count currentPage totalPages }"
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
806
|
async function requestGraphqlHttp(params) {
|
|
700
807
|
const response = await fetch(params.url, {
|
|
701
808
|
method: "POST",
|
|
@@ -787,29 +894,6 @@ async function finalizeGraphqlResult(input, url, result) {
|
|
|
787
894
|
}
|
|
788
895
|
return result;
|
|
789
896
|
}
|
|
790
|
-
async function findExistingFeedback(params) {
|
|
791
|
-
const command = `${params.input.command}.find-existing`;
|
|
792
|
-
const body = buildFeedbackFindRequestBody(command, params.identity);
|
|
793
|
-
const http = await requestGraphqlHttp({
|
|
794
|
-
input: params.input,
|
|
795
|
-
url: params.url,
|
|
796
|
-
requestId: params.requestId,
|
|
797
|
-
body,
|
|
798
|
-
controller: params.controller
|
|
799
|
-
});
|
|
800
|
-
const gqlErrors = http.graph.errors;
|
|
801
|
-
if (Array.isArray(gqlErrors) && gqlErrors.length > 0) {
|
|
802
|
-
return null;
|
|
803
|
-
}
|
|
804
|
-
const feedbackNode = extractFeedbackListNode(http.graph);
|
|
805
|
-
if (!feedbackNode) {
|
|
806
|
-
return null;
|
|
807
|
-
}
|
|
808
|
-
return {
|
|
809
|
-
feedbackNode,
|
|
810
|
-
requestId: http.requestId
|
|
811
|
-
};
|
|
812
|
-
}
|
|
813
897
|
function graphqlTypeForValue(value) {
|
|
814
898
|
if (Array.isArray(value)) {
|
|
815
899
|
const firstNonNull = value.find((item) => item !== null && item !== void 0);
|
|
@@ -909,32 +993,6 @@ async function graphqlRequest(input) {
|
|
|
909
993
|
const controller = new AbortController();
|
|
910
994
|
const timeoutId = setTimeout(() => controller.abort(), input.config.timeoutMs);
|
|
911
995
|
try {
|
|
912
|
-
if (isFeedbackCreateCommand(input)) {
|
|
913
|
-
const feedbackIdentity = extractFeedbackIdentity(input.variables);
|
|
914
|
-
if (feedbackIdentity) {
|
|
915
|
-
const existing = await findExistingFeedback({
|
|
916
|
-
input,
|
|
917
|
-
url,
|
|
918
|
-
requestId,
|
|
919
|
-
controller,
|
|
920
|
-
identity: feedbackIdentity
|
|
921
|
-
});
|
|
922
|
-
if (existing) {
|
|
923
|
-
return finalizeGraphqlResult(
|
|
924
|
-
input,
|
|
925
|
-
url,
|
|
926
|
-
buildFeedbackReuseEnvelope({
|
|
927
|
-
command: input.command,
|
|
928
|
-
field: input.field,
|
|
929
|
-
status: 200,
|
|
930
|
-
requestId: existing.requestId,
|
|
931
|
-
feedbackNode: existing.feedbackNode,
|
|
932
|
-
reason: "preexisting"
|
|
933
|
-
})
|
|
934
|
-
);
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
996
|
const http = await requestGraphqlHttpWithRetry({
|
|
939
997
|
input,
|
|
940
998
|
url,
|
|
@@ -979,32 +1037,6 @@ async function graphqlRequest(input) {
|
|
|
979
1037
|
const ok = Boolean(mutationPayload.ok);
|
|
980
1038
|
const status = typeof mutationPayload.status === "number" ? mutationPayload.status : ok ? 200 : 400;
|
|
981
1039
|
if (!ok) {
|
|
982
|
-
if (isFeedbackCreateCommand(input) && isDuplicateFeedbackMutationError(mutationPayload)) {
|
|
983
|
-
const feedbackIdentity = extractFeedbackIdentity(input.variables);
|
|
984
|
-
if (feedbackIdentity) {
|
|
985
|
-
const existing = await findExistingFeedback({
|
|
986
|
-
input,
|
|
987
|
-
url,
|
|
988
|
-
requestId: responseRequestId,
|
|
989
|
-
controller,
|
|
990
|
-
identity: feedbackIdentity
|
|
991
|
-
});
|
|
992
|
-
if (existing) {
|
|
993
|
-
return finalizeGraphqlResult(
|
|
994
|
-
input,
|
|
995
|
-
url,
|
|
996
|
-
buildFeedbackReuseEnvelope({
|
|
997
|
-
command: input.command,
|
|
998
|
-
field: input.field,
|
|
999
|
-
status: 200,
|
|
1000
|
-
requestId: existing.requestId,
|
|
1001
|
-
feedbackNode: existing.feedbackNode,
|
|
1002
|
-
reason: "duplicate_race"
|
|
1003
|
-
})
|
|
1004
|
-
);
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
1040
|
const mutationErrors = mutationPayload.errors ?? null;
|
|
1009
1041
|
const details = {
|
|
1010
1042
|
errors: mutationErrors,
|
|
@@ -1094,7 +1126,7 @@ async function graphqlRequest(input) {
|
|
|
1094
1126
|
}
|
|
1095
1127
|
|
|
1096
1128
|
// src/output.ts
|
|
1097
|
-
var
|
|
1129
|
+
var import_node_fs2 = require("fs");
|
|
1098
1130
|
var RETRYABLE_WRITE_CODES = /* @__PURE__ */ new Set(["EAGAIN", "EINTR"]);
|
|
1099
1131
|
var RETRY_BACKOFF_MS = 1;
|
|
1100
1132
|
var EnvelopeEmittedSignal = class extends Error {
|
|
@@ -1113,7 +1145,7 @@ function writeStdoutFully(text) {
|
|
|
1113
1145
|
let offset = 0;
|
|
1114
1146
|
while (offset < buffer.length) {
|
|
1115
1147
|
try {
|
|
1116
|
-
const bytesWritten = (0,
|
|
1148
|
+
const bytesWritten = (0, import_node_fs2.writeSync)(fd, buffer, offset, buffer.length - offset);
|
|
1117
1149
|
if (bytesWritten <= 0) {
|
|
1118
1150
|
sleepBriefly(RETRY_BACKOFF_MS);
|
|
1119
1151
|
continue;
|
|
@@ -1460,14 +1492,6 @@ var RESOURCE_QUERY_FIELDS = {
|
|
|
1460
1492
|
"acceptedAnswerIds",
|
|
1461
1493
|
"labelIds"
|
|
1462
1494
|
],
|
|
1463
|
-
feedback: [
|
|
1464
|
-
"name",
|
|
1465
|
-
"slug",
|
|
1466
|
-
"year",
|
|
1467
|
-
"quarter",
|
|
1468
|
-
"organizationId",
|
|
1469
|
-
"memberIds"
|
|
1470
|
-
],
|
|
1471
1495
|
survey: [
|
|
1472
1496
|
"name",
|
|
1473
1497
|
"slug",
|
|
@@ -1629,7 +1653,6 @@ var RESOURCE_FIELD_ALIASES = {
|
|
|
1629
1653
|
stand_ups: "stand_up",
|
|
1630
1654
|
headlines: "headline",
|
|
1631
1655
|
questions: "question",
|
|
1632
|
-
feedbacks: "feedback",
|
|
1633
1656
|
surveys: "survey",
|
|
1634
1657
|
responsibilities: "responsibility",
|
|
1635
1658
|
smart_kpi_views: "smart_kpi_view",
|
|
@@ -1876,222 +1899,15 @@ async function runGraphqlMutationCommand(input) {
|
|
|
1876
1899
|
message
|
|
1877
1900
|
}),
|
|
1878
1901
|
exitCode: EXIT_CODES.generic
|
|
1879
|
-
});
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
|
-
// src/commands/runtimeOptions.ts
|
|
1884
|
-
var import_node_fs3 = require("fs");
|
|
1885
|
-
var import_promises2 = require("fs/promises");
|
|
1886
|
-
var import_node_path2 = require("path");
|
|
1887
|
-
|
|
1888
|
-
// src/authStorage.ts
|
|
1889
|
-
var import_node_child_process = require("child_process");
|
|
1890
|
-
var import_node_fs2 = require("fs");
|
|
1891
|
-
var import_promises = require("fs/promises");
|
|
1892
|
-
var import_node_os = require("os");
|
|
1893
|
-
var import_node_path = require("path");
|
|
1894
|
-
var import_node_util = require("util");
|
|
1895
|
-
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
1896
|
-
var KEYCHAIN_SERVICE = "wave-cli";
|
|
1897
|
-
var FILE_NAME = "auth-token.json";
|
|
1898
|
-
function normalize2(raw) {
|
|
1899
|
-
if (typeof raw !== "string") return void 0;
|
|
1900
|
-
const trimmed = raw.trim();
|
|
1901
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
1902
|
-
}
|
|
1903
|
-
function authHome(env = process.env) {
|
|
1904
|
-
return normalize2(env.WAVE_CLI_HOME) ?? (0, import_node_path.join)((0, import_node_os.homedir)(), ".wave");
|
|
1905
|
-
}
|
|
1906
|
-
function tokenPath(env = process.env) {
|
|
1907
|
-
return (0, import_node_path.join)(authHome(env), FILE_NAME);
|
|
1908
|
-
}
|
|
1909
|
-
function configPath(env = process.env) {
|
|
1910
|
-
return normalize2(env.WAVE_CONFIG_PATH) ?? (0, import_node_path.join)(authHome(env), "config.json");
|
|
1911
|
-
}
|
|
1912
|
-
function storageMode(env = process.env) {
|
|
1913
|
-
const raw = normalize2(env.WAVE_CLI_AUTH_STORAGE)?.toLowerCase();
|
|
1914
|
-
if (raw === "keychain" || raw === "file" || raw === "disabled") return raw;
|
|
1915
|
-
return "auto";
|
|
1916
|
-
}
|
|
1917
|
-
function accountForBaseUrl(baseUrl) {
|
|
1918
|
-
return normalize2(baseUrl) ?? "default";
|
|
1919
|
-
}
|
|
1920
|
-
async function commandExists(command) {
|
|
1921
|
-
try {
|
|
1922
|
-
await (0, import_promises.access)(command, import_node_fs2.constants.X_OK);
|
|
1923
|
-
return true;
|
|
1924
|
-
} catch {
|
|
1925
|
-
return false;
|
|
1926
|
-
}
|
|
1927
|
-
}
|
|
1928
|
-
async function keychainAvailable(env = process.env) {
|
|
1929
|
-
if (process.platform !== "darwin") return false;
|
|
1930
|
-
if (storageMode(env) === "file" || storageMode(env) === "disabled") return false;
|
|
1931
|
-
return commandExists("/usr/bin/security");
|
|
1932
|
-
}
|
|
1933
|
-
async function preferredStorage(env = process.env) {
|
|
1934
|
-
const mode = storageMode(env);
|
|
1935
|
-
if (mode === "disabled") return "disabled";
|
|
1936
|
-
if (mode === "file") return "file";
|
|
1937
|
-
if (mode === "keychain") return await keychainAvailable(env) ? "keychain" : "file";
|
|
1938
|
-
return await keychainAvailable(env) ? "keychain" : "file";
|
|
1939
|
-
}
|
|
1940
|
-
async function readKeychainToken(baseUrl) {
|
|
1941
|
-
try {
|
|
1942
|
-
const { stdout } = await execFileAsync("/usr/bin/security", [
|
|
1943
|
-
"find-generic-password",
|
|
1944
|
-
"-a",
|
|
1945
|
-
accountForBaseUrl(baseUrl),
|
|
1946
|
-
"-s",
|
|
1947
|
-
KEYCHAIN_SERVICE,
|
|
1948
|
-
"-w"
|
|
1949
|
-
], { encoding: "utf8" });
|
|
1950
|
-
return normalize2(String(stdout)) ?? null;
|
|
1951
|
-
} catch {
|
|
1952
|
-
return null;
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
async function writeKeychainToken(token, baseUrl) {
|
|
1956
|
-
await execFileAsync("/usr/bin/security", [
|
|
1957
|
-
"add-generic-password",
|
|
1958
|
-
"-a",
|
|
1959
|
-
accountForBaseUrl(baseUrl),
|
|
1960
|
-
"-s",
|
|
1961
|
-
KEYCHAIN_SERVICE,
|
|
1962
|
-
"-w",
|
|
1963
|
-
token,
|
|
1964
|
-
"-U"
|
|
1965
|
-
]);
|
|
1966
|
-
}
|
|
1967
|
-
async function deleteKeychainToken(baseUrl) {
|
|
1968
|
-
try {
|
|
1969
|
-
await execFileAsync("/usr/bin/security", [
|
|
1970
|
-
"delete-generic-password",
|
|
1971
|
-
"-a",
|
|
1972
|
-
accountForBaseUrl(baseUrl),
|
|
1973
|
-
"-s",
|
|
1974
|
-
KEYCHAIN_SERVICE
|
|
1975
|
-
]);
|
|
1976
|
-
return true;
|
|
1977
|
-
} catch {
|
|
1978
|
-
return false;
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
async function readFileToken(baseUrl, env = process.env) {
|
|
1982
|
-
const path = tokenPath(env);
|
|
1983
|
-
if (!(0, import_node_fs2.existsSync)(path)) return null;
|
|
1984
|
-
try {
|
|
1985
|
-
const raw = await (0, import_promises.readFile)(path, "utf8");
|
|
1986
|
-
const payload = JSON.parse(raw);
|
|
1987
|
-
const token = normalize2(payload.token);
|
|
1988
|
-
const storedBaseUrl = normalize2(payload.baseUrl);
|
|
1989
|
-
const requestedBaseUrl = normalize2(baseUrl);
|
|
1990
|
-
if (!token) return null;
|
|
1991
|
-
if (storedBaseUrl !== requestedBaseUrl) return null;
|
|
1992
|
-
return token;
|
|
1993
|
-
} catch {
|
|
1994
|
-
return null;
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
async function writeFileToken(token, baseUrl, env = process.env) {
|
|
1998
|
-
const home = authHome(env);
|
|
1999
|
-
const path = tokenPath(env);
|
|
2000
|
-
await (0, import_promises.mkdir)(home, { recursive: true, mode: 448 });
|
|
2001
|
-
await (0, import_promises.writeFile)(
|
|
2002
|
-
path,
|
|
2003
|
-
`${JSON.stringify({ token, baseUrl: baseUrl ?? null, updatedAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
2004
|
-
`,
|
|
2005
|
-
{ mode: 384 }
|
|
2006
|
-
);
|
|
2007
|
-
await (0, import_promises.chmod)(path, 384);
|
|
2008
|
-
}
|
|
2009
|
-
async function deleteFileToken(env = process.env) {
|
|
2010
|
-
const path = tokenPath(env);
|
|
2011
|
-
if (!(0, import_node_fs2.existsSync)(path)) return false;
|
|
2012
|
-
await (0, import_promises.rm)(path, { force: true });
|
|
2013
|
-
return true;
|
|
2014
|
-
}
|
|
2015
|
-
async function readStoredToken(baseUrl) {
|
|
2016
|
-
const mode = await preferredStorage();
|
|
2017
|
-
if (mode === "disabled") return null;
|
|
2018
|
-
if (mode === "keychain") {
|
|
2019
|
-
const keychainToken = await readKeychainToken(baseUrl);
|
|
2020
|
-
if (keychainToken) return { token: keychainToken, source: "keychain" };
|
|
2021
|
-
}
|
|
2022
|
-
const fileToken = await readFileToken(baseUrl);
|
|
2023
|
-
return fileToken ? { token: fileToken, source: "file" } : null;
|
|
2024
|
-
}
|
|
2025
|
-
async function writeStoredToken(token, baseUrl) {
|
|
2026
|
-
const mode = await preferredStorage();
|
|
2027
|
-
if (mode === "disabled") {
|
|
2028
|
-
return { kind: "disabled", available: false };
|
|
2029
|
-
}
|
|
2030
|
-
if (mode === "keychain") {
|
|
2031
|
-
try {
|
|
2032
|
-
await writeKeychainToken(token, baseUrl);
|
|
2033
|
-
return {
|
|
2034
|
-
kind: "keychain",
|
|
2035
|
-
available: true,
|
|
2036
|
-
service: KEYCHAIN_SERVICE,
|
|
2037
|
-
account: accountForBaseUrl(baseUrl)
|
|
2038
|
-
};
|
|
2039
|
-
} catch {
|
|
2040
|
-
await writeFileToken(token, baseUrl);
|
|
2041
|
-
return { kind: "file", available: true, path: tokenPath() };
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
await writeFileToken(token, baseUrl);
|
|
2045
|
-
return { kind: "file", available: true, path: tokenPath() };
|
|
2046
|
-
}
|
|
2047
|
-
async function persistBaseUrl(baseUrl, env = process.env) {
|
|
2048
|
-
const path = configPath(env);
|
|
2049
|
-
let existing = {};
|
|
2050
|
-
if ((0, import_node_fs2.existsSync)(path)) {
|
|
2051
|
-
const raw = await (0, import_promises.readFile)(path, "utf8");
|
|
2052
|
-
const parsed = JSON.parse(raw);
|
|
2053
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2054
|
-
throw new Error(`Wave config file must contain a JSON object: ${path}`);
|
|
2055
|
-
}
|
|
2056
|
-
existing = parsed;
|
|
2057
|
-
}
|
|
2058
|
-
await (0, import_promises.mkdir)((0, import_node_path.dirname)(path), { recursive: true, mode: 448 });
|
|
2059
|
-
await (0, import_promises.writeFile)(path, `${JSON.stringify({ ...existing, baseUrl }, null, 2)}
|
|
2060
|
-
`, {
|
|
2061
|
-
mode: 384
|
|
2062
|
-
});
|
|
2063
|
-
await (0, import_promises.chmod)(path, 384);
|
|
2064
|
-
return path;
|
|
2065
|
-
}
|
|
2066
|
-
async function removeStoredToken(baseUrl) {
|
|
2067
|
-
const removedKeychain = await deleteKeychainToken(baseUrl);
|
|
2068
|
-
const removedFile = await deleteFileToken();
|
|
2069
|
-
return removedKeychain || removedFile;
|
|
2070
|
-
}
|
|
2071
|
-
async function getAuthStorageInfo(baseUrl) {
|
|
2072
|
-
const mode = await preferredStorage();
|
|
2073
|
-
if (mode === "disabled") return { kind: "disabled", available: false };
|
|
2074
|
-
if (mode === "keychain") {
|
|
2075
|
-
return {
|
|
2076
|
-
kind: "keychain",
|
|
2077
|
-
available: true,
|
|
2078
|
-
service: KEYCHAIN_SERVICE,
|
|
2079
|
-
account: accountForBaseUrl(baseUrl)
|
|
2080
|
-
};
|
|
2081
|
-
}
|
|
2082
|
-
const path = tokenPath();
|
|
2083
|
-
let available = true;
|
|
2084
|
-
if ((0, import_node_fs2.existsSync)(path)) {
|
|
2085
|
-
try {
|
|
2086
|
-
const modeBits = (await (0, import_promises.stat)(path)).mode & 511;
|
|
2087
|
-
available = modeBits === 384;
|
|
2088
|
-
} catch {
|
|
2089
|
-
available = false;
|
|
2090
|
-
}
|
|
1902
|
+
});
|
|
2091
1903
|
}
|
|
2092
|
-
return { kind: "file", available, path };
|
|
2093
1904
|
}
|
|
2094
1905
|
|
|
1906
|
+
// src/commands/runtimeOptions.ts
|
|
1907
|
+
var import_node_fs3 = require("fs");
|
|
1908
|
+
var import_promises2 = require("fs/promises");
|
|
1909
|
+
var import_node_path2 = require("path");
|
|
1910
|
+
|
|
2095
1911
|
// src/authClient.ts
|
|
2096
1912
|
var import_node_crypto2 = require("crypto");
|
|
2097
1913
|
|
|
@@ -2538,17 +2354,15 @@ async function resolveWithAuthenticatedOrganization(context) {
|
|
|
2538
2354
|
if (organizationId) resolved.organizationId = organizationId;
|
|
2539
2355
|
return resolved;
|
|
2540
2356
|
}
|
|
2541
|
-
function defaultConfigPath(
|
|
2542
|
-
const
|
|
2543
|
-
if (explicitEnv) return explicitEnv;
|
|
2544
|
-
const candidate = (0, import_node_path2.join)(authHome(env), "config.json");
|
|
2357
|
+
function defaultConfigPath() {
|
|
2358
|
+
const candidate = (0, import_node_path2.join)(authHome(), "config.json");
|
|
2545
2359
|
return (0, import_node_fs3.existsSync)(candidate) ? candidate : void 0;
|
|
2546
2360
|
}
|
|
2547
2361
|
async function resolveConfigFileContext(options, env) {
|
|
2548
2362
|
const path = firstDefined(
|
|
2549
2363
|
normalize3(options.configPath),
|
|
2550
2364
|
normalize3(options.config),
|
|
2551
|
-
defaultConfigPath(
|
|
2365
|
+
defaultConfigPath()
|
|
2552
2366
|
);
|
|
2553
2367
|
if (!path) return {};
|
|
2554
2368
|
if (!(0, import_node_fs3.existsSync)(path)) {
|
|
@@ -2693,13 +2507,13 @@ function parseRequiredOption(raw, flag) {
|
|
|
2693
2507
|
function optionKey(flag) {
|
|
2694
2508
|
return flag.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
2695
2509
|
}
|
|
2696
|
-
function
|
|
2510
|
+
function asRecord(value) {
|
|
2697
2511
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
2698
2512
|
}
|
|
2699
2513
|
function visibleSearchText(row) {
|
|
2700
|
-
const record =
|
|
2514
|
+
const record = asRecord(row);
|
|
2701
2515
|
if (!record) return "";
|
|
2702
|
-
const attributes =
|
|
2516
|
+
const attributes = asRecord(record.attributes);
|
|
2703
2517
|
const values = [];
|
|
2704
2518
|
for (const field of SEARCHABLE_VISIBLE_FIELDS) {
|
|
2705
2519
|
const topLevelValue = record[field];
|
|
@@ -2713,7 +2527,7 @@ function matchesSearchQuery(row, query) {
|
|
|
2713
2527
|
return visibleSearchText(row).includes(query.toLowerCase());
|
|
2714
2528
|
}
|
|
2715
2529
|
function filterListEnvelopeByQuery(payload, query) {
|
|
2716
|
-
const record =
|
|
2530
|
+
const record = asRecord(payload);
|
|
2717
2531
|
if (!record || !Array.isArray(record.data)) return payload;
|
|
2718
2532
|
const filteredData = record.data.filter((row) => matchesSearchQuery(row, query));
|
|
2719
2533
|
return {
|
|
@@ -3640,9 +3454,65 @@ var subitemUpdateContract = {
|
|
|
3640
3454
|
rootKey: "subitem",
|
|
3641
3455
|
fields: subitemFields
|
|
3642
3456
|
};
|
|
3457
|
+
var reminderFields = {
|
|
3458
|
+
title: { type: "string", example: "Follow up with customer" },
|
|
3459
|
+
description: { type: "string" },
|
|
3460
|
+
due_at: { type: "string" },
|
|
3461
|
+
starts_at: { type: "string" },
|
|
3462
|
+
timezone: { type: "string", example: "America/Phoenix" },
|
|
3463
|
+
schedule: {
|
|
3464
|
+
type: "object",
|
|
3465
|
+
example: { type: "once", due_at: "2026-09-01T09:00:00-07:00" }
|
|
3466
|
+
},
|
|
3467
|
+
notification: {
|
|
3468
|
+
type: "object",
|
|
3469
|
+
example: { channels: ["in_app"], lead_minutes: 15 }
|
|
3470
|
+
},
|
|
3471
|
+
resources_attributes: { type: "array" },
|
|
3472
|
+
reminder_delegates_attributes: { type: "array" }
|
|
3473
|
+
};
|
|
3474
|
+
var reminderCreateContract = {
|
|
3475
|
+
rootKey: "reminder",
|
|
3476
|
+
fields: reminderFields,
|
|
3477
|
+
required: ["title", "schedule", "notification"],
|
|
3478
|
+
additionalProperties: false
|
|
3479
|
+
};
|
|
3480
|
+
var reminderUpdateContract = {
|
|
3481
|
+
rootKey: "reminder",
|
|
3482
|
+
fields: reminderFields,
|
|
3483
|
+
additionalProperties: false
|
|
3484
|
+
};
|
|
3485
|
+
var sketchFields = {
|
|
3486
|
+
name: { type: "string" },
|
|
3487
|
+
creation_key: { type: "string" },
|
|
3488
|
+
member_id: { type: "string" },
|
|
3489
|
+
teams_ids: { type: "array", items: { type: "string" } },
|
|
3490
|
+
status: {
|
|
3491
|
+
type: "string",
|
|
3492
|
+
enum: ["backlog", "planned", "in_progress", "completed", "cancelled", "ready_for_qa", "blocked"]
|
|
3493
|
+
},
|
|
3494
|
+
priority: { type: "string", enum: PRIORITIES }
|
|
3495
|
+
};
|
|
3496
|
+
var sketchCreateContract = {
|
|
3497
|
+
rootKey: "sketch",
|
|
3498
|
+
fields: sketchFields,
|
|
3499
|
+
required: ["name", "teams_ids", "creation_key"],
|
|
3500
|
+
additionalProperties: false
|
|
3501
|
+
};
|
|
3502
|
+
var sketchMetadataUpdateContract = {
|
|
3503
|
+
rootKey: "sketch",
|
|
3504
|
+
fields: Object.fromEntries(
|
|
3505
|
+
Object.entries(sketchFields).filter(([field]) => field !== "creation_key")
|
|
3506
|
+
),
|
|
3507
|
+
additionalProperties: false
|
|
3508
|
+
};
|
|
3643
3509
|
var CONTRACTS = {
|
|
3644
3510
|
"list-items.create": listItemCreateContract,
|
|
3645
3511
|
"list-items.update": listItemUpdateContract,
|
|
3512
|
+
"reminders.create": reminderCreateContract,
|
|
3513
|
+
"reminders.update": reminderUpdateContract,
|
|
3514
|
+
"sketches.create": sketchCreateContract,
|
|
3515
|
+
"sketches.update-metadata": sketchMetadataUpdateContract,
|
|
3646
3516
|
"subitems.create": subitemCreateContract,
|
|
3647
3517
|
"subitems.update": subitemUpdateContract
|
|
3648
3518
|
};
|
|
@@ -3714,8 +3584,10 @@ function validateOperationDataJson(operationId2, value) {
|
|
|
3714
3584
|
const missing = (contract.required ?? []).filter(
|
|
3715
3585
|
(field) => entity[field] === void 0 || entity[field] === null || entity[field] === ""
|
|
3716
3586
|
);
|
|
3587
|
+
const unsupported = contract.additionalProperties === false ? Object.keys(entity).filter((field) => !Object.prototype.hasOwnProperty.call(contract.fields, field)) : [];
|
|
3717
3588
|
return [
|
|
3718
3589
|
...missing.map((field) => `${contract.rootKey}.${field} is required.`),
|
|
3590
|
+
...unsupported.map((field) => `${contract.rootKey}.${field} is not permitted.`),
|
|
3719
3591
|
...validateFields(contract.fields, entity, [contract.rootKey])
|
|
3720
3592
|
].map(
|
|
3721
3593
|
(error) => `Invalid input value for dataJson: ${error}`
|
|
@@ -3759,14 +3631,25 @@ function entitySchema(contract) {
|
|
|
3759
3631
|
])
|
|
3760
3632
|
),
|
|
3761
3633
|
...contract.required ? { required: [...contract.required] } : {},
|
|
3762
|
-
additionalProperties: true
|
|
3634
|
+
additionalProperties: contract.additionalProperties ?? true
|
|
3763
3635
|
};
|
|
3764
3636
|
}
|
|
3637
|
+
function exampleValue2(contract) {
|
|
3638
|
+
if (contract.example !== void 0) return contract.example;
|
|
3639
|
+
if (contract.type === "array") return [];
|
|
3640
|
+
if (contract.type === "object") return {};
|
|
3641
|
+
if (contract.type === "number") return 0;
|
|
3642
|
+
if (contract.type === "boolean") return false;
|
|
3643
|
+
return "example";
|
|
3644
|
+
}
|
|
3765
3645
|
function exampleDataJsonForOperation(operationId2) {
|
|
3766
3646
|
const contract = CONTRACTS[operationId2];
|
|
3767
3647
|
if (!contract) return null;
|
|
3768
3648
|
const entity = Object.fromEntries(
|
|
3769
|
-
(contract.required ?? []).map((field) =>
|
|
3649
|
+
(contract.required ?? []).map((field) => {
|
|
3650
|
+
const fieldContract = contract.fields[field];
|
|
3651
|
+
return [field, fieldContract ? exampleValue2(fieldContract) : "example"];
|
|
3652
|
+
})
|
|
3770
3653
|
);
|
|
3771
3654
|
return { [contract.rootKey]: entity };
|
|
3772
3655
|
}
|
|
@@ -3872,7 +3755,7 @@ function registerEntityCrudCommands(program, config) {
|
|
|
3872
3755
|
const entityCommand = program.command(config.command).description(config.description);
|
|
3873
3756
|
const createHelp4 = buildDataJsonHelp(config.rootKey, "create") ?? "JSON object, optionally wrapped with root key";
|
|
3874
3757
|
const updateHelp5 = buildDataJsonHelp(config.rootKey, "update") ?? "JSON object, optionally wrapped with root key";
|
|
3875
|
-
const listField2 = config.listField ??
|
|
3758
|
+
const listField2 = config.listField ?? config.resourcePath;
|
|
3876
3759
|
const list = entityCommand.command("list").option("--page <page>").option("--per <per>");
|
|
3877
3760
|
const listParams = config.listParams ?? [];
|
|
3878
3761
|
const listParamHelp = config.listParamHelp ?? {};
|
|
@@ -3912,12 +3795,14 @@ function registerEntityCrudCommands(program, config) {
|
|
|
3912
3795
|
isList: true
|
|
3913
3796
|
});
|
|
3914
3797
|
});
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3798
|
+
if (config.registerSearch !== false) {
|
|
3799
|
+
registerGraphqlSearchCommand(entityCommand, {
|
|
3800
|
+
command: config.command,
|
|
3801
|
+
field: listField2,
|
|
3802
|
+
variableTypes: config.listVariableTypes,
|
|
3803
|
+
selectionSet: config.listSelectionSet
|
|
3804
|
+
});
|
|
3805
|
+
}
|
|
3921
3806
|
const show = entityCommand.command("show").requiredOption("--id <id>");
|
|
3922
3807
|
showParams.forEach((param) => {
|
|
3923
3808
|
const cliParam = param.replace(/_/g, "-");
|
|
@@ -3928,7 +3813,7 @@ function registerEntityCrudCommands(program, config) {
|
|
|
3928
3813
|
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
3929
3814
|
const organizationId = resolveOrganizationId(context.organizationId);
|
|
3930
3815
|
const defaultCommand = `${config.command}.show`;
|
|
3931
|
-
const defaultField = config.showField ??
|
|
3816
|
+
const defaultField = config.showField ?? toSingularResourceName(config.resourcePath);
|
|
3932
3817
|
const mappedShowParams = Object.fromEntries(
|
|
3933
3818
|
showParams.map((param) => {
|
|
3934
3819
|
const optionKey2 = param.replace(/_([a-z])/g, (_, char) => char.toUpperCase());
|
|
@@ -4012,6 +3897,22 @@ function registerEntityCrudCommands(program, config) {
|
|
|
4012
3897
|
}
|
|
4013
3898
|
});
|
|
4014
3899
|
});
|
|
3900
|
+
for (const mutation of config.idMutationCommands ?? []) {
|
|
3901
|
+
entityCommand.command(mutation.command).description(mutation.description).requiredOption("--id <id>").action(async (opts, cmd) => {
|
|
3902
|
+
const id = idSchema2.parse(opts.id);
|
|
3903
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
3904
|
+
const organizationId = resolveOrganizationId(context.organizationId);
|
|
3905
|
+
await runGraphqlMutationCommand({
|
|
3906
|
+
command: `${config.command}.${mutation.command}`,
|
|
3907
|
+
runtimeOptions: context.runtimeOptions,
|
|
3908
|
+
field: mutation.field,
|
|
3909
|
+
variables: {
|
|
3910
|
+
organization_id: organizationId,
|
|
3911
|
+
[mutation.idVariable]: id
|
|
3912
|
+
}
|
|
3913
|
+
});
|
|
3914
|
+
});
|
|
3915
|
+
}
|
|
4015
3916
|
}
|
|
4016
3917
|
var __testables = {
|
|
4017
3918
|
toSingularResourceName,
|
|
@@ -4048,7 +3949,7 @@ var displayPreferenceAttributesSelectionSet = "attributes { id viewType favorite
|
|
|
4048
3949
|
var filterPreferenceAttributesSelectionSet = "attributes { id filterType filter memberId focusMemberId focusTeamId filterableId filterableType preferenceType agendaItemId }";
|
|
4049
3950
|
var healthUpdateSummarySelectionSet = "id type value memberId status createdAt updatedAt updatableType updatableId parentUpdateId emojis { id name memberId } resources { ...ResourceSummaryFull }";
|
|
4050
3951
|
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 } }`;
|
|
4051
|
-
function
|
|
3952
|
+
function asRecord2(value) {
|
|
4052
3953
|
return value && typeof value === "object" ? value : null;
|
|
4053
3954
|
}
|
|
4054
3955
|
function toNonEmptyString(value) {
|
|
@@ -4081,9 +3982,9 @@ function parseProjectPriority(value) {
|
|
|
4081
3982
|
return parsed.data.toUpperCase();
|
|
4082
3983
|
}
|
|
4083
3984
|
function normalizeProjectRowForDisplay(row) {
|
|
4084
|
-
const record =
|
|
3985
|
+
const record = asRecord2(row);
|
|
4085
3986
|
if (!record) return row;
|
|
4086
|
-
const attributes =
|
|
3987
|
+
const attributes = asRecord2(record.attributes);
|
|
4087
3988
|
const topLevelName = toNonEmptyString(record.name);
|
|
4088
3989
|
const topLevelTitle = toNonEmptyString(record.title);
|
|
4089
3990
|
const attributeName = toNonEmptyString(attributes?.name);
|
|
@@ -4098,7 +3999,7 @@ function normalizeProjectRowForDisplay(row) {
|
|
|
4098
3999
|
};
|
|
4099
4000
|
}
|
|
4100
4001
|
function normalizeProjectsListForDisplay(payload) {
|
|
4101
|
-
const record =
|
|
4002
|
+
const record = asRecord2(payload);
|
|
4102
4003
|
if (!record || !Array.isArray(record.data)) return payload;
|
|
4103
4004
|
return {
|
|
4104
4005
|
...record,
|
|
@@ -4316,7 +4217,7 @@ var MEETING_STATUSES = /* @__PURE__ */ new Set(["upcoming", "active", "completed
|
|
|
4316
4217
|
var MEETING_REPEATS = /* @__PURE__ */ new Set(["never", "weekly", "biweekly", "monthly", "quarterly"]);
|
|
4317
4218
|
var createHelp2 = buildDataJsonHelp("meeting", "create") ?? 'JSON object for meeting or {"meeting": {...}}';
|
|
4318
4219
|
var updateHelp2 = buildDataJsonHelp("meeting", "update") ?? 'JSON object for meeting or {"meeting": {...}}';
|
|
4319
|
-
function
|
|
4220
|
+
function asNonEmptyString(value) {
|
|
4320
4221
|
if (typeof value !== "string") {
|
|
4321
4222
|
return void 0;
|
|
4322
4223
|
}
|
|
@@ -4374,7 +4275,7 @@ function normalizeMeetingCreateBody(body) {
|
|
|
4374
4275
|
});
|
|
4375
4276
|
}
|
|
4376
4277
|
const meeting = { ...entity };
|
|
4377
|
-
const type =
|
|
4278
|
+
const type = asNonEmptyString(meeting.type);
|
|
4378
4279
|
if (!type || !MEETING_TYPES.has(type)) {
|
|
4379
4280
|
throw new CliError({
|
|
4380
4281
|
message: "Invalid meeting.type. Use one of: TeamMeeting, OneOnOneMeeting.",
|
|
@@ -4384,8 +4285,8 @@ function normalizeMeetingCreateBody(body) {
|
|
|
4384
4285
|
details: { field: "meeting.type", allowed: Array.from(MEETING_TYPES) }
|
|
4385
4286
|
});
|
|
4386
4287
|
}
|
|
4387
|
-
const memberId =
|
|
4388
|
-
const date =
|
|
4288
|
+
const memberId = asNonEmptyString(meeting.member_id);
|
|
4289
|
+
const date = asNonEmptyString(meeting.date);
|
|
4389
4290
|
const startTime = toFiniteNumber(meeting.start_time, "meeting.start_time");
|
|
4390
4291
|
const missingRequired = [];
|
|
4391
4292
|
if (!memberId) missingRequired.push("member_id");
|
|
@@ -4400,7 +4301,7 @@ function normalizeMeetingCreateBody(body) {
|
|
|
4400
4301
|
details: { requiredFields: ["member_id", "date", "start_time"], rootKey: "meeting" }
|
|
4401
4302
|
});
|
|
4402
4303
|
}
|
|
4403
|
-
const status =
|
|
4304
|
+
const status = asNonEmptyString(meeting.status);
|
|
4404
4305
|
if (status && !MEETING_STATUSES.has(status)) {
|
|
4405
4306
|
throw new CliError({
|
|
4406
4307
|
message: "Invalid meeting.status. Use one of: upcoming, active, completed.",
|
|
@@ -4410,7 +4311,7 @@ function normalizeMeetingCreateBody(body) {
|
|
|
4410
4311
|
details: { field: "meeting.status", allowed: Array.from(MEETING_STATUSES) }
|
|
4411
4312
|
});
|
|
4412
4313
|
}
|
|
4413
|
-
const repeats =
|
|
4314
|
+
const repeats = asNonEmptyString(meeting.repeats) ?? "never";
|
|
4414
4315
|
if (!MEETING_REPEATS.has(repeats)) {
|
|
4415
4316
|
throw new CliError({
|
|
4416
4317
|
message: "Invalid meeting.repeats. Use one of: never, weekly, biweekly, monthly, quarterly.",
|
|
@@ -5139,13 +5040,35 @@ var SMART_KPI_NAMES = [
|
|
|
5139
5040
|
var SMART_KPI_NAME_SET = new Set(SMART_KPI_NAMES);
|
|
5140
5041
|
|
|
5141
5042
|
// src/commands/systemTools.ts
|
|
5043
|
+
var REMINDER_ATTRIBUTES_SELECTION = `
|
|
5044
|
+
id
|
|
5045
|
+
organizationId
|
|
5046
|
+
creatorId
|
|
5047
|
+
title
|
|
5048
|
+
description
|
|
5049
|
+
dueAt
|
|
5050
|
+
startsAt
|
|
5051
|
+
timezone
|
|
5052
|
+
schedule
|
|
5053
|
+
notification
|
|
5054
|
+
status
|
|
5055
|
+
nextTriggerAt
|
|
5056
|
+
lastTriggeredAt
|
|
5057
|
+
clearedAt
|
|
5058
|
+
reminderDelegates { id memberId organizationId }
|
|
5059
|
+
delegateMembers { id email firstName lastName organizationId }
|
|
5060
|
+
resources { id resourceType url creatorId attachment { id fileKey filename } }
|
|
5061
|
+
createdAt
|
|
5062
|
+
updatedAt
|
|
5063
|
+
`;
|
|
5064
|
+
var REMINDER_LIST_SELECTION = `{ data { id type attributes { ${REMINDER_ATTRIBUTES_SELECTION} } } count currentPage totalPages }`;
|
|
5065
|
+
var REMINDER_SHOW_SELECTION = `{ id type attributes { ${REMINDER_ATTRIBUTES_SELECTION} } }`;
|
|
5142
5066
|
var TODO_STATUSES = /* @__PURE__ */ new Set(["open", "completed"]);
|
|
5143
5067
|
var KNOWLEDGE_CONTENT_TYPES = /* @__PURE__ */ new Set(["company", "policy", "process"]);
|
|
5144
5068
|
var KNOWLEDGE_STATUSES = /* @__PURE__ */ new Set(["draft", "published"]);
|
|
5145
5069
|
var NEWS_STATUSES = /* @__PURE__ */ new Set(["active", "completed"]);
|
|
5146
5070
|
var NEWS_HEADLINE_TYPES = /* @__PURE__ */ new Set(["team", "org_wide"]);
|
|
5147
5071
|
var QUESTION_STATUSES = /* @__PURE__ */ new Set(["asked", "answered"]);
|
|
5148
|
-
var PULSE_STATUSES = /* @__PURE__ */ new Set(["on_track", "at_risk", "off_track"]);
|
|
5149
5072
|
var SURVEY_RECIPIENT_TYPES = /* @__PURE__ */ new Set(["member", "team", "org_wide"]);
|
|
5150
5073
|
var SURVEY_NAMES = /* @__PURE__ */ new Set([
|
|
5151
5074
|
"employee_net_promoter_score",
|
|
@@ -5158,21 +5081,6 @@ var SURVEY_NAMES = /* @__PURE__ */ new Set([
|
|
|
5158
5081
|
"manager_review",
|
|
5159
5082
|
"onboarding"
|
|
5160
5083
|
]);
|
|
5161
|
-
var FEEDBACK_QUARTERS = /* @__PURE__ */ new Set(["q1", "q2", "q3", "q4"]);
|
|
5162
|
-
var FEEDBACK_NAMES = /* @__PURE__ */ new Set([
|
|
5163
|
-
"productivity_and_focus",
|
|
5164
|
-
"company_collaboration",
|
|
5165
|
-
"project_management",
|
|
5166
|
-
"employee_engagement",
|
|
5167
|
-
"training_and_development",
|
|
5168
|
-
"innovation_and_creativity",
|
|
5169
|
-
"customer_insights",
|
|
5170
|
-
"process_improvement",
|
|
5171
|
-
"leadership_and_management",
|
|
5172
|
-
"company_culture",
|
|
5173
|
-
"roadmap_and_strategy",
|
|
5174
|
-
"customer_testing_and_feedback"
|
|
5175
|
-
]);
|
|
5176
5084
|
var SCORECARD_INTERVALS = /* @__PURE__ */ new Set([
|
|
5177
5085
|
"daily",
|
|
5178
5086
|
"weekly",
|
|
@@ -5223,7 +5131,7 @@ function normalizeTodosCreateBody(body) {
|
|
|
5223
5131
|
}
|
|
5224
5132
|
return { ...body, todo };
|
|
5225
5133
|
}
|
|
5226
|
-
function
|
|
5134
|
+
function asNonEmptyString2(value) {
|
|
5227
5135
|
if (typeof value !== "string") {
|
|
5228
5136
|
return void 0;
|
|
5229
5137
|
}
|
|
@@ -5231,7 +5139,7 @@ function asNonEmptyString3(value) {
|
|
|
5231
5139
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
5232
5140
|
}
|
|
5233
5141
|
function validateEnumField(params) {
|
|
5234
|
-
const value =
|
|
5142
|
+
const value = asNonEmptyString2(params.rawValue);
|
|
5235
5143
|
if (!value) {
|
|
5236
5144
|
return void 0;
|
|
5237
5145
|
}
|
|
@@ -5265,7 +5173,7 @@ function normalizeKnowledgeCreateBody(body) {
|
|
|
5265
5173
|
message: "Invalid content.status. Use one of: draft, published."
|
|
5266
5174
|
});
|
|
5267
5175
|
content.status = status ?? "draft";
|
|
5268
|
-
const memberId =
|
|
5176
|
+
const memberId = asNonEmptyString2(content.member_id);
|
|
5269
5177
|
if (!memberId) {
|
|
5270
5178
|
throwMissingRequiredCreateFields("content", ["member_id"]);
|
|
5271
5179
|
}
|
|
@@ -5274,7 +5182,7 @@ function normalizeKnowledgeCreateBody(body) {
|
|
|
5274
5182
|
}
|
|
5275
5183
|
function normalizeNewsCreateBody(body) {
|
|
5276
5184
|
const headline = ensureEntityObject(body, "headline");
|
|
5277
|
-
const memberId =
|
|
5185
|
+
const memberId = asNonEmptyString2(headline.member_id);
|
|
5278
5186
|
if (!memberId) {
|
|
5279
5187
|
throwMissingRequiredCreateFields("headline", ["member_id"]);
|
|
5280
5188
|
}
|
|
@@ -5303,14 +5211,14 @@ function normalizeNewsCreateBody(body) {
|
|
|
5303
5211
|
}
|
|
5304
5212
|
function normalizeQuestionsCreateBody(body) {
|
|
5305
5213
|
const question = ensureEntityObject(body, "question");
|
|
5306
|
-
const summary =
|
|
5307
|
-
const currentName =
|
|
5214
|
+
const summary = asNonEmptyString2(question.summary);
|
|
5215
|
+
const currentName = asNonEmptyString2(question.name);
|
|
5308
5216
|
if (!currentName && summary) {
|
|
5309
5217
|
question.name = summary;
|
|
5310
5218
|
}
|
|
5311
5219
|
delete question.summary;
|
|
5312
|
-
const name =
|
|
5313
|
-
const memberId =
|
|
5220
|
+
const name = asNonEmptyString2(question.name);
|
|
5221
|
+
const memberId = asNonEmptyString2(question.member_id);
|
|
5314
5222
|
const missing = [];
|
|
5315
5223
|
if (!name) missing.push("name");
|
|
5316
5224
|
if (!memberId) missing.push("member_id");
|
|
@@ -5332,13 +5240,13 @@ function normalizeQuestionsCreateBody(body) {
|
|
|
5332
5240
|
}
|
|
5333
5241
|
function normalizeQuestionsUpdateBody(body) {
|
|
5334
5242
|
const question = ensureEntityObject(body, "question");
|
|
5335
|
-
const summary =
|
|
5336
|
-
const currentName =
|
|
5243
|
+
const summary = asNonEmptyString2(question.summary);
|
|
5244
|
+
const currentName = asNonEmptyString2(question.name);
|
|
5337
5245
|
if (!currentName && summary) {
|
|
5338
5246
|
question.name = summary;
|
|
5339
5247
|
}
|
|
5340
5248
|
delete question.summary;
|
|
5341
|
-
const name =
|
|
5249
|
+
const name = asNonEmptyString2(question.name);
|
|
5342
5250
|
if (name) {
|
|
5343
5251
|
question.name = name;
|
|
5344
5252
|
}
|
|
@@ -5353,37 +5261,10 @@ function normalizeQuestionsUpdateBody(body) {
|
|
|
5353
5261
|
}
|
|
5354
5262
|
return { ...body, question };
|
|
5355
5263
|
}
|
|
5356
|
-
function normalizePulseCreateBody(body) {
|
|
5357
|
-
const healthUpdate = ensureEntityObject(body, "health_update");
|
|
5358
|
-
const healthUpdatableId = asNonEmptyString3(healthUpdate.health_updatable_id) ?? asNonEmptyString3(healthUpdate.updatable_id);
|
|
5359
|
-
const healthUpdatableType = asNonEmptyString3(healthUpdate.health_updatable_type) ?? asNonEmptyString3(healthUpdate.updatable_type);
|
|
5360
|
-
const memberId = asNonEmptyString3(healthUpdate.member_id);
|
|
5361
|
-
const status = validateEnumField({
|
|
5362
|
-
rawValue: healthUpdate.status,
|
|
5363
|
-
field: "health_update.status",
|
|
5364
|
-
allowed: PULSE_STATUSES,
|
|
5365
|
-
message: "Invalid health_update.status. Use one of: on_track, at_risk, off_track."
|
|
5366
|
-
});
|
|
5367
|
-
const missing = [];
|
|
5368
|
-
if (!healthUpdatableId) missing.push("health_updatable_id");
|
|
5369
|
-
if (!healthUpdatableType) missing.push("health_updatable_type");
|
|
5370
|
-
if (!memberId) missing.push("member_id");
|
|
5371
|
-
if (!status) missing.push("status");
|
|
5372
|
-
if (missing.length > 0) {
|
|
5373
|
-
throwMissingRequiredCreateFields("health_update", missing);
|
|
5374
|
-
}
|
|
5375
|
-
healthUpdate.health_updatable_id = healthUpdatableId;
|
|
5376
|
-
healthUpdate.health_updatable_type = healthUpdatableType;
|
|
5377
|
-
healthUpdate.member_id = memberId;
|
|
5378
|
-
healthUpdate.status = status;
|
|
5379
|
-
delete healthUpdate.updatable_id;
|
|
5380
|
-
delete healthUpdate.updatable_type;
|
|
5381
|
-
return { ...body, health_update: healthUpdate };
|
|
5382
|
-
}
|
|
5383
5264
|
function normalizeSurveysCreateBody(body) {
|
|
5384
5265
|
const survey = ensureEntityObject(body, "survey");
|
|
5385
|
-
const title =
|
|
5386
|
-
const currentName =
|
|
5266
|
+
const title = asNonEmptyString2(survey.title);
|
|
5267
|
+
const currentName = asNonEmptyString2(survey.name);
|
|
5387
5268
|
if (!currentName && title) {
|
|
5388
5269
|
survey.name = title;
|
|
5389
5270
|
}
|
|
@@ -5412,8 +5293,8 @@ function normalizeSurveysCreateBody(body) {
|
|
|
5412
5293
|
}
|
|
5413
5294
|
function normalizeSurveysUpdateBody(body) {
|
|
5414
5295
|
const survey = ensureEntityObject(body, "survey");
|
|
5415
|
-
const title =
|
|
5416
|
-
const currentName =
|
|
5296
|
+
const title = asNonEmptyString2(survey.title);
|
|
5297
|
+
const currentName = asNonEmptyString2(survey.name);
|
|
5417
5298
|
if (!currentName && title) {
|
|
5418
5299
|
survey.name = title;
|
|
5419
5300
|
}
|
|
@@ -5438,77 +5319,16 @@ function normalizeSurveysUpdateBody(body) {
|
|
|
5438
5319
|
}
|
|
5439
5320
|
return { ...body, survey };
|
|
5440
5321
|
}
|
|
5441
|
-
function normalizeFeedbacksCreateBody(body) {
|
|
5442
|
-
const feedback = ensureEntityObject(body, "feedback");
|
|
5443
|
-
const title = asNonEmptyString3(feedback.title);
|
|
5444
|
-
const currentName = asNonEmptyString3(feedback.name);
|
|
5445
|
-
if (!currentName && title) {
|
|
5446
|
-
feedback.name = title;
|
|
5447
|
-
}
|
|
5448
|
-
delete feedback.title;
|
|
5449
|
-
const name = validateEnumField({
|
|
5450
|
-
rawValue: feedback.name,
|
|
5451
|
-
field: "feedback.name",
|
|
5452
|
-
allowed: FEEDBACK_NAMES,
|
|
5453
|
-
message: "Invalid feedback.name. Use one of: productivity_and_focus, company_collaboration, project_management, employee_engagement, training_and_development, innovation_and_creativity, customer_insights, process_improvement, leadership_and_management, company_culture, roadmap_and_strategy, customer_testing_and_feedback."
|
|
5454
|
-
});
|
|
5455
|
-
const quarter = validateEnumField({
|
|
5456
|
-
rawValue: feedback.quarter,
|
|
5457
|
-
field: "feedback.quarter",
|
|
5458
|
-
allowed: FEEDBACK_QUARTERS,
|
|
5459
|
-
message: "Invalid feedback.quarter. Use one of: q1, q2, q3, q4."
|
|
5460
|
-
});
|
|
5461
|
-
const year = asNonEmptyString3(feedback.year);
|
|
5462
|
-
const missing = [];
|
|
5463
|
-
if (!name) missing.push("name");
|
|
5464
|
-
if (!quarter) missing.push("quarter");
|
|
5465
|
-
if (!year) missing.push("year");
|
|
5466
|
-
if (missing.length > 0) {
|
|
5467
|
-
throwMissingRequiredCreateFields("feedback", missing);
|
|
5468
|
-
}
|
|
5469
|
-
feedback.name = name;
|
|
5470
|
-
feedback.quarter = quarter;
|
|
5471
|
-
feedback.year = year;
|
|
5472
|
-
return { ...body, feedback };
|
|
5473
|
-
}
|
|
5474
|
-
function normalizeFeedbacksUpdateBody(body) {
|
|
5475
|
-
const feedback = ensureEntityObject(body, "feedback");
|
|
5476
|
-
const title = asNonEmptyString3(feedback.title);
|
|
5477
|
-
const currentName = asNonEmptyString3(feedback.name);
|
|
5478
|
-
if (!currentName && title) {
|
|
5479
|
-
feedback.name = title;
|
|
5480
|
-
}
|
|
5481
|
-
delete feedback.title;
|
|
5482
|
-
const name = validateEnumField({
|
|
5483
|
-
rawValue: feedback.name,
|
|
5484
|
-
field: "feedback.name",
|
|
5485
|
-
allowed: FEEDBACK_NAMES,
|
|
5486
|
-
message: "Invalid feedback.name. Use one of: productivity_and_focus, company_collaboration, project_management, employee_engagement, training_and_development, innovation_and_creativity, customer_insights, process_improvement, leadership_and_management, company_culture, roadmap_and_strategy, customer_testing_and_feedback."
|
|
5487
|
-
});
|
|
5488
|
-
if (name) {
|
|
5489
|
-
feedback.name = name;
|
|
5490
|
-
}
|
|
5491
|
-
const quarter = validateEnumField({
|
|
5492
|
-
rawValue: feedback.quarter,
|
|
5493
|
-
field: "feedback.quarter",
|
|
5494
|
-
allowed: FEEDBACK_QUARTERS,
|
|
5495
|
-
message: "Invalid feedback.quarter. Use one of: q1, q2, q3, q4."
|
|
5496
|
-
});
|
|
5497
|
-
if (quarter) {
|
|
5498
|
-
feedback.quarter = quarter;
|
|
5499
|
-
}
|
|
5500
|
-
return { ...body, feedback };
|
|
5501
|
-
}
|
|
5502
5322
|
function normalizeAccountabilityCreateBody(body) {
|
|
5503
5323
|
const responsibility = ensureEntityObject(body, "responsibility");
|
|
5504
|
-
const summary =
|
|
5505
|
-
const currentName =
|
|
5324
|
+
const summary = asNonEmptyString2(responsibility.summary);
|
|
5325
|
+
const currentName = asNonEmptyString2(responsibility.name);
|
|
5506
5326
|
if (!currentName && summary) {
|
|
5507
5327
|
responsibility.name = summary;
|
|
5508
5328
|
}
|
|
5509
5329
|
delete responsibility.summary;
|
|
5510
|
-
const name =
|
|
5511
|
-
const memberId =
|
|
5330
|
+
const name = asNonEmptyString2(responsibility.name);
|
|
5331
|
+
const memberId = asNonEmptyString2(responsibility.member_id);
|
|
5512
5332
|
const missing = [];
|
|
5513
5333
|
if (!name) missing.push("name");
|
|
5514
5334
|
if (!memberId) missing.push("member_id");
|
|
@@ -5523,8 +5343,8 @@ function normalizeAccountabilityCreateBody(body) {
|
|
|
5523
5343
|
}
|
|
5524
5344
|
function normalizeAccountabilityUpdateBody(body) {
|
|
5525
5345
|
const responsibility = ensureEntityObject(body, "responsibility");
|
|
5526
|
-
const summary =
|
|
5527
|
-
const currentName =
|
|
5346
|
+
const summary = asNonEmptyString2(responsibility.summary);
|
|
5347
|
+
const currentName = asNonEmptyString2(responsibility.name);
|
|
5528
5348
|
if (!currentName && summary) {
|
|
5529
5349
|
responsibility.name = summary;
|
|
5530
5350
|
}
|
|
@@ -5556,7 +5376,7 @@ function parseSmartKpiViewCreateBody(raw) {
|
|
|
5556
5376
|
}
|
|
5557
5377
|
function normalizeSmartKpiViewCreateBody(body) {
|
|
5558
5378
|
const smartKpiView = ensureEntityObject(body, "smart_kpi_view");
|
|
5559
|
-
const name =
|
|
5379
|
+
const name = asNonEmptyString2(smartKpiView.name);
|
|
5560
5380
|
if (!name) {
|
|
5561
5381
|
throwMissingRequiredCreateFields("smart_kpi_view", ["name"]);
|
|
5562
5382
|
}
|
|
@@ -5594,9 +5414,9 @@ function buildKpisCreateMutation(params) {
|
|
|
5594
5414
|
});
|
|
5595
5415
|
}
|
|
5596
5416
|
const smartKpi = { ...entity };
|
|
5597
|
-
const name =
|
|
5598
|
-
const smartKpiViewId =
|
|
5599
|
-
const measurableGroupId =
|
|
5417
|
+
const name = asNonEmptyString2(smartKpi.name);
|
|
5418
|
+
const smartKpiViewId = asNonEmptyString2(smartKpi.smart_kpi_view_id);
|
|
5419
|
+
const measurableGroupId = asNonEmptyString2(smartKpi.measurable_group_id);
|
|
5600
5420
|
const hasAllowedName = typeof name === "string" && SMART_KPI_NAME_SET.has(name);
|
|
5601
5421
|
if (!name) {
|
|
5602
5422
|
throw new CliError({
|
|
@@ -5616,7 +5436,7 @@ function buildKpisCreateMutation(params) {
|
|
|
5616
5436
|
measurable_type: "number",
|
|
5617
5437
|
condition: "greater_than_or_equal_to"
|
|
5618
5438
|
};
|
|
5619
|
-
const notes =
|
|
5439
|
+
const notes = asNonEmptyString2(smartKpi.notes);
|
|
5620
5440
|
if (notes) {
|
|
5621
5441
|
measurable.notes = notes;
|
|
5622
5442
|
}
|
|
@@ -5685,6 +5505,32 @@ function registerSmartKpiViewCommands(program) {
|
|
|
5685
5505
|
});
|
|
5686
5506
|
}
|
|
5687
5507
|
function registerSystemToolCommands(program) {
|
|
5508
|
+
registerEntityCrudCommands(program, {
|
|
5509
|
+
command: "reminders",
|
|
5510
|
+
description: "Reminder operations",
|
|
5511
|
+
resourcePath: "reminders",
|
|
5512
|
+
rootKey: "reminder",
|
|
5513
|
+
requiredCreateFields: ["title"],
|
|
5514
|
+
listParams: ["status", "sort"],
|
|
5515
|
+
allowQueryJson: false,
|
|
5516
|
+
registerSearch: false,
|
|
5517
|
+
listSelectionSet: REMINDER_LIST_SELECTION,
|
|
5518
|
+
showSelectionSet: REMINDER_SHOW_SELECTION,
|
|
5519
|
+
idMutationCommands: [
|
|
5520
|
+
{
|
|
5521
|
+
command: "clear",
|
|
5522
|
+
description: "Clear a reminder while retaining its history",
|
|
5523
|
+
field: "clear_reminder",
|
|
5524
|
+
idVariable: "reminder_id"
|
|
5525
|
+
},
|
|
5526
|
+
{
|
|
5527
|
+
command: "destroy",
|
|
5528
|
+
description: "Cancel a reminder while retaining its history",
|
|
5529
|
+
field: "destroy_reminder",
|
|
5530
|
+
idVariable: "reminder_id"
|
|
5531
|
+
}
|
|
5532
|
+
]
|
|
5533
|
+
});
|
|
5688
5534
|
registerEntityCrudCommands(program, {
|
|
5689
5535
|
command: "lists",
|
|
5690
5536
|
description: "List operations",
|
|
@@ -5829,18 +5675,6 @@ function registerSystemToolCommands(program) {
|
|
|
5829
5675
|
listParams: ["answered", "asked"],
|
|
5830
5676
|
allowQueryJson: false
|
|
5831
5677
|
});
|
|
5832
|
-
registerEntityCrudCommands(program, {
|
|
5833
|
-
command: "pulse",
|
|
5834
|
-
description: "Pulse operations",
|
|
5835
|
-
resourcePath: "health_updates",
|
|
5836
|
-
rootKey: "health_update",
|
|
5837
|
-
listField: "feedbacks",
|
|
5838
|
-
showField: "feedback",
|
|
5839
|
-
requiredCreateFields: ["health_updatable_id", "health_updatable_type", "member_id", "status"],
|
|
5840
|
-
normalizeCreateBody: normalizePulseCreateBody,
|
|
5841
|
-
listParams: ["last", "latest", "start_date", "name", "quarter", "year"],
|
|
5842
|
-
allowQueryJson: false
|
|
5843
|
-
});
|
|
5844
5678
|
registerEntityCrudCommands(program, {
|
|
5845
5679
|
command: "surveys",
|
|
5846
5680
|
description: "Survey operations",
|
|
@@ -5852,17 +5686,6 @@ function registerSystemToolCommands(program) {
|
|
|
5852
5686
|
listParams: ["completed", "current_member", "due", "exclude_completed", "sent"],
|
|
5853
5687
|
allowQueryJson: false
|
|
5854
5688
|
});
|
|
5855
|
-
registerEntityCrudCommands(program, {
|
|
5856
|
-
command: "feedbacks",
|
|
5857
|
-
description: "Feedback operations",
|
|
5858
|
-
resourcePath: "feedback",
|
|
5859
|
-
rootKey: "feedback",
|
|
5860
|
-
requiredCreateFields: ["name", "quarter", "year"],
|
|
5861
|
-
normalizeCreateBody: normalizeFeedbacksCreateBody,
|
|
5862
|
-
normalizeUpdateBody: normalizeFeedbacksUpdateBody,
|
|
5863
|
-
listParams: ["last", "latest", "start_date"],
|
|
5864
|
-
allowQueryJson: false
|
|
5865
|
-
});
|
|
5866
5689
|
registerEntityCrudCommands(program, {
|
|
5867
5690
|
command: "accountability",
|
|
5868
5691
|
description: "Accountability operations",
|
|
@@ -6019,7 +5842,7 @@ function ensureRootObject(body, rootKey) {
|
|
|
6019
5842
|
}
|
|
6020
5843
|
return { ...root };
|
|
6021
5844
|
}
|
|
6022
|
-
function
|
|
5845
|
+
function asNonEmptyString3(value) {
|
|
6023
5846
|
if (typeof value !== "string") {
|
|
6024
5847
|
return void 0;
|
|
6025
5848
|
}
|
|
@@ -6029,7 +5852,7 @@ function asNonEmptyString4(value) {
|
|
|
6029
5852
|
function normalizeOrganizationUpdateBody(body) {
|
|
6030
5853
|
const organization = ensureRootObject(body, "organization");
|
|
6031
5854
|
const detail = isRecord3(organization.organization_detail_attributes) ? { ...organization.organization_detail_attributes } : {};
|
|
6032
|
-
const workspaceName =
|
|
5855
|
+
const workspaceName = asNonEmptyString3(organization.workspace_name);
|
|
6033
5856
|
if (workspaceName) {
|
|
6034
5857
|
detail.workspace_name = workspaceName;
|
|
6035
5858
|
}
|
|
@@ -6042,7 +5865,7 @@ function normalizeOrganizationUpdateBody(body) {
|
|
|
6042
5865
|
function normalizeOrganizationMetaProfileUpdateBody(body) {
|
|
6043
5866
|
const root = ensureRootObject(body, "organization_meta_profile");
|
|
6044
5867
|
const profile = isRecord3(root.profile) ? { ...root.profile } : {};
|
|
6045
|
-
const title =
|
|
5868
|
+
const title = asNonEmptyString3(root.title);
|
|
6046
5869
|
if (title) {
|
|
6047
5870
|
const companyIdentity = isRecord3(profile.company_identity) ? { ...profile.company_identity } : {};
|
|
6048
5871
|
companyIdentity.one_sentence_summary = title;
|
|
@@ -6072,7 +5895,7 @@ function normalizeOrganizationMetaProfileUpdateBody(body) {
|
|
|
6072
5895
|
function normalizeKeyMetricMetaProfileUpdateBody(body) {
|
|
6073
5896
|
const root = ensureRootObject(body, "key_metric_meta_profile");
|
|
6074
5897
|
const profile = isRecord3(root.profile) ? { ...root.profile } : {};
|
|
6075
|
-
const annualRevenue =
|
|
5898
|
+
const annualRevenue = asNonEmptyString3(root.annual_revenue);
|
|
6076
5899
|
if (annualRevenue) {
|
|
6077
5900
|
const financial = isRecord3(profile.financial) ? { ...profile.financial } : {};
|
|
6078
5901
|
financial.revenue = annualRevenue;
|
|
@@ -6256,7 +6079,7 @@ function ensureRootObject2(body, rootKey) {
|
|
|
6256
6079
|
}
|
|
6257
6080
|
return { ...root };
|
|
6258
6081
|
}
|
|
6259
|
-
function
|
|
6082
|
+
function asNonEmptyString4(value) {
|
|
6260
6083
|
if (typeof value !== "string") {
|
|
6261
6084
|
return void 0;
|
|
6262
6085
|
}
|
|
@@ -6284,8 +6107,8 @@ function normalizeStrategicPlanUpdateBody(body) {
|
|
|
6284
6107
|
}
|
|
6285
6108
|
function normalizeStrategicObjectiveUpdateBody(body) {
|
|
6286
6109
|
const strategicObjective = ensureRootObject2(body, "strategic_objective");
|
|
6287
|
-
const title =
|
|
6288
|
-
if (!
|
|
6110
|
+
const title = asNonEmptyString4(strategicObjective.title);
|
|
6111
|
+
if (!asNonEmptyString4(strategicObjective.summary) && title) {
|
|
6289
6112
|
strategicObjective.summary = title;
|
|
6290
6113
|
}
|
|
6291
6114
|
delete strategicObjective.title;
|
|
@@ -6308,8 +6131,8 @@ function normalizeStrategicObjectiveUpdateBody(body) {
|
|
|
6308
6131
|
}
|
|
6309
6132
|
function normalizeAnnualObjectiveCreateBody(body) {
|
|
6310
6133
|
const annualObjective = ensureRootObject2(body, "annual_objective");
|
|
6311
|
-
const title =
|
|
6312
|
-
if (!
|
|
6134
|
+
const title = asNonEmptyString4(annualObjective.title);
|
|
6135
|
+
if (!asNonEmptyString4(annualObjective.name) && title) {
|
|
6313
6136
|
annualObjective.name = title;
|
|
6314
6137
|
}
|
|
6315
6138
|
delete annualObjective.title;
|
|
@@ -6317,8 +6140,8 @@ function normalizeAnnualObjectiveCreateBody(body) {
|
|
|
6317
6140
|
}
|
|
6318
6141
|
function normalizeQuarterlyObjectiveCreateBody(body) {
|
|
6319
6142
|
const quarterlyObjective = ensureRootObject2(body, "quarterly_objective");
|
|
6320
|
-
const title =
|
|
6321
|
-
if (!
|
|
6143
|
+
const title = asNonEmptyString4(quarterlyObjective.title);
|
|
6144
|
+
if (!asNonEmptyString4(quarterlyObjective.name) && title) {
|
|
6322
6145
|
quarterlyObjective.name = title;
|
|
6323
6146
|
}
|
|
6324
6147
|
delete quarterlyObjective.title;
|
|
@@ -6461,7 +6284,18 @@ function requiredParentSearchOption(parentFlag, parentKind) {
|
|
|
6461
6284
|
}
|
|
6462
6285
|
function buildChildResourceSelectionSet(parentField, extraFields = []) {
|
|
6463
6286
|
const fields = Array.from(
|
|
6464
|
-
/* @__PURE__ */ new Set([
|
|
6287
|
+
/* @__PURE__ */ new Set([
|
|
6288
|
+
"id",
|
|
6289
|
+
"type",
|
|
6290
|
+
"name",
|
|
6291
|
+
"status",
|
|
6292
|
+
"priority",
|
|
6293
|
+
"rank",
|
|
6294
|
+
"dueDate",
|
|
6295
|
+
"memberId",
|
|
6296
|
+
parentField,
|
|
6297
|
+
...extraFields
|
|
6298
|
+
])
|
|
6465
6299
|
);
|
|
6466
6300
|
const attributeFields = fields.filter((field) => field !== "type");
|
|
6467
6301
|
return `{ ${fields.join(" ")} attributes { ${attributeFields.join(" ")} } }`;
|
|
@@ -6469,6 +6303,30 @@ function buildChildResourceSelectionSet(parentField, extraFields = []) {
|
|
|
6469
6303
|
function buildChildListSelectionSet(parentField, extraFields = []) {
|
|
6470
6304
|
return `{ data ${buildChildResourceSelectionSet(parentField, extraFields)} count currentPage totalPages }`;
|
|
6471
6305
|
}
|
|
6306
|
+
function buildChildShowSelectionSet(parentField, extraFields = []) {
|
|
6307
|
+
const fields = Array.from(
|
|
6308
|
+
/* @__PURE__ */ new Set([
|
|
6309
|
+
"id",
|
|
6310
|
+
"type",
|
|
6311
|
+
"name",
|
|
6312
|
+
"status",
|
|
6313
|
+
"priority",
|
|
6314
|
+
"rank",
|
|
6315
|
+
"dueDate",
|
|
6316
|
+
"memberId",
|
|
6317
|
+
parentField,
|
|
6318
|
+
"notes",
|
|
6319
|
+
"hasNotes",
|
|
6320
|
+
"hasUnreadNotes",
|
|
6321
|
+
"notesUpdatedAt",
|
|
6322
|
+
"notesLastReadAt",
|
|
6323
|
+
"estimateIds",
|
|
6324
|
+
...extraFields
|
|
6325
|
+
])
|
|
6326
|
+
);
|
|
6327
|
+
const attributeFields = fields.filter((field) => field !== "type");
|
|
6328
|
+
return `{ ${fields.join(" ")} attributes { ${attributeFields.join(" ")} } }`;
|
|
6329
|
+
}
|
|
6472
6330
|
function parseJsonObject2(raw) {
|
|
6473
6331
|
try {
|
|
6474
6332
|
const parsed = JSON.parse(raw);
|
|
@@ -6846,11 +6704,14 @@ function registerChildEntityCommands(program) {
|
|
|
6846
6704
|
updateField: "update_talking_point",
|
|
6847
6705
|
destroyField: "destroy_talking_point",
|
|
6848
6706
|
idVariable: "talking_point_id",
|
|
6707
|
+
showField: "talking_point",
|
|
6849
6708
|
listOperationName: "TalkingPointsList",
|
|
6709
|
+
showOperationName: "TalkingPointsShow",
|
|
6850
6710
|
createOperationName: "TalkingPointsCreate",
|
|
6851
6711
|
updateOperationName: "TalkingPointsUpdate",
|
|
6852
6712
|
destroyOperationName: "TalkingPointsDestroy",
|
|
6853
6713
|
listSelectionSet: buildChildListSelectionSet("meetingId", ["description", "creatorId", "slug"]),
|
|
6714
|
+
showSelectionSet: buildChildShowSelectionSet("meetingId", ["description", "creatorId", "slug"]),
|
|
6854
6715
|
listParentTypedField: "meetingId"
|
|
6855
6716
|
});
|
|
6856
6717
|
}
|
|
@@ -7217,7 +7078,7 @@ var import_zod18 = require("zod");
|
|
|
7217
7078
|
|
|
7218
7079
|
// src/internalOptions.ts
|
|
7219
7080
|
var INTERNAL_OPTIONS_KEY = "__waveInternalOptions";
|
|
7220
|
-
function
|
|
7081
|
+
function asRecord3(value) {
|
|
7221
7082
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
7222
7083
|
return null;
|
|
7223
7084
|
}
|
|
@@ -7231,7 +7092,7 @@ function setInternalCliOptions(program, options) {
|
|
|
7231
7092
|
function getInternalCliOptions(command) {
|
|
7232
7093
|
let current = command;
|
|
7233
7094
|
while (current) {
|
|
7234
|
-
const record =
|
|
7095
|
+
const record = asRecord3(current[INTERNAL_OPTIONS_KEY]);
|
|
7235
7096
|
if (record) {
|
|
7236
7097
|
return {
|
|
7237
7098
|
enableRetryOnEmptyPhrase: record.enableRetryOnEmptyPhrase === true
|
|
@@ -8034,7 +7895,7 @@ var import_commander = require("commander");
|
|
|
8034
7895
|
var import_node_crypto3 = require("crypto");
|
|
8035
7896
|
|
|
8036
7897
|
// src/version.ts
|
|
8037
|
-
var CLI_VERSION = "0.1.
|
|
7898
|
+
var CLI_VERSION = "0.1.88";
|
|
8038
7899
|
|
|
8039
7900
|
// src/operationMetadata.ts
|
|
8040
7901
|
var DISCOVERY_OPERATION_IDS = [
|
|
@@ -8070,8 +7931,6 @@ var DISCOVERY_OPERATION_IDS = [
|
|
|
8070
7931
|
"doctor",
|
|
8071
7932
|
"doctor.examples",
|
|
8072
7933
|
"doctor.schema",
|
|
8073
|
-
"feedbacks.examples",
|
|
8074
|
-
"feedbacks.schema",
|
|
8075
7934
|
"foundation.examples",
|
|
8076
7935
|
"foundation.schema",
|
|
8077
7936
|
"issue-groups.examples",
|
|
@@ -8108,8 +7967,6 @@ var DISCOVERY_OPERATION_IDS = [
|
|
|
8108
7967
|
"project-content.schema",
|
|
8109
7968
|
"projects.examples",
|
|
8110
7969
|
"projects.schema",
|
|
8111
|
-
"pulse.examples",
|
|
8112
|
-
"pulse.schema",
|
|
8113
7970
|
"questions.examples",
|
|
8114
7971
|
"questions.schema",
|
|
8115
7972
|
"recognition.examples",
|
|
@@ -8151,7 +8008,9 @@ var DISCOVERY_OPERATION_IDS = [
|
|
|
8151
8008
|
"todos.examples",
|
|
8152
8009
|
"todos.schema",
|
|
8153
8010
|
"whiteboards.examples",
|
|
8154
|
-
"whiteboards.schema"
|
|
8011
|
+
"whiteboards.schema",
|
|
8012
|
+
"sketches.examples",
|
|
8013
|
+
"sketches.schema"
|
|
8155
8014
|
];
|
|
8156
8015
|
var READ_OPERATION_IDS = [
|
|
8157
8016
|
"accountability.list",
|
|
@@ -8188,9 +8047,6 @@ var READ_OPERATION_IDS = [
|
|
|
8188
8047
|
"desktop-context.member-statuses",
|
|
8189
8048
|
"desktop-context.recent",
|
|
8190
8049
|
"desktop-context.status",
|
|
8191
|
-
"feedbacks.list",
|
|
8192
|
-
"feedbacks.search",
|
|
8193
|
-
"feedbacks.show",
|
|
8194
8050
|
"find",
|
|
8195
8051
|
"foundation.annual-objectives.list",
|
|
8196
8052
|
"foundation.annual-objectives.search",
|
|
@@ -8226,6 +8082,7 @@ var READ_OPERATION_IDS = [
|
|
|
8226
8082
|
"mail.message",
|
|
8227
8083
|
"mail.messages",
|
|
8228
8084
|
"mail.open",
|
|
8085
|
+
"mail.relay-evidence",
|
|
8229
8086
|
"mail.settings",
|
|
8230
8087
|
"mail.snippets",
|
|
8231
8088
|
"mail.sync-status",
|
|
@@ -8290,9 +8147,6 @@ var READ_OPERATION_IDS = [
|
|
|
8290
8147
|
"projects.list",
|
|
8291
8148
|
"projects.search",
|
|
8292
8149
|
"projects.show",
|
|
8293
|
-
"pulse.list",
|
|
8294
|
-
"pulse.search",
|
|
8295
|
-
"pulse.show",
|
|
8296
8150
|
"questions.list",
|
|
8297
8151
|
"questions.search",
|
|
8298
8152
|
"questions.show",
|
|
@@ -8304,6 +8158,8 @@ var READ_OPERATION_IDS = [
|
|
|
8304
8158
|
"rock-collections.list",
|
|
8305
8159
|
"rock-collections.search",
|
|
8306
8160
|
"rock-collections.show",
|
|
8161
|
+
"reminders.list",
|
|
8162
|
+
"reminders.show",
|
|
8307
8163
|
"rocks.list",
|
|
8308
8164
|
"rocks.search",
|
|
8309
8165
|
"rocks.show",
|
|
@@ -8316,6 +8172,8 @@ var READ_OPERATION_IDS = [
|
|
|
8316
8172
|
"skills.list",
|
|
8317
8173
|
"skills.show",
|
|
8318
8174
|
"stand-ups.list",
|
|
8175
|
+
"signatures.list",
|
|
8176
|
+
"signatures.show",
|
|
8319
8177
|
"stand-ups.search",
|
|
8320
8178
|
"stand-ups.show",
|
|
8321
8179
|
"subissues.list",
|
|
@@ -8339,13 +8197,12 @@ var READ_OPERATION_IDS = [
|
|
|
8339
8197
|
"support.settings",
|
|
8340
8198
|
"support.ticket-counts",
|
|
8341
8199
|
"support.tickets",
|
|
8342
|
-
"signatures.list",
|
|
8343
|
-
"signatures.show",
|
|
8344
8200
|
"surveys.list",
|
|
8345
8201
|
"surveys.search",
|
|
8346
8202
|
"surveys.show",
|
|
8347
8203
|
"talking-points.list",
|
|
8348
8204
|
"talking-points.search",
|
|
8205
|
+
"talking-points.show",
|
|
8349
8206
|
"tasks.list",
|
|
8350
8207
|
"tasks.search",
|
|
8351
8208
|
"tasks.show",
|
|
@@ -8367,7 +8224,10 @@ var READ_OPERATION_IDS = [
|
|
|
8367
8224
|
"tree",
|
|
8368
8225
|
"whiteboards.list",
|
|
8369
8226
|
"whiteboards.open",
|
|
8370
|
-
"whiteboards.show"
|
|
8227
|
+
"whiteboards.show",
|
|
8228
|
+
"sketches.list",
|
|
8229
|
+
"sketches.open",
|
|
8230
|
+
"sketches.show"
|
|
8371
8231
|
];
|
|
8372
8232
|
var WRITE_OPERATION_IDS = [
|
|
8373
8233
|
"accountability.create",
|
|
@@ -8418,8 +8278,6 @@ var WRITE_OPERATION_IDS = [
|
|
|
8418
8278
|
"datasheets.view.delete",
|
|
8419
8279
|
"datasheets.view.reorder",
|
|
8420
8280
|
"datasheets.view.update",
|
|
8421
|
-
"feedbacks.create",
|
|
8422
|
-
"feedbacks.update",
|
|
8423
8281
|
"foundation.annual-objectives.create",
|
|
8424
8282
|
"foundation.annual-objectives.update",
|
|
8425
8283
|
"foundation.quarterly-objectives.create",
|
|
@@ -8467,8 +8325,6 @@ var WRITE_OPERATION_IDS = [
|
|
|
8467
8325
|
"project-content.update",
|
|
8468
8326
|
"projects.create",
|
|
8469
8327
|
"projects.update",
|
|
8470
|
-
"pulse.create",
|
|
8471
|
-
"pulse.update",
|
|
8472
8328
|
"questions.create",
|
|
8473
8329
|
"questions.update",
|
|
8474
8330
|
"rock-collections.create",
|
|
@@ -8476,6 +8332,10 @@ var WRITE_OPERATION_IDS = [
|
|
|
8476
8332
|
"rocks.create",
|
|
8477
8333
|
"rocks.update",
|
|
8478
8334
|
"rocks.update-status",
|
|
8335
|
+
"reminders.clear",
|
|
8336
|
+
"reminders.create",
|
|
8337
|
+
"reminders.destroy",
|
|
8338
|
+
"reminders.update",
|
|
8479
8339
|
"scorecard-groups.create",
|
|
8480
8340
|
"scorecard-groups.update",
|
|
8481
8341
|
"scorecards.create",
|
|
@@ -8517,7 +8377,9 @@ var WRITE_OPERATION_IDS = [
|
|
|
8517
8377
|
"todo-groups.create",
|
|
8518
8378
|
"todo-groups.update",
|
|
8519
8379
|
"todos.create",
|
|
8520
|
-
"todos.update"
|
|
8380
|
+
"todos.update",
|
|
8381
|
+
"sketches.create",
|
|
8382
|
+
"sketches.update-metadata"
|
|
8521
8383
|
];
|
|
8522
8384
|
var DIRECT_MACHINE_WRITE_OPERATION_IDS = /* @__PURE__ */ new Set(["automations.create"]);
|
|
8523
8385
|
var AUTH_OPERATION_IDS = ["login", "logout"];
|
|
@@ -8538,6 +8400,8 @@ var DESTRUCTIVE_OPERATION_IDS = /* @__PURE__ */ new Set([
|
|
|
8538
8400
|
"datasheets.view.delete",
|
|
8539
8401
|
"milestones.destroy",
|
|
8540
8402
|
"project-content.destroy",
|
|
8403
|
+
"reminders.clear",
|
|
8404
|
+
"reminders.destroy",
|
|
8541
8405
|
"signatures.destroy",
|
|
8542
8406
|
"signatures.void",
|
|
8543
8407
|
"subissues.destroy",
|
|
@@ -9835,15 +9699,15 @@ function normalizeAgentFilePath(file, parentRef) {
|
|
|
9835
9699
|
const trimmed = nonEmptyString3.parse(file).trim().replace(/^\/+|\/+$/g, "");
|
|
9836
9700
|
const fileName = trimmed.startsWith(".agent/") ? trimmed.slice(".agent/".length) : trimmed;
|
|
9837
9701
|
const isThreadWorkspace = atlasThreadWorkspaceParentRefPattern.test(parentRef);
|
|
9838
|
-
const isSupportedFile = isThreadWorkspace ? /^[a-z0-9][a-z0-9-]*\.(?:md|txt)$/.test(fileName) : isSupportedAgentOverlayFileName(fileName);
|
|
9702
|
+
const isSupportedFile = isThreadWorkspace ? /^[a-z0-9][a-z0-9-]*\.(?:md|txt|csv)$/.test(fileName) : isSupportedAgentOverlayFileName(fileName);
|
|
9839
9703
|
if (fileName.includes("\\") || fileName.includes("/") || fileName === "." || fileName === ".." || !isSupportedFile) {
|
|
9840
9704
|
throw new CliError({
|
|
9841
|
-
message: isThreadWorkspace ? "Atlas task workspaces support only lowercase kebab-case .md or .
|
|
9705
|
+
message: isThreadWorkspace ? "Atlas task workspaces support only lowercase kebab-case .md, .txt, or .csv basenames." : ".agent supports only notes.md, summary.md, or <lowercase-kebab-slug>.md.",
|
|
9842
9706
|
kind: "invalid_args",
|
|
9843
9707
|
status: 400,
|
|
9844
9708
|
exitCode: EXIT_CODES.invalidArgs,
|
|
9845
9709
|
details: {
|
|
9846
|
-
supportedFiles: isThreadWorkspace ? ["<lowercase-kebab-slug>.md", "<lowercase-kebab-slug>.txt"] : [...supportedAgentOverlaySystemFiles, "<lowercase-kebab-slug>.md"]
|
|
9710
|
+
supportedFiles: isThreadWorkspace ? ["<lowercase-kebab-slug>.md", "<lowercase-kebab-slug>.txt", "<lowercase-kebab-slug>.csv"] : [...supportedAgentOverlaySystemFiles, "<lowercase-kebab-slug>.md"]
|
|
9847
9711
|
}
|
|
9848
9712
|
});
|
|
9849
9713
|
}
|
|
@@ -11326,7 +11190,7 @@ function positiveInt2(raw, fallback) {
|
|
|
11326
11190
|
function requestTimeoutMs(totalTimeoutMs) {
|
|
11327
11191
|
return Math.max(1e3, Math.min(totalTimeoutMs, 1e4));
|
|
11328
11192
|
}
|
|
11329
|
-
function
|
|
11193
|
+
function asRecord4(value) {
|
|
11330
11194
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
11331
11195
|
}
|
|
11332
11196
|
function asString(value) {
|
|
@@ -11376,9 +11240,9 @@ function cliTokenFromPoll(payload) {
|
|
|
11376
11240
|
return asString(payload.cliToken) ?? asString(payload.cli_token) ?? asString(payload.token);
|
|
11377
11241
|
}
|
|
11378
11242
|
function unwrapMutationResult(value) {
|
|
11379
|
-
const record =
|
|
11243
|
+
const record = asRecord4(value);
|
|
11380
11244
|
if (!record) return null;
|
|
11381
|
-
const data =
|
|
11245
|
+
const data = asRecord4(record.data);
|
|
11382
11246
|
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"))) {
|
|
11383
11247
|
return data;
|
|
11384
11248
|
}
|
|
@@ -11443,7 +11307,7 @@ async function runTokenLogin(cmd, opts) {
|
|
|
11443
11307
|
exitCode: mapStatusToExitCode(status.error.status)
|
|
11444
11308
|
});
|
|
11445
11309
|
}
|
|
11446
|
-
const statusData =
|
|
11310
|
+
const statusData = asRecord4(status.result.data.cliAuthStatus) ?? {};
|
|
11447
11311
|
const storage = await writeStoredToken(token, baseUrl);
|
|
11448
11312
|
const configPath2 = opts.saveBaseUrl ? await persistBaseUrl(baseUrl) : void 0;
|
|
11449
11313
|
return printEnvelopeAndExit({
|
|
@@ -11660,7 +11524,7 @@ async function runLogout(cmd) {
|
|
|
11660
11524
|
});
|
|
11661
11525
|
if (result.ok) {
|
|
11662
11526
|
requestId = result.result.requestId;
|
|
11663
|
-
const payload =
|
|
11527
|
+
const payload = asRecord4(result.result.data.revokeCliToken) ?? {};
|
|
11664
11528
|
revokedRemote = payload.ok !== false;
|
|
11665
11529
|
} else {
|
|
11666
11530
|
requestId = result.requestId;
|
|
@@ -11723,7 +11587,7 @@ async function runAuthStatus(cmd) {
|
|
|
11723
11587
|
exitCode: mapStatusToExitCode(result.error.status)
|
|
11724
11588
|
});
|
|
11725
11589
|
}
|
|
11726
|
-
const status =
|
|
11590
|
+
const status = asRecord4(result.result.data.cliAuthStatus) ?? {};
|
|
11727
11591
|
const baseAuthStatus = status.baseAuthStatus;
|
|
11728
11592
|
return printEnvelopeAndExit({
|
|
11729
11593
|
envelope: envelope({
|
|
@@ -11990,6 +11854,26 @@ var RECENT_TOOL_SUPPORT_REGISTRY = [
|
|
|
11990
11854
|
]
|
|
11991
11855
|
}
|
|
11992
11856
|
}),
|
|
11857
|
+
entry({
|
|
11858
|
+
cliKey: "sketches",
|
|
11859
|
+
displayName: "Sketches",
|
|
11860
|
+
backend: backendToolKey("sketches"),
|
|
11861
|
+
routes: ["/sketches", "/sketches/[sketchId]"],
|
|
11862
|
+
capabilityCategories: ["collaboration", "design", "metadata", "read_only_discovery"],
|
|
11863
|
+
sensitiveOutputNotes: [
|
|
11864
|
+
"Sketch commands must not print document bytes, collaboration updates, embedded files, comments, or auth material."
|
|
11865
|
+
],
|
|
11866
|
+
implementation: {
|
|
11867
|
+
milestone: "WAVE-12",
|
|
11868
|
+
status: "implemented_command_surface",
|
|
11869
|
+
enabledCommands: ["open", "list", "show", "create", "update-metadata"],
|
|
11870
|
+
forbiddenCommands: ["save-document", "render", "export", "import"],
|
|
11871
|
+
notes: [
|
|
11872
|
+
"The Sketch surface is limited to metadata and does not provide an editor, renderer, binary transport, or provider connector.",
|
|
11873
|
+
"Create and metadata update use the existing typed GraphQL mutations."
|
|
11874
|
+
]
|
|
11875
|
+
}
|
|
11876
|
+
}),
|
|
11993
11877
|
entry({
|
|
11994
11878
|
cliKey: "time-tracking",
|
|
11995
11879
|
displayName: "Time Tracking",
|
|
@@ -13027,6 +12911,158 @@ function registerWhiteboardsCommands(program) {
|
|
|
13027
12911
|
});
|
|
13028
12912
|
}
|
|
13029
12913
|
|
|
12914
|
+
// src/commands/sketches.ts
|
|
12915
|
+
var SKETCH_METADATA_SELECTION = "id name slug status priority archivedAt organizationId memberId teamIds documentGeneration documentVersion partytimeRoomId partytimeRoomVersion createdAt updatedAt";
|
|
12916
|
+
var SKETCHES_SELECTION = `{ count currentPage totalPages data { ${SKETCH_METADATA_SELECTION} } }`;
|
|
12917
|
+
var SKETCH_SELECTION = `{ ${SKETCH_METADATA_SELECTION} }`;
|
|
12918
|
+
function baseVariables4(contextOrganizationId) {
|
|
12919
|
+
return { organization_id: resolveOrganizationId(contextOrganizationId) };
|
|
12920
|
+
}
|
|
12921
|
+
function listFilters3(opts) {
|
|
12922
|
+
return {
|
|
12923
|
+
page: opts.page,
|
|
12924
|
+
per: opts.per,
|
|
12925
|
+
team_id: opts.teamId,
|
|
12926
|
+
member_id: opts.memberId,
|
|
12927
|
+
include_archived: opts.includeArchived
|
|
12928
|
+
};
|
|
12929
|
+
}
|
|
12930
|
+
function listVariableTypes3() {
|
|
12931
|
+
return {
|
|
12932
|
+
organization_id: "ID!",
|
|
12933
|
+
page: "Int",
|
|
12934
|
+
per: "Int",
|
|
12935
|
+
team_id: "ID",
|
|
12936
|
+
member_id: "ID",
|
|
12937
|
+
include_archived: "Boolean"
|
|
12938
|
+
};
|
|
12939
|
+
}
|
|
12940
|
+
async function runSketchQuery(cmd, config) {
|
|
12941
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
12942
|
+
await runGraphqlQueryCommand({
|
|
12943
|
+
command: config.command,
|
|
12944
|
+
operationName: config.operationName,
|
|
12945
|
+
runtimeOptions: context.runtimeOptions,
|
|
12946
|
+
field: config.field,
|
|
12947
|
+
variables: normalizeGraphqlVariables2({
|
|
12948
|
+
...baseVariables4(context.organizationId),
|
|
12949
|
+
...config.variables
|
|
12950
|
+
}),
|
|
12951
|
+
...config.variableTypes ? { variableTypes: config.variableTypes } : {},
|
|
12952
|
+
...config.isList ? { isList: true } : {},
|
|
12953
|
+
...config.isShow ? { isShow: true } : {},
|
|
12954
|
+
selectionSet: config.selectionSet
|
|
12955
|
+
});
|
|
12956
|
+
}
|
|
12957
|
+
function addListFilterOptions3(command) {
|
|
12958
|
+
return command.option("--page <page>").option("--per <per>").option("--team-id <teamId>").option("--member-id <memberId>").option("--include-archived <includeArchived>");
|
|
12959
|
+
}
|
|
12960
|
+
function sketchOpenData() {
|
|
12961
|
+
const tool = getRecentToolSupport("sketches");
|
|
12962
|
+
return {
|
|
12963
|
+
cliKey: "sketches",
|
|
12964
|
+
displayName: "Sketches",
|
|
12965
|
+
backend: {
|
|
12966
|
+
toolKey: tool?.backend.toolKey ?? "sketches",
|
|
12967
|
+
status: tool?.backend.status ?? "verified_wave_02",
|
|
12968
|
+
sourceMilestone: tool?.backend.sourceMilestone ?? "WAVE-02"
|
|
12969
|
+
},
|
|
12970
|
+
route: tool?.safeRouteTargets.primaryRoute ?? "/sketches",
|
|
12971
|
+
safeRouteTargets: tool?.safeRouteTargets ?? {
|
|
12972
|
+
primaryRoute: "/sketches",
|
|
12973
|
+
deepLinkTemplates: ["/sketches", "/sketches/[sketchId]"],
|
|
12974
|
+
status: "verified_wave_03",
|
|
12975
|
+
sourceMilestone: "WAVE-03"
|
|
12976
|
+
},
|
|
12977
|
+
implementation: {
|
|
12978
|
+
enabledCommands: ["open", "list", "show", "create", "update-metadata"],
|
|
12979
|
+
excludedCommands: ["save-document", "render", "export", "import"]
|
|
12980
|
+
},
|
|
12981
|
+
sensitiveOutputNotes: tool?.sensitiveOutputNotes ?? [
|
|
12982
|
+
"Sketch commands return metadata only and never return document bytes, collaboration updates, embedded files, comments, or tokens."
|
|
12983
|
+
]
|
|
12984
|
+
};
|
|
12985
|
+
}
|
|
12986
|
+
function registerSketchCommands(program) {
|
|
12987
|
+
const sketches = program.command("sketches").description("Sketch metadata operations with bounded create and update support");
|
|
12988
|
+
sketches.command("open").description("Return verified Sketches app routes without opening a browser").option("--readable", "Print the primary route path only").option("--json", "Emit the stable JSON envelope").action((opts) => {
|
|
12989
|
+
const data = sketchOpenData();
|
|
12990
|
+
if (opts.readable && !opts.json) return printTextAndExit({ text: String(data.route) });
|
|
12991
|
+
return printEnvelopeAndExit({
|
|
12992
|
+
envelope: {
|
|
12993
|
+
ok: true,
|
|
12994
|
+
command: "sketches.open",
|
|
12995
|
+
status: 200,
|
|
12996
|
+
data,
|
|
12997
|
+
error: null,
|
|
12998
|
+
meta: { requestId: "local_sketches" }
|
|
12999
|
+
}
|
|
13000
|
+
});
|
|
13001
|
+
});
|
|
13002
|
+
addListFilterOptions3(sketches.command("list").description("Read safe Sketch metadata")).action(
|
|
13003
|
+
async (opts, cmd) => {
|
|
13004
|
+
await runSketchQuery(cmd, {
|
|
13005
|
+
command: "sketches.list",
|
|
13006
|
+
operationName: "Sketches",
|
|
13007
|
+
field: "sketches",
|
|
13008
|
+
variables: listFilters3(opts),
|
|
13009
|
+
variableTypes: listVariableTypes3(),
|
|
13010
|
+
isList: true,
|
|
13011
|
+
selectionSet: SKETCHES_SELECTION
|
|
13012
|
+
});
|
|
13013
|
+
}
|
|
13014
|
+
);
|
|
13015
|
+
sketches.command("show").description("Read safe Sketch detail metadata").requiredOption("--slug <slug>").action(async (opts, cmd) => {
|
|
13016
|
+
await runSketchQuery(cmd, {
|
|
13017
|
+
command: "sketches.show",
|
|
13018
|
+
operationName: "Sketch",
|
|
13019
|
+
field: "sketch",
|
|
13020
|
+
variables: { slug: opts.slug },
|
|
13021
|
+
variableTypes: { organization_id: "ID!", slug: "ID!" },
|
|
13022
|
+
isShow: true,
|
|
13023
|
+
selectionSet: SKETCH_SELECTION
|
|
13024
|
+
});
|
|
13025
|
+
});
|
|
13026
|
+
sketches.command("create").description("Create a Sketch with a required team and idempotency key").requiredOption("--data-json <dataJson>", 'Sketch JSON or {"sketch": {...}}').action(async (opts, cmd) => {
|
|
13027
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
13028
|
+
const body = __testables.normalizeBody(String(opts.dataJson), "sketch");
|
|
13029
|
+
assertOperationPayload("sketches.create", body);
|
|
13030
|
+
await runGraphqlMutationCommand({
|
|
13031
|
+
command: "sketches.create",
|
|
13032
|
+
runtimeOptions: context.runtimeOptions,
|
|
13033
|
+
field: "create_sketch",
|
|
13034
|
+
variables: {
|
|
13035
|
+
organization_id: resolveOrganizationId(context.organizationId),
|
|
13036
|
+
params: body
|
|
13037
|
+
},
|
|
13038
|
+
variableTypes: {
|
|
13039
|
+
organization_id: "ID!",
|
|
13040
|
+
params: "CreateSketchParamsInput!"
|
|
13041
|
+
}
|
|
13042
|
+
});
|
|
13043
|
+
});
|
|
13044
|
+
sketches.command("update-metadata").description("Update bounded Sketch metadata; document content is never accepted").requiredOption("--id <id>").requiredOption("--data-json <dataJson>", 'Sketch metadata JSON or {"sketch": {...}}').action(async (opts, cmd) => {
|
|
13045
|
+
const context = await resolveCommandContext(cmd.optsWithGlobals());
|
|
13046
|
+
const body = __testables.normalizeBody(String(opts.dataJson), "sketch");
|
|
13047
|
+
assertOperationPayload("sketches.update-metadata", body);
|
|
13048
|
+
await runGraphqlMutationCommand({
|
|
13049
|
+
command: "sketches.update-metadata",
|
|
13050
|
+
runtimeOptions: context.runtimeOptions,
|
|
13051
|
+
field: "update_sketch",
|
|
13052
|
+
variables: {
|
|
13053
|
+
organization_id: resolveOrganizationId(context.organizationId),
|
|
13054
|
+
sketch_id: String(opts.id),
|
|
13055
|
+
params: body
|
|
13056
|
+
},
|
|
13057
|
+
variableTypes: {
|
|
13058
|
+
organization_id: "ID!",
|
|
13059
|
+
sketch_id: "ID!",
|
|
13060
|
+
params: "UpdateSketchParamsInput!"
|
|
13061
|
+
}
|
|
13062
|
+
});
|
|
13063
|
+
});
|
|
13064
|
+
}
|
|
13065
|
+
|
|
13030
13066
|
// src/commands/timeTracking.ts
|
|
13031
13067
|
var TIME_TRACKING_ENTRY_SELECTION = "id organizationId memberId memberName taskId projectId projectName labelId createdByMemberId localDate durationMinutes startMinute endMinute startedAt endedAt status source createdAt updatedAt";
|
|
13032
13068
|
var TIME_TRACKING_ENTRIES_SELECTION = `{ count currentPage totalPages data { ${TIME_TRACKING_ENTRY_SELECTION} } }`;
|
|
@@ -13057,7 +13093,7 @@ var TIME_TRACKING_FORBIDDEN_COMMANDS = [
|
|
|
13057
13093
|
"payroll",
|
|
13058
13094
|
"billing"
|
|
13059
13095
|
];
|
|
13060
|
-
function
|
|
13096
|
+
function baseVariables5(contextOrganizationId) {
|
|
13061
13097
|
return {
|
|
13062
13098
|
organization_id: resolveOrganizationId(contextOrganizationId)
|
|
13063
13099
|
};
|
|
@@ -13112,7 +13148,7 @@ async function runTimeTrackingQuery(cmd, config) {
|
|
|
13112
13148
|
runtimeOptions: context.runtimeOptions,
|
|
13113
13149
|
field: config.field,
|
|
13114
13150
|
variables: normalizeGraphqlVariables2({
|
|
13115
|
-
...
|
|
13151
|
+
...baseVariables5(context.organizationId),
|
|
13116
13152
|
...config.variables
|
|
13117
13153
|
}),
|
|
13118
13154
|
variableTypes: config.variableTypes,
|
|
@@ -13374,11 +13410,11 @@ function sanitizePlannerJson(value) {
|
|
|
13374
13410
|
}
|
|
13375
13411
|
return output;
|
|
13376
13412
|
}
|
|
13377
|
-
function
|
|
13413
|
+
function asRecord5(value) {
|
|
13378
13414
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
13379
13415
|
}
|
|
13380
13416
|
function readPlannerStateKey(value, keys) {
|
|
13381
|
-
const record =
|
|
13417
|
+
const record = asRecord5(value);
|
|
13382
13418
|
if (!record) {
|
|
13383
13419
|
return null;
|
|
13384
13420
|
}
|
|
@@ -13573,6 +13609,7 @@ var MAIL_ENABLED_COMMANDS = [
|
|
|
13573
13609
|
"open",
|
|
13574
13610
|
"validate-provider",
|
|
13575
13611
|
"workspace",
|
|
13612
|
+
"relay-evidence",
|
|
13576
13613
|
"accounts",
|
|
13577
13614
|
"messages",
|
|
13578
13615
|
"conversations",
|
|
@@ -13638,6 +13675,9 @@ var MAIL_SETTINGS_SELECTION = "{ id organizationId memberId defaultMailAccountId
|
|
|
13638
13675
|
var MAIL_UNREAD_COUNT_SELECTION = "{ total byAccount byLabel }";
|
|
13639
13676
|
var MAIL_SYNC_STATUS_SELECTION = "{ id status operationStatus operationToolKey accountId accountIds page per view importedCount updatedCount providerCount counts errorCode statusCode queuedAt startedAt completedAt createdAt updatedAt }";
|
|
13640
13677
|
var MAIL_WORKSPACE_SELECTION = `{ accounts ${MAIL_ACCOUNT_SELECTION} messages ${MAIL_MESSAGES_SELECTION} labels ${MAIL_LABEL_SELECTION} snippets ${MAIL_SNIPPET_SELECTION} settings ${MAIL_SETTINGS_SELECTION} unreadCount ${MAIL_UNREAD_COUNT_SELECTION} }`;
|
|
13678
|
+
var MAIL_RELAY_EVIDENCE_ACCOUNT_SELECTION = "{ id provider service status connectionState syncStatus emailAddress displayName lastSyncedAt }";
|
|
13679
|
+
var MAIL_RELAY_EVIDENCE_MESSAGE_SELECTION = "{ id mailAccountId subject from status direction sentAt receivedAt snippet createdAt updatedAt }";
|
|
13680
|
+
var MAIL_RELAY_EVIDENCE_SELECTION = `{ accounts ${MAIL_RELAY_EVIDENCE_ACCOUNT_SELECTION} messages { count currentPage totalPages data ${MAIL_RELAY_EVIDENCE_MESSAGE_SELECTION} } }`;
|
|
13641
13681
|
var OUTLOOK_PROVIDER_VALIDATION_EVIDENCE = {
|
|
13642
13682
|
provider: "microsoft",
|
|
13643
13683
|
oauthProviderId: "wave-microsoft-outlook",
|
|
@@ -13802,7 +13842,8 @@ function buildMailOpenData() {
|
|
|
13802
13842
|
forbiddenCommands: [...MAIL_FORBIDDEN_COMMANDS]
|
|
13803
13843
|
},
|
|
13804
13844
|
sensitiveOutputNotes: tool?.sensitiveOutputNotes ?? [
|
|
13805
|
-
"Mail commands are metadata-only and must not print message bodies, subjects, snippets, contacts, attachments, provider payloads, token material, account addresses/display names, label names/colors, snippet content, preferences, signatures, sync search text, sync error bodies, or user-authored mail content."
|
|
13845
|
+
"Default Mail commands are metadata-only and must not print message bodies, subjects, snippets, contacts, attachments, provider payloads, token material, account addresses/display names, label names/colors, snippet content, preferences, signatures, sync search text, sync error bodies, or user-authored mail content.",
|
|
13846
|
+
"mail relay-evidence is the explicit bounded exception for an authenticated, user-authorized relay: it exposes mailbox identity plus sender, subject, date, and snippet metadata, but never bodies, recipients, attachments, provider IDs, or token material."
|
|
13806
13847
|
]
|
|
13807
13848
|
};
|
|
13808
13849
|
}
|
|
@@ -13915,6 +13956,26 @@ function registerMailCommands(program) {
|
|
|
13915
13956
|
isShow: true
|
|
13916
13957
|
});
|
|
13917
13958
|
});
|
|
13959
|
+
addPaginationOptions(
|
|
13960
|
+
mail.command("relay-evidence").description(
|
|
13961
|
+
"Read bounded mailbox identity and recent message metadata for an explicitly authorized relay"
|
|
13962
|
+
).option("--account-id <accountId>")
|
|
13963
|
+
).action(async (opts, cmd) => {
|
|
13964
|
+
await runMailQuery(cmd, opts, {
|
|
13965
|
+
command: "mail.relay-evidence",
|
|
13966
|
+
operationName: "MailRelayEvidence",
|
|
13967
|
+
field: "mail_workspace",
|
|
13968
|
+
variables: mailWorkspaceVariables,
|
|
13969
|
+
variableTypes: {
|
|
13970
|
+
organization_id: "ID!",
|
|
13971
|
+
account_id: "ID",
|
|
13972
|
+
page: "Int",
|
|
13973
|
+
per: "Int"
|
|
13974
|
+
},
|
|
13975
|
+
selectionSet: MAIL_RELAY_EVIDENCE_SELECTION,
|
|
13976
|
+
isShow: true
|
|
13977
|
+
});
|
|
13978
|
+
});
|
|
13918
13979
|
mail.command("accounts").description("Read safe Mail account metadata").action(async (opts, cmd) => {
|
|
13919
13980
|
await runMailQuery(cmd, opts, {
|
|
13920
13981
|
command: "mail.accounts",
|
|
@@ -15956,7 +16017,7 @@ var URL_OR_TRANSPORT_KEY = /(?:^|_)(?:url|uri|token|nonce|post_fields|postfields
|
|
|
15956
16017
|
function isRecord7(value) {
|
|
15957
16018
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
15958
16019
|
}
|
|
15959
|
-
function
|
|
16020
|
+
function asNonEmptyString5(value) {
|
|
15960
16021
|
if (typeof value !== "string") return null;
|
|
15961
16022
|
const trimmed = value.trim();
|
|
15962
16023
|
return trimmed.length > 0 ? trimmed : null;
|
|
@@ -16001,7 +16062,7 @@ function parseCreatePayload(raw, mode) {
|
|
|
16001
16062
|
["name", "subject", "message", "expires_at", "visibility", "metadata", "recipients"],
|
|
16002
16063
|
"--data-json"
|
|
16003
16064
|
);
|
|
16004
|
-
const parsedMode =
|
|
16065
|
+
const parsedMode = asNonEmptyString5(mode);
|
|
16005
16066
|
if (parsedMode !== "request" && parsedMode !== "self_sign") {
|
|
16006
16067
|
throw new CliError({
|
|
16007
16068
|
message: "signatures create requires --mode request or --mode self_sign.",
|
|
@@ -16019,9 +16080,9 @@ function parseUpdatePayload(raw, options) {
|
|
|
16019
16080
|
["name", "subject", "message", "expires_at", "visibility", "recipients", "fields"],
|
|
16020
16081
|
"--data-json"
|
|
16021
16082
|
);
|
|
16022
|
-
const name =
|
|
16023
|
-
const subject =
|
|
16024
|
-
const message =
|
|
16083
|
+
const name = asNonEmptyString5(options.name);
|
|
16084
|
+
const subject = asNonEmptyString5(options.subject);
|
|
16085
|
+
const message = asNonEmptyString5(options.message);
|
|
16025
16086
|
const patch = {
|
|
16026
16087
|
...data,
|
|
16027
16088
|
...name ? { name } : {},
|
|
@@ -16156,8 +16217,8 @@ function requireUploadTarget(payload) {
|
|
|
16156
16217
|
exitCode: EXIT_CODES.networkOrUpstream
|
|
16157
16218
|
});
|
|
16158
16219
|
}
|
|
16159
|
-
const postUrl =
|
|
16160
|
-
const fileKey =
|
|
16220
|
+
const postUrl = asNonEmptyString5(attributes.postUrl);
|
|
16221
|
+
const fileKey = asNonEmptyString5(attributes.getUrl);
|
|
16161
16222
|
const rawPostFields = attributes.postFields;
|
|
16162
16223
|
if (!postUrl || !fileKey || !isRecord7(rawPostFields) || !fileKey.startsWith("uploads/signatures/")) {
|
|
16163
16224
|
throw new CliError({
|
|
@@ -16628,7 +16689,7 @@ var AUTOMATION_RUN_STATUS_SELECTION = `{
|
|
|
16628
16689
|
queuedAt
|
|
16629
16690
|
completedAt
|
|
16630
16691
|
}`;
|
|
16631
|
-
function
|
|
16692
|
+
function asRecord6(value) {
|
|
16632
16693
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
16633
16694
|
}
|
|
16634
16695
|
function asRequiredString(value) {
|
|
@@ -16659,7 +16720,7 @@ function requirePaginationInteger(value, key, minimum) {
|
|
|
16659
16720
|
});
|
|
16660
16721
|
}
|
|
16661
16722
|
function normalizeAutomationList(payload) {
|
|
16662
|
-
const page =
|
|
16723
|
+
const page = asRecord6(payload);
|
|
16663
16724
|
if (!page || !Array.isArray(page.data)) {
|
|
16664
16725
|
throw new CliError({
|
|
16665
16726
|
message: "Automation list response did not include a paginated data collection.",
|
|
@@ -16670,8 +16731,8 @@ function normalizeAutomationList(payload) {
|
|
|
16670
16731
|
}
|
|
16671
16732
|
const rows = page.data;
|
|
16672
16733
|
const data = rows.map((value) => {
|
|
16673
|
-
const row =
|
|
16674
|
-
const attributes =
|
|
16734
|
+
const row = asRecord6(value);
|
|
16735
|
+
const attributes = asRecord6(row?.attributes);
|
|
16675
16736
|
if (!row || !attributes) {
|
|
16676
16737
|
throw new CliError({
|
|
16677
16738
|
message: "Automation list response included a malformed automation record.",
|
|
@@ -16756,13 +16817,13 @@ function parseJsonOption(value, optionName, schema) {
|
|
|
16756
16817
|
return schema.parse(parseJson(String(value), optionName));
|
|
16757
16818
|
}
|
|
16758
16819
|
function normalizePersistedCreatePayload(payload) {
|
|
16759
|
-
const mutation =
|
|
16760
|
-
const mutationData =
|
|
16761
|
-
const persisted =
|
|
16762
|
-
const attributes =
|
|
16763
|
-
const automationExecution =
|
|
16764
|
-
const meta =
|
|
16765
|
-
const idempotency =
|
|
16820
|
+
const mutation = asRecord6(payload);
|
|
16821
|
+
const mutationData = asRecord6(mutation?.data);
|
|
16822
|
+
const persisted = asRecord6(mutationData?.data) ?? mutationData;
|
|
16823
|
+
const attributes = asRecord6(persisted?.attributes);
|
|
16824
|
+
const automationExecution = asRecord6(attributes?.automation_execution) ?? asRecord6(attributes?.automationExecution);
|
|
16825
|
+
const meta = asRecord6(mutationData?.meta);
|
|
16826
|
+
const idempotency = asRecord6(meta?.atlas_idempotency);
|
|
16766
16827
|
const id = asRequiredString(persisted?.id);
|
|
16767
16828
|
const slug = asRequiredString(persisted?.slug) ?? asRequiredString(attributes?.slug);
|
|
16768
16829
|
const replay = idempotency?.replay;
|
|
@@ -16793,10 +16854,10 @@ function normalizePersistedCreatePayload(payload) {
|
|
|
16793
16854
|
};
|
|
16794
16855
|
}
|
|
16795
16856
|
function normalizePersistedUpdatePayload(payload) {
|
|
16796
|
-
const mutation =
|
|
16797
|
-
const mutationData =
|
|
16798
|
-
const persisted =
|
|
16799
|
-
const attributes =
|
|
16857
|
+
const mutation = asRecord6(payload);
|
|
16858
|
+
const mutationData = asRecord6(mutation?.data);
|
|
16859
|
+
const persisted = asRecord6(mutationData?.data) ?? mutationData;
|
|
16860
|
+
const attributes = asRecord6(persisted?.attributes);
|
|
16800
16861
|
const id = asRequiredString(persisted?.id);
|
|
16801
16862
|
const slug = asRequiredString(persisted?.slug) ?? asRequiredString(attributes?.slug);
|
|
16802
16863
|
const updateVersion = asRequiredString(persisted?.updateVersion) ?? asRequiredString(attributes?.updateVersion) ?? asRequiredString(attributes?.update_version);
|
|
@@ -16817,7 +16878,7 @@ function normalizePersistedUpdatePayload(payload) {
|
|
|
16817
16878
|
};
|
|
16818
16879
|
}
|
|
16819
16880
|
function normalizeAutomationRunPayload(payload) {
|
|
16820
|
-
const mutation =
|
|
16881
|
+
const mutation = asRecord6(payload);
|
|
16821
16882
|
if (!mutation) {
|
|
16822
16883
|
throw new CliError({
|
|
16823
16884
|
message: "Automation run response did not include a mutation payload.",
|
|
@@ -16835,7 +16896,7 @@ function normalizeAutomationRunPayload(payload) {
|
|
|
16835
16896
|
data: mutation.data ?? null
|
|
16836
16897
|
};
|
|
16837
16898
|
}
|
|
16838
|
-
const data =
|
|
16899
|
+
const data = asRecord6(mutation.data);
|
|
16839
16900
|
const automationTaskId = asRequiredString(data?.automation_task_id);
|
|
16840
16901
|
const automationTaskSlug = asRequiredString(data?.automation_task_slug);
|
|
16841
16902
|
const agentId = asRequiredString(data?.agent_id);
|
|
@@ -17574,8 +17635,8 @@ name
|
|
|
17574
17635
|
categories
|
|
17575
17636
|
availability
|
|
17576
17637
|
integrationKey
|
|
17577
|
-
|
|
17578
|
-
|
|
17638
|
+
connectorProvider
|
|
17639
|
+
connectorService
|
|
17579
17640
|
logoAssetPath
|
|
17580
17641
|
`.trim();
|
|
17581
17642
|
var OVERVIEW_SELECTION = `
|
|
@@ -17909,6 +17970,7 @@ var PRIMARY_NAMESPACES = [
|
|
|
17909
17970
|
"support",
|
|
17910
17971
|
"recognition",
|
|
17911
17972
|
"whiteboards",
|
|
17973
|
+
"sketches",
|
|
17912
17974
|
"time-tracking",
|
|
17913
17975
|
"planner",
|
|
17914
17976
|
"mail",
|
|
@@ -17940,9 +18002,7 @@ var ADVANCED_NAMESPACES = [
|
|
|
17940
18002
|
"stand-ups",
|
|
17941
18003
|
"news",
|
|
17942
18004
|
"questions",
|
|
17943
|
-
"pulse",
|
|
17944
18005
|
"surveys",
|
|
17945
|
-
"feedbacks",
|
|
17946
18006
|
"accountability",
|
|
17947
18007
|
"kpis",
|
|
17948
18008
|
"scorecard-groups",
|
|
@@ -18256,6 +18316,28 @@ var NAMESPACE_DOCS = {
|
|
|
18256
18316
|
commands: ["open", "list", "show"]
|
|
18257
18317
|
}
|
|
18258
18318
|
},
|
|
18319
|
+
sketches: {
|
|
18320
|
+
name: "sketches",
|
|
18321
|
+
tier: "primary",
|
|
18322
|
+
description: "Sketch metadata, bounded create/update operations, and verified app-route metadata.",
|
|
18323
|
+
examples: [
|
|
18324
|
+
"wave sketches list --page 1 --per 20",
|
|
18325
|
+
"wave sketches show --slug SKT-02",
|
|
18326
|
+
`wave sketches create --data-json '{"name":"Design review","teams_ids":["team-1"],"creation_key":"design-review-1"}'`,
|
|
18327
|
+
`wave sketches update-metadata --id 123 --data-json '{"name":"Design review"}'`,
|
|
18328
|
+
"wave sketches open"
|
|
18329
|
+
],
|
|
18330
|
+
schema: {
|
|
18331
|
+
output: "json-envelope-default",
|
|
18332
|
+
mutates: true,
|
|
18333
|
+
safety: [
|
|
18334
|
+
"Uses verified GraphQL fields sketches, sketch, createSketch, and updateSketch.",
|
|
18335
|
+
"Create requires a team and an idempotency creation key; update accepts only bounded metadata fields.",
|
|
18336
|
+
"Never accepts or emits native document bytes, collaboration updates, render/export data, embedded files, comments, or tokens."
|
|
18337
|
+
],
|
|
18338
|
+
commands: ["open", "list", "show", "create", "update-metadata"]
|
|
18339
|
+
}
|
|
18340
|
+
},
|
|
18259
18341
|
"time-tracking": {
|
|
18260
18342
|
name: "time-tracking",
|
|
18261
18343
|
tier: "primary",
|
|
@@ -18316,9 +18398,10 @@ var NAMESPACE_DOCS = {
|
|
|
18316
18398
|
mail: {
|
|
18317
18399
|
name: "mail",
|
|
18318
18400
|
tier: "primary",
|
|
18319
|
-
description: "Mail read-only metadata for workspace, accounts, messages, conversations, labels, snippets, settings, sync status, and verified app route metadata.",
|
|
18401
|
+
description: "Mail read-only metadata for workspace, explicitly authorized relay evidence, accounts, messages, conversations, labels, snippets, settings, sync status, and verified app route metadata.",
|
|
18320
18402
|
examples: [
|
|
18321
18403
|
"wave mail workspace --page 1 --per 20",
|
|
18404
|
+
"wave mail relay-evidence --account-id 123 --page 1 --per 20",
|
|
18322
18405
|
"wave mail accounts",
|
|
18323
18406
|
"wave mail messages --account-id 123 --view inbox --page 1 --per 20",
|
|
18324
18407
|
"wave mail conversations --account-id 123 --view inbox --page 1 --per 20",
|
|
@@ -18340,7 +18423,8 @@ var NAMESPACE_DOCS = {
|
|
|
18340
18423
|
"Microsoft Outlook Mail maps to service outlook_mail and Outlook Calendar maps to service outlook_calendar with custom OAuth provider wave-microsoft-outlook.",
|
|
18341
18424
|
"Uses the verified WAVE-03 safe app route /mail.",
|
|
18342
18425
|
"Account output is limited to ids, provider/service, status, connection state, sync status, and timestamps.",
|
|
18343
|
-
"
|
|
18426
|
+
"Default message and conversation output omits bodies, subjects, snippets, contacts, attachments, provider payloads, provider ids, raw thread ids, and user-authored mail content.",
|
|
18427
|
+
"relay-evidence is an explicit authenticated relay surface limited to mailbox identity plus sender, subject, date, and snippet metadata; it still omits bodies, recipients, attachments, provider ids, and token material.",
|
|
18344
18428
|
"Label, snippet, settings, and sync-status output omits user label names/colors, snippet title/shortcut/body, signatures, preferences, sync search text, operation reasons, error bodies, and token material.",
|
|
18345
18429
|
"Does not expose send, reply, reply-all, forward, draft, provider-action, sync/connect/disconnect, mark, archive, trash, star, label/snippet CRUD, export, print, or write commands."
|
|
18346
18430
|
],
|
|
@@ -18348,6 +18432,7 @@ var NAMESPACE_DOCS = {
|
|
|
18348
18432
|
"open",
|
|
18349
18433
|
"validate-provider",
|
|
18350
18434
|
"workspace",
|
|
18435
|
+
"relay-evidence",
|
|
18351
18436
|
"accounts",
|
|
18352
18437
|
"messages",
|
|
18353
18438
|
"conversations",
|
|
@@ -18944,7 +19029,11 @@ function buildCli(options) {
|
|
|
18944
19029
|
"Explicit organization ID override"
|
|
18945
19030
|
).option(
|
|
18946
19031
|
"--config <configPath>",
|
|
18947
|
-
"Optional JSON config file (default:
|
|
19032
|
+
"Optional JSON config file (default: ~/.wave/config.json when present)"
|
|
19033
|
+
).addOption(
|
|
19034
|
+
new import_commander2.Option("--auth-home <path>", "Credential storage directory (default: ~/.wave)")
|
|
19035
|
+
).addOption(
|
|
19036
|
+
new import_commander2.Option("--auth-storage <mode>", "Credential storage mode").choices(["auto", "keychain", "file", "disabled"]).default("auto")
|
|
18948
19037
|
).option("--timeout-ms <timeoutMs>", "HTTP timeout in milliseconds").option("--agent-name <agentName>", "Agent name for tracing").option("--agent-run-id <agentRunId>", "Agent run identifier for tracing").option("--request-id <requestId>", "Request identifier").option(
|
|
18949
19038
|
"--atlas-member-id <memberId>",
|
|
18950
19039
|
"Atlas ledger member ID (prefer WAVE_ATLAS_MEMBER_ID env var)"
|
|
@@ -18976,6 +19065,14 @@ function buildCli(options) {
|
|
|
18976
19065
|
"--openapi-version <openapiVersion>",
|
|
18977
19066
|
"Optional pinned OpenAPI version/hash"
|
|
18978
19067
|
).exitOverride();
|
|
19068
|
+
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
19069
|
+
const runtimeOptions = actionCommand.optsWithGlobals();
|
|
19070
|
+
configureAuthStorage({
|
|
19071
|
+
...runtimeOptions.authHome ? { home: runtimeOptions.authHome } : {},
|
|
19072
|
+
...runtimeOptions.config ? { configPath: runtimeOptions.config } : {},
|
|
19073
|
+
...runtimeOptions.authStorage ? { mode: runtimeOptions.authStorage } : {}
|
|
19074
|
+
});
|
|
19075
|
+
});
|
|
18979
19076
|
setInternalCliOptions(program, options?.internal);
|
|
18980
19077
|
registerTaskCommands(program);
|
|
18981
19078
|
registerProjectCommands(program);
|
|
@@ -19000,6 +19097,7 @@ function buildCli(options) {
|
|
|
19000
19097
|
registerSupportCommands(program);
|
|
19001
19098
|
registerRecognitionCommands(program);
|
|
19002
19099
|
registerWhiteboardsCommands(program);
|
|
19100
|
+
registerSketchCommands(program);
|
|
19003
19101
|
registerTimeTrackingCommands(program);
|
|
19004
19102
|
registerPlannerCommands(program);
|
|
19005
19103
|
registerMailCommands(program);
|
|
@@ -19264,9 +19362,10 @@ function withTrustedMachineAuth(auth, callback) {
|
|
|
19264
19362
|
for (const key of Object.keys(process.env)) {
|
|
19265
19363
|
if (key.startsWith("WAVE_")) delete process.env[key];
|
|
19266
19364
|
}
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
|
|
19365
|
+
return withAuthStorageOptions(
|
|
19366
|
+
{ home: "/dev/null", mode: "disabled" },
|
|
19367
|
+
() => withMachineRuntimeAuth(auth, callback)
|
|
19368
|
+
).finally(() => {
|
|
19270
19369
|
for (const key of Object.keys(process.env)) {
|
|
19271
19370
|
if (key.startsWith("WAVE_")) delete process.env[key];
|
|
19272
19371
|
}
|
|
@@ -19473,7 +19572,15 @@ async function maybeRunMachineExecute(argv, program) {
|
|
|
19473
19572
|
}
|
|
19474
19573
|
try {
|
|
19475
19574
|
await withTrustedMachineAuth(auth, async () => {
|
|
19476
|
-
await program.parseAsync([
|
|
19575
|
+
await program.parseAsync([
|
|
19576
|
+
process.execPath,
|
|
19577
|
+
"wave",
|
|
19578
|
+
"--auth-storage",
|
|
19579
|
+
"disabled",
|
|
19580
|
+
"--auth-home",
|
|
19581
|
+
"/dev/null",
|
|
19582
|
+
...commandArgs(resolved.command, normalizedInput)
|
|
19583
|
+
]);
|
|
19477
19584
|
});
|
|
19478
19585
|
} catch (error) {
|
|
19479
19586
|
if (isEnvelopeEmittedSignal(error)) return true;
|