@rhost/testkit 1.4.0 → 1.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.
Files changed (73) hide show
  1. package/README.md +1 -0
  2. package/dist/cli/index.js +15 -4
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/cli/init.d.ts.map +1 -1
  5. package/dist/cli/init.js +107 -19
  6. package/dist/cli/init.js.map +1 -1
  7. package/dist/cli/lint.d.ts +2 -0
  8. package/dist/cli/lint.d.ts.map +1 -0
  9. package/dist/cli/lint.js +163 -0
  10. package/dist/cli/lint.js.map +1 -0
  11. package/dist/cli/mush-format.d.ts +2 -0
  12. package/dist/cli/mush-format.d.ts.map +1 -0
  13. package/dist/cli/mush-format.js +232 -0
  14. package/dist/cli/mush-format.js.map +1 -0
  15. package/dist/client.d.ts +43 -1
  16. package/dist/client.d.ts.map +1 -1
  17. package/dist/client.js +78 -5
  18. package/dist/client.js.map +1 -1
  19. package/dist/index.d.ts +3 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +10 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/offline/document.d.ts +8 -0
  24. package/dist/offline/document.d.ts.map +1 -0
  25. package/dist/offline/document.js +124 -0
  26. package/dist/offline/document.js.map +1 -0
  27. package/dist/offline/expect.d.ts +27 -0
  28. package/dist/offline/expect.d.ts.map +1 -0
  29. package/dist/offline/expect.js +90 -0
  30. package/dist/offline/expect.js.map +1 -0
  31. package/dist/offline/index.d.ts +5 -0
  32. package/dist/offline/index.d.ts.map +1 -0
  33. package/dist/offline/index.js +14 -0
  34. package/dist/offline/index.js.map +1 -0
  35. package/dist/offline/mock-client.d.ts +19 -0
  36. package/dist/offline/mock-client.d.ts.map +1 -0
  37. package/dist/offline/mock-client.js +36 -0
  38. package/dist/offline/mock-client.js.map +1 -0
  39. package/dist/offline/mock-world.d.ts +30 -0
  40. package/dist/offline/mock-world.d.ts.map +1 -0
  41. package/dist/offline/mock-world.js +64 -0
  42. package/dist/offline/mock-world.js.map +1 -0
  43. package/dist/offline/reduced-expect.d.ts +38 -0
  44. package/dist/offline/reduced-expect.d.ts.map +1 -0
  45. package/dist/offline/reduced-expect.js +61 -0
  46. package/dist/offline/reduced-expect.js.map +1 -0
  47. package/dist/offline/runner.d.ts +13 -0
  48. package/dist/offline/runner.d.ts.map +1 -0
  49. package/dist/offline/runner.js +174 -0
  50. package/dist/offline/runner.js.map +1 -0
  51. package/dist/offline/types.d.ts +78 -0
  52. package/dist/offline/types.d.ts.map +1 -0
  53. package/dist/offline/types.js +3 -0
  54. package/dist/offline/types.js.map +1 -0
  55. package/dist/reporter.d.ts +3 -1
  56. package/dist/reporter.d.ts.map +1 -1
  57. package/dist/reporter.js +20 -0
  58. package/dist/reporter.js.map +1 -1
  59. package/dist/runner.d.ts +39 -0
  60. package/dist/runner.d.ts.map +1 -1
  61. package/dist/runner.js +82 -15
  62. package/dist/runner.js.map +1 -1
  63. package/dist/validator/formatter.js +13 -2
  64. package/dist/validator/formatter.js.map +1 -1
  65. package/dist/validator/mush-format.d.ts +43 -0
  66. package/dist/validator/mush-format.d.ts.map +1 -0
  67. package/dist/validator/mush-format.js +484 -0
  68. package/dist/validator/mush-format.js.map +1 -0
  69. package/dist/validator/mush-lint.d.ts +22 -0
  70. package/dist/validator/mush-lint.d.ts.map +1 -0
  71. package/dist/validator/mush-lint.js +590 -0
  72. package/dist/validator/mush-lint.js.map +1 -0
  73. package/package.json +10 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mush-format.js","sourceRoot":"","sources":["../../src/validator/mush-format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export type LintSeverity = 'ERROR' | 'WARN' | 'INFO';
2
+ export interface LintDiag {
3
+ code: string;
4
+ severity: LintSeverity;
5
+ /** 1-based line number in the source file */
6
+ line: number;
7
+ /** Attribute name if applicable */
8
+ attr?: string;
9
+ message: string;
10
+ }
11
+ export interface LintResult {
12
+ diagnostics: LintDiag[];
13
+ errors: number;
14
+ warnings: number;
15
+ infos: number;
16
+ }
17
+ /**
18
+ * Lint a softcode file (.mush or .installer.txt).
19
+ * Returns all diagnostics sorted by line number.
20
+ */
21
+ export declare function lintContent(content: string, filename?: string): LintResult;
22
+ //# sourceMappingURL=mush-lint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mush-lint.d.ts","sourceRoot":"","sources":["../../src/validator/mush-lint.ts"],"names":[],"mappings":"AA6BA,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;IACvB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACvB,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACjB;AAuCD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAY,GAAG,UAAU,CAmC7E"}
@@ -0,0 +1,590 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // mush-lint — static analysis for RhostMUSH softcode files
4
+ //
5
+ // Checks implemented:
6
+ // Safety S1 Bare user input in @pemit/@emit/think
7
+ // S2 @create without @lock
8
+ // S3 execscript() with user input
9
+ // S4 User input in @switch case label
10
+ // S5 Hardcoded dbref in HELP* attrs
11
+ // Complete C1 FN_* accepts %0 without input guard
12
+ // C2 CMD_* with no HELP* entry
13
+ // C3 Installer missing header/footer markers
14
+ // C4 Installer missing UNINSTALL section
15
+ // Format F1 Line > 78 chars in help.txt or @@ comments
16
+ // F2 Separator line not 78 chars
17
+ // F3 Wrong attribute order (Config→UDFs→Commands→Help)
18
+ // F4 Comment style mismatch (// or ## instead of @@)
19
+ // Length L1 Attribute body > 7500 chars
20
+ // Style I1 Attribute name not uppercase
21
+ // I2 No Version field in installer header
22
+ // I3 No Requires field in installer header
23
+ // ---------------------------------------------------------------------------
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.lintContent = lintContent;
26
+ const mushcode_1 = require("@ursamu/mushcode");
27
+ // ---------------------------------------------------------------------------
28
+ // Entry point
29
+ // ---------------------------------------------------------------------------
30
+ /**
31
+ * Lint a softcode file (.mush or .installer.txt).
32
+ * Returns all diagnostics sorted by line number.
33
+ */
34
+ function lintContent(content, filename = '<input>') {
35
+ const lines = content.split('\n');
36
+ const attrs = parseAttrs(lines);
37
+ const diags = [];
38
+ // File-level checks
39
+ checkInstallerStructure(lines, diags); // C3, C4, I2, I3
40
+ checkCommentStyle(lines, attrs, diags); // F4
41
+ checkLineLengths(lines, diags); // F1, F2
42
+ // Attribute-level checks
43
+ checkAttrOrder(attrs, diags); // F3
44
+ checkAttrNames(attrs, diags); // I1
45
+ for (const attr of attrs) {
46
+ checkAttrLength(attr, diags); // L1
47
+ if (!attr.ast)
48
+ continue;
49
+ checkBareUserInput(attr, diags); // S1
50
+ checkSwitchCaseLabel(attr, diags); // S4
51
+ checkExecscript(attr, diags); // S3
52
+ checkHelpDbref(attr, diags); // S5
53
+ checkFnGuard(attr, diags); // C1
54
+ }
55
+ checkUncreatedObjects(lines, diags); // S2
56
+ checkCmdHelpPairs(attrs, diags); // C2
57
+ diags.sort((a, b) => a.line - b.line);
58
+ return {
59
+ diagnostics: diags,
60
+ errors: diags.filter(d => d.severity === 'ERROR').length,
61
+ warnings: diags.filter(d => d.severity === 'WARN').length,
62
+ infos: diags.filter(d => d.severity === 'INFO').length,
63
+ };
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // File parser — extract AttrRecords from lines
67
+ // ---------------------------------------------------------------------------
68
+ function parseAttrs(lines) {
69
+ const records = [];
70
+ // Collect multi-line logical attributes (indented continuation lines)
71
+ let current = null;
72
+ for (let i = 0; i < lines.length; i++) {
73
+ const raw = lines[i];
74
+ const trimmed = raw.trim();
75
+ // New attribute line
76
+ const m = trimmed.match(/^&([A-Za-z_][A-Za-z0-9_.:@-]*)\s+([^=\s][^=]*)=(.*)$/);
77
+ if (m) {
78
+ if (current)
79
+ records.push(finishAttr(current));
80
+ current = { name: m[1].toUpperCase(), rawName: m[1], object: m[2].trim(), value: m[3], line: i + 1 };
81
+ continue;
82
+ }
83
+ // Continuation: indented line after an attribute
84
+ if (current && raw.match(/^\s+\S/) && !trimmed.startsWith('&') && !trimmed.startsWith('@') && !trimmed.startsWith('//')) {
85
+ current.value += ' ' + trimmed;
86
+ continue;
87
+ }
88
+ // Any other command resets continuation
89
+ if (current) {
90
+ records.push(finishAttr(current));
91
+ current = null;
92
+ }
93
+ }
94
+ if (current)
95
+ records.push(finishAttr(current));
96
+ return records;
97
+ }
98
+ function finishAttr(r) {
99
+ const value = r.value.trim();
100
+ let ast = null;
101
+ if (value) {
102
+ try {
103
+ ast = (0, mushcode_1.parse)(value);
104
+ }
105
+ catch { /* unparseable */ }
106
+ }
107
+ return { ...r, value, ast };
108
+ }
109
+ // ---------------------------------------------------------------------------
110
+ // S1 — Bare user input in @pemit / @emit / @remit / @oemit / think
111
+ // ---------------------------------------------------------------------------
112
+ const OUTPUT_CMDS = new Set(['pemit', 'emit', 'remit', 'oemit', 'zemit', 'wall', 'notify']);
113
+ // Any function call is treated as "handling" its arguments for S1 purposes.
114
+ // Only flag substitutions in the raw text flow (not inside any function call).
115
+ // Substitution codes that represent user input
116
+ const USER_INPUT_RE = /^[0-9]$|^v[a-z]$/;
117
+ function checkBareUserInput(attr, diags) {
118
+ if (!attr.ast)
119
+ return;
120
+ walkAtCmd(attr.ast, (cmd) => {
121
+ if (!OUTPUT_CMDS.has(cmd.name.toLowerCase()))
122
+ return;
123
+ const bare = findBareUserSubs(cmd.value);
124
+ for (const sub of bare) {
125
+ diags.push({
126
+ code: 'S1',
127
+ severity: 'ERROR',
128
+ line: attr.line,
129
+ attr: attr.name,
130
+ message: `Bare %${sub.code} in @${cmd.name} — wrap with secure(%${sub.code}) or stripchars(...)`,
131
+ });
132
+ }
133
+ });
134
+ }
135
+ /** Walk AST and call cb for every AtCommand node (including those inside DollarPattern/BracedString) */
136
+ function walkAtCmd(node, cb) {
137
+ if (!node || typeof node !== 'object')
138
+ return;
139
+ switch (node.type) {
140
+ case 'AtCommand':
141
+ cb(node);
142
+ walkAtCmd(node.value, cb);
143
+ break;
144
+ case 'DollarPattern':
145
+ walkAtCmd(node.action, cb);
146
+ break;
147
+ case 'CommandList':
148
+ for (const c of node.commands)
149
+ walkAtCmd(c, cb);
150
+ break;
151
+ case 'UserCommand':
152
+ for (const p of node.parts)
153
+ walkAtCmd(p, cb);
154
+ break;
155
+ case 'BracedString':
156
+ // Re-parse braced content to catch nested @pemit in action bodies
157
+ for (const p of node.parts)
158
+ walkAtCmd(p, cb);
159
+ break;
160
+ case 'EvalBlock':
161
+ for (const p of node.parts)
162
+ walkAtCmd(p, cb);
163
+ break;
164
+ case 'FunctionCall':
165
+ for (const arg of node.args)
166
+ walkAtCmd(arg, cb);
167
+ break;
168
+ case 'Arg':
169
+ for (const p of node.parts)
170
+ walkAtCmd(p, cb);
171
+ break;
172
+ }
173
+ }
174
+ /**
175
+ * Find user-input substitutions (%0-9, %va-vz) that appear in the "text flow"
176
+ * of a node — i.e. NOT inside any protective function call.
177
+ * We stop recursing into FunctionCall nodes whose name is in SAFE_FUNS;
178
+ * other function calls are treated as pass-through.
179
+ */
180
+ function findBareUserSubs(node) {
181
+ const found = [];
182
+ collectBareUserSubs(node, false /* insideFn */, found);
183
+ return found;
184
+ }
185
+ function collectBareUserSubs(node, insideFn, out) {
186
+ if (!node || typeof node !== 'object')
187
+ return;
188
+ switch (node.type) {
189
+ case 'Substitution':
190
+ // Only flag if NOT inside any function call at any depth
191
+ if (!insideFn && USER_INPUT_RE.test(node.code))
192
+ out.push(node);
193
+ break;
194
+ case 'FunctionCall':
195
+ // All function calls protect their arguments — don't flag inside them
196
+ return;
197
+ case 'Arg':
198
+ for (const p of node.parts)
199
+ collectBareUserSubs(p, insideFn, out);
200
+ break;
201
+ case 'EvalBlock':
202
+ case 'UserCommand':
203
+ case 'BracedString':
204
+ case 'Text': {
205
+ const parts = node.parts;
206
+ for (const p of parts)
207
+ collectBareUserSubs(p, insideFn, out);
208
+ break;
209
+ }
210
+ case 'CommandList':
211
+ for (const c of node.commands)
212
+ collectBareUserSubs(c, insideFn, out);
213
+ break;
214
+ case 'AtCommand':
215
+ // Only check the value, not object (which is typically %#)
216
+ collectBareUserSubs(node.value, insideFn, out);
217
+ break;
218
+ case 'DollarPattern':
219
+ collectBareUserSubs(node.action, insideFn, out);
220
+ break;
221
+ }
222
+ }
223
+ // ---------------------------------------------------------------------------
224
+ // S2 — @create without @lock
225
+ // ---------------------------------------------------------------------------
226
+ function checkUncreatedObjects(lines, diags) {
227
+ // Track @create <name> and watch for @lock <name>=
228
+ const created = new Map(); // name → line
229
+ const locked = new Set();
230
+ for (let i = 0; i < lines.length; i++) {
231
+ const line = lines[i].trim();
232
+ const createM = line.match(/^@create\s+(.+?)(\s*=.*)?$/i);
233
+ if (createM) {
234
+ const name = createM[1].trim().replace(/\s+<[^>]+>$/, ''); // strip <tag>
235
+ created.set(name.toLowerCase(), i + 1);
236
+ }
237
+ const lockM = line.match(/^@lock\s+(.+?)=/i);
238
+ if (lockM) {
239
+ locked.add(lockM[1].trim().toLowerCase());
240
+ }
241
+ }
242
+ for (const [name, lineNo] of created) {
243
+ if (!locked.has(name)) {
244
+ diags.push({
245
+ code: 'S2',
246
+ severity: 'ERROR',
247
+ line: lineNo,
248
+ message: `@create "${name}" has no @lock — all system objects must be locked`,
249
+ });
250
+ }
251
+ }
252
+ }
253
+ // ---------------------------------------------------------------------------
254
+ // S3 — execscript() with user input
255
+ // ---------------------------------------------------------------------------
256
+ function checkExecscript(attr, diags) {
257
+ // Walk AST for FunctionCall named execscript and check args 0 and 1
258
+ walkFunctionCalls(attr.ast, 'execscript', (node) => {
259
+ const args = node.args;
260
+ // Check first two args for user substitutions
261
+ for (let i = 0; i < Math.min(args.length, 2); i++) {
262
+ const subs = findAllUserSubs(args[i]);
263
+ if (subs.length > 0) {
264
+ diags.push({
265
+ code: 'S3',
266
+ severity: 'ERROR',
267
+ line: attr.line,
268
+ attr: attr.name,
269
+ message: `execscript() arg ${i + 1} contains %${subs[0].code} — never pass user input to execscript`,
270
+ });
271
+ break;
272
+ }
273
+ }
274
+ });
275
+ }
276
+ function walkFunctionCalls(node, name, cb) {
277
+ if (!node || typeof node !== 'object')
278
+ return;
279
+ if (node.type === 'FunctionCall' && node.name.toLowerCase() === name.toLowerCase()) {
280
+ cb(node);
281
+ }
282
+ const children = getChildren(node);
283
+ for (const c of children)
284
+ walkFunctionCalls(c, name, cb);
285
+ }
286
+ function getChildren(node) {
287
+ switch (node.type) {
288
+ case 'UserCommand': return node.parts;
289
+ case 'CommandList': return node.commands;
290
+ case 'AtCommand': return [node.object, node.value];
291
+ case 'DollarPattern': return [node.action];
292
+ case 'FunctionCall': return node.args;
293
+ case 'Arg': return node.parts;
294
+ case 'EvalBlock': return node.parts;
295
+ case 'BracedString': return node.parts;
296
+ case 'Text': return node.parts;
297
+ default: return [];
298
+ }
299
+ }
300
+ /** Find ALL user substitution nodes (including those inside function calls) */
301
+ function findAllUserSubs(node) {
302
+ const found = [];
303
+ collectAllUserSubs(node, found);
304
+ return found;
305
+ }
306
+ function collectAllUserSubs(node, out) {
307
+ if (!node || typeof node !== 'object')
308
+ return;
309
+ if (node.type === 'Substitution' && USER_INPUT_RE.test(node.code)) {
310
+ out.push(node);
311
+ return;
312
+ }
313
+ for (const c of getChildren(node))
314
+ collectAllUserSubs(c, out);
315
+ }
316
+ // ---------------------------------------------------------------------------
317
+ // S4 — User input in @switch case label
318
+ // ---------------------------------------------------------------------------
319
+ const SWITCH_CMDS = new Set(['switch', 'switchall']);
320
+ function checkSwitchCaseLabel(attr, diags) {
321
+ if (!attr.ast)
322
+ return;
323
+ walkAtCmd(attr.ast, (cmd) => {
324
+ if (!SWITCH_CMDS.has(cmd.name.toLowerCase()))
325
+ return;
326
+ // The case list is in cmd.value (a UserCommand or CommandList)
327
+ // Split into label and body segments: bodies are BracedStrings
328
+ const valueParts = flatParts(cmd.value);
329
+ let inLabel = true;
330
+ for (const part of valueParts) {
331
+ if (part.type === 'BracedString') {
332
+ inLabel = false;
333
+ continue;
334
+ }
335
+ if (part.type === 'Literal' && part.value === ',') {
336
+ inLabel = true;
337
+ continue;
338
+ }
339
+ if (inLabel) {
340
+ const subs = findAllUserSubs(part);
341
+ if (subs.length > 0) {
342
+ diags.push({
343
+ code: 'S4',
344
+ severity: 'ERROR',
345
+ line: attr.line,
346
+ attr: attr.name,
347
+ message: `User input (%${subs[0].code}) in @switch case label — case labels are evaluated, this is injectable`,
348
+ });
349
+ return; // one diag per @switch is enough
350
+ }
351
+ }
352
+ }
353
+ });
354
+ }
355
+ function flatParts(node) {
356
+ if (node.type === 'UserCommand')
357
+ return node.parts;
358
+ if (node.type === 'CommandList')
359
+ return node.commands;
360
+ return [node];
361
+ }
362
+ // ---------------------------------------------------------------------------
363
+ // S5 — Hardcoded dbref in HELP* attributes
364
+ // ---------------------------------------------------------------------------
365
+ function checkHelpDbref(attr, diags) {
366
+ if (!attr.name.startsWith('HELP'))
367
+ return;
368
+ if (/#\d+/.test(attr.value)) {
369
+ diags.push({
370
+ code: 'S5',
371
+ severity: 'ERROR',
372
+ line: attr.line,
373
+ attr: attr.name,
374
+ message: `Hardcoded dbref in ${attr.name} — help text must use names only`,
375
+ });
376
+ }
377
+ }
378
+ // ---------------------------------------------------------------------------
379
+ // C1 — FN_* accepts %0 without input guard
380
+ // ---------------------------------------------------------------------------
381
+ function checkFnGuard(attr, diags) {
382
+ if (!attr.name.startsWith('FN_'))
383
+ return;
384
+ // Does this function use %0-%9 at all?
385
+ const subs = findAllUserSubs(attr.ast);
386
+ if (subs.length === 0)
387
+ return;
388
+ // Check for a guard: value should start with [if(not(%0,...) or [if(eq(%0,...)]
389
+ // In the AST, the top-level node should be a UserCommand whose first non-whitespace
390
+ // part is an EvalBlock containing an 'if' or 'switch' FunctionCall.
391
+ if (hasInputGuard(attr.ast))
392
+ return;
393
+ diags.push({
394
+ code: 'C1',
395
+ severity: 'ERROR',
396
+ line: attr.line,
397
+ attr: attr.name,
398
+ message: `${attr.name} accepts %0 but has no input guard — add [if(not(%0),#-1 MISSING ARG,...)]`,
399
+ });
400
+ }
401
+ function hasInputGuard(node) {
402
+ if (node.type !== 'UserCommand')
403
+ return false;
404
+ // First significant part must be an EvalBlock
405
+ const firstSig = node.parts.find(p => p.type !== 'Literal' || p.value.trim() !== '');
406
+ if (!firstSig || firstSig.type !== 'EvalBlock')
407
+ return false;
408
+ // The EvalBlock should contain a guard function call as its only (or first) element
409
+ const inner = firstSig.parts[0];
410
+ if (!inner || inner.type !== 'FunctionCall')
411
+ return false;
412
+ const name = inner.name.toLowerCase();
413
+ return name === 'if' || name === 'ifelse' || name === 'switch' || name === 'when';
414
+ }
415
+ // ---------------------------------------------------------------------------
416
+ // C2 — CMD_* with no HELP* entry
417
+ // ---------------------------------------------------------------------------
418
+ function checkCmdHelpPairs(attrs, diags) {
419
+ const cmds = attrs.filter(a => a.name.startsWith('CMD_'));
420
+ const helps = new Set(attrs.filter(a => a.name.startsWith('HELP')).map(a => a.name));
421
+ for (const cmd of cmds) {
422
+ // Strip CMD_ prefix, look for HELP_<suffix> or HELP<suffix>
423
+ const suffix = cmd.name.slice(4); // e.g. FINGER from CMD_FINGER
424
+ const hasHelp = helps.has(`HELP_${suffix}`) || helps.has(`HELP${suffix}`);
425
+ if (!hasHelp) {
426
+ diags.push({
427
+ code: 'C2',
428
+ severity: 'ERROR',
429
+ line: cmd.line,
430
+ attr: cmd.name,
431
+ message: `${cmd.name} has no HELP entry — every command needs help text`,
432
+ });
433
+ }
434
+ }
435
+ }
436
+ // ---------------------------------------------------------------------------
437
+ // C3 — Installer missing header/footer markers
438
+ // C4 — Installer missing UNINSTALL section
439
+ // ---------------------------------------------------------------------------
440
+ function checkInstallerStructure(lines, diags) {
441
+ const text = lines.join('\n');
442
+ // Only run structural checks on installer files (look for @@ markers)
443
+ const isInstaller = lines.some(l => l.startsWith('@@'));
444
+ if (!isInstaller)
445
+ return;
446
+ if (!/@@ Mushcode Installer for:/i.test(text)) {
447
+ diags.push({ code: 'C3', severity: 'ERROR', line: 1, message: 'Missing "@@ Mushcode Installer for:" header line' });
448
+ }
449
+ if (!/@@ \[END OF FILE\]/i.test(text)) {
450
+ diags.push({ code: 'C3', severity: 'ERROR', line: lines.length, message: 'Missing "@@ [END OF FILE]" terminal marker' });
451
+ }
452
+ if (!/@@ ---\[ UNINSTALL \]---/i.test(text)) {
453
+ diags.push({ code: 'C4', severity: 'ERROR', line: lines.length, message: 'No UNINSTALL section — add @@ ---[ UNINSTALL ]--- block' });
454
+ }
455
+ // I2, I3 — header field presence
456
+ if (!/@@ Version:/i.test(text)) {
457
+ diags.push({ code: 'I2', severity: 'INFO', line: 1, message: 'Version field missing from installer header' });
458
+ }
459
+ if (!/@@ Requires:/i.test(text)) {
460
+ diags.push({ code: 'I3', severity: 'INFO', line: 1, message: 'Requires field missing from installer header — add "None" if no prerequisites' });
461
+ }
462
+ }
463
+ // ---------------------------------------------------------------------------
464
+ // F1 — Line > 78 chars (help and @@ comment lines only)
465
+ // F2 — Separator line not exactly 78 chars
466
+ // ---------------------------------------------------------------------------
467
+ function checkLineLengths(lines, diags) {
468
+ for (let i = 0; i < lines.length; i++) {
469
+ const line = lines[i];
470
+ const lineNo = i + 1;
471
+ // F2 — separator lines must be exactly 78 chars
472
+ if (/^@@ ={3,}/.test(line) || /^@@ ---\[/.test(line)) {
473
+ if (line.length !== 78) {
474
+ diags.push({
475
+ code: 'F2',
476
+ severity: 'WARN',
477
+ line: lineNo,
478
+ message: `Separator line is ${line.length} chars — must be exactly 78`,
479
+ });
480
+ }
481
+ continue;
482
+ }
483
+ // F1 — @@ comment lines
484
+ if (line.startsWith('@@') && line.length > 78) {
485
+ diags.push({
486
+ code: 'F1',
487
+ severity: 'WARN',
488
+ line: lineNo,
489
+ message: `@@ comment line is ${line.length} chars — max is 78`,
490
+ });
491
+ }
492
+ }
493
+ }
494
+ // ---------------------------------------------------------------------------
495
+ // F3 — Wrong attribute order (Config → UDFs → Commands → Help)
496
+ // ---------------------------------------------------------------------------
497
+ const ATTR_ORDER_RANK = {
498
+ D_: 0, CONF_: 0, CONFIG_: 0, // config/data
499
+ FN_: 1, // UDFs
500
+ CMD_: 2, // commands
501
+ HELP: 3, // help (prefix match)
502
+ };
503
+ function attrRank(name) {
504
+ for (const [prefix, rank] of Object.entries(ATTR_ORDER_RANK)) {
505
+ if (name.startsWith(prefix))
506
+ return rank;
507
+ }
508
+ return 1; // default: treat as UDF-level
509
+ }
510
+ function checkAttrOrder(attrs, diags) {
511
+ // Group by object, then check order within each object
512
+ const byObj = new Map();
513
+ for (const attr of attrs) {
514
+ const key = attr.object.toLowerCase();
515
+ if (!byObj.has(key))
516
+ byObj.set(key, []);
517
+ byObj.get(key).push(attr);
518
+ }
519
+ for (const [, objAttrs] of byObj) {
520
+ let maxRank = -1;
521
+ for (const attr of objAttrs) {
522
+ const rank = attrRank(attr.name);
523
+ if (rank < maxRank) {
524
+ diags.push({
525
+ code: 'F3',
526
+ severity: 'WARN',
527
+ line: attr.line,
528
+ attr: attr.name,
529
+ message: `${attr.name} appears after a higher-priority attribute — order must be: Config, UDFs, Commands, Help`,
530
+ });
531
+ }
532
+ else {
533
+ maxRank = Math.max(maxRank, rank);
534
+ }
535
+ }
536
+ }
537
+ }
538
+ // ---------------------------------------------------------------------------
539
+ // F4 — Comment style: // or ## used instead of @@
540
+ // ---------------------------------------------------------------------------
541
+ function checkCommentStyle(lines, attrs, diags) {
542
+ // Build set of attribute line numbers so we don't flag inline comments in attr values
543
+ const attrLines = new Set(attrs.map(a => a.line));
544
+ for (let i = 0; i < lines.length; i++) {
545
+ const lineNo = i + 1;
546
+ if (attrLines.has(lineNo))
547
+ continue;
548
+ const trimmed = lines[i].trim();
549
+ // Standalone // comment line at the top level of an installer file
550
+ if (/^\/\//.test(trimmed) || /^##\s/.test(trimmed)) {
551
+ diags.push({
552
+ code: 'F4',
553
+ severity: 'WARN',
554
+ line: lineNo,
555
+ message: `Line ${lineNo} uses "${trimmed.slice(0, 2)}" comment style — convert to @@ in installer files`,
556
+ });
557
+ }
558
+ }
559
+ }
560
+ // ---------------------------------------------------------------------------
561
+ // L1 — Attribute body > 7500 chars
562
+ // ---------------------------------------------------------------------------
563
+ function checkAttrLength(attr, diags) {
564
+ if (attr.value.length > 7500) {
565
+ diags.push({
566
+ code: 'L1',
567
+ severity: 'WARN',
568
+ line: attr.line,
569
+ attr: attr.name,
570
+ message: `${attr.name} is ${attr.value.length} chars — approaching 8000-char Rhost limit, consider chunking into ${attr.name}.0, ${attr.name}.1, ...`,
571
+ });
572
+ }
573
+ }
574
+ // ---------------------------------------------------------------------------
575
+ // I1 — Attribute name not uppercase
576
+ // ---------------------------------------------------------------------------
577
+ function checkAttrNames(attrs, diags) {
578
+ for (const attr of attrs) {
579
+ if (attr.rawName !== attr.name) {
580
+ diags.push({
581
+ code: 'I1',
582
+ severity: 'INFO',
583
+ line: attr.line,
584
+ attr: attr.name,
585
+ message: `Attribute ${attr.rawName} should be ${attr.name} — use uppercase for all attribute names`,
586
+ });
587
+ }
588
+ }
589
+ }
590
+ //# sourceMappingURL=mush-lint.js.map