agentsys 5.3.0 → 5.3.2
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 +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor/commands/audit-project-agents.md +454 -0
- package/.cursor/commands/audit-project-github.md +141 -0
- package/.cursor/commands/audit-project.md +330 -0
- package/.cursor/commands/consult.md +417 -0
- package/.cursor/commands/debate.md +381 -0
- package/.cursor/commands/delivery-approval.md +334 -0
- package/.cursor/commands/deslop.md +142 -0
- package/.cursor/commands/drift-detect.md +259 -0
- package/.cursor/commands/enhance.md +172 -0
- package/.cursor/commands/learn.md +165 -0
- package/.cursor/commands/next-task.md +519 -0
- package/.cursor/commands/perf.md +464 -0
- package/.cursor/commands/repo-map.md +124 -0
- package/.cursor/commands/ship-ci-review-loop.md +468 -0
- package/.cursor/commands/ship-deployment.md +348 -0
- package/.cursor/commands/ship-error-handling.md +265 -0
- package/.cursor/commands/ship.md +517 -0
- package/.cursor/commands/sync-docs.md +171 -0
- package/.cursor/commands/web-ctl.md +101 -0
- package/.cursor/skills/consult/SKILL.md +425 -0
- package/.cursor/skills/debate/SKILL.md +316 -0
- package/.cursor/skills/deslop/SKILL.md +204 -0
- package/.cursor/skills/discover-tasks/SKILL.md +297 -0
- package/.cursor/skills/drift-analysis/SKILL.md +324 -0
- package/.cursor/skills/enhance-agent-prompts/SKILL.md +277 -0
- package/.cursor/skills/enhance-claude-memory/SKILL.md +387 -0
- package/.cursor/skills/enhance-cross-file/SKILL.md +110 -0
- package/.cursor/skills/enhance-docs/SKILL.md +298 -0
- package/.cursor/skills/enhance-hooks/SKILL.md +554 -0
- package/.cursor/skills/enhance-orchestrator/SKILL.md +255 -0
- package/.cursor/skills/enhance-plugins/SKILL.md +319 -0
- package/.cursor/skills/enhance-prompts/SKILL.md +340 -0
- package/.cursor/skills/enhance-skills/SKILL.md +436 -0
- package/.cursor/skills/learn/SKILL.md +349 -0
- package/.cursor/skills/orchestrate-review/SKILL.md +260 -0
- package/.cursor/skills/perf-analyzer/SKILL.md +37 -0
- package/.cursor/skills/perf-baseline-manager/SKILL.md +30 -0
- package/.cursor/skills/perf-benchmarker/SKILL.md +52 -0
- package/.cursor/skills/perf-code-paths/SKILL.md +32 -0
- package/.cursor/skills/perf-investigation-logger/SKILL.md +41 -0
- package/.cursor/skills/perf-profiler/SKILL.md +42 -0
- package/.cursor/skills/perf-theory-gatherer/SKILL.md +35 -0
- package/.cursor/skills/perf-theory-tester/SKILL.md +36 -0
- package/.cursor/skills/repo-mapping/SKILL.md +83 -0
- package/.cursor/skills/sync-docs/SKILL.md +351 -0
- package/.cursor/skills/validate-delivery/SKILL.md +186 -0
- package/.cursor/skills/web-auth/SKILL.md +177 -0
- package/.cursor/skills/web-browse/SKILL.md +516 -0
- package/.kiro/agents/agent-enhancer.json +12 -0
- package/.kiro/agents/ci-fixer.json +13 -0
- package/.kiro/agents/ci-monitor.json +12 -0
- package/.kiro/agents/claudemd-enhancer.json +12 -0
- package/.kiro/agents/consult-agent.json +13 -0
- package/.kiro/agents/cross-file-enhancer.json +12 -0
- package/.kiro/agents/debate-orchestrator.json +13 -0
- package/.kiro/agents/delivery-validator.json +12 -0
- package/.kiro/agents/deslop-agent.json +12 -0
- package/.kiro/agents/docs-enhancer.json +12 -0
- package/.kiro/agents/exploration-agent.json +12 -0
- package/.kiro/agents/hooks-enhancer.json +11 -0
- package/.kiro/agents/implementation-agent.json +13 -0
- package/.kiro/agents/learn-agent.json +12 -0
- package/.kiro/agents/map-validator.json +11 -0
- package/.kiro/agents/perf-analyzer.json +12 -0
- package/.kiro/agents/perf-code-paths.json +11 -0
- package/.kiro/agents/perf-investigation-logger.json +12 -0
- package/.kiro/agents/perf-orchestrator.json +13 -0
- package/.kiro/agents/perf-theory-gatherer.json +12 -0
- package/.kiro/agents/perf-theory-tester.json +13 -0
- package/.kiro/agents/plan-synthesizer.json +12 -0
- package/.kiro/agents/planning-agent.json +12 -0
- package/.kiro/agents/plugin-enhancer.json +12 -0
- package/.kiro/agents/prompt-enhancer.json +12 -0
- package/.kiro/agents/reviewer-perf-test.json +11 -0
- package/.kiro/agents/reviewer-quality-security.json +11 -0
- package/.kiro/agents/simple-fixer.json +13 -0
- package/.kiro/agents/skills-enhancer.json +11 -0
- package/.kiro/agents/sync-docs-agent.json +13 -0
- package/.kiro/agents/task-discoverer.json +12 -0
- package/.kiro/agents/test-coverage-checker.json +12 -0
- package/.kiro/agents/web-session.json +12 -0
- package/.kiro/agents/worktree-manager.json +13 -0
- package/.kiro/skills/consult/SKILL.md +425 -0
- package/.kiro/skills/debate/SKILL.md +316 -0
- package/.kiro/skills/deslop/SKILL.md +204 -0
- package/.kiro/skills/discover-tasks/SKILL.md +297 -0
- package/.kiro/skills/drift-analysis/SKILL.md +324 -0
- package/.kiro/skills/enhance-agent-prompts/SKILL.md +277 -0
- package/.kiro/skills/enhance-claude-memory/SKILL.md +387 -0
- package/.kiro/skills/enhance-cross-file/SKILL.md +110 -0
- package/.kiro/skills/enhance-docs/SKILL.md +298 -0
- package/.kiro/skills/enhance-hooks/SKILL.md +554 -0
- package/.kiro/skills/enhance-orchestrator/SKILL.md +255 -0
- package/.kiro/skills/enhance-plugins/SKILL.md +319 -0
- package/.kiro/skills/enhance-prompts/SKILL.md +340 -0
- package/.kiro/skills/enhance-skills/SKILL.md +436 -0
- package/.kiro/skills/learn/SKILL.md +349 -0
- package/.kiro/skills/orchestrate-review/SKILL.md +260 -0
- package/.kiro/skills/perf-analyzer/SKILL.md +37 -0
- package/.kiro/skills/perf-baseline-manager/SKILL.md +30 -0
- package/.kiro/skills/perf-benchmarker/SKILL.md +52 -0
- package/.kiro/skills/perf-code-paths/SKILL.md +32 -0
- package/.kiro/skills/perf-investigation-logger/SKILL.md +41 -0
- package/.kiro/skills/perf-profiler/SKILL.md +42 -0
- package/.kiro/skills/perf-theory-gatherer/SKILL.md +35 -0
- package/.kiro/skills/perf-theory-tester/SKILL.md +36 -0
- package/.kiro/skills/repo-mapping/SKILL.md +83 -0
- package/.kiro/skills/sync-docs/SKILL.md +351 -0
- package/.kiro/skills/validate-delivery/SKILL.md +186 -0
- package/.kiro/skills/web-auth/SKILL.md +177 -0
- package/.kiro/skills/web-browse/SKILL.md +516 -0
- package/.kiro/steering/audit-project-agents.md +459 -0
- package/.kiro/steering/audit-project-github.md +146 -0
- package/.kiro/steering/audit-project.md +330 -0
- package/.kiro/steering/consult.md +422 -0
- package/.kiro/steering/debate.md +386 -0
- package/.kiro/steering/delivery-approval.md +339 -0
- package/.kiro/steering/deslop.md +149 -0
- package/.kiro/steering/drift-detect.md +264 -0
- package/.kiro/steering/enhance.md +177 -0
- package/.kiro/steering/learn.md +166 -0
- package/.kiro/steering/next-task.md +481 -0
- package/.kiro/steering/perf.md +469 -0
- package/.kiro/steering/repo-map.md +126 -0
- package/.kiro/steering/ship-ci-review-loop.md +473 -0
- package/.kiro/steering/ship-deployment.md +353 -0
- package/.kiro/steering/ship-error-handling.md +270 -0
- package/.kiro/steering/ship.md +522 -0
- package/.kiro/steering/sync-docs.md +178 -0
- package/.kiro/steering/web-ctl.md +106 -0
- package/CHANGELOG.md +15 -0
- package/bin/cli.js +2 -2
- package/lib/adapter-transforms.js +34 -2
- package/package.json +1 -1
- package/site/content.json +1 -1
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: manual
|
|
3
|
+
name: "perf"
|
|
4
|
+
description: "Use when user asks to \"run perf\", \"performance investigation\", \"benchmark regression\", \"profiling workflow\", \"baseline performance\". Runs structured perf investigations with baselines, profiling, hypotheses, and decisions."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /perf - Performance Investigation Workflow
|
|
8
|
+
|
|
9
|
+
Run a rigorous, evidence-driven performance investigation with strict rules, baselines, and reproducible benchmarks.
|
|
10
|
+
|
|
11
|
+
## Canonical Requirements
|
|
12
|
+
|
|
13
|
+
All behavior must follow:
|
|
14
|
+
- `docs/perf-requirements.md` (source of truth)
|
|
15
|
+
- `docs/perf-research-methodology.md`
|
|
16
|
+
|
|
17
|
+
## Arguments
|
|
18
|
+
|
|
19
|
+
- `--resume`: Continue the latest investigation from `{state-dir}/perf/investigation.json`
|
|
20
|
+
- `--phase <phase>`: Force starting phase (use only when resuming)
|
|
21
|
+
- `--id <id>`: Set investigation id (new only)
|
|
22
|
+
- `--scenario <text>`: Short scenario description
|
|
23
|
+
- `--command <cmd>`: Benchmark command (prints PERF_METRICS markers)
|
|
24
|
+
- `--version <ver>`: Baseline version label
|
|
25
|
+
- `--duration <seconds>`: Benchmark duration override (default 60s; use smaller values for micro-benchmarks)
|
|
26
|
+
- `--runs <n>`: Number of runs for start-to-end benchmarks (use with median aggregation)
|
|
27
|
+
- `--aggregate <median|mean|min|max>`: Aggregation method for multi-run benchmarks (default median)
|
|
28
|
+
- `--quote <text>`: User quote to record in logs
|
|
29
|
+
- `--hypotheses-file <path>`: JSON file with hypothesis list (for hypotheses phase)
|
|
30
|
+
- `--param-env <name>`: Env var for breaking-point value (default PERF_PARAM_VALUE)
|
|
31
|
+
- `--param-min <n>`: Breaking-point min value (default 1)
|
|
32
|
+
- `--param-max <n>`: Breaking-point max value (default 500)
|
|
33
|
+
- `--cpu <limit>`: Constraint CPU limit (default 1)
|
|
34
|
+
- `--memory <limit>`: Constraint memory limit (default 1GB)
|
|
35
|
+
- `--change <summary>`: Optimization change summary
|
|
36
|
+
- `--verdict <continue|stop>`: Decision verdict
|
|
37
|
+
- `--rationale <text>`: Decision rationale
|
|
38
|
+
|
|
39
|
+
## Phase 1: Initialize Investigation State
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
|
|
43
|
+
const pluginRoot = getPluginRoot('perf');
|
|
44
|
+
if (!pluginRoot) { console.error('Error: Could not locate perf plugin root'); process.exit(1); }
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
const args = argumentParser.parseArguments('$ARGUMENTS');
|
|
60
|
+
const options = {
|
|
61
|
+
resume: false,
|
|
62
|
+
phase: null,
|
|
63
|
+
id: null,
|
|
64
|
+
scenario: '',
|
|
65
|
+
command: '',
|
|
66
|
+
version: '',
|
|
67
|
+
duration: null,
|
|
68
|
+
runs: null,
|
|
69
|
+
aggregate: '',
|
|
70
|
+
quote: '',
|
|
71
|
+
hypothesesFile: '',
|
|
72
|
+
paramEnv: 'PERF_PARAM_VALUE',
|
|
73
|
+
paramMin: 1,
|
|
74
|
+
paramMax: 500,
|
|
75
|
+
cpu: '1',
|
|
76
|
+
memory: '1GB',
|
|
77
|
+
change: '',
|
|
78
|
+
verdict: '',
|
|
79
|
+
rationale: ''
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < args.length; i++) {
|
|
83
|
+
const arg = args[i];
|
|
84
|
+
if (arg === '--resume') options.resume = true;
|
|
85
|
+
else if (arg === '--phase' && args[i + 1]) options.phase = args[++i];
|
|
86
|
+
else if (arg === '--id' && args[i + 1]) options.id = args[++i];
|
|
87
|
+
else if (arg === '--scenario' && args[i + 1]) options.scenario = args[++i];
|
|
88
|
+
else if (arg === '--command' && args[i + 1]) options.command = args[++i];
|
|
89
|
+
else if (arg === '--version' && args[i + 1]) options.version = args[++i];
|
|
90
|
+
else if (arg === '--duration' && args[i + 1]) options.duration = Number(args[++i]);
|
|
91
|
+
else if (arg === '--runs' && args[i + 1]) options.runs = Number(args[++i]);
|
|
92
|
+
else if (arg === '--aggregate' && args[i + 1]) options.aggregate = args[++i];
|
|
93
|
+
else if (arg === '--quote' && args[i + 1]) options.quote = args[++i];
|
|
94
|
+
else if (arg === '--hypotheses-file' && args[i + 1]) options.hypothesesFile = args[++i];
|
|
95
|
+
else if (arg === '--param-env' && args[i + 1]) options.paramEnv = args[++i];
|
|
96
|
+
else if (arg === '--param-min' && args[i + 1]) options.paramMin = Number(args[++i]);
|
|
97
|
+
else if (arg === '--param-max' && args[i + 1]) options.paramMax = Number(args[++i]);
|
|
98
|
+
else if (arg === '--cpu' && args[i + 1]) options.cpu = args[++i];
|
|
99
|
+
else if (arg === '--memory' && args[i + 1]) options.memory = args[++i];
|
|
100
|
+
else if (arg === '--change' && args[i + 1]) options.change = args[++i];
|
|
101
|
+
else if (arg === '--verdict' && args[i + 1]) options.verdict = args[++i];
|
|
102
|
+
else if (arg === '--rationale' && args[i + 1]) options.rationale = args[++i];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const cwd = process.cwd();
|
|
106
|
+
const allowedPhases = investigationState.PHASES;
|
|
107
|
+
if (options.phase && !allowedPhases.includes(options.phase)) {
|
|
108
|
+
console.error(`Invalid phase: ${options.phase}. Allowed: ${allowedPhases.join(', ')}`);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let state = investigationState.readInvestigation(cwd);
|
|
113
|
+
if (options.resume) {
|
|
114
|
+
if (!state) {
|
|
115
|
+
console.error('No active investigation found. Run /perf without --resume first.');
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
state = investigationState.initializeInvestigation({
|
|
120
|
+
id: options.id,
|
|
121
|
+
phase: options.phase,
|
|
122
|
+
scenario: options.scenario
|
|
123
|
+
}, cwd);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (options.phase && options.resume) {
|
|
127
|
+
state = investigationState.updateInvestigation({ phase: options.phase }, cwd);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const userQuote = options.quote || options.scenario || 'n/a';
|
|
131
|
+
if (options.command || options.version || options.scenario) {
|
|
132
|
+
state = investigationState.updateInvestigation({
|
|
133
|
+
scenario: {
|
|
134
|
+
description: options.scenario || state.scenario?.description || '',
|
|
135
|
+
metrics: state.scenario?.metrics || [],
|
|
136
|
+
successCriteria: state.scenario?.successCriteria || '',
|
|
137
|
+
scenarios: state.scenario?.scenarios || []
|
|
138
|
+
},
|
|
139
|
+
benchmark: {
|
|
140
|
+
command: options.command || state.benchmark?.command || '',
|
|
141
|
+
version: options.version || state.benchmark?.version || '',
|
|
142
|
+
duration: Number.isFinite(options.duration) ? options.duration : state.benchmark?.duration,
|
|
143
|
+
runs: Number.isFinite(options.runs) ? options.runs : state.benchmark?.runs,
|
|
144
|
+
aggregate: options.aggregate || state.benchmark?.aggregate
|
|
145
|
+
}
|
|
146
|
+
}, cwd);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log(`
|
|
150
|
+
## /perf Investigation
|
|
151
|
+
|
|
152
|
+
**ID**: ${state.id}
|
|
153
|
+
**Phase**: ${state.phase}
|
|
154
|
+
**Scenario**: ${state.scenario?.description || 'n/a'}
|
|
155
|
+
|
|
156
|
+
Running phase handler...
|
|
157
|
+
`);
|
|
158
|
+
|
|
159
|
+
const phase = state.phase;
|
|
160
|
+
const command = state.benchmark?.command || options.command;
|
|
161
|
+
const version = state.benchmark?.version || options.version;
|
|
162
|
+
|
|
163
|
+
function requireFields(fields) {
|
|
164
|
+
const missing = fields.filter(Boolean);
|
|
165
|
+
if (missing.length > 0) {
|
|
166
|
+
console.error(`Missing required input(s): ${missing.join(', ')}`);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const phaseRequirements = {
|
|
172
|
+
setup: () => requireFields([
|
|
173
|
+
state.scenario?.description ? '' : '--scenario',
|
|
174
|
+
command ? '' : '--command',
|
|
175
|
+
version ? '' : '--version'
|
|
176
|
+
]),
|
|
177
|
+
baseline: () => requireFields([command ? '' : '--command', version ? '' : '--version']),
|
|
178
|
+
'breaking-point': () => requireFields([command ? '' : '--command']),
|
|
179
|
+
constraints: () => requireFields([command ? '' : '--command']),
|
|
180
|
+
hypotheses: () => requireFields([state.scenario?.description ? '' : '--scenario']),
|
|
181
|
+
'code-paths': () => requireFields([state.scenario?.description ? '' : '--scenario']),
|
|
182
|
+
profiling: () => requireFields([]),
|
|
183
|
+
optimization: () => requireFields([options.change ? '' : '--change']),
|
|
184
|
+
decision: () => requireFields([options.verdict ? '' : '--verdict', options.rationale ? '' : '--rationale']),
|
|
185
|
+
consolidation: () => requireFields([version ? '' : '--version'])
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
async function runPhase() {
|
|
189
|
+
if (phaseRequirements[phase]) {
|
|
190
|
+
phaseRequirements[phase]();
|
|
191
|
+
}
|
|
192
|
+
switch (phase) {
|
|
193
|
+
case 'setup': {
|
|
194
|
+
state = investigationState.updateInvestigation({ phase: 'baseline' }, cwd);
|
|
195
|
+
investigationState.appendSetupLog({
|
|
196
|
+
id: state.id,
|
|
197
|
+
userQuote,
|
|
198
|
+
scenario: state.scenario?.description || '',
|
|
199
|
+
command,
|
|
200
|
+
version,
|
|
201
|
+
duration: Number.isFinite(options.duration) ? options.duration : state.benchmark?.duration,
|
|
202
|
+
runs: Number.isFinite(options.runs) ? options.runs : state.benchmark?.runs,
|
|
203
|
+
aggregate: options.aggregate || state.benchmark?.aggregate
|
|
204
|
+
}, cwd);
|
|
205
|
+
checkpoint.commitCheckpoint({
|
|
206
|
+
phase: 'setup',
|
|
207
|
+
id: state.id,
|
|
208
|
+
baselineVersion: version,
|
|
209
|
+
deltaSummary: 'n/a'
|
|
210
|
+
});
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
case 'baseline': {
|
|
214
|
+
const runs = Number.isFinite(options.runs) ? options.runs : state.benchmark?.runs;
|
|
215
|
+
const aggregate = options.aggregate || state.benchmark?.aggregate;
|
|
216
|
+
const result = benchmarkRunner.runBenchmarkSeries(command, {
|
|
217
|
+
duration: Number.isFinite(options.duration) ? options.duration : undefined,
|
|
218
|
+
runs,
|
|
219
|
+
aggregate
|
|
220
|
+
});
|
|
221
|
+
baselineStore.writeBaseline(version, { command, metrics: result.metrics }, cwd);
|
|
222
|
+
const baselinePath = baselineStore.getBaselinePath(version, cwd);
|
|
223
|
+
investigationState.appendBaselineLog({
|
|
224
|
+
id: state.id,
|
|
225
|
+
userQuote,
|
|
226
|
+
command,
|
|
227
|
+
metrics: result.metrics,
|
|
228
|
+
baselinePath,
|
|
229
|
+
duration: Number.isFinite(options.duration) ? options.duration : state.benchmark?.duration,
|
|
230
|
+
runs,
|
|
231
|
+
aggregate: aggregate || (runs ? 'median' : undefined),
|
|
232
|
+
scenarios: state.scenario?.scenarios
|
|
233
|
+
}, cwd);
|
|
234
|
+
state = investigationState.updateInvestigation({ phase: 'breaking-point' }, cwd);
|
|
235
|
+
checkpoint.commitCheckpoint({
|
|
236
|
+
phase: 'baseline',
|
|
237
|
+
id: state.id,
|
|
238
|
+
baselineVersion: version,
|
|
239
|
+
deltaSummary: 'n/a'
|
|
240
|
+
});
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
case 'breaking-point': {
|
|
244
|
+
const result = await breakingPointRunner.runBreakingPointSearch({
|
|
245
|
+
command,
|
|
246
|
+
paramEnv: options.paramEnv,
|
|
247
|
+
min: options.paramMin,
|
|
248
|
+
max: options.paramMax
|
|
249
|
+
});
|
|
250
|
+
investigationState.updateInvestigation({
|
|
251
|
+
breakingPoint: result.breakingPoint,
|
|
252
|
+
breakingPointHistory: result.history,
|
|
253
|
+
phase: 'constraints'
|
|
254
|
+
}, cwd);
|
|
255
|
+
investigationState.appendBreakingPointLog({
|
|
256
|
+
id: state.id,
|
|
257
|
+
userQuote,
|
|
258
|
+
paramEnv: options.paramEnv,
|
|
259
|
+
min: options.paramMin,
|
|
260
|
+
max: options.paramMax,
|
|
261
|
+
breakingPoint: result.breakingPoint,
|
|
262
|
+
history: result.history
|
|
263
|
+
}, cwd);
|
|
264
|
+
checkpoint.commitCheckpoint({
|
|
265
|
+
phase: 'breaking-point',
|
|
266
|
+
id: state.id,
|
|
267
|
+
baselineVersion: version || 'n/a',
|
|
268
|
+
deltaSummary: `breakingPoint=${result.breakingPoint ?? 'n/a'}`
|
|
269
|
+
});
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
case 'constraints': {
|
|
273
|
+
const runs = Number.isFinite(options.runs) ? options.runs : state.benchmark?.runs;
|
|
274
|
+
const aggregate = options.aggregate || state.benchmark?.aggregate;
|
|
275
|
+
const results = constraintRunner.runConstraintTest({
|
|
276
|
+
command,
|
|
277
|
+
constraints: { cpu: options.cpu, memory: options.memory },
|
|
278
|
+
duration: Number.isFinite(options.duration) ? options.duration : undefined,
|
|
279
|
+
runs,
|
|
280
|
+
aggregate
|
|
281
|
+
});
|
|
282
|
+
const nextResults = Array.isArray(state.constraintResults) ? state.constraintResults : [];
|
|
283
|
+
nextResults.push(results);
|
|
284
|
+
investigationState.updateInvestigation({ constraintResults: nextResults, phase: 'hypotheses' }, cwd);
|
|
285
|
+
investigationState.appendConstraintLog({
|
|
286
|
+
id: state.id,
|
|
287
|
+
userQuote,
|
|
288
|
+
constraints: results.constraints,
|
|
289
|
+
delta: results.delta
|
|
290
|
+
}, cwd);
|
|
291
|
+
checkpoint.commitCheckpoint({
|
|
292
|
+
phase: 'constraints',
|
|
293
|
+
id: state.id,
|
|
294
|
+
baselineVersion: version || 'n/a',
|
|
295
|
+
deltaSummary: 'constraints'
|
|
296
|
+
});
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
case 'hypotheses': {
|
|
300
|
+
const gitHistory = checkpoint.getRecentCommits(5);
|
|
301
|
+
let hypotheses = Array.isArray(state.hypotheses) ? state.hypotheses : [];
|
|
302
|
+
if (hypotheses.length === 0) {
|
|
303
|
+
if (!options.hypothesesFile) {
|
|
304
|
+
console.error('Missing hypotheses. Run perf-theory-gatherer or provide --hypotheses-file.');
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
const raw = fs.readFileSync(options.hypothesesFile, 'utf8');
|
|
309
|
+
const parsed = JSON.parse(raw);
|
|
310
|
+
hypotheses = Array.isArray(parsed.hypotheses) ? parsed.hypotheses : parsed;
|
|
311
|
+
} catch (error) {
|
|
312
|
+
console.error(`Failed to load hypotheses file: ${error.message}`);
|
|
313
|
+
process.exit(1);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
investigationState.updateInvestigation({ hypotheses, phase: 'code-paths' }, cwd);
|
|
317
|
+
investigationState.appendHypothesesLog({
|
|
318
|
+
id: state.id,
|
|
319
|
+
userQuote,
|
|
320
|
+
hypotheses,
|
|
321
|
+
gitHistory,
|
|
322
|
+
hypothesesFile: options.hypothesesFile || null
|
|
323
|
+
}, cwd);
|
|
324
|
+
checkpoint.commitCheckpoint({
|
|
325
|
+
phase: 'hypotheses',
|
|
326
|
+
id: state.id,
|
|
327
|
+
baselineVersion: version || 'n/a',
|
|
328
|
+
deltaSummary: 'n/a'
|
|
329
|
+
});
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
case 'code-paths': {
|
|
333
|
+
const mapStatus = repoMap.status(cwd);
|
|
334
|
+
if (!mapStatus.exists) {
|
|
335
|
+
console.log('Repo map not found. Run /repo-map init for better code-path coverage.');
|
|
336
|
+
}
|
|
337
|
+
const repoMapStatus = mapStatus.exists
|
|
338
|
+
? `available (files=${mapStatus.status?.files ?? 'n/a'}, symbols=${mapStatus.status?.symbols ?? 'n/a'})`
|
|
339
|
+
: 'missing';
|
|
340
|
+
const map = repoMap.load(cwd);
|
|
341
|
+
const result = codePaths.collectCodePaths(map, state.scenario?.description || '');
|
|
342
|
+
investigationState.updateInvestigation({ codePaths: result.paths, phase: 'profiling' }, cwd);
|
|
343
|
+
investigationState.appendCodePathsLog({
|
|
344
|
+
id: state.id,
|
|
345
|
+
userQuote,
|
|
346
|
+
keywords: result.keywords,
|
|
347
|
+
paths: result.paths,
|
|
348
|
+
repoMapStatus
|
|
349
|
+
}, cwd);
|
|
350
|
+
checkpoint.commitCheckpoint({
|
|
351
|
+
phase: 'code-paths',
|
|
352
|
+
id: state.id,
|
|
353
|
+
baselineVersion: version || 'n/a',
|
|
354
|
+
deltaSummary: `paths=${result.paths.length}`
|
|
355
|
+
});
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
case 'profiling': {
|
|
359
|
+
const result = profilingRunner.runProfiling({ repoPath: cwd, command });
|
|
360
|
+
if (!result.ok) {
|
|
361
|
+
console.error(`Profiling failed: ${result.error}`);
|
|
362
|
+
process.exit(1);
|
|
363
|
+
}
|
|
364
|
+
const nextResults = Array.isArray(state.profilingResults) ? state.profilingResults : [];
|
|
365
|
+
nextResults.push(result.result);
|
|
366
|
+
investigationState.updateInvestigation({ profilingResults: nextResults, phase: 'optimization' }, cwd);
|
|
367
|
+
investigationState.appendProfilingLog({
|
|
368
|
+
id: state.id,
|
|
369
|
+
userQuote,
|
|
370
|
+
tool: result.result.tool,
|
|
371
|
+
command: result.result.command,
|
|
372
|
+
artifacts: result.result.artifacts,
|
|
373
|
+
hotspots: result.result.hotspots
|
|
374
|
+
}, cwd);
|
|
375
|
+
checkpoint.commitCheckpoint({
|
|
376
|
+
phase: 'profiling',
|
|
377
|
+
id: state.id,
|
|
378
|
+
baselineVersion: version || 'n/a',
|
|
379
|
+
deltaSummary: 'n/a'
|
|
380
|
+
});
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
case 'optimization': {
|
|
384
|
+
const gitHistory = checkpoint.getRecentCommits(5);
|
|
385
|
+
const runs = Number.isFinite(options.runs) ? options.runs : state.benchmark?.runs;
|
|
386
|
+
const aggregate = options.aggregate || state.benchmark?.aggregate;
|
|
387
|
+
const result = optimizationRunner.runOptimizationExperiment({
|
|
388
|
+
command,
|
|
389
|
+
changeSummary: options.change,
|
|
390
|
+
duration: Number.isFinite(options.duration) ? options.duration : undefined,
|
|
391
|
+
runs,
|
|
392
|
+
aggregate
|
|
393
|
+
});
|
|
394
|
+
const nextResults = Array.isArray(state.results) ? state.results : [];
|
|
395
|
+
nextResults.push(result);
|
|
396
|
+
investigationState.updateInvestigation({ results: nextResults, phase: 'decision' }, cwd);
|
|
397
|
+
investigationState.appendOptimizationLog({
|
|
398
|
+
id: state.id,
|
|
399
|
+
userQuote,
|
|
400
|
+
change: options.change,
|
|
401
|
+
delta: result.delta,
|
|
402
|
+
verdict: result.verdict,
|
|
403
|
+
gitHistory,
|
|
404
|
+
runs,
|
|
405
|
+
aggregate: aggregate || (runs ? 'median' : undefined)
|
|
406
|
+
}, cwd);
|
|
407
|
+
checkpoint.commitCheckpoint({
|
|
408
|
+
phase: 'optimization',
|
|
409
|
+
id: state.id,
|
|
410
|
+
baselineVersion: version || 'n/a',
|
|
411
|
+
deltaSummary: 'n/a'
|
|
412
|
+
});
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
case 'decision': {
|
|
416
|
+
const decision = { verdict: options.verdict, rationale: options.rationale };
|
|
417
|
+
investigationState.updateInvestigation({ decision, phase: 'consolidation' }, cwd);
|
|
418
|
+
investigationState.appendDecisionLog({
|
|
419
|
+
id: state.id,
|
|
420
|
+
userQuote,
|
|
421
|
+
verdict: options.verdict,
|
|
422
|
+
rationale: options.rationale,
|
|
423
|
+
resultsCount: Array.isArray(state.results) ? state.results.length : 0
|
|
424
|
+
}, cwd);
|
|
425
|
+
checkpoint.commitCheckpoint({
|
|
426
|
+
phase: 'decision',
|
|
427
|
+
id: state.id,
|
|
428
|
+
baselineVersion: version || 'n/a',
|
|
429
|
+
deltaSummary: 'n/a'
|
|
430
|
+
});
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
case 'consolidation': {
|
|
434
|
+
const baseline = baselineStore.readBaseline(version, cwd);
|
|
435
|
+
if (!baseline) {
|
|
436
|
+
console.error(`Baseline not found for version ${version}`);
|
|
437
|
+
process.exit(1);
|
|
438
|
+
}
|
|
439
|
+
const result = consolidation.consolidateBaseline({ version, baseline }, cwd);
|
|
440
|
+
investigationState.appendConsolidationLog({
|
|
441
|
+
id: state.id,
|
|
442
|
+
userQuote,
|
|
443
|
+
version,
|
|
444
|
+
path: result.path
|
|
445
|
+
}, cwd);
|
|
446
|
+
investigationState.updateInvestigation({ phase: 'complete' }, cwd);
|
|
447
|
+
checkpoint.commitCheckpoint({
|
|
448
|
+
phase: 'consolidation',
|
|
449
|
+
id: state.id,
|
|
450
|
+
baselineVersion: version,
|
|
451
|
+
deltaSummary: 'n/a'
|
|
452
|
+
});
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
default:
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
await runPhase();
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
## Output
|
|
464
|
+
|
|
465
|
+
- Updated `{state-dir}/perf/investigation.json`
|
|
466
|
+
- Investigation log at `{state-dir}/perf/investigations/<id>.md`
|
|
467
|
+
- Baseline files at `{state-dir}/perf/baselines/<version>.json`
|
|
468
|
+
|
|
469
|
+
Begin the performance investigation now.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
inclusion: manual
|
|
3
|
+
name: "repo-map"
|
|
4
|
+
description: "Use when user asks to \"create repo map\", \"generate repo map\", \"update repo map\", \"repo map status\", \"map symbols\". Builds and updates AST-based repo map using ast-grep."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /repo-map - AST Repo Map
|
|
8
|
+
|
|
9
|
+
Generate a cached repository map of symbols and imports using ast-grep. This enables faster drift detection and more accurate code context.
|
|
10
|
+
|
|
11
|
+
## Arguments
|
|
12
|
+
|
|
13
|
+
Parse from `$ARGUMENTS`:
|
|
14
|
+
|
|
15
|
+
- **Action**: `init` | `update` | `status` | `rebuild` (default: `status`)
|
|
16
|
+
- `--force`: Force rebuild (for `init`)
|
|
17
|
+
- `--full`: Force full rebuild (for `update`)
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
|
|
21
|
+
- `/repo-map init`
|
|
22
|
+
- `/repo-map update --full`
|
|
23
|
+
- `/repo-map status`
|
|
24
|
+
|
|
25
|
+
## Execution
|
|
26
|
+
|
|
27
|
+
### 1) Load Repo Map Module
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
|
|
31
|
+
const pluginRoot = getPluginRoot('repo-map');
|
|
32
|
+
if (!pluginRoot) { console.error('Error: Could not locate repo-map plugin root'); process.exit(1); }
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 2) Parse Arguments
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
const args = '$ARGUMENTS'.split(' ').filter(Boolean);
|
|
40
|
+
const action = (args[0] || 'status').toLowerCase();
|
|
41
|
+
|
|
42
|
+
const options = {
|
|
43
|
+
force: args.includes('--force'),
|
|
44
|
+
full: args.includes('--full')
|
|
45
|
+
};
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3) Ensure ast-grep is Available
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
const installed = await repoMap.checkAstGrepInstalled();
|
|
52
|
+
if (!installed.found || !repoMap.installer.meetsMinimumVersion(installed.version)) {
|
|
53
|
+
const suggestion = repoMap.getInstallInstructions();
|
|
54
|
+
const choice = **ast-grep is required for repo-map. Install now?**
|
|
55
|
+
|
|
56
|
+
1. **Install via npm** - Runs: npm install -g @ast-grep/cli
|
|
57
|
+
2. **Skip for now** - Show install instructions and exit
|
|
58
|
+
|
|
59
|
+
Reply with the number or name of your choice.
|
|
60
|
+
|
|
61
|
+
if (choice?.[0] === 'Install via npm') {
|
|
62
|
+
await Bash('npm install -g @ast-grep/cli');
|
|
63
|
+
} else {
|
|
64
|
+
console.log(suggestion);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 4) Run Action
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
let result;
|
|
74
|
+
|
|
75
|
+
if (action === 'init' || action === 'rebuild') {
|
|
76
|
+
result = await repoMap.init(process.cwd(), {
|
|
77
|
+
force: action === 'rebuild' || options.force
|
|
78
|
+
});
|
|
79
|
+
} else if (action === 'update') {
|
|
80
|
+
result = await repoMap.update(process.cwd(), { full: options.full });
|
|
81
|
+
} else if (action === 'status') {
|
|
82
|
+
result = repoMap.status(process.cwd());
|
|
83
|
+
} else {
|
|
84
|
+
console.log('Unknown action. Use: init | update | status | rebuild');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (result?.success === false) {
|
|
89
|
+
console.log(result.error || 'Repo-map failed');
|
|
90
|
+
if (result.installSuggestion) console.log(result.installSuggestion);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (action === 'status' && !result.exists) {
|
|
95
|
+
console.log('No repo-map found. Run /repo-map init to generate one.');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 5) Validate Results (init/update only)
|
|
101
|
+
|
|
102
|
+
After `init` or `update`, run validation using the lightweight agent:
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
if (action === 'init' || action === 'rebuild' || action === 'update') {
|
|
106
|
+
const summary = result?.map?.stats || result?.summary || result?.changes || {};
|
|
107
|
+
const validation = Delegate to the `map-validator` subagent:
|
|
108
|
+
> Validate repo-map results. Summary: ${JSON.stringify(summary)}
|
|
109
|
+
console.log(validation);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Output Format
|
|
114
|
+
|
|
115
|
+
```markdown
|
|
116
|
+
## Repo Map Result
|
|
117
|
+
|
|
118
|
+
**Action**: init|update|status
|
|
119
|
+
**Files**: <count>
|
|
120
|
+
**Symbols**: <count>
|
|
121
|
+
**Languages**: <list>
|
|
122
|
+
**Commit**: <hash>
|
|
123
|
+
|
|
124
|
+
### Notes
|
|
125
|
+
- <warnings or validation results>
|
|
126
|
+
```
|