@llblab/pi-kit 0.3.2 → 0.5.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/AGENTS.md +3 -3
- package/BACKLOG.md +1 -1
- package/CHANGELOG.md +10 -0
- package/README.md +19 -10
- package/node_modules/@llblab/pi-actors/AGENTS.md +1 -0
- package/node_modules/@llblab/pi-actors/CHANGELOG.md +6 -0
- package/node_modules/@llblab/pi-actors/dist/skills/actors/SKILL.md +16 -6
- package/node_modules/@llblab/pi-actors/dist/skills/music-player/SKILL.md +3 -3
- package/node_modules/@llblab/pi-actors/dist/skills/music-player/genapps/music-player.mjs +6 -4
- package/node_modules/@llblab/pi-actors/dist/skills/music-player/scripts/playback.mjs +85 -18
- package/node_modules/@llblab/pi-actors/dist/skills/swarm/SKILL.md +2 -6
- package/node_modules/@llblab/pi-actors/dist/skills/swarm/references/development-swarm.md +2 -31
- package/node_modules/@llblab/pi-actors/docs/recipe-library.md +1 -1
- package/node_modules/@llblab/pi-actors/package.json +1 -1
- package/node_modules/@llblab/pi-actors/skills/actors/SKILL.md +16 -6
- package/node_modules/@llblab/pi-actors/skills/music-player/SKILL.md +3 -3
- package/node_modules/@llblab/pi-actors/skills/music-player/genapps/music-player.mjs +6 -4
- package/node_modules/@llblab/pi-actors/skills/music-player/scripts/playback.mjs +85 -18
- package/node_modules/@llblab/pi-actors/skills/swarm/SKILL.md +2 -6
- package/node_modules/@llblab/pi-actors/skills/swarm/references/development-swarm.md +2 -31
- package/node_modules/@llblab/pi-clean-room/AGENTS.md +5 -0
- package/node_modules/@llblab/pi-clean-room/BACKLOG.md +3 -0
- package/node_modules/@llblab/pi-clean-room/CHANGELOG.md +15 -0
- package/node_modules/@llblab/pi-clean-room/README.md +61 -0
- package/node_modules/@llblab/pi-clean-room/banner.jpg +0 -0
- package/node_modules/@llblab/pi-clean-room/index.ts +178 -0
- package/node_modules/@llblab/pi-clean-room/package.json +53 -0
- package/node_modules/@llblab/pi-grow-loop/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-grow-loop/CHANGELOG.md +4 -0
- package/node_modules/@llblab/pi-grow-loop/package.json +1 -1
- package/node_modules/@llblab/pi-grow-loop/skills/grow-loop/SKILL.md +3 -17
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +28 -0
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +3 -0
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +79 -0
- package/node_modules/@llblab/pi-state-flow/README.md +197 -0
- package/node_modules/@llblab/pi-state-flow/index.ts +4 -0
- package/node_modules/@llblab/pi-state-flow/lib/context.ts +88 -0
- package/node_modules/@llblab/pi-state-flow/lib/episode.ts +29 -0
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +238 -0
- package/node_modules/@llblab/pi-state-flow/lib/json.ts +78 -0
- package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +38 -0
- package/node_modules/@llblab/pi-state-flow/lib/session.ts +49 -0
- package/node_modules/@llblab/pi-state-flow/lib/skills.ts +58 -0
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +103 -0
- package/node_modules/@llblab/pi-state-flow/lib/state.ts +20 -0
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +16 -0
- package/node_modules/@llblab/pi-state-flow/lib/terminal.ts +148 -0
- package/node_modules/@llblab/pi-state-flow/lib/transition.ts +47 -0
- package/node_modules/@llblab/pi-state-flow/lib/validation.ts +27 -0
- package/node_modules/@llblab/pi-state-flow/package.json +55 -0
- package/node_modules/@llblab/pi-telegram/BACKLOG.md +3 -0
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +18 -0
- package/node_modules/@llblab/pi-telegram/README.md +2 -2
- package/node_modules/@llblab/pi-telegram/docs/README.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +5 -3
- package/node_modules/@llblab/pi-telegram/docs/compact-matrix-literal.md +39 -11
- package/node_modules/@llblab/pi-telegram/docs/generative-apps.md +2 -2
- package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +17 -5
- package/node_modules/@llblab/pi-telegram/docs/outbound.md +6 -4
- package/node_modules/@llblab/pi-telegram/docs/public-api.md +1 -1
- package/node_modules/@llblab/pi-telegram/index.ts +13 -1
- package/node_modules/@llblab/pi-telegram/lib/bindings.ts +12 -3
- package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +29 -18
- package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +15 -6
- package/node_modules/@llblab/pi-telegram/lib/bus.ts +11 -4
- package/node_modules/@llblab/pi-telegram/lib/keyboard.ts +5 -3
- package/node_modules/@llblab/pi-telegram/lib/outbound-buttons.ts +72 -15
- package/node_modules/@llblab/pi-telegram/lib/outbound-markup.ts +81 -9
- package/node_modules/@llblab/pi-telegram/lib/outbound.ts +2 -0
- package/node_modules/@llblab/pi-telegram/lib/replies.ts +1 -1
- package/node_modules/@llblab/pi-telegram/lib/routing.ts +89 -32
- package/node_modules/@llblab/pi-telegram/lib/sync.ts +74 -15
- package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +32 -1
- package/node_modules/@llblab/pi-telegram/lib/thread-reconciler.ts +17 -0
- package/node_modules/@llblab/pi-telegram/lib/threads.ts +123 -15
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/skills/generated-control-surface/SKILL.md +4 -2
- package/node_modules/@llblab/pi-telegram/skills/generated-control-surface/references/layout-and-state.md +4 -2
- package/node_modules/@llblab/pi-telegram/skills/generative-apps/SKILL.md +4 -3
- package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/SKILL.md +19 -8
- package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/references/diagnosis.md +4 -2
- package/node_modules/@llblab/skills/abcd-context/AGENTS.md +40 -0
- package/node_modules/@llblab/skills/abcd-context/BACKLOG.md +3 -0
- package/node_modules/@llblab/skills/abcd-context/CHANGELOG.md +19 -0
- package/node_modules/@llblab/skills/abcd-context/README.md +30 -0
- package/node_modules/@llblab/skills/abcd-context/SKILL.md +122 -0
- package/node_modules/@llblab/skills/abcd-context/docs/README.md +9 -0
- package/node_modules/@llblab/skills/abcd-context/docs/protocols.md +199 -0
- package/node_modules/@llblab/skills/abcd-context/docs/templates.md +194 -0
- package/node_modules/@llblab/skills/abcd-context/docs/validation-design.md +117 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/AGENTS.md +10 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/BACKLOG.md +5 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/CHANGELOG.md +5 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/README.md +10 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/docs/README.md +7 -0
- package/node_modules/@llblab/skills/abcd-context/fixtures/abcd-project/docs/overview.md +3 -0
- package/node_modules/@llblab/skills/abcd-context/recipes/validate-context.json +7 -0
- package/node_modules/@llblab/skills/abcd-context/scripts/_self-test.mjs +244 -0
- package/node_modules/@llblab/skills/abcd-context/scripts/validate-context.mjs +497 -0
- package/node_modules/@llblab/skills/brain-storm/AGENTS.md +5 -0
- package/node_modules/@llblab/skills/brain-storm/SKILL.md +321 -0
- package/node_modules/@llblab/skills/coding-contract/SKILL.md +228 -0
- package/node_modules/@llblab/skills/domain-dag/AGENTS.md +6 -0
- package/node_modules/@llblab/skills/domain-dag/SKILL.md +257 -0
- package/node_modules/@llblab/skills/domain-dag/domain-dag.json +9 -0
- package/node_modules/@llblab/skills/domain-dag/recipes/validate-domain-dag.json +7 -0
- package/node_modules/@llblab/skills/domain-dag/scripts/validate-domain-dag.mjs +771 -0
- package/node_modules/@llblab/skills/domain-dag/scripts/validate-domain-dag.sh +4 -0
- package/node_modules/@llblab/skills/edge-tts/AGENTS.md +19 -0
- package/node_modules/@llblab/skills/edge-tts/SKILL.md +56 -0
- package/node_modules/@llblab/skills/edge-tts/recipes/say-edge.json +9 -0
- package/node_modules/@llblab/skills/edge-tts/scripts/say.mjs +1548 -0
- package/node_modules/@llblab/skills/edge-tts/scripts/say.sh +4 -0
- package/node_modules/@llblab/skills/extra-self/SKILL.md +229 -0
- package/node_modules/@llblab/skills/frontend-design/SKILL.md +78 -0
- package/node_modules/@llblab/skills/groq-stt/AGENTS.md +15 -0
- package/node_modules/@llblab/skills/groq-stt/SKILL.md +35 -0
- package/node_modules/@llblab/skills/groq-stt/recipes/transcribe-groq.json +10 -0
- package/node_modules/@llblab/skills/groq-stt/scripts/transcribe.mjs +190 -0
- package/node_modules/@llblab/skills/groq-stt/scripts/transcribe.sh +4 -0
- package/node_modules/@llblab/skills/mistral-stt/AGENTS.md +15 -0
- package/node_modules/@llblab/skills/mistral-stt/SKILL.md +35 -0
- package/node_modules/@llblab/skills/mistral-stt/recipes/transcribe-mistral.json +10 -0
- package/node_modules/@llblab/skills/mistral-stt/scripts/transcribe.mjs +191 -0
- package/node_modules/@llblab/skills/mistral-stt/scripts/transcribe.sh +4 -0
- package/node_modules/@llblab/skills/package.json +46 -0
- package/node_modules/@llblab/skills/re-review/SKILL.md +318 -0
- package/node_modules/@llblab/skills/release-flow/SKILL.md +456 -0
- package/node_modules/@llblab/skills/show-me/SKILL.md +144 -0
- package/package.json +20 -8
- package/node_modules/@llblab/pi-actors/dist/skills/music-player/scripts/playback-client.mjs +0 -143
- package/node_modules/@llblab/pi-actors/skills/music-player/scripts/playback-client.mjs +0 -143
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
|
|
9
|
+
const scriptDir = path.dirname(new URL(import.meta.url).pathname);
|
|
10
|
+
const skillDir = path.resolve(scriptDir, "..");
|
|
11
|
+
const validator = path.join(scriptDir, "validate-context.mjs");
|
|
12
|
+
const fixtureRoot = path.join(skillDir, "fixtures/abcd-project");
|
|
13
|
+
|
|
14
|
+
let pass = 0;
|
|
15
|
+
let fail = 0;
|
|
16
|
+
|
|
17
|
+
const defaultOutput = run([]);
|
|
18
|
+
const pathOutput = run([fixtureRoot], { withoutRootEnv: true });
|
|
19
|
+
const selfOutput = run([skillDir], { withoutRootEnv: true });
|
|
20
|
+
const missingPathOutput = run([path.join(fixtureRoot, "missing")], {
|
|
21
|
+
withoutRootEnv: true,
|
|
22
|
+
});
|
|
23
|
+
const jsonOptionOutput = run(["--json"]);
|
|
24
|
+
const invalidLineRefRoot = createInvalidLineRefFixture();
|
|
25
|
+
const tableRoot = createTableFixture();
|
|
26
|
+
try {
|
|
27
|
+
const invalidLineRefOutput = run([invalidLineRefRoot], {
|
|
28
|
+
withoutRootEnv: true,
|
|
29
|
+
});
|
|
30
|
+
const compactTableOutput = run([tableRoot], { withoutRootEnv: true });
|
|
31
|
+
fs.writeFileSync(
|
|
32
|
+
path.join(tableRoot, "docs/table.md"),
|
|
33
|
+
[
|
|
34
|
+
"# Table",
|
|
35
|
+
"",
|
|
36
|
+
`| ${"Wide header ".repeat(12)} | Value |`,
|
|
37
|
+
"|------------|---:|",
|
|
38
|
+
"| Content | 1 |",
|
|
39
|
+
"",
|
|
40
|
+
"LaTeX is allowed: $\\frac{a}{b}$.",
|
|
41
|
+
"",
|
|
42
|
+
].join("\n"),
|
|
43
|
+
);
|
|
44
|
+
const nonCompactTableOutput = run([tableRoot], { withoutRootEnv: true });
|
|
45
|
+
fs.writeFileSync(
|
|
46
|
+
path.join(tableRoot, "docs/table.md"),
|
|
47
|
+
fs
|
|
48
|
+
.readFileSync(path.join(tableRoot, "docs/table.md"), "utf8")
|
|
49
|
+
.replace("|------------|---:|", "| --- | ---: |"),
|
|
50
|
+
);
|
|
51
|
+
const wideTableOutput = run([tableRoot], { withoutRootEnv: true });
|
|
52
|
+
|
|
53
|
+
checkSuccess("default fixture", defaultOutput);
|
|
54
|
+
checkSuccess("fixture path arg", pathOutput);
|
|
55
|
+
checkSuccess("self", selfOutput);
|
|
56
|
+
checkMissingPath(missingPathOutput);
|
|
57
|
+
checkRejectedJsonOption(jsonOptionOutput);
|
|
58
|
+
checkInvalidLineReference(invalidLineRefOutput);
|
|
59
|
+
checkCompactTableAndLatex(compactTableOutput);
|
|
60
|
+
checkNonCompactTable(nonCompactTableOutput);
|
|
61
|
+
checkWideTable(wideTableOutput);
|
|
62
|
+
} finally {
|
|
63
|
+
fs.rmSync(invalidLineRefRoot, { recursive: true, force: true });
|
|
64
|
+
fs.rmSync(tableRoot, { recursive: true, force: true });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log("PASS: validate-context fixture + self-reference regression");
|
|
68
|
+
console.log(`Self-test assertions: ${pass} passed, ${fail} failed`);
|
|
69
|
+
process.exit(fail ? 1 : 0);
|
|
70
|
+
|
|
71
|
+
function run(argv, options = {}) {
|
|
72
|
+
const env = {
|
|
73
|
+
...process.env,
|
|
74
|
+
NO_COLOR: "1",
|
|
75
|
+
};
|
|
76
|
+
if (!options.withoutRootEnv) env.VALIDATE_CONTEXT_ROOT = fixtureRoot;
|
|
77
|
+
const result = spawnSync(process.execPath, [validator, ...argv], {
|
|
78
|
+
encoding: "utf8",
|
|
79
|
+
env,
|
|
80
|
+
});
|
|
81
|
+
if (result.error) {
|
|
82
|
+
return { status: 1, stdout: "", stderr: String(result.error) };
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function checkSuccess(scope, result) {
|
|
88
|
+
assert(result.status === 0, `${scope} exits 0`);
|
|
89
|
+
assert(result.stdout.includes("[PASS]"), `${scope} prints readable checks`);
|
|
90
|
+
assert(
|
|
91
|
+
result.stdout.includes("Context validation PASSED"),
|
|
92
|
+
`${scope} prints a readable summary`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function checkMissingPath(result) {
|
|
97
|
+
assert(result.status !== 0, "missing path is rejected");
|
|
98
|
+
assert(
|
|
99
|
+
result.stderr.includes("Project root does not exist"),
|
|
100
|
+
"missing path is explained",
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function checkRejectedJsonOption(result) {
|
|
105
|
+
assert(result.status !== 0, "JSON option is rejected");
|
|
106
|
+
assert(
|
|
107
|
+
result.stderr.includes("Unknown option: --json"),
|
|
108
|
+
"JSON option removal is explained",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function checkInvalidLineReference(result) {
|
|
113
|
+
assert(result.status !== 0, "out-of-range line reference is rejected");
|
|
114
|
+
assert(
|
|
115
|
+
result.stdout.includes("Line ref out of range"),
|
|
116
|
+
"out-of-range line reference is explained",
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function checkCompactTableAndLatex(result) {
|
|
121
|
+
assert(result.status === 0, "compact table and LaTeX are accepted");
|
|
122
|
+
assert(
|
|
123
|
+
result.stdout.includes("Markdown table checks passed"),
|
|
124
|
+
"compact table delimiter passes",
|
|
125
|
+
);
|
|
126
|
+
assert(!result.stdout.includes("LaTeX syntax"), "LaTeX is not checked");
|
|
127
|
+
assert(
|
|
128
|
+
result.stdout.includes("Documentation links validated"),
|
|
129
|
+
"links inside indented backtick and tilde fences are ignored",
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function checkNonCompactTable(result) {
|
|
134
|
+
assert(result.status !== 0, "non-compact table delimiter fails validation");
|
|
135
|
+
assert(
|
|
136
|
+
result.stdout.includes("Non-compact Markdown table delimiter"),
|
|
137
|
+
"non-compact table delimiter is explained",
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function checkWideTable(result) {
|
|
142
|
+
assert(result.status === 0, "wide table remains valid");
|
|
143
|
+
assert(
|
|
144
|
+
result.stdout.includes("Wide Markdown table"),
|
|
145
|
+
"table row over 120 chars warns",
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function createTableFixture() {
|
|
150
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "abcd-context-table-"));
|
|
151
|
+
fs.mkdirSync(path.join(root, "docs"));
|
|
152
|
+
fs.writeFileSync(
|
|
153
|
+
path.join(root, "README.md"),
|
|
154
|
+
[
|
|
155
|
+
"# Probe",
|
|
156
|
+
"",
|
|
157
|
+
"- [Context](./AGENTS.md)",
|
|
158
|
+
"- [Backlog](./BACKLOG.md)",
|
|
159
|
+
"- [History](./CHANGELOG.md)",
|
|
160
|
+
"- [Docs](./docs/README.md)",
|
|
161
|
+
"",
|
|
162
|
+
].join("\n"),
|
|
163
|
+
);
|
|
164
|
+
fs.writeFileSync(
|
|
165
|
+
path.join(root, "AGENTS.md"),
|
|
166
|
+
"# Context\n\n## Meta-Protocol Principles\n\n- Rule.\n\n## Operating Principles\n\n- Rule.\n",
|
|
167
|
+
);
|
|
168
|
+
fs.writeFileSync(path.join(root, "BACKLOG.md"), "# Backlog\n\nNo open work.\n");
|
|
169
|
+
fs.writeFileSync(path.join(root, "CHANGELOG.md"), "# Changelog\n\nNo releases.\n");
|
|
170
|
+
fs.writeFileSync(
|
|
171
|
+
path.join(root, "docs/README.md"),
|
|
172
|
+
"# Docs\n\n- [Table](./table.md)\n",
|
|
173
|
+
);
|
|
174
|
+
fs.writeFileSync(
|
|
175
|
+
path.join(root, "docs/table.md"),
|
|
176
|
+
[
|
|
177
|
+
"# Table",
|
|
178
|
+
"",
|
|
179
|
+
"| Left | Right | Center |",
|
|
180
|
+
"| --- | ---: | :---: |",
|
|
181
|
+
"| A | B | C |",
|
|
182
|
+
"",
|
|
183
|
+
" ````markdown",
|
|
184
|
+
"|------------|---:|",
|
|
185
|
+
"[Ignored missing link](./missing-backtick.md)",
|
|
186
|
+
"```",
|
|
187
|
+
"````",
|
|
188
|
+
"",
|
|
189
|
+
"~~~markdown",
|
|
190
|
+
"|------------|---:|",
|
|
191
|
+
"[Ignored missing link](./missing-tilde.md)",
|
|
192
|
+
"~~~",
|
|
193
|
+
"",
|
|
194
|
+
"LaTeX is allowed: $\\frac{a}{b}$.",
|
|
195
|
+
"",
|
|
196
|
+
].join("\n"),
|
|
197
|
+
);
|
|
198
|
+
return root;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function createInvalidLineRefFixture() {
|
|
202
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "abcd-context-line-ref-"));
|
|
203
|
+
fs.mkdirSync(path.join(root, "docs"));
|
|
204
|
+
fs.writeFileSync(
|
|
205
|
+
path.join(root, "README.md"),
|
|
206
|
+
[
|
|
207
|
+
"# Probe",
|
|
208
|
+
"",
|
|
209
|
+
"- [Context](./AGENTS.md)",
|
|
210
|
+
"- [Backlog](./BACKLOG.md)",
|
|
211
|
+
"- [History](./CHANGELOG.md)",
|
|
212
|
+
"- [Docs](./docs/README.md)",
|
|
213
|
+
"- [Invalid line](./AGENTS.md#L999)",
|
|
214
|
+
"",
|
|
215
|
+
].join("\n"),
|
|
216
|
+
);
|
|
217
|
+
fs.writeFileSync(
|
|
218
|
+
path.join(root, "AGENTS.md"),
|
|
219
|
+
[
|
|
220
|
+
"# Context",
|
|
221
|
+
"",
|
|
222
|
+
"## Meta-Protocol Principles",
|
|
223
|
+
"",
|
|
224
|
+
"- Rule.",
|
|
225
|
+
"",
|
|
226
|
+
"## Operating Principles",
|
|
227
|
+
"",
|
|
228
|
+
"- Rule.",
|
|
229
|
+
"",
|
|
230
|
+
].join("\n"),
|
|
231
|
+
);
|
|
232
|
+
fs.writeFileSync(path.join(root, "BACKLOG.md"), "# Backlog\n\nNo open work.\n");
|
|
233
|
+
fs.writeFileSync(path.join(root, "CHANGELOG.md"), "# Changelog\n\nNo releases.\n");
|
|
234
|
+
fs.writeFileSync(path.join(root, "docs/README.md"), "# Docs\n\nNo docs.\n");
|
|
235
|
+
return root;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function assert(ok, label) {
|
|
239
|
+
if (ok) pass++;
|
|
240
|
+
else {
|
|
241
|
+
fail++;
|
|
242
|
+
console.error(`FAIL: ${label}`);
|
|
243
|
+
}
|
|
244
|
+
}
|