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.
- package/.github/ISSUE_TEMPLATE/bug_report.yml +63 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +48 -0
- package/.github/pull_request_template.md +27 -0
- package/.github/workflows/ci.yml +45 -0
- package/.github/workflows/release.yml +46 -0
- package/AGENTS.md +42 -10
- package/CHANGELOG.md +79 -0
- package/CONTRIBUTING.md +50 -0
- package/INSTALL.md +211 -0
- package/README.md +255 -71
- package/SECURITY.md +20 -0
- package/VERSION +1 -1
- package/assets/code-archaeology-banner.svg +195 -0
- package/commands/code-archaeology.md +7 -5
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +137 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +1 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -17
- package/dist/index.js.map +1 -1
- package/dist/platform.d.ts +4 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +11 -0
- package/dist/platform.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -0
- package/dist/runtime.d.ts +18 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +49 -0
- package/dist/runtime.js.map +1 -0
- package/dist/types.d.ts +1 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/docs/ARCHITECTURE.md +123 -0
- package/docs/INSTALL.md +156 -0
- package/docs/README.md +72 -0
- package/docs/RELEASE.md +139 -0
- package/docs/SECURITY_AUDIT.md +38 -0
- package/docs/index.html +740 -0
- package/hooks/hermes/runner.ps1 +247 -0
- package/hooks/hermes/runner.sh +262 -0
- package/hooks/hermes/setup.ps1 +41 -0
- package/hooks/hermes/setup.sh +41 -0
- package/hooks/opencode/init.ps1 +83 -0
- package/hooks/opencode/revert-phase.ps1 +12 -0
- package/hooks/opencode/revert-phase.sh +3 -8
- package/hooks/opencode/update-expedition.ps1 +51 -0
- package/hooks/opencode/verify-package.sh +47 -0
- package/hooks/opencode/verify-phase.ps1 +35 -0
- package/hooks/opencode/verify-phase.sh +7 -7
- package/hooks/shared/command-utils.ps1 +100 -0
- package/package.json +41 -6
- package/prompts/dead_code.md +45 -0
- package/prompts/dependencies.md +49 -0
- package/prompts/discovery.md +47 -0
- package/prompts/dry.md +49 -0
- package/prompts/errors.md +52 -0
- package/prompts/final_verify.md +58 -0
- package/prompts/legacy.md +49 -0
- package/prompts/polish.md +48 -0
- package/prompts/types_consolidate.md +48 -0
- package/prompts/types_harden.md +51 -0
- package/skills/code-archaeology/SKILL.md +2 -2
- package/skills/hermes/INTEGRATION.md +120 -0
- package/skills/hermes/README.md +167 -0
- package/skills/hermes/code-archaeology-prompt.md +203 -0
- package/wiki/Expedition-Workflow.md +34 -0
- package/wiki/Home.md +27 -0
- package/wiki/Installation.md +44 -0
- package/wiki/Release-Process.md +31 -0
- package/wiki/Security-and-Safety.md +21 -0
- package/plugins/code-archaeology.ts +0 -8
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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.
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"@
|
|
56
|
-
"
|
|
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
|