openplanr 1.7.0 → 1.7.2

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 CHANGED
@@ -189,7 +189,7 @@ Built-in templates: `rest-endpoint`, `react-component`, `database-migration`, `a
189
189
  | `planr revise <ID>` | AI-driven *alignment* of planning artifacts with codebase (with diff preview) |
190
190
  | `planr search <query>` | Full-text search across all artifacts |
191
191
  | `planr sync` | Validate and fix cross-references |
192
- | `planr status` | Tree view of all planning progress |
192
+ | `planr status [scope]` | Whole-project delivery report status + GitHub/Linear cross-ref + outstanding work (`--md` / `--json` / `--github` / `--linear`) |
193
193
 
194
194
  ### AI agent rules
195
195
 
@@ -1,3 +1,5 @@
1
1
  import type { Command } from 'commander';
2
+ import { type DeliveryStatus } from '../../services/delivery-status-service.js';
2
3
  export declare function registerStatusCommand(program: Command): void;
4
+ export declare function renderMarkdown(s: DeliveryStatus): string;
3
5
  //# sourceMappingURL=status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QAiPrD"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2CAA2C,CAAC;AAInD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QAsCrD;AA0CD,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAoCxD"}
@@ -1,239 +1,156 @@
1
1
  import chalk from 'chalk';
2
- import { parseTaskMarkdown } from '../../agents/task-parser.js';
3
- import { listArtifacts, readArtifact, readArtifactRaw } from '../../services/artifact-service.js';
4
2
  import { loadConfig } from '../../services/config-service.js';
3
+ import { collectDeliveryStatus, } from '../../services/delivery-status-service.js';
5
4
  import { colorByPercent } from '../../utils/format.js';
6
5
  import { display, logger } from '../../utils/logger.js';
7
- import { parseMarkdown } from '../../utils/markdown.js';
8
6
  export function registerStatusCommand(program) {
9
7
  program
10
8
  .command('status')
11
- .description('Show project planning status')
12
- .option('--all', 'show all items without truncation')
13
- .action(async (opts) => {
9
+ .argument('[scope]', 'limit the report to one spec/epic/feature id or slug')
10
+ .description('Whole-project delivery report — every spec/backlog/quick-task by status, optionally cross-referenced with GitHub PRs + Linear')
11
+ .option('--github', 'live-resolve linked GitHub issue state + correlate PRs by id (needs `gh` auth)')
12
+ .option('--linear', 'live-resolve Linear issue state (else uses reconciled state from frontmatter)')
13
+ .option('--md', 'output the delivery report as markdown (paste-ready)')
14
+ .option('--json', 'output the delivery report as JSON')
15
+ .option('--all', 'show all items without truncation (terminal view)')
16
+ .action(async (scope, opts) => {
14
17
  const projectDir = program.opts().projectDir;
15
18
  const config = await loadConfig(projectDir);
16
- const showAll = !!opts.all;
17
- logger.heading(`OpenPlanr Status — ${config.projectName}`);
18
- display.blank();
19
- // Gather all artifacts
20
- const epics = await listArtifacts(projectDir, config, 'epic');
21
- const features = await listArtifacts(projectDir, config, 'feature');
22
- const stories = await listArtifacts(projectDir, config, 'story');
23
- const tasks = await listArtifacts(projectDir, config, 'task');
24
- // Build parent lookups: featureId → epicId, storyId → featureId, taskId → storyId/featureId
25
- const featureToEpic = new Map();
26
- const storyToFeature = new Map();
27
- const taskToParent = new Map();
28
- for (const f of features) {
29
- const data = await readArtifact(projectDir, config, 'feature', f.id);
30
- if (data?.data.epicId)
31
- featureToEpic.set(f.id, data.data.epicId);
32
- }
33
- for (const s of stories) {
34
- const data = await readArtifact(projectDir, config, 'story', s.id);
35
- if (data?.data.featureId)
36
- storyToFeature.set(s.id, data.data.featureId);
19
+ const status = await collectDeliveryStatus(projectDir, config, {
20
+ scope,
21
+ github: !!opts.github,
22
+ linear: !!opts.linear,
23
+ });
24
+ if (opts.json) {
25
+ display.line(JSON.stringify(status, (k, v) => (k === '_linearId' ? undefined : v), 2));
26
+ return;
37
27
  }
38
- for (const t of tasks) {
39
- const data = await readArtifact(projectDir, config, 'task', t.id);
40
- const parentStory = data?.data.storyId;
41
- const parentFeature = data?.data.featureId;
42
- if (parentStory)
43
- taskToParent.set(t.id, parentStory);
44
- else if (parentFeature)
45
- taskToParent.set(t.id, parentFeature);
28
+ if (opts.md) {
29
+ display.line(renderMarkdown(status));
30
+ return;
46
31
  }
47
- // Task completion metrics
48
- const taskMetrics = new Map();
49
- for (const t of tasks) {
50
- const raw = await readArtifactRaw(projectDir, config, 'task', t.id);
51
- if (raw) {
52
- const parsed = parseTaskMarkdown(raw);
53
- const subtasks = parsed.filter((s) => s.depth > 0);
54
- const total = subtasks.length || parsed.length;
55
- const done = (subtasks.length > 0 ? subtasks : parsed).filter((s) => s.done).length;
56
- taskMetrics.set(t.id, { done, total });
57
- }
58
- }
59
- // Tree view: group by epic hierarchy
60
- if (epics.length > 0) {
61
- printSection('Epics', epics, showAll);
62
- for (const epic of epics) {
63
- display.blank();
64
- display.line(chalk.bold.cyan(` ${epic.id}: ${epic.title}`));
65
- // Features under this epic
66
- const epicFeatures = features.filter((f) => featureToEpic.get(f.id) === epic.id);
67
- if (epicFeatures.length > 0) {
68
- const featureList = showAll ? epicFeatures : epicFeatures.slice(0, 5);
69
- for (const f of featureList) {
70
- display.line(chalk.white(` ${f.id} ${f.title}`));
71
- // Stories under this feature
72
- const featureStories = stories.filter((s) => storyToFeature.get(s.id) === f.id);
73
- const storyList = showAll ? featureStories : featureStories.slice(0, 3);
74
- for (const s of storyList) {
75
- display.line(chalk.dim(` ${s.id} ${s.title}`));
76
- }
77
- if (!showAll && featureStories.length > 3) {
78
- display.line(chalk.dim(` ... and ${featureStories.length - 3} more stories`));
79
- }
80
- }
81
- if (!showAll && epicFeatures.length > 5) {
82
- display.line(chalk.dim(` ... and ${epicFeatures.length - 5} more features`));
83
- }
84
- }
85
- }
86
- // Show orphaned features (no epic parent)
87
- const orphanFeatures = features.filter((f) => !featureToEpic.has(f.id));
88
- if (orphanFeatures.length > 0) {
89
- display.blank();
90
- display.line(chalk.yellow(` Unlinked Features: ${orphanFeatures.length}`));
91
- for (const f of showAll ? orphanFeatures : orphanFeatures.slice(0, 5)) {
92
- display.line(chalk.dim(` ${f.id} ${f.title}`));
93
- }
94
- }
95
- // Show orphaned stories (no feature parent)
96
- const orphanStories = stories.filter((s) => !storyToFeature.has(s.id));
97
- if (orphanStories.length > 0) {
98
- display.blank();
99
- display.line(chalk.yellow(` Unlinked Stories: ${orphanStories.length}`));
100
- for (const s of showAll ? orphanStories : orphanStories.slice(0, 5)) {
101
- display.line(chalk.dim(` ${s.id} ${s.title}`));
102
- }
103
- }
32
+ renderTerminal(status, { showAll: !!opts.all, config });
33
+ });
34
+ }
35
+ // ── status presentation ──────────────────────────────────────────────────────
36
+ const MD_ICON = {
37
+ done: '✅',
38
+ closed: '✅',
39
+ decomposed: '🔄',
40
+ 'in-progress': '🔄',
41
+ decomposing: '⏳',
42
+ shaping: '✏️',
43
+ promoted: '↗',
44
+ superseded: '⚫',
45
+ blocked: '⛔',
46
+ pending: '',
47
+ open: '•',
48
+ };
49
+ const mdIcon = (s) => MD_ICON[(s || '').toLowerCase()] ?? '•';
50
+ function statusColor(s) {
51
+ const k = (s || '').toLowerCase();
52
+ if (k === 'done' || k === 'closed')
53
+ return chalk.green;
54
+ if (k === 'blocked')
55
+ return chalk.red;
56
+ if (k === 'superseded')
57
+ return chalk.dim;
58
+ if (k === 'pending' || k === 'open')
59
+ return chalk.dim;
60
+ return chalk.yellow; // in-progress / decomposed / shaping / promoted …
61
+ }
62
+ function ghCell(i) {
63
+ const pr = i.github?.pr;
64
+ if (pr)
65
+ return `#${pr.number}${pr.merged ? ' ✓' : ''}`;
66
+ if (i.github?.issue)
67
+ return `issue #${i.github.issue}${i.github.issueState ? ` (${i.github.issueState})` : ''}`;
68
+ return '—';
69
+ }
70
+ function linCell(i) {
71
+ if (!i.linear)
72
+ return '—';
73
+ return i.linear.state ? `${i.linear.identifier} (${i.linear.state})` : i.linear.identifier;
74
+ }
75
+ function progCell(i) {
76
+ return i.progress && i.progress.total > 0 ? `${i.progress.done}/${i.progress.total}` : '';
77
+ }
78
+ export function renderMarkdown(s) {
79
+ const L = [];
80
+ L.push(`# ${s.projectName} Delivery Status`, '');
81
+ L.push('> Generated by `planr status --md`. Source of truth: `.planr/` frontmatter.', '');
82
+ L.push('## Summary', '');
83
+ for (const row of s.summary) {
84
+ const addressed = row.addressed > 0 ? ` + ${row.addressed} promoted/superseded` : '';
85
+ L.push(`- **${row.label}:** ${row.done} done${addressed} ${row.total} total`);
86
+ }
87
+ L.push(`- **Outstanding:** ${s.outstanding.length === 0 ? 'none' : s.outstanding.length}`, '');
88
+ for (const label of s.order) {
89
+ const items = s.groups[label];
90
+ L.push(`## ${label}`, '');
91
+ L.push('| ID | Status | Title | Progress | PR | Linear |');
92
+ L.push('|----|--------|-------|----------|----|--------|');
93
+ for (const i of items) {
94
+ const title = i.title.replace(/\|/g, '\\|');
95
+ L.push(`| ${i.id} | ${mdIcon(i.status)} ${i.status} | ${title} | ${progCell(i)} | ${ghCell(i)} | ${linCell(i)} |`);
104
96
  }
105
- else {
106
- // No epics — flat listing fallback
107
- printSection('Features', features, showAll);
108
- printSection('User Stories', stories, showAll);
97
+ L.push('');
98
+ }
99
+ L.push('## Outstanding work', '');
100
+ if (s.outstanding.length === 0) {
101
+ L.push('None — every item is done or addressed (promoted/superseded).');
102
+ }
103
+ else {
104
+ for (const i of s.outstanding)
105
+ L.push(`- **${i.id}** ${i.title} — _${i.status}_`);
106
+ }
107
+ if (s.warnings.length) {
108
+ L.push('', '## Notes', '');
109
+ for (const w of s.warnings)
110
+ L.push(`- ${w}`);
111
+ }
112
+ return L.join('\n');
113
+ }
114
+ function renderTerminal(s, ctx) {
115
+ logger.heading(`Delivery Status — ${s.projectName} (${s.mode})`);
116
+ display.blank();
117
+ for (const label of s.order) {
118
+ const items = s.groups[label];
119
+ const doneN = items.filter((i) => i.done).length;
120
+ const addressedN = items.filter((i) => i.addressed).length;
121
+ const resolvedPct = items.length ? Math.round(((doneN + addressedN) / items.length) * 100) : 0;
122
+ const addressedTxt = addressedN > 0 ? ` (+${addressedN} promoted/superseded)` : '';
123
+ display.line(` ${chalk.bold(label)}: ${colorByPercent(`${doneN}/${items.length} done`, resolvedPct)}${chalk.dim(addressedTxt)}`);
124
+ const list = ctx.showAll ? items : items.slice(0, 12);
125
+ for (const i of list) {
126
+ const st = statusColor(i.status)(`[${i.status}]`);
127
+ const prog = progCell(i) ? chalk.dim(` ${progCell(i)}`) : '';
128
+ const gh = i.github?.pr || i.github?.issue ? chalk.cyan(` ${ghCell(i)}`) : '';
129
+ const lin = i.linear ? chalk.magenta(` ${linCell(i)}`) : '';
130
+ display.line(` ${i.id} ${i.title} ${st}${prog}${gh}${lin}`);
109
131
  }
110
- // Task lists with completion metrics
132
+ if (!ctx.showAll && items.length > 12)
133
+ display.line(chalk.dim(` … and ${items.length - 12} more (use --all)`));
111
134
  display.blank();
112
- const taskIcon = tasks.length > 0 ? '●' : '○';
113
- display.line(` ${taskIcon} Task Lists: ${tasks.length}`);
114
- if (tasks.length > 0) {
115
- const taskList = showAll ? tasks : tasks.slice(0, 5);
116
- for (const t of taskList) {
117
- const metrics = taskMetrics.get(t.id);
118
- if (metrics && metrics.total > 0) {
119
- const pct = Math.round((metrics.done / metrics.total) * 100);
120
- const progressText = `(${metrics.done}/${metrics.total} subtasks, ${pct}%)`;
121
- const coloredProgress = colorByPercent(progressText, pct);
122
- display.line(` ${t.id} ${t.title} ${coloredProgress}`);
123
- }
124
- else {
125
- display.line(` ${t.id} ${t.title}`);
126
- }
127
- }
128
- if (!showAll && tasks.length > 5) {
129
- display.line(chalk.dim(` ... and ${tasks.length - 5} more`));
130
- }
131
- // Overall task completion summary
132
- let totalDone = 0;
133
- let totalSubtasks = 0;
134
- for (const m of taskMetrics.values()) {
135
- totalDone += m.done;
136
- totalSubtasks += m.total;
137
- }
138
- if (totalSubtasks > 0) {
139
- const overallPct = Math.round((totalDone / totalSubtasks) * 100);
140
- display.blank();
141
- display.line(` ${colorByPercent(`Overall: ${totalDone}/${totalSubtasks} subtasks complete (${overallPct}%)`, overallPct)}`);
142
- }
143
- }
144
- // Backlog items
145
- const backlogItems = await listArtifacts(projectDir, config, 'backlog');
146
- if (backlogItems.length > 0) {
147
- display.blank();
148
- display.line(` ${chalk.red('●')} Backlog: ${backlogItems.length}`);
149
- const blList = showAll ? backlogItems : backlogItems.slice(0, 5);
150
- for (const bl of blList) {
151
- const blRaw = await readArtifactRaw(projectDir, config, 'backlog', bl.id);
152
- const priority = blRaw
153
- ? parseMarkdown(blRaw).data.priority || 'medium'
154
- : 'medium';
155
- const priorityColor = priority === 'critical' ? chalk.red : priority === 'high' ? chalk.yellow : chalk.dim;
156
- display.line(` ${bl.id} ${bl.title} ${priorityColor(`[${priority}]`)}`);
157
- }
158
- if (!showAll && backlogItems.length > 5) {
159
- display.line(chalk.dim(` ... and ${backlogItems.length - 5} more`));
160
- }
161
- }
162
- // Sprint
163
- const sprints = await listArtifacts(projectDir, config, 'sprint');
164
- const activeSprint = sprints.length > 0
165
- ? await (async () => {
166
- for (const s of sprints) {
167
- const sRaw = await readArtifactRaw(projectDir, config, 'sprint', s.id);
168
- if (sRaw && parseMarkdown(sRaw).data.status === 'active') {
169
- return { ...s, data: parseMarkdown(sRaw).data };
170
- }
171
- }
172
- return null;
173
- })()
174
- : null;
175
- if (activeSprint) {
176
- display.blank();
177
- const sprintName = activeSprint.data.name || activeSprint.title;
178
- const endDate = activeSprint.data.endDate;
179
- let remaining = '';
180
- if (endDate) {
181
- const daysLeft = Math.ceil((new Date(endDate).getTime() - Date.now()) / (1000 * 60 * 60 * 24));
182
- remaining = daysLeft > 0 ? chalk.yellow(` (${daysLeft}d left)`) : chalk.red(' (ended)');
183
- }
184
- display.line(` ${chalk.blueBright('●')} Active Sprint: ${activeSprint.id} — ${sprintName}${remaining}`);
185
- }
186
- // Quick tasks (standalone, outside hierarchy)
187
- const quickTasks = await listArtifacts(projectDir, config, 'quick');
188
- if (quickTasks.length > 0) {
189
- display.blank();
190
- display.line(` ● Quick Tasks: ${quickTasks.length}`);
191
- const quickList = showAll ? quickTasks : quickTasks.slice(0, 5);
192
- for (const qt of quickList) {
193
- const raw = await readArtifactRaw(projectDir, config, 'quick', qt.id);
194
- if (raw) {
195
- const parsed = parseTaskMarkdown(raw);
196
- const subtasks = parsed.filter((s) => s.depth > 0);
197
- const total = subtasks.length || parsed.length;
198
- const done = (subtasks.length > 0 ? subtasks : parsed).filter((s) => s.done).length;
199
- if (total > 0) {
200
- const pct = Math.round((done / total) * 100);
201
- display.line(` ${qt.id} ${qt.title} ${colorByPercent(`(${done}/${total}, ${pct}%)`, pct)}`);
202
- }
203
- else {
204
- display.line(` ${qt.id} ${qt.title}`);
205
- }
206
- }
207
- else {
208
- display.line(` ${qt.id} ${qt.title}`);
209
- }
210
- }
211
- if (!showAll && quickTasks.length > 5) {
212
- display.line(chalk.dim(` ... and ${quickTasks.length - 5} more`));
213
- }
135
+ }
136
+ // Outstanding work
137
+ if (s.outstanding.length === 0) {
138
+ display.line(` ${chalk.green('●')} Outstanding work: none every item is done or addressed (promoted/superseded).`);
139
+ }
140
+ else {
141
+ display.line(` ${chalk.yellow('●')} Outstanding work: ${s.outstanding.length}`);
142
+ for (const i of ctx.showAll ? s.outstanding : s.outstanding.slice(0, 12)) {
143
+ display.line(` ${i.id} ${i.title} ${statusColor(i.status)(`[${i.status}]`)}`);
214
144
  }
215
- // Summary counts
216
- const quickCount = quickTasks.length > 0 ? `, ${quickTasks.length} quick tasks` : '';
217
- const blCount = backlogItems.length > 0 ? `, ${backlogItems.length} backlog` : '';
218
- const sprintCount = sprints.length > 0 ? `, ${sprints.length} sprint${sprints.length !== 1 ? 's' : ''}` : '';
145
+ if (!ctx.showAll && s.outstanding.length > 12)
146
+ display.line(chalk.dim(` … and ${s.outstanding.length - 12} more`));
147
+ }
148
+ for (const w of s.warnings) {
219
149
  display.blank();
220
- display.line(chalk.dim(` Totals: ${epics.length} epics, ${features.length} features, ${stories.length} stories, ${tasks.length} task lists${quickCount}${blCount}${sprintCount}`));
221
- logger.dim(`Targets: ${config.targets.join(', ')}`);
222
- logger.dim(`Artifacts: ${config.outputPaths.agile}/`);
223
- });
224
- }
225
- function printSection(label, items, showAll) {
226
- const count = items.length;
227
- const icon = count > 0 ? '●' : '○';
228
- display.line(` ${icon} ${label}: ${count}`);
229
- if (count > 0) {
230
- const list = showAll ? items : items.slice(0, 5);
231
- for (const item of list) {
232
- display.line(` ${item.id} ${item.title}`);
233
- }
234
- if (!showAll && count > 5) {
235
- display.line(chalk.dim(` ... and ${count - 5} more`));
236
- }
150
+ logger.dim(` ${w}`);
237
151
  }
152
+ display.blank();
153
+ logger.dim(`Tip: --md for a paste-ready report · --json for machine output · --github --linear for live status`);
154
+ logger.dim(`Artifacts: ${ctx.config.outputPaths.agile}/`);
238
155
  }
239
156
  //# sourceMappingURL=status.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAClG,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8BAA8B,CAAC;SAC3C,MAAM,CAAC,OAAO,EAAE,mCAAmC,CAAC;SACpD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,UAAoB,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAE3B,MAAM,CAAC,OAAO,CAAC,sBAAsB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,uBAAuB;QACvB,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAE9D,4FAA4F;QAC5F,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;QAChD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;QACjD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE/C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YACrE,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM;gBAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,MAAgB,CAAC,CAAC;QAC7E,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YACnE,IAAI,IAAI,EAAE,IAAI,CAAC,SAAS;gBAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,SAAmB,CAAC,CAAC;QACpF,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAClE,MAAM,WAAW,GAAG,IAAI,EAAE,IAAI,CAAC,OAA6B,CAAC;YAC7D,MAAM,aAAa,GAAG,IAAI,EAAE,IAAI,CAAC,SAA+B,CAAC;YACjE,IAAI,WAAW;gBAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;iBAChD,IAAI,aAAa;gBAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QAChE,CAAC;QAED,0BAA0B;QAC1B,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2C,CAAC;QACvE,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YACpE,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;gBACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;gBAC/C,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;gBACpF,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,qCAAqC;QACrC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAE7D,2BAA2B;gBAC3B,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;gBACjF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC5B,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACtE,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;wBAC5B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;wBAErD,6BAA6B;wBAC7B,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;wBAChF,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBACxE,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;4BAC1B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;wBACvD,CAAC;wBACD,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BAC1C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,cAAc,CAAC,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;wBACrF,CAAC;oBACH,CAAC;oBACD,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,YAAY,CAAC,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBAClF,CAAC;gBACH,CAAC;YACH,CAAC;YAED,0CAA0C;YAC1C,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACxE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,OAAO,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAC5E,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBACtE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;YAED,4CAA4C;YAC5C,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACvE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,uBAAuB,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAC1E,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBACpE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,mCAAmC;YACnC,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC5C,YAAY,CAAC,cAAc,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAED,qCAAqC;QACrC,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,KAAK,QAAQ,gBAAgB,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACrD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACtC,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;oBACjC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;oBAC7D,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,cAAc,GAAG,IAAI,CAAC;oBAC5E,MAAM,eAAe,GAAG,cAAc,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;oBAC1D,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC,CAAC;gBAC9D,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YACD,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAClE,CAAC;YAED,kCAAkC;YAClC,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,aAAa,GAAG,CAAC,CAAC;YACtB,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;gBACrC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC;gBACpB,aAAa,IAAI,CAAC,CAAC,KAAK,CAAC;YAC3B,CAAC;YACD,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;gBACjE,OAAO,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,IAAI,CACV,KAAK,cAAc,CAAC,YAAY,SAAS,IAAI,aAAa,uBAAuB,UAAU,IAAI,EAAE,UAAU,CAAC,EAAE,CAC/G,CAAC;YACJ,CAAC;QACH,CAAC;QAED,gBAAgB;QAChB,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACxE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;YACpE,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACjE,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC1E,MAAM,QAAQ,GAAG,KAAK;oBACpB,CAAC,CAAE,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAmB,IAAI,QAAQ;oBAC5D,CAAC,CAAC,QAAQ,CAAC;gBACb,MAAM,aAAa,GACjB,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;gBACvF,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,KAAK,aAAa,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/E,CAAC;YACD,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,YAAY,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAED,SAAS;QACT,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAClE,MAAM,YAAY,GAChB,OAAO,CAAC,MAAM,GAAG,CAAC;YAChB,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;gBAChB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;oBACxB,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;oBACvE,IAAI,IAAI,IAAK,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAiB,KAAK,QAAQ,EAAE,CAAC;wBACrE,OAAO,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;oBAClD,CAAC;gBACH,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,EAAE;YACN,CAAC,CAAC,IAAI,CAAC;QAEX,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,UAAU,GAAI,YAAY,CAAC,IAAI,CAAC,IAAe,IAAI,YAAY,CAAC,KAAK,CAAC;YAC5E,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,OAA6B,CAAC;YAChE,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CACnE,CAAC;gBACF,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC1F,CAAC;YACD,OAAO,CAAC,IAAI,CACV,KAAK,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,mBAAmB,YAAY,CAAC,EAAE,MAAM,UAAU,GAAG,SAAS,EAAE,CAC3F,CAAC;QACJ,CAAC;QAED,8CAA8C;QAC9C,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACpE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,oBAAoB,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChE,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;gBACtE,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;oBACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;oBACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;oBAC/C,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;oBACpF,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;wBACd,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;wBAC7C,OAAO,CAAC,IAAI,CACV,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,KAAK,cAAc,CAAC,IAAI,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,CACnF,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;oBAC5C,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YACD,IAAI,CAAC,OAAO,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,UAAU,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,MAAM,WAAW,GACf,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CACV,KAAK,CAAC,GAAG,CACP,aAAa,KAAK,CAAC,MAAM,WAAW,QAAQ,CAAC,MAAM,cAAc,OAAO,CAAC,MAAM,aAAa,KAAK,CAAC,MAAM,cAAc,UAAU,GAAG,OAAO,GAAG,WAAW,EAAE,CAC3J,CACF,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,YAAY,CACnB,KAAa,EACb,KAA2C,EAC3C,OAAgB;IAEhB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC,CAAC;IAC7C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjD,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,OAAO,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Delivery-status aggregation — the deterministic core behind `planr status`
3
+ * (no slug → whole-project delivery report). Rolls up every Spec / Backlog /
4
+ * Quick Task (or the agile tree) by status and OPTIONALLY cross-references
5
+ * GitHub PRs and Linear issue state.
6
+ *
7
+ * Reuses existing services (no new auth, no new sources):
8
+ * listSpecs (spec-service) — spec rows + status + counts
9
+ * listArtifacts/readArtifact/readArtifactRaw (artifact-service) — frontmatter
10
+ * fetchRecentPullRequests/getIssue (github-service) — PR/issue state (gh CLI)
11
+ * createLinearClient/fetchLinearIssueStateNames (linear-service) — live issue state
12
+ *
13
+ * Pure aggregation + a typed result so the command layer can render it as
14
+ * terminal / markdown / json without re-querying.
15
+ */
16
+ import type { OpenPlanrConfig } from '../models/types.js';
17
+ export interface DeliveryItem {
18
+ id: string;
19
+ title: string;
20
+ type: 'spec' | 'epic' | 'feature' | 'story' | 'task' | 'quick' | 'backlog';
21
+ status: string;
22
+ done: boolean;
23
+ /**
24
+ * Resolved without being "done": `promoted` (backlog graduated into a
25
+ * spec/QT/story) or `superseded` (split/replaced). Addressed items are NOT
26
+ * outstanding work, but they also don't inflate the done count.
27
+ */
28
+ addressed: boolean;
29
+ /** subtask completion, when the artifact is a checklist */
30
+ progress?: {
31
+ done: number;
32
+ total: number;
33
+ };
34
+ priority?: string;
35
+ linear?: {
36
+ identifier: string;
37
+ url?: string;
38
+ state?: string;
39
+ };
40
+ github?: {
41
+ issue?: number;
42
+ issueState?: string;
43
+ pr?: {
44
+ number: number;
45
+ merged: boolean;
46
+ };
47
+ };
48
+ }
49
+ export interface DeliveryStatus {
50
+ projectName: string;
51
+ mode: 'spec-driven' | 'agile';
52
+ groups: Record<string, DeliveryItem[]>;
53
+ order: string[];
54
+ summary: {
55
+ label: string;
56
+ done: number;
57
+ addressed: number;
58
+ total: number;
59
+ }[];
60
+ /** Items that are neither done nor addressed — the real open work. */
61
+ outstanding: DeliveryItem[];
62
+ warnings: string[];
63
+ }
64
+ export interface CollectOptions {
65
+ scope?: string;
66
+ github?: boolean;
67
+ linear?: boolean;
68
+ }
69
+ /** Collect the full delivery status (optionally scoped, optionally live-enriched). */
70
+ export declare function collectDeliveryStatus(projectDir: string, config: OpenPlanrConfig, opts?: CollectOptions): Promise<DeliveryStatus>;
71
+ //# sourceMappingURL=delivery-status-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-status-service.d.ts","sourceRoot":"","sources":["../../src/services/delivery-status-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKxE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC;CAC5F;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IACvC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7E,sEAAsE;IACtE,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAyED,sFAAsF;AACtF,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,cAAc,CAAC,CAoEzB"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Delivery-status aggregation — the deterministic core behind `planr status`
3
+ * (no slug → whole-project delivery report). Rolls up every Spec / Backlog /
4
+ * Quick Task (or the agile tree) by status and OPTIONALLY cross-references
5
+ * GitHub PRs and Linear issue state.
6
+ *
7
+ * Reuses existing services (no new auth, no new sources):
8
+ * listSpecs (spec-service) — spec rows + status + counts
9
+ * listArtifacts/readArtifact/readArtifactRaw (artifact-service) — frontmatter
10
+ * fetchRecentPullRequests/getIssue (github-service) — PR/issue state (gh CLI)
11
+ * createLinearClient/fetchLinearIssueStateNames (linear-service) — live issue state
12
+ *
13
+ * Pure aggregation + a typed result so the command layer can render it as
14
+ * terminal / markdown / json without re-querying.
15
+ */
16
+ import { parseTaskMarkdown } from '../agents/task-parser.js';
17
+ import { logger } from '../utils/logger.js';
18
+ import { listArtifacts, readArtifact, readArtifactRaw } from './artifact-service.js';
19
+ import { listSpecs } from './spec-service.js';
20
+ /** Per-type "done" semantics for a delivery roll-up. */
21
+ function isDone(type, status) {
22
+ const s = (status || '').toLowerCase();
23
+ if (type === 'backlog')
24
+ return s === 'closed' || s === 'done';
25
+ return s === 'done' || s === 'completed' || s === 'shipped' || s === 'released';
26
+ }
27
+ /**
28
+ * "Addressed" = resolved without being done: a backlog item `promoted` into a
29
+ * spec/QT/story, or any artifact `superseded` (split/replaced). These are not
30
+ * outstanding work — but counting them as "done" misstates the delivery
31
+ * summary (e.g. "1 done + 6 promoted", not "7 done").
32
+ */
33
+ function isAddressed(status) {
34
+ const s = (status || '').toLowerCase();
35
+ return s === 'promoted' || s === 'superseded';
36
+ }
37
+ function pickStr(v) {
38
+ return typeof v === 'string' && v.trim() ? v.trim() : undefined;
39
+ }
40
+ /** Read an artifact's frontmatter + (for checklists) its subtask completion. */
41
+ async function toItem(projectDir, config, type, meta) {
42
+ const artType = type;
43
+ const read = await readArtifact(projectDir, config, artType, meta.id);
44
+ const fm = (read?.data ?? {});
45
+ const status = pickStr(fm.status) ?? 'pending';
46
+ let progress;
47
+ if (type === 'quick' || type === 'task') {
48
+ const raw = await readArtifactRaw(projectDir, config, artType, meta.id);
49
+ if (raw) {
50
+ const parsed = parseTaskMarkdown(raw);
51
+ const subtasks = parsed.filter((s) => s.depth > 0);
52
+ const list = subtasks.length > 0 ? subtasks : parsed;
53
+ const total = list.length;
54
+ if (total > 0)
55
+ progress = { done: list.filter((s) => s.done).length, total };
56
+ }
57
+ }
58
+ const linearId = pickStr(fm.linearIssueIdentifier);
59
+ const item = {
60
+ id: meta.id,
61
+ title: pickStr(fm.title) ?? meta.title,
62
+ type,
63
+ status,
64
+ done: isDone(type, status),
65
+ addressed: isAddressed(status),
66
+ progress,
67
+ priority: pickStr(fm.priority),
68
+ };
69
+ if (linearId) {
70
+ item.linear = {
71
+ identifier: linearId,
72
+ url: pickStr(fm.linearIssueUrl),
73
+ state: pickStr(fm.linearStatusReconciled),
74
+ };
75
+ // stash the UUID for the optional --linear live pass
76
+ item._linearId = pickStr(fm.linearIssueId);
77
+ }
78
+ const ghIssue = typeof fm.githubIssue === 'number' ? fm.githubIssue : undefined;
79
+ if (ghIssue)
80
+ item.github = { issue: ghIssue };
81
+ return item;
82
+ }
83
+ /** Collect the full delivery status (optionally scoped, optionally live-enriched). */
84
+ export async function collectDeliveryStatus(projectDir, config, opts = {}) {
85
+ const warnings = [];
86
+ const specs = config.idPrefix?.spec ? await listSpecs(projectDir, config) : [];
87
+ const mode = specs.length > 0 ? 'spec-driven' : 'agile';
88
+ const groups = {};
89
+ const order = [];
90
+ const add = (label, items) => {
91
+ if (items.length === 0)
92
+ return;
93
+ groups[label] = items;
94
+ order.push(label);
95
+ };
96
+ if (mode === 'spec-driven') {
97
+ add('Specs', specs.map((s) => ({
98
+ id: s.id,
99
+ title: s.title,
100
+ type: 'spec',
101
+ status: s.status,
102
+ done: isDone('spec', s.status),
103
+ addressed: isAddressed(s.status),
104
+ // spec rows report status only — we don't roll up per-spec task completion here
105
+ // (would read every spec's task files); `done` status is the delivery signal.
106
+ })));
107
+ }
108
+ else {
109
+ for (const t of ['epic', 'feature', 'story', 'task']) {
110
+ const list = await listArtifacts(projectDir, config, t);
111
+ const items = await Promise.all(list.map((m) => toItem(projectDir, config, t, m)));
112
+ add(t === 'epic' ? 'Epics' : t === 'feature' ? 'Features' : t === 'story' ? 'Stories' : 'Tasks', items);
113
+ }
114
+ }
115
+ const backlog = await listArtifacts(projectDir, config, 'backlog');
116
+ add('Backlog', await Promise.all(backlog.map((m) => toItem(projectDir, config, 'backlog', m))));
117
+ const quick = await listArtifacts(projectDir, config, 'quick');
118
+ add('Quick Tasks', await Promise.all(quick.map((m) => toItem(projectDir, config, 'quick', m))));
119
+ // Optional scoping to one id/slug (matches the item or its id prefix).
120
+ if (opts.scope) {
121
+ const scope = opts.scope.trim().toLowerCase();
122
+ for (const label of order) {
123
+ groups[label] = groups[label].filter((i) => {
124
+ const id = i.id.toLowerCase();
125
+ return id === scope || id.startsWith(scope) || i.title.toLowerCase().includes(scope);
126
+ });
127
+ }
128
+ }
129
+ const allItems = order.flatMap((l) => groups[l]);
130
+ if (opts.linear)
131
+ await enrichLinear(allItems, warnings);
132
+ if (opts.github)
133
+ await enrichGithub(allItems, warnings);
134
+ const summary = order.map((label) => ({
135
+ label,
136
+ done: groups[label].filter((i) => i.done).length,
137
+ addressed: groups[label].filter((i) => i.addressed).length,
138
+ total: groups[label].length,
139
+ }));
140
+ const outstanding = allItems.filter((i) => !i.done && !i.addressed);
141
+ return { projectName: config.projectName, mode, groups, order, summary, outstanding, warnings };
142
+ }
143
+ /** --linear: resolve live issue state for items carrying a Linear UUID. */
144
+ async function enrichLinear(items, warnings) {
145
+ const withId = items.filter((i) => i._linearId);
146
+ if (withId.length === 0)
147
+ return;
148
+ try {
149
+ const { createLinearClient, fetchLinearIssueStateNames, LINEAR_CREDENTIAL_KEY } = await import('./linear-service.js');
150
+ const { resolveApiKey } = await import('./credentials-service.js');
151
+ const token = (await resolveApiKey(LINEAR_CREDENTIAL_KEY))?.trim();
152
+ if (!token) {
153
+ warnings.push('--linear: no Linear token (run `planr linear init` or set PLANR_LINEAR_TOKEN); using reconciled state.');
154
+ return;
155
+ }
156
+ const client = createLinearClient(token);
157
+ const ids = withId.map((i) => i._linearId);
158
+ const states = await fetchLinearIssueStateNames(client, ids);
159
+ for (const i of withId) {
160
+ const uuid = i._linearId;
161
+ const state = states.get(uuid);
162
+ if (state && i.linear)
163
+ i.linear.state = state;
164
+ }
165
+ }
166
+ catch (err) {
167
+ logger.debug('enrichLinear failed', err);
168
+ warnings.push('--linear: could not reach Linear; using reconciled state from frontmatter.');
169
+ }
170
+ }
171
+ /** --github: resolve issue state + best-effort PR correlation (artifact id in PR title/branch). */
172
+ async function enrichGithub(items, warnings) {
173
+ try {
174
+ const { verifyGitHubRepo, getIssue, fetchRecentPullRequests } = await import('./github-service.js');
175
+ await verifyGitHubRepo();
176
+ // Best-effort PR correlation: a wide PR window, matched by artifact id in title/branch.
177
+ const { pullRequests, warning } = await fetchRecentPullRequests({ days: 3650, limit: 300 });
178
+ if (warning)
179
+ warnings.push(`--github: ${warning}`);
180
+ for (const i of items) {
181
+ const idRe = new RegExp(`\\b${i.id}\\b`, 'i');
182
+ const pr = pullRequests.find((p) => idRe.test(p.title));
183
+ if (pr)
184
+ i.github = { ...(i.github ?? {}), pr: { number: pr.number, merged: pr.mergedAt != null } };
185
+ }
186
+ // Resolve linked-issue state where an artifact stored a githubIssue number.
187
+ for (const i of items) {
188
+ if (!i.github?.issue)
189
+ continue;
190
+ try {
191
+ const issue = await getIssue(i.github.issue);
192
+ i.github.issueState = issue.state;
193
+ }
194
+ catch {
195
+ /* issue gone / no access — skip */
196
+ }
197
+ }
198
+ }
199
+ catch (err) {
200
+ logger.debug('enrichGithub failed', err);
201
+ warnings.push('--github: could not reach GitHub (is `gh` authenticated?); showing frontmatter links only.');
202
+ }
203
+ }
204
+ //# sourceMappingURL=delivery-status-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-status-service.js","sourceRoot":"","sources":["../../src/services/delivery-status-service.ts"],"names":[],"mappings":"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"}
@@ -130,7 +130,7 @@ error_reports:
130
130
 
131
131
  - **R1** — Never auto-chain PLAN → SHIP. Always wait for explicit "ship {feature}".
132
132
  - **R2** — Max 2 tasks per US.
133
- - **R3** — Roles using `Sonnet 4.6` are analysis/decomposition; roles using `Opus 4.7` are codegen. On Codex, use the model picker to match.
133
+ - **R3** — Roles using `Sonnet 4.6` are analysis/decomposition; roles using `Opus 4.8` are codegen. On Codex, use the model picker to match.
134
134
  - **R5** — Files in any task's `Preserve:` list MUST NOT be touched. Conformance test asserts this via `git diff` on Preserve paths.
135
135
  - **R6** — Max 3 correction iterations per task.
136
136
  - **R7** — Refresh CLAUDE.md (or skip if planr-managed); always write `.pipeline-shipped` marker.
@@ -143,7 +143,7 @@ What is IN scope. What is explicitly OUT of scope for this US.]
143
143
 
144
144
  > **US:** us-{N} — [US Title]
145
145
  > **Feature:** feat-{name}
146
- > **Agent:** [Frontend Agent | Backend Agent] (Opus 4.7)
146
+ > **Agent:** [Frontend Agent | Backend Agent] (Opus 4.8)
147
147
  > **Type:** [UI | Tech]
148
148
  > **Status:** pending
149
149
 
@@ -98,7 +98,7 @@ list. **Treat the restrictions as binding.**
98
98
  - **R1** — Never auto-chain PO → DEV. Two user invocations required.
99
99
  - **R2** — Max 2 tasks per US (1 if no PNG, 2 if PNG present).
100
100
  - **R3** — Model assignments: roles using `Sonnet 4.6` are analysis/decomposition;
101
- roles using `Opus 4.7` are codegen. On Cursor, use the runtime's tier
101
+ roles using `Opus 4.8` are codegen. On Cursor, use the runtime's tier
102
102
  selector (Cursor's "Composer model" setting) and pick the equivalent.
103
103
  - **R5** — Files in any task's `Preserve:` list MUST NOT be touched.
104
104
  - **R6** — Max 3 correction iterations per task. After 3, write
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openplanr",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "AI-powered planning CLI — backlog, sprints, task templates, estimation, GitHub and Linear sync, and AI agent rules for Cursor, Claude Code, and Codex",
5
5
  "type": "module",
6
6
  "main": "./dist/cli/index.js",
@@ -71,7 +71,7 @@
71
71
  "url": "https://github.com/openplanr/OpenPlanr/issues"
72
72
  },
73
73
  "dependencies": {
74
- "@anthropic-ai/sdk": "^0.81.0",
74
+ "@anthropic-ai/sdk": "^0.91.1",
75
75
  "@inquirer/prompts": "^8.3.2",
76
76
  "@linear/sdk": "^65.2.0",
77
77
  "@napi-rs/keyring": "^1.2.0",