@wave-ai-os/wave-cli 0.1.87 → 0.2.0
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 +6 -20
- package/dist/index.cjs +1660 -1343
- package/dist/index.js +1652 -1335
- package/package.json +6 -1
- package/scripts/check-goals-domain.mjs +35 -0
- package/scripts/verify-dev-api.mjs +11 -162
- package/scripts/verify-goals-artifact.mjs +37 -0
- package/scripts/verify-reminder-artifact.mjs +34 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wave-ai-os/wave-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"wave": "dist/index.js"
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
"build": "tsup src/index.ts --format esm,cjs --dts --clean",
|
|
14
14
|
"dev": "node --disable-warning=DEP0205 --import tsx src/index.ts",
|
|
15
15
|
"test": "vitest run",
|
|
16
|
+
"test:reminders": "npm run build && vitest run test/reminders_commands.test.ts test/reminders_artifact.test.ts && npm run verify:reminders-artifact",
|
|
17
|
+
"verify:reminders-artifact": "node scripts/verify-reminder-artifact.mjs",
|
|
18
|
+
"verify:goals-artifact": "node scripts/verify-goals-artifact.mjs",
|
|
19
|
+
"prepack": "npm run build && npm run verify:reminders-artifact && npm run verify:goals-artifact",
|
|
20
|
+
"prepublishOnly": "npm run verify:reminders-artifact && npm run verify:goals-artifact",
|
|
16
21
|
"verify:dev": "node scripts/verify-dev-api.mjs",
|
|
17
22
|
"benchmark:cli": "node scripts/benchmark-cli.mjs",
|
|
18
23
|
"postinstall": "node scripts/postinstall-local-bin.mjs"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
7
|
+
// These are migration, immutable history, compatibility, or negative-control
|
|
8
|
+
// sources. They intentionally retain old identifiers; active contracts must not.
|
|
9
|
+
const exceptions = [
|
|
10
|
+
"test/goals_contract.test.ts",
|
|
11
|
+
"scripts/verify-goals-artifact.mjs"
|
|
12
|
+
];
|
|
13
|
+
const self = 'scripts/check-goals-domain.mjs';
|
|
14
|
+
const legacy = /(?<![A-Za-z])rocks?(?=[^a-z]|$)|(?<=\\b)rocks?(?=[^a-z]|$)|Rocks?(?![a-z])|ROCKS?(?![A-Z])/;
|
|
15
|
+
const excepted = (path) => path === self || exceptions.some((entry) => entry.endsWith('/') ? path.startsWith(entry) : path === entry);
|
|
16
|
+
let output = '';
|
|
17
|
+
try {
|
|
18
|
+
output = execFileSync('git', ['grep', '--untracked', '-I', '-n', '-i', 'rock', '--', '.'], { cwd: root, encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 });
|
|
19
|
+
} catch (error) {
|
|
20
|
+
if (error.status !== 1) throw error;
|
|
21
|
+
}
|
|
22
|
+
const failures = output.split('\n').filter(Boolean).filter((line) => {
|
|
23
|
+
const separator = line.indexOf(':');
|
|
24
|
+
return !excepted(line.slice(0, separator)) && legacy.test(line.slice(separator + 1));
|
|
25
|
+
});
|
|
26
|
+
const files = execFileSync('git', ['ls-files', '--cached', '--others', '--exclude-standard', '-z'], { cwd: root, encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 }).split('\0').filter(Boolean);
|
|
27
|
+
for (const path of new Set(files)) {
|
|
28
|
+
if (!excepted(path) && existsSync(resolve(root, path)) && legacy.test(path)) failures.push(`Legacy domain filename: ${path}`);
|
|
29
|
+
}
|
|
30
|
+
if (failures.length) {
|
|
31
|
+
process.stderr.write(failures.join('\n') + '\n');
|
|
32
|
+
process.exitCode = 1;
|
|
33
|
+
} else {
|
|
34
|
+
process.stdout.write('Goals domain guard passed: no retired feature identifiers outside declared compatibility/history boundaries.\n');
|
|
35
|
+
}
|
|
@@ -365,7 +365,7 @@ const idLookup = {};
|
|
|
365
365
|
const listSeeds = [
|
|
366
366
|
["projects", ["projects", "list", "--page", "1", "--per", "2"]],
|
|
367
367
|
["tasks", ["tasks", "list", "--page", "1", "--per", "2"]],
|
|
368
|
-
["
|
|
368
|
+
["goals", ["goals", "list", "--page", "1", "--per", "2"]],
|
|
369
369
|
["meetings", ["meetings", "list", "--per", "2"]],
|
|
370
370
|
["members", ["members", "list", "--page", "1", "--per", "2"]],
|
|
371
371
|
["teams", ["teams", "list", "--page", "1", "--per", "2"]],
|
|
@@ -375,14 +375,12 @@ const listSeeds = [
|
|
|
375
375
|
["issueGroups", ["issue-groups", "list", "--page", "1", "--per", "2"]],
|
|
376
376
|
["todoGroups", ["todo-groups", "list", "--page", "1", "--per", "2"]],
|
|
377
377
|
["todos", ["todos", "list", "--page", "1", "--per", "2"]],
|
|
378
|
-
["
|
|
378
|
+
["goalCollections", ["goal-collections", "list", "--page", "1", "--per", "2"]],
|
|
379
379
|
["knowledge", ["knowledge", "list", "--page", "1", "--per", "2"]],
|
|
380
380
|
["standUps", ["stand-ups", "list", "--page", "1", "--per", "2"]],
|
|
381
381
|
["news", ["news", "list", "--page", "1", "--per", "2"]],
|
|
382
382
|
["questions", ["questions", "list", "--page", "1", "--per", "2"]],
|
|
383
|
-
["pulse", ["pulse", "list", "--page", "1", "--per", "2"]],
|
|
384
383
|
["surveys", ["surveys", "list", "--page", "1", "--per", "2"]],
|
|
385
|
-
["feedbacks", ["feedbacks", "list", "--page", "1", "--per", "2"]],
|
|
386
384
|
["accountability", ["accountability", "list", "--page", "1", "--per", "2"]],
|
|
387
385
|
["kpis", ["kpis", "list", "--page", "1", "--per", "2"]],
|
|
388
386
|
["scorecardGroups", ["scorecard-groups", "list", "--page", "1", "--per", "2"]],
|
|
@@ -422,7 +420,7 @@ for (const [key, args] of listSeeds) {
|
|
|
422
420
|
|
|
423
421
|
const projectId = idLookup.projects;
|
|
424
422
|
const taskId = idLookup.tasks;
|
|
425
|
-
const
|
|
423
|
+
const goalId = idLookup.goals;
|
|
426
424
|
const meetingId = idLookup.meetings;
|
|
427
425
|
const memberId = idLookup.members;
|
|
428
426
|
const teamId = idLookup.teams;
|
|
@@ -432,14 +430,12 @@ const listId = idLookup.lists;
|
|
|
432
430
|
const listItemId = idLookup.listItems;
|
|
433
431
|
const todoGroupId = idLookup.todoGroups;
|
|
434
432
|
const todoId = idLookup.todos;
|
|
435
|
-
const
|
|
433
|
+
const goalCollectionId = idLookup.goalCollections;
|
|
436
434
|
const contentId = idLookup.knowledge;
|
|
437
435
|
const standUpId = idLookup.standUps;
|
|
438
436
|
const headlineId = idLookup.news;
|
|
439
437
|
const questionId = idLookup.questions;
|
|
440
|
-
const pulseId = idLookup.pulse;
|
|
441
438
|
const surveyId = idLookup.surveys;
|
|
442
|
-
const feedbackId = idLookup.feedbacks;
|
|
443
439
|
const responsibilityId = idLookup.accountability;
|
|
444
440
|
const kpiId = idLookup.kpis;
|
|
445
441
|
const kpiSmartKpiViewId = idLookup.kpiSmartKpiViewId;
|
|
@@ -456,7 +452,6 @@ const orgMetaOneSentenceSummaryVerify = `Verify Title ${verifyStamp}`;
|
|
|
456
452
|
const keyMetricRevenueVerify = String(1000 + Number(verifyStamp.slice(-3)));
|
|
457
453
|
const questionNameVerify = `CLI Verify Question Update ${verifyStamp}`;
|
|
458
454
|
const surveyDueDateVerify = "2026-12-31";
|
|
459
|
-
const feedbackQuarterVerify = "q3";
|
|
460
455
|
const accountabilityNameVerify = `CLI Verify Responsibility Update ${verifyStamp}`;
|
|
461
456
|
const organizationMetaProfileSeed = runWave(
|
|
462
457
|
["organizations", "meta-profile", "show", "--id", orgId],
|
|
@@ -497,7 +492,7 @@ const meetingCreatePayload = teamId
|
|
|
497
492
|
const probes = [
|
|
498
493
|
["projects", "show", "--id", projectId],
|
|
499
494
|
["tasks", "show", "--id", taskId],
|
|
500
|
-
["
|
|
495
|
+
["goals", "show", "--id", goalId],
|
|
501
496
|
["meetings", "show", "--id", meetingId],
|
|
502
497
|
["members", "show", "--id", memberId],
|
|
503
498
|
["teams", "show", "--id", teamId],
|
|
@@ -507,14 +502,12 @@ const probes = [
|
|
|
507
502
|
["issue-groups", "show", "--id", issueGroupId],
|
|
508
503
|
["todo-groups", "show", "--id", todoGroupId],
|
|
509
504
|
["todos", "show", "--id", todoId],
|
|
510
|
-
["
|
|
505
|
+
["goal-collections", "show", "--id", goalCollectionId],
|
|
511
506
|
["knowledge", "show", "--id", contentId],
|
|
512
507
|
["stand-ups", "show", "--id", standUpId],
|
|
513
508
|
["news", "show", "--id", headlineId],
|
|
514
509
|
["questions", "show", "--id", questionId],
|
|
515
|
-
["pulse", "show", "--id", pulseId],
|
|
516
510
|
["surveys", "show", "--id", surveyId],
|
|
517
|
-
["feedbacks", "show", "--id", feedbackId],
|
|
518
511
|
["accountability", "show", "--id", responsibilityId],
|
|
519
512
|
["kpis", "show", "--id", kpiId],
|
|
520
513
|
["scorecard-groups", "show", "--id", measurableGroupId],
|
|
@@ -532,9 +525,9 @@ const probes = [
|
|
|
532
525
|
["projects", "update", "--id", projectId, "--data-json", payload("project", { description: "verify-update" })],
|
|
533
526
|
["tasks", "create", "--project-id", projectId, "--summary", "CLI verify task"],
|
|
534
527
|
["tasks", "update", "--id", taskId, "--summary", "CLI verify task update"],
|
|
535
|
-
["
|
|
536
|
-
["
|
|
537
|
-
["
|
|
528
|
+
["goals", "update-status", "--id", goalId, "--status", "on_track"],
|
|
529
|
+
["goals", "create", "--data-json", payload("goal", { name: "CLI Verify Goal", goal_collection_id: goalCollectionId, status: "on_track", priority: "no_priority", goal_type: "individual" })],
|
|
530
|
+
["goals", "update", "--id", goalId, "--data-json", payload("goal", { description: "verify-update" })],
|
|
538
531
|
["meetings", "notes", "--id", meetingId, "--content", "CLI verify notes"],
|
|
539
532
|
["meetings", "create", "--data-json", payload("meeting", meetingCreatePayload)],
|
|
540
533
|
["meetings", "update", "--id", meetingId, "--data-json", payload("meeting", { notes: "verify-update" })],
|
|
@@ -557,8 +550,8 @@ const probes = [
|
|
|
557
550
|
["todo-groups", "update", "--id", todoGroupId, "--data-json", payload("todo_group", { description: "verify-update" })],
|
|
558
551
|
["todos", "create", "--data-json", payload("todo", { todo_group_id: todoGroupId, name: "CLI Verify Todo", status: "open", priority: "no_priority" })],
|
|
559
552
|
["todos", "update", "--id", todoId, "--data-json", payload("todo", { description: "verify-update" })],
|
|
560
|
-
["
|
|
561
|
-
["
|
|
553
|
+
["goal-collections", "create", "--data-json", payload("goal_collection", { name: "CLI Verify Goal Collection", status: "in_progress", priority: "no_priority" })],
|
|
554
|
+
["goal-collections", "update", "--id", goalCollectionId, "--data-json", payload("goal_collection", { description: "verify-update" })],
|
|
562
555
|
["knowledge", "create", "--data-json", payload("content", { content_type: "process", status: "draft", name: "CLI Verify Doc", member_id: memberId })],
|
|
563
556
|
["knowledge", "update", "--id", contentId, "--data-json", payload("content", { name: "CLI Verify Doc Update" })],
|
|
564
557
|
["stand-ups", "create", "--data-json", payload("stand_up", { member_id: memberId, completed_date: "2026-04-06" })],
|
|
@@ -567,12 +560,8 @@ const probes = [
|
|
|
567
560
|
["news", "update", "--id", headlineId, "--data-json", payload("headline", { description: "verify-update" })],
|
|
568
561
|
["questions", "create", "--data-json", payload("question", { name: "CLI Verify Question", member_id: memberId })],
|
|
569
562
|
["questions", "update", "--id", questionId, "--data-json", payload("question", { name: questionNameVerify, description: "verify-update" })],
|
|
570
|
-
["pulse", "create", "--data-json", payload("health_update", { health_updatable_id: projectId, health_updatable_type: "Project", member_id: memberId, value: "on_track", status: "on_track" })],
|
|
571
|
-
["pulse", "update", "--id", pulseId, "--data-json", payload("health_update", { value: "verify-update" })],
|
|
572
563
|
["surveys", "create", "--data-json", payload("survey", { name: "engagement", recipient_type: "org_wide" })],
|
|
573
564
|
["surveys", "update", "--id", surveyId, "--data-json", payload("survey", { name: "engagement", recipient_type: "org_wide", due_date: surveyDueDateVerify })],
|
|
574
|
-
["feedbacks", "create", "--data-json", payload("feedback", { name: "company_culture", quarter: "q2", year: "2026" })],
|
|
575
|
-
["feedbacks", "update", "--id", feedbackId, "--data-json", payload("feedback", { name: "roadmap_and_strategy", quarter: feedbackQuarterVerify, year: "2026" })],
|
|
576
565
|
["accountability", "create", "--data-json", payload("responsibility", { name: "CLI Verify Responsibility", member_id: memberId })],
|
|
577
566
|
["accountability", "update", "--id", responsibilityId, "--data-json", payload("responsibility", { name: accountabilityNameVerify })],
|
|
578
567
|
["kpis", "create", "--data-json", payload("smart_kpi", { smart_kpi_view_id: kpiSmartKpiViewId, name: kpiCreateName })],
|
|
@@ -611,7 +600,6 @@ for (const args of probes) {
|
|
|
611
600
|
|
|
612
601
|
const validationRemediationEntries = [];
|
|
613
602
|
let validationRemediationFailures = 0;
|
|
614
|
-
let feedbackQuarterExpected = feedbackQuarterVerify;
|
|
615
603
|
|
|
616
604
|
function recordValidationRemediation(entry) {
|
|
617
605
|
validationRemediationEntries.push(entry);
|
|
@@ -717,136 +705,6 @@ function remediateStandupsCreateDuplicateDate() {
|
|
|
717
705
|
}
|
|
718
706
|
}
|
|
719
707
|
|
|
720
|
-
function remediateFeedbacksUpdateDuplicateName() {
|
|
721
|
-
const operation = "feedbacks.update";
|
|
722
|
-
const initial = findFirstResultByPrefix(results, ["feedbacks", "update"]);
|
|
723
|
-
if (!initial) {
|
|
724
|
-
recordValidationRemediation({
|
|
725
|
-
operation,
|
|
726
|
-
offendingFields: ["feedback.name"],
|
|
727
|
-
backendMessage: "initial probe missing",
|
|
728
|
-
initialResult: "missing",
|
|
729
|
-
remediation: "none",
|
|
730
|
-
finalResult: "missing"
|
|
731
|
-
});
|
|
732
|
-
validationRemediationFailures += 1;
|
|
733
|
-
return;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
const messages = extractValidationMessages(initial);
|
|
737
|
-
const isDuplicateNameValidation =
|
|
738
|
-
isValidationErrorResult(initial) &&
|
|
739
|
-
messages.some((msg) => /name has already been taken/i.test(msg));
|
|
740
|
-
|
|
741
|
-
if (!isDuplicateNameValidation) {
|
|
742
|
-
recordValidationRemediation({
|
|
743
|
-
operation,
|
|
744
|
-
offendingFields: ["feedback.name"],
|
|
745
|
-
backendMessage: messages[0] ?? "",
|
|
746
|
-
initialResult: summarizeStatus(initial),
|
|
747
|
-
remediation: "none_not_required",
|
|
748
|
-
finalResult: summarizeStatus(initial)
|
|
749
|
-
});
|
|
750
|
-
return;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
const initialPayload = parseDataJsonFromArgs(initial.args);
|
|
754
|
-
const feedbackBody =
|
|
755
|
-
initialPayload && typeof initialPayload.feedback === "object" ? initialPayload.feedback : null;
|
|
756
|
-
const originalName =
|
|
757
|
-
feedbackBody && typeof feedbackBody.name === "string" ? feedbackBody.name : "feedback";
|
|
758
|
-
|
|
759
|
-
if (!feedbackBody) {
|
|
760
|
-
recordValidationRemediation({
|
|
761
|
-
operation,
|
|
762
|
-
offendingFields: ["feedback.name"],
|
|
763
|
-
backendMessage: messages[0] ?? "",
|
|
764
|
-
initialResult: summarizeStatus(initial),
|
|
765
|
-
remediation: "failed_missing_feedback_payload",
|
|
766
|
-
finalResult: summarizeStatus(initial)
|
|
767
|
-
});
|
|
768
|
-
validationRemediationFailures += 1;
|
|
769
|
-
return;
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
const feedbackId = getArgValue(initial.args, "--id");
|
|
773
|
-
if (!feedbackId) {
|
|
774
|
-
recordValidationRemediation({
|
|
775
|
-
operation,
|
|
776
|
-
offendingFields: ["feedback.name", "feedback.year"],
|
|
777
|
-
backendMessage: messages[0] ?? "",
|
|
778
|
-
initialResult: summarizeStatus(initial),
|
|
779
|
-
remediation: "failed_missing_feedback_id",
|
|
780
|
-
finalResult: summarizeStatus(initial)
|
|
781
|
-
});
|
|
782
|
-
validationRemediationFailures += 1;
|
|
783
|
-
return;
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
const showArgs = ["feedbacks", "show", "--id", String(feedbackId)];
|
|
787
|
-
const showResult = runWave(showArgs, env);
|
|
788
|
-
results.push(showResult);
|
|
789
|
-
|
|
790
|
-
const currentName = firstDefinedValue(showResult?.parsed, [
|
|
791
|
-
["data", "feedback", "attributes", "name"],
|
|
792
|
-
["data", "feedback", "name"]
|
|
793
|
-
]);
|
|
794
|
-
const currentQuarter = firstDefinedValue(showResult?.parsed, [
|
|
795
|
-
["data", "feedback", "attributes", "quarter"],
|
|
796
|
-
["data", "feedback", "quarter"]
|
|
797
|
-
]);
|
|
798
|
-
const currentYear = firstDefinedValue(showResult?.parsed, [
|
|
799
|
-
["data", "feedback", "attributes", "year"],
|
|
800
|
-
["data", "feedback", "year"]
|
|
801
|
-
]);
|
|
802
|
-
|
|
803
|
-
if (!showResult.parsed?.ok || !currentName || !currentQuarter) {
|
|
804
|
-
recordValidationRemediation({
|
|
805
|
-
operation,
|
|
806
|
-
offendingFields: ["feedback.name", "feedback.year"],
|
|
807
|
-
backendMessage: messages[0] ?? "",
|
|
808
|
-
initialResult: summarizeStatus(initial),
|
|
809
|
-
remediation: `failed_feedback_show_lookup id=${feedbackId};lookup=${summarizeStatus(showResult)}`,
|
|
810
|
-
finalResult: summarizeStatus(initial)
|
|
811
|
-
});
|
|
812
|
-
validationRemediationFailures += 1;
|
|
813
|
-
return;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
const parsedYear = Number.parseInt(String(currentYear ?? ""), 10);
|
|
817
|
-
const remediatedYear = Number.isFinite(parsedYear) ? parsedYear + 1 : 2030;
|
|
818
|
-
const nextPayload = {
|
|
819
|
-
feedback: {
|
|
820
|
-
...feedbackBody,
|
|
821
|
-
name: String(currentName),
|
|
822
|
-
quarter: String(currentQuarter),
|
|
823
|
-
year: String(remediatedYear)
|
|
824
|
-
}
|
|
825
|
-
};
|
|
826
|
-
const retryArgs = withUpdatedDataJson(initial.args, nextPayload);
|
|
827
|
-
const finalResult = runWave(retryArgs, env);
|
|
828
|
-
results.push(finalResult);
|
|
829
|
-
|
|
830
|
-
recordValidationRemediation({
|
|
831
|
-
operation,
|
|
832
|
-
offendingFields: ["feedback.name", "feedback.year"],
|
|
833
|
-
backendMessage: messages[0] ?? "",
|
|
834
|
-
initialResult: summarizeStatus(initial),
|
|
835
|
-
remediation:
|
|
836
|
-
`fallback_non_unique_field original_name=${originalName}` +
|
|
837
|
-
` remediated_name=${String(currentName)}` +
|
|
838
|
-
` remediated_quarter=${String(currentQuarter)}` +
|
|
839
|
-
` remediated_year=${String(remediatedYear)}`,
|
|
840
|
-
finalResult: summarizeStatus(finalResult)
|
|
841
|
-
});
|
|
842
|
-
|
|
843
|
-
if (finalResult.parsed?.ok !== true) {
|
|
844
|
-
validationRemediationFailures += 1;
|
|
845
|
-
} else {
|
|
846
|
-
feedbackQuarterExpected = String(currentQuarter);
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
|
|
850
708
|
function remediateQuarterlyObjectiveParentMismatch() {
|
|
851
709
|
const operation = "foundation.quarterly-objectives.create";
|
|
852
710
|
const initial = findFirstResultByPrefix(results, [
|
|
@@ -952,7 +810,6 @@ function remediateQuarterlyObjectiveParentMismatch() {
|
|
|
952
810
|
}
|
|
953
811
|
|
|
954
812
|
remediateStandupsCreateDuplicateDate();
|
|
955
|
-
remediateFeedbacksUpdateDuplicateName();
|
|
956
813
|
remediateQuarterlyObjectiveParentMismatch();
|
|
957
814
|
|
|
958
815
|
let deleteVerifyLine = "";
|
|
@@ -1119,14 +976,6 @@ verifyFieldWrite({
|
|
|
1119
976
|
]
|
|
1120
977
|
});
|
|
1121
978
|
|
|
1122
|
-
verifyFieldWrite({
|
|
1123
|
-
label: "feedbacks.update verify quarter",
|
|
1124
|
-
showArgs: ["feedbacks", "show", "--id", feedbackId],
|
|
1125
|
-
expectedValue: feedbackQuarterExpected,
|
|
1126
|
-
requiredSuccessPrefix: ["feedbacks", "update"],
|
|
1127
|
-
candidatePaths: [["data", "feedback", "attributes", "quarter"]]
|
|
1128
|
-
});
|
|
1129
|
-
|
|
1130
979
|
verifyFieldWrite({
|
|
1131
980
|
label: "accountability.update verify name",
|
|
1132
981
|
showArgs: ["accountability", "show", "--id", responsibilityId],
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
const entrypoint = resolve(process.env.GOALS_PROOF_CLI_BIN || "dist/index.js");
|
|
7
|
+
const run = (...args) => {
|
|
8
|
+
const result = spawnSync(process.execPath, [entrypoint, ...args], { encoding: "utf8", timeout: 15000 });
|
|
9
|
+
assert.ifError(result.error);
|
|
10
|
+
assert.equal(result.status, 0, result.stderr);
|
|
11
|
+
return result.stdout;
|
|
12
|
+
};
|
|
13
|
+
const discovery = run("api", "ls", "--readable");
|
|
14
|
+
const operations = [];
|
|
15
|
+
for (const namespace of ["goals", "goal-collections"]) {
|
|
16
|
+
const commands = ["list", "show", "search", "create", "update", "schema", "examples"];
|
|
17
|
+
if (namespace === "goals") commands.push("update-status");
|
|
18
|
+
const help = run(namespace, "--help");
|
|
19
|
+
assert.match(help, new RegExp(`^Usage: wave ${namespace} `));
|
|
20
|
+
for (const command of commands) {
|
|
21
|
+
assert.match(help, new RegExp(`^\\s+${command}(?:\\s|$)`, "m"));
|
|
22
|
+
assert.ok(discovery.split("\n").some(line => line.trim() === `wave ${namespace} ${command}`), `${namespace}.${command} missing from discovery`);
|
|
23
|
+
operations.push(`${namespace}.${command}`);
|
|
24
|
+
}
|
|
25
|
+
for (const command of ["schema", "examples"]) {
|
|
26
|
+
const output = JSON.parse(run(namespace, command));
|
|
27
|
+
assert.equal(output.ok, true);
|
|
28
|
+
assert.equal(output.command, `${namespace}.${command}`);
|
|
29
|
+
if (command === "schema") assert.equal(output.data.namespace.name, namespace);
|
|
30
|
+
else assert.ok(output.data.examples.every(example => example.startsWith(`wave ${namespace} `)));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
assert.match(run("goals", "list", "--help"), /--goal-collection-id/);
|
|
34
|
+
assert.match(run("goals", "list", "--help"), /--goal-type/);
|
|
35
|
+
assert.match(run("milestones", "list", "--help"), /--goal-id/);
|
|
36
|
+
assert.doesNotMatch(discovery, /\brocks?\b|rock[_-]/i);
|
|
37
|
+
process.stdout.write(`${JSON.stringify({ ok: true, artifact: entrypoint, operations })}\n`);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
const entrypoint = resolve("dist/index.js");
|
|
7
|
+
const requiredCommands = ["list", "show", "create", "update", "clear", "destroy"];
|
|
8
|
+
|
|
9
|
+
if (!existsSync(entrypoint)) {
|
|
10
|
+
throw new Error("Missing dist/index.js. Run npm run build before verifying the release artifact.");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const result = spawnSync(process.execPath, [entrypoint, "reminders", "--help"], {
|
|
14
|
+
cwd: process.cwd(),
|
|
15
|
+
encoding: "utf8",
|
|
16
|
+
env: process.env
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
if (result.status !== 0) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Reminder release artifact failed with exit ${String(result.status)}: ${result.stderr || result.stdout}`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const missing = requiredCommands.filter(
|
|
26
|
+
(command) => !new RegExp(`^\\s+${command}(?:\\s|$)`, "m").test(result.stdout)
|
|
27
|
+
);
|
|
28
|
+
if (missing.length > 0) {
|
|
29
|
+
throw new Error(`Reminder release artifact is missing commands: ${missing.join(", ")}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
process.stdout.write(
|
|
33
|
+
`${JSON.stringify({ ok: true, artifact: entrypoint, namespace: "reminders", commands: requiredCommands })}\n`
|
|
34
|
+
);
|