@keel_flow/pack-general-se 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jglasskatz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # @keel_flow/pack-general-se
2
+
3
+ General software engineering principles for Keel projects: fourteen principles covering naming, error boundaries, test contracts, single source of truth, no dead code, no TODO comments, gate reproducibility, and more — each with a machine-checkable `check` function that integrates with `keel verify`.
4
+
5
+ Part of the [Keel](https://github.com/jglasskatz/keel) framework.
6
+
7
+ ## Install
8
+
9
+ ```
10
+ npm install @keel_flow/pack-general-se
11
+ ```
12
+
13
+ ## License
14
+
15
+ MIT
@@ -0,0 +1,6 @@
1
+ import type { PrincipleWithCheck, PrinciplePack } from "@keel_flow/schema";
2
+ export declare function hasIgnoreFileDirective(src: string, principleId: string): boolean;
3
+ export declare function isIgnoreNextLine(src: string, lineIndex: number, principleId: string): boolean;
4
+ export declare const generalSEPrinciples: PrincipleWithCheck[];
5
+ export declare const generalSEPack: PrinciplePack;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAa,MAAM,mBAAmB,CAAC;AAiJtF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAGhF;AAID,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAK7F;AAQD,eAAO,MAAM,mBAAmB,EAAE,kBAAkB,EAgenD,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,aAK3B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,669 @@
1
+ import { existsSync, readFileSync } from "fs";
2
+ import { join } from "path";
3
+ import { parse, AST_NODE_TYPES } from "@typescript-eslint/typescript-estree";
4
+ import { isReExportOnlyBarrel, isTypeOnlyModule, isTemplateFile } from "./scope-filters.js";
5
+ function parseProgram(src) {
6
+ try {
7
+ return parse(src, { jsx: false, loc: true, range: false, comment: true });
8
+ }
9
+ catch {
10
+ return null;
11
+ }
12
+ }
13
+ function walk(node, visit) {
14
+ visit(node);
15
+ for (const key in node) {
16
+ if (key === "parent")
17
+ continue;
18
+ const value = node[key];
19
+ if (Array.isArray(value)) {
20
+ for (const child of value) {
21
+ if (child && typeof child === "object" && "type" in child) {
22
+ walk(child, visit);
23
+ }
24
+ }
25
+ }
26
+ else if (value && typeof value === "object" && "type" in value) {
27
+ walk(value, visit);
28
+ }
29
+ }
30
+ }
31
+ const VAGUE = new Set(["data", "info", "temp", "tmp", "obj", "item", "thing", "stuff", "val"]);
32
+ const FUNCTION_TYPES = new Set([
33
+ AST_NODE_TYPES.FunctionDeclaration,
34
+ AST_NODE_TYPES.FunctionExpression,
35
+ AST_NODE_TYPES.ArrowFunctionExpression,
36
+ AST_NODE_TYPES.TSDeclareFunction,
37
+ AST_NODE_TYPES.TSEmptyBodyFunctionExpression,
38
+ ]);
39
+ function paramIdentifiers(param, out) {
40
+ if (param.type === AST_NODE_TYPES.Identifier) {
41
+ out.push(param);
42
+ }
43
+ else if (param.type === AST_NODE_TYPES.AssignmentPattern) {
44
+ paramIdentifiers(param.left, out);
45
+ }
46
+ else if (param.type === AST_NODE_TYPES.RestElement) {
47
+ if (param.argument.type === AST_NODE_TYPES.Identifier)
48
+ out.push(param.argument);
49
+ }
50
+ else if (param.type === AST_NODE_TYPES.TSParameterProperty) {
51
+ paramIdentifiers(param.parameter, out);
52
+ }
53
+ }
54
+ // Collects identifiers in the same positions the @keel_flow/naming-is-design ESLint
55
+ // rule inspects: VariableDeclarator ids and function parameters. Type-position
56
+ // names, object keys and member accesses are deliberately excluded so verify-time
57
+ // and editor-time enforcement agree token-for-token.
58
+ function vagueNames(ast) {
59
+ const flagged = [];
60
+ walk(ast, (node) => {
61
+ if (node.type === AST_NODE_TYPES.VariableDeclarator &&
62
+ node.id.type === AST_NODE_TYPES.Identifier &&
63
+ VAGUE.has(node.id.name)) {
64
+ flagged.push(node.id);
65
+ }
66
+ if (FUNCTION_TYPES.has(node.type)) {
67
+ const params = node.params ?? [];
68
+ for (const param of params) {
69
+ const ids = [];
70
+ paramIdentifiers(param, ids);
71
+ for (const id of ids)
72
+ if (VAGUE.has(id.name))
73
+ flagged.push(id);
74
+ }
75
+ }
76
+ });
77
+ return flagged;
78
+ }
79
+ // Counts `any` type uses (TSAnyKeyword) not covered by a justified
80
+ // `eslint-disable-next-line @typescript-eslint/no-explicit-any -- <reason>`
81
+ // directive. Justification is matched against the nearest preceding comment with
82
+ // only blank/comment lines between it and the `any`, so a blank line does not
83
+ // break suppression. AST parsing means `any` inside a string literal or comment
84
+ // is never counted.
85
+ function countUnjustifiedAny(ast, sourceLines) {
86
+ const justifiedLines = justifiedDisableEndLines(ast.comments ?? []);
87
+ let unjustified = 0;
88
+ walk(ast, (node) => {
89
+ if (node.type !== AST_NODE_TYPES.TSAnyKeyword)
90
+ return;
91
+ const line = node.loc.start.line;
92
+ if (isSuppressed(line, justifiedLines, sourceLines))
93
+ return;
94
+ unjustified += 1;
95
+ });
96
+ return unjustified;
97
+ }
98
+ function justifiedDisableEndLines(comments) {
99
+ const ends = [];
100
+ for (const comment of comments) {
101
+ if (comment.type !== "Line")
102
+ continue;
103
+ const sameLineDisable = /eslint-disable-line\s+(?:[^\n]*\s)?@typescript-eslint\/no-explicit-any\b/.test(comment.value);
104
+ if (sameLineDisable && /--\s*\S/.test(comment.value)) {
105
+ ends.push(-comment.loc.end.line);
106
+ continue;
107
+ }
108
+ if (/^\s*eslint-disable-next-line\s+(?:[^\n]*\s)?@typescript-eslint\/no-explicit-any\b/.test(comment.value) &&
109
+ /--\s*\S/.test(comment.value)) {
110
+ ends.push(comment.loc.end.line);
111
+ }
112
+ }
113
+ return ends;
114
+ }
115
+ function isCommentOrBlankLine(text) {
116
+ const t = text.trim();
117
+ return t === "" || t.startsWith("//") || t.startsWith("*") || t.startsWith("/*");
118
+ }
119
+ function isSuppressed(anyLine, disableLines, sourceLines) {
120
+ for (const raw of disableLines) {
121
+ if (raw < 0) {
122
+ if (-raw === anyLine)
123
+ return true;
124
+ continue;
125
+ }
126
+ if (raw >= anyLine)
127
+ continue;
128
+ let allBlank = true;
129
+ for (let l = raw + 1; l < anyLine; l++) {
130
+ const text = sourceLines[l - 1] ?? "";
131
+ if (!isCommentOrBlankLine(text)) {
132
+ allBlank = false;
133
+ break;
134
+ }
135
+ }
136
+ if (allBlank)
137
+ return true;
138
+ }
139
+ return false;
140
+ }
141
+ // Honors `@keel-ignore-file: <principle-id>` directive anywhere in the source.
142
+ // Use when a file is structurally required to violate a principle (e.g. ORM
143
+ // type definitions whose property names are dictated by the library API).
144
+ export function hasIgnoreFileDirective(src, principleId) {
145
+ const escaped = principleId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
146
+ return new RegExp(`@keel-ignore-file\\s*:\\s*${escaped}\\b`).test(src);
147
+ }
148
+ // Honors `@keel-ignore-next-line: <principle-id>` directive on the line above
149
+ // a match. Mirrors eslint-disable-next-line semantics.
150
+ export function isIgnoreNextLine(src, lineIndex, principleId) {
151
+ const lines = src.split("\n");
152
+ const prev = lines[lineIndex - 1] ?? "";
153
+ const escaped = principleId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
154
+ return new RegExp(`@keel-ignore-next-line\\s*:\\s*${escaped}\\b`).test(prev);
155
+ }
156
+ // A principle's own check file inevitably contains the patterns it looks
157
+ // for; exclude self-scans so the gate doesn't fire on itself.
158
+ function isOwnCheckFile(path) {
159
+ return /packages\/pack-[^/]+\/src\/index\.ts$/.test(path);
160
+ }
161
+ export const generalSEPrinciples = [
162
+ {
163
+ id: "single-source-of-truth",
164
+ description: "Every fact has exactly one canonical home; all other references point to it",
165
+ rationale: "Duplicated truth diverges over time; the second copy is wrong before anyone notices",
166
+ severity: "critical",
167
+ },
168
+ {
169
+ id: "no-dead-code",
170
+ description: "Delete code that is not called; do not comment it out",
171
+ rationale: "Dead code is confusion for the next reader and a maintenance liability",
172
+ severity: "warning",
173
+ },
174
+ {
175
+ id: "tests-as-contracts",
176
+ description: "Every public module has a co-located test that proves its contract",
177
+ rationale: "A test is the cheapest, most precise form of documentation that cannot go stale",
178
+ severity: "critical",
179
+ check({ diff, cwd }) {
180
+ // Honor the verify cwd so checks resolve files correctly when the
181
+ // orchestrator or scheduler invokes verify against a project at a
182
+ // non-process-cwd path; fall back to process.cwd() for direct runs.
183
+ const root = cwd ?? process.cwd();
184
+ const violations = [];
185
+ const addedOrModifiedSrc = diff.files.filter((f) => (f.status === "added" || f.status === "modified") &&
186
+ f.path.match(/packages\/[^/]+\/src\/[^/]+\.ts$/) &&
187
+ !f.path.endsWith(".test.ts") &&
188
+ !f.path.endsWith(".d.ts") &&
189
+ !isTemplateFile(f.path));
190
+ for (const file of addedOrModifiedSrc) {
191
+ if (/packages\/pack-[^/]+\/src\/index\.ts$/.test(file.path))
192
+ continue;
193
+ if (/packages\/eslint-plugin\/src\/rules\//.test(file.path))
194
+ continue;
195
+ const absPath = join(root, file.path);
196
+ if (existsSync(absPath)) {
197
+ try {
198
+ const src = readFileSync(absPath, "utf-8");
199
+ const ast = parseProgram(src);
200
+ if (ast) {
201
+ if (isReExportOnlyBarrel(ast.body))
202
+ continue;
203
+ if (isTypeOnlyModule(ast.body))
204
+ continue;
205
+ }
206
+ }
207
+ catch {
208
+ // unreadable — fall through to test-existence check
209
+ }
210
+ }
211
+ const basename = file.path.replace(/^.*\/([^/]+)\.ts$/, "$1");
212
+ const packageRoot = file.path.replace(/(packages\/[^/]+)\/.*$/, "$1");
213
+ const candidates = [
214
+ file.path.replace(/\.ts$/, ".test.ts"),
215
+ `${packageRoot}/src/__tests__/${basename}.test.ts`,
216
+ `${packageRoot}/__tests__/${basename}.test.ts`,
217
+ `${packageRoot}/src/index.test.ts`,
218
+ ];
219
+ if (!candidates.some((p) => existsSync(join(root, p)))) {
220
+ violations.push({
221
+ principleId: "tests-as-contracts",
222
+ file: file.path,
223
+ severity: "critical",
224
+ message: `Source file "${file.path}" has no test — looked for co-located ${basename}.test.ts, __tests__/${basename}.test.ts, or package-level index.test.ts`,
225
+ });
226
+ }
227
+ }
228
+ return violations;
229
+ },
230
+ },
231
+ {
232
+ id: "errors-at-boundaries",
233
+ description: "Validate and throw at every system boundary; never pass invalid state inward",
234
+ rationale: "Errors close to their origin are cheap; errors discovered deep in the call stack are expensive",
235
+ severity: "critical",
236
+ },
237
+ {
238
+ id: "no-comments-unless-why",
239
+ description: "Write zero comments by default; the only acceptable comment explains a non-obvious why",
240
+ rationale: "Identifiers carry meaning; comments explaining what or how go stale and mislead",
241
+ severity: "warning",
242
+ },
243
+ {
244
+ id: "request-isolation",
245
+ description: "Each request is fully self-contained; no shared mutable state between requests",
246
+ rationale: "Shared state is the source of the hardest bugs to reproduce and the hardest to debug under load",
247
+ severity: "critical",
248
+ },
249
+ {
250
+ id: "wrong-way-impossible",
251
+ description: "Make invalid states unrepresentable at the type level",
252
+ rationale: "A type error at compile time is free; a runtime error in production is expensive",
253
+ severity: "critical",
254
+ check({ diff, cwd }) {
255
+ // Honor the verify cwd so file reads resolve against the target project
256
+ // rather than the runner's working directory.
257
+ const root = cwd ?? process.cwd();
258
+ const violations = [];
259
+ for (const file of diff.files) {
260
+ if (!file.path.endsWith(".ts"))
261
+ continue;
262
+ if (isOwnCheckFile(file.path))
263
+ continue;
264
+ const absPath = join(root, file.path);
265
+ if (!existsSync(absPath))
266
+ continue;
267
+ try {
268
+ const content = readFileSync(absPath, "utf-8");
269
+ if (hasIgnoreFileDirective(content, "wrong-way-impossible"))
270
+ continue;
271
+ const ast = parseProgram(content);
272
+ if (!ast)
273
+ continue;
274
+ const unjustified = countUnjustifiedAny(ast, content.split("\n"));
275
+ if (unjustified > 0) {
276
+ violations.push({
277
+ principleId: "wrong-way-impossible",
278
+ file: file.path,
279
+ severity: "warning",
280
+ message: `Found ${unjustified} unjustified use(s) of ": any" in "${file.path}". Use precise types, unknown, or add an eslint-disable-next-line @typescript-eslint/no-explicit-any with a reason comment.`,
281
+ });
282
+ }
283
+ }
284
+ catch {
285
+ // File unreadable at check time; skip rather than false-positive
286
+ }
287
+ }
288
+ return violations;
289
+ },
290
+ },
291
+ {
292
+ id: "existing-patterns-first",
293
+ description: "Before introducing a new abstraction, check whether an existing pattern covers the need",
294
+ rationale: "Proliferating abstractions raises the cognitive load for every future contributor",
295
+ severity: "warning",
296
+ },
297
+ {
298
+ id: "boundaries-not-layers",
299
+ description: "Organize code by bounded context (what it does) rather than by technical layer (how it does it)",
300
+ rationale: "Layer-organized code scatters a single feature across multiple directories, making changes require touching many files",
301
+ severity: "warning",
302
+ },
303
+ {
304
+ id: "naming-is-design",
305
+ description: "Names must communicate intent precisely; rename ruthlessly when the concept evolves",
306
+ rationale: "Imprecise names accumulate cognitive debt; every reader must reverse-engineer intent that a good name would convey directly",
307
+ severity: "warning",
308
+ check({ diff, cwd }) {
309
+ // Honor the verify cwd so file reads resolve against the target project
310
+ // rather than the runner's working directory.
311
+ const root = cwd ?? process.cwd();
312
+ const violations = [];
313
+ for (const file of diff.files) {
314
+ if (!file.path.endsWith(".ts"))
315
+ continue;
316
+ if (file.status === "removed")
317
+ continue;
318
+ if (isOwnCheckFile(file.path))
319
+ continue;
320
+ // architecture/data.ts is a data file; the word "data" in its filename
321
+ // and string-literal layer ids is structural, not a vague identifier.
322
+ if (file.path.endsWith("/architecture/data.ts"))
323
+ continue;
324
+ const absPath = join(root, file.path);
325
+ if (!existsSync(absPath))
326
+ continue;
327
+ try {
328
+ const content = readFileSync(absPath, "utf-8");
329
+ if (hasIgnoreFileDirective(content, "naming-is-design"))
330
+ continue;
331
+ const ast = parseProgram(content);
332
+ if (!ast)
333
+ continue;
334
+ const flagged = vagueNames(ast);
335
+ if (flagged.length > 2) {
336
+ violations.push({
337
+ principleId: "naming-is-design",
338
+ file: file.path,
339
+ severity: "warning",
340
+ message: `Found ${flagged.length} vague identifier(s) in "${file.path}". Use names that communicate intent.`,
341
+ });
342
+ }
343
+ }
344
+ catch {
345
+ // File unreadable; skip
346
+ }
347
+ }
348
+ return violations;
349
+ },
350
+ },
351
+ {
352
+ id: "delete-before-add",
353
+ description: "Before adding a new abstraction or dependency, delete the thing it replaces; leave no orphans",
354
+ rationale: "Orphaned abstractions and unreferenced dependencies accumulate silently and increase maintenance surface without providing value",
355
+ severity: "warning",
356
+ },
357
+ {
358
+ id: "no-todo-comments",
359
+ description: "Source files contain no TODO / FIXME / XXX comments; either build the thing or surface the blocker",
360
+ rationale: "A TODO is a promise to a future reader that the author already knows won't be kept; tasks belong in the issue tracker or commit message, not as drift in source",
361
+ severity: "warning",
362
+ check({ diff, cwd }) {
363
+ // Honor the verify cwd so file reads resolve against the target project
364
+ // rather than the runner's working directory.
365
+ const root = cwd ?? process.cwd();
366
+ const violations = [];
367
+ for (const file of diff.files) {
368
+ if (file.status === "removed")
369
+ continue;
370
+ if (!/\.(ts|tsx|js|jsx|mjs)$/.test(file.path))
371
+ continue;
372
+ if (isOwnCheckFile(file.path))
373
+ continue;
374
+ if (file.path.endsWith(".test.ts") || file.path.endsWith(".test.tsx"))
375
+ continue;
376
+ const absPath = join(root, file.path);
377
+ if (!existsSync(absPath))
378
+ continue;
379
+ let content;
380
+ try {
381
+ content = readFileSync(absPath, "utf-8");
382
+ }
383
+ catch {
384
+ continue;
385
+ }
386
+ if (hasIgnoreFileDirective(content, "no-todo-comments"))
387
+ continue;
388
+ const ast = parseProgram(content);
389
+ if (!ast)
390
+ continue;
391
+ for (const comment of ast.comments ?? []) {
392
+ if (!/\b(TODO|FIXME|XXX)\b/.test(comment.value))
393
+ continue;
394
+ const line = comment.loc.start.line;
395
+ if (isIgnoreNextLine(content, line - 1, "no-todo-comments"))
396
+ continue;
397
+ violations.push({
398
+ principleId: "no-todo-comments",
399
+ file: file.path,
400
+ line,
401
+ severity: "warning",
402
+ message: `${file.path}:${line} — TODO/FIXME/XXX comment present. Either build it, file an issue, or annotate with // @keel-ignore-next-line: no-todo-comments and explain why.`,
403
+ });
404
+ }
405
+ }
406
+ return violations;
407
+ },
408
+ },
409
+ {
410
+ id: "gate-is-reproducible",
411
+ description: "The verify gate's result must not depend on the runner's OS, Node version, or local cache",
412
+ rationale: "A gate that green-lights locally but fails in CI (or vice-versa) destroys confidence in the gate; hardcoded machine paths are the most common root cause",
413
+ severity: "critical",
414
+ check({ diff, cwd }) {
415
+ // Honor the verify cwd so file reads resolve against the target project
416
+ // rather than the runner's working directory.
417
+ const root = cwd ?? process.cwd();
418
+ const violations = [];
419
+ const ABSOLUTE_PATH_RE = /\/Users\/[^/\s"'`]+\/|\/home\/[^/\s"'`]+\//g;
420
+ for (const file of diff.files) {
421
+ if (file.status === "removed")
422
+ continue;
423
+ if (isOwnCheckFile(file.path))
424
+ continue;
425
+ if (isTemplateFile(file.path))
426
+ continue;
427
+ if (file.path === "architecture/data.ts" || file.path.endsWith("/architecture/data.ts"))
428
+ continue;
429
+ if (/packages\/eslint-plugin\/src\/rules\//.test(file.path))
430
+ continue;
431
+ if (!file.path.match(/\.(ts|tsx|js|mjs|json|yaml|yml)$/))
432
+ continue;
433
+ if (file.path.endsWith(".test.ts") || file.path.endsWith(".test.tsx"))
434
+ continue;
435
+ const absPath = join(root, file.path);
436
+ if (!existsSync(absPath))
437
+ continue;
438
+ let content;
439
+ try {
440
+ content = readFileSync(absPath, "utf-8");
441
+ }
442
+ catch {
443
+ continue;
444
+ }
445
+ if (hasIgnoreFileDirective(content, "gate-is-reproducible"))
446
+ continue;
447
+ const lines = content.split("\n");
448
+ for (let i = 0; i < lines.length; i++) {
449
+ const line = lines[i] ?? "";
450
+ const matches = line.matchAll(ABSOLUTE_PATH_RE);
451
+ for (const match of matches) {
452
+ if (isIgnoreNextLine(content, i, "gate-is-reproducible"))
453
+ continue;
454
+ violations.push({
455
+ principleId: "gate-is-reproducible",
456
+ file: file.path,
457
+ line: i + 1,
458
+ severity: "critical",
459
+ message: `${file.path}:${i + 1} — hardcoded absolute user path "${match[0].replace(/\/$/, "")}" makes the result machine-specific. Use process.cwd(), os.homedir(), or a relative path instead.`,
460
+ });
461
+ }
462
+ }
463
+ }
464
+ return violations;
465
+ },
466
+ },
467
+ {
468
+ id: "no-untyped-seam-fetch",
469
+ description: "Cross-process seam calls must go through the typed client; raw fetch() to the API base URL is forbidden in code that has a typed client available",
470
+ rationale: "Hand-rolled fetch bypasses the type system: wrong procedure names and malformed inputs compile silently, creating seam bugs that only surface at runtime",
471
+ severity: "critical",
472
+ check({ diff, cwd }) {
473
+ const FETCH_HOLDERS = new Set(["globalThis", "window", "self"]);
474
+ const API_URL_VARS = new Set([
475
+ "API_URL",
476
+ "KEEL_API_URL",
477
+ "apiUrl",
478
+ "apiURL",
479
+ "baseUrl",
480
+ "baseURL",
481
+ "apiBase",
482
+ "apiBaseUrl",
483
+ "BASE_URL",
484
+ "API_BASE_URL",
485
+ ]);
486
+ const KEEL_ENV_KEYS = new Set([
487
+ "KEEL_API_URL",
488
+ "API_URL",
489
+ "API_BASE_URL",
490
+ ]);
491
+ const NON_EXTENSION_RE = /^[a-zA-Z][a-zA-Z0-9_]+$/;
492
+ const KNOWN_EXTENSIONS = new Set([
493
+ "png", "jpg", "jpeg", "gif", "svg", "ico", "webp",
494
+ "js", "ts", "mjs", "cjs", "jsx", "tsx",
495
+ "css", "scss", "less",
496
+ "json", "yaml", "yml", "xml", "html", "htm",
497
+ "txt", "md", "pdf", "csv",
498
+ "woff", "woff2", "ttf", "eot",
499
+ "map",
500
+ ]);
501
+ function looksLikeTrpcPath(segment) {
502
+ const lastSlashIdx = segment.lastIndexOf("/");
503
+ const lastSegment = lastSlashIdx >= 0 ? segment.slice(lastSlashIdx + 1) : segment;
504
+ const dotIdx = lastSegment.indexOf(".");
505
+ if (dotIdx < 0)
506
+ return false;
507
+ const routerPart = lastSegment.slice(0, dotIdx);
508
+ const procedurePart = lastSegment.slice(dotIdx + 1);
509
+ if (!NON_EXTENSION_RE.test(routerPart))
510
+ return false;
511
+ if (!NON_EXTENSION_RE.test(procedurePart))
512
+ return false;
513
+ if (KNOWN_EXTENSIONS.has(procedurePart.toLowerCase()))
514
+ return false;
515
+ return true;
516
+ }
517
+ function isFetchCallee(callee) {
518
+ if (callee.type === AST_NODE_TYPES.Identifier)
519
+ return callee.name === "fetch";
520
+ return (callee.type === AST_NODE_TYPES.MemberExpression &&
521
+ !callee.computed &&
522
+ callee.property.type === AST_NODE_TYPES.Identifier &&
523
+ callee.property.name === "fetch" &&
524
+ callee.object.type === AST_NODE_TYPES.Identifier &&
525
+ FETCH_HOLDERS.has(callee.object.name));
526
+ }
527
+ function isProcessEnvApiKey(node) {
528
+ if (node.type !== AST_NODE_TYPES.MemberExpression)
529
+ return false;
530
+ if (node.object.type !== AST_NODE_TYPES.MemberExpression ||
531
+ node.object.object.type !== AST_NODE_TYPES.Identifier ||
532
+ node.object.object.name !== "process" ||
533
+ node.object.property.type !== AST_NODE_TYPES.Identifier ||
534
+ node.object.property.name !== "env")
535
+ return false;
536
+ if (!node.computed && node.property.type === AST_NODE_TYPES.Identifier) {
537
+ return KEEL_ENV_KEYS.has(node.property.name);
538
+ }
539
+ if (node.computed && node.property.type === AST_NODE_TYPES.Literal && typeof node.property.value === "string") {
540
+ return KEEL_ENV_KEYS.has(node.property.value);
541
+ }
542
+ return false;
543
+ }
544
+ function isProcessEnvAnyKey(node) {
545
+ return (node.type === AST_NODE_TYPES.MemberExpression &&
546
+ node.object.type === AST_NODE_TYPES.MemberExpression &&
547
+ node.object.object.type === AST_NODE_TYPES.Identifier &&
548
+ node.object.object.name === "process" &&
549
+ node.object.property.type === AST_NODE_TYPES.Identifier &&
550
+ node.object.property.name === "env");
551
+ }
552
+ function collectAliasedVars(ast) {
553
+ const aliased = new Set();
554
+ walk(ast, (node) => {
555
+ if (node.type === AST_NODE_TYPES.VariableDeclarator &&
556
+ node.id.type === AST_NODE_TYPES.Identifier &&
557
+ node.init &&
558
+ isProcessEnvApiKey(node.init)) {
559
+ aliased.add(node.id.name);
560
+ }
561
+ });
562
+ return aliased;
563
+ }
564
+ function isApiUrlReference(node, aliasedVars) {
565
+ if (node.type === AST_NODE_TYPES.Identifier) {
566
+ if (API_URL_VARS.has(node.name))
567
+ return true;
568
+ if (aliasedVars.has(node.name))
569
+ return true;
570
+ }
571
+ if (isProcessEnvAnyKey(node))
572
+ return true;
573
+ return false;
574
+ }
575
+ const KEEL_API_HOSTS = /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?/;
576
+ function templateHasApiSeam(node, aliasedVars) {
577
+ const hasApiRef = node.expressions.some((expr) => isApiUrlReference(expr, aliasedVars));
578
+ if (!hasApiRef)
579
+ return false;
580
+ return node.quasis.some((quasi) => looksLikeTrpcPath(quasi.value.raw));
581
+ }
582
+ function stringLiteralHasApiSeam(value) {
583
+ if (!KEEL_API_HOSTS.test(value))
584
+ return false;
585
+ return looksLikeTrpcPath(value);
586
+ }
587
+ function leftmostBinaryOperand(node) {
588
+ if (node.type === AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
589
+ return leftmostBinaryOperand(node.left);
590
+ }
591
+ return node;
592
+ }
593
+ function firstArgIsApiSeam(arg, aliasedVars) {
594
+ if (arg.type === AST_NODE_TYPES.TemplateLiteral)
595
+ return templateHasApiSeam(arg, aliasedVars);
596
+ if (arg.type === AST_NODE_TYPES.Literal && typeof arg.value === "string") {
597
+ return stringLiteralHasApiSeam(arg.value);
598
+ }
599
+ if (arg.type === AST_NODE_TYPES.BinaryExpression && arg.operator === "+") {
600
+ if (isApiUrlReference(leftmostBinaryOperand(arg), aliasedVars)) {
601
+ return true;
602
+ }
603
+ }
604
+ return false;
605
+ }
606
+ // Honor the verify cwd so file reads resolve against the target project
607
+ // rather than the runner's working directory.
608
+ const root = cwd ?? process.cwd();
609
+ const violations = [];
610
+ for (const file of diff.files) {
611
+ if (file.status === "removed")
612
+ continue;
613
+ if (!/\.(ts|tsx)$/.test(file.path))
614
+ continue;
615
+ if (file.path.endsWith(".test.ts") || file.path.endsWith(".test.tsx"))
616
+ continue;
617
+ if (isOwnCheckFile(file.path))
618
+ continue;
619
+ if (/packages\/(cli|telemetry)\//.test(file.path))
620
+ continue;
621
+ const absPath = join(root, file.path);
622
+ if (!existsSync(absPath))
623
+ continue;
624
+ let content;
625
+ try {
626
+ content = readFileSync(absPath, "utf-8");
627
+ }
628
+ catch {
629
+ continue;
630
+ }
631
+ if (hasIgnoreFileDirective(content, "no-untyped-seam-fetch"))
632
+ continue;
633
+ const ast = parseProgram(content);
634
+ if (!ast)
635
+ continue;
636
+ const aliasedVars = collectAliasedVars(ast);
637
+ walk(ast, (node) => {
638
+ if (node.type !== AST_NODE_TYPES.CallExpression)
639
+ return;
640
+ if (!isFetchCallee(node.callee))
641
+ return;
642
+ const firstArg = node.arguments[0];
643
+ if (!firstArg)
644
+ return;
645
+ if (!firstArgIsApiSeam(firstArg, aliasedVars))
646
+ return;
647
+ const line = node.loc.start.line;
648
+ if (isIgnoreNextLine(content, line - 1, "no-untyped-seam-fetch"))
649
+ return;
650
+ violations.push({
651
+ principleId: "no-untyped-seam-fetch",
652
+ file: file.path,
653
+ line,
654
+ severity: "critical",
655
+ message: `${file.path}:${line} — raw fetch() to the API seam. Use createServerClient() and call the typed procedure instead.`,
656
+ });
657
+ });
658
+ }
659
+ return violations;
660
+ },
661
+ },
662
+ ];
663
+ export const generalSEPack = {
664
+ id: "@keel_flow/pack-general-se",
665
+ version: "0.1.0",
666
+ description: "General software engineering principles applicable to any TypeScript codebase.",
667
+ principles: generalSEPrinciples,
668
+ };
669
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ interface Stmt {
2
+ type: string;
3
+ exportKind?: string;
4
+ importKind?: string;
5
+ source?: unknown;
6
+ declaration?: unknown;
7
+ }
8
+ export declare function isReExportOnlyBarrel(body: Stmt[]): boolean;
9
+ export declare function isTypeOnlyModule(body: Stmt[]): boolean;
10
+ export declare function isTemplateFile(path: string): boolean;
11
+ export {};
12
+ //# sourceMappingURL=scope-filters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-filters.d.ts","sourceRoot":"","sources":["../src/scope-filters.ts"],"names":[],"mappings":"AAAA,UAAU,IAAI;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,CAU1D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,CAQtD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD"}
@@ -0,0 +1,20 @@
1
+ export function isReExportOnlyBarrel(body) {
2
+ if (body.length === 0)
3
+ return false;
4
+ return body.every((stmt) => stmt.type === "ExportAllDeclaration" ||
5
+ (stmt.type === "ExportNamedDeclaration" &&
6
+ stmt.source !== null &&
7
+ stmt.source !== undefined &&
8
+ stmt.declaration === null));
9
+ }
10
+ export function isTypeOnlyModule(body) {
11
+ if (body.length === 0)
12
+ return false;
13
+ return body.every((stmt) => (stmt.type === "ImportDeclaration" && stmt.importKind === "type") ||
14
+ ((stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportAllDeclaration") &&
15
+ stmt.exportKind === "type"));
16
+ }
17
+ export function isTemplateFile(path) {
18
+ return path.endsWith(".tpl") || path.endsWith(".tpl.ts");
19
+ }
20
+ //# sourceMappingURL=scope-filters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-filters.js","sourceRoot":"","sources":["../src/scope-filters.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,IAAI,CAAC,KAAK,CACf,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,IAAI,KAAK,sBAAsB;QACpC,CAAC,IAAI,CAAC,IAAI,KAAK,wBAAwB;YACrC,IAAI,CAAC,MAAM,KAAK,IAAI;YACpB,IAAI,CAAC,MAAM,KAAK,SAAS;YACzB,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,CAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,IAAI,CAAC,KAAK,CACf,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,IAAI,CAAC,IAAI,KAAK,mBAAmB,IAAI,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC;QACjE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,wBAAwB,IAAI,IAAI,CAAC,IAAI,KAAK,sBAAsB,CAAC;YAC/E,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,CAChC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC3D,CAAC"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@keel_flow/pack-general-se",
3
+ "version": "0.2.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "General software engineering principles for Keel projects",
7
+ "keywords": [
8
+ "keel",
9
+ "principles",
10
+ "engineering"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "import": "./dist/index.js",
24
+ "types": "./dist/index.d.ts"
25
+ },
26
+ "./scope-filters": {
27
+ "import": "./dist/scope-filters.js",
28
+ "types": "./dist/scope-filters.d.ts"
29
+ }
30
+ },
31
+ "dependencies": {
32
+ "@typescript-eslint/typescript-estree": "^8.0.0",
33
+ "@keel_flow/schema": "0.2.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^25.9.1",
37
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
38
+ "@typescript-eslint/parser": "^8.0.0",
39
+ "eslint": "^9.0.0",
40
+ "typescript": "^5.5.0",
41
+ "vitest": "^2.0.0"
42
+ },
43
+ "scripts": {
44
+ "build": "tsc",
45
+ "typecheck": "tsc --noEmit",
46
+ "test": "vitest run",
47
+ "lint": "eslint src"
48
+ }
49
+ }