sqlew 5.1.0 → 5.2.1
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/CHANGELOG.md +2140 -2081
- package/LICENSE +190 -190
- package/NOTICE +24 -24
- package/README.md +204 -190
- package/dist/adapters/mysql-adapter.js +3 -3
- package/dist/adapters/postgresql-adapter.js +3 -3
- package/dist/cli/db-export.js +32 -32
- package/dist/cli/db-import.js +30 -30
- package/dist/cli/hooks/codex-transcript.d.ts +23 -0
- package/dist/cli/hooks/codex-transcript.d.ts.map +1 -0
- package/dist/cli/hooks/codex-transcript.js +134 -0
- package/dist/cli/hooks/codex-transcript.js.map +1 -0
- package/dist/cli/hooks/on-exit-plan.d.ts.map +1 -1
- package/dist/cli/hooks/on-exit-plan.js +72 -4
- package/dist/cli/hooks/on-exit-plan.js.map +1 -1
- package/dist/cli/hooks/on-prompt.d.ts.map +1 -1
- package/dist/cli/hooks/on-prompt.js +38 -16
- package/dist/cli/hooks/on-prompt.js.map +1 -1
- package/dist/cli/hooks/plan-processor.d.ts.map +1 -1
- package/dist/cli/hooks/plan-processor.js +16 -2
- package/dist/cli/hooks/plan-processor.js.map +1 -1
- package/dist/cli/hooks/pr-adr.js +5 -5
- package/dist/cli/hooks/stdin-parser.d.ts +43 -0
- package/dist/cli/hooks/stdin-parser.d.ts.map +1 -1
- package/dist/cli/hooks/stdin-parser.js +212 -6
- package/dist/cli/hooks/stdin-parser.js.map +1 -1
- package/dist/cli/hooks/track-plan.d.ts +13 -0
- package/dist/cli/hooks/track-plan.d.ts.map +1 -1
- package/dist/cli/hooks/track-plan.js +73 -18
- package/dist/cli/hooks/track-plan.js.map +1 -1
- package/dist/cli.js +48 -48
- package/dist/config/global-config.d.ts +7 -1
- package/dist/config/global-config.d.ts.map +1 -1
- package/dist/config/global-config.js +5 -26
- package/dist/config/global-config.js.map +1 -1
- package/dist/database/migrations/v4/20251126000000_v4_bootstrap.js +32 -32
- package/dist/database/migrations/v4/20251126000001_v4_migrate_data.d.ts.map +1 -1
- package/dist/database/migrations/v4/20251126000001_v4_migrate_data.js +2 -1
- package/dist/database/migrations/v4/20251126000001_v4_migrate_data.js.map +1 -1
- package/dist/database/migrations/v4/20260102204000_v4_fix_decision_set_example.js +3 -3
- package/dist/help-data/constraint.toml +259 -259
- package/dist/help-data/decision.toml +845 -845
- package/dist/help-data/queue.toml +134 -134
- package/dist/server/tool-schemas.js +30 -30
- package/dist/tests/docker/native/db-init.js +9 -9
- package/dist/tests/unit/hooks/codex-hook-normalization.test.d.ts +7 -0
- package/dist/tests/unit/hooks/codex-hook-normalization.test.d.ts.map +1 -0
- package/dist/tests/unit/hooks/codex-hook-normalization.test.js +112 -0
- package/dist/tests/unit/hooks/codex-hook-normalization.test.js.map +1 -0
- package/dist/tests/unit/hooks/grok-hook-normalization.test.d.ts +9 -0
- package/dist/tests/unit/hooks/grok-hook-normalization.test.d.ts.map +1 -0
- package/dist/tests/unit/hooks/grok-hook-normalization.test.js +136 -0
- package/dist/tests/unit/hooks/grok-hook-normalization.test.js.map +1 -0
- package/dist/tests/unit/hooks/grok-plan-template-injection.test.d.ts +7 -0
- package/dist/tests/unit/hooks/grok-plan-template-injection.test.d.ts.map +1 -0
- package/dist/tests/unit/hooks/grok-plan-template-injection.test.js +55 -0
- package/dist/tests/unit/hooks/grok-plan-template-injection.test.js.map +1 -0
- package/dist/tests/utils/db-schema.js +48 -48
- package/dist/tests/utils/test-helpers.js +48 -48
- package/dist/tools/constraints/actions/get.js +5 -5
- package/dist/utils/path-normalize.d.ts +23 -0
- package/dist/utils/path-normalize.d.ts.map +1 -0
- package/dist/utils/path-normalize.js +38 -0
- package/dist/utils/path-normalize.js.map +1 -0
- package/dist/utils/project-root.d.ts +7 -3
- package/dist/utils/project-root.d.ts.map +1 -1
- package/dist/utils/project-root.js +17 -3
- package/dist/utils/project-root.js.map +1 -1
- package/dist/watcher/base-watcher.d.ts +0 -4
- package/dist/watcher/base-watcher.d.ts.map +1 -1
- package/dist/watcher/base-watcher.js +11 -22
- package/dist/watcher/base-watcher.js.map +1 -1
- package/docs/ADR_CONCEPTS.md +152 -152
- package/docs/CLI_USAGE.md +392 -392
- package/docs/CONFIGURATION.md +157 -157
- package/docs/CROSS_DATABASE.md +66 -66
- package/docs/DATABASE_AUTH.md +135 -135
- package/docs/HOOKS_GUIDE.md +116 -67
- package/docs/MIGRATION_TO_SAAS.md +176 -176
- package/docs/SHARED_DATABASE.md +108 -108
- package/package.json +88 -88
- package/scripts/copy-help-data.js +19 -19
- package/scripts/filter-test-output.js +78 -78
package/package.json
CHANGED
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "sqlew",
|
|
3
|
-
"description": "Automated ADR (Architecture Decision Records) for
|
|
4
|
-
"version": "5.1
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"sqlew": "dist/index.js"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"dist/",
|
|
12
|
-
"scripts/",
|
|
13
|
-
"assets/",
|
|
14
|
-
"docs/",
|
|
15
|
-
"README.md",
|
|
16
|
-
"LICENSE",
|
|
17
|
-
"NOTICE",
|
|
18
|
-
"CHANGELOG.md",
|
|
19
|
-
"MIGRATION_v2.md"
|
|
20
|
-
],
|
|
21
|
-
"scripts": {
|
|
22
|
-
"build": "tsc && node scripts/copy-help-data.js",
|
|
23
|
-
"start": "node dist/index.js",
|
|
24
|
-
"dev": "tsc --watch",
|
|
25
|
-
"clean": "rimraf dist",
|
|
26
|
-
"rebuild": "npm run clean && npm run build",
|
|
27
|
-
"test": "node --test --test-force-exit --import tsx \"src/tests/unit/**/*.test.ts\" \"src/tests/feature/**/*.test.ts\" \"src/tests/database/**/*.test.ts\" \"src/tests/integration/**/*.test.ts\" | node scripts/filter-test-output.js",
|
|
28
|
-
"test:ci": "npm run build && npm test",
|
|
29
|
-
"test:native": "npm run build && node --test --test-concurrency=1 --test-force-exit dist/tests/docker/native/**/*.test.js | node scripts/filter-test-output.js",
|
|
30
|
-
"prepare": "husky",
|
|
31
|
-
"prepublishOnly": "npm run rebuild",
|
|
32
|
-
"knex": "npx tsx node_modules/knex/bin/cli.js --knexfile src/knexfile.ts",
|
|
33
|
-
"migrate:make": "npm run knex migrate:make",
|
|
34
|
-
"migrate:latest": "npm run knex migrate:latest",
|
|
35
|
-
"migrate:rollback": "npm run knex migrate:rollback",
|
|
36
|
-
"test:backend": "node --test --test-force-exit --import tsx \"src/tests/backend/**/*.test.ts\" | node scripts/filter-test-output.js",
|
|
37
|
-
"test:backend:verbose": "node --test --test-force-exit --import tsx \"src/tests/backend/**/*.test.ts\"",
|
|
38
|
-
"migrate:status": "npm run knex migrate:status"
|
|
39
|
-
},
|
|
40
|
-
"engines": {
|
|
41
|
-
"node": ">=20.0.0"
|
|
42
|
-
},
|
|
43
|
-
"repository": {
|
|
44
|
-
"type": "git",
|
|
45
|
-
"url": "git+https://github.com/sqlew-io/sqlew.git"
|
|
46
|
-
},
|
|
47
|
-
"bugs": {
|
|
48
|
-
"url": "https://github.com/sqlew-io/sqlew/issues"
|
|
49
|
-
},
|
|
50
|
-
"homepage": "https://github.com/sqlew-io/sqlew#readme",
|
|
51
|
-
"keywords": [
|
|
52
|
-
"adr",
|
|
53
|
-
"architecture-decision-record",
|
|
54
|
-
"mcp",
|
|
55
|
-
"mcp-server",
|
|
56
|
-
"model-context-protocol",
|
|
57
|
-
"ai-agents",
|
|
58
|
-
"claude-code",
|
|
59
|
-
"architectural-decisions",
|
|
60
|
-
"decision-management",
|
|
61
|
-
"sqlite",
|
|
62
|
-
"postgresql",
|
|
63
|
-
"mysql",
|
|
64
|
-
"token-efficiency"
|
|
65
|
-
],
|
|
66
|
-
"author": "sqlew-io",
|
|
67
|
-
"license": "Apache-2.0",
|
|
68
|
-
"dependencies": {
|
|
69
|
-
"@modelcontextprotocol/sdk": "^1.21.1",
|
|
70
|
-
"better-sqlite3": "^12.4.1",
|
|
71
|
-
"chokidar": "^4.0.3",
|
|
72
|
-
"knex": "^3.1.0",
|
|
73
|
-
"knex-schema-inspector": "^3.1.0",
|
|
74
|
-
"mysql2": "^3.15.3",
|
|
75
|
-
"pg": "^8.16.3",
|
|
76
|
-
"smol-toml": "^1.4.2",
|
|
77
|
-
"zod": "^4.0.0"
|
|
78
|
-
},
|
|
79
|
-
"devDependencies": {
|
|
80
|
-
"@types/better-sqlite3": "^7.6.0",
|
|
81
|
-
"@types/knex": "^0.15.2",
|
|
82
|
-
"@types/node": "^20.0.0",
|
|
83
|
-
"husky": "^9.1.7",
|
|
84
|
-
"rimraf": "^6.1.0",
|
|
85
|
-
"tsx": "^4.20.6",
|
|
86
|
-
"typescript": "^5.0.0"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "sqlew",
|
|
3
|
+
"description": "Automated ADR (Architecture Decision Records) for AI Coding Agents - MCP server with SQL-backed decision repository",
|
|
4
|
+
"version": "5.2.1",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"sqlew": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/",
|
|
12
|
+
"scripts/",
|
|
13
|
+
"assets/",
|
|
14
|
+
"docs/",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"NOTICE",
|
|
18
|
+
"CHANGELOG.md",
|
|
19
|
+
"MIGRATION_v2.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc && node scripts/copy-help-data.js",
|
|
23
|
+
"start": "node dist/index.js",
|
|
24
|
+
"dev": "tsc --watch",
|
|
25
|
+
"clean": "rimraf dist",
|
|
26
|
+
"rebuild": "npm run clean && npm run build",
|
|
27
|
+
"test": "node --test --test-force-exit --import tsx \"src/tests/unit/**/*.test.ts\" \"src/tests/feature/**/*.test.ts\" \"src/tests/database/**/*.test.ts\" \"src/tests/integration/**/*.test.ts\" | node scripts/filter-test-output.js",
|
|
28
|
+
"test:ci": "npm run build && npm test",
|
|
29
|
+
"test:native": "npm run build && node --test --test-concurrency=1 --test-force-exit dist/tests/docker/native/**/*.test.js | node scripts/filter-test-output.js",
|
|
30
|
+
"prepare": "husky",
|
|
31
|
+
"prepublishOnly": "npm run rebuild",
|
|
32
|
+
"knex": "npx tsx node_modules/knex/bin/cli.js --knexfile src/knexfile.ts",
|
|
33
|
+
"migrate:make": "npm run knex migrate:make",
|
|
34
|
+
"migrate:latest": "npm run knex migrate:latest",
|
|
35
|
+
"migrate:rollback": "npm run knex migrate:rollback",
|
|
36
|
+
"test:backend": "node --test --test-force-exit --import tsx \"src/tests/backend/**/*.test.ts\" | node scripts/filter-test-output.js",
|
|
37
|
+
"test:backend:verbose": "node --test --test-force-exit --import tsx \"src/tests/backend/**/*.test.ts\"",
|
|
38
|
+
"migrate:status": "npm run knex migrate:status"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=20.0.0"
|
|
42
|
+
},
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/sqlew-io/sqlew.git"
|
|
46
|
+
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/sqlew-io/sqlew/issues"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/sqlew-io/sqlew#readme",
|
|
51
|
+
"keywords": [
|
|
52
|
+
"adr",
|
|
53
|
+
"architecture-decision-record",
|
|
54
|
+
"mcp",
|
|
55
|
+
"mcp-server",
|
|
56
|
+
"model-context-protocol",
|
|
57
|
+
"ai-agents",
|
|
58
|
+
"claude-code",
|
|
59
|
+
"architectural-decisions",
|
|
60
|
+
"decision-management",
|
|
61
|
+
"sqlite",
|
|
62
|
+
"postgresql",
|
|
63
|
+
"mysql",
|
|
64
|
+
"token-efficiency"
|
|
65
|
+
],
|
|
66
|
+
"author": "sqlew-io",
|
|
67
|
+
"license": "Apache-2.0",
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"@modelcontextprotocol/sdk": "^1.21.1",
|
|
70
|
+
"better-sqlite3": "^12.4.1",
|
|
71
|
+
"chokidar": "^4.0.3",
|
|
72
|
+
"knex": "^3.1.0",
|
|
73
|
+
"knex-schema-inspector": "^3.1.0",
|
|
74
|
+
"mysql2": "^3.15.3",
|
|
75
|
+
"pg": "^8.16.3",
|
|
76
|
+
"smol-toml": "^1.4.2",
|
|
77
|
+
"zod": "^4.0.0"
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
81
|
+
"@types/knex": "^0.15.2",
|
|
82
|
+
"@types/node": "^20.0.0",
|
|
83
|
+
"husky": "^9.1.7",
|
|
84
|
+
"rimraf": "^6.1.0",
|
|
85
|
+
"tsx": "^4.20.6",
|
|
86
|
+
"typescript": "^5.0.0"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copy help-data TOML files to dist directory
|
|
3
|
-
* Used in build process since tsc doesn't copy non-TS files
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { cpSync } from 'fs';
|
|
7
|
-
import { fileURLToPath } from 'url';
|
|
8
|
-
import { dirname, join } from 'path';
|
|
9
|
-
|
|
10
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
-
const __dirname = dirname(__filename);
|
|
12
|
-
const projectRoot = join(__dirname, '..');
|
|
13
|
-
|
|
14
|
-
const src = join(projectRoot, 'src', 'help-data');
|
|
15
|
-
const dest = join(projectRoot, 'dist', 'help-data');
|
|
16
|
-
|
|
17
|
-
cpSync(src, dest, { recursive: true });
|
|
18
|
-
|
|
19
|
-
console.log('✅ Copied help-data to dist/');
|
|
1
|
+
/**
|
|
2
|
+
* Copy help-data TOML files to dist directory
|
|
3
|
+
* Used in build process since tsc doesn't copy non-TS files
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { cpSync } from 'fs';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import { dirname, join } from 'path';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
const projectRoot = join(__dirname, '..');
|
|
13
|
+
|
|
14
|
+
const src = join(projectRoot, 'src', 'help-data');
|
|
15
|
+
const dest = join(projectRoot, 'dist', 'help-data');
|
|
16
|
+
|
|
17
|
+
cpSync(src, dest, { recursive: true });
|
|
18
|
+
|
|
19
|
+
console.log('✅ Copied help-data to dist/');
|
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Cross-platform test output filter for AI-optimized test results.
|
|
4
|
-
* Filters test output to show only failures and summary lines.
|
|
5
|
-
*
|
|
6
|
-
* Usage: node --test ... | node scripts/filter-test-output.js
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { createInterface } from 'readline';
|
|
10
|
-
|
|
11
|
-
const rl = createInterface({
|
|
12
|
-
input: process.stdin,
|
|
13
|
-
output: process.stdout,
|
|
14
|
-
terminal: false
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
// Pattern matches: errors, failures (lines to SHOW)
|
|
18
|
-
const includePattern = /(✖|Error|FAIL)/;
|
|
19
|
-
|
|
20
|
-
// Pattern matches: passing tests, test start markers (lines to EXCLUDE)
|
|
21
|
-
const excludePattern = /(✔|✅|▶)/;
|
|
22
|
-
|
|
23
|
-
// Pattern matches: TAP pass lines and subtest headers (never failures)
|
|
24
|
-
const tapNonFailurePattern = /^\s*(ok \d|# Subtest:)/;
|
|
25
|
-
|
|
26
|
-
// Pattern to detect final summary section (lines starting with ℹ)
|
|
27
|
-
const summaryPattern = /^ℹ /;
|
|
28
|
-
|
|
29
|
-
let inSummary = false;
|
|
30
|
-
let previousLine = null;
|
|
31
|
-
let linesAfterFailure = 0;
|
|
32
|
-
let hasFailures = false; // Track if any failures were detected
|
|
33
|
-
|
|
34
|
-
rl.on('line', (line) => {
|
|
35
|
-
// If we encounter a summary line, enter summary mode
|
|
36
|
-
if (summaryPattern.test(line)) {
|
|
37
|
-
inSummary = true;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// In summary mode, show all ℹ lines (complete table)
|
|
41
|
-
if (inSummary && summaryPattern.test(line)) {
|
|
42
|
-
console.log(line);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// If we're tracking lines after a failure, show them
|
|
47
|
-
if (linesAfterFailure > 0) {
|
|
48
|
-
console.log(line);
|
|
49
|
-
linesAfterFailure--;
|
|
50
|
-
previousLine = line;
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Check if current line is a failure
|
|
55
|
-
// Exclude TAP pass lines (ok N) and subtest headers (# Subtest:) that may contain "Error" in test names
|
|
56
|
-
const isFailure = includePattern.test(line) && !excludePattern.test(line) && !tapNonFailurePattern.test(line);
|
|
57
|
-
|
|
58
|
-
if (isFailure) {
|
|
59
|
-
hasFailures = true; // Mark that we detected failures
|
|
60
|
-
// Show previous line (context before failure, e.g., "test at ...")
|
|
61
|
-
if (previousLine !== null) {
|
|
62
|
-
console.log(previousLine);
|
|
63
|
-
}
|
|
64
|
-
// Show the failure line itself
|
|
65
|
-
console.log(line);
|
|
66
|
-
// Show next 1 line after failure (error details)
|
|
67
|
-
linesAfterFailure = 1;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Remember current line as previous for next iteration
|
|
71
|
-
previousLine = line;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
rl.on('close', () => {
|
|
75
|
-
// Exit with code 1 if failures detected, 0 otherwise
|
|
76
|
-
// This propagates test failure to shell exit code
|
|
77
|
-
process.exit(hasFailures ? 1 : 0);
|
|
78
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Cross-platform test output filter for AI-optimized test results.
|
|
4
|
+
* Filters test output to show only failures and summary lines.
|
|
5
|
+
*
|
|
6
|
+
* Usage: node --test ... | node scripts/filter-test-output.js
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { createInterface } from 'readline';
|
|
10
|
+
|
|
11
|
+
const rl = createInterface({
|
|
12
|
+
input: process.stdin,
|
|
13
|
+
output: process.stdout,
|
|
14
|
+
terminal: false
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Pattern matches: errors, failures (lines to SHOW)
|
|
18
|
+
const includePattern = /(✖|Error|FAIL)/;
|
|
19
|
+
|
|
20
|
+
// Pattern matches: passing tests, test start markers (lines to EXCLUDE)
|
|
21
|
+
const excludePattern = /(✔|✅|▶)/;
|
|
22
|
+
|
|
23
|
+
// Pattern matches: TAP pass lines and subtest headers (never failures)
|
|
24
|
+
const tapNonFailurePattern = /^\s*(ok \d|# Subtest:)/;
|
|
25
|
+
|
|
26
|
+
// Pattern to detect final summary section (lines starting with ℹ)
|
|
27
|
+
const summaryPattern = /^ℹ /;
|
|
28
|
+
|
|
29
|
+
let inSummary = false;
|
|
30
|
+
let previousLine = null;
|
|
31
|
+
let linesAfterFailure = 0;
|
|
32
|
+
let hasFailures = false; // Track if any failures were detected
|
|
33
|
+
|
|
34
|
+
rl.on('line', (line) => {
|
|
35
|
+
// If we encounter a summary line, enter summary mode
|
|
36
|
+
if (summaryPattern.test(line)) {
|
|
37
|
+
inSummary = true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// In summary mode, show all ℹ lines (complete table)
|
|
41
|
+
if (inSummary && summaryPattern.test(line)) {
|
|
42
|
+
console.log(line);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// If we're tracking lines after a failure, show them
|
|
47
|
+
if (linesAfterFailure > 0) {
|
|
48
|
+
console.log(line);
|
|
49
|
+
linesAfterFailure--;
|
|
50
|
+
previousLine = line;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check if current line is a failure
|
|
55
|
+
// Exclude TAP pass lines (ok N) and subtest headers (# Subtest:) that may contain "Error" in test names
|
|
56
|
+
const isFailure = includePattern.test(line) && !excludePattern.test(line) && !tapNonFailurePattern.test(line);
|
|
57
|
+
|
|
58
|
+
if (isFailure) {
|
|
59
|
+
hasFailures = true; // Mark that we detected failures
|
|
60
|
+
// Show previous line (context before failure, e.g., "test at ...")
|
|
61
|
+
if (previousLine !== null) {
|
|
62
|
+
console.log(previousLine);
|
|
63
|
+
}
|
|
64
|
+
// Show the failure line itself
|
|
65
|
+
console.log(line);
|
|
66
|
+
// Show next 1 line after failure (error details)
|
|
67
|
+
linesAfterFailure = 1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Remember current line as previous for next iteration
|
|
71
|
+
previousLine = line;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
rl.on('close', () => {
|
|
75
|
+
// Exit with code 1 if failures detected, 0 otherwise
|
|
76
|
+
// This propagates test failure to shell exit code
|
|
77
|
+
process.exit(hasFailures ? 1 : 0);
|
|
78
|
+
});
|