persona-harness 0.3.0-alpha.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/.persona/harness.jsonc +9 -0
- package/.persona/rules/backend/gradle-bootstrap.md +27 -0
- package/.persona/rules/backend/java-backend-bootstrap.md +28 -0
- package/.persona/rules/backend/java-common.md +22 -0
- package/.persona/rules/backend/layered-architecture.md +19 -0
- package/.persona/rules/backend/package-structure.md +21 -0
- package/.persona/rules/backend/spring-controller.md +19 -0
- package/.persona/rules/backend/spring-dto.md +21 -0
- package/.persona/rules/backend/spring-entity.md +22 -0
- package/.persona/rules/backend/spring-repository.md +22 -0
- package/.persona/rules/backend/spring-service.md +23 -0
- package/.persona/rules/backend/spring-test.md +32 -0
- package/.persona/rules/backend/step1-api-contract.md +29 -0
- package/.persona/rules/backend/step2-3-api-contract.md +24 -0
- package/.persona/rules/backend/validation-exception.md +18 -0
- package/.persona/rules/clean-code/abstraction.md +18 -0
- package/.persona/rules/clean-code/common.md +21 -0
- package/.persona/rules/clean-code/method-design.md +20 -0
- package/.persona/rules/clean-code/naming.md +19 -0
- package/.persona/rules/clean-code/oop.md +18 -0
- package/.persona/rules/clean-code/testability.md +19 -0
- package/CHANGELOG.md +40 -0
- package/LICENSE +201 -0
- package/README.ja.md +95 -0
- package/README.ko.md +95 -0
- package/README.md +125 -0
- package/README.zh-cn.md +95 -0
- package/dist/cli/bearshell.d.ts +12 -0
- package/dist/cli/bearshell.js +189 -0
- package/dist/cli/bearshell.js.map +1 -0
- package/dist/cli/history.d.ts +15 -0
- package/dist/cli/history.js +156 -0
- package/dist/cli/history.js.map +1 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/index.js +117 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +21 -0
- package/dist/cli/init.js +194 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/intake-profile.d.ts +52 -0
- package/dist/cli/intake-profile.js +167 -0
- package/dist/cli/intake-profile.js.map +1 -0
- package/dist/cli/intake.d.ts +14 -0
- package/dist/cli/intake.js +209 -0
- package/dist/cli/intake.js.map +1 -0
- package/dist/cli/plan-command.d.ts +4 -0
- package/dist/cli/plan-command.js +130 -0
- package/dist/cli/plan-command.js.map +1 -0
- package/dist/cli/plan-status.d.ts +11 -0
- package/dist/cli/plan-status.js +41 -0
- package/dist/cli/plan-status.js.map +1 -0
- package/dist/cli/plan.d.ts +10 -0
- package/dist/cli/plan.js +199 -0
- package/dist/cli/plan.js.map +1 -0
- package/dist/cli/policy.d.ts +7 -0
- package/dist/cli/policy.js +139 -0
- package/dist/cli/policy.js.map +1 -0
- package/dist/cli/report-status.d.ts +13 -0
- package/dist/cli/report-status.js +40 -0
- package/dist/cli/report-status.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/phase0/drift-detector.d.ts +24 -0
- package/dist/phase0/drift-detector.js +334 -0
- package/dist/phase0/drift-detector.js.map +1 -0
- package/dist/phase0/evidence.d.ts +9 -0
- package/dist/phase0/evidence.js +36 -0
- package/dist/phase0/evidence.js.map +1 -0
- package/dist/phase0/file-role.d.ts +5 -0
- package/dist/phase0/file-role.js +55 -0
- package/dist/phase0/file-role.js.map +1 -0
- package/dist/phase0/harness-config.d.ts +12 -0
- package/dist/phase0/harness-config.js +115 -0
- package/dist/phase0/harness-config.js.map +1 -0
- package/dist/phase0/hooks.d.ts +8 -0
- package/dist/phase0/hooks.js +127 -0
- package/dist/phase0/hooks.js.map +1 -0
- package/dist/phase0/injection.d.ts +2 -0
- package/dist/phase0/injection.js +77 -0
- package/dist/phase0/injection.js.map +1 -0
- package/dist/phase0/java-role-discovery.d.ts +6 -0
- package/dist/phase0/java-role-discovery.js +90 -0
- package/dist/phase0/java-role-discovery.js.map +1 -0
- package/dist/phase0/messages.d.ts +2 -0
- package/dist/phase0/messages.js +30 -0
- package/dist/phase0/messages.js.map +1 -0
- package/dist/phase0/policy-overlay.d.ts +12 -0
- package/dist/phase0/policy-overlay.js +171 -0
- package/dist/phase0/policy-overlay.js.map +1 -0
- package/dist/phase0/project-profile.d.ts +1 -0
- package/dist/phase0/project-profile.js +148 -0
- package/dist/phase0/project-profile.js.map +1 -0
- package/dist/phase0/rule-catalog.d.ts +14 -0
- package/dist/phase0/rule-catalog.js +77 -0
- package/dist/phase0/rule-catalog.js.map +1 -0
- package/dist/phase0/rule-diagnostics-report.d.ts +17 -0
- package/dist/phase0/rule-diagnostics-report.js +51 -0
- package/dist/phase0/rule-diagnostics-report.js.map +1 -0
- package/dist/phase0/rule-frontmatter-diagnostics.d.ts +19 -0
- package/dist/phase0/rule-frontmatter-diagnostics.js +65 -0
- package/dist/phase0/rule-frontmatter-diagnostics.js.map +1 -0
- package/dist/phase0/rule-frontmatter.d.ts +23 -0
- package/dist/phase0/rule-frontmatter.js +172 -0
- package/dist/phase0/rule-frontmatter.js.map +1 -0
- package/dist/phase0/rule-glob.d.ts +2 -0
- package/dist/phase0/rule-glob.js +38 -0
- package/dist/phase0/rule-glob.js.map +1 -0
- package/dist/phase0/rule-loader.d.ts +13 -0
- package/dist/phase0/rule-loader.js +143 -0
- package/dist/phase0/rule-loader.js.map +1 -0
- package/dist/phase0/shared-skill-router.d.ts +14 -0
- package/dist/phase0/shared-skill-router.js +85 -0
- package/dist/phase0/shared-skill-router.js.map +1 -0
- package/dist/phase0/store.d.ts +6 -0
- package/dist/phase0/store.js +14 -0
- package/dist/phase0/store.js.map +1 -0
- package/dist/phase0/target-file.d.ts +2 -0
- package/dist/phase0/target-file.js +41 -0
- package/dist/phase0/target-file.js.map +1 -0
- package/dist/phase0/types.d.ts +38 -0
- package/dist/phase0/types.js +2 -0
- package/dist/phase0/types.js.map +1 -0
- package/dist/phase1/observer/controller-repository-observer.d.ts +17 -0
- package/dist/phase1/observer/controller-repository-observer.js +210 -0
- package/dist/phase1/observer/controller-repository-observer.js.map +1 -0
- package/dist/phase1/observer/controller-sql-observer.d.ts +20 -0
- package/dist/phase1/observer/controller-sql-observer.js +148 -0
- package/dist/phase1/observer/controller-sql-observer.js.map +1 -0
- package/dist/phase1/observer/java-source.d.ts +9 -0
- package/dist/phase1/observer/java-source.js +88 -0
- package/dist/phase1/observer/java-source.js.map +1 -0
- package/dist/phase1/observer/report.d.ts +52 -0
- package/dist/phase1/observer/report.js +173 -0
- package/dist/phase1/observer/report.js.map +1 -0
- package/dist/phase1/observer/service-storage-observer.d.ts +20 -0
- package/dist/phase1/observer/service-storage-observer.js +155 -0
- package/dist/phase1/observer/service-storage-observer.js.map +1 -0
- package/dist/phase1/observer/test-contract-anchor-matchers.d.ts +10 -0
- package/dist/phase1/observer/test-contract-anchor-matchers.js +198 -0
- package/dist/phase1/observer/test-contract-anchor-matchers.js.map +1 -0
- package/dist/phase1/observer/test-contract-observer.d.ts +21 -0
- package/dist/phase1/observer/test-contract-observer.js +70 -0
- package/dist/phase1/observer/test-contract-observer.js.map +1 -0
- package/docs/README.md +34 -0
- package/docs/current/README.md +35 -0
- package/docs/current/java-backend-mvp-install-guide.md +160 -0
- package/docs/current/persona-harness-detailed-usage.md +782 -0
- package/docs/current/release/README.md +6 -0
- package/docs/current/release/release-checklist.md +113 -0
- package/docs/current/release/release-notes-template.md +68 -0
- package/docs/current/v0.3.0-alpha-publish-readiness.md +185 -0
- package/docs/current/v0.3.0-external-tester-feedback-template.md +214 -0
- package/docs/current/v0.3.0-external-tester-guide.md +217 -0
- package/docs/current/v0.3.0-gradle-spring-build-guidance.md +100 -0
- package/package.json +87 -0
- package/packages/shared-skills/skills/programming/SKILL.md +490 -0
- package/packages/shared-skills/skills/programming/references/java/README.md +193 -0
- package/packages/shared-skills/skills/programming/references/java/anti-patterns.md +85 -0
- package/packages/shared-skills/skills/programming/references/java/application-layer.md +200 -0
- package/packages/shared-skills/skills/programming/references/java/architecture.md +152 -0
- package/packages/shared-skills/skills/programming/references/java/backend.md +152 -0
- package/packages/shared-skills/skills/programming/references/java/code-quality-refactoring.md +146 -0
- package/packages/shared-skills/skills/programming/references/java/concurrency-discipline.md +98 -0
- package/packages/shared-skills/skills/programming/references/java/domain-model.md +214 -0
- package/packages/shared-skills/skills/programming/references/java/error-handling.md +179 -0
- package/packages/shared-skills/skills/programming/references/java/foundations.md +49 -0
- package/packages/shared-skills/skills/programming/references/java/java-idioms.md +108 -0
- package/packages/shared-skills/skills/programming/references/java/language-core.md +96 -0
- package/packages/shared-skills/skills/programming/references/java/method-and-naming.md +164 -0
- package/packages/shared-skills/skills/programming/references/java/object-collaboration.md +140 -0
- package/packages/shared-skills/skills/programming/references/java/performance-discipline.md +115 -0
- package/packages/shared-skills/skills/programming/references/java/repository-pattern.md +181 -0
- package/packages/shared-skills/skills/programming/references/java/technology-seams.md +92 -0
- package/packages/shared-skills/skills/programming/references/java/test-design.md +149 -0
- package/packages/shared-skills/skills/programming/references/java/testing.md +188 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intake.js","sourceRoot":"","sources":["../../src/cli/intake.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CliRunResult } from "./bearshell.js";
|
|
2
|
+
import { type PlanOptions } from "./plan.js";
|
|
3
|
+
export declare function planUsage(invocation?: string): string;
|
|
4
|
+
export declare function runPlanCommand(args: readonly string[], options?: PlanOptions, invocationName?: string): CliRunResult;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { IMPLEMENTATION_REPORT_PATH, PlanDraftError, PLAN_PATH, REVIEW_REPORT_PATH, initializeWorkflowPlan, } from "./plan.js";
|
|
2
|
+
import { PlanStatusError, readWorkflowPlanStatus, updateWorkflowPlanStatus, } from "./plan-status.js";
|
|
3
|
+
import { WorkflowReportStatusError, parseWorkflowReportKind, updateWorkflowReportStatus, } from "./report-status.js";
|
|
4
|
+
export function planUsage(invocation = "ph") {
|
|
5
|
+
return [
|
|
6
|
+
`Usage: ${invocation} plan [--force | --status | --accept | --revise | --report-filled <implementation|review>]`,
|
|
7
|
+
"",
|
|
8
|
+
"Creates and manages a blackbear architecture plan before implementation.",
|
|
9
|
+
"",
|
|
10
|
+
"Options:",
|
|
11
|
+
" --force Replace existing workflow drafts.",
|
|
12
|
+
" --status Read the plan acceptance status.",
|
|
13
|
+
" --accept Mark the plan status as accepted.",
|
|
14
|
+
" --revise Mark the plan status as needs-revision.",
|
|
15
|
+
" --report-filled <implementation|review>",
|
|
16
|
+
" Mark a filled workflow report as filled.",
|
|
17
|
+
"",
|
|
18
|
+
"Output:",
|
|
19
|
+
`- ${PLAN_PATH}`,
|
|
20
|
+
`- ${IMPLEMENTATION_REPORT_PATH}`,
|
|
21
|
+
`- ${REVIEW_REPORT_PATH}`,
|
|
22
|
+
"",
|
|
23
|
+
"Scope:",
|
|
24
|
+
"- Java/Spring backend Clean Code planning surface",
|
|
25
|
+
"- Uses README and backend project profile as planning context",
|
|
26
|
+
"- No rule enforcement",
|
|
27
|
+
"- No autonomous implementation",
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|
|
30
|
+
function parsePlanArgs(args) {
|
|
31
|
+
if (args.length === 0) {
|
|
32
|
+
return { kind: "run", force: false };
|
|
33
|
+
}
|
|
34
|
+
if (args[0] === "--report-filled") {
|
|
35
|
+
const reportKind = parseWorkflowReportKind(args[1]);
|
|
36
|
+
if (args.length !== 2 || reportKind === undefined) {
|
|
37
|
+
return { kind: "invalid", message: "Report kind must be implementation or review." };
|
|
38
|
+
}
|
|
39
|
+
return { kind: "report-filled", reportKind };
|
|
40
|
+
}
|
|
41
|
+
if (args.length > 1) {
|
|
42
|
+
return { kind: "invalid", message: "Plan command accepts one option at a time." };
|
|
43
|
+
}
|
|
44
|
+
const arg = args[0];
|
|
45
|
+
if (arg === "--help" || arg === "-h") {
|
|
46
|
+
return { kind: "help" };
|
|
47
|
+
}
|
|
48
|
+
if (arg === "--force") {
|
|
49
|
+
return { kind: "run", force: true };
|
|
50
|
+
}
|
|
51
|
+
if (arg === "--status") {
|
|
52
|
+
return { kind: "status" };
|
|
53
|
+
}
|
|
54
|
+
if (arg === "--accept") {
|
|
55
|
+
return { kind: "accept" };
|
|
56
|
+
}
|
|
57
|
+
if (arg === "--revise") {
|
|
58
|
+
return { kind: "revise" };
|
|
59
|
+
}
|
|
60
|
+
return { kind: "invalid", message: `Unknown option: ${arg}` };
|
|
61
|
+
}
|
|
62
|
+
function statusOutput(title, planPath, status) {
|
|
63
|
+
return [`Persona Harness ${title}.`, "", `Plan: ${planPath}`, `Status: ${status}`].join("\n") + "\n";
|
|
64
|
+
}
|
|
65
|
+
function reportStatusOutput(title, relativePath, reportPath, status) {
|
|
66
|
+
return [
|
|
67
|
+
`Persona Harness ${title}.`,
|
|
68
|
+
"",
|
|
69
|
+
`Workflow report: ${relativePath}`,
|
|
70
|
+
`Path: ${reportPath}`,
|
|
71
|
+
`Status: ${status}`,
|
|
72
|
+
].join("\n") + "\n";
|
|
73
|
+
}
|
|
74
|
+
function updateStatus(status, options) {
|
|
75
|
+
const result = updateWorkflowPlanStatus(status, options);
|
|
76
|
+
const title = status === "accepted" ? "plan accepted" : "plan marked for revision";
|
|
77
|
+
return { status: 0, stdout: statusOutput(title, result.planPath, result.status), stderr: "" };
|
|
78
|
+
}
|
|
79
|
+
export function runPlanCommand(args, options = {}, invocationName = "ph") {
|
|
80
|
+
const parsed = parsePlanArgs(args);
|
|
81
|
+
if (parsed.kind === "help") {
|
|
82
|
+
return { status: 0, stdout: `${planUsage(invocationName)}\n`, stderr: "" };
|
|
83
|
+
}
|
|
84
|
+
if (parsed.kind === "invalid") {
|
|
85
|
+
return { status: 1, stdout: "", stderr: `${parsed.message}\n\n${planUsage(invocationName)}\n` };
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
if (parsed.kind === "status") {
|
|
89
|
+
const result = readWorkflowPlanStatus(options);
|
|
90
|
+
return { status: 0, stdout: statusOutput("plan status", result.planPath, result.status), stderr: "" };
|
|
91
|
+
}
|
|
92
|
+
if (parsed.kind === "accept") {
|
|
93
|
+
return updateStatus("accepted", options);
|
|
94
|
+
}
|
|
95
|
+
if (parsed.kind === "revise") {
|
|
96
|
+
return updateStatus("needs-revision", options);
|
|
97
|
+
}
|
|
98
|
+
if (parsed.kind === "report-filled") {
|
|
99
|
+
const result = updateWorkflowReportStatus(parsed.reportKind, "filled", options);
|
|
100
|
+
return {
|
|
101
|
+
status: 0,
|
|
102
|
+
stdout: reportStatusOutput("workflow report filled", result.relativePath, result.reportPath, result.status),
|
|
103
|
+
stderr: "",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const planPath = initializeWorkflowPlan(options, parsed.force);
|
|
107
|
+
return {
|
|
108
|
+
status: 0,
|
|
109
|
+
stdout: [
|
|
110
|
+
"Persona Harness blackbear plan draft created.",
|
|
111
|
+
"",
|
|
112
|
+
`Plan: ${planPath}`,
|
|
113
|
+
"",
|
|
114
|
+
"Next:",
|
|
115
|
+
`- Review and complete ${PLAN_PATH} before implementation.`,
|
|
116
|
+
"- Run `ph plan --accept` before implementation, or `ph plan --revise` if the plan needs changes.",
|
|
117
|
+
`- Fill ${IMPLEMENTATION_REPORT_PATH} after implementation, then run \`ph plan --report-filled implementation\`.`,
|
|
118
|
+
`- Fill ${REVIEW_REPORT_PATH} after review/manual QA, then run \`ph plan --report-filled review\`.`,
|
|
119
|
+
].join("\n") + "\n",
|
|
120
|
+
stderr: "",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
if (error instanceof PlanDraftError || error instanceof PlanStatusError || error instanceof WorkflowReportStatusError) {
|
|
125
|
+
return { status: 1, stdout: "", stderr: `${error.message}\n` };
|
|
126
|
+
}
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=plan-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-command.js","sourceRoot":"","sources":["../../src/cli/plan-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type PlanOptions } from "./plan.js";
|
|
2
|
+
export type PlanAcceptanceStatus = "draft" | "needs-revision" | "accepted";
|
|
3
|
+
export type PlanStatusResult = {
|
|
4
|
+
readonly planPath: string;
|
|
5
|
+
readonly status: string;
|
|
6
|
+
};
|
|
7
|
+
export declare class PlanStatusError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
export declare function readWorkflowPlanStatus(options?: PlanOptions): PlanStatusResult;
|
|
11
|
+
export declare function updateWorkflowPlanStatus(status: PlanAcceptanceStatus, options?: PlanOptions): PlanStatusResult;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { PLAN_PATH } from "./plan.js";
|
|
5
|
+
export class PlanStatusError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "PlanStatusError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function resolvePlanPath(options) {
|
|
12
|
+
const projectDir = resolve(options.projectDir ?? process.cwd());
|
|
13
|
+
return join(projectDir, PLAN_PATH);
|
|
14
|
+
}
|
|
15
|
+
function readPlanText(planPath) {
|
|
16
|
+
if (!existsSync(planPath)) {
|
|
17
|
+
throw new PlanStatusError("No workflow plan found. Run ph plan first.");
|
|
18
|
+
}
|
|
19
|
+
return readFileSync(planPath, "utf8");
|
|
20
|
+
}
|
|
21
|
+
function extractStatus(planText) {
|
|
22
|
+
const match = planText.match(/^Status:\s*(.+?)\s*$/m);
|
|
23
|
+
if (match?.[1] === undefined) {
|
|
24
|
+
throw new PlanStatusError("No Status line found in .persona/workflow/plan.md.");
|
|
25
|
+
}
|
|
26
|
+
return match[1].trim();
|
|
27
|
+
}
|
|
28
|
+
export function readWorkflowPlanStatus(options = {}) {
|
|
29
|
+
const planPath = resolvePlanPath(options);
|
|
30
|
+
const planText = readPlanText(planPath);
|
|
31
|
+
return { planPath, status: extractStatus(planText) };
|
|
32
|
+
}
|
|
33
|
+
export function updateWorkflowPlanStatus(status, options = {}) {
|
|
34
|
+
const planPath = resolvePlanPath(options);
|
|
35
|
+
const planText = readPlanText(planPath);
|
|
36
|
+
extractStatus(planText);
|
|
37
|
+
const updatedPlan = planText.replace(/^Status:\s*.+?\s*$/m, `Status: ${status}`);
|
|
38
|
+
writeFileSync(planPath, updatedPlan);
|
|
39
|
+
return { planPath, status };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=plan-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-status.js","sourceRoot":"","sources":["../../src/cli/plan-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,OAAO,EAAE,SAAS,EAAoB,MAAM,WAAW,CAAA;AASvD,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;IAC/B,CAAC;CACF;AAED,SAAS,eAAe,CAAC,OAAoB;IAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;IAC/D,OAAO,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB;IACpC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,eAAe,CAAC,4CAA4C,CAAC,CAAA;IACzE,CAAC;IACD,OAAO,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;IACrD,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,eAAe,CAAC,oDAAoD,CAAC,CAAA;IACjF,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAuB,EAAE;IAC9D,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;IACzC,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;IACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,MAA4B,EAC5B,UAAuB,EAAE;IAEzB,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;IACzC,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;IACvC,aAAa,CAAC,QAAQ,CAAC,CAAA;IAEvB,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,WAAW,MAAM,EAAE,CAAC,CAAA;IAChF,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;IACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;AAC7B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type PlanOptions = {
|
|
2
|
+
readonly projectDir?: string;
|
|
3
|
+
};
|
|
4
|
+
export declare class PlanDraftError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare const PLAN_PATH = ".persona/workflow/plan.md";
|
|
8
|
+
export declare const IMPLEMENTATION_REPORT_PATH = ".persona/workflow/implementation-report.md";
|
|
9
|
+
export declare const REVIEW_REPORT_PATH = ".persona/workflow/review-report.md";
|
|
10
|
+
export declare function initializeWorkflowPlan(options?: PlanOptions, force?: boolean): string;
|
package/dist/cli/plan.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { loadBackendPolicyOverlay } from "../phase0/policy-overlay.js";
|
|
5
|
+
import { loadBackendProjectProfileSummary } from "../phase0/project-profile.js";
|
|
6
|
+
export class PlanDraftError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "PlanDraftError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export const PLAN_PATH = ".persona/workflow/plan.md";
|
|
13
|
+
export const IMPLEMENTATION_REPORT_PATH = ".persona/workflow/implementation-report.md";
|
|
14
|
+
export const REVIEW_REPORT_PATH = ".persona/workflow/review-report.md";
|
|
15
|
+
const README_PATH = "README.md";
|
|
16
|
+
function readReadmeHeading(projectDir) {
|
|
17
|
+
const readmePath = join(projectDir, README_PATH);
|
|
18
|
+
if (!existsSync(readmePath)) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
const readme = readFileSync(readmePath, "utf8");
|
|
22
|
+
for (const line of readme.split(/\r?\n/)) {
|
|
23
|
+
const heading = line.match(/^#\s+(.+)$/);
|
|
24
|
+
if (heading?.[1] !== undefined) {
|
|
25
|
+
return heading[1].trim();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
function profileSummaryLines(projectDir) {
|
|
31
|
+
const summary = loadBackendProjectProfileSummary(projectDir);
|
|
32
|
+
if (summary.length > 0) {
|
|
33
|
+
return summary;
|
|
34
|
+
}
|
|
35
|
+
return [
|
|
36
|
+
"프로젝트 프로필 요약:",
|
|
37
|
+
"- 응답된 항목 없음",
|
|
38
|
+
"",
|
|
39
|
+
"프로필 사용 원칙:",
|
|
40
|
+
"- 이 요약은 구현 전 architecture/technology plan 참고용이다.",
|
|
41
|
+
"- 사용자의 README/요구사항과 명시 지시가 우선한다.",
|
|
42
|
+
"- 이 요약은 rule enforcement나 product-quality 보증이 아니다.",
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
function policyOverlayLines(projectDir) {
|
|
46
|
+
return loadBackendPolicyOverlay(projectDir).summaryLines;
|
|
47
|
+
}
|
|
48
|
+
function readmeLines(projectDir) {
|
|
49
|
+
const heading = readReadmeHeading(projectDir);
|
|
50
|
+
return [
|
|
51
|
+
`Requirements source: \`${README_PATH}\``,
|
|
52
|
+
heading === undefined ? "README status: missing" : `README heading: ${heading}`,
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
function createPlanDraft(projectDir) {
|
|
56
|
+
const policyOverlaySummary = policyOverlayLines(projectDir);
|
|
57
|
+
return [
|
|
58
|
+
"# Blackbear Architecture Plan",
|
|
59
|
+
"",
|
|
60
|
+
"Role: `blackbear`",
|
|
61
|
+
"Status: draft",
|
|
62
|
+
"",
|
|
63
|
+
"## Inputs",
|
|
64
|
+
"",
|
|
65
|
+
...readmeLines(projectDir),
|
|
66
|
+
"",
|
|
67
|
+
...profileSummaryLines(projectDir),
|
|
68
|
+
...(policyOverlaySummary.length > 0 ? ["", ...policyOverlaySummary] : []),
|
|
69
|
+
"",
|
|
70
|
+
"## Architecture / Technology Plan",
|
|
71
|
+
"",
|
|
72
|
+
"- [ ] 요구사항의 핵심 유스케이스를 README 기준으로 정리한다.",
|
|
73
|
+
"- [ ] Java/Spring Gradle 기준의 기술 선택을 명시한다.",
|
|
74
|
+
"- [ ] package/layer 구조를 정한다.",
|
|
75
|
+
"- [ ] storage/persistence 선택과 repository boundary를 정한다.",
|
|
76
|
+
"- [ ] DTO boundary와 domain behavior 기준을 정한다.",
|
|
77
|
+
"",
|
|
78
|
+
"## Non-Goals",
|
|
79
|
+
"",
|
|
80
|
+
"- rule enforcement가 아니다.",
|
|
81
|
+
"- generated app product-quality 보증이 아니다.",
|
|
82
|
+
"- frontend/infra workflow가 아니다.",
|
|
83
|
+
"- TDD workflow 강제가 아니다.",
|
|
84
|
+
"- autonomous subagent 실행이 아니다.",
|
|
85
|
+
"",
|
|
86
|
+
"## Acceptance",
|
|
87
|
+
"",
|
|
88
|
+
"- implementation must not start until this plan is reviewed or accepted.",
|
|
89
|
+
"- 구현 후에는 Gradle test/build와 manual QA evidence를 별도 report에 남긴다.",
|
|
90
|
+
"",
|
|
91
|
+
].join("\n");
|
|
92
|
+
}
|
|
93
|
+
function createImplementationReportTemplate(projectDir) {
|
|
94
|
+
return [
|
|
95
|
+
"# Jaeki Implementation Report",
|
|
96
|
+
"",
|
|
97
|
+
"Role: `jaeki`",
|
|
98
|
+
"Status: template",
|
|
99
|
+
"",
|
|
100
|
+
"## Inputs",
|
|
101
|
+
"",
|
|
102
|
+
...readmeLines(projectDir),
|
|
103
|
+
"",
|
|
104
|
+
"Plan source: `.persona/workflow/plan.md`",
|
|
105
|
+
"",
|
|
106
|
+
"## Implemented Files",
|
|
107
|
+
"",
|
|
108
|
+
"- [ ] 작성/수정한 production files",
|
|
109
|
+
"- [ ] 작성/수정한 configuration files",
|
|
110
|
+
"- [ ] 작성/수정한 test files",
|
|
111
|
+
"",
|
|
112
|
+
"## Verification",
|
|
113
|
+
"",
|
|
114
|
+
"- [ ] `gradle test`",
|
|
115
|
+
"- [ ] `gradle build`",
|
|
116
|
+
"- [ ] 실행 가능한 Spring Boot 앱이면 `gradle bootRun`",
|
|
117
|
+
"",
|
|
118
|
+
"## Manual QA",
|
|
119
|
+
"",
|
|
120
|
+
"- [ ] HTTP happy path를 curl 또는 동등한 HTTP client로 실행했다.",
|
|
121
|
+
"- [ ] HTTP failure path를 curl 또는 동등한 HTTP client로 실행했다.",
|
|
122
|
+
"- [ ] Manual QA가 불가능하면 사유와 stderr/핵심 로그를 기록한다.",
|
|
123
|
+
"",
|
|
124
|
+
"## Status Lifecycle",
|
|
125
|
+
"",
|
|
126
|
+
"- 채운 뒤에는 `ph plan --report-filled implementation`을 실행한다.",
|
|
127
|
+
"",
|
|
128
|
+
"## Notes",
|
|
129
|
+
"",
|
|
130
|
+
"- 구현 중 바뀐 결정:",
|
|
131
|
+
"- 남은 한계:",
|
|
132
|
+
"",
|
|
133
|
+
].join("\n");
|
|
134
|
+
}
|
|
135
|
+
function createReviewReportTemplate(projectDir) {
|
|
136
|
+
return [
|
|
137
|
+
"# Roach Review Report",
|
|
138
|
+
"",
|
|
139
|
+
"Role: `roach`",
|
|
140
|
+
"Status: template",
|
|
141
|
+
"",
|
|
142
|
+
"## Inputs",
|
|
143
|
+
"",
|
|
144
|
+
...readmeLines(projectDir),
|
|
145
|
+
"",
|
|
146
|
+
"Plan source: `.persona/workflow/plan.md`",
|
|
147
|
+
"Implementation report: `.persona/workflow/implementation-report.md`",
|
|
148
|
+
"",
|
|
149
|
+
"## Requirements Check",
|
|
150
|
+
"",
|
|
151
|
+
"- [ ] README 요구사항이 구현 결과와 대응된다.",
|
|
152
|
+
"- [ ] 미구현 요구사항이 있으면 명시한다.",
|
|
153
|
+
"",
|
|
154
|
+
"## Boundary Review",
|
|
155
|
+
"",
|
|
156
|
+
"- [ ] Controller는 HTTP request/response와 Service 위임만 담당한다.",
|
|
157
|
+
"- [ ] Application Service는 use-case 흐름만 조율한다.",
|
|
158
|
+
"- [ ] Repository port는 domain에 있고 구현체는 infrastructure에 있다.",
|
|
159
|
+
"- [ ] Request/Response DTO와 Command/Result DTO 경계가 분리된다.",
|
|
160
|
+
"- [ ] Domain model은 자신의 상태 판단/행동을 스스로 가진다.",
|
|
161
|
+
"",
|
|
162
|
+
"## Verification Review",
|
|
163
|
+
"",
|
|
164
|
+
"- [ ] `gradle test` 결과를 확인했다.",
|
|
165
|
+
"- [ ] `gradle build` 결과를 확인했다.",
|
|
166
|
+
"- [ ] 실행 가능한 Spring Boot 앱이면 `gradle bootRun` 결과를 확인했다.",
|
|
167
|
+
"- [ ] HTTP happy path / failure path manual QA evidence를 확인했다.",
|
|
168
|
+
"",
|
|
169
|
+
"## Status Lifecycle",
|
|
170
|
+
"",
|
|
171
|
+
"- 채운 뒤에는 `ph plan --report-filled review`를 실행한다.",
|
|
172
|
+
"",
|
|
173
|
+
"## Remaining Limits",
|
|
174
|
+
"",
|
|
175
|
+
"- product-quality 보증이 아닌 smoke/review evidence로 남긴다.",
|
|
176
|
+
"- 남은 리스크:",
|
|
177
|
+
"",
|
|
178
|
+
].join("\n");
|
|
179
|
+
}
|
|
180
|
+
function existingWorkflowPaths(projectDir) {
|
|
181
|
+
return [PLAN_PATH, IMPLEMENTATION_REPORT_PATH, REVIEW_REPORT_PATH].filter((path) => existsSync(join(projectDir, path)));
|
|
182
|
+
}
|
|
183
|
+
export function initializeWorkflowPlan(options = {}, force = false) {
|
|
184
|
+
const projectDir = resolve(options.projectDir ?? process.cwd());
|
|
185
|
+
const workflowDir = join(projectDir, ".persona", "workflow");
|
|
186
|
+
const planPath = join(projectDir, PLAN_PATH);
|
|
187
|
+
const implementationReportPath = join(projectDir, IMPLEMENTATION_REPORT_PATH);
|
|
188
|
+
const reviewReportPath = join(projectDir, REVIEW_REPORT_PATH);
|
|
189
|
+
const existingPaths = existingWorkflowPaths(projectDir);
|
|
190
|
+
if (existingPaths.length > 0 && !force) {
|
|
191
|
+
throw new PlanDraftError(`${existingPaths.join(", ")} already exists. Re-run with --force to replace the drafts.`);
|
|
192
|
+
}
|
|
193
|
+
mkdirSync(workflowDir, { recursive: true });
|
|
194
|
+
writeFileSync(planPath, createPlanDraft(projectDir));
|
|
195
|
+
writeFileSync(implementationReportPath, createImplementationReportTemplate(projectDir));
|
|
196
|
+
writeFileSync(reviewReportPath, createReviewReportTemplate(projectDir));
|
|
197
|
+
return planPath;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/cli/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CliRunResult } from "./bearshell.js";
|
|
2
|
+
type PolicyOptions = {
|
|
3
|
+
readonly projectDir?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function policyUsage(invocation?: string): string;
|
|
6
|
+
export declare function runPolicyCommand(args: readonly string[], options?: PolicyOptions, invocationName?: string): CliRunResult;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
const POLICY_OVERLAY_PATH = ".persona/policies/overlay.jsonc";
|
|
5
|
+
const COMPANY_BACKEND_POLICY_PATH = ".persona/policies/company/backend.md";
|
|
6
|
+
const PERSONAL_BACKEND_POLICY_PATH = ".persona/policies/personal/backend.md";
|
|
7
|
+
const POLICY_FILES = [
|
|
8
|
+
{
|
|
9
|
+
path: POLICY_OVERLAY_PATH,
|
|
10
|
+
contents: `${JSON.stringify({
|
|
11
|
+
schema: "persona.policy-overlay.v1",
|
|
12
|
+
status: "draft",
|
|
13
|
+
scope: {
|
|
14
|
+
role: "backend",
|
|
15
|
+
mvp: "java-spring-clean-code",
|
|
16
|
+
productized: false,
|
|
17
|
+
},
|
|
18
|
+
enabled: true,
|
|
19
|
+
priority: ["company", "personal", "clean-code-baseline"],
|
|
20
|
+
sources: {
|
|
21
|
+
company: COMPANY_BACKEND_POLICY_PATH,
|
|
22
|
+
personal: PERSONAL_BACKEND_POLICY_PATH,
|
|
23
|
+
},
|
|
24
|
+
limits: {
|
|
25
|
+
maxBulletsPerSource: 5,
|
|
26
|
+
},
|
|
27
|
+
}, null, 2)}\n`,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
path: COMPANY_BACKEND_POLICY_PATH,
|
|
31
|
+
contents: [
|
|
32
|
+
"# Backend Company Policy",
|
|
33
|
+
"",
|
|
34
|
+
"<!-- Add company/team backend policy bullets here. -->",
|
|
35
|
+
"",
|
|
36
|
+
].join("\n"),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
path: PERSONAL_BACKEND_POLICY_PATH,
|
|
40
|
+
contents: [
|
|
41
|
+
"# Backend Personal Philosophy",
|
|
42
|
+
"",
|
|
43
|
+
"<!-- Add personal backend philosophy bullets here. -->",
|
|
44
|
+
"",
|
|
45
|
+
].join("\n"),
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
function parsePolicyArgs(args) {
|
|
49
|
+
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|
50
|
+
return { kind: "help" };
|
|
51
|
+
}
|
|
52
|
+
const command = args[0];
|
|
53
|
+
if (command !== "init") {
|
|
54
|
+
return { kind: "invalid", message: `Unknown policy command: ${command}` };
|
|
55
|
+
}
|
|
56
|
+
let force = false;
|
|
57
|
+
for (const arg of args.slice(1)) {
|
|
58
|
+
if (arg === "--help" || arg === "-h") {
|
|
59
|
+
return { kind: "help" };
|
|
60
|
+
}
|
|
61
|
+
if (arg === "--force") {
|
|
62
|
+
force = true;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
return { kind: "invalid", message: `Unknown option: ${arg}` };
|
|
66
|
+
}
|
|
67
|
+
return { kind: "init", force };
|
|
68
|
+
}
|
|
69
|
+
export function policyUsage(invocation = "ph") {
|
|
70
|
+
return [
|
|
71
|
+
`Usage: ${invocation} policy <command> [args...]`,
|
|
72
|
+
"",
|
|
73
|
+
"Commands:",
|
|
74
|
+
" init [--force] Create backend-only company/personal policy overlay files.",
|
|
75
|
+
"",
|
|
76
|
+
"Output:",
|
|
77
|
+
`- ${POLICY_OVERLAY_PATH}`,
|
|
78
|
+
`- ${COMPANY_BACKEND_POLICY_PATH}`,
|
|
79
|
+
`- ${PERSONAL_BACKEND_POLICY_PATH}`,
|
|
80
|
+
"",
|
|
81
|
+
"Scope:",
|
|
82
|
+
"- Java/Spring backend planning context",
|
|
83
|
+
"- No rule enforcement",
|
|
84
|
+
"- No frontend/infra/global policy loading",
|
|
85
|
+
].join("\n");
|
|
86
|
+
}
|
|
87
|
+
function writePolicyFiles(projectDir, force) {
|
|
88
|
+
const existing = POLICY_FILES.filter((file) => existsSync(join(projectDir, file.path))).map((file) => file.path);
|
|
89
|
+
if (existing.length > 0 && !force) {
|
|
90
|
+
throw new Error(`${existing.join(", ")} already exists. Re-run with --force to replace policy overlay files.`);
|
|
91
|
+
}
|
|
92
|
+
for (const file of POLICY_FILES) {
|
|
93
|
+
const targetPath = join(projectDir, file.path);
|
|
94
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
95
|
+
writeFileSync(targetPath, file.contents);
|
|
96
|
+
}
|
|
97
|
+
return POLICY_FILES.map((file) => file.path);
|
|
98
|
+
}
|
|
99
|
+
export function runPolicyCommand(args, options = {}, invocationName = "ph") {
|
|
100
|
+
const parsed = parsePolicyArgs(args);
|
|
101
|
+
if (parsed.kind === "help") {
|
|
102
|
+
return { status: 0, stdout: `${policyUsage(invocationName)}\n`, stderr: "" };
|
|
103
|
+
}
|
|
104
|
+
if (parsed.kind === "invalid") {
|
|
105
|
+
return { status: 1, stdout: "", stderr: `${parsed.message}\n\n${policyUsage(invocationName)}\n` };
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const projectDir = resolve(options.projectDir ?? process.cwd());
|
|
109
|
+
const written = writePolicyFiles(projectDir, parsed.force);
|
|
110
|
+
return {
|
|
111
|
+
status: 0,
|
|
112
|
+
stdout: [
|
|
113
|
+
"Persona Harness policy overlay initialized.",
|
|
114
|
+
"",
|
|
115
|
+
"Installed:",
|
|
116
|
+
...written.map((path) => `- ${path}`),
|
|
117
|
+
"",
|
|
118
|
+
"Next:",
|
|
119
|
+
"- Fill company/personal backend policy bullets.",
|
|
120
|
+
"- Run ph plan before implementation.",
|
|
121
|
+
"",
|
|
122
|
+
"Scope:",
|
|
123
|
+
"- backend-only planning/injection context",
|
|
124
|
+
"- diagnostics-only fallback",
|
|
125
|
+
"- no enforcement gate",
|
|
126
|
+
"",
|
|
127
|
+
].join("\n"),
|
|
128
|
+
stderr: "",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
return {
|
|
133
|
+
status: 1,
|
|
134
|
+
stdout: "",
|
|
135
|
+
stderr: `${error instanceof Error ? error.message : String(error)}\n`,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/cli/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PlanOptions } from "./plan.js";
|
|
2
|
+
export type WorkflowReportKind = "implementation" | "review";
|
|
3
|
+
export type WorkflowReportStatus = "filled";
|
|
4
|
+
export type WorkflowReportStatusResult = {
|
|
5
|
+
readonly reportPath: string;
|
|
6
|
+
readonly relativePath: string;
|
|
7
|
+
readonly status: WorkflowReportStatus;
|
|
8
|
+
};
|
|
9
|
+
export declare class WorkflowReportStatusError extends Error {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
export declare function parseWorkflowReportKind(value: string | undefined): WorkflowReportKind | undefined;
|
|
13
|
+
export declare function updateWorkflowReportStatus(kind: WorkflowReportKind, status: WorkflowReportStatus, options?: PlanOptions): WorkflowReportStatusResult;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { IMPLEMENTATION_REPORT_PATH, REVIEW_REPORT_PATH } from "./plan.js";
|
|
5
|
+
export class WorkflowReportStatusError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "WorkflowReportStatusError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function reportPathForKind(kind) {
|
|
12
|
+
if (kind === "implementation") {
|
|
13
|
+
return IMPLEMENTATION_REPORT_PATH;
|
|
14
|
+
}
|
|
15
|
+
return REVIEW_REPORT_PATH;
|
|
16
|
+
}
|
|
17
|
+
export function parseWorkflowReportKind(value) {
|
|
18
|
+
if (value === "implementation") {
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
if (value === "review") {
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
export function updateWorkflowReportStatus(kind, status, options = {}) {
|
|
27
|
+
const projectDir = resolve(options.projectDir ?? process.cwd());
|
|
28
|
+
const relativePath = reportPathForKind(kind);
|
|
29
|
+
const reportPath = join(projectDir, relativePath);
|
|
30
|
+
if (!existsSync(reportPath)) {
|
|
31
|
+
throw new WorkflowReportStatusError(`No ${kind} report found. Run ph plan first.`);
|
|
32
|
+
}
|
|
33
|
+
const reportText = readFileSync(reportPath, "utf8");
|
|
34
|
+
if (!/^Status:\s*.+?\s*$/m.test(reportText)) {
|
|
35
|
+
throw new WorkflowReportStatusError(`No Status line found in ${relativePath}.`);
|
|
36
|
+
}
|
|
37
|
+
writeFileSync(reportPath, reportText.replace(/^Status:\s*.+?\s*$/m, `Status: ${status}`));
|
|
38
|
+
return { reportPath, relativePath, status };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=report-status.js.map
|