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,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `planr revise` — core service (EPIC-003, FEAT-010 + FEAT-011).
|
|
3
|
+
*
|
|
4
|
+
* Exposes composable primitives; the CLI and future cascade service
|
|
5
|
+
* orchestrate them. Phase 1 (FEAT-010) ships `reviseArtifact` for dry-run
|
|
6
|
+
* decision generation; Phase 2 (FEAT-011) adds `applyDecision` for the
|
|
7
|
+
* write path and exposes the verifier context so callers can run
|
|
8
|
+
* `verifyDecision` against the same inputs the agent saw.
|
|
9
|
+
*/
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { buildCodebaseContext, extractKeywords, formatCodebaseContext, } from '../ai/codebase/context-builder.js';
|
|
12
|
+
import { buildRevisePrompt, } from '../ai/prompts/prompt-builder.js';
|
|
13
|
+
import { aiReviseDecisionSchema } from '../ai/schemas/ai-response-schemas.js';
|
|
14
|
+
import { TOKEN_BUDGETS } from '../ai/types.js';
|
|
15
|
+
import { logger } from '../utils/logger.js';
|
|
16
|
+
import { generateJSON } from './ai-service.js';
|
|
17
|
+
import { findArtifactTypeById, getArtifactDir, getParentChain, listArtifacts, readArtifact, readArtifactRaw, resolveArtifactFilename, } from './artifact-service.js';
|
|
18
|
+
import { atomicWriteFile } from './atomic-write-service.js';
|
|
19
|
+
import { renderDiff } from './diff-service.js';
|
|
20
|
+
import { getCanonicalSections } from './template-sections.js';
|
|
21
|
+
/**
|
|
22
|
+
* Error thrown when an artifact id cannot be resolved to an artifact type or
|
|
23
|
+
* the artifact file does not exist on disk.
|
|
24
|
+
*/
|
|
25
|
+
export class ReviseArtifactNotFoundError extends Error {
|
|
26
|
+
artifactId;
|
|
27
|
+
constructor(artifactId, message) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = 'ReviseArtifactNotFoundError';
|
|
30
|
+
this.artifactId = artifactId;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Revise a single artifact — Phase 1 dry-run.
|
|
35
|
+
*
|
|
36
|
+
* Does NOT write any files. The returned decision is the agent output after
|
|
37
|
+
* schema validation; evidence verification, diff preview, and write are all
|
|
38
|
+
* Phase 2 responsibilities (FEAT-011). Cascade, siblings, and declared
|
|
39
|
+
* sources are Phase 3 (FEAT-012) and onwards.
|
|
40
|
+
*/
|
|
41
|
+
export async function reviseArtifact(projectDir, config, provider, artifactId, options) {
|
|
42
|
+
const artifactType = findArtifactTypeById(artifactId);
|
|
43
|
+
if (!artifactType) {
|
|
44
|
+
throw new ReviseArtifactNotFoundError(artifactId, `Cannot determine artifact type from ID: ${artifactId}. Expected format: EPIC-001, FEAT-001, US-001, TASK-001.`);
|
|
45
|
+
}
|
|
46
|
+
const artifactRaw = await readArtifactRaw(projectDir, config, artifactType, artifactId);
|
|
47
|
+
if (artifactRaw === null) {
|
|
48
|
+
throw new ReviseArtifactNotFoundError(artifactId, `Artifact ${artifactId} not found under ${artifactType}/ directory.`);
|
|
49
|
+
}
|
|
50
|
+
const parents = await loadParentPromptArtifacts(projectDir, config, artifactType, artifactId);
|
|
51
|
+
const siblings = options.noSiblingContext
|
|
52
|
+
? []
|
|
53
|
+
: await loadSiblingPromptArtifacts(projectDir, config, artifactType, artifactId, options.maxSiblings ?? 8);
|
|
54
|
+
let codebaseContextFormatted;
|
|
55
|
+
let codebaseCtx;
|
|
56
|
+
if (!options.noCodeContext) {
|
|
57
|
+
const keywords = extractKeywords(artifactRaw);
|
|
58
|
+
codebaseCtx = await buildCodebaseContext(projectDir, keywords);
|
|
59
|
+
codebaseContextFormatted = formatCodebaseContext(codebaseCtx);
|
|
60
|
+
}
|
|
61
|
+
const messages = buildRevisePrompt({
|
|
62
|
+
artifact: { id: artifactId, type: artifactType, content: artifactRaw },
|
|
63
|
+
parents,
|
|
64
|
+
siblings,
|
|
65
|
+
codebaseContextFormatted,
|
|
66
|
+
sources: [], // Declared-sources loader lands with the revise.yaml config work
|
|
67
|
+
writableScope: options.writableScope ?? 'all',
|
|
68
|
+
canonicalSections: getCanonicalSections(artifactType),
|
|
69
|
+
});
|
|
70
|
+
logger.debug(`reviseArtifact: calling AI for ${artifactId}`);
|
|
71
|
+
const result = await generateJSON(provider, messages, aiReviseDecisionSchema, {
|
|
72
|
+
maxTokens: TOKEN_BUDGETS.revise,
|
|
73
|
+
});
|
|
74
|
+
// resolveArtifactFilename strips the `.md` extension (other callers want the
|
|
75
|
+
// slug form). Revise must write to the full `.md` file, so append the
|
|
76
|
+
// extension explicitly. Defensive fallback if a future version ever returns
|
|
77
|
+
// a filename with the extension intact.
|
|
78
|
+
const filenameNoExt = await resolveArtifactFilename(projectDir, config, artifactType, artifactId);
|
|
79
|
+
const artifactDir = path.join(projectDir, getArtifactDir(config, artifactType));
|
|
80
|
+
const fullFilename = filenameNoExt.endsWith('.md') ? filenameNoExt : `${filenameNoExt}.md`;
|
|
81
|
+
const artifactPath = path.join(artifactDir, fullFilename);
|
|
82
|
+
const verifierContext = {
|
|
83
|
+
projectDir,
|
|
84
|
+
config,
|
|
85
|
+
artifactDir: path.dirname(artifactPath),
|
|
86
|
+
codebaseContextFormatted,
|
|
87
|
+
knownSourceRefs: [], // Phase 2 sources loader will populate
|
|
88
|
+
knownPatternRuleIds: codebaseCtx ? codebaseCtx.patternRules.map((r) => r.name) : [],
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
decision: result.result,
|
|
92
|
+
usage: result.usage ?? { inputTokens: 0, outputTokens: 0 },
|
|
93
|
+
contextStats: {
|
|
94
|
+
parentsLoaded: parents.length,
|
|
95
|
+
siblingsLoaded: siblings.length,
|
|
96
|
+
codebaseContextIncluded: !!codebaseContextFormatted,
|
|
97
|
+
sourcesLoaded: 0,
|
|
98
|
+
},
|
|
99
|
+
artifactPath,
|
|
100
|
+
originalContent: artifactRaw,
|
|
101
|
+
verifierContext,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Apply a (verified) decision: write the artifact atomically when
|
|
106
|
+
* `action === 'revise'` and `dryRun` is false, emit an audit entry
|
|
107
|
+
* describing the outcome either way.
|
|
108
|
+
*
|
|
109
|
+
* Caller is expected to have already run `verifyDecision` — `applyDecision`
|
|
110
|
+
* trusts that whatever decision arrives is allowed to be written.
|
|
111
|
+
*/
|
|
112
|
+
export async function applyDecision(options) {
|
|
113
|
+
const { decision, audit, dryRun, originalContent, artifactPath, backupDir } = options;
|
|
114
|
+
const timestamp = new Date().toISOString();
|
|
115
|
+
if (decision.action === 'skip') {
|
|
116
|
+
audit.appendEntry({
|
|
117
|
+
artifactId: decision.artifactId,
|
|
118
|
+
artifactPath,
|
|
119
|
+
outcome: 'skipped-by-agent',
|
|
120
|
+
rationale: decision.rationale,
|
|
121
|
+
evidence: decision.evidence,
|
|
122
|
+
ambiguous: decision.ambiguous,
|
|
123
|
+
cascadeLevel: options.cascadeLevel,
|
|
124
|
+
timestamp,
|
|
125
|
+
});
|
|
126
|
+
return { outcome: 'skipped-by-agent', wrote: false, diff: '' };
|
|
127
|
+
}
|
|
128
|
+
if (decision.action === 'flag') {
|
|
129
|
+
audit.appendEntry({
|
|
130
|
+
artifactId: decision.artifactId,
|
|
131
|
+
artifactPath,
|
|
132
|
+
outcome: 'flagged',
|
|
133
|
+
rationale: decision.rationale,
|
|
134
|
+
evidence: decision.evidence,
|
|
135
|
+
ambiguous: decision.ambiguous,
|
|
136
|
+
cascadeLevel: options.cascadeLevel,
|
|
137
|
+
timestamp,
|
|
138
|
+
});
|
|
139
|
+
return { outcome: 'flagged', wrote: false, diff: '' };
|
|
140
|
+
}
|
|
141
|
+
// action === 'revise'
|
|
142
|
+
const diff = decision.revisedMarkdown
|
|
143
|
+
? renderDiff(originalContent, decision.revisedMarkdown, {
|
|
144
|
+
color: false,
|
|
145
|
+
oldLabel: `${decision.artifactId} (before)`,
|
|
146
|
+
newLabel: `${decision.artifactId} (proposed)`,
|
|
147
|
+
})
|
|
148
|
+
: '';
|
|
149
|
+
if (dryRun) {
|
|
150
|
+
audit.appendEntry({
|
|
151
|
+
artifactId: decision.artifactId,
|
|
152
|
+
artifactPath,
|
|
153
|
+
outcome: 'would-apply',
|
|
154
|
+
rationale: decision.rationale,
|
|
155
|
+
evidence: decision.evidence,
|
|
156
|
+
ambiguous: decision.ambiguous,
|
|
157
|
+
cascadeLevel: options.cascadeLevel,
|
|
158
|
+
diff,
|
|
159
|
+
timestamp,
|
|
160
|
+
});
|
|
161
|
+
return { outcome: 'would-apply', wrote: false, diff };
|
|
162
|
+
}
|
|
163
|
+
// Real apply: atomic write + sidecar backup.
|
|
164
|
+
const backupPath = path.join(backupDir, `${decision.artifactId}.md.bak`);
|
|
165
|
+
await atomicWriteFile(artifactPath, decision.revisedMarkdown ?? '', { backupPath });
|
|
166
|
+
audit.appendEntry({
|
|
167
|
+
artifactId: decision.artifactId,
|
|
168
|
+
artifactPath,
|
|
169
|
+
outcome: 'applied',
|
|
170
|
+
rationale: decision.rationale,
|
|
171
|
+
evidence: decision.evidence,
|
|
172
|
+
ambiguous: decision.ambiguous,
|
|
173
|
+
cascadeLevel: options.cascadeLevel,
|
|
174
|
+
diff,
|
|
175
|
+
timestamp,
|
|
176
|
+
});
|
|
177
|
+
return { outcome: 'applied', wrote: true, diff };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Load immediate-sibling artifacts (same artifact type, same parent) as
|
|
181
|
+
* prompt entries. Lazy-reads each sibling's body only if it's going to be
|
|
182
|
+
* included — the listing check is cheap, the reads are budgeted by
|
|
183
|
+
* `maxSiblings` (default 8) so the prompt stays within token budget even on
|
|
184
|
+
* epics with many features.
|
|
185
|
+
*
|
|
186
|
+
* For epic scope, there are no siblings (epics live at the top). For types
|
|
187
|
+
* without a parent-id relationship (quick, backlog, etc.), returns empty.
|
|
188
|
+
*/
|
|
189
|
+
export async function loadSiblingPromptArtifacts(projectDir, config, type, id, maxSiblings) {
|
|
190
|
+
const parentFieldByType = {
|
|
191
|
+
feature: 'epicId',
|
|
192
|
+
story: 'featureId',
|
|
193
|
+
task: 'storyId',
|
|
194
|
+
};
|
|
195
|
+
const parentField = parentFieldByType[type];
|
|
196
|
+
if (!parentField)
|
|
197
|
+
return [];
|
|
198
|
+
const self = await readArtifact(projectDir, config, type, id);
|
|
199
|
+
if (!self)
|
|
200
|
+
return [];
|
|
201
|
+
const parentId = self.data[parentField];
|
|
202
|
+
if (!parentId)
|
|
203
|
+
return [];
|
|
204
|
+
const siblings = [];
|
|
205
|
+
const listing = await listArtifacts(projectDir, config, type);
|
|
206
|
+
for (const entry of listing) {
|
|
207
|
+
if (siblings.length >= maxSiblings)
|
|
208
|
+
break;
|
|
209
|
+
if (entry.id === id)
|
|
210
|
+
continue;
|
|
211
|
+
const sib = await readArtifact(projectDir, config, type, entry.id);
|
|
212
|
+
if (sib && sib.data[parentField] === parentId) {
|
|
213
|
+
siblings.push({ id: entry.id, type, content: sib.content });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return siblings;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Resolve the parent chain for an artifact and return it as the ordered
|
|
220
|
+
* `RevisePromptArtifact[]` the prompt builder expects (epic → feature →
|
|
221
|
+
* story). Empty array for top-level artifacts (epic scope).
|
|
222
|
+
*/
|
|
223
|
+
export async function loadParentPromptArtifacts(projectDir, config, type, id) {
|
|
224
|
+
const chain = await getParentChain(projectDir, config, type, id);
|
|
225
|
+
const parents = [];
|
|
226
|
+
if (chain.epic) {
|
|
227
|
+
parents.push({
|
|
228
|
+
id: String(chain.epic.data.id),
|
|
229
|
+
type: 'epic',
|
|
230
|
+
content: chain.epic.content,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
if (chain.feature) {
|
|
234
|
+
parents.push({
|
|
235
|
+
id: String(chain.feature.data.id),
|
|
236
|
+
type: 'feature',
|
|
237
|
+
content: chain.feature.content,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (chain.story) {
|
|
241
|
+
parents.push({
|
|
242
|
+
id: String(chain.story.data.id),
|
|
243
|
+
type: 'story',
|
|
244
|
+
content: chain.story.content,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return parents;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=revise-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revise-service.js","sourceRoot":"","sources":["../../src/services/revise-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heuristic parsing of a standup transcript into yesterday / today / blockers.
|
|
3
|
+
*/
|
|
4
|
+
export interface TranscriptSegment {
|
|
5
|
+
section: 'yesterday' | 'today' | 'blockers' | 'note';
|
|
6
|
+
text: string;
|
|
7
|
+
/** Placeholder for future audio/text sync (milliseconds from clip start) */
|
|
8
|
+
audioOffsetMs?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ParsedStandup {
|
|
11
|
+
yesterday: string[];
|
|
12
|
+
today: string[];
|
|
13
|
+
blockers: string[];
|
|
14
|
+
incomplete: boolean;
|
|
15
|
+
notes: string[];
|
|
16
|
+
/** Best-effort line segments (no audio yet — offsets unused until capture exists) */
|
|
17
|
+
segments: TranscriptSegment[];
|
|
18
|
+
}
|
|
19
|
+
export declare function parseStandupTranscript(raw: string): ParsedStandup;
|
|
20
|
+
export declare function formatStandupMarkdown(parsed: ParsedStandup): string;
|
|
21
|
+
//# sourceMappingURL=standup-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standup-parser.d.ts","sourceRoot":"","sources":["../../src/services/standup-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,qFAAqF;IACrF,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAMD,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CA0EjE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAoBnE"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heuristic parsing of a standup transcript into yesterday / today / blockers.
|
|
3
|
+
*/
|
|
4
|
+
const YDAY = /^(yesterday|last day|previously|done)\s*[:-]?\s*(.+)$/i;
|
|
5
|
+
const TODAY = /^(today|now|this session|working on)\s*[:-]?\s*(.+)$/i;
|
|
6
|
+
const BLOCK = /^(blockers?|blocked|impediments?)\s*[:-]?\s*(.+)$/i;
|
|
7
|
+
export function parseStandupTranscript(raw) {
|
|
8
|
+
const yesterday = [];
|
|
9
|
+
const today = [];
|
|
10
|
+
const blockers = [];
|
|
11
|
+
const notes = [];
|
|
12
|
+
const segments = [];
|
|
13
|
+
const lines = raw
|
|
14
|
+
.split(/\r?\n/)
|
|
15
|
+
.map((l) => l.trim())
|
|
16
|
+
.filter(Boolean);
|
|
17
|
+
let mode = null;
|
|
18
|
+
for (const line of lines) {
|
|
19
|
+
let m = line.match(YDAY);
|
|
20
|
+
if (m) {
|
|
21
|
+
mode = 'y';
|
|
22
|
+
const t = m[2].trim();
|
|
23
|
+
yesterday.push(t);
|
|
24
|
+
segments.push({ section: 'yesterday', text: t });
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
m = line.match(TODAY);
|
|
28
|
+
if (m) {
|
|
29
|
+
mode = 't';
|
|
30
|
+
const t = m[2].trim();
|
|
31
|
+
today.push(t);
|
|
32
|
+
segments.push({ section: 'today', text: t });
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
m = line.match(BLOCK);
|
|
36
|
+
if (m) {
|
|
37
|
+
mode = 'b';
|
|
38
|
+
const t = m[2].trim();
|
|
39
|
+
blockers.push(t);
|
|
40
|
+
segments.push({ section: 'blockers', text: t });
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (/^[-*]\s+/.test(line)) {
|
|
44
|
+
const item = line.replace(/^[-*]\s+/, '').trim();
|
|
45
|
+
if (mode === 'y') {
|
|
46
|
+
yesterday.push(item);
|
|
47
|
+
segments.push({ section: 'yesterday', text: item });
|
|
48
|
+
}
|
|
49
|
+
else if (mode === 't') {
|
|
50
|
+
today.push(item);
|
|
51
|
+
segments.push({ section: 'today', text: item });
|
|
52
|
+
}
|
|
53
|
+
else if (mode === 'b') {
|
|
54
|
+
blockers.push(item);
|
|
55
|
+
segments.push({ section: 'blockers', text: item });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
notes.push(item);
|
|
59
|
+
segments.push({ section: 'note', text: item });
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (mode === 'y') {
|
|
64
|
+
yesterday.push(line);
|
|
65
|
+
segments.push({ section: 'yesterday', text: line });
|
|
66
|
+
}
|
|
67
|
+
else if (mode === 't') {
|
|
68
|
+
today.push(line);
|
|
69
|
+
segments.push({ section: 'today', text: line });
|
|
70
|
+
}
|
|
71
|
+
else if (mode === 'b') {
|
|
72
|
+
blockers.push(line);
|
|
73
|
+
segments.push({ section: 'blockers', text: line });
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
notes.push(line);
|
|
77
|
+
segments.push({ section: 'note', text: line });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const incomplete = yesterday.length === 0 || today.length === 0;
|
|
81
|
+
return { yesterday, today, blockers, incomplete, notes, segments };
|
|
82
|
+
}
|
|
83
|
+
export function formatStandupMarkdown(parsed) {
|
|
84
|
+
const sec = (title, items) => {
|
|
85
|
+
const body = items.length > 0 ? items.map((i) => `- ${i}`).join('\n') : '_— none recorded —_';
|
|
86
|
+
return `## ${title}\n\n${body}`;
|
|
87
|
+
};
|
|
88
|
+
return [
|
|
89
|
+
'# Standup',
|
|
90
|
+
'',
|
|
91
|
+
sec('Yesterday', parsed.yesterday),
|
|
92
|
+
'',
|
|
93
|
+
sec('Today', parsed.today),
|
|
94
|
+
'',
|
|
95
|
+
sec('Blockers', parsed.blockers),
|
|
96
|
+
parsed.notes.length > 0 ? `\n## Notes\n\n${parsed.notes.map((n) => `- ${n}`).join('\n')}` : '',
|
|
97
|
+
parsed.incomplete
|
|
98
|
+
? '\n> **Note:** Some standup sections look incomplete. Fill in missing parts before sending.\n'
|
|
99
|
+
: '',
|
|
100
|
+
]
|
|
101
|
+
.filter(Boolean)
|
|
102
|
+
.join('\n');
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=standup-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standup-parser.js","sourceRoot":"","sources":["../../src/services/standup-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Append generated standup markdown to a user story file.
|
|
3
|
+
*/
|
|
4
|
+
import type { OpenPlanrConfig } from '../models/types.js';
|
|
5
|
+
export declare function injectStandupSection(raw: string, standupMarkdown: string, date: string): string;
|
|
6
|
+
export declare function appendStandupToStory(projectDir: string, config: OpenPlanrConfig, storyId: string, standupMarkdown: string): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=story-standup-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-standup-service.d.ts","sourceRoot":"","sources":["../../src/services/story-standup-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAK1D,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAe/F;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Append generated standup markdown to a user story file.
|
|
3
|
+
*/
|
|
4
|
+
import { readArtifactRaw, updateArtifact } from './artifact-service.js';
|
|
5
|
+
const STANDUP_SECTION = '## Standup notes';
|
|
6
|
+
export function injectStandupSection(raw, standupMarkdown, date) {
|
|
7
|
+
const block = `\n### ${date}\n\n${standupMarkdown.trim()}\n`;
|
|
8
|
+
if (raw.includes(STANDUP_SECTION)) {
|
|
9
|
+
const idx = raw.indexOf(STANDUP_SECTION) + STANDUP_SECTION.length;
|
|
10
|
+
return `${raw.slice(0, idx)}${block}${raw.slice(idx)}`;
|
|
11
|
+
}
|
|
12
|
+
const tasksMatch = /\n## Tasks\b/m.exec(raw);
|
|
13
|
+
if (tasksMatch?.index !== undefined) {
|
|
14
|
+
const i = tasksMatch.index;
|
|
15
|
+
return `${raw.slice(0, i)}\n\n${STANDUP_SECTION}\n${block}\n${raw.slice(i)}`;
|
|
16
|
+
}
|
|
17
|
+
return `${raw.trimEnd()}\n\n${STANDUP_SECTION}\n${block}\n`;
|
|
18
|
+
}
|
|
19
|
+
export async function appendStandupToStory(projectDir, config, storyId, standupMarkdown) {
|
|
20
|
+
const raw = await readArtifactRaw(projectDir, config, 'story', storyId);
|
|
21
|
+
if (!raw)
|
|
22
|
+
throw new Error(`Story ${storyId} not found.`);
|
|
23
|
+
const date = new Date().toISOString().split('T')[0];
|
|
24
|
+
const next = injectStandupSection(raw, standupMarkdown, date);
|
|
25
|
+
await updateArtifact(projectDir, config, 'story', storyId, next);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=story-standup-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-standup-service.js","sourceRoot":"","sources":["../../src/services/story-standup-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAExE,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAE,eAAuB,EAAE,IAAY;IACrF,MAAM,KAAK,GAAG,SAAS,IAAI,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC;IAE7D,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC;QAClE,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IACzD,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,UAAU,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;QAC3B,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,eAAe,KAAK,KAAK,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,CAAC;IAED,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,OAAO,eAAe,KAAK,KAAK,IAAI,CAAC;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,MAAuB,EACvB,OAAe,EACf,eAAuB;IAEvB,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxE,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,SAAS,OAAO,aAAa,CAAC,CAAC;IAEzD,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;IAC9D,MAAM,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical section lists per artifact type (EPIC-003, FEAT-014 follow-up).
|
|
3
|
+
*
|
|
4
|
+
* The revise prompt uses these to give the agent a *soft* conformance hint:
|
|
5
|
+
* "these are the sections a ${type} artifact canonically has — don't invent
|
|
6
|
+
* new ones; flag instead." This prevents the failure mode where the agent
|
|
7
|
+
* helpfully adds something like `## Relevant Files` to an epic (a task-level
|
|
8
|
+
* convention) when there is no drift justifying it.
|
|
9
|
+
*
|
|
10
|
+
* The lists mirror what the Handlebars templates in `src/templates/<type>/`
|
|
11
|
+
* actually emit. Kept hardcoded rather than parsed from the .hbs files at
|
|
12
|
+
* runtime because:
|
|
13
|
+
*
|
|
14
|
+
* 1. Handlebars templates contain `{{ }}` interpolation that would need
|
|
15
|
+
* stripping before we could grep `## ` headings.
|
|
16
|
+
* 2. If a template gains a new section, we want an explicit review step
|
|
17
|
+
* in this file, not silent pickup.
|
|
18
|
+
* 3. Parsing templates would couple revise to handlebars internals.
|
|
19
|
+
*
|
|
20
|
+
* When you add or rename a template section, update the matching entry here.
|
|
21
|
+
*/
|
|
22
|
+
import type { ArtifactType } from '../models/types.js';
|
|
23
|
+
/**
|
|
24
|
+
* Return the canonical section list for an artifact type, or `undefined`
|
|
25
|
+
* when the type has no enforced convention (e.g., `backlog`).
|
|
26
|
+
*/
|
|
27
|
+
export declare function getCanonicalSections(type: ArtifactType): readonly string[] | undefined;
|
|
28
|
+
//# sourceMappingURL=template-sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-sections.d.ts","sourceRoot":"","sources":["../../src/services/template-sections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA6BvD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAEtF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical section lists per artifact type (EPIC-003, FEAT-014 follow-up).
|
|
3
|
+
*
|
|
4
|
+
* The revise prompt uses these to give the agent a *soft* conformance hint:
|
|
5
|
+
* "these are the sections a ${type} artifact canonically has — don't invent
|
|
6
|
+
* new ones; flag instead." This prevents the failure mode where the agent
|
|
7
|
+
* helpfully adds something like `## Relevant Files` to an epic (a task-level
|
|
8
|
+
* convention) when there is no drift justifying it.
|
|
9
|
+
*
|
|
10
|
+
* The lists mirror what the Handlebars templates in `src/templates/<type>/`
|
|
11
|
+
* actually emit. Kept hardcoded rather than parsed from the .hbs files at
|
|
12
|
+
* runtime because:
|
|
13
|
+
*
|
|
14
|
+
* 1. Handlebars templates contain `{{ }}` interpolation that would need
|
|
15
|
+
* stripping before we could grep `## ` headings.
|
|
16
|
+
* 2. If a template gains a new section, we want an explicit review step
|
|
17
|
+
* in this file, not silent pickup.
|
|
18
|
+
* 3. Parsing templates would couple revise to handlebars internals.
|
|
19
|
+
*
|
|
20
|
+
* When you add or rename a template section, update the matching entry here.
|
|
21
|
+
*/
|
|
22
|
+
const CANONICAL_SECTIONS = {
|
|
23
|
+
epic: [
|
|
24
|
+
'Business Value',
|
|
25
|
+
'Target Users',
|
|
26
|
+
'Problem Statement',
|
|
27
|
+
'Solution Overview',
|
|
28
|
+
'Success Criteria',
|
|
29
|
+
'Key Features',
|
|
30
|
+
'Dependencies',
|
|
31
|
+
'Risks',
|
|
32
|
+
'Features',
|
|
33
|
+
],
|
|
34
|
+
feature: [
|
|
35
|
+
'Overview',
|
|
36
|
+
'Functional Requirements',
|
|
37
|
+
'User Stories',
|
|
38
|
+
'Dependencies',
|
|
39
|
+
'Technical Considerations',
|
|
40
|
+
'Risks',
|
|
41
|
+
'Success Metrics',
|
|
42
|
+
],
|
|
43
|
+
story: ['User Story', 'Acceptance Criteria', 'Additional Notes', 'Tasks'],
|
|
44
|
+
task: ['Artifact Sources', 'Tasks', 'Acceptance Criteria Mapping', 'Relevant Files', 'Notes'],
|
|
45
|
+
// `quick`, `backlog`, `sprint`, `adr`, `checklist` — no canonical list
|
|
46
|
+
// enforced. Revise will skip the template-structure hint for these types.
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Return the canonical section list for an artifact type, or `undefined`
|
|
50
|
+
* when the type has no enforced convention (e.g., `backlog`).
|
|
51
|
+
*/
|
|
52
|
+
export function getCanonicalSections(type) {
|
|
53
|
+
return CANONICAL_SECTIONS[type];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=template-sections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-sections.js","sourceRoot":"","sources":["../../src/services/template-sections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,MAAM,kBAAkB,GAAqD;IAC3E,IAAI,EAAE;QACJ,gBAAgB;QAChB,cAAc;QACd,mBAAmB;QACnB,mBAAmB;QACnB,kBAAkB;QAClB,cAAc;QACd,cAAc;QACd,OAAO;QACP,UAAU;KACX;IACD,OAAO,EAAE;QACP,UAAU;QACV,yBAAyB;QACzB,cAAc;QACd,cAAc;QACd,0BAA0B;QAC1B,OAAO;QACP,iBAAiB;KAClB;IACD,KAAK,EAAE,CAAC,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,OAAO,CAAC;IACzE,IAAI,EAAE,CAAC,kBAAkB,EAAE,OAAO,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,OAAO,CAAC;IAC7F,uEAAuE;IACvE,0EAA0E;CAC3E,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAkB;IACrD,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-service.d.ts","sourceRoot":"","sources":["../../src/services/template-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"template-service.d.ts","sourceRoot":"","sources":["../../src/services/template-service.ts"],"names":[],"mappings":"AA2BA,uFAAuF;AACvF,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,sCAAsC;AACrE,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAYjB"}
|
|
@@ -13,6 +13,7 @@ Handlebars.registerHelper('checkboxList', (items) => {
|
|
|
13
13
|
});
|
|
14
14
|
Handlebars.registerHelper('join', (arr, sep) => Array.isArray(arr) ? arr.join(typeof sep === 'string' ? sep : ', ') : '');
|
|
15
15
|
Handlebars.registerHelper('eq', (a, b) => a === b);
|
|
16
|
+
Handlebars.registerHelper('length', (arr) => (Array.isArray(arr) ? arr.length : 0));
|
|
16
17
|
/** Compile and render a Handlebars template, checking the override directory first. */
|
|
17
18
|
export async function renderTemplate(templatePath, data, // Template data is inherently untyped
|
|
18
19
|
overrideDir) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-service.js","sourceRoot":"","sources":["../../src/services/template-service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsC,CAAC;AAEpE,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,UAAU,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,GAAW,EAAE,EAAE,CACrD,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CACjD,CAAC;AAEF,UAAU,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC,KAAe,EAAE,EAAE;IAC5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAEH,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,GAAa,EAAE,GAAY,EAAE,EAAE,CAChE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CACzE,CAAC;AAEF,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAErE,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,YAAoB,EACpB,IAA6B,EAAE,sCAAsC;AACrE,WAAoB;IAEpB,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACtE,IAAI,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrC,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,YAAoB,EAAE,WAAoB;IAC3E,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAC1D,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACnC,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,YAAY,CAAC,CAAC;AACpD,CAAC"}
|
|
1
|
+
{"version":3,"file":"template-service.js","sourceRoot":"","sources":["../../src/services/template-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice-oriented standup workflow: consume transcript text from file or stdin.
|
|
3
|
+
* Live microphone capture can be added later without changing the parser.
|
|
4
|
+
*/
|
|
5
|
+
import type { VoiceStandupSession } from '../models/types.js';
|
|
6
|
+
export declare function loadTranscriptFromFile(path: string): Promise<VoiceStandupSession>;
|
|
7
|
+
export declare function transcriptToStandupMarkdown(transcript: string): string;
|
|
8
|
+
/** Read transcript from `--file` or stdin (must not be empty). */
|
|
9
|
+
export declare function readStandupTranscriptSource(opts: {
|
|
10
|
+
file?: string;
|
|
11
|
+
}): Promise<string>;
|
|
12
|
+
//# sourceMappingURL=voice-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-service.d.ts","sourceRoot":"","sources":["../../src/services/voice-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAWvF;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGtE;AAED,kEAAkE;AAClE,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAe1F"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice-oriented standup workflow: consume transcript text from file or stdin.
|
|
3
|
+
* Live microphone capture can be added later without changing the parser.
|
|
4
|
+
*/
|
|
5
|
+
import { readFile } from 'node:fs/promises';
|
|
6
|
+
import { formatStandupMarkdown, parseStandupTranscript } from './standup-parser.js';
|
|
7
|
+
export async function loadTranscriptFromFile(path) {
|
|
8
|
+
try {
|
|
9
|
+
const transcript = await readFile(path, 'utf-8');
|
|
10
|
+
return { status: 'done', transcript: transcript.trim() };
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
return {
|
|
14
|
+
status: 'error',
|
|
15
|
+
transcript: '',
|
|
16
|
+
errorMessage: err.message,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function transcriptToStandupMarkdown(transcript) {
|
|
21
|
+
const parsed = parseStandupTranscript(transcript);
|
|
22
|
+
return formatStandupMarkdown(parsed);
|
|
23
|
+
}
|
|
24
|
+
/** Read transcript from `--file` or stdin (must not be empty). */
|
|
25
|
+
export async function readStandupTranscriptSource(opts) {
|
|
26
|
+
if (opts.file) {
|
|
27
|
+
const session = await loadTranscriptFromFile(opts.file);
|
|
28
|
+
if (session.status === 'error') {
|
|
29
|
+
throw new Error(session.errorMessage || 'Failed to read transcript file');
|
|
30
|
+
}
|
|
31
|
+
return session.transcript;
|
|
32
|
+
}
|
|
33
|
+
const chunks = [];
|
|
34
|
+
for await (const c of process.stdin)
|
|
35
|
+
chunks.push(c);
|
|
36
|
+
const text = Buffer.concat(chunks).toString('utf-8').trim();
|
|
37
|
+
if (!text) {
|
|
38
|
+
throw new Error('Provide --file <path> or pipe transcript text on stdin.');
|
|
39
|
+
}
|
|
40
|
+
return text;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=voice-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-service.js","sourceRoot":"","sources":["../../src/services/voice-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAY;IACvD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,MAAM,EAAE,OAAO;YACf,UAAU,EAAE,EAAE;YACd,YAAY,EAAG,GAAa,CAAC,OAAO;SACrC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,UAAkB;IAC5D,MAAM,MAAM,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,IAAuB;IACvE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,IAAI,gCAAgC,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,OAAO,CAAC,UAAU,CAAC;IAC5B,CAAC;IACD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK;QAAE,MAAM,CAAC,IAAI,CAAC,CAAW,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|