agentic-forge 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +24 -0
- package/.github/workflows/ci.yml +70 -0
- package/.markdownlint-cli2.jsonc +16 -0
- package/.prettierignore +3 -0
- package/.prettierrc +6 -0
- package/.vscode/agentic-forge.code-workspace +26 -0
- package/CHANGELOG.md +100 -0
- package/CLAUDE.md +158 -0
- package/CONTRIBUTING.md +152 -0
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/agentic-forge-banner.png +0 -0
- package/biome.json +21 -0
- package/package.json +5 -0
- package/scripts/copy-assets.js +21 -0
- package/src/agents/explorer.md +97 -0
- package/src/agents/reviewer.md +137 -0
- package/src/checkpoints/manager.ts +119 -0
- package/src/claude/.claude/skills/analyze/SKILL.md +241 -0
- package/src/claude/.claude/skills/analyze/references/bug.md +62 -0
- package/src/claude/.claude/skills/analyze/references/debt.md +76 -0
- package/src/claude/.claude/skills/analyze/references/doc.md +67 -0
- package/src/claude/.claude/skills/analyze/references/security.md +76 -0
- package/src/claude/.claude/skills/analyze/references/style.md +72 -0
- package/src/claude/.claude/skills/create-checkpoint/SKILL.md +88 -0
- package/src/claude/.claude/skills/create-log/SKILL.md +75 -0
- package/src/claude/.claude/skills/fix-analyze/SKILL.md +102 -0
- package/src/claude/.claude/skills/git-branch/SKILL.md +71 -0
- package/src/claude/.claude/skills/git-commit/SKILL.md +107 -0
- package/src/claude/.claude/skills/git-pr/SKILL.md +96 -0
- package/src/claude/.claude/skills/orchestrate/SKILL.md +120 -0
- package/src/claude/.claude/skills/sdlc-plan/SKILL.md +163 -0
- package/src/claude/.claude/skills/sdlc-plan/references/bug.md +115 -0
- package/src/claude/.claude/skills/sdlc-plan/references/chore.md +105 -0
- package/src/claude/.claude/skills/sdlc-plan/references/feature.md +130 -0
- package/src/claude/.claude/skills/sdlc-review/SKILL.md +215 -0
- package/src/claude/.claude/skills/workflow-builder/SKILL.md +185 -0
- package/src/claude/.claude/skills/workflow-builder/references/REFERENCE.md +487 -0
- package/src/claude/.claude/skills/workflow-builder/references/workflow-example.yaml +427 -0
- package/src/cli.ts +182 -0
- package/src/commands/config-cmd.ts +28 -0
- package/src/commands/index.ts +21 -0
- package/src/commands/init.ts +96 -0
- package/src/commands/release-notes.ts +85 -0
- package/src/commands/resume.ts +103 -0
- package/src/commands/run.ts +234 -0
- package/src/commands/shortcuts.ts +11 -0
- package/src/commands/skills-dir.ts +11 -0
- package/src/commands/status.ts +112 -0
- package/src/commands/update.ts +64 -0
- package/src/commands/version.ts +27 -0
- package/src/commands/workflows.ts +129 -0
- package/src/config.ts +129 -0
- package/src/console.ts +790 -0
- package/src/executor.ts +354 -0
- package/src/git/worktree.ts +236 -0
- package/src/logging/logger.ts +95 -0
- package/src/orchestrator.ts +815 -0
- package/src/parser.ts +225 -0
- package/src/progress.ts +306 -0
- package/src/prompts/agentic-system.md +31 -0
- package/src/ralph-loop.ts +260 -0
- package/src/renderer.ts +164 -0
- package/src/runner.ts +634 -0
- package/src/signal-manager.ts +55 -0
- package/src/steps/base.ts +71 -0
- package/src/steps/conditional-step.ts +144 -0
- package/src/steps/index.ts +15 -0
- package/src/steps/parallel-step.ts +213 -0
- package/src/steps/prompt-step.ts +121 -0
- package/src/steps/ralph-loop-step.ts +186 -0
- package/src/steps/serial-step.ts +84 -0
- package/src/templates/analysis/bug.md.j2 +35 -0
- package/src/templates/analysis/debt.md.j2 +38 -0
- package/src/templates/analysis/doc.md.j2 +45 -0
- package/src/templates/analysis/security.md.j2 +35 -0
- package/src/templates/analysis/style.md.j2 +44 -0
- package/src/templates/analysis-summary.md.j2 +58 -0
- package/src/templates/checkpoint.md.j2 +27 -0
- package/src/templates/implementation-report.md.j2 +81 -0
- package/src/templates/memory.md.j2 +16 -0
- package/src/templates/plan-bug.md.j2 +42 -0
- package/src/templates/plan-chore.md.j2 +27 -0
- package/src/templates/plan-feature.md.j2 +41 -0
- package/src/templates/progress.json.j2 +16 -0
- package/src/templates/ralph-report.md.j2 +45 -0
- package/src/types.ts +141 -0
- package/src/workflows/analyze-codebase-merge.yaml +328 -0
- package/src/workflows/analyze-codebase.yaml +196 -0
- package/src/workflows/analyze-single.yaml +56 -0
- package/src/workflows/demo.yaml +180 -0
- package/src/workflows/one-shot.yaml +54 -0
- package/src/workflows/plan-build-review.yaml +160 -0
- package/src/workflows/ralph-loop.yaml +73 -0
- package/tests/config.test.ts +219 -0
- package/tests/console.test.ts +506 -0
- package/tests/executor.test.ts +339 -0
- package/tests/init.test.ts +86 -0
- package/tests/logger.test.ts +110 -0
- package/tests/parser.test.ts +290 -0
- package/tests/progress.test.ts +345 -0
- package/tests/ralph-loop.test.ts +418 -0
- package/tests/renderer.test.ts +350 -0
- package/tests/runner.test.ts +497 -0
- package/tests/setup.test.ts +7 -0
- package/tests/signal-manager.test.ts +26 -0
- package/tests/steps.test.ts +412 -0
- package/tests/worktree.test.ts +411 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/** Ralph loop step executor. */
|
|
2
|
+
|
|
3
|
+
import type { ConsoleOutput } from "../console.js";
|
|
4
|
+
import { extractSummary } from "../console.js";
|
|
5
|
+
import type { WorkflowLogger } from "../logging/logger.js";
|
|
6
|
+
import { WORKFLOW_STATUS, updateStepCompleted, updateStepFailed } from "../progress.js";
|
|
7
|
+
import {
|
|
8
|
+
buildRalphSystemMessage,
|
|
9
|
+
createRalphState,
|
|
10
|
+
deactivateRalphState,
|
|
11
|
+
detectCompletionPromise,
|
|
12
|
+
loadRalphState,
|
|
13
|
+
updateRalphIteration,
|
|
14
|
+
} from "../ralph-loop.js";
|
|
15
|
+
import { runClaude } from "../runner.js";
|
|
16
|
+
import type { StepDefinition, WorkflowProgress } from "../types.js";
|
|
17
|
+
import {
|
|
18
|
+
type StepContext,
|
|
19
|
+
StepExecutor,
|
|
20
|
+
type StepResult,
|
|
21
|
+
buildTemplateContext,
|
|
22
|
+
resolveModel,
|
|
23
|
+
} from "./base.js";
|
|
24
|
+
|
|
25
|
+
export class RalphLoopStepExecutor extends StepExecutor {
|
|
26
|
+
async execute(
|
|
27
|
+
step: StepDefinition,
|
|
28
|
+
progress: WorkflowProgress,
|
|
29
|
+
context: StepContext,
|
|
30
|
+
logger: WorkflowLogger,
|
|
31
|
+
console: ConsoleOutput,
|
|
32
|
+
): Promise<StepResult> {
|
|
33
|
+
const promptTemplate = step.prompt ?? "";
|
|
34
|
+
const templateContext = buildTemplateContext(context);
|
|
35
|
+
|
|
36
|
+
let completionPromise = step.completionPromise ?? "COMPLETE";
|
|
37
|
+
if (context.renderer.hasVariables(completionPromise)) {
|
|
38
|
+
completionPromise = context.renderer.renderString(completionPromise, templateContext);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Handle max_iterations which may be a template string or integer
|
|
42
|
+
const maxIterationsRaw = step.maxIterations;
|
|
43
|
+
let maxIterations: number;
|
|
44
|
+
if (typeof maxIterationsRaw === "string" && context.renderer.hasVariables(maxIterationsRaw)) {
|
|
45
|
+
maxIterations = Number.parseInt(
|
|
46
|
+
context.renderer.renderString(maxIterationsRaw, templateContext),
|
|
47
|
+
10,
|
|
48
|
+
);
|
|
49
|
+
} else {
|
|
50
|
+
maxIterations = maxIterationsRaw ? Number.parseInt(String(maxIterationsRaw), 10) : 5;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const timeout = (step.stepTimeoutMinutes ?? 30) * 60;
|
|
54
|
+
const bypassPermissions = context.workflowSettings?.bypassPermissions ?? false;
|
|
55
|
+
const allowedTools = context.workflowSettings?.requiredTools?.length
|
|
56
|
+
? context.workflowSettings.requiredTools
|
|
57
|
+
: null;
|
|
58
|
+
|
|
59
|
+
// Always enable streaming when console is provided
|
|
60
|
+
const printOutput = true;
|
|
61
|
+
|
|
62
|
+
logger.info(step.name, `Starting Ralph loop (max ${maxIterations} iterations)`);
|
|
63
|
+
console.info(`Ralph loop starting (max ${maxIterations} iterations)`);
|
|
64
|
+
|
|
65
|
+
const allOutputs: string[] = [];
|
|
66
|
+
|
|
67
|
+
// Check for existing ralph state to resume from
|
|
68
|
+
const existingState = loadRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
69
|
+
let startIteration: number;
|
|
70
|
+
if (existingState?.active) {
|
|
71
|
+
startIteration = existingState.iteration;
|
|
72
|
+
logger.info(step.name, `Resuming Ralph loop from iteration ${startIteration}`);
|
|
73
|
+
console.info(`Resuming Ralph loop from iteration ${startIteration}`);
|
|
74
|
+
} else {
|
|
75
|
+
startIteration = 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
for (let iteration = startIteration; iteration <= maxIterations; iteration++) {
|
|
79
|
+
logger.info(step.name, `Ralph loop iteration ${iteration}/${maxIterations}`);
|
|
80
|
+
|
|
81
|
+
// Render prompt with iteration context
|
|
82
|
+
const iterationContext = {
|
|
83
|
+
...templateContext,
|
|
84
|
+
iteration,
|
|
85
|
+
max_iterations: maxIterations,
|
|
86
|
+
};
|
|
87
|
+
let prompt: string;
|
|
88
|
+
if (context.renderer.hasVariables(promptTemplate)) {
|
|
89
|
+
prompt = context.renderer.renderString(promptTemplate, iterationContext);
|
|
90
|
+
} else {
|
|
91
|
+
prompt = promptTemplate;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Create ralph state on first iteration
|
|
95
|
+
if (iteration === startIteration && !existingState?.active) {
|
|
96
|
+
createRalphState(
|
|
97
|
+
progress.workflowId,
|
|
98
|
+
step.name,
|
|
99
|
+
prompt,
|
|
100
|
+
maxIterations,
|
|
101
|
+
completionPromise,
|
|
102
|
+
context.repoRoot,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const systemMessage = buildRalphSystemMessage(iteration, maxIterations, completionPromise);
|
|
107
|
+
const fullPrompt = `${systemMessage}${prompt}`;
|
|
108
|
+
|
|
109
|
+
// Display iteration header BEFORE running Claude
|
|
110
|
+
console.ralphIterationStart(step.name, iteration, maxIterations);
|
|
111
|
+
|
|
112
|
+
const result = await runClaude({
|
|
113
|
+
prompt: fullPrompt,
|
|
114
|
+
cwd: context.repoRoot,
|
|
115
|
+
model: resolveModel(context, step.model),
|
|
116
|
+
timeout,
|
|
117
|
+
printOutput,
|
|
118
|
+
skipPermissions: bypassPermissions,
|
|
119
|
+
allowedTools,
|
|
120
|
+
console,
|
|
121
|
+
workflowId: context.workflowId,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (!result.success) {
|
|
125
|
+
const errorSummary = result.stderr ? extractSummary(result.stderr) : "Unknown error";
|
|
126
|
+
logger.warning(step.name, `Iteration ${iteration} failed: ${result.stderr}`);
|
|
127
|
+
console.ralphIteration(step.name, iteration, maxIterations, `Failed: ${errorSummary}`);
|
|
128
|
+
if (iteration < maxIterations) {
|
|
129
|
+
updateRalphIteration(progress.workflowId, step.name, context.repoRoot);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
deactivateRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
133
|
+
const errorMsg = `Ralph loop failed after ${maxIterations} iterations`;
|
|
134
|
+
console.stepFailed(step.name, errorMsg);
|
|
135
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
136
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
137
|
+
return { success: false, error: errorMsg };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
allOutputs.push(result.stdout);
|
|
141
|
+
|
|
142
|
+
// Print iteration summary
|
|
143
|
+
const iterationSummary = extractSummary(result.stdout);
|
|
144
|
+
console.ralphIteration(step.name, iteration, maxIterations, iterationSummary);
|
|
145
|
+
|
|
146
|
+
const completionResult = detectCompletionPromise(result.stdout, completionPromise);
|
|
147
|
+
|
|
148
|
+
// Check for failure signal first
|
|
149
|
+
if (completionResult.isFailed) {
|
|
150
|
+
const errorMsg = `Ralph loop failed: ${completionResult.failureReason}`;
|
|
151
|
+
logger.error(step.name, errorMsg);
|
|
152
|
+
deactivateRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
153
|
+
const combinedOutput = allOutputs.join("\n\n---\n\n");
|
|
154
|
+
console.stepFailed(step.name, errorMsg);
|
|
155
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
156
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
157
|
+
return { success: false, error: errorMsg, fullOutput: combinedOutput };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (completionResult.isComplete && completionResult.promiseMatched) {
|
|
161
|
+
logger.info(step.name, `Ralph loop completed at iteration ${iteration}`);
|
|
162
|
+
deactivateRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
163
|
+
const combinedOutput = allOutputs.join("\n\n---\n\n");
|
|
164
|
+
const outputSummary = `Completed in ${iteration} iterations`;
|
|
165
|
+
updateStepCompleted(progress, step.name, outputSummary, combinedOutput);
|
|
166
|
+
console.ralphComplete(step.name, iteration, maxIterations);
|
|
167
|
+
return { success: true, outputSummary, fullOutput: combinedOutput };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (iteration < maxIterations) {
|
|
171
|
+
updateRalphIteration(progress.workflowId, step.name, context.repoRoot);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
logger.warning(
|
|
176
|
+
step.name,
|
|
177
|
+
`Ralph loop reached max iterations (${maxIterations}) without completion`,
|
|
178
|
+
);
|
|
179
|
+
deactivateRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
180
|
+
const combinedOutput = allOutputs.join("\n\n---\n\n");
|
|
181
|
+
const outputSummary = `Max iterations (${maxIterations}) reached without completion promise`;
|
|
182
|
+
updateStepCompleted(progress, step.name, outputSummary, combinedOutput);
|
|
183
|
+
console.ralphMaxIterations(step.name, maxIterations);
|
|
184
|
+
return { success: true, outputSummary, fullOutput: combinedOutput };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** Serial step executor. */
|
|
2
|
+
|
|
3
|
+
import type { ConsoleOutput } from "../console.js";
|
|
4
|
+
import type { WorkflowLogger } from "../logging/logger.js";
|
|
5
|
+
import { WORKFLOW_STATUS, updateStepCompleted, updateStepFailed } from "../progress.js";
|
|
6
|
+
import type { StepDefinition, WorkflowProgress } from "../types.js";
|
|
7
|
+
import {
|
|
8
|
+
type BranchStepExecutor,
|
|
9
|
+
type StepContext,
|
|
10
|
+
StepExecutor,
|
|
11
|
+
type StepResult,
|
|
12
|
+
} from "./base.js";
|
|
13
|
+
|
|
14
|
+
export class SerialStepExecutor extends StepExecutor {
|
|
15
|
+
constructor(private branchExecutor: BranchStepExecutor) {
|
|
16
|
+
super();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async execute(
|
|
20
|
+
step: StepDefinition,
|
|
21
|
+
progress: WorkflowProgress,
|
|
22
|
+
context: StepContext,
|
|
23
|
+
logger: WorkflowLogger,
|
|
24
|
+
console: ConsoleOutput,
|
|
25
|
+
): Promise<StepResult> {
|
|
26
|
+
if (!step.steps || step.steps.length === 0) {
|
|
27
|
+
logger.warning(step.name, "Serial step has no sub-steps");
|
|
28
|
+
updateStepCompleted(progress, step.name, "No sub-steps to execute");
|
|
29
|
+
console.stepComplete(step.name, "No sub-steps to execute");
|
|
30
|
+
return { success: true, outputSummary: "No sub-steps to execute" };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
logger.info(step.name, `Starting serial execution of ${step.steps.length} steps`);
|
|
34
|
+
console.info(`Serial: executing ${step.steps.length} steps in sequence`);
|
|
35
|
+
|
|
36
|
+
let completedCount = 0;
|
|
37
|
+
|
|
38
|
+
for (const subStep of step.steps) {
|
|
39
|
+
try {
|
|
40
|
+
const result = await this.branchExecutor(subStep, progress, context, logger, console);
|
|
41
|
+
|
|
42
|
+
if (!result.success) {
|
|
43
|
+
logger.warning(
|
|
44
|
+
step.name,
|
|
45
|
+
`Serial block stopped at step '${subStep.name}' due to failure`,
|
|
46
|
+
);
|
|
47
|
+
const errorMsg = `Step '${subStep.name}' failed: ${result.error}`;
|
|
48
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
49
|
+
console.stepFailed(step.name, `Step '${subStep.name}' failed`);
|
|
50
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
51
|
+
return { success: false, error: errorMsg };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
completedCount++;
|
|
55
|
+
|
|
56
|
+
if (progress.status === WORKFLOW_STATUS.FAILED) {
|
|
57
|
+
logger.warning(
|
|
58
|
+
step.name,
|
|
59
|
+
`Serial block stopped at step '${subStep.name}' due to failure`,
|
|
60
|
+
);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
} catch (e) {
|
|
64
|
+
const errStr = e instanceof Error ? e.message : String(e);
|
|
65
|
+
logger.error(subStep.name, `Step failed in serial block: ${errStr}`);
|
|
66
|
+
const errorMsg = `Step '${subStep.name}' failed: ${errStr}`;
|
|
67
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
68
|
+
console.stepFailed(step.name, `Step '${subStep.name}' failed`);
|
|
69
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
70
|
+
return { success: false, error: errorMsg };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (progress.status !== WORKFLOW_STATUS.FAILED) {
|
|
75
|
+
const outputSummary = `Completed ${completedCount}/${step.steps.length} steps`;
|
|
76
|
+
updateStepCompleted(progress, step.name, outputSummary);
|
|
77
|
+
console.stepComplete(step.name, outputSummary);
|
|
78
|
+
logger.info(step.name, outputSummary);
|
|
79
|
+
return { success: true, outputSummary };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { success: false, error: "Serial execution failed" };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Bug Analysis Report
|
|
2
|
+
|
|
3
|
+
Generated: {{ generated }}
|
|
4
|
+
Scope: {{ scope }}
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
Found {{ summary.total }} potential issues.
|
|
9
|
+
|
|
10
|
+
| Severity | Count |
|
|
11
|
+
|----------|-------|
|
|
12
|
+
| Critical | {{ summary.critical }} |
|
|
13
|
+
| Major | {{ summary.major }} |
|
|
14
|
+
| Minor | {{ summary.minor }} |
|
|
15
|
+
|
|
16
|
+
## Findings
|
|
17
|
+
|
|
18
|
+
{% for finding in findings %}
|
|
19
|
+
### {{ finding.id }}: {{ finding.title }}
|
|
20
|
+
|
|
21
|
+
**Severity**: {{ finding.severity }}
|
|
22
|
+
**Category**: {{ finding.category }}
|
|
23
|
+
**File**: {{ finding.file }}:{{ finding.line }}
|
|
24
|
+
|
|
25
|
+
{{ finding.description }}
|
|
26
|
+
|
|
27
|
+
**Recommendation**: {{ finding.recommendation }}
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
{% endfor %}
|
|
32
|
+
|
|
33
|
+
{% if not findings %}
|
|
34
|
+
No potential bugs found.
|
|
35
|
+
{% endif %}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Technical Debt Analysis Report
|
|
2
|
+
|
|
3
|
+
Generated: {{ generated }}
|
|
4
|
+
Scope: {{ scope }}
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
Found {{ summary.total }} technical debt items.
|
|
9
|
+
|
|
10
|
+
| Priority | Count |
|
|
11
|
+
|----------|-------|
|
|
12
|
+
| High | {{ summary.high }} |
|
|
13
|
+
| Medium | {{ summary.medium }} |
|
|
14
|
+
| Low | {{ summary.low }} |
|
|
15
|
+
|
|
16
|
+
## Findings
|
|
17
|
+
|
|
18
|
+
{% for finding in findings %}
|
|
19
|
+
### {{ finding.id }}: {{ finding.title }}
|
|
20
|
+
|
|
21
|
+
**Priority**: {{ finding.priority }}
|
|
22
|
+
**Category**: {{ finding.category }}
|
|
23
|
+
**File**: {{ finding.file }}{% if finding.line %}:{{ finding.line }}{% endif %}
|
|
24
|
+
|
|
25
|
+
{{ finding.description }}
|
|
26
|
+
|
|
27
|
+
**Effort**: {{ finding.effort | default("Unknown") }}
|
|
28
|
+
**Impact**: {{ finding.impact | default("Unknown") }}
|
|
29
|
+
|
|
30
|
+
**Recommendation**: {{ finding.recommendation }}
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
{% endfor %}
|
|
35
|
+
|
|
36
|
+
{% if not findings %}
|
|
37
|
+
No technical debt issues found.
|
|
38
|
+
{% endif %}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Documentation Analysis Report
|
|
2
|
+
|
|
3
|
+
Generated: {{ generated }}
|
|
4
|
+
Scope: {{ scope }}
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
Found {{ summary.total }} documentation issues.
|
|
9
|
+
|
|
10
|
+
| Priority | Count |
|
|
11
|
+
|----------|-------|
|
|
12
|
+
| High | {{ summary.high }} |
|
|
13
|
+
| Medium | {{ summary.medium }} |
|
|
14
|
+
| Low | {{ summary.low }} |
|
|
15
|
+
|
|
16
|
+
## Findings
|
|
17
|
+
|
|
18
|
+
{% for finding in findings %}
|
|
19
|
+
### {{ finding.id }}: {{ finding.title }}
|
|
20
|
+
|
|
21
|
+
**Priority**: {{ finding.priority }}
|
|
22
|
+
**Category**: {{ finding.category }}
|
|
23
|
+
**File**: {{ finding.file }}{% if finding.line %}:{{ finding.line }}{% endif %}
|
|
24
|
+
|
|
25
|
+
{{ finding.description }}
|
|
26
|
+
|
|
27
|
+
**Recommendation**: {{ finding.recommendation }}
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
{% endfor %}
|
|
32
|
+
|
|
33
|
+
{% if not findings %}
|
|
34
|
+
No documentation issues found.
|
|
35
|
+
{% endif %}
|
|
36
|
+
|
|
37
|
+
## Coverage Overview
|
|
38
|
+
|
|
39
|
+
{% if coverage %}
|
|
40
|
+
| Metric | Value |
|
|
41
|
+
|--------|-------|
|
|
42
|
+
| Files with docs | {{ coverage.files_documented }} / {{ coverage.files_total }} |
|
|
43
|
+
| Functions documented | {{ coverage.functions_documented }} / {{ coverage.functions_total }} |
|
|
44
|
+
| Classes documented | {{ coverage.classes_documented }} / {{ coverage.classes_total }} |
|
|
45
|
+
{% endif %}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Security Analysis Report
|
|
2
|
+
|
|
3
|
+
Generated: {{ generated }}
|
|
4
|
+
Scope: {{ scope }}
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
| Severity | Count |
|
|
9
|
+
|----------|-------|
|
|
10
|
+
| Critical | {{ summary.critical }} |
|
|
11
|
+
| Major | {{ summary.major }} |
|
|
12
|
+
| Minor | {{ summary.minor }} |
|
|
13
|
+
| **Total** | {{ summary.total }} |
|
|
14
|
+
|
|
15
|
+
## Findings
|
|
16
|
+
|
|
17
|
+
{% for finding in findings %}
|
|
18
|
+
### {{ finding.id }}: {{ finding.title }}
|
|
19
|
+
|
|
20
|
+
**Severity**: {{ finding.severity | upper }}
|
|
21
|
+
**Category**: {{ finding.category }}
|
|
22
|
+
**File**: {{ finding.file }}:{{ finding.line }}
|
|
23
|
+
{% if finding.cwe %}**CWE**: {{ finding.cwe }}{% endif %}
|
|
24
|
+
|
|
25
|
+
{{ finding.description }}
|
|
26
|
+
|
|
27
|
+
**Recommendation**: {{ finding.recommendation }}
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
{% endfor %}
|
|
32
|
+
|
|
33
|
+
{% if not findings %}
|
|
34
|
+
No security issues found.
|
|
35
|
+
{% endif %}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Style Analysis Report
|
|
2
|
+
|
|
3
|
+
Generated: {{ generated }}
|
|
4
|
+
Scope: {{ scope }}
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
Found {{ summary.total }} style issues.
|
|
9
|
+
|
|
10
|
+
| Severity | Count |
|
|
11
|
+
|----------|-------|
|
|
12
|
+
| Major | {{ summary.major }} |
|
|
13
|
+
| Minor | {{ summary.minor }} |
|
|
14
|
+
| Info | {{ summary.info }} |
|
|
15
|
+
|
|
16
|
+
## Findings
|
|
17
|
+
|
|
18
|
+
{% for finding in findings %}
|
|
19
|
+
### {{ finding.id }}: {{ finding.title }}
|
|
20
|
+
|
|
21
|
+
**Severity**: {{ finding.severity }}
|
|
22
|
+
**Category**: {{ finding.category }}
|
|
23
|
+
**File**: {{ finding.file }}:{{ finding.line }}
|
|
24
|
+
|
|
25
|
+
{{ finding.description }}
|
|
26
|
+
|
|
27
|
+
**Expected**: `{{ finding.expected }}`
|
|
28
|
+
**Actual**: `{{ finding.actual }}`
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
{% endfor %}
|
|
33
|
+
|
|
34
|
+
{% if not findings %}
|
|
35
|
+
No style issues found.
|
|
36
|
+
{% endif %}
|
|
37
|
+
|
|
38
|
+
## Patterns Checked
|
|
39
|
+
|
|
40
|
+
{% if patterns %}
|
|
41
|
+
{% for pattern in patterns %}
|
|
42
|
+
- [{% if pattern.passed %}x{% else %} {% endif %}] {{ pattern.name }}
|
|
43
|
+
{% endfor %}
|
|
44
|
+
{% endif %}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Analysis Summary
|
|
2
|
+
|
|
3
|
+
Generated: {{ workflow.completed_at }}
|
|
4
|
+
Workflow: {{ workflow.name }}
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This report summarizes the results of running {{ analysis_steps | length }} analysis types on the codebase.
|
|
9
|
+
|
|
10
|
+
| Analysis | Status | Summary |
|
|
11
|
+
|----------|--------|---------|
|
|
12
|
+
{%- for step_name, step in analysis_steps.items() %}
|
|
13
|
+
| {{ step_name | replace('analyze-', '') | title }} | {{ step.status }} | {{ step.output_summary | default('-') }} |
|
|
14
|
+
{%- endfor %}
|
|
15
|
+
|
|
16
|
+
## Analysis Details
|
|
17
|
+
{% for step_name, step in analysis_steps.items() %}
|
|
18
|
+
### {{ step_name | replace('analyze-', '') | title }} Analysis
|
|
19
|
+
|
|
20
|
+
**Status**: {{ step.status }}
|
|
21
|
+
{%- if step.output_summary %}
|
|
22
|
+
|
|
23
|
+
**Summary**: {{ step.output_summary }}
|
|
24
|
+
{%- endif %}
|
|
25
|
+
|
|
26
|
+
Output: `agentic/analysis/{{ step_name | replace('analyze-', '') }}.md`
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
{%- endfor %}
|
|
30
|
+
{% if inputs.autofix and inputs.autofix != 'none' %}
|
|
31
|
+
|
|
32
|
+
## Autofix Summary
|
|
33
|
+
|
|
34
|
+
Autofix was enabled at severity level: **{{ inputs.autofix }}**
|
|
35
|
+
|
|
36
|
+
| Type | Fix Status |
|
|
37
|
+
|------|------------|
|
|
38
|
+
{%- for step_name, step in fix_steps.items() %}
|
|
39
|
+
| {{ step_name | replace('fix-', '') | replace('apply-', '') | replace('-fixes', '') | title }} | {{ step.status }} |
|
|
40
|
+
{%- endfor %}
|
|
41
|
+
{% endif %}
|
|
42
|
+
|
|
43
|
+
## Files Changed
|
|
44
|
+
|
|
45
|
+
{% if files_changed -%}
|
|
46
|
+
{% for file in files_changed %}
|
|
47
|
+
- `{{ file }}`
|
|
48
|
+
{% endfor %}
|
|
49
|
+
{%- else -%}
|
|
50
|
+
No files were changed during this analysis.
|
|
51
|
+
{%- endif %}
|
|
52
|
+
{% if pull_requests %}
|
|
53
|
+
|
|
54
|
+
## Pull Requests
|
|
55
|
+
{% for pr in pull_requests %}
|
|
56
|
+
- [#{{ pr.number }}]({{ pr.url }})
|
|
57
|
+
{%- endfor %}
|
|
58
|
+
{% endif %}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
checkpoint_id: {{ checkpoint_id }}
|
|
3
|
+
step: {{ step }}
|
|
4
|
+
created: {{ created }}
|
|
5
|
+
workflow_id: {{ workflow_id }}
|
|
6
|
+
status: {{ status }}
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
{{ context }}
|
|
12
|
+
|
|
13
|
+
## Progress
|
|
14
|
+
|
|
15
|
+
{{ progress }}
|
|
16
|
+
|
|
17
|
+
{% if notes %}
|
|
18
|
+
## Notes for Next Session
|
|
19
|
+
|
|
20
|
+
{{ notes }}
|
|
21
|
+
{% endif %}
|
|
22
|
+
|
|
23
|
+
{% if issues %}
|
|
24
|
+
## Issues Discovered
|
|
25
|
+
|
|
26
|
+
{{ issues }}
|
|
27
|
+
{% endif %}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Implementation Report
|
|
2
|
+
|
|
3
|
+
Generated: {{ workflow.completed_at }}
|
|
4
|
+
Workflow: {{ workflow.name }}
|
|
5
|
+
ID: {{ workflow.id | default(workflow.workflow_id, true) }}
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
**Status**: {{ workflow.status | default('completed') }}
|
|
10
|
+
**Started**: {{ workflow.started_at }}
|
|
11
|
+
**Completed**: {{ workflow.completed_at }}
|
|
12
|
+
|
|
13
|
+
## Task
|
|
14
|
+
|
|
15
|
+
{% if inputs.task %}
|
|
16
|
+
{{ inputs.task }}
|
|
17
|
+
{% elif inputs.feature_name %}
|
|
18
|
+
Feature: {{ inputs.feature_name }}
|
|
19
|
+
{% elif inputs.description %}
|
|
20
|
+
{{ inputs.description }}
|
|
21
|
+
{% else %}
|
|
22
|
+
_No task description provided_
|
|
23
|
+
{% endif %}
|
|
24
|
+
|
|
25
|
+
## Steps Completed
|
|
26
|
+
|
|
27
|
+
| Step | Status | Summary |
|
|
28
|
+
|------|--------|---------|
|
|
29
|
+
{% for step_name, step in steps.items() %}
|
|
30
|
+
| {{ step_name }} | {{ step.status }} | {{ step.output_summary | default('-') | truncate(50) }} |
|
|
31
|
+
{% endfor %}
|
|
32
|
+
|
|
33
|
+
## Files Changed
|
|
34
|
+
|
|
35
|
+
{% if files_changed %}
|
|
36
|
+
{% for file in files_changed %}
|
|
37
|
+
- `{{ file }}`
|
|
38
|
+
{% endfor %}
|
|
39
|
+
{% else %}
|
|
40
|
+
No files were changed during this workflow.
|
|
41
|
+
{% endif %}
|
|
42
|
+
|
|
43
|
+
{% if branches %}
|
|
44
|
+
## Branches
|
|
45
|
+
|
|
46
|
+
{% for branch in branches %}
|
|
47
|
+
- `{{ branch }}`
|
|
48
|
+
{% endfor %}
|
|
49
|
+
{% endif %}
|
|
50
|
+
|
|
51
|
+
{% if pull_requests %}
|
|
52
|
+
## Pull Requests
|
|
53
|
+
|
|
54
|
+
{% for pr in pull_requests %}
|
|
55
|
+
- [#{{ pr.number }}]({{ pr.url }})
|
|
56
|
+
{% endfor %}
|
|
57
|
+
{% endif %}
|
|
58
|
+
|
|
59
|
+
## Detailed Results
|
|
60
|
+
|
|
61
|
+
{% for step_name, step in steps.items() %}
|
|
62
|
+
### {{ step_name }}
|
|
63
|
+
|
|
64
|
+
**Status**: {{ step.status }}
|
|
65
|
+
{% if step.started_at %}**Started**: {{ step.started_at }}{% endif %}
|
|
66
|
+
{% if step.completed_at %}**Completed**: {{ step.completed_at }}{% endif %}
|
|
67
|
+
|
|
68
|
+
{% if step.output_summary %}
|
|
69
|
+
{{ step.output_summary }}
|
|
70
|
+
{% endif %}
|
|
71
|
+
|
|
72
|
+
{% if step.files_changed %}
|
|
73
|
+
Files changed:
|
|
74
|
+
{% for file in step.files_changed %}
|
|
75
|
+
- `{{ file }}`
|
|
76
|
+
{% endfor %}
|
|
77
|
+
{% endif %}
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
{% endfor %}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: {{ id }}
|
|
3
|
+
created: {{ created }}
|
|
4
|
+
category: {{ category }}
|
|
5
|
+
tags: {{ tags | tojson }}
|
|
6
|
+
{% if source %}
|
|
7
|
+
source:
|
|
8
|
+
workflow: {{ source.workflow }}
|
|
9
|
+
step: {{ source.step }}
|
|
10
|
+
{% endif %}
|
|
11
|
+
relevance: {{ relevance }}
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# {{ title }}
|
|
15
|
+
|
|
16
|
+
{{ content }}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Bug Fix Plan: {{ title }}
|
|
2
|
+
|
|
3
|
+
Created: {{ created }}
|
|
4
|
+
Status: {{ status }}
|
|
5
|
+
Workflow: {{ workflow_id }}
|
|
6
|
+
|
|
7
|
+
## Bug Summary
|
|
8
|
+
|
|
9
|
+
{{ summary }}
|
|
10
|
+
|
|
11
|
+
## Root Cause Analysis
|
|
12
|
+
|
|
13
|
+
{{ root_cause }}
|
|
14
|
+
|
|
15
|
+
## Progress Tracker
|
|
16
|
+
|
|
17
|
+
{% for milestone in milestones %}
|
|
18
|
+
### Milestone {{ milestone.id }}: {{ milestone.title }}
|
|
19
|
+
|
|
20
|
+
{% for task in milestone.tasks %}
|
|
21
|
+
- [{% if task.completed %}x{% else %} {% endif %}] {{ task.id }}: {{ task.description }}
|
|
22
|
+
{% endfor %}
|
|
23
|
+
|
|
24
|
+
{% endfor %}
|
|
25
|
+
|
|
26
|
+
## Affected Files
|
|
27
|
+
|
|
28
|
+
{% for file in affected_files %}
|
|
29
|
+
- {{ file }}
|
|
30
|
+
{% endfor %}
|
|
31
|
+
|
|
32
|
+
## Test Plan
|
|
33
|
+
|
|
34
|
+
{% for test in test_plan %}
|
|
35
|
+
- {{ test }}
|
|
36
|
+
{% endfor %}
|
|
37
|
+
|
|
38
|
+
## Verification Steps
|
|
39
|
+
|
|
40
|
+
{% for step in verification_steps %}
|
|
41
|
+
1. {{ step }}
|
|
42
|
+
{% endfor %}
|