@laitszkin/apollo-toolkit 4.1.3 → 5.0.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/CHANGELOG.md +45 -0
- package/bin/apollo-toolkit.ts +4 -0
- package/dist/bin/apollo-toolkit.js +4 -0
- package/package.json +7 -2
- package/packages/cli/dist/help-text-builder.d.ts +23 -0
- package/packages/cli/dist/help-text-builder.js +166 -0
- package/packages/cli/dist/index.d.ts +6 -17
- package/packages/cli/dist/index.js +52 -246
- package/packages/cli/dist/installer.d.ts +1 -0
- package/packages/cli/dist/installer.js +20 -7
- package/packages/cli/dist/parsers/install-parser.d.ts +15 -0
- package/packages/cli/dist/parsers/install-parser.js +87 -0
- package/packages/cli/dist/parsers/parser-utils.d.ts +9 -0
- package/packages/cli/dist/parsers/parser-utils.js +16 -0
- package/packages/cli/dist/parsers/tool-parser.d.ts +16 -0
- package/packages/cli/dist/parsers/tool-parser.js +58 -0
- package/packages/cli/dist/parsers/types.d.ts +50 -0
- package/packages/cli/dist/parsers/types.js +1 -0
- package/packages/cli/dist/parsers/uninstall-parser.d.ts +15 -0
- package/packages/cli/dist/parsers/uninstall-parser.js +67 -0
- package/packages/cli/dist/tool-registration.d.ts +2 -0
- package/packages/cli/dist/tool-registration.js +2 -0
- package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/cli/dist/types.d.ts +3 -1
- package/packages/cli/dist/updater.js +11 -5
- package/packages/cli/help-text-builder.ts +180 -0
- package/packages/cli/index.ts +59 -251
- package/packages/cli/installer.ts +19 -7
- package/packages/cli/package.json +6 -3
- package/packages/cli/parsers/install-parser.ts +94 -0
- package/packages/cli/parsers/parser-utils.ts +17 -0
- package/packages/cli/parsers/tool-parser.ts +65 -0
- package/packages/cli/parsers/types.ts +56 -0
- package/packages/cli/parsers/uninstall-parser.ts +75 -0
- package/packages/cli/tool-registration.ts +3 -0
- package/packages/cli/types.ts +6 -1
- package/packages/cli/updater.ts +11 -5
- package/packages/tool-registry/dist/registry.js +3 -4
- package/packages/tool-registry/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tool-registry/dist/types.d.ts +2 -9
- package/packages/tool-registry/package.json +3 -3
- package/packages/tool-registry/registry.ts +3 -4
- package/packages/tool-registry/tsconfig.json +6 -2
- package/packages/tool-registry/types.ts +3 -9
- package/packages/tool-utils/app-error.ts +97 -0
- package/packages/tool-utils/dist/app-error.d.ts +49 -0
- package/packages/tool-utils/dist/app-error.js +80 -0
- package/packages/tool-utils/dist/index.d.ts +5 -0
- package/packages/tool-utils/dist/index.js +3 -0
- package/packages/tool-utils/dist/platform-adapter.d.ts +48 -0
- package/packages/tool-utils/dist/platform-adapter.js +73 -0
- package/packages/tool-utils/dist/schema.d.ts +68 -0
- package/packages/tool-utils/dist/schema.js +67 -0
- package/packages/tool-utils/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tool-utils/index.ts +12 -0
- package/packages/tool-utils/package.json +3 -3
- package/packages/tool-utils/platform-adapter.ts +112 -0
- package/packages/tool-utils/schema.ts +122 -0
- package/packages/tools/architecture/dist/index.d.ts +13 -0
- package/packages/tools/architecture/dist/index.js +55 -57
- package/packages/tools/architecture/dist/index.test.js +17 -4
- package/packages/tools/architecture/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/architecture/index.test.ts +27 -14
- package/packages/tools/architecture/index.ts +85 -88
- package/packages/tools/architecture/package.json +3 -3
- package/packages/tools/codegraph/dist/index.js +21 -17
- package/packages/tools/codegraph/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/codegraph/index.ts +21 -17
- package/packages/tools/codegraph/package.json +3 -3
- package/packages/tools/create-review-report/dist/index.d.ts +1 -2
- package/packages/tools/create-review-report/dist/index.js +46 -77
- package/packages/tools/create-review-report/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/create-review-report/index.ts +52 -81
- package/packages/tools/create-review-report/package.json +3 -3
- package/packages/tools/create-specs/dist/index.d.ts +1 -2
- package/packages/tools/create-specs/dist/index.js +70 -123
- package/packages/tools/create-specs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/create-specs/index.ts +82 -128
- package/packages/tools/create-specs/package.json +3 -3
- package/packages/tools/docs-to-voice/dist/index.d.ts +1 -2
- package/packages/tools/docs-to-voice/dist/index.js +116 -219
- package/packages/tools/docs-to-voice/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/docs-to-voice/index.ts +265 -385
- package/packages/tools/docs-to-voice/package.json +3 -3
- package/packages/tools/enforce-video-aspect-ratio/dist/index.d.ts +1 -2
- package/packages/tools/enforce-video-aspect-ratio/dist/index.js +77 -154
- package/packages/tools/enforce-video-aspect-ratio/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/enforce-video-aspect-ratio/index.ts +87 -172
- package/packages/tools/enforce-video-aspect-ratio/package.json +3 -3
- package/packages/tools/eval/dist/index.js +7 -0
- package/packages/tools/eval/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/eval/index.ts +8 -0
- package/packages/tools/eval/package.json +3 -3
- package/packages/tools/extract-conversations/dist/index.d.ts +1 -2
- package/packages/tools/extract-conversations/dist/index.js +31 -29
- package/packages/tools/extract-conversations/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/extract-conversations/index.ts +37 -30
- package/packages/tools/extract-conversations/package.json +3 -3
- package/packages/tools/extract-pdf-text/dist/index.d.ts +1 -2
- package/packages/tools/extract-pdf-text/dist/index.js +44 -65
- package/packages/tools/extract-pdf-text/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/extract-pdf-text/index.ts +55 -74
- package/packages/tools/extract-pdf-text/package.json +3 -3
- package/packages/tools/filter-logs/dist/index.js +60 -84
- package/packages/tools/filter-logs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/filter-logs/index.ts +67 -97
- package/packages/tools/filter-logs/package.json +3 -3
- package/packages/tools/find-github-issues/dist/index.d.ts +10 -0
- package/packages/tools/find-github-issues/dist/index.js +34 -5
- package/packages/tools/find-github-issues/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/find-github-issues/index.ts +37 -5
- package/packages/tools/find-github-issues/package.json +3 -3
- package/packages/tools/generate-storyboard-images/dist/index.d.ts +1 -2
- package/packages/tools/generate-storyboard-images/dist/index.js +98 -173
- package/packages/tools/generate-storyboard-images/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/generate-storyboard-images/index.ts +100 -188
- package/packages/tools/generate-storyboard-images/package.json +3 -3
- package/packages/tools/open-github-issue/dist/index.d.ts +13 -0
- package/packages/tools/open-github-issue/dist/index.js +67 -68
- package/packages/tools/open-github-issue/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/open-github-issue/index.ts +71 -72
- package/packages/tools/open-github-issue/package.json +3 -3
- package/packages/tools/read-github-issue/dist/index.d.ts +16 -1
- package/packages/tools/read-github-issue/dist/index.js +32 -40
- package/packages/tools/read-github-issue/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/read-github-issue/index.ts +32 -45
- package/packages/tools/read-github-issue/package.json +3 -3
- package/packages/tools/render-error-book/dist/index.d.ts +1 -2
- package/packages/tools/render-error-book/dist/index.js +74 -95
- package/packages/tools/render-error-book/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/render-error-book/index.ts +88 -103
- package/packages/tools/render-error-book/package.json +3 -3
- package/packages/tools/render-katex/dist/index.d.ts +1 -2
- package/packages/tools/render-katex/dist/index.js +70 -157
- package/packages/tools/render-katex/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/render-katex/index.ts +138 -222
- package/packages/tools/render-katex/package.json +3 -3
- package/packages/tools/review-threads/dist/index.d.ts +12 -0
- package/packages/tools/review-threads/dist/index.js +83 -86
- package/packages/tools/review-threads/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/review-threads/index.ts +90 -84
- package/packages/tools/review-threads/package.json +3 -3
- package/packages/tools/search-logs/dist/index.js +100 -136
- package/packages/tools/search-logs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/search-logs/index.ts +113 -145
- package/packages/tools/search-logs/package.json +3 -3
- package/packages/tools/sync-memory-index/dist/index.js +34 -28
- package/packages/tools/sync-memory-index/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/sync-memory-index/index.ts +37 -28
- package/packages/tools/sync-memory-index/package.json +3 -3
- package/packages/tools/validate-openai-agent-config/dist/index.js +13 -7
- package/packages/tools/validate-openai-agent-config/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/validate-openai-agent-config/index.ts +13 -7
- package/packages/tools/validate-openai-agent-config/package.json +3 -3
- package/packages/tools/validate-skill-frontmatter/dist/index.js +12 -6
- package/packages/tools/validate-skill-frontmatter/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/validate-skill-frontmatter/index.ts +12 -6
- package/packages/tools/validate-skill-frontmatter/package.json +3 -3
- package/packages/tui/dist/index.d.ts +2 -1
- package/packages/tui/dist/index.js +1 -0
- package/packages/tui/dist/stdio-adapter.d.ts +36 -0
- package/packages/tui/dist/stdio-adapter.js +69 -0
- package/packages/tui/dist/terminal.js +3 -1
- package/packages/tui/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tui/dist/types.d.ts +17 -0
- package/packages/tui/index.ts +2 -1
- package/packages/tui/package.json +6 -5
- package/packages/tui/stdio-adapter.ts +85 -0
- package/packages/tui/terminal.ts +3 -1
- package/packages/tui/tsconfig.json +5 -2
- package/packages/tui/types.ts +19 -0
- package/resources/project-architecture/assets/architecture.css +2 -1
- package/resources/project-architecture/atlas/atlas.history.log +1 -0
- package/resources/project-architecture/atlas/atlas.history.undo.json +13 -2
- package/resources/project-architecture/atlas/atlas.history.undo.stack.json +610 -0
- package/resources/project-architecture/atlas/atlas.index.yaml +81 -5
- package/resources/project-architecture/atlas/features/cli-dispatch.yaml +43 -0
- package/resources/project-architecture/atlas/features/terminal-ui.yaml +29 -0
- package/resources/project-architecture/atlas/features/tool-registry.yaml +22 -0
- package/resources/project-architecture/atlas/features/tool-utils.yaml +22 -0
- package/resources/project-architecture/features/cli-dispatch/arg-parser.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/help-builder.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/index.html +64 -0
- package/resources/project-architecture/features/cli-dispatch/installer-core.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/tool-discovery.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/update-checker.html +40 -0
- package/resources/project-architecture/features/terminal-ui/banner-display.html +40 -0
- package/resources/project-architecture/features/terminal-ui/index.html +50 -0
- package/resources/project-architecture/features/terminal-ui/interactive-prompts.html +40 -0
- package/resources/project-architecture/features/terminal-ui/terminal-detection.html +40 -0
- package/resources/project-architecture/features/tool-registry/formatter.html +40 -0
- package/resources/project-architecture/features/tool-registry/index.html +43 -0
- package/resources/project-architecture/features/tool-registry/registry-core.html +40 -0
- package/resources/project-architecture/features/tool-utils/index.html +43 -0
- package/resources/project-architecture/features/tool-utils/log-utils.html +40 -0
- package/resources/project-architecture/features/tool-utils/skill-discovery.html +40 -0
- package/resources/project-architecture/index.html +365 -121
- package/scripts/rewrite-imports.mjs +2 -2
- package/scripts/test.sh +144 -8
- package/skills/design/SKILL.md +57 -64
- package/skills/design/assets/templates/DESIGN.md +12 -0
- package/skills/design/references/code-smells.md +94 -0
- package/skills/design/references/module-boundary-adjustment.md +126 -0
- package/skills/design/references/module-internal-restructuring.md +132 -0
- package/skills/design/references/module-internal-simplification.md +164 -0
|
@@ -88,7 +88,7 @@ for (const name of TOOL_NAMES) {
|
|
|
88
88
|
/**
|
|
89
89
|
* Map a @laitszkin/* specifier to a root-relative path.
|
|
90
90
|
*/
|
|
91
|
-
function resolvePackage(specifier) {
|
|
91
|
+
export function resolvePackage(specifier) {
|
|
92
92
|
const name = specifier.replace('@laitszkin/', '');
|
|
93
93
|
return PACKAGE_MAP[name] || null;
|
|
94
94
|
}
|
|
@@ -96,7 +96,7 @@ function resolvePackage(specifier) {
|
|
|
96
96
|
/**
|
|
97
97
|
* Compute relative import path from sourceFile to pkgPath.
|
|
98
98
|
*/
|
|
99
|
-
function relativePath(fromFile, pkgPath) {
|
|
99
|
+
export function relativePath(fromFile, pkgPath) {
|
|
100
100
|
const fromDir = dirname(fromFile);
|
|
101
101
|
let rel = relative(fromDir, resolve(root, pkgPath));
|
|
102
102
|
if (!rel.startsWith('.')) rel = './' + rel;
|
package/scripts/test.sh
CHANGED
|
@@ -3,15 +3,66 @@
|
|
|
3
3
|
# a Node.js 24.x test runner IPC deserialization issue that can make
|
|
4
4
|
# tests flaky when --experimental-test-module-mocks is active globally.
|
|
5
5
|
# See: https://github.com/nodejs/node/issues (test_runner IPC clone)
|
|
6
|
+
#
|
|
7
|
+
# Coverage enforcement (COVERAGE=true):
|
|
8
|
+
# Per-group line/branch/function thresholds are checked immediately after
|
|
9
|
+
# each group. Combined coverage = weighted average of Groups 1+2. Group 3
|
|
10
|
+
# (codegraph mock.module tests) excluded due to Node.js incompatible flags.
|
|
11
|
+
# Combined weighted coverage (Groups 1 + 2) is enforced after all groups
|
|
12
|
+
# finish.
|
|
13
|
+
#
|
|
14
|
+
# Limitations:
|
|
15
|
+
# - Split-process: Each group runs in a separate node process, so there is
|
|
16
|
+
# no single coverage report. The combined estimate is a file-weighted
|
|
17
|
+
# average of per-group results.
|
|
18
|
+
# - Group 3 (mock.module): Excluded from coverage enforcement due to
|
|
19
|
+
# --experimental-test-module-mocks incompatibility with v8 coverage.
|
|
20
|
+
# - Windows glob: The test/**/*.test.js glob uses forward slashes.
|
|
21
|
+
# In CI (shell: bash) this works correctly via Git Bash.
|
|
22
|
+
# For direct cmd.exe/PowerShell invocation, use backslash globs instead.
|
|
6
23
|
|
|
7
24
|
EXIT=0
|
|
8
25
|
|
|
26
|
+
# Coverage tracking globals (populated when COVERAGE=true)
|
|
27
|
+
G1_PCT=0
|
|
28
|
+
G1_FILES=0
|
|
29
|
+
G2_PCT=0
|
|
30
|
+
G2_FILES=0
|
|
31
|
+
|
|
32
|
+
# Use TMPDIR, TEMP, or /tmp as fallback for platforms without mktemp
|
|
33
|
+
RUN_TEST_LOG="${TMPDIR:-${TEMP:-/tmp}}/test-run-$$.log"
|
|
34
|
+
|
|
35
|
+
# Extract a pipe-delimited column from the "all files" coverage summary line,
|
|
36
|
+
# stripping whitespace and trailing '%'.
|
|
37
|
+
# Columns: (1) file | (2) line % | (3) branch % | (4) funcs % | (5) uncovered lines
|
|
38
|
+
_cov_col() {
|
|
39
|
+
local col="$1" text="$2"
|
|
40
|
+
echo "$text" | grep "all files" | awk -F'|' -v c="$col" '{
|
|
41
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, "", $c)
|
|
42
|
+
gsub(/%/, "", $c)
|
|
43
|
+
print $c
|
|
44
|
+
}'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Count the number of individual file entries in a coverage table
|
|
48
|
+
# (lines with numeric coverage data before "all files", excluding the header).
|
|
49
|
+
_cov_file_count() {
|
|
50
|
+
echo "$1" | awk -F'|' '
|
|
51
|
+
/^ℹ all files/{exit}
|
|
52
|
+
/^ℹ file .* line %/{next}
|
|
53
|
+
$2 ~ /[0-9]/{c++}
|
|
54
|
+
END{print c}
|
|
55
|
+
'
|
|
56
|
+
}
|
|
57
|
+
|
|
9
58
|
run_test_group() {
|
|
10
59
|
local label="$1"
|
|
11
60
|
shift
|
|
12
61
|
echo ""
|
|
13
62
|
echo "==> $label"
|
|
14
|
-
|
|
63
|
+
"$@" 2>&1 | tee -a "$RUN_TEST_LOG"
|
|
64
|
+
local group_exit=${PIPESTATUS[0]}
|
|
65
|
+
if [ "$group_exit" -eq 0 ]; then
|
|
15
66
|
echo " PASS"
|
|
16
67
|
else
|
|
17
68
|
echo " FAIL"
|
|
@@ -19,21 +70,106 @@ run_test_group() {
|
|
|
19
70
|
fi
|
|
20
71
|
}
|
|
21
72
|
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
73
|
+
# Like run_test_group but executes via "node --experimental-test-coverage"
|
|
74
|
+
# and enforces per-group threshold checks. Stores line percentage and file
|
|
75
|
+
# count in the named global variables for later combined-weight computation.
|
|
76
|
+
# Usage: run_coverage_group label line_thr branch_thr func_thr pct_var files_var node_args...
|
|
77
|
+
# Note: do NOT include "node" in node_args; it is prepended automatically.
|
|
78
|
+
run_coverage_group() {
|
|
79
|
+
local label="$1" line_thr="$2" branch_thr="$3" func_thr="$4" pct_var="$5" files_var="$6"
|
|
80
|
+
shift 6
|
|
81
|
+
|
|
82
|
+
echo ""
|
|
83
|
+
echo "==> $label"
|
|
84
|
+
|
|
85
|
+
local out
|
|
86
|
+
out=$(node --experimental-test-coverage "$@" 2>&1)
|
|
87
|
+
local exit_code=$?
|
|
88
|
+
echo "$out"
|
|
89
|
+
|
|
90
|
+
if [ $exit_code -ne 0 ]; then
|
|
91
|
+
echo " FAIL (tests failed)"
|
|
92
|
+
EXIT=1
|
|
93
|
+
return 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
local line_pct branch_pct func_pct file_count
|
|
97
|
+
line_pct=$(_cov_col 2 "$out")
|
|
98
|
+
branch_pct=$(_cov_col 3 "$out")
|
|
99
|
+
func_pct=$(_cov_col 4 "$out")
|
|
100
|
+
file_count=$(_cov_file_count "$out")
|
|
25
101
|
|
|
26
|
-
|
|
27
|
-
|
|
102
|
+
if [ -z "$line_pct" ]; then
|
|
103
|
+
echo " FAIL (no coverage data)"
|
|
104
|
+
EXIT=1
|
|
105
|
+
return 1
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# Store for combined-weight computation (even when thresholds fail)
|
|
109
|
+
eval "$pct_var=\$line_pct"
|
|
110
|
+
eval "$files_var=\$file_count"
|
|
111
|
+
|
|
112
|
+
local fail=0
|
|
113
|
+
[ "$(echo "$line_pct < $line_thr" | bc -l 2>/dev/null)" = "1" ] && fail=1
|
|
114
|
+
[ "$(echo "$branch_pct < $branch_thr" | bc -l 2>/dev/null)" = "1" ] && fail=1
|
|
115
|
+
[ "$(echo "$func_pct < $func_thr" | bc -l 2>/dev/null)" = "1" ] && fail=1
|
|
116
|
+
|
|
117
|
+
if [ "$fail" = "1" ]; then
|
|
118
|
+
echo " FAIL (lines=${line_pct}% branches=${branch_pct}% funcs=${func_pct}%)"
|
|
119
|
+
EXIT=1
|
|
120
|
+
return 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
echo " PASS (lines=${line_pct}% branches=${branch_pct}% funcs=${func_pct}%)"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# Group 2 test file list (shared between coverage and non-coverage paths)
|
|
128
|
+
EXCLUDE='(cmd-init|cmd-list-apis|cmd-survey|eval)'
|
|
28
129
|
PACKAGE_TEST_FILES=$(find packages -name '*.test.js' -not -path '*/node_modules/*' | grep -v -E "$EXCLUDE" | sort | tr '\n' ' ')
|
|
29
|
-
|
|
30
|
-
|
|
130
|
+
|
|
131
|
+
if [ "$COVERAGE" = "true" ]; then
|
|
132
|
+
# Group 1: stable non-mock tests (test/) — coverage with thresholds
|
|
133
|
+
run_coverage_group "Stable tests (test/)" 75 60 65 G1_PCT G1_FILES \
|
|
134
|
+
--test 'test/**/*.test.js'
|
|
135
|
+
|
|
136
|
+
# Group 2: package tests (no mock.module) — coverage with thresholds
|
|
137
|
+
run_coverage_group "Package tests (no mock.module)" 65 60 65 G2_PCT G2_FILES \
|
|
138
|
+
--test $PACKAGE_TEST_FILES
|
|
139
|
+
else
|
|
140
|
+
# Group 1: stable non-mock tests (test/)
|
|
141
|
+
run_test_group "Stable tests (test/)" \
|
|
142
|
+
node --test 'test/**/*.test.js'
|
|
143
|
+
|
|
144
|
+
# Group 2: package .test.js files that do NOT need mock.module
|
|
145
|
+
run_test_group "Package tests (no mock.module)" \
|
|
146
|
+
node --test $PACKAGE_TEST_FILES
|
|
147
|
+
fi
|
|
31
148
|
|
|
32
149
|
# Group 3: mock-dependent tests — isolated with --experimental-test-module-mocks
|
|
150
|
+
# Always runs the same way (excluded from coverage enforcement).
|
|
33
151
|
run_test_group "Package tests (mock.module)" \
|
|
34
152
|
node --experimental-test-module-mocks --test \
|
|
35
153
|
'packages/tools/codegraph/dist/lib/cmd-init.test.js' \
|
|
36
154
|
'packages/tools/codegraph/dist/lib/cmd-list-apis.test.js' \
|
|
37
155
|
'packages/tools/codegraph/dist/lib/cmd-survey.test.js'
|
|
38
156
|
|
|
157
|
+
# Combined weighted coverage enforcement (Groups 1 + 2 only)
|
|
158
|
+
if [ "$COVERAGE" = "true" ]; then
|
|
159
|
+
total_files=$((G1_FILES + G2_FILES))
|
|
160
|
+
if [ "$total_files" -gt 0 ]; then
|
|
161
|
+
combined_pct=$(echo "scale=2; ($G1_PCT * $G1_FILES + $G2_PCT * $G2_FILES) / $total_files" | bc -l)
|
|
162
|
+
echo ""
|
|
163
|
+
echo "==> Combined coverage (G1+G2, file-weighted): ${combined_pct}%"
|
|
164
|
+
if [ "$(echo "$combined_pct < 80" | bc -l)" = "1" ]; then
|
|
165
|
+
echo " FAIL (combined coverage ${combined_pct}% < 80%)"
|
|
166
|
+
EXIT=1
|
|
167
|
+
else
|
|
168
|
+
echo " PASS (combined coverage ${combined_pct}% >= 80%)"
|
|
169
|
+
fi
|
|
170
|
+
fi
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
rm -f "$RUN_TEST_LOG"
|
|
174
|
+
|
|
39
175
|
exit $EXIT
|
package/skills/design/SKILL.md
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: design
|
|
3
|
-
description: Reads SPEC.md, validates technical feasibility through web research, finds quality reference implementations, confirms tech stack compatibility, then produces DESIGN.md (architecture design, external dependencies), CHECKLIST.md (verification strategy), and
|
|
3
|
+
description: Reads SPEC.md, validates technical feasibility through web research, finds quality reference implementations, confirms tech stack compatibility, then produces DESIGN.md (architecture design, external dependencies), CHECKLIST.md (verification strategy), Architecture Diff, and design-time refactoring plan. Not for use without a SPEC.md.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Goal
|
|
7
7
|
|
|
8
8
|
Transform business specifications (SPEC.md) into technical design.
|
|
9
9
|
Research first, design second — avoid reinventing wheels and ground every decision in evidence.
|
|
10
|
+
During architecture survey, identify and classify refactoring opportunities by module boundary scope — include them as standard design output.
|
|
10
11
|
|
|
11
12
|
## Acceptance Criteria
|
|
12
13
|
|
|
13
14
|
- Three web research passes completed and recorded
|
|
14
|
-
- `docs/plans/<YYYY-MM-DD>/<spec_name>/DESIGN.md` produced, covering: architecture design, external dependencies (with API facts and limits), data persistence, invariants, technical trade-offs
|
|
15
|
+
- `docs/plans/<YYYY-MM-DD>/<spec_name>/DESIGN.md` produced, covering: architecture design, external dependencies (with API facts and limits), data persistence, invariants, technical trade-offs, design-time refactoring
|
|
15
16
|
- `docs/plans/<YYYY-MM-DD>/<spec_name>/CHECKLIST.md` produced, covering: behavior-to-test mapping, hardening requirements, test level choices
|
|
16
17
|
- Architecture Diff produced using the C4 model hierarchy
|
|
18
|
+
- Design-time refactoring classified by module boundary scope (T1–T3) and dispositioned (refactored / scheduled / deferred with rationale)
|
|
17
19
|
|
|
18
20
|
## Workflow
|
|
19
21
|
|
|
@@ -44,13 +46,13 @@ Output: Feasibility assessment + risk checklist
|
|
|
44
46
|
|
|
45
47
|
**⚠️ Decision gate — STOP if blocking issues are found.**
|
|
46
48
|
|
|
47
|
-
| Assessment |
|
|
48
|
-
|
|
49
|
-
| ✅ All feasible |
|
|
50
|
-
| ⚠️ Partial validation needed |
|
|
51
|
-
| 🛑 **Blocking issues found** |
|
|
49
|
+
| Assessment | Action |
|
|
50
|
+
|---|---|
|
|
51
|
+
| ✅ All feasible | Continue to Step 3 |
|
|
52
|
+
| ⚠️ Partial validation needed | Continue, mark uncertain items as Exploratory-level risks; suggest spike/prototype where warranted |
|
|
53
|
+
| 🛑 **Blocking issues found** | **STOP.** Do not proceed. Document infeasibility with evidence (API limits, licensing, platform gaps). Request SPEC.md revision |
|
|
52
54
|
|
|
53
|
-
**Why this gate exists**: The spec phase validates
|
|
55
|
+
**Why this gate exists**: The spec phase validates against existing code only — it does not check external feasibility. This is the pipeline's only chance to catch real-world constraints before design. If blocking, escalate before designing.
|
|
54
56
|
|
|
55
57
|
#### 2b. Existing Quality References
|
|
56
58
|
|
|
@@ -80,19 +82,21 @@ Cover the following sections:
|
|
|
80
82
|
- **Research Summary**: Feasibility per requirement, existing references, tech stack compatibility (from Step 2)
|
|
81
83
|
- **Architecture Overview**: Module list with responsibilities, entry points, trust boundary, target vs baseline comparison
|
|
82
84
|
- **Interaction Design**: Module call relationships, coupling patterns (route / RPC / event / sync), failure propagation, ordering constraints
|
|
83
|
-
- **External Dependencies**: API facts, limits and failure modes, security and keys
|
|
85
|
+
- **External Dependencies**: API facts, limits and failure modes, security and keys
|
|
84
86
|
- **Data Persistence**: Storage resources, consistency expectations
|
|
85
87
|
- **System Invariants**: Architectural constraints that must not be violated, plus violation symptoms
|
|
86
88
|
- **Technical Trade-offs**: Each decision with rejected alternatives and lock-in effects
|
|
89
|
+
- **Design-Time Refactoring**: T1–T3 code health findings classified and dispositioned
|
|
87
90
|
|
|
88
91
|
Use `Req 1`, `Req 2` numbering to reference SPEC.md requirements (matching the SPEC.md template's `Requirement 1`, `Requirement 2`).
|
|
89
92
|
|
|
90
93
|
**Scale awareness** — Not every section applies at full depth. Adapt based on the change's scope:
|
|
91
94
|
|
|
92
|
-
- **Interaction Design (Section 3)**: If the change is confined to a single module with no new cross-module coupling, mark this section as `None
|
|
93
|
-
- **External Dependency deep-dives (Section 4.2)**: For simple utility libraries (e.g., date formatting, UUID generation)
|
|
94
|
-
- **Target vs Baseline (Section 2.3)**: If the change touches multiple dimensions (new modules, removed modules, ownership shifts, deployment changes), expand
|
|
95
|
-
- **System Invariants (Section 6)**: If the change does not modify any architectural constraint
|
|
95
|
+
- **Interaction Design (Section 3)**: If the change is confined to a single module with no new cross-module coupling, mark this section as `None`. Do not fabricate INT-### entries.
|
|
96
|
+
- **External Dependency deep-dives (Section 4.2)**: For simple utility libraries (e.g., date formatting, UUID generation) with no API quotas, authentication, or failure modes, skip the sub-tables. A one-line entry in Section 4.1 overview suffices.
|
|
97
|
+
- **Target vs Baseline (Section 2.3)**: If the change touches multiple dimensions (new modules, removed modules, ownership shifts, deployment changes), expand to multiple rows. A single-dimension change needs only one row.
|
|
98
|
+
- **System Invariants (Section 6)**: If the change does not modify any architectural constraint, explicitly write `None` with brief justification.
|
|
99
|
+
- **Design-Time Refactoring (Section 8)**: If no code health issues were identified during the architecture survey, write `None`. Do not fabricate findings.
|
|
96
100
|
|
|
97
101
|
**Design self-challenge** — Before finalizing the design, step back and ask three questions:
|
|
98
102
|
|
|
@@ -100,6 +104,14 @@ Use `Req 1`, `Req 2` numbering to reference SPEC.md requirements (matching the S
|
|
|
100
104
|
2. **Is this the simplest viable design?** Have I introduced abstractions, indirections, or intermediate layers that are not justified by the current requirements? Prefer the simplest structure that works.
|
|
101
105
|
3. **Are there rejected alternatives?** For every major architectural decision (module split, dependency choice, communication pattern), if you have not considered and explicitly rejected at least one alternative, you may be settling on the first workable solution rather than the best one.
|
|
102
106
|
|
|
107
|
+
**Design-time refactoring** — While designing the target architecture, also assess code health in the affected modules:
|
|
108
|
+
|
|
109
|
+
- **T1 (Module-internal simplification)**: Simplify control flow, remove dead code, inline unnecessary wrappers within a single function or file. Existing unit tests validate behavior — refactor directly.
|
|
110
|
+
- **T2 (Module-internal restructuring)**: Extract shared logic, consolidate state, reorganize files within the same module boundary. Existing integration tests validate behavior — include in the design's task decomposition.
|
|
111
|
+
- **T3 (Module boundary adjustment)**: Changes affecting a module's public API, data contract, or cross-module coupling. Requires dedicated test coverage — define test strategy in CHECKLIST.md.
|
|
112
|
+
|
|
113
|
+
See `references/code-smells.md` for patterns to identify, and the module-specific reference files for detailed guidance per tier.
|
|
114
|
+
|
|
103
115
|
**Single spec**: Produce one DESIGN.md for one SPEC.md.
|
|
104
116
|
**Batch spec**: Produce **one** unified DESIGN.md covering the scope of all SPEC.md files in the batch.
|
|
105
117
|
|
|
@@ -109,12 +121,12 @@ Use the `test-case-strategy` skill to design the verification strategy.
|
|
|
109
121
|
Use `assets/templates/CHECKLIST.md`.
|
|
110
122
|
|
|
111
123
|
The CHECKLIST.md defines the **test plan** — it maps SPEC.md requirements to tests, defines hardening requirements, and records test-level decisions.
|
|
112
|
-
(Do not include execution tracking fields — those belong to the implementation phase.)
|
|
113
124
|
|
|
114
125
|
Cover the following sections:
|
|
115
126
|
- **Behavior-to-Test Checklist**: Each BDD requirement mapped to one or more tests
|
|
116
127
|
- **Hardening Requirements**: Regression tests, drift checks, property-based tests, edge cases, authorization checks
|
|
117
128
|
- **E2E / Integration Decisions**: Per flow, choose the appropriate test level with rationale
|
|
129
|
+
- **Design-Time Refactoring (T3)**: If T3 refactoring is planned, define its test coverage requirements here
|
|
118
130
|
|
|
119
131
|
**Mandatory test coverage** (applies when the SPEC.md describes changes other than pure documentation or pure test changes):
|
|
120
132
|
|
|
@@ -138,6 +150,12 @@ Do not read unrelated features or modules — maintain context economy.
|
|
|
138
150
|
|
|
139
151
|
If no existing architecture exists, skip the baseline comparison and start defining the boundary from System Context level.
|
|
140
152
|
|
|
153
|
+
**Code health assessment** — While reading code to measure the baseline, actively assess code quality:
|
|
154
|
+
- Identify code smells, dead code, legacy patterns, and unnecessary complexity in the affected modules
|
|
155
|
+
- Classify findings using the T1–T3 framework (see `references/code-smells.md` for patterns to recognize)
|
|
156
|
+
- T1 items (module-internal simplification) are safe to refactor immediately — existing tests validate behavioral preservation
|
|
157
|
+
- T2 and T3 items feed into the target architecture design in Step 3
|
|
158
|
+
|
|
141
159
|
#### 5b. Measure Baseline Drift
|
|
142
160
|
|
|
143
161
|
Compare the existing architecture diagram against the current code to assess its reliability:
|
|
@@ -151,13 +169,7 @@ Compare the existing architecture diagram against the current code to assess its
|
|
|
151
169
|
3. **Component level** (submodules): Define functions, variables, dataflows, and error rows within each submodule
|
|
152
170
|
4. **Code level** (selective): Only supplement function-level details for critical paths
|
|
153
171
|
|
|
154
|
-
C4 level
|
|
155
|
-
| C4 Level | Maps to | Purpose |
|
|
156
|
-
|----------|---------|---------|
|
|
157
|
-
| System Context | Overall system + external actors | System boundary and external dependencies |
|
|
158
|
-
| Container | Feature (functional module) | High-level functional boundary |
|
|
159
|
-
| Component | Submodule (implementation unit) | Internal implementation units |
|
|
160
|
-
| Code | Function level | Function-level details (selective) |
|
|
172
|
+
C4 level mapping: System Context → system boundary, Container → feature, Component → submodule, Code → function (selective). See `references/definition.md` for full definitions.
|
|
161
173
|
|
|
162
174
|
#### 5d. Evidence Tracing
|
|
163
175
|
|
|
@@ -170,46 +182,21 @@ Each component should link to:
|
|
|
170
182
|
Two alternative workflows — use the **Classic flow** when `codegraph` is not installed, or the **CodeGraph-integrated flow** when it is available.
|
|
171
183
|
|
|
172
184
|
**Classic flow** (manual):
|
|
185
|
+
Generate and validate the architecture diff using `apltk architecture` commands. Confirm validation passes, then produce a visual comparison. See `references/architecture.md` for all CLI flags.
|
|
173
186
|
|
|
174
|
-
|
|
175
|
-
apltk architecture --spec <spec_dir> render
|
|
176
|
-
apltk architecture --spec <spec_dir> validate
|
|
177
|
-
```
|
|
187
|
+
**New flow (CodeGraph-integrated):**
|
|
178
188
|
|
|
179
|
-
|
|
189
|
+
1. **Survey the existing API landscape** — Use `apltk codegraph list-apis` to review the full project API directory (function names, file paths, callers). Understand what existing modules and functions your new feature will interact with.
|
|
180
190
|
|
|
181
|
-
|
|
182
|
-
apltk architecture diff
|
|
183
|
-
```
|
|
191
|
+
2. **Fill the proposal skeleton** — Based on your design decisions from steps 5a–5d, fill in the `proposal.yaml` file generated by `apltk architecture template`. Define the feature, its submodules, their functions, and cross-feature edges.
|
|
184
192
|
|
|
185
|
-
**
|
|
193
|
+
3. **Apply and verify** — Apply the mutations and verify correctness:
|
|
194
|
+
- `apltk architecture apply` processes all mutations with undo protection
|
|
195
|
+
- `apltk codegraph verify` confirms every symbol and edge reference exists in actual code
|
|
196
|
+
|
|
197
|
+
4. **Render diff** (optional) — `apltk architecture diff --spec <spec_dir>` for visual confirmation.
|
|
186
198
|
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
apltk codegraph list-apis --all
|
|
190
|
-
```
|
|
191
|
-
This returns the full project API directory (function names, file paths, callers) as a reference for integration points. Use this data to understand what existing modules, services, and functions your new feature will interact with.
|
|
192
|
-
|
|
193
|
-
2. **Fill the proposal skeleton**: Based on your design decisions from steps 5a-5d,
|
|
194
|
-
fill in the `proposal.yaml` file generated by `apltk architecture template`.
|
|
195
|
-
Define the feature, its submodules, their functions, and cross-feature edges.
|
|
196
|
-
|
|
197
|
-
3. **Apply batch mutations**:
|
|
198
|
-
```bash
|
|
199
|
-
apltk architecture apply <spec_dir>/architecture_diff/atlas/proposal.yaml --spec <spec_dir>
|
|
200
|
-
```
|
|
201
|
-
This processes all mutations in one call with undo protection.
|
|
202
|
-
|
|
203
|
-
4. **Verify correctness**:
|
|
204
|
-
```bash
|
|
205
|
-
apltk codegraph verify --spec <spec_dir>
|
|
206
|
-
```
|
|
207
|
-
This confirms every symbol and edge reference in the spec overlay exists in the actual code.
|
|
208
|
-
|
|
209
|
-
5. **Render and validate** (optional, for visual confirmation):
|
|
210
|
-
```bash
|
|
211
|
-
apltk architecture diff --spec <spec_dir>
|
|
212
|
-
```
|
|
199
|
+
See `references/architecture.md` for exact CLI flags and mutation commands.
|
|
213
200
|
|
|
214
201
|
**Single spec**: Produce one Architecture Diff for one SPEC.md.
|
|
215
202
|
**Batch spec**: Produce **one** unified Architecture Diff covering all SPEC.md files in the batch.
|
|
@@ -225,23 +212,29 @@ Before delivering, run two passes — completeness then quality.
|
|
|
225
212
|
- External dependency API facts are traceable to official documentation
|
|
226
213
|
- CHECKLIST.md completely covers all BDD requirements from SPEC.md
|
|
227
214
|
- Architecture Diff covers the full change scope
|
|
215
|
+
- Design-time refactoring is documented in DESIGN.md Section 8, with T1–T3 findings classified and dispositioned (refactored / scheduled / deferred with rationale)
|
|
228
216
|
|
|
229
217
|
**Design quality checks** (architectural soundness):
|
|
230
218
|
|
|
231
|
-
- **Requirement traceability**: Can every BDD behavior from SPEC.md be traced to a module, interaction, data flow, or invariant in this design?
|
|
232
|
-
- **Internal consistency**: Do the modules listed in Section 2 appear as callers or callees in Section 3? Do the dependencies in Section 4 correspond to module responsibilities in Section 2?
|
|
233
|
-
- **Design simplicity**:
|
|
234
|
-
- **Risk transparency**: Are all feasibility risks, compatibility concerns, or uncertain technical points from Step 2 either addressed in the design or explicitly documented as accepted risks?
|
|
219
|
+
- **Requirement traceability**: Can every BDD behavior from SPEC.md be traced to a module, interaction, data flow, or invariant in this design?
|
|
220
|
+
- **Internal consistency**: Do the modules listed in Section 2 appear as callers or callees in Section 3? Do the dependencies in Section 4 correspond to module responsibilities in Section 2?
|
|
221
|
+
- **Design simplicity**: Is this the simplest design that satisfies all requirements? Could any module, abstraction, or dependency be removed without breaking functionality?
|
|
222
|
+
- **Risk transparency**: Are all feasibility risks, compatibility concerns, or uncertain technical points from Step 2 either addressed in the design or explicitly documented as accepted risks?
|
|
223
|
+
- **Refactoring disposition**: Are all identified code health findings accounted for — either refactored, scheduled in the task plan, or explicitly deferred with rationale? Unaddressed T1/T2 findings represent missed opportunities to reduce technical debt at the cheapest possible time.
|
|
235
224
|
|
|
236
225
|
## Examples
|
|
237
226
|
|
|
238
|
-
- "SPEC.md defines a real-time messaging feature" → Research WebSocket vs SSE vs Polling
|
|
227
|
+
- "SPEC.md defines a real-time messaging feature" → Research WebSocket vs SSE vs Polling → Confirm compatibility → Choose SSE → Design architecture → Produce DESIGN.md + CHECKLIST.md + Architecture Diff → During code survey, identify legacy socket wrapper (T2) → schedule extraction in task plan
|
|
239
228
|
- "SPEC.md requires CSV export, repo has no CSV library" → Research Node.js CSV libraries (json2csv vs csv-writer vs papaparse) → Confirm compatibility → Choose the lightest option → Design export flow architecture
|
|
240
|
-
- "Batch spec: docs/plans/2026-05-29/auth-redesign/ with 3 SPEC.md files (login, permissions, 2FA)" → Read all 3 SPEC.md files → Unified research
|
|
229
|
+
- "Batch spec: docs/plans/2026-05-29/auth-redesign/ with 3 SPEC.md files (login, permissions, 2FA)" → Read all 3 SPEC.md files → Unified research → Produce **one** DESIGN.md + CHECKLIST.md + Architecture Diff → Identify dead auth middleware during survey (T1) → remove and verify with existing tests
|
|
241
230
|
|
|
242
231
|
## References
|
|
243
232
|
|
|
244
233
|
- `assets/templates/DESIGN.md` — DESIGN.md template
|
|
245
234
|
- `assets/templates/CHECKLIST.md` — CHECKLIST.md template
|
|
246
|
-
- `references/architecture.md` — `apltk architecture` CLI reference (all mutation commands
|
|
247
|
-
- `references/definition.md` — C4 model level definitions
|
|
235
|
+
- `references/architecture.md` — `apltk architecture` CLI reference (all mutation commands)
|
|
236
|
+
- `references/definition.md` — C4 model level definitions
|
|
237
|
+
- `references/code-smells.md` — Common code smell patterns to spot during architecture survey
|
|
238
|
+
- `references/module-internal-simplification.md` — T1: module-internal simplification patterns
|
|
239
|
+
- `references/module-internal-restructuring.md` — T2: module-internal restructuring patterns
|
|
240
|
+
- `references/module-boundary-adjustment.md` — T3: module boundary adjustment patterns
|
|
@@ -139,3 +139,15 @@ If none, write **None** and note the scope (e.g., stdlib only / in-process calls
|
|
|
139
139
|
| Decision | Rejected Alternatives | Lock-in Effect on Implementation |
|
|
140
140
|
|---|---|---|
|
|
141
141
|
| […] | […] | […] |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 8. Design-Time Refactoring
|
|
146
|
+
|
|
147
|
+
Code health findings identified during architecture survey, classified by module boundary scope.
|
|
148
|
+
|
|
149
|
+
| Finding | Affected Module | Tier (T1/T2/T3) | Disposition (Refactored / Scheduled / Deferred) | Test Evidence |
|
|
150
|
+
|---|---|---|---|---|
|
|
151
|
+
| […] | […] | […] | […] | […] |
|
|
152
|
+
|
|
153
|
+
If none, write **None**.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Code Smell Patterns — Architecture Survey Reference
|
|
2
|
+
|
|
3
|
+
Common patterns to recognize while reading code during architecture survey.
|
|
4
|
+
Use this catalog to identify refactoring opportunities; each entry notes the likely tier (T1/T2/T3) for dispositioning.
|
|
5
|
+
|
|
6
|
+
## Control Flow
|
|
7
|
+
|
|
8
|
+
### Deeply Nested Conditionals
|
|
9
|
+
Multiple levels of `if`/`else`/`switch` exceeding 3 levels deep, or containing duplicated branch predicates.
|
|
10
|
+
- **T1 fix**: Early returns, guard clauses, switch-to-map, predicate extraction
|
|
11
|
+
- **Symptoms**: Methods with >3 indent levels, repeated `if (condition)` checks
|
|
12
|
+
|
|
13
|
+
### Mutable Flag Variables
|
|
14
|
+
Boolean or enum variables threaded through functions purely to control which branch runs later.
|
|
15
|
+
- **T1 fix**: Split the function at the decision point; caller chooses which path
|
|
16
|
+
- **Symptoms**: `let/var` flags declared at function start, set in multiple branches
|
|
17
|
+
|
|
18
|
+
### Sequential Conditionals Hiding State Machine
|
|
19
|
+
A chain of `if`/`else` blocks that implicitly represent state transitions.
|
|
20
|
+
- **T2 fix**: Explicit state machine or table-driven dispatch
|
|
21
|
+
- **Symptoms**: State variable mutated across a chain, each branch checks both old and new state
|
|
22
|
+
|
|
23
|
+
## Data & State
|
|
24
|
+
|
|
25
|
+
### Shotgun Duplication
|
|
26
|
+
The same small expression or transformation repeated across multiple functions or files.
|
|
27
|
+
- **T2 fix**: Extract to shared utility or helper; place in the lowest-level module that needs it
|
|
28
|
+
- **Symptoms**: Copy-pasted 2-5 line blocks, grep reveals identical patterns across module
|
|
29
|
+
|
|
30
|
+
### Temporary Field
|
|
31
|
+
An object property or class field only set in some code paths and always `null`/`undefined` in others.
|
|
32
|
+
- **T1 fix**: Extract a separate type or parameter object; remove the field from the base type
|
|
33
|
+
- **Symptoms**: Fields with `?`/`| undefined` that are checked before every use
|
|
34
|
+
|
|
35
|
+
### Overly Permissive Null Handling
|
|
36
|
+
Parameters or return types that accept `null` when the semantics don't require it, propagating `?.` / `== null` checks through callers.
|
|
37
|
+
- **T1 fix**: Tighten the contract — require defined values, push null handling to the boundary
|
|
38
|
+
- **Symptoms**: Chains of `?.a?.b?.c`, unnecessary `== null` checks on always-present data
|
|
39
|
+
|
|
40
|
+
## Structure
|
|
41
|
+
|
|
42
|
+
### Dead Code
|
|
43
|
+
Exported functions never called, branches unreachable due to constants, commented-out code blocks.
|
|
44
|
+
- **T1 fix**: Remove the function or branch; let the compiler/test suite catch if something depended on it
|
|
45
|
+
- **Symptoms**: grep shows zero callers, `if (false)`, files with only comments
|
|
46
|
+
|
|
47
|
+
### Lazy Class / Middle Man
|
|
48
|
+
A class or function that does nothing but delegate to another, with no added behavior or transformation.
|
|
49
|
+
- **T1 fix**: Inline the delegation; remove the intermediate
|
|
50
|
+
- **Symptoms**: 1:1 method mapping between wrapper and wrapped, no state or logic added
|
|
51
|
+
|
|
52
|
+
### Divergent Change Pattern
|
|
53
|
+
The same class or file is modified for multiple unrelated reasons across recent commits.
|
|
54
|
+
- **T2 fix**: Split the file along axis-of-change lines; each responsibility gets its own home
|
|
55
|
+
- **Symptoms**: git log shows the same file touched for feature work, bug fixes, and refactoring in the same period
|
|
56
|
+
|
|
57
|
+
### Data Clump
|
|
58
|
+
The same 2-4 parameters appear together across multiple function signatures.
|
|
59
|
+
- **T2 fix**: Extract parameter object; group validation and formatting with the new type
|
|
60
|
+
- **Symptoms**: `(start, end, limit)`, `(userId, role, tenantId)` repeated across 3+ functions
|
|
61
|
+
|
|
62
|
+
## Coupling
|
|
63
|
+
|
|
64
|
+
### Feature Envy
|
|
65
|
+
A function accesses data or calls methods on another object more than on its own.
|
|
66
|
+
- **T2 fix**: Move the function to the object that owns the data it depends on
|
|
67
|
+
- **Symptoms**: `a.x`, `a.y`, `a.z` in a method of `B`; long chains of `getter().getter()`
|
|
68
|
+
|
|
69
|
+
### Inappropriate Intimacy
|
|
70
|
+
Two modules or classes reach into each other's internal state rather than using public interfaces.
|
|
71
|
+
- **T3 fix**: Define a clear interface between them; extract shared state into a third module
|
|
72
|
+
- **Symptoms**: `friend`/`internal` usage across module boundaries, circular imports
|
|
73
|
+
|
|
74
|
+
### God Object / God Module
|
|
75
|
+
A single file or class with disproportionate size and responsibility breadth.
|
|
76
|
+
- **T3 fix**: Decompose by responsibility into separate modules; update callers
|
|
77
|
+
- **Symptoms**: File exceeds 500 lines, contains >1 "section" comment block, 10+ imports
|
|
78
|
+
|
|
79
|
+
## Legacy & Migration
|
|
80
|
+
|
|
81
|
+
### Deprecated API Usage
|
|
82
|
+
Import from deprecated packages, usage of `@deprecated`-marked symbols, or reliance on removed Node.js/TypeScript features.
|
|
83
|
+
- **T1 fix**: Replace with the recommended alternative (often a find-and-replace across the module)
|
|
84
|
+
- **Symptoms**: `@deprecated` JSDoc, runtime deprecation warnings, import from `/dist/` or `lib/`
|
|
85
|
+
|
|
86
|
+
### No-Longer-Needed Workaround
|
|
87
|
+
Code that exists to work around a bug or gap in a previous framework/library version, now resolved upstream.
|
|
88
|
+
- **T1 fix**: Remove the workaround; test the happy path and edge case
|
|
89
|
+
- **Symptoms**: Comments referencing old issue numbers or "temporary" workarounds, version-gated blocks for very old versions
|
|
90
|
+
|
|
91
|
+
### Commented-Out Alternative
|
|
92
|
+
A second version of a function/block left commented out "for reference."
|
|
93
|
+
- **T1 fix**: Remove; if needed, git history preserves the alternative
|
|
94
|
+
- **Symptoms**: Blocks commented out with explanations like "old version" or "alternative approach"
|