agentsys 5.0.3 → 5.1.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/.claude-plugin/marketplace.json +21 -14
- package/.claude-plugin/plugin.json +1 -1
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +18 -0
- package/README.md +7 -6
- package/adapters/codex/skills/agnix/SKILL.md +0 -1
- package/adapters/codex/skills/audit-project/SKILL.md +0 -1
- package/adapters/codex/skills/audit-project-agents/SKILL.md +0 -1
- package/adapters/codex/skills/audit-project-github/SKILL.md +0 -1
- package/adapters/codex/skills/consult/SKILL.md +132 -57
- package/adapters/codex/skills/debate/SKILL.md +214 -0
- package/adapters/codex/skills/delivery-approval/SKILL.md +0 -1
- package/adapters/codex/skills/deslop/SKILL.md +0 -1
- package/adapters/codex/skills/drift-detect/SKILL.md +0 -1
- package/adapters/codex/skills/enhance/SKILL.md +0 -1
- package/adapters/codex/skills/learn/SKILL.md +0 -1
- package/adapters/codex/skills/next-task/SKILL.md +0 -1
- package/adapters/codex/skills/perf/SKILL.md +0 -1
- package/adapters/codex/skills/repo-map/SKILL.md +0 -1
- package/adapters/codex/skills/ship/SKILL.md +0 -1
- package/adapters/codex/skills/ship-ci-review-loop/SKILL.md +0 -1
- package/adapters/codex/skills/ship-deployment/SKILL.md +0 -1
- package/adapters/codex/skills/ship-error-handling/SKILL.md +0 -1
- package/adapters/codex/skills/sync-docs/SKILL.md +0 -1
- package/adapters/opencode/agents/agent-enhancer.md +0 -1
- package/adapters/opencode/agents/agnix-agent.md +0 -1
- package/adapters/opencode/agents/ci-fixer.md +0 -1
- package/adapters/opencode/agents/ci-monitor.md +0 -1
- package/adapters/opencode/agents/claudemd-enhancer.md +0 -1
- package/adapters/opencode/agents/consult-agent.md +122 -30
- package/adapters/opencode/agents/cross-file-enhancer.md +0 -1
- package/adapters/opencode/agents/debate-orchestrator.md +169 -0
- package/adapters/opencode/agents/delivery-validator.md +0 -1
- package/adapters/opencode/agents/deslop-agent.md +0 -1
- package/adapters/opencode/agents/docs-enhancer.md +0 -1
- package/adapters/opencode/agents/exploration-agent.md +0 -1
- package/adapters/opencode/agents/hooks-enhancer.md +0 -1
- package/adapters/opencode/agents/implementation-agent.md +0 -1
- package/adapters/opencode/agents/learn-agent.md +0 -1
- package/adapters/opencode/agents/map-validator.md +0 -1
- package/adapters/opencode/agents/perf-analyzer.md +0 -1
- package/adapters/opencode/agents/perf-code-paths.md +0 -1
- package/adapters/opencode/agents/perf-investigation-logger.md +0 -1
- package/adapters/opencode/agents/perf-orchestrator.md +0 -1
- package/adapters/opencode/agents/perf-theory-gatherer.md +0 -1
- package/adapters/opencode/agents/perf-theory-tester.md +0 -1
- package/adapters/opencode/agents/plan-synthesizer.md +0 -1
- package/adapters/opencode/agents/planning-agent.md +0 -1
- package/adapters/opencode/agents/plugin-enhancer.md +0 -1
- package/adapters/opencode/agents/prompt-enhancer.md +0 -1
- package/adapters/opencode/agents/simple-fixer.md +0 -1
- package/adapters/opencode/agents/skills-enhancer.md +0 -1
- package/adapters/opencode/agents/sync-docs-agent.md +0 -1
- package/adapters/opencode/agents/task-discoverer.md +0 -1
- package/adapters/opencode/agents/test-coverage-checker.md +0 -1
- package/adapters/opencode/agents/worktree-manager.md +0 -1
- package/adapters/opencode/commands/agnix.md +0 -1
- package/adapters/opencode/commands/audit-project-agents.md +0 -1
- package/adapters/opencode/commands/audit-project-github.md +0 -1
- package/adapters/opencode/commands/audit-project.md +0 -1
- package/adapters/opencode/commands/consult.md +133 -57
- package/adapters/opencode/commands/debate.md +224 -0
- package/adapters/opencode/commands/delivery-approval.md +0 -1
- package/adapters/opencode/commands/deslop.md +0 -1
- package/adapters/opencode/commands/drift-detect.md +0 -1
- package/adapters/opencode/commands/enhance.md +0 -1
- package/adapters/opencode/commands/learn.md +0 -1
- package/adapters/opencode/commands/next-task.md +0 -1
- package/adapters/opencode/commands/perf.md +0 -1
- package/adapters/opencode/commands/repo-map.md +0 -1
- package/adapters/opencode/commands/ship-ci-review-loop.md +0 -1
- package/adapters/opencode/commands/ship-deployment.md +0 -1
- package/adapters/opencode/commands/ship-error-handling.md +0 -1
- package/adapters/opencode/commands/ship.md +0 -1
- package/adapters/opencode/commands/sync-docs.md +0 -1
- package/adapters/opencode/skills/agnix/SKILL.md +1 -2
- package/adapters/opencode/skills/consult/SKILL.md +33 -23
- package/adapters/opencode/skills/debate/SKILL.md +245 -0
- package/adapters/opencode/skills/deslop/SKILL.md +1 -2
- package/adapters/opencode/skills/discover-tasks/SKILL.md +1 -2
- package/adapters/opencode/skills/drift-analysis/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-agent-prompts/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-claude-memory/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-cross-file/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-docs/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-hooks/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-orchestrator/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-plugins/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-prompts/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-skills/SKILL.md +1 -2
- package/adapters/opencode/skills/learn/SKILL.md +1 -2
- package/adapters/opencode/skills/orchestrate-review/SKILL.md +0 -1
- package/adapters/opencode/skills/perf-analyzer/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-baseline-manager/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-benchmarker/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-code-paths/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-investigation-logger/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-profiler/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-theory-gatherer/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-theory-tester/SKILL.md +1 -2
- package/adapters/opencode/skills/repo-mapping/SKILL.md +1 -2
- package/adapters/opencode/skills/sync-docs/SKILL.md +1 -2
- package/adapters/opencode/skills/validate-delivery/SKILL.md +1 -2
- package/lib/adapter-transforms.js +24 -4
- package/package.json +1 -1
- package/plugins/agnix/.claude-plugin/plugin.json +1 -1
- package/plugins/agnix/skills/agnix/SKILL.md +1 -1
- package/plugins/audit-project/.claude-plugin/plugin.json +1 -1
- package/plugins/audit-project/lib/adapter-transforms.js +24 -4
- package/plugins/consult/.claude-plugin/plugin.json +1 -1
- package/plugins/consult/agents/consult-agent.md +122 -29
- package/plugins/consult/commands/consult.md +135 -58
- package/plugins/consult/skills/consult/SKILL.md +31 -20
- package/plugins/debate/.claude-plugin/plugin.json +21 -0
- package/plugins/debate/agents/debate-orchestrator.md +175 -0
- package/plugins/debate/commands/debate.md +221 -0
- package/plugins/debate/lib/adapter-transforms.js +298 -0
- package/plugins/debate/lib/collectors/codebase.js +392 -0
- package/plugins/debate/lib/collectors/docs-patterns.js +713 -0
- package/plugins/debate/lib/collectors/documentation.js +219 -0
- package/plugins/debate/lib/collectors/github.js +330 -0
- package/plugins/debate/lib/collectors/index.js +126 -0
- package/plugins/debate/lib/config/index.js +14 -0
- package/plugins/debate/lib/cross-platform/index.js +539 -0
- package/plugins/debate/lib/discovery/index.js +352 -0
- package/plugins/debate/lib/drift-detect/collectors.js +37 -0
- package/plugins/debate/lib/enhance/agent-analyzer.js +421 -0
- package/plugins/debate/lib/enhance/agent-patterns.js +571 -0
- package/plugins/debate/lib/enhance/auto-suppression.js +622 -0
- package/plugins/debate/lib/enhance/benchmark.js +417 -0
- package/plugins/debate/lib/enhance/cross-file-analyzer.js +930 -0
- package/plugins/debate/lib/enhance/cross-file-patterns.js +370 -0
- package/plugins/debate/lib/enhance/docs-analyzer.js +325 -0
- package/plugins/debate/lib/enhance/docs-patterns.js +671 -0
- package/plugins/debate/lib/enhance/fixer.js +721 -0
- package/plugins/debate/lib/enhance/hook-analyzer.js +135 -0
- package/plugins/debate/lib/enhance/hook-patterns.js +40 -0
- package/plugins/debate/lib/enhance/index.js +127 -0
- package/plugins/debate/lib/enhance/plugin-analyzer.js +402 -0
- package/plugins/debate/lib/enhance/plugin-patterns.js +326 -0
- package/plugins/debate/lib/enhance/projectmemory-analyzer.js +551 -0
- package/plugins/debate/lib/enhance/projectmemory-patterns.js +617 -0
- package/plugins/debate/lib/enhance/prompt-analyzer.js +457 -0
- package/plugins/debate/lib/enhance/prompt-patterns.js +1484 -0
- package/plugins/debate/lib/enhance/reporter.js +1348 -0
- package/plugins/debate/lib/enhance/security-patterns.js +284 -0
- package/plugins/debate/lib/enhance/skill-analyzer.js +182 -0
- package/plugins/debate/lib/enhance/skill-patterns.js +147 -0
- package/plugins/debate/lib/enhance/suppression.js +352 -0
- package/plugins/debate/lib/enhance/tool-patterns.js +373 -0
- package/plugins/debate/lib/index.js +270 -0
- package/plugins/debate/lib/patterns/cli-enhancers.js +611 -0
- package/plugins/debate/lib/patterns/pipeline.js +948 -0
- package/plugins/debate/lib/patterns/review-patterns.js +558 -0
- package/plugins/debate/lib/patterns/slop-analyzers.js +2305 -0
- package/plugins/debate/lib/patterns/slop-patterns.js +1187 -0
- package/plugins/debate/lib/perf/analyzer/index.js +22 -0
- package/plugins/debate/lib/perf/argument-parser.js +105 -0
- package/plugins/debate/lib/perf/baseline-comparator.js +50 -0
- package/plugins/debate/lib/perf/baseline-store.js +127 -0
- package/plugins/debate/lib/perf/benchmark-runner.js +404 -0
- package/plugins/debate/lib/perf/breaking-point-finder.js +52 -0
- package/plugins/debate/lib/perf/breaking-point-runner.js +60 -0
- package/plugins/debate/lib/perf/checkpoint.js +123 -0
- package/plugins/debate/lib/perf/code-paths.js +86 -0
- package/plugins/debate/lib/perf/consolidation.js +37 -0
- package/plugins/debate/lib/perf/constraint-runner.js +71 -0
- package/plugins/debate/lib/perf/experiment-runner.js +32 -0
- package/plugins/debate/lib/perf/index.js +41 -0
- package/plugins/debate/lib/perf/investigation-state.js +874 -0
- package/plugins/debate/lib/perf/optimization-runner.js +79 -0
- package/plugins/debate/lib/perf/profilers/go.js +22 -0
- package/plugins/debate/lib/perf/profilers/index.js +46 -0
- package/plugins/debate/lib/perf/profilers/java.js +23 -0
- package/plugins/debate/lib/perf/profilers/node.js +27 -0
- package/plugins/debate/lib/perf/profilers/python.js +23 -0
- package/plugins/debate/lib/perf/profilers/rust.js +23 -0
- package/plugins/debate/lib/perf/profiling-runner.js +75 -0
- package/plugins/debate/lib/perf/schemas.js +140 -0
- package/plugins/debate/lib/platform/detect-platform.js +413 -0
- package/plugins/debate/lib/platform/detection-configs.js +93 -0
- package/plugins/debate/lib/platform/state-dir.js +132 -0
- package/plugins/debate/lib/platform/verify-tools.js +182 -0
- package/plugins/debate/lib/repo-map/cache.js +152 -0
- package/plugins/debate/lib/repo-map/concurrency.js +29 -0
- package/plugins/debate/lib/repo-map/index.js +222 -0
- package/plugins/debate/lib/repo-map/installer.js +212 -0
- package/plugins/debate/lib/repo-map/queries/go.js +27 -0
- package/plugins/debate/lib/repo-map/queries/index.js +100 -0
- package/plugins/debate/lib/repo-map/queries/java.js +38 -0
- package/plugins/debate/lib/repo-map/queries/javascript.js +55 -0
- package/plugins/debate/lib/repo-map/queries/python.js +24 -0
- package/plugins/debate/lib/repo-map/queries/rust.js +73 -0
- package/plugins/debate/lib/repo-map/queries/typescript.js +38 -0
- package/plugins/debate/lib/repo-map/runner.js +1364 -0
- package/plugins/debate/lib/repo-map/updater.js +562 -0
- package/plugins/debate/lib/repo-map/usage-analyzer.js +407 -0
- package/plugins/debate/lib/schemas/plugin-manifest.schema.json +57 -0
- package/plugins/debate/lib/schemas/validator.js +247 -0
- package/plugins/debate/lib/sources/custom-handler.js +199 -0
- package/plugins/debate/lib/sources/policy-questions.js +246 -0
- package/plugins/debate/lib/sources/source-cache.js +165 -0
- package/plugins/debate/lib/state/workflow-state.js +576 -0
- package/plugins/debate/lib/types/agent-frontmatter.d.ts +134 -0
- package/plugins/debate/lib/types/command-frontmatter.d.ts +107 -0
- package/plugins/debate/lib/types/hook-frontmatter.d.ts +115 -0
- package/plugins/debate/lib/types/index.d.ts +84 -0
- package/plugins/debate/lib/types/plugin-manifest.d.ts +102 -0
- package/plugins/debate/lib/types/skill-frontmatter.d.ts +89 -0
- package/plugins/debate/lib/utils/atomic-write.js +94 -0
- package/plugins/debate/lib/utils/cache-manager.js +159 -0
- package/plugins/debate/lib/utils/command-parser.js +0 -0
- package/plugins/debate/lib/utils/context-optimizer.js +300 -0
- package/plugins/debate/lib/utils/deprecation.js +37 -0
- package/plugins/debate/lib/utils/shell-escape.js +88 -0
- package/plugins/debate/lib/utils/state-helpers.js +61 -0
- package/plugins/debate/skills/debate/SKILL.md +264 -0
- package/plugins/deslop/.claude-plugin/plugin.json +1 -1
- package/plugins/deslop/lib/adapter-transforms.js +24 -4
- package/plugins/deslop/skills/deslop/SKILL.md +1 -1
- package/plugins/drift-detect/.claude-plugin/plugin.json +1 -1
- package/plugins/drift-detect/lib/adapter-transforms.js +24 -4
- package/plugins/drift-detect/skills/drift-analysis/SKILL.md +1 -1
- package/plugins/enhance/.claude-plugin/plugin.json +1 -1
- package/plugins/enhance/lib/adapter-transforms.js +24 -4
- package/plugins/enhance/skills/enhance-agent-prompts/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-claude-memory/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-cross-file/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-docs/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-hooks/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-orchestrator/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-plugins/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-prompts/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-skills/SKILL.md +1 -1
- package/plugins/learn/.claude-plugin/plugin.json +1 -1
- package/plugins/learn/agents/learn-agent.md +1 -1
- package/plugins/learn/lib/adapter-transforms.js +24 -4
- package/plugins/learn/skills/learn/SKILL.md +1 -1
- package/plugins/next-task/.claude-plugin/plugin.json +1 -1
- package/plugins/next-task/agents/exploration-agent.md +1 -1
- package/plugins/next-task/lib/adapter-transforms.js +24 -4
- package/plugins/next-task/skills/discover-tasks/SKILL.md +1 -1
- package/plugins/next-task/skills/validate-delivery/SKILL.md +1 -1
- package/plugins/perf/.claude-plugin/plugin.json +1 -1
- package/plugins/perf/lib/adapter-transforms.js +24 -4
- package/plugins/perf/skills/perf-analyzer/SKILL.md +1 -1
- package/plugins/perf/skills/perf-baseline-manager/SKILL.md +1 -1
- package/plugins/perf/skills/perf-benchmarker/SKILL.md +1 -1
- package/plugins/perf/skills/perf-code-paths/SKILL.md +1 -1
- package/plugins/perf/skills/perf-investigation-logger/SKILL.md +1 -1
- package/plugins/perf/skills/perf-profiler/SKILL.md +1 -1
- package/plugins/perf/skills/perf-theory-gatherer/SKILL.md +1 -1
- package/plugins/perf/skills/perf-theory-tester/SKILL.md +1 -1
- package/plugins/repo-map/.claude-plugin/plugin.json +1 -1
- package/plugins/repo-map/lib/adapter-transforms.js +24 -4
- package/plugins/ship/.claude-plugin/plugin.json +1 -1
- package/plugins/ship/lib/adapter-transforms.js +24 -4
- package/plugins/sync-docs/.claude-plugin/plugin.json +1 -1
- package/plugins/sync-docs/lib/adapter-transforms.js +24 -4
- package/plugins/sync-docs/skills/sync-docs/SKILL.md +1 -1
- package/scripts/gen-adapters.js +6 -7
- package/scripts/generate-docs.js +4 -2
- package/scripts/plugins.txt +1 -0
- package/site/content.json +6 -6
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Tool Verification System
|
|
4
|
+
* Checks availability and versions of development tools for graceful degradation
|
|
5
|
+
*
|
|
6
|
+
* Usage: node lib/platform/verify-tools.js
|
|
7
|
+
* Output: JSON with tool availability and versions
|
|
8
|
+
*
|
|
9
|
+
* @author Avi Fenesh
|
|
10
|
+
* @license MIT
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { spawn } = require('child_process');
|
|
14
|
+
|
|
15
|
+
// Detect Windows platform
|
|
16
|
+
const isWindows = process.platform === 'win32';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Checks if a tool is available and returns its version
|
|
20
|
+
* Uses safe execution methods to avoid shell injection vulnerabilities
|
|
21
|
+
* @param {string} command - Command to check (e.g., 'git', 'node')
|
|
22
|
+
* @param {string} versionFlag - Flag to get version (default: '--version')
|
|
23
|
+
* @returns {Promise<Object>} { available: boolean, version: string|null }
|
|
24
|
+
*/
|
|
25
|
+
function checkTool(command, versionFlag = '--version') {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
// Validate command contains only safe characters (alphanumeric, underscore, hyphen)
|
|
28
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(command)) {
|
|
29
|
+
return resolve({ available: false, version: null });
|
|
30
|
+
}
|
|
31
|
+
// Validate versionFlag contains only safe characters
|
|
32
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(versionFlag)) {
|
|
33
|
+
return resolve({ available: false, version: null });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let child;
|
|
37
|
+
|
|
38
|
+
if (isWindows) {
|
|
39
|
+
// On Windows, spawn shell directly with command as single argument
|
|
40
|
+
child = spawn('cmd.exe', ['/c', command, versionFlag], {
|
|
41
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
42
|
+
windowsHide: true
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
// On Unix, spawn directly without shell
|
|
46
|
+
child = spawn(command, [versionFlag], {
|
|
47
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let stdout = '';
|
|
52
|
+
|
|
53
|
+
// Set timeout
|
|
54
|
+
const timeout = setTimeout(() => {
|
|
55
|
+
child.kill();
|
|
56
|
+
resolve({ available: false, version: null });
|
|
57
|
+
}, 5000);
|
|
58
|
+
|
|
59
|
+
child.stdout.on('data', (data) => {
|
|
60
|
+
try {
|
|
61
|
+
stdout += data.toString();
|
|
62
|
+
} catch {
|
|
63
|
+
// Ignore data conversion errors - will result in empty/partial version string
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
child.on('error', () => {
|
|
68
|
+
clearTimeout(timeout);
|
|
69
|
+
resolve({ available: false, version: null });
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
child.on('close', (code) => {
|
|
73
|
+
clearTimeout(timeout);
|
|
74
|
+
if (code !== 0) {
|
|
75
|
+
return resolve({ available: false, version: null });
|
|
76
|
+
}
|
|
77
|
+
const version = stdout.trim().split('\n')[0];
|
|
78
|
+
resolve({ available: true, version });
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Tool definitions with their version flags
|
|
85
|
+
*/
|
|
86
|
+
const TOOL_DEFINITIONS = [
|
|
87
|
+
// Version control
|
|
88
|
+
{ name: 'git', flag: '--version' },
|
|
89
|
+
{ name: 'gh', flag: '--version' },
|
|
90
|
+
|
|
91
|
+
// Node.js ecosystem
|
|
92
|
+
{ name: 'node', flag: '--version' },
|
|
93
|
+
{ name: 'npm', flag: '--version' },
|
|
94
|
+
{ name: 'pnpm', flag: '--version' },
|
|
95
|
+
{ name: 'yarn', flag: '--version' },
|
|
96
|
+
{ name: 'bun', flag: '--version' },
|
|
97
|
+
|
|
98
|
+
// Python ecosystem
|
|
99
|
+
{ name: 'python', flag: '--version' },
|
|
100
|
+
{ name: 'python3', flag: '--version' },
|
|
101
|
+
{ name: 'pip', flag: '--version' },
|
|
102
|
+
{ name: 'pip3', flag: '--version' },
|
|
103
|
+
{ name: 'poetry', flag: '--version' },
|
|
104
|
+
|
|
105
|
+
// Rust ecosystem
|
|
106
|
+
{ name: 'cargo', flag: '--version' },
|
|
107
|
+
{ name: 'rustc', flag: '--version' },
|
|
108
|
+
{ name: 'rustup', flag: '--version' },
|
|
109
|
+
|
|
110
|
+
// Go ecosystem
|
|
111
|
+
{ name: 'go', flag: 'version' },
|
|
112
|
+
|
|
113
|
+
// Java ecosystem
|
|
114
|
+
{ name: 'java', flag: '--version' },
|
|
115
|
+
{ name: 'javac', flag: '--version' },
|
|
116
|
+
{ name: 'mvn', flag: '--version' },
|
|
117
|
+
{ name: 'gradle', flag: '--version' },
|
|
118
|
+
|
|
119
|
+
// Containerization
|
|
120
|
+
{ name: 'docker', flag: '--version' },
|
|
121
|
+
|
|
122
|
+
// Deployment platforms
|
|
123
|
+
{ name: 'railway', flag: '--version' },
|
|
124
|
+
{ name: 'vercel', flag: '--version' },
|
|
125
|
+
{ name: 'netlify', flag: '--version' },
|
|
126
|
+
{ name: 'flyctl', flag: 'version' },
|
|
127
|
+
|
|
128
|
+
// CI/CD tools
|
|
129
|
+
{ name: 'circleci', flag: 'version' }
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Verifies all development tools (parallel execution)
|
|
134
|
+
* Runs all tool checks in parallel for fast execution
|
|
135
|
+
* @returns {Promise<Object>} Tool availability map
|
|
136
|
+
*/
|
|
137
|
+
async function verifyTools() {
|
|
138
|
+
try {
|
|
139
|
+
const results = await Promise.all(
|
|
140
|
+
TOOL_DEFINITIONS.map(tool => checkTool(tool.name, tool.flag))
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const toolMap = {};
|
|
144
|
+
TOOL_DEFINITIONS.forEach((tool, index) => {
|
|
145
|
+
toolMap[tool.name] = results[index];
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return toolMap;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
// Log error for debugging but return empty map for graceful degradation
|
|
151
|
+
console.error(`[WARN] Tool verification failed: ${error.message}`);
|
|
152
|
+
// Return all tools as unavailable rather than throwing
|
|
153
|
+
const toolMap = {};
|
|
154
|
+
TOOL_DEFINITIONS.forEach((tool) => {
|
|
155
|
+
toolMap[tool.name] = { available: false, version: null };
|
|
156
|
+
});
|
|
157
|
+
return toolMap;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// When run directly, output JSON
|
|
162
|
+
if (require.main === module) {
|
|
163
|
+
(async () => {
|
|
164
|
+
try {
|
|
165
|
+
const result = await verifyTools();
|
|
166
|
+
console.log(JSON.stringify(result, null, 2));
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error(JSON.stringify({
|
|
169
|
+
error: error.message,
|
|
170
|
+
timestamp: new Date().toISOString()
|
|
171
|
+
}, null, 2));
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
})();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Export for use as module
|
|
178
|
+
module.exports = {
|
|
179
|
+
verifyTools,
|
|
180
|
+
checkTool,
|
|
181
|
+
TOOL_DEFINITIONS
|
|
182
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo map cache management
|
|
3
|
+
*
|
|
4
|
+
* @module lib/repo-map/cache
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const { getStateDirPath } = require('../platform/state-dir');
|
|
12
|
+
const { writeJsonAtomic, writeFileAtomic } = require('../utils/atomic-write');
|
|
13
|
+
|
|
14
|
+
const MAP_FILENAME = 'repo-map.json';
|
|
15
|
+
const STALE_FILENAME = 'repo-map.stale';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get repo-map path
|
|
19
|
+
* @param {string} basePath - Repository root
|
|
20
|
+
* @returns {string}
|
|
21
|
+
*/
|
|
22
|
+
function getMapPath(basePath) {
|
|
23
|
+
return path.join(getStateDirPath(basePath), MAP_FILENAME);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get stale marker path
|
|
28
|
+
* @param {string} basePath - Repository root
|
|
29
|
+
* @returns {string}
|
|
30
|
+
*/
|
|
31
|
+
function getStalePath(basePath) {
|
|
32
|
+
return path.join(getStateDirPath(basePath), STALE_FILENAME);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Ensure state directory exists
|
|
37
|
+
* @param {string} basePath - Repository root
|
|
38
|
+
* @returns {string}
|
|
39
|
+
*/
|
|
40
|
+
function ensureStateDir(basePath) {
|
|
41
|
+
const stateDir = getStateDirPath(basePath);
|
|
42
|
+
if (!fs.existsSync(stateDir)) {
|
|
43
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
return stateDir;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Load repo-map from cache
|
|
50
|
+
* @param {string} basePath - Repository root
|
|
51
|
+
* @returns {Object|null}
|
|
52
|
+
*/
|
|
53
|
+
function load(basePath) {
|
|
54
|
+
const mapPath = getMapPath(basePath);
|
|
55
|
+
if (!fs.existsSync(mapPath)) return null;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const raw = fs.readFileSync(mapPath, 'utf8');
|
|
59
|
+
return JSON.parse(raw);
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Save repo-map to cache
|
|
67
|
+
* @param {string} basePath - Repository root
|
|
68
|
+
* @param {Object} map - Map object
|
|
69
|
+
*/
|
|
70
|
+
function save(basePath, map) {
|
|
71
|
+
ensureStateDir(basePath);
|
|
72
|
+
const mapPath = getMapPath(basePath);
|
|
73
|
+
|
|
74
|
+
const output = {
|
|
75
|
+
...map,
|
|
76
|
+
updated: new Date().toISOString()
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
writeJsonAtomic(mapPath, output);
|
|
80
|
+
|
|
81
|
+
// Clear stale marker if present
|
|
82
|
+
clearStale(basePath);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Check if repo-map exists
|
|
87
|
+
* @param {string} basePath - Repository root
|
|
88
|
+
* @returns {boolean}
|
|
89
|
+
*/
|
|
90
|
+
function exists(basePath) {
|
|
91
|
+
return fs.existsSync(getMapPath(basePath));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Mark repo-map as stale
|
|
96
|
+
* @param {string} basePath - Repository root
|
|
97
|
+
*/
|
|
98
|
+
function markStale(basePath) {
|
|
99
|
+
ensureStateDir(basePath);
|
|
100
|
+
writeFileAtomic(getStalePath(basePath), new Date().toISOString());
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Clear stale marker
|
|
105
|
+
* @param {string} basePath - Repository root
|
|
106
|
+
*/
|
|
107
|
+
function clearStale(basePath) {
|
|
108
|
+
const stalePath = getStalePath(basePath);
|
|
109
|
+
if (fs.existsSync(stalePath)) {
|
|
110
|
+
fs.unlinkSync(stalePath);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Check if stale marker exists
|
|
116
|
+
* @param {string} basePath - Repository root
|
|
117
|
+
* @returns {boolean}
|
|
118
|
+
*/
|
|
119
|
+
function isMarkedStale(basePath) {
|
|
120
|
+
return fs.existsSync(getStalePath(basePath));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Get basic status summary
|
|
125
|
+
* @param {string} basePath - Repository root
|
|
126
|
+
* @returns {Object|null}
|
|
127
|
+
*/
|
|
128
|
+
function getStatus(basePath) {
|
|
129
|
+
const map = load(basePath);
|
|
130
|
+
if (!map) return null;
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
generated: map.generated,
|
|
134
|
+
updated: map.updated,
|
|
135
|
+
commit: map.git?.commit,
|
|
136
|
+
branch: map.git?.branch,
|
|
137
|
+
files: Object.keys(map.files || {}).length,
|
|
138
|
+
symbols: map.stats?.totalSymbols || 0,
|
|
139
|
+
languages: map.project?.languages || []
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = {
|
|
144
|
+
load,
|
|
145
|
+
save,
|
|
146
|
+
exists,
|
|
147
|
+
getStatus,
|
|
148
|
+
getMapPath,
|
|
149
|
+
markStale,
|
|
150
|
+
clearStale,
|
|
151
|
+
isMarkedStale
|
|
152
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
async function runWithConcurrency(items, limit, worker) {
|
|
4
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
5
|
+
return [];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const maxConcurrency = Math.max(1, Math.min(items.length, Math.floor(limit) || 1));
|
|
9
|
+
const results = new Array(items.length);
|
|
10
|
+
let cursor = 0;
|
|
11
|
+
|
|
12
|
+
async function runWorker() {
|
|
13
|
+
while (true) {
|
|
14
|
+
const index = cursor;
|
|
15
|
+
cursor += 1;
|
|
16
|
+
if (index >= items.length) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
results[index] = await worker(items[index], index);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
await Promise.all(Array.from({ length: maxConcurrency }, () => runWorker()));
|
|
24
|
+
return results;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
runWithConcurrency
|
|
29
|
+
};
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo Map - AST-based repository symbol mapping
|
|
3
|
+
*
|
|
4
|
+
* Uses ast-grep (sg) for accurate symbol extraction across multiple languages.
|
|
5
|
+
* Generates a cached map of exports, functions, classes, and imports.
|
|
6
|
+
*
|
|
7
|
+
* @module lib/repo-map
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const installer = require('./installer');
|
|
13
|
+
const runner = require('./runner');
|
|
14
|
+
const cache = require('./cache');
|
|
15
|
+
const updater = require('./updater');
|
|
16
|
+
const usageAnalyzer = require('./usage-analyzer');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Initialize a new repo map (full scan)
|
|
20
|
+
* @param {string} basePath - Repository root path
|
|
21
|
+
* @param {Object} options - Options
|
|
22
|
+
* @param {boolean} options.force - Force rebuild even if map exists
|
|
23
|
+
* @param {string[]} options.languages - Languages to scan (auto-detect if not specified)
|
|
24
|
+
* @returns {Promise<{success: boolean, map?: Object, error?: string}>}
|
|
25
|
+
*/
|
|
26
|
+
async function init(basePath, options = {}) {
|
|
27
|
+
// Check if ast-grep is installed
|
|
28
|
+
const installed = await installer.checkInstalled();
|
|
29
|
+
if (!installed.found) {
|
|
30
|
+
return {
|
|
31
|
+
success: false,
|
|
32
|
+
error: 'ast-grep not found',
|
|
33
|
+
installSuggestion: installer.getInstallInstructions()
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!installer.meetsMinimumVersion(installed.version)) {
|
|
38
|
+
return {
|
|
39
|
+
success: false,
|
|
40
|
+
error: `ast-grep version ${installed.version || 'unknown'} is too old. Minimum required: ${installer.getMinimumVersion()}`,
|
|
41
|
+
installSuggestion: installer.getInstallInstructions()
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Check if map already exists
|
|
46
|
+
const existing = cache.load(basePath);
|
|
47
|
+
if (existing && !options.force) {
|
|
48
|
+
return {
|
|
49
|
+
success: false,
|
|
50
|
+
error: 'Repo map already exists. Use --force to rebuild or /repo-map update to refresh.',
|
|
51
|
+
existing: cache.getStatus(basePath)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Detect languages in the project
|
|
56
|
+
const languages = options.languages || await runner.detectLanguages(basePath);
|
|
57
|
+
if (languages.length === 0) {
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
error: 'No supported languages detected in repository'
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Run full scan
|
|
65
|
+
const startTime = Date.now();
|
|
66
|
+
const map = await runner.fullScan(basePath, languages, {
|
|
67
|
+
fileLimit: options.fileLimit
|
|
68
|
+
});
|
|
69
|
+
map.stats.scanDurationMs = Date.now() - startTime;
|
|
70
|
+
|
|
71
|
+
// Save map
|
|
72
|
+
cache.save(basePath, map);
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
success: true,
|
|
76
|
+
map,
|
|
77
|
+
summary: {
|
|
78
|
+
files: Object.keys(map.files).length,
|
|
79
|
+
symbols: map.stats.totalSymbols,
|
|
80
|
+
languages: map.project.languages,
|
|
81
|
+
duration: map.stats.scanDurationMs
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Update an existing repo map (incremental)
|
|
88
|
+
* @param {string} basePath - Repository root path
|
|
89
|
+
* @param {Object} options - Options
|
|
90
|
+
* @param {boolean} options.full - Force full rebuild instead of incremental
|
|
91
|
+
* @returns {Promise<{success: boolean, changes?: Object, error?: string}>}
|
|
92
|
+
*/
|
|
93
|
+
async function update(basePath, options = {}) {
|
|
94
|
+
// Check if ast-grep is installed
|
|
95
|
+
const installed = await installer.checkInstalled();
|
|
96
|
+
if (!installed.found) {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
error: 'ast-grep not found',
|
|
100
|
+
installSuggestion: installer.getInstallInstructions()
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!installer.meetsMinimumVersion(installed.version)) {
|
|
105
|
+
return {
|
|
106
|
+
success: false,
|
|
107
|
+
error: `ast-grep version ${installed.version || 'unknown'} is too old. Minimum required: ${installer.getMinimumVersion()}`,
|
|
108
|
+
installSuggestion: installer.getInstallInstructions()
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Load existing map
|
|
113
|
+
const existing = cache.load(basePath);
|
|
114
|
+
if (!existing) {
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
error: 'No repo map found. Run /repo-map init first.'
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Force full rebuild if requested
|
|
122
|
+
if (options.full) {
|
|
123
|
+
return init(basePath, { force: true });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Incremental update
|
|
127
|
+
const result = await updater.incrementalUpdate(basePath, existing);
|
|
128
|
+
|
|
129
|
+
if (result.success) {
|
|
130
|
+
cache.save(basePath, result.map);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get repo map status
|
|
138
|
+
* @param {string} basePath - Repository root path
|
|
139
|
+
* @returns {{exists: boolean, status?: Object}}
|
|
140
|
+
*/
|
|
141
|
+
function status(basePath) {
|
|
142
|
+
const map = cache.load(basePath);
|
|
143
|
+
if (!map) {
|
|
144
|
+
return { exists: false };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const staleness = updater.checkStaleness(basePath, map);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
exists: true,
|
|
151
|
+
status: {
|
|
152
|
+
generated: map.generated,
|
|
153
|
+
updated: map.updated,
|
|
154
|
+
commit: map.git?.commit,
|
|
155
|
+
branch: map.git?.branch,
|
|
156
|
+
files: Object.keys(map.files).length,
|
|
157
|
+
symbols: map.stats?.totalSymbols || 0,
|
|
158
|
+
languages: map.project?.languages || [],
|
|
159
|
+
staleness
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Load repo map (if exists)
|
|
166
|
+
* @param {string} basePath - Repository root path
|
|
167
|
+
* @returns {Object|null} - The map or null if not found
|
|
168
|
+
*/
|
|
169
|
+
function load(basePath) {
|
|
170
|
+
return cache.load(basePath);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Check if ast-grep is installed
|
|
175
|
+
* @returns {Promise<{found: boolean, version?: string, path?: string}>}
|
|
176
|
+
*/
|
|
177
|
+
async function checkAstGrepInstalled() {
|
|
178
|
+
return installer.checkInstalled();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get install instructions for ast-grep
|
|
183
|
+
* @returns {string}
|
|
184
|
+
*/
|
|
185
|
+
function getInstallInstructions() {
|
|
186
|
+
return installer.getInstallInstructions();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Check if repo map exists
|
|
191
|
+
* @param {string} basePath - Repository root path
|
|
192
|
+
* @returns {boolean}
|
|
193
|
+
*/
|
|
194
|
+
function exists(basePath) {
|
|
195
|
+
return cache.exists(basePath);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
module.exports = {
|
|
199
|
+
init,
|
|
200
|
+
update,
|
|
201
|
+
status,
|
|
202
|
+
load,
|
|
203
|
+
exists,
|
|
204
|
+
checkAstGrepInstalled,
|
|
205
|
+
getInstallInstructions,
|
|
206
|
+
|
|
207
|
+
// Usage analysis functions
|
|
208
|
+
buildUsageIndex: usageAnalyzer.buildUsageIndex,
|
|
209
|
+
findUsages: usageAnalyzer.findUsages,
|
|
210
|
+
findDependents: usageAnalyzer.findDependents,
|
|
211
|
+
findUnusedExports: usageAnalyzer.findUnusedExports,
|
|
212
|
+
findOrphanedInfrastructure: usageAnalyzer.findOrphanedInfrastructure,
|
|
213
|
+
getDependencyGraph: usageAnalyzer.getDependencyGraph,
|
|
214
|
+
findCircularDependencies: usageAnalyzer.findCircularDependencies,
|
|
215
|
+
|
|
216
|
+
// Re-export submodules for advanced usage
|
|
217
|
+
installer,
|
|
218
|
+
runner,
|
|
219
|
+
cache,
|
|
220
|
+
updater,
|
|
221
|
+
usageAnalyzer
|
|
222
|
+
};
|