openplanr 1.2.6 → 1.2.8
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/README.md +54 -1
- package/dist/ai/prompts/prompt-builder.d.ts +48 -0
- package/dist/ai/prompts/prompt-builder.d.ts.map +1 -1
- package/dist/ai/prompts/prompt-builder.js +57 -1
- package/dist/ai/prompts/prompt-builder.js.map +1 -1
- package/dist/ai/prompts/system-prompts.d.ts +23 -0
- package/dist/ai/prompts/system-prompts.d.ts.map +1 -1
- package/dist/ai/prompts/system-prompts.js +98 -0
- package/dist/ai/prompts/system-prompts.js.map +1 -1
- package/dist/ai/schemas/ai-response-schemas.d.ts +68 -0
- package/dist/ai/schemas/ai-response-schemas.d.ts.map +1 -1
- package/dist/ai/schemas/ai-response-schemas.js +81 -0
- package/dist/ai/schemas/ai-response-schemas.js.map +1 -1
- package/dist/ai/types.d.ts +2 -0
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/ai/types.js +2 -0
- package/dist/ai/types.js.map +1 -1
- package/dist/cli/commands/context.d.ts +6 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +45 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/export.d.ts.map +1 -1
- package/dist/cli/commands/export.js +8 -0
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/report-linter.d.ts +6 -0
- package/dist/cli/commands/report-linter.d.ts.map +1 -0
- package/dist/cli/commands/report-linter.js +61 -0
- package/dist/cli/commands/report-linter.js.map +1 -0
- package/dist/cli/commands/report.d.ts +6 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +150 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/revise.d.ts +23 -0
- package/dist/cli/commands/revise.d.ts.map +1 -0
- package/dist/cli/commands/revise.js +502 -0
- package/dist/cli/commands/revise.js.map +1 -0
- package/dist/cli/commands/story.d.ts.map +1 -1
- package/dist/cli/commands/story.js +31 -0
- package/dist/cli/commands/story.js.map +1 -1
- package/dist/cli/commands/voice.d.ts +6 -0
- package/dist/cli/commands/voice.d.ts.map +1 -0
- package/dist/cli/commands/voice.js +64 -0
- package/dist/cli/commands/voice.js.map +1 -0
- package/dist/cli/index.js +10 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/models/schema.d.ts +63 -0
- package/dist/models/schema.d.ts.map +1 -1
- package/dist/models/schema.js +31 -0
- package/dist/models/schema.js.map +1 -1
- package/dist/models/types.d.ts +280 -0
- package/dist/models/types.d.ts.map +1 -1
- package/dist/services/atomic-write-service.d.ts +41 -0
- package/dist/services/atomic-write-service.d.ts.map +1 -0
- package/dist/services/atomic-write-service.js +87 -0
- package/dist/services/atomic-write-service.js.map +1 -0
- package/dist/services/audit-log-service.d.ts +50 -0
- package/dist/services/audit-log-service.d.ts.map +1 -0
- package/dist/services/audit-log-service.js +213 -0
- package/dist/services/audit-log-service.js.map +1 -0
- package/dist/services/cascade-service.d.ts +62 -0
- package/dist/services/cascade-service.d.ts.map +1 -0
- package/dist/services/cascade-service.js +189 -0
- package/dist/services/cascade-service.js.map +1 -0
- package/dist/services/context-pack-service.d.ts +12 -0
- package/dist/services/context-pack-service.d.ts.map +1 -0
- package/dist/services/context-pack-service.js +155 -0
- package/dist/services/context-pack-service.js.map +1 -0
- package/dist/services/diff-service.d.ts +18 -0
- package/dist/services/diff-service.d.ts.map +1 -0
- package/dist/services/diff-service.js +35 -0
- package/dist/services/diff-service.js.map +1 -0
- package/dist/services/distribution-service.d.ts +18 -0
- package/dist/services/distribution-service.d.ts.map +1 -0
- package/dist/services/distribution-service.js +104 -0
- package/dist/services/distribution-service.js.map +1 -0
- package/dist/services/evidence-service.d.ts +17 -0
- package/dist/services/evidence-service.d.ts.map +1 -0
- package/dist/services/evidence-service.js +85 -0
- package/dist/services/evidence-service.js.map +1 -0
- package/dist/services/evidence-verifier.d.ts +71 -0
- package/dist/services/evidence-verifier.d.ts.map +1 -0
- package/dist/services/evidence-verifier.js +171 -0
- package/dist/services/evidence-verifier.js.map +1 -0
- package/dist/services/git-service.d.ts +60 -0
- package/dist/services/git-service.d.ts.map +1 -0
- package/dist/services/git-service.js +137 -0
- package/dist/services/git-service.js.map +1 -0
- package/dist/services/github-service.d.ts +28 -1
- package/dist/services/github-service.d.ts.map +1 -1
- package/dist/services/github-service.js +95 -0
- package/dist/services/github-service.js.map +1 -1
- package/dist/services/graph-integrity.d.ts +36 -0
- package/dist/services/graph-integrity.d.ts.map +1 -0
- package/dist/services/graph-integrity.js +54 -0
- package/dist/services/graph-integrity.js.map +1 -0
- package/dist/services/prompt-service.d.ts +18 -0
- package/dist/services/prompt-service.d.ts.map +1 -1
- package/dist/services/prompt-service.js +47 -0
- package/dist/services/prompt-service.js.map +1 -1
- package/dist/services/report-linter-service.d.ts +10 -0
- package/dist/services/report-linter-service.d.ts.map +1 -0
- package/dist/services/report-linter-service.js +95 -0
- package/dist/services/report-linter-service.js.map +1 -0
- package/dist/services/report-service.d.ts +37 -0
- package/dist/services/report-service.d.ts.map +1 -0
- package/dist/services/report-service.js +173 -0
- package/dist/services/report-service.js.map +1 -0
- package/dist/services/revise-cache-service.d.ts +46 -0
- package/dist/services/revise-cache-service.d.ts.map +1 -0
- package/dist/services/revise-cache-service.js +88 -0
- package/dist/services/revise-cache-service.js.map +1 -0
- package/dist/services/revise-service.d.ts +108 -0
- package/dist/services/revise-service.d.ts.map +1 -0
- package/dist/services/revise-service.js +249 -0
- package/dist/services/revise-service.js.map +1 -0
- package/dist/services/standup-parser.d.ts +21 -0
- package/dist/services/standup-parser.d.ts.map +1 -0
- package/dist/services/standup-parser.js +104 -0
- package/dist/services/standup-parser.js.map +1 -0
- package/dist/services/story-standup-service.d.ts +7 -0
- package/dist/services/story-standup-service.d.ts.map +1 -0
- package/dist/services/story-standup-service.js +27 -0
- package/dist/services/story-standup-service.js.map +1 -0
- package/dist/services/template-sections.d.ts +28 -0
- package/dist/services/template-sections.d.ts.map +1 -0
- package/dist/services/template-sections.js +55 -0
- package/dist/services/template-sections.js.map +1 -0
- package/dist/services/template-service.d.ts.map +1 -1
- package/dist/services/template-service.js +1 -0
- package/dist/services/template-service.js.map +1 -1
- package/dist/services/voice-service.d.ts +12 -0
- package/dist/services/voice-service.d.ts.map +1 -0
- package/dist/services/voice-service.js +42 -0
- package/dist/services/voice-service.js.map +1 -0
- package/dist/templates/export/planning-report.html.hbs +10 -0
- package/dist/templates/export/planning-report.md.hbs +11 -0
- package/dist/templates/linter/linter-config.json.hbs +13 -0
- package/dist/templates/reports/executive.md.hbs +28 -0
- package/dist/templates/reports/release-notes.md.hbs +37 -0
- package/dist/templates/reports/retrospective.md.hbs +36 -0
- package/dist/templates/reports/sprint.md.hbs +91 -0
- package/dist/templates/reports/standup.md.hbs +27 -0
- package/dist/templates/reports/weekly.md.hbs +42 -0
- package/dist/templates/voice/standup.md.hbs +20 -0
- package/dist/utils/diff.d.ts +26 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/diff.js +143 -0
- package/dist/utils/diff.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cascade execution for `planr revise` (EPIC-003, FEAT-012).
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
*
|
|
6
|
+
* 1. **Build cascade order** — top-down: epic → features → stories → tasks.
|
|
7
|
+
* The artifact hierarchy is a strict tree; no cycle detection is needed.
|
|
8
|
+
* 2. **Execute the cascade** — for each artifact in order, call the
|
|
9
|
+
* caller-provided `processOne` closure. The cascade stops on
|
|
10
|
+
* SIGINT, `[q]uit`, or an unrecoverable agent error, and always
|
|
11
|
+
* flushes audit entries immediately so an interrupted run leaves an
|
|
12
|
+
* accurate record.
|
|
13
|
+
* 3. **Progress tracking** — emits a `CascadeProgress` snapshot before
|
|
14
|
+
* each artifact, with a rolling ETA.
|
|
15
|
+
*
|
|
16
|
+
* This service owns NO rollback logic. Partial cascades that break the
|
|
17
|
+
* artifact graph are the concern of FEAT-013's post-flight rollback.
|
|
18
|
+
*/
|
|
19
|
+
import { logger } from '../utils/logger.js';
|
|
20
|
+
import { listArtifacts, readArtifact } from './artifact-service.js';
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Cascade order (§1.0)
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the cascade plan for a root artifact, walking its descendants in
|
|
26
|
+
* top-down order. For an epic root, the plan is:
|
|
27
|
+
* EPIC → [features under epic] → [stories under those features] → [tasks under those stories]
|
|
28
|
+
* For a feature root, the EPIC level is empty and features contain only the root, etc.
|
|
29
|
+
*/
|
|
30
|
+
export async function buildCascadeOrder(projectDir, config, rootType, rootId) {
|
|
31
|
+
const levels = [
|
|
32
|
+
{ type: 'epic', label: 'epic', artifactIds: [] },
|
|
33
|
+
{ type: 'feature', label: 'features', artifactIds: [] },
|
|
34
|
+
{ type: 'story', label: 'stories', artifactIds: [] },
|
|
35
|
+
{ type: 'task', label: 'tasks', artifactIds: [] },
|
|
36
|
+
];
|
|
37
|
+
if (rootType === 'epic') {
|
|
38
|
+
levels[0].artifactIds = [rootId];
|
|
39
|
+
const features = await listArtifacts(projectDir, config, 'feature');
|
|
40
|
+
for (const f of features) {
|
|
41
|
+
const featureArtifact = await readArtifact(projectDir, config, 'feature', f.id);
|
|
42
|
+
if (featureArtifact?.data.epicId === rootId) {
|
|
43
|
+
levels[1].artifactIds.push(f.id);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
for (const featureId of levels[1].artifactIds) {
|
|
47
|
+
const stories = await listArtifacts(projectDir, config, 'story');
|
|
48
|
+
for (const s of stories) {
|
|
49
|
+
const storyArtifact = await readArtifact(projectDir, config, 'story', s.id);
|
|
50
|
+
if (storyArtifact?.data.featureId === featureId) {
|
|
51
|
+
levels[2].artifactIds.push(s.id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
for (const storyId of levels[2].artifactIds) {
|
|
56
|
+
const tasks = await listArtifacts(projectDir, config, 'task');
|
|
57
|
+
for (const t of tasks) {
|
|
58
|
+
const taskArtifact = await readArtifact(projectDir, config, 'task', t.id);
|
|
59
|
+
if (taskArtifact?.data.storyId === storyId) {
|
|
60
|
+
levels[3].artifactIds.push(t.id);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (rootType === 'feature') {
|
|
66
|
+
levels[1].artifactIds = [rootId];
|
|
67
|
+
const stories = await listArtifacts(projectDir, config, 'story');
|
|
68
|
+
for (const s of stories) {
|
|
69
|
+
const storyArtifact = await readArtifact(projectDir, config, 'story', s.id);
|
|
70
|
+
if (storyArtifact?.data.featureId === rootId) {
|
|
71
|
+
levels[2].artifactIds.push(s.id);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const storyId of levels[2].artifactIds) {
|
|
75
|
+
const tasks = await listArtifacts(projectDir, config, 'task');
|
|
76
|
+
for (const t of tasks) {
|
|
77
|
+
const taskArtifact = await readArtifact(projectDir, config, 'task', t.id);
|
|
78
|
+
if (taskArtifact?.data.storyId === storyId) {
|
|
79
|
+
levels[3].artifactIds.push(t.id);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (rootType === 'story') {
|
|
85
|
+
levels[2].artifactIds = [rootId];
|
|
86
|
+
const tasks = await listArtifacts(projectDir, config, 'task');
|
|
87
|
+
for (const t of tasks) {
|
|
88
|
+
const taskArtifact = await readArtifact(projectDir, config, 'task', t.id);
|
|
89
|
+
if (taskArtifact?.data.storyId === rootId) {
|
|
90
|
+
levels[3].artifactIds.push(t.id);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (rootType === 'task') {
|
|
95
|
+
levels[3].artifactIds = [rootId];
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Non-hierarchy types (quick, backlog, sprint, adr, checklist) — cascade
|
|
99
|
+
// is a no-op scope that only processes the root. We stash the id at the
|
|
100
|
+
// tasks level to avoid leaving the plan empty.
|
|
101
|
+
levels[3].artifactIds = [rootId];
|
|
102
|
+
}
|
|
103
|
+
const orderedIds = levels.flatMap((l) => l.artifactIds);
|
|
104
|
+
return { rootId, rootType, levels, orderedIds };
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Drive the cascade plan through the provided processor. Installs a SIGINT
|
|
108
|
+
* handler for the duration of the run; on Ctrl+C it waits for the current
|
|
109
|
+
* artifact to finish (so no half-written files) and then stops. The SIGINT
|
|
110
|
+
* handler is removed on completion whether or not it fired.
|
|
111
|
+
*/
|
|
112
|
+
export async function executeCascade(options) {
|
|
113
|
+
const { plan, processor } = options;
|
|
114
|
+
const signalTarget = options.signalTarget ?? process;
|
|
115
|
+
const total = plan.orderedIds.length;
|
|
116
|
+
let completed = 0;
|
|
117
|
+
let interruptedByUser = false;
|
|
118
|
+
const sigintHandler = () => {
|
|
119
|
+
interruptedByUser = true;
|
|
120
|
+
logger.warn('\nSIGINT received — cascade will stop after current artifact completes.');
|
|
121
|
+
};
|
|
122
|
+
signalTarget.once('SIGINT', sigintHandler);
|
|
123
|
+
const started = Date.now();
|
|
124
|
+
try {
|
|
125
|
+
for (const level of plan.levels) {
|
|
126
|
+
for (const artifactId of level.artifactIds) {
|
|
127
|
+
if (interruptedByUser) {
|
|
128
|
+
return {
|
|
129
|
+
completed,
|
|
130
|
+
total,
|
|
131
|
+
interrupted: { reason: 'sigint', atArtifactId: artifactId },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const progress = {
|
|
135
|
+
completed,
|
|
136
|
+
total,
|
|
137
|
+
currentArtifactId: artifactId,
|
|
138
|
+
currentLevelLabel: level.label,
|
|
139
|
+
etaSeconds: estimateEta(started, completed, total),
|
|
140
|
+
};
|
|
141
|
+
options.onProgress?.(progress);
|
|
142
|
+
let outcome;
|
|
143
|
+
try {
|
|
144
|
+
outcome = await processor({
|
|
145
|
+
artifactId,
|
|
146
|
+
levelLabel: level.label,
|
|
147
|
+
progress,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
logger.error(`Cascade aborted at ${artifactId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
152
|
+
return {
|
|
153
|
+
completed,
|
|
154
|
+
total,
|
|
155
|
+
interrupted: { reason: 'agent_error', atArtifactId: artifactId },
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
completed++;
|
|
159
|
+
if (!outcome.continue) {
|
|
160
|
+
return {
|
|
161
|
+
completed,
|
|
162
|
+
total,
|
|
163
|
+
interrupted: {
|
|
164
|
+
reason: outcome.stopReason === 'q' ? 'q' : 'agent_error',
|
|
165
|
+
atArtifactId: artifactId,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return { completed, total };
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
signalTarget.removeListener('SIGINT', sigintHandler);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Estimate seconds remaining based on observed pace. Returns null for the
|
|
179
|
+
* first couple of samples so the UI doesn't print wildly unstable numbers.
|
|
180
|
+
*/
|
|
181
|
+
function estimateEta(startedMs, completed, total) {
|
|
182
|
+
if (completed < 2 || total === 0)
|
|
183
|
+
return null;
|
|
184
|
+
const elapsed = (Date.now() - startedMs) / 1000;
|
|
185
|
+
const perItem = elapsed / completed;
|
|
186
|
+
const remaining = Math.max(0, total - completed);
|
|
187
|
+
return Math.round(perItem * remaining);
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=cascade-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cascade-service.js","sourceRoot":"","sources":["../../src/services/cascade-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assemble stakeholder report context from `.planr/` artifacts and optional GitHub signals.
|
|
3
|
+
*/
|
|
4
|
+
import type { OpenPlanrConfig, StakeholderReportContext, StakeholderReportType } from '../models/types.js';
|
|
5
|
+
export interface BuildContextOptions {
|
|
6
|
+
reportType: StakeholderReportType;
|
|
7
|
+
days: number;
|
|
8
|
+
sprintId?: string;
|
|
9
|
+
includeGitHub: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function buildStakeholderReportContext(projectDir: string, config: OpenPlanrConfig, opts: BuildContextOptions): Promise<StakeholderReportContext>;
|
|
12
|
+
//# sourceMappingURL=context-pack-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-pack-service.d.ts","sourceRoot":"","sources":["../../src/services/context-pack-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAEV,eAAe,EAIf,wBAAwB,EACxB,qBAAqB,EACtB,MAAM,oBAAoB,CAAC;AAI5B,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,qBAAqB,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;CACxB;AAaD,wBAAsB,6BAA6B,CACjD,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,wBAAwB,CAAC,CAmHnC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assemble stakeholder report context from `.planr/` artifacts and optional GitHub signals.
|
|
3
|
+
*/
|
|
4
|
+
import { listArtifacts, readArtifact } from './artifact-service.js';
|
|
5
|
+
import { fetchRecentCommits, fetchRecentPullRequests } from './github-service.js';
|
|
6
|
+
function statusOf(data) {
|
|
7
|
+
const s = data.status ?? data.Status;
|
|
8
|
+
return typeof s === 'string' ? s : 'unknown';
|
|
9
|
+
}
|
|
10
|
+
function titleOf(meta, data) {
|
|
11
|
+
const t = data.title;
|
|
12
|
+
if (typeof t === 'string' && t.trim())
|
|
13
|
+
return t;
|
|
14
|
+
return meta.title;
|
|
15
|
+
}
|
|
16
|
+
export async function buildStakeholderReportContext(projectDir, config, opts) {
|
|
17
|
+
const generatedAt = new Date().toISOString();
|
|
18
|
+
const epicsMeta = await listArtifacts(projectDir, config, 'epic');
|
|
19
|
+
const featuresMeta = await listArtifacts(projectDir, config, 'feature');
|
|
20
|
+
const storiesMeta = await listArtifacts(projectDir, config, 'story');
|
|
21
|
+
const tasksMeta = await listArtifacts(projectDir, config, 'task');
|
|
22
|
+
const epics = [];
|
|
23
|
+
for (const m of epicsMeta) {
|
|
24
|
+
const a = await readArtifact(projectDir, config, 'epic', m.id);
|
|
25
|
+
const data = (a?.data ?? {});
|
|
26
|
+
epics.push({
|
|
27
|
+
id: m.id,
|
|
28
|
+
title: titleOf(m, data),
|
|
29
|
+
status: statusOf(data),
|
|
30
|
+
type: 'epic',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const features = [];
|
|
34
|
+
for (const m of featuresMeta) {
|
|
35
|
+
const a = await readArtifact(projectDir, config, 'feature', m.id);
|
|
36
|
+
const data = (a?.data ?? {});
|
|
37
|
+
features.push({
|
|
38
|
+
id: m.id,
|
|
39
|
+
title: titleOf(m, data),
|
|
40
|
+
status: statusOf(data),
|
|
41
|
+
type: 'feature',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const stories = [];
|
|
45
|
+
for (const m of storiesMeta) {
|
|
46
|
+
const a = await readArtifact(projectDir, config, 'story', m.id);
|
|
47
|
+
const data = (a?.data ?? {});
|
|
48
|
+
stories.push({
|
|
49
|
+
id: m.id,
|
|
50
|
+
title: titleOf(m, data),
|
|
51
|
+
status: statusOf(data),
|
|
52
|
+
type: 'story',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const tasks = [];
|
|
56
|
+
for (const m of tasksMeta) {
|
|
57
|
+
const a = await readArtifact(projectDir, config, 'task', m.id);
|
|
58
|
+
const data = (a?.data ?? {});
|
|
59
|
+
tasks.push({
|
|
60
|
+
id: m.id,
|
|
61
|
+
title: titleOf(m, data),
|
|
62
|
+
status: statusOf(data),
|
|
63
|
+
type: 'task',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
let sprint;
|
|
67
|
+
if (opts.sprintId) {
|
|
68
|
+
const s = await readArtifact(projectDir, config, 'sprint', opts.sprintId);
|
|
69
|
+
if (s) {
|
|
70
|
+
const data = s.data;
|
|
71
|
+
const rawGoals = data.goals;
|
|
72
|
+
const goals = Array.isArray(rawGoals) ? rawGoals.map(String) : [];
|
|
73
|
+
const rawTaskIds = data.taskIds;
|
|
74
|
+
const taskIds = Array.isArray(rawTaskIds) ? rawTaskIds.map(String) : [];
|
|
75
|
+
sprint = {
|
|
76
|
+
sprintId: opts.sprintId,
|
|
77
|
+
name: String(data.name ?? opts.sprintId),
|
|
78
|
+
status: statusOf(data),
|
|
79
|
+
startDate: String(data.startDate ?? ''),
|
|
80
|
+
endDate: String(data.endDate ?? ''),
|
|
81
|
+
goals,
|
|
82
|
+
taskIds,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
let github;
|
|
87
|
+
let noGitHub = !opts.includeGitHub;
|
|
88
|
+
if (opts.includeGitHub) {
|
|
89
|
+
const [cRes, pRes] = await Promise.all([
|
|
90
|
+
fetchRecentCommits({ days: opts.days, limit: 30 }),
|
|
91
|
+
fetchRecentPullRequests({ days: opts.days, limit: 20 }),
|
|
92
|
+
]);
|
|
93
|
+
const warn = [cRes.warning, pRes.warning].filter(Boolean).join(' ');
|
|
94
|
+
github = {
|
|
95
|
+
commits: cRes.commits,
|
|
96
|
+
pullRequests: pRes.pullRequests,
|
|
97
|
+
warning: warn || undefined,
|
|
98
|
+
fetchedAt: generatedAt,
|
|
99
|
+
};
|
|
100
|
+
noGitHub = Boolean(warn) && cRes.commits.length === 0 && pRes.pullRequests.length === 0;
|
|
101
|
+
}
|
|
102
|
+
const doneStories = stories.filter((x) => /done|closed/i.test(x.status));
|
|
103
|
+
const anchorStories = doneStories.length > 0 ? doneStories.slice(0, 15) : stories.slice(0, 15);
|
|
104
|
+
const evidence = buildEvidenceList(github, anchorStories);
|
|
105
|
+
const branding = config.reports;
|
|
106
|
+
return {
|
|
107
|
+
projectName: config.projectName,
|
|
108
|
+
generatedAt,
|
|
109
|
+
reportType: opts.reportType,
|
|
110
|
+
daysLookback: opts.days,
|
|
111
|
+
sprint,
|
|
112
|
+
artifacts: { epics, features, stories, tasks },
|
|
113
|
+
github,
|
|
114
|
+
branding,
|
|
115
|
+
placeholders: {
|
|
116
|
+
noSprint: !sprint,
|
|
117
|
+
noGitHub: noGitHub,
|
|
118
|
+
noStoriesCompleted: doneStories.length === 0,
|
|
119
|
+
},
|
|
120
|
+
evidence,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function buildEvidenceList(github, stories) {
|
|
124
|
+
const out = [];
|
|
125
|
+
for (const s of stories) {
|
|
126
|
+
out.push({
|
|
127
|
+
id: `artifact-${s.id}`,
|
|
128
|
+
kind: 'artifact',
|
|
129
|
+
label: `${s.id}: ${s.title}`,
|
|
130
|
+
detail: `Status: ${s.status}`,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
if (github) {
|
|
134
|
+
for (const c of github.commits.slice(0, 20)) {
|
|
135
|
+
out.push({
|
|
136
|
+
id: `commit-${c.shortSha}`,
|
|
137
|
+
kind: 'commit',
|
|
138
|
+
label: c.message,
|
|
139
|
+
url: c.url,
|
|
140
|
+
detail: `${c.authorLogin} · ${c.committedDate}`,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
for (const p of github.pullRequests.slice(0, 15)) {
|
|
144
|
+
out.push({
|
|
145
|
+
id: `pr-${p.number}`,
|
|
146
|
+
kind: 'pull_request',
|
|
147
|
+
label: `PR #${p.number}: ${p.title}`,
|
|
148
|
+
url: p.url,
|
|
149
|
+
detail: `${p.state} · ${p.authorLogin}`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=context-pack-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-pack-service.js","sourceRoot":"","sources":["../../src/services/context-pack-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colored diff preview for revise (EPIC-003, FEAT-011 §4.2).
|
|
3
|
+
*
|
|
4
|
+
* Wraps the pure `unifiedDiff` utility with chalk formatting. The returned
|
|
5
|
+
* string is what the CLI prints before asking the user to apply / skip /
|
|
6
|
+
* edit / re-view / quit.
|
|
7
|
+
*/
|
|
8
|
+
import { type UnifiedDiffOptions } from '../utils/diff.js';
|
|
9
|
+
export interface RenderDiffOptions extends UnifiedDiffOptions {
|
|
10
|
+
/** Set to false to skip ANSI color codes (useful for tests / non-TTY output). */
|
|
11
|
+
color?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Produce a unified diff between `oldText` and `newText`, color-coded for
|
|
15
|
+
* terminal display. Returns the empty string when the two are identical.
|
|
16
|
+
*/
|
|
17
|
+
export declare function renderDiff(oldText: string, newText: string, options?: RenderDiffOptions): string;
|
|
18
|
+
//# sourceMappingURL=diff-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-service.d.ts","sourceRoot":"","sources":["../../src/services/diff-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAe,MAAM,kBAAkB,CAAC;AAExE,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAeR"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colored diff preview for revise (EPIC-003, FEAT-011 §4.2).
|
|
3
|
+
*
|
|
4
|
+
* Wraps the pure `unifiedDiff` utility with chalk formatting. The returned
|
|
5
|
+
* string is what the CLI prints before asking the user to apply / skip /
|
|
6
|
+
* edit / re-view / quit.
|
|
7
|
+
*/
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { unifiedDiff } from '../utils/diff.js';
|
|
10
|
+
/**
|
|
11
|
+
* Produce a unified diff between `oldText` and `newText`, color-coded for
|
|
12
|
+
* terminal display. Returns the empty string when the two are identical.
|
|
13
|
+
*/
|
|
14
|
+
export function renderDiff(oldText, newText, options = {}) {
|
|
15
|
+
const raw = unifiedDiff(oldText, newText, options);
|
|
16
|
+
if (raw.length === 0)
|
|
17
|
+
return '';
|
|
18
|
+
if (options.color === false)
|
|
19
|
+
return raw;
|
|
20
|
+
return raw
|
|
21
|
+
.split('\n')
|
|
22
|
+
.map((line) => {
|
|
23
|
+
if (line.startsWith('+++') || line.startsWith('---'))
|
|
24
|
+
return chalk.bold(line);
|
|
25
|
+
if (line.startsWith('@@'))
|
|
26
|
+
return chalk.cyan(line);
|
|
27
|
+
if (line.startsWith('+'))
|
|
28
|
+
return chalk.green(line);
|
|
29
|
+
if (line.startsWith('-'))
|
|
30
|
+
return chalk.red(line);
|
|
31
|
+
return chalk.dim(line);
|
|
32
|
+
})
|
|
33
|
+
.join('\n');
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=diff-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-service.js","sourceRoot":"","sources":["../../src/services/diff-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAA2B,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOxE;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,OAAe,EACf,UAA6B,EAAE;IAE/B,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACnD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK;QAAE,OAAO,GAAG,CAAC;IAExC,OAAO,GAAG;SACP,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9E,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delivery channels for stakeholder reports (GitHub issue push; Slack webhooks; email stub).
|
|
3
|
+
*/
|
|
4
|
+
import type { DistributionResult, OpenPlanrConfig } from '../models/types.js';
|
|
5
|
+
export declare function pushReportAsGitHubIssue(args: {
|
|
6
|
+
title: string;
|
|
7
|
+
body: string;
|
|
8
|
+
dryRun: boolean;
|
|
9
|
+
}): Promise<DistributionResult>;
|
|
10
|
+
export declare function pushReportToSlack(config: OpenPlanrConfig, markdown: string, args?: {
|
|
11
|
+
dryRun?: boolean;
|
|
12
|
+
}): Promise<DistributionResult>;
|
|
13
|
+
export declare function pushReportByEmail(_config: OpenPlanrConfig, _args: {
|
|
14
|
+
to: string[];
|
|
15
|
+
subject: string;
|
|
16
|
+
body: string;
|
|
17
|
+
}): Promise<DistributionResult>;
|
|
18
|
+
//# sourceMappingURL=distribution-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distribution-service.d.ts","sourceRoot":"","sources":["../../src/services/distribution-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAW9E,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CACjB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwB9B;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CA0D7B;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrD,OAAO,CAAC,kBAAkB,CAAC,CAc7B"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delivery channels for stakeholder reports (GitHub issue push; Slack webhooks; email stub).
|
|
3
|
+
*/
|
|
4
|
+
import { createIssue, ensureLabel } from './github-service.js';
|
|
5
|
+
const SLACK_TEXT_MAX = 12000;
|
|
6
|
+
function truncateForSlack(text) {
|
|
7
|
+
const t = text.trim();
|
|
8
|
+
if (t.length <= SLACK_TEXT_MAX)
|
|
9
|
+
return t;
|
|
10
|
+
return `${t.slice(0, SLACK_TEXT_MAX)}\n\n…(truncated; full report saved locally)`;
|
|
11
|
+
}
|
|
12
|
+
export async function pushReportAsGitHubIssue(args) {
|
|
13
|
+
if (args.dryRun) {
|
|
14
|
+
return {
|
|
15
|
+
channel: 'github_issue',
|
|
16
|
+
ok: true,
|
|
17
|
+
message: 'Dry run: would create GitHub issue with stakeholder report body.',
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
await ensureLabel('planr:report');
|
|
22
|
+
const { url } = await createIssue(args.title, args.body, ['planr:report']);
|
|
23
|
+
return {
|
|
24
|
+
channel: 'github_issue',
|
|
25
|
+
ok: true,
|
|
26
|
+
message: 'Created GitHub issue with report.',
|
|
27
|
+
url,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
return {
|
|
32
|
+
channel: 'github_issue',
|
|
33
|
+
ok: false,
|
|
34
|
+
message: err.message,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function pushReportToSlack(config, markdown, args) {
|
|
39
|
+
const url = config.distribution?.slackWebhookUrl;
|
|
40
|
+
if (args?.dryRun) {
|
|
41
|
+
if (!url) {
|
|
42
|
+
return {
|
|
43
|
+
channel: 'slack',
|
|
44
|
+
ok: true,
|
|
45
|
+
message: 'Dry run: no Slack webhook in config (no POST). Add `distribution.slackWebhookUrl` to .planr/config.json, then run without --dry-run to send.',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
channel: 'slack',
|
|
50
|
+
ok: true,
|
|
51
|
+
message: `Dry run: would POST ~${Math.min(markdown.length, SLACK_TEXT_MAX)} chars to your Slack webhook (no request sent).`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (!url) {
|
|
55
|
+
return {
|
|
56
|
+
channel: 'slack',
|
|
57
|
+
ok: false,
|
|
58
|
+
message: 'Slack is not configured. Set `distribution.slackWebhookUrl` in .planr/config.json (or use --push github).',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const payload = { text: truncateForSlack(markdown) };
|
|
63
|
+
const res = await fetch(url, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: { 'Content-Type': 'application/json' },
|
|
66
|
+
body: JSON.stringify(payload),
|
|
67
|
+
});
|
|
68
|
+
const bodyText = await res.text().catch(() => '');
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
return {
|
|
71
|
+
channel: 'slack',
|
|
72
|
+
ok: false,
|
|
73
|
+
message: `Slack webhook failed (${res.status}): ${bodyText || res.statusText}. Check the webhook URL and app permissions.`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
channel: 'slack',
|
|
78
|
+
ok: true,
|
|
79
|
+
message: 'Posted report to Slack.',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return {
|
|
84
|
+
channel: 'slack',
|
|
85
|
+
ok: false,
|
|
86
|
+
message: `Slack request failed: ${err.message}`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export async function pushReportByEmail(_config, _args) {
|
|
91
|
+
if (!_config.distribution?.emailSmtpHost) {
|
|
92
|
+
return {
|
|
93
|
+
channel: 'email',
|
|
94
|
+
ok: false,
|
|
95
|
+
message: 'Email is not configured. Set `distribution.emailSmtpHost` and related fields in .planr/config.json.',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
channel: 'email',
|
|
100
|
+
ok: false,
|
|
101
|
+
message: 'SMTP delivery is not implemented in this build.',
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=distribution-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distribution-service.js","sourceRoot":"","sources":["../../src/services/distribution-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence linking and validation for stakeholder reports.
|
|
3
|
+
*/
|
|
4
|
+
import type { ClaimValidationResult, EvidenceSummary, ReportEvidenceItem, StakeholderReportType } from '../models/types.js';
|
|
5
|
+
export declare function countEvidenceAnchors(markdown: string): number;
|
|
6
|
+
export interface ValidateClaimsOptions {
|
|
7
|
+
/** Included for forward-compatible per-report tuning; reserved for future use. */
|
|
8
|
+
reportType?: StakeholderReportType;
|
|
9
|
+
}
|
|
10
|
+
export declare function validateClaimsHaveAnchors(markdown: string, minAnchors: number, options?: ValidateClaimsOptions): ClaimValidationResult[];
|
|
11
|
+
export declare function validateRemoteEvidence(items: ReportEvidenceItem[]): Promise<{
|
|
12
|
+
inaccessible: ReportEvidenceItem[];
|
|
13
|
+
repoOk: boolean;
|
|
14
|
+
repoMessage: string;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function summarizeEvidenceItem(item: ReportEvidenceItem): EvidenceSummary;
|
|
17
|
+
//# sourceMappingURL=evidence-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-service.d.ts","sourceRoot":"","sources":["../../src/services/evidence-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,oBAAoB,CAAC;AAM5B,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI7D;AAED,MAAM,WAAW,qBAAqB;IACpC,kFAAkF;IAClF,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAcD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,qBAAqB,EAAE,CAkCzB;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC;IACjF,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAeD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,kBAAkB,GAAG,eAAe,CAM/E"}
|