mirror of
https://github.com/jparkerweb/plan2code.git
synced 2026-07-21 18:33:22 -07:00
v1.14.0 — add Step 3b review workflow, unify file naming, resilient code references
- Add /plan2code-3b-review: 5-step post-implementation review with adaptive scope, 11 dimensions, reference-file architecture, and Plan/Apply/Verify fixes - Unify workflow/skill file naming to single-dash (drop -- and --- conventions) - Add Devin platform support and CLAUDE.md MANDATORY FIRST STEP template - Guide agents to use semantic anchors over line numbers in workflow prompts - Bump version to 1.14.0
This commit is contained in:
@@ -16,14 +16,14 @@ const ANALYZE_PROMPT_PATH = new URL('../src/prompts/analyze.md', import.meta.url
|
||||
function readPromptFiles(plan2codeRoot: string): Record<string, string> {
|
||||
const srcDir = path.join(plan2codeRoot, 'src');
|
||||
const promptFiles = [
|
||||
'plan2code-1--plan.md',
|
||||
'plan2code-1b--revise-plan.md',
|
||||
'plan2code-2--document.md',
|
||||
'plan2code-3--implement.md',
|
||||
'plan2code-4--finalize.md',
|
||||
'plan2code---init.md',
|
||||
'plan2code---init-update.md',
|
||||
'plan2code---quick-task.md',
|
||||
'plan2code-1-plan.md',
|
||||
'plan2code-1b-revise-plan.md',
|
||||
'plan2code-2-document.md',
|
||||
'plan2code-3-implement.md',
|
||||
'plan2code-4-finalize.md',
|
||||
'plan2code-init.md',
|
||||
'plan2code-init-update.md',
|
||||
'plan2code-quick-task.md',
|
||||
];
|
||||
|
||||
const contents: Record<string, string> = {};
|
||||
|
||||
@@ -69,8 +69,8 @@ function detectPlan2CodeRoot(): string | null {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const srcDir = path.join(dir, 'src');
|
||||
if (
|
||||
fs.existsSync(path.join(srcDir, 'plan2code-1--plan.md')) &&
|
||||
fs.existsSync(path.join(srcDir, 'plan2code-2--document.md'))
|
||||
fs.existsSync(path.join(srcDir, 'plan2code-1-plan.md')) &&
|
||||
fs.existsSync(path.join(srcDir, 'plan2code-2-document.md'))
|
||||
) {
|
||||
return dir;
|
||||
}
|
||||
@@ -764,8 +764,8 @@ export async function runCLI(): Promise<void> {
|
||||
|
||||
// Warn if the path doesn't look like a plan2code repo
|
||||
const hasSrcPrompts =
|
||||
fs.existsSync(path.join(resolvedPlan2CodeRoot, 'src', 'plan2code-1--plan.md')) &&
|
||||
fs.existsSync(path.join(resolvedPlan2CodeRoot, 'src', 'plan2code-2--document.md'));
|
||||
fs.existsSync(path.join(resolvedPlan2CodeRoot, 'src', 'plan2code-1-plan.md')) &&
|
||||
fs.existsSync(path.join(resolvedPlan2CodeRoot, 'src', 'plan2code-2-document.md'));
|
||||
if (!hasSrcPrompts) {
|
||||
console.log(chalk.yellow('⚠ No src/plan2code-*.md prompts found at that path. Hashing and analysis may be limited.'));
|
||||
}
|
||||
|
||||
@@ -99,14 +99,14 @@ function generateRunId(): string {
|
||||
export function collectPromptVersions(plan2codeRoot: string): PromptVersions {
|
||||
const srcDir = path.join(plan2codeRoot, 'src');
|
||||
return {
|
||||
plan: sha256File(path.join(srcDir, 'plan2code-1--plan.md')),
|
||||
revise_plan: sha256File(path.join(srcDir, 'plan2code-1b--revise-plan.md')),
|
||||
document: sha256File(path.join(srcDir, 'plan2code-2--document.md')),
|
||||
implement: sha256File(path.join(srcDir, 'plan2code-3--implement.md')),
|
||||
finalize: sha256File(path.join(srcDir, 'plan2code-4--finalize.md')),
|
||||
init: sha256File(path.join(srcDir, 'plan2code---init.md')),
|
||||
init_update: sha256File(path.join(srcDir, 'plan2code---init-update.md')),
|
||||
quick_task: sha256File(path.join(srcDir, 'plan2code---quick-task.md')),
|
||||
plan: sha256File(path.join(srcDir, 'plan2code-1-plan.md')),
|
||||
revise_plan: sha256File(path.join(srcDir, 'plan2code-1b-revise-plan.md')),
|
||||
document: sha256File(path.join(srcDir, 'plan2code-2-document.md')),
|
||||
implement: sha256File(path.join(srcDir, 'plan2code-3-implement.md')),
|
||||
finalize: sha256File(path.join(srcDir, 'plan2code-4-finalize.md')),
|
||||
init: sha256File(path.join(srcDir, 'plan2code-init.md')),
|
||||
init_update: sha256File(path.join(srcDir, 'plan2code-init-update.md')),
|
||||
quick_task: sha256File(path.join(srcDir, 'plan2code-quick-task.md')),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,18 @@ import type { PromptEdit } from './types.js';
|
||||
// ── Shared fixtures ───────────────────────────────────────────────────────────
|
||||
|
||||
const PROMPT_CONTENTS: Record<string, string> = {
|
||||
'plan2code-1--plan.md': 'This is the plan prompt content. It has some text here.',
|
||||
'plan2code-2--document.md': 'Document prompt with repeated text. repeated text. Done.',
|
||||
'plan2code-3--implement.md': 'Implement prompt content.',
|
||||
'plan2code-1-plan.md': 'This is the plan prompt content. It has some text here.',
|
||||
'plan2code-2-document.md': 'Document prompt with repeated text. repeated text. Done.',
|
||||
'plan2code-3-implement.md': 'Implement prompt content.',
|
||||
};
|
||||
|
||||
function makeEdit(overrides: Partial<PromptEdit> = {}): PromptEdit {
|
||||
return {
|
||||
file: 'plan2code-1--plan.md',
|
||||
file: 'plan2code-1-plan.md',
|
||||
rationale: 'test rationale',
|
||||
expected_metric_impact: 'test impact',
|
||||
char_count_before: PROMPT_CONTENTS['plan2code-1--plan.md'].length,
|
||||
char_count_after: PROMPT_CONTENTS['plan2code-1--plan.md'].length,
|
||||
char_count_before: PROMPT_CONTENTS['plan2code-1-plan.md'].length,
|
||||
char_count_after: PROMPT_CONTENTS['plan2code-1-plan.md'].length,
|
||||
char_count_delta: 0,
|
||||
old_text: 'some text',
|
||||
new_text: 'better text',
|
||||
@@ -59,10 +59,10 @@ describe('validateEdit', () => {
|
||||
|
||||
it('warns when old_text appears multiple times', () => {
|
||||
const edit = makeEdit({
|
||||
file: 'plan2code-2--document.md',
|
||||
file: 'plan2code-2-document.md',
|
||||
old_text: 'repeated text',
|
||||
char_count_before: PROMPT_CONTENTS['plan2code-2--document.md'].length,
|
||||
char_count_after: PROMPT_CONTENTS['plan2code-2--document.md'].length,
|
||||
char_count_before: PROMPT_CONTENTS['plan2code-2-document.md'].length,
|
||||
char_count_after: PROMPT_CONTENTS['plan2code-2-document.md'].length,
|
||||
});
|
||||
const result = validateEdit(edit, PROMPT_CONTENTS);
|
||||
expect(result.valid).toBe(true);
|
||||
|
||||
@@ -32,14 +32,14 @@ function generateProposalId(): string {
|
||||
function readPromptFiles(plan2codeRoot: string): Record<string, string> {
|
||||
const srcDir = path.join(plan2codeRoot, 'src');
|
||||
const promptFiles = [
|
||||
'plan2code-1--plan.md',
|
||||
'plan2code-1b--revise-plan.md',
|
||||
'plan2code-2--document.md',
|
||||
'plan2code-3--implement.md',
|
||||
'plan2code-4--finalize.md',
|
||||
'plan2code---init.md',
|
||||
'plan2code---init-update.md',
|
||||
'plan2code---quick-task.md',
|
||||
'plan2code-1-plan.md',
|
||||
'plan2code-1b-revise-plan.md',
|
||||
'plan2code-2-document.md',
|
||||
'plan2code-3-implement.md',
|
||||
'plan2code-4-finalize.md',
|
||||
'plan2code-init.md',
|
||||
'plan2code-init-update.md',
|
||||
'plan2code-quick-task.md',
|
||||
];
|
||||
|
||||
const contents: Record<string, string> = {};
|
||||
|
||||
@@ -76,7 +76,7 @@ For each step (1–4), provide:
|
||||
|
||||
Numbered list. For each underperforming metric:
|
||||
1. **Metric:** [metric name] | **Value:** [actual] | **Target:** [target]
|
||||
- **File:** [plan2code-X--name.md]
|
||||
- **File:** [plan2code-X-name.md]
|
||||
- **Section:** [specific heading or section name]
|
||||
- **Hypothesis:** [specific gap in the prompt that would explain the metric miss]
|
||||
- **Confidence:** [High/Medium/Low] — [reason for confidence level]
|
||||
|
||||
@@ -67,7 +67,7 @@ Produce EXACTLY the following sections. The JSON block is parsed by machine —
|
||||
```json
|
||||
[
|
||||
{
|
||||
"file": "plan2code-X--name.md",
|
||||
"file": "plan2code-X-name.md",
|
||||
"rationale": "One sentence explaining what this edit fixes",
|
||||
"expected_metric_impact": "avg_metric_name: expected direction and magnitude",
|
||||
"char_count_before": 0,
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// All TypeScript interfaces for plan2code-metrics
|
||||
|
||||
export interface PromptVersions {
|
||||
plan: string; // sha256:... plan2code-1--plan.md
|
||||
revise_plan: string; // plan2code-1b--revise-plan.md
|
||||
document: string; // plan2code-2--document.md
|
||||
implement: string; // plan2code-3--implement.md
|
||||
finalize: string; // plan2code-4--finalize.md
|
||||
init: string; // plan2code---init.md
|
||||
init_update: string; // plan2code---init-update.md
|
||||
quick_task: string; // plan2code---quick-task.md
|
||||
plan: string; // sha256:... plan2code-1-plan.md
|
||||
revise_plan: string; // plan2code-1b-revise-plan.md
|
||||
document: string; // plan2code-2-document.md
|
||||
implement: string; // plan2code-3-implement.md
|
||||
finalize: string; // plan2code-4-finalize.md
|
||||
init: string; // plan2code-init.md
|
||||
init_update: string; // plan2code-init-update.md
|
||||
quick_task: string; // plan2code-quick-task.md
|
||||
}
|
||||
|
||||
export interface Step1PlanMetrics {
|
||||
|
||||
Reference in New Issue
Block a user