opencode-code-archaeology 2.0.0 → 2.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.
Files changed (76) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +63 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.yml +48 -0
  3. package/.github/pull_request_template.md +27 -0
  4. package/.github/workflows/ci.yml +45 -0
  5. package/.github/workflows/release.yml +46 -0
  6. package/AGENTS.md +42 -10
  7. package/CHANGELOG.md +79 -0
  8. package/CONTRIBUTING.md +50 -0
  9. package/INSTALL.md +211 -0
  10. package/README.md +255 -71
  11. package/SECURITY.md +20 -0
  12. package/VERSION +1 -1
  13. package/assets/code-archaeology-banner.svg +195 -0
  14. package/commands/code-archaeology.md +7 -5
  15. package/dist/cli.d.ts +3 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +137 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/index.d.ts +1 -5
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +1 -17
  22. package/dist/index.js.map +1 -1
  23. package/dist/platform.d.ts +4 -0
  24. package/dist/platform.d.ts.map +1 -0
  25. package/dist/platform.js +11 -0
  26. package/dist/platform.js.map +1 -0
  27. package/dist/plugin.d.ts +3 -0
  28. package/dist/plugin.d.ts.map +1 -0
  29. package/dist/plugin.js +3 -0
  30. package/dist/plugin.js.map +1 -0
  31. package/dist/runtime.d.ts +18 -0
  32. package/dist/runtime.d.ts.map +1 -0
  33. package/dist/runtime.js +49 -0
  34. package/dist/runtime.js.map +1 -0
  35. package/dist/types.d.ts +1 -6
  36. package/dist/types.d.ts.map +1 -1
  37. package/dist/types.js.map +1 -1
  38. package/docs/ARCHITECTURE.md +123 -0
  39. package/docs/INSTALL.md +156 -0
  40. package/docs/README.md +72 -0
  41. package/docs/RELEASE.md +139 -0
  42. package/docs/SECURITY_AUDIT.md +38 -0
  43. package/docs/index.html +740 -0
  44. package/hooks/hermes/runner.ps1 +247 -0
  45. package/hooks/hermes/runner.sh +262 -0
  46. package/hooks/hermes/setup.ps1 +41 -0
  47. package/hooks/hermes/setup.sh +41 -0
  48. package/hooks/opencode/init.ps1 +83 -0
  49. package/hooks/opencode/revert-phase.ps1 +12 -0
  50. package/hooks/opencode/revert-phase.sh +3 -8
  51. package/hooks/opencode/update-expedition.ps1 +51 -0
  52. package/hooks/opencode/verify-package.sh +47 -0
  53. package/hooks/opencode/verify-phase.ps1 +35 -0
  54. package/hooks/opencode/verify-phase.sh +7 -7
  55. package/hooks/shared/command-utils.ps1 +100 -0
  56. package/package.json +41 -6
  57. package/prompts/dead_code.md +45 -0
  58. package/prompts/dependencies.md +49 -0
  59. package/prompts/discovery.md +47 -0
  60. package/prompts/dry.md +49 -0
  61. package/prompts/errors.md +52 -0
  62. package/prompts/final_verify.md +58 -0
  63. package/prompts/legacy.md +49 -0
  64. package/prompts/polish.md +48 -0
  65. package/prompts/types_consolidate.md +48 -0
  66. package/prompts/types_harden.md +51 -0
  67. package/skills/code-archaeology/SKILL.md +2 -2
  68. package/skills/hermes/INTEGRATION.md +120 -0
  69. package/skills/hermes/README.md +167 -0
  70. package/skills/hermes/code-archaeology-prompt.md +203 -0
  71. package/wiki/Expedition-Workflow.md +34 -0
  72. package/wiki/Home.md +27 -0
  73. package/wiki/Installation.md +44 -0
  74. package/wiki/Release-Process.md +31 -0
  75. package/wiki/Security-and-Safety.md +21 -0
  76. package/plugins/code-archaeology.ts +0 -8
@@ -1,4 +1,4 @@
1
- # Revert changes in the current working tree back to the last commit.
1
+ # Move current working tree changes into a recoverable stash.
2
2
  # Usage: revert-phase.sh [phase-name]
3
3
 
4
4
  set -euo pipefail
@@ -7,11 +7,6 @@ PHASE="${1:-unknown}"
7
7
 
8
8
  echo "[$PHASE] ⚠️ Reverting changes due to failure..."
9
9
 
10
- # Stash any changes and drop them
11
- git stash push -m "code-archaeology-revert-$PHASE" --include-untracked 2>/dev/null || true
12
- git stash drop 2>/dev/null || true
10
+ git stash push -m "code-archaeology-revert-$PHASE" --include-untracked >/dev/null 2>&1 || true
13
11
 
14
- # Reset to HEAD
15
- git reset --hard HEAD
16
-
17
- echo "[$PHASE] ✅ Reverted to last commit"
12
+ echo "[$PHASE] Changes preserved in git stash"
@@ -0,0 +1,51 @@
1
+ # Update expedition status in session.json
2
+ # Usage: update-expedition.ps1 <phase> <status> [findings_count] [error_message]
3
+
4
+ $ErrorActionPreference = 'Stop'
5
+
6
+ $PHASE = $args[0]
7
+ $STATUS = $args[1]
8
+ $FINDINGS = if ($args[2]) { [int]$args[2] } else { 0 }
9
+ $ERROR_MSG = if ($args[3]) { $args[3] } else { "" }
10
+
11
+ $ARCHAEOLOGY_DIR = ".archaeology"
12
+ $SESSION_FILE = "$ARCHAEOLOGY_DIR/session.json"
13
+
14
+ if (!(Test-Path "$SESSION_FILE")) {
15
+ Write-Error "Error: session.json not found. Run init.ps1 first."
16
+ exit 1
17
+ }
18
+
19
+ $NOW = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
20
+
21
+ $session = Get-Content "$SESSION_FILE" -Raw | ConvertFrom-Json
22
+
23
+ foreach ($expedition in $session.expeditions) {
24
+ if ($expedition.phase -eq $PHASE) {
25
+ $expedition.status = $STATUS
26
+ $expedition.findings_count = $FINDINGS
27
+ if ($STATUS -eq "completed" -or $STATUS -eq "done") {
28
+ $expedition | Add-Member -MemberType NoteProperty -Name "completed_at" -Value $NOW -Force
29
+ }
30
+ if ($ERROR_MSG) {
31
+ $expedition | Add-Member -MemberType NoteProperty -Name "error" -Value $ERROR_MSG -Force
32
+ } else {
33
+ if ($expedition.PSObject.Properties["error"]) {
34
+ $expedition.PSObject.Properties.Remove("error")
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ $session.updated_at = $NOW
41
+
42
+ # Update total findings
43
+ $total = 0
44
+ foreach ($expedition in $session.expeditions) {
45
+ $total += $expedition.findings_count
46
+ }
47
+ $session.total_findings = $total
48
+
49
+ $session | ConvertTo-Json -Depth 10 | Set-Content "$SESSION_FILE" -Encoding UTF8
50
+
51
+ Write-Host "[$PHASE] Updated status: $STATUS (findings: $FINDINGS)"
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ pack_json=$(npm pack --json --dry-run)
5
+
6
+ PACK_JSON="$pack_json" node <<'NODE'
7
+ const pack = JSON.parse(process.env.PACK_JSON ?? '[]');
8
+ const files = new Set((pack[0]?.files ?? []).map((file) => file.path));
9
+
10
+ const requiredFiles = [
11
+ 'dist/cli.js',
12
+ 'dist/index.js',
13
+ 'commands/code-archaeology.md',
14
+ 'skills/code-archaeology/SKILL.md',
15
+ 'hooks/opencode/init.sh',
16
+ 'hooks/opencode/verify-phase.sh',
17
+ 'hooks/opencode/revert-phase.sh',
18
+ 'hooks/opencode/update-expedition.sh',
19
+ 'hooks/opencode/verify-package.sh',
20
+ 'prompts/discovery.md',
21
+ 'schema/expedition-report.json',
22
+ 'docs/index.html',
23
+ 'docs/README.md',
24
+ 'wiki/Home.md',
25
+ 'assets/code-archaeology-banner.svg',
26
+ 'AGENTS.md',
27
+ 'VERSION',
28
+ 'README.md',
29
+ 'INSTALL.md',
30
+ 'SECURITY.md',
31
+ 'CONTRIBUTING.md',
32
+ 'CHANGELOG.md',
33
+ 'LICENSE',
34
+ ];
35
+
36
+ const missingFiles = requiredFiles.filter((file) => !files.has(file));
37
+
38
+ if (missingFiles.length > 0) {
39
+ console.error('Package is missing required files:');
40
+ for (const file of missingFiles) {
41
+ console.error(`- ${file}`);
42
+ }
43
+ process.exit(1);
44
+ }
45
+
46
+ console.log(`Package dry-run includes ${files.size} files and all required release assets.`);
47
+ NODE
@@ -0,0 +1,35 @@
1
+ # Verify that tests pass and typecheck succeeds.
2
+ # Usage: verify-phase.ps1 [phase-name]
3
+
4
+ $ErrorActionPreference = 'Stop'
5
+
6
+ $PHASE = if ($args[0]) { $args[0] } else { "unknown" }
7
+ $ARCHAEOLOGY_DIR = ".archaeology"
8
+ $SESSION_FILE = "$ARCHAEOLOGY_DIR/session.json"
9
+ $SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
10
+ . (Join-Path $SCRIPT_DIR "../shared/command-utils.ps1")
11
+
12
+ # Verification commands must not be read from repository-local state.
13
+ # A malicious repository can pre-seed .archaeology/session.json; executing commands
14
+ # from that file would cross the repository-to-workstation trust boundary.
15
+ # Operators who intentionally need custom commands can approve them explicitly via
16
+ # environment variables for the current process.
17
+ $TEST_CMD = if ($env:CODE_ARCHAEOLOGY_TEST_COMMAND) { $env:CODE_ARCHAEOLOGY_TEST_COMMAND } else { "npm test" }
18
+ $TYPECHECK_CMD = if ($env:CODE_ARCHAEOLOGY_TYPECHECK_COMMAND) { $env:CODE_ARCHAEOLOGY_TYPECHECK_COMMAND } else { "npx tsc --noEmit" }
19
+
20
+ Write-Host "[$PHASE] Running test command: $TEST_CMD"
21
+ try {
22
+ Invoke-CheckedCommand -CommandLine $TEST_CMD | Out-Default
23
+ } catch {
24
+ Write-Error "[$PHASE] Tests FAILED"
25
+ exit 1
26
+ }
27
+
28
+ Write-Host "[$PHASE] Running typecheck: $TYPECHECK_CMD"
29
+ try {
30
+ Invoke-CheckedCommand -CommandLine $TYPECHECK_CMD 2>$null | Out-Default
31
+ } catch {
32
+ Write-Warning "[$PHASE] Typecheck reported errors (non-blocking for some languages)"
33
+ }
34
+
35
+ Write-Host "[$PHASE] Verification passed"
@@ -9,13 +9,13 @@ SESSION_FILE="$ARCHAEOLOGY_DIR/session.json"
9
9
 
10
10
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
11
11
 
12
- # Source config from session file if jq is available
13
- TEST_CMD="npm test"
14
- TYPECHECK_CMD="npx tsc --noEmit"
15
- if command -v jq >/dev/null 2>&1 && [[ -f "$SESSION_FILE" ]]; then
16
- TEST_CMD=$(jq -r '.config.test_command // "npm test"' "$SESSION_FILE")
17
- TYPECHECK_CMD=$(jq -r '.config.typecheck_command // "npx tsc --noEmit"' "$SESSION_FILE")
18
- fi
12
+ # Verification commands must not be read from repository-local state.
13
+ # A malicious repository can pre-seed .archaeology/session.json; executing commands
14
+ # from that file would cross the repository-to-workstation trust boundary.
15
+ # Operators who intentionally need custom commands can approve them explicitly via
16
+ # environment variables for the current process.
17
+ TEST_CMD="${CODE_ARCHAEOLOGY_TEST_COMMAND:-npm test}"
18
+ TYPECHECK_CMD="${CODE_ARCHAEOLOGY_TYPECHECK_COMMAND:-npx tsc --noEmit}"
19
19
 
20
20
  echo "[$PHASE] Running test command: $TEST_CMD"
21
21
  if ! bash -c "$TEST_CMD"; then
@@ -0,0 +1,100 @@
1
+ # Shared PowerShell command parsing and execution helpers for verification hooks.
2
+
3
+ function Convert-CommandElementToArgument {
4
+ param(
5
+ [Parameter(Mandatory=$true)]
6
+ [System.Management.Automation.Language.CommandElementAst]$Element,
7
+
8
+ [Parameter(Mandatory=$true)]
9
+ [string]$CommandLine
10
+ )
11
+
12
+ if ($Element -is [System.Management.Automation.Language.StringConstantExpressionAst]) {
13
+ return $Element.Value
14
+ }
15
+
16
+ if ($Element -is [System.Management.Automation.Language.ExpandableStringExpressionAst]) {
17
+ return $Element.Value
18
+ }
19
+
20
+ if ($Element -is [System.Management.Automation.Language.CommandParameterAst]) {
21
+ if ($null -ne $Element.Argument) {
22
+ $argumentValue = Convert-CommandElementToArgument -Element $Element.Argument -CommandLine $CommandLine
23
+ return "-$($Element.ParameterName):$argumentValue"
24
+ }
25
+
26
+ return "-$($Element.ParameterName)"
27
+ }
28
+
29
+ throw "Unsupported command syntax in command: $CommandLine"
30
+ }
31
+
32
+ function Split-CommandLine {
33
+ param([Parameter(Mandatory=$true)][string]$CommandLine)
34
+
35
+ [System.Management.Automation.Language.Token[]]$tokens = @()
36
+ [System.Management.Automation.Language.ParseError[]]$parseErrors = @()
37
+ $ast = [System.Management.Automation.Language.Parser]::ParseInput($CommandLine, [ref]$tokens, [ref]$parseErrors)
38
+
39
+ if ($parseErrors.Count -gt 0) {
40
+ $message = ($parseErrors | ForEach-Object { $_.Message }) -join "; "
41
+ throw "Invalid command syntax: $CommandLine. $message"
42
+ }
43
+
44
+ $statements = @($ast.EndBlock.Statements)
45
+ if ($statements.Count -ne 1 -or $statements[0] -isnot [System.Management.Automation.Language.PipelineAst]) {
46
+ throw "Only a single simple command is supported: $CommandLine"
47
+ }
48
+
49
+ $pipeline = [System.Management.Automation.Language.PipelineAst]$statements[0]
50
+ if ($pipeline.PipelineElements.Count -ne 1 -or $pipeline.PipelineElements[0] -isnot [System.Management.Automation.Language.CommandAst]) {
51
+ throw "Only a single simple command is supported: $CommandLine"
52
+ }
53
+
54
+ $commandAst = [System.Management.Automation.Language.CommandAst]$pipeline.PipelineElements[0]
55
+ if ($commandAst.Redirections.Count -gt 0) {
56
+ throw "Command must not contain redirections: $CommandLine"
57
+ }
58
+
59
+ $parts = [System.Collections.Generic.List[string]]::new()
60
+ foreach ($element in $commandAst.CommandElements) {
61
+ $parts.Add((Convert-CommandElementToArgument -Element $element -CommandLine $CommandLine))
62
+ }
63
+
64
+ return $parts.ToArray()
65
+ }
66
+
67
+ function Invoke-CheckedCommand {
68
+ param([Parameter(Mandatory=$true)][string]$CommandLine)
69
+
70
+ [string[]]$parts = @(Split-CommandLine -CommandLine $CommandLine)
71
+ if ($parts.Count -eq 0) {
72
+ throw "Empty command"
73
+ }
74
+
75
+ $command = $parts[0]
76
+ $arguments = @()
77
+ if ($parts.Count -gt 1) {
78
+ $arguments = $parts[1..($parts.Count - 1)]
79
+ }
80
+
81
+ $resolvedCommand = Get-Command -Name $command -ErrorAction Stop | Select-Object -First 1
82
+ $isExternalApplication = $resolvedCommand.CommandType -eq [System.Management.Automation.CommandTypes]::Application
83
+ if ($isExternalApplication) {
84
+ $global:LASTEXITCODE = 0
85
+ }
86
+
87
+ & $command @arguments
88
+
89
+ if ($isExternalApplication) {
90
+ $exitCode = $LASTEXITCODE
91
+ if ($exitCode -ne 0) {
92
+ throw "Command failed with exit code $exitCode: $CommandLine"
93
+ }
94
+ return
95
+ }
96
+
97
+ if (-not $?) {
98
+ throw "Command failed: $CommandLine"
99
+ }
100
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-code-archaeology",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Excavate, catalog, and restore a codebase by removing accumulated sediment—dead code, legacy fallbacks, circular dependencies, weak types, and defensive programming slop.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,6 +12,14 @@
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
14
  "default": "./dist/index.js"
15
+ },
16
+ "./plugin": {
17
+ "types": "./dist/plugin.d.ts",
18
+ "default": "./dist/plugin.js"
19
+ },
20
+ "./types": {
21
+ "types": "./dist/types.d.ts",
22
+ "default": "./dist/types.js"
15
23
  }
16
24
  },
17
25
  "files": [
@@ -19,16 +27,29 @@
19
27
  "hooks",
20
28
  "commands",
21
29
  "skills",
22
- "plugins",
23
- "policies",
30
+ "prompts",
24
31
  "schema",
32
+ "docs/README.md",
33
+ "docs/index.html",
34
+ "docs/INSTALL.md",
35
+ "docs/ARCHITECTURE.md",
36
+ "docs/RELEASE.md",
37
+ "docs/SECURITY_AUDIT.md",
38
+ "wiki",
39
+ "assets",
40
+ ".github",
25
41
  "AGENTS.md",
26
42
  "VERSION",
27
43
  "README.md",
44
+ "INSTALL.md",
45
+ "SECURITY.md",
46
+ "CONTRIBUTING.md",
47
+ "CHANGELOG.md",
28
48
  "LICENSE"
29
49
  ],
30
50
  "scripts": {
31
51
  "build": "tsc",
52
+ "test": "npm run build && node --test tests/*.test.mjs",
32
53
  "typecheck": "tsc --noEmit",
33
54
  "verify:pack": "bash hooks/opencode/verify-package.sh",
34
55
  "prepack": "tsc"
@@ -46,14 +67,28 @@
46
67
  "type": "git",
47
68
  "url": "git+https://github.com/Maleick/Code-Archaeology.git"
48
69
  },
49
- "homepage": "https://github.com/Maleick/Code-Archaeology",
70
+ "author": {
71
+ "name": "Maleick",
72
+ "url": "https://github.com/Maleick"
73
+ },
74
+ "homepage": "https://github.com/Maleick/Code-Archaeology#readme",
50
75
  "bugs": {
51
76
  "url": "https://github.com/Maleick/Code-Archaeology/issues"
52
77
  },
53
78
  "license": "MIT",
54
79
  "devDependencies": {
55
- "@types/node": "^20.0.0",
56
- "typescript": "^5.0.0"
80
+ "@semantic-release/changelog": "^6.0.3",
81
+ "@semantic-release/commit-analyzer": "^13.0.1",
82
+ "@semantic-release/git": "^10.0.1",
83
+ "@semantic-release/github": "^12.0.6",
84
+ "@semantic-release/npm": "^13.1.5",
85
+ "@semantic-release/release-notes-generator": "^14.1.0",
86
+ "@types/node": "^25.6.0",
87
+ "semantic-release": "^25.0.3",
88
+ "typescript": "^6.0.3"
89
+ },
90
+ "overrides": {
91
+ "npm": "^11.14.0"
57
92
  },
58
93
  "engines": {
59
94
  "node": ">=18"
@@ -0,0 +1,45 @@
1
+ # Expedition 1: Dead Code Excavation
2
+
3
+ ## Objective
4
+ Identify and catalog all dead code—unused exports, unreachable functions, unreferenced variables, and orphaned files.
5
+
6
+ ## Instructions
7
+
8
+ 1. **Tool-Based Discovery**
9
+ - Run `knip` (TypeScript/JavaScript) or `vulture` (Python)
10
+ - Run `jscpd` to find duplicate code that may indicate dead copies
11
+ - If tools unavailable, perform AST-based manual analysis
12
+
13
+ 2. **Classification**
14
+ For each finding, classify confidence:
15
+ - **HIGH**: Tool-confirmed unused export with zero references
16
+ - **MEDIUM**: Likely unused but has dynamic access or test references
17
+ - **LOW**: Possibly used via reflection or build-time injection
18
+
19
+ 3. **Impact Assessment**
20
+ - Note if removal affects public API
21
+ - Check for test files that import but don't meaningfully test
22
+ - Verify no build scripts or CI depend on the code
23
+
24
+ ## Output
25
+
26
+ Write to `.archaeology/expedition1-report.md`:
27
+ - Table of all findings with file paths, line numbers, confidence levels
28
+ - Categorized by type (unused export, unreachable code, orphaned file, duplicate)
29
+ - Recommended action per finding (remove, flag for review, keep)
30
+ - Estimated lines of code affected
31
+
32
+ ## Execution Rules
33
+ - If `mode == survey`: catalog only, zero changes
34
+ - If `mode == excavate`: generate mock patch files for review
35
+ - If `mode == restore`:
36
+ - Remove HIGH confidence artifacts always
37
+ - Remove MEDIUM confidence artifacts only if `strict_mode == true`
38
+ - NEVER remove LOW confidence artifacts
39
+ - Run tests after each removal batch
40
+ - Revert immediately if tests fail
41
+
42
+ ## Constraints
43
+ - NEVER remove code that is dynamically accessed (eval, require(variable), etc.)
44
+ - NEVER remove exports that are part of a public API unless explicitly deprecated
45
+ - ALWAYS verify with grep that no references exist before removing
@@ -0,0 +1,49 @@
1
+ # Expedition 3: Circular Dependency Cartography
2
+
3
+ ## Objective
4
+ Map all circular dependencies in the module graph and provide remediation strategies.
5
+
6
+ ## Instructions
7
+
8
+ 1. **Tool-Based Analysis**
9
+ - Run `madge --circular` (TypeScript/JavaScript)
10
+ - Run `pydeps` (Python) or equivalent
11
+ - If tools unavailable, build import graph manually
12
+
13
+ 2. **Dependency Mapping**
14
+ For each cycle found:
15
+ - List all files in the cycle
16
+ - Identify the specific imports creating the cycle
17
+ - Determine if the cycle is direct (A→B→A) or indirect (A→B→C→A)
18
+ - Calculate cycle complexity (number of nodes, edges)
19
+
20
+ 3. **Remediation Strategy**
21
+ For each cycle, determine the best fix:
22
+ - Extract shared code to a new module (preferred)
23
+ - Use dependency inversion / interfaces
24
+ - Move code to break the cycle
25
+ - Convert to dynamic imports (if appropriate)
26
+ - Flag as architectural issue requiring human design review
27
+
28
+ ## Output
29
+
30
+ Write to `.archaeology/expedition3-report.md`:
31
+ - Complete cycle inventory with file paths and import chains
32
+ - Visualization data (can be rendered with graphviz)
33
+ - Remediation recommendation per cycle
34
+ - Estimated effort to resolve each cycle
35
+
36
+ ## Execution Rules
37
+ - If `mode == survey`: catalog only
38
+ - If `mode == excavate`: generate detailed migration plans
39
+ - If `mode == restore`:
40
+ - Fix simple cycles (2-node, clear extraction path) automatically
41
+ - Flag complex cycles for human review
42
+ - NEVER create new abstractions that obscure the cycle—break it properly
43
+ - Run tests after each fix
44
+
45
+ ## Constraints
46
+ - NEVER introduce dynamic imports just to hide a cycle—fix the architecture
47
+ - NEVER extract code into poorly-named "utils" files—use domain-appropriate names
48
+ - ALWAYS ensure the fixed graph has no new cycles introduced
49
+ - ALWAYS verify the cycle is real (not a type-only import that tree-shakes away)
@@ -0,0 +1,47 @@
1
+ # Phase 0: Site Survey & Baseline
2
+
3
+ ## Objective
4
+ Establish a complete inventory of the codebase before any modifications. Document the baseline state so all subsequent expeditions have a reference point.
5
+
6
+ ## Instructions
7
+
8
+ 1. **Verify Preconditions**
9
+ - Confirm working tree is clean
10
+ - Confirm tests pass at baseline
11
+ - Create branch `{{ branch_name }}`
12
+ - Create `.archaeology/` directory
13
+
14
+ 2. **File Inventory**
15
+ - Catalog all source files by directory
16
+ - Note file counts, line counts, and language distribution
17
+ - Identify configuration files (package.json, tsconfig, etc.)
18
+
19
+ 3. **Dependency Mapping**
20
+ - Document all external dependencies
21
+ - Note devDependencies vs production dependencies
22
+ - Flag any deprecated or outdated packages
23
+
24
+ 4. **Baseline Metrics**
25
+ - Record test count and coverage (if available)
26
+ - Record type error count
27
+ - Record lint error count
28
+ - Save current git HEAD to `.archaeology/baseline.txt`
29
+
30
+ ## Output
31
+
32
+ Write to `.archaeology/site_survey.md`:
33
+ - Executive summary of codebase size and structure
34
+ - Dependency health assessment
35
+ - Baseline metrics table
36
+ - Risk factors identified
37
+
38
+ Write to `.archaeology/artifact_inventory.json`:
39
+ - Machine-readable file inventory
40
+
41
+ Write to `.archaeology/stratum_graph.json`:
42
+ - Dependency graph data for visualization
43
+
44
+ ## Constraints
45
+ - ZERO file modifications in this phase
46
+ - If tests fail at baseline, abort immediately
47
+ - Do not proceed to Expedition 1 until this report is complete
package/prompts/dry.md ADDED
@@ -0,0 +1,49 @@
1
+ # Expedition 6: DRY Stratification
2
+
3
+ ## Objective
4
+ Identify semantic duplication across the codebase and extract shared abstractions. Only extract true semantic duplicates, not coincidental similarity.
5
+
6
+ ## Instructions
7
+
8
+ 1. **Duplicate Detection**
9
+ - Run `jscpd` with `min_duplicate_lines: 5`
10
+ - Search for repeated patterns manually (error messages, validation logic, API calls)
11
+ - Look for copy-pasted code blocks with minor variations
12
+
13
+ 2. **Semantic Analysis**
14
+ For each duplicate found:
15
+ - Determine if the duplication is coincidental (same structure, different semantics)
16
+ - Check if the duplicated code represents a real domain concept
17
+ - Assess if extraction would create a meaningful abstraction
18
+ - Verify the duplicated code isn't better left inline (trivial one-liners)
19
+
20
+ 3. **Extraction Planning**
21
+ - Identify the canonical location for the extracted code
22
+ - Determine the appropriate abstraction level (function, class, constant, etc.)
23
+ - Plan parameterization for minor variations
24
+ - Check for existing utility libraries that could host the code
25
+
26
+ ## Output
27
+
28
+ Write to `.archaeology/expedition6-report.md`:
29
+ - Catalog of all duplications with locations and similarity scores
30
+ - Classification: semantic vs. coincidental
31
+ - Extraction recommendation for each semantic duplicate
32
+ - Proposed abstraction name and location
33
+ - Files affected by extraction
34
+
35
+ ## Execution Rules
36
+ - If `mode == survey`: catalog only
37
+ - If `mode == excavate`: generate extraction plans with before/after code
38
+ - If `mode == restore`:
39
+ - Extract HIGH confidence semantic duplications
40
+ - Extract MEDIUM confidence only if `strict_mode == true`
41
+ - NEVER extract coincidental similarities—leave them inline
42
+ - Run tests after each extraction
43
+
44
+ ## Constraints
45
+ - NEVER extract code into a "utils" grab bag—use domain-appropriate names
46
+ - NEVER create abstractions over cyclic dependencies (fix cycles in Expedition 3 first)
47
+ - ALWAYS ensure the extracted code is actually used in 3+ places or is likely to be
48
+ - NEVER change behavior during extraction—pure refactor only
49
+ - ALWAYS prefer composition over premature abstraction
@@ -0,0 +1,52 @@
1
+ # Expedition 7: Error Handling Stratigraphy
2
+
3
+ ## Objective
4
+ Identify and catalog problematic error handling patterns: suppressed errors, empty catch blocks, overly broad try/catch, and error swallowing.
5
+
6
+ ## Instructions
7
+
8
+ 1. **Pattern Search**
9
+ Search for these anti-patterns:
10
+ - Empty or console-only catch blocks
11
+ - `catch (e) { return null; }` or similar suppression
12
+ - `try/catch` around non-throwing code (defensive overprogramming)
13
+ - Broad exception types when specific ones are available
14
+ - `suppress`, `silence`, `safe`, `onError` in function names (often indicate error hiding)
15
+ - Ignored Promise rejections (`.catch(() => {})`)
16
+
17
+ 2. **Context Analysis**
18
+ For each finding:
19
+ - Determine if the suppression is intentional (expected failure case)
20
+ - Identify what error information is being lost
21
+ - Assess if the error should propagate to a higher handler
22
+ - Check if logging/monitoring is adequate
23
+
24
+ 3. **Boundary Classification**
25
+ - I/O boundary: File system, network, external API calls (legitimate try/catch)
26
+ - Internal boundary: Business logic, pure functions (suspicious suppression)
27
+ - User input boundary: Form validation, CLI arguments (may need specific handling)
28
+
29
+ ## Output
30
+
31
+ Write to `.archaeology/expedition7-report.md`:
32
+ - Inventory of all error handling issues with locations
33
+ - Classification by anti-pattern type
34
+ - Risk assessment (data loss, silent failures, debugging difficulty)
35
+ - Recommended fix for each issue
36
+ - Boundary classification for each finding
37
+
38
+ ## Execution Rules
39
+ - If `mode == survey`: catalog only
40
+ - If `mode == excavate`: generate fix proposals
41
+ - If `mode == restore`:
42
+ - Remove error hiding from internal boundaries
43
+ - Add proper logging or propagation
44
+ - NEVER remove try/catch from I/O or external input boundaries
45
+ - Run tests after each change
46
+
47
+ ## Constraints
48
+ - NEVER remove try/catch from I/O operations (file read, network request, DB query)
49
+ - NEVER remove try/catch from external API boundaries
50
+ - ALWAYS preserve error information—replace suppression with logging or re-throwing
51
+ - NEVER let errors propagate unhandled—replace with explicit error handling
52
+ - ALWAYS consider if the catch block is testing an expected condition (if so, refactor to validation)
@@ -0,0 +1,58 @@
1
+ # Phase 9: Site Preservation & Final Catalog
2
+
3
+ ## Objective
4
+ Verify all previous expeditions produced a healthy codebase. Generate final metrics and preserve the excavation record.
5
+
6
+ ## Instructions
7
+
8
+ 1. **Test Verification**
9
+ - Run `{{ test_command }}` — must exit 0
10
+ - Run `{{ typecheck_command }}` — must exit 0
11
+ - If either fails, STOP and revert to baseline
12
+
13
+ 2. **Regression Checks**
14
+ - Re-run dependency analysis—verify no NEW cycles introduced
15
+ - Re-run dead code analysis—verify no NEW dead code created
16
+ - Check that no types were weakened during previous expeditions
17
+ - Verify no new duplications were introduced
18
+
19
+ 3. **Metrics Collection**
20
+ - Calculate lines changed (added/removed)
21
+ - Calculate test coverage delta (if available)
22
+ - Count type errors resolved
23
+ - Count cycles broken
24
+ - Count dead code removed
25
+
26
+ 4. **Diff Preservation**
27
+ - Run `git diff --stat > .archaeology/excavation_log.txt`
28
+ - Capture the complete change summary
29
+
30
+ ## Output
31
+
32
+ Write to `.archaeology/FINAL_CATALOG.md`:
33
+ - Executive summary of all expeditions
34
+ - Before/after metrics comparison table
35
+ - List of all artifacts removed
36
+ - List of all types consolidated
37
+ - List of all cycles broken
38
+ - Recommendations for future maintenance
39
+ - Human review sign-off checklist (if mode != survey)
40
+
41
+ Write to `.archaeology/excavation_log.txt`:
42
+ - Complete `git diff --stat` output
43
+
44
+ ## Final Checks
45
+ - [ ] All tests passing
46
+ - [ ] Type checker zero errors
47
+ - [ ] No new circular dependencies
48
+ - [ ] No new dead code
49
+ - [ ] Linting passes (if applicable)
50
+ - [ ] Documentation updated
51
+ - [ ] Human review completed (if mode != survey)
52
+
53
+ ## Constraints
54
+ - NEVER claim success if any test fails
55
+ - NEVER ignore new type errors introduced during expeditions
56
+ - ALWAYS revert all changes if this phase fails—do not leave repo in broken state
57
+ - ALWAYS preserve `.archaeology/` directory for historical record
58
+ - NEVER delete `.archaeology/` reports even after successful completion