smartlisa 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -0
- package/dist/cli.js +6517 -0
- package/dist/src/adapters/cli/formatter.d.ts +34 -0
- package/dist/src/adapters/cli/formatter.d.ts.map +1 -0
- package/dist/src/adapters/cli/formatter.js +254 -0
- package/dist/src/adapters/cli/formatter.js.map +1 -0
- package/dist/src/adapters/cli/index.d.ts +14 -0
- package/dist/src/adapters/cli/index.d.ts.map +1 -0
- package/dist/src/adapters/cli/index.js +781 -0
- package/dist/src/adapters/cli/index.js.map +1 -0
- package/dist/src/adapters/state/__tests__/api.test.d.ts +8 -0
- package/dist/src/adapters/state/__tests__/api.test.d.ts.map +1 -0
- package/dist/src/adapters/state/__tests__/api.test.js +500 -0
- package/dist/src/adapters/state/__tests__/api.test.js.map +1 -0
- package/dist/src/adapters/state/__tests__/filesystem.test.d.ts +7 -0
- package/dist/src/adapters/state/__tests__/filesystem.test.d.ts.map +1 -0
- package/dist/src/adapters/state/__tests__/filesystem.test.js +418 -0
- package/dist/src/adapters/state/__tests__/filesystem.test.js.map +1 -0
- package/dist/src/adapters/state/api.d.ts +148 -0
- package/dist/src/adapters/state/api.d.ts.map +1 -0
- package/dist/src/adapters/state/api.js +337 -0
- package/dist/src/adapters/state/api.js.map +1 -0
- package/dist/src/adapters/state/filesystem.d.ts +80 -0
- package/dist/src/adapters/state/filesystem.d.ts.map +1 -0
- package/dist/src/adapters/state/filesystem.js +228 -0
- package/dist/src/adapters/state/filesystem.js.map +1 -0
- package/dist/src/adapters/state/index.d.ts +9 -0
- package/dist/src/adapters/state/index.d.ts.map +1 -0
- package/dist/src/adapters/state/index.js +10 -0
- package/dist/src/adapters/state/index.js.map +1 -0
- package/dist/src/adapters/state/types.d.ts +131 -0
- package/dist/src/adapters/state/types.d.ts.map +1 -0
- package/dist/src/adapters/state/types.js +11 -0
- package/dist/src/adapters/state/types.js.map +1 -0
- package/dist/src/core/__tests__/context.test.d.ts +12 -0
- package/dist/src/core/__tests__/context.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/context.test.js +528 -0
- package/dist/src/core/__tests__/context.test.js.map +1 -0
- package/dist/src/core/__tests__/discover.test.d.ts +2 -0
- package/dist/src/core/__tests__/discover.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/discover.test.js +667 -0
- package/dist/src/core/__tests__/discover.test.js.map +1 -0
- package/dist/src/core/__tests__/engine.test.d.ts +2 -0
- package/dist/src/core/__tests__/engine.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/engine.test.js +444 -0
- package/dist/src/core/__tests__/engine.test.js.map +1 -0
- package/dist/src/core/__tests__/feedback.test.d.ts +2 -0
- package/dist/src/core/__tests__/feedback.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/feedback.test.js +351 -0
- package/dist/src/core/__tests__/feedback.test.js.map +1 -0
- package/dist/src/core/__tests__/plan.test.d.ts +2 -0
- package/dist/src/core/__tests__/plan.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/plan.test.js +429 -0
- package/dist/src/core/__tests__/plan.test.js.map +1 -0
- package/dist/src/core/__tests__/schemas.test.d.ts +2 -0
- package/dist/src/core/__tests__/schemas.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/schemas.test.js +614 -0
- package/dist/src/core/__tests__/schemas.test.js.map +1 -0
- package/dist/src/core/__tests__/state.test.d.ts +2 -0
- package/dist/src/core/__tests__/state.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/state.test.js +1107 -0
- package/dist/src/core/__tests__/state.test.js.map +1 -0
- package/dist/src/core/__tests__/status.test.d.ts +2 -0
- package/dist/src/core/__tests__/status.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/status.test.js +600 -0
- package/dist/src/core/__tests__/status.test.js.map +1 -0
- package/dist/src/core/__tests__/test-helpers.d.ts +28 -0
- package/dist/src/core/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/src/core/__tests__/test-helpers.js +185 -0
- package/dist/src/core/__tests__/test-helpers.js.map +1 -0
- package/dist/src/core/__tests__/utils.test.d.ts +2 -0
- package/dist/src/core/__tests__/utils.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/utils.test.js +276 -0
- package/dist/src/core/__tests__/utils.test.js.map +1 -0
- package/dist/src/core/__tests__/validate.test.d.ts +2 -0
- package/dist/src/core/__tests__/validate.test.d.ts.map +1 -0
- package/dist/src/core/__tests__/validate.test.js +354 -0
- package/dist/src/core/__tests__/validate.test.js.map +1 -0
- package/dist/src/core/commands/discover.d.ts +71 -0
- package/dist/src/core/commands/discover.d.ts.map +1 -0
- package/dist/src/core/commands/discover.js +687 -0
- package/dist/src/core/commands/discover.js.map +1 -0
- package/dist/src/core/commands/feedback.d.ts +49 -0
- package/dist/src/core/commands/feedback.d.ts.map +1 -0
- package/dist/src/core/commands/feedback.js +283 -0
- package/dist/src/core/commands/feedback.js.map +1 -0
- package/dist/src/core/commands/index.d.ts +11 -0
- package/dist/src/core/commands/index.d.ts.map +1 -0
- package/dist/src/core/commands/index.js +11 -0
- package/dist/src/core/commands/index.js.map +1 -0
- package/dist/src/core/commands/plan.d.ts +108 -0
- package/dist/src/core/commands/plan.d.ts.map +1 -0
- package/dist/src/core/commands/plan.js +621 -0
- package/dist/src/core/commands/plan.js.map +1 -0
- package/dist/src/core/commands/status.d.ts +72 -0
- package/dist/src/core/commands/status.d.ts.map +1 -0
- package/dist/src/core/commands/status.js +720 -0
- package/dist/src/core/commands/status.js.map +1 -0
- package/dist/src/core/commands/validate.d.ts +47 -0
- package/dist/src/core/commands/validate.d.ts.map +1 -0
- package/dist/src/core/commands/validate.js +608 -0
- package/dist/src/core/commands/validate.js.map +1 -0
- package/dist/src/core/engine.d.ts +294 -0
- package/dist/src/core/engine.d.ts.map +1 -0
- package/dist/src/core/engine.js +219 -0
- package/dist/src/core/engine.js.map +1 -0
- package/dist/src/core/index.d.ts +14 -0
- package/dist/src/core/index.d.ts.map +1 -0
- package/dist/src/core/index.js +18 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/core/prompts/context-helpers.d.ts +48 -0
- package/dist/src/core/prompts/context-helpers.d.ts.map +1 -0
- package/dist/src/core/prompts/context-helpers.js +206 -0
- package/dist/src/core/prompts/context-helpers.js.map +1 -0
- package/dist/src/core/prompts/discovery.d.ts +11 -0
- package/dist/src/core/prompts/discovery.d.ts.map +1 -0
- package/dist/src/core/prompts/discovery.js +179 -0
- package/dist/src/core/prompts/discovery.js.map +1 -0
- package/dist/src/core/prompts/feedback.d.ts +38 -0
- package/dist/src/core/prompts/feedback.d.ts.map +1 -0
- package/dist/src/core/prompts/feedback.js +292 -0
- package/dist/src/core/prompts/feedback.js.map +1 -0
- package/dist/src/core/prompts/index.d.ts +12 -0
- package/dist/src/core/prompts/index.d.ts.map +1 -0
- package/dist/src/core/prompts/index.js +12 -0
- package/dist/src/core/prompts/index.js.map +1 -0
- package/dist/src/core/prompts/planning.d.ts +15 -0
- package/dist/src/core/prompts/planning.d.ts.map +1 -0
- package/dist/src/core/prompts/planning.js +293 -0
- package/dist/src/core/prompts/planning.js.map +1 -0
- package/dist/src/core/prompts/status.d.ts +41 -0
- package/dist/src/core/prompts/status.d.ts.map +1 -0
- package/dist/src/core/prompts/status.js +270 -0
- package/dist/src/core/prompts/status.js.map +1 -0
- package/dist/src/core/prompts/validate.d.ts +62 -0
- package/dist/src/core/prompts/validate.d.ts.map +1 -0
- package/dist/src/core/prompts/validate.js +302 -0
- package/dist/src/core/prompts/validate.js.map +1 -0
- package/dist/src/core/schemas.d.ts +5045 -0
- package/dist/src/core/schemas.d.ts.map +1 -0
- package/dist/src/core/schemas.js +492 -0
- package/dist/src/core/schemas.js.map +1 -0
- package/dist/src/core/state.d.ts +156 -0
- package/dist/src/core/state.d.ts.map +1 -0
- package/dist/src/core/state.js +608 -0
- package/dist/src/core/state.js.map +1 -0
- package/dist/src/core/types.d.ts +167 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +102 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/core/utils.d.ts +39 -0
- package/dist/src/core/utils.d.ts.map +1 -0
- package/dist/src/core/utils.js +208 -0
- package/dist/src/core/utils.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,781 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Lisa CLI - Command Line Interface for Lisa Planning Engine
|
|
4
|
+
*
|
|
5
|
+
* A standalone CLI that can be used independently of Claude Code.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* lisa status - Show project overview
|
|
9
|
+
* lisa discover - Start/continue discovery
|
|
10
|
+
* lisa plan milestones - Generate milestones
|
|
11
|
+
* ...
|
|
12
|
+
*/
|
|
13
|
+
import { createEngine } from "../../core/engine.js";
|
|
14
|
+
import { handleResult, output } from "./formatter.js";
|
|
15
|
+
function parseArgs(args) {
|
|
16
|
+
const result = {
|
|
17
|
+
positional: [],
|
|
18
|
+
flags: {},
|
|
19
|
+
};
|
|
20
|
+
let i = 0;
|
|
21
|
+
while (i < args.length) {
|
|
22
|
+
const arg = args[i];
|
|
23
|
+
if (arg.startsWith("--")) {
|
|
24
|
+
const key = arg.slice(2);
|
|
25
|
+
const nextArg = args[i + 1];
|
|
26
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
27
|
+
result.flags[key] = nextArg;
|
|
28
|
+
i += 2;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
result.flags[key] = true;
|
|
32
|
+
i++;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (arg.startsWith("-")) {
|
|
36
|
+
const key = arg.slice(1);
|
|
37
|
+
result.flags[key] = true;
|
|
38
|
+
i++;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
if (!result.command) {
|
|
42
|
+
result.command = arg;
|
|
43
|
+
}
|
|
44
|
+
else if (!result.subcommand) {
|
|
45
|
+
result.subcommand = arg;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
result.positional.push(arg);
|
|
49
|
+
}
|
|
50
|
+
i++;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// Help System
|
|
57
|
+
// ============================================================================
|
|
58
|
+
function showHelp() {
|
|
59
|
+
// ASCII art banner
|
|
60
|
+
console.log();
|
|
61
|
+
console.log(" _ ___ ____ _ ");
|
|
62
|
+
console.log(" | | |_ _/ ___| / \\ ");
|
|
63
|
+
console.log(" | | | |\\___ \\ / _ \\ ");
|
|
64
|
+
console.log(" | |___ | | ___) / ___ \\ ");
|
|
65
|
+
console.log(" |_____|___|____/_/ \\_\\");
|
|
66
|
+
console.log();
|
|
67
|
+
console.log(" AI-powered planning system");
|
|
68
|
+
console.log();
|
|
69
|
+
output.subheader("Usage:");
|
|
70
|
+
console.log(" lisa <command> [subcommand] [options]");
|
|
71
|
+
console.log(" lisa <command> --help Show help for a specific command");
|
|
72
|
+
output.blank();
|
|
73
|
+
output.subheader("Commands:");
|
|
74
|
+
console.log(" status View project state and story details");
|
|
75
|
+
console.log(" discover Gather project context through guided discovery");
|
|
76
|
+
console.log(" plan Create and manage roadmap artifacts");
|
|
77
|
+
console.log(" feedback Track progress and manage feedback items");
|
|
78
|
+
console.log(" validate Check plan integrity and coverage");
|
|
79
|
+
output.blank();
|
|
80
|
+
output.subheader("Quick Start:");
|
|
81
|
+
console.log(" lisa discover init \"My Project\" Initialize a new project");
|
|
82
|
+
console.log(" lisa discover Start discovery process");
|
|
83
|
+
console.log(" lisa plan milestones View/create milestones");
|
|
84
|
+
console.log(" lisa status Check project overview");
|
|
85
|
+
output.blank();
|
|
86
|
+
output.subheader("Global Options:");
|
|
87
|
+
console.log(" --help, -h Show help (use with any command for details)");
|
|
88
|
+
console.log(" --full Show full output without truncation");
|
|
89
|
+
console.log(" --format json Output in JSON format");
|
|
90
|
+
output.blank();
|
|
91
|
+
output.subheader("Examples:");
|
|
92
|
+
console.log(" lisa status --help Get help on status commands");
|
|
93
|
+
console.log(" lisa discover --deep Deep discovery mode");
|
|
94
|
+
console.log(" lisa feedback mark E1.S1 done Mark story as complete");
|
|
95
|
+
console.log(" lisa status context E1 --full View epic context in full");
|
|
96
|
+
output.blank();
|
|
97
|
+
output.subheader("Note:");
|
|
98
|
+
console.log(" When using npm scripts, pass flags after '--':");
|
|
99
|
+
console.log(" npm run lisa -- --help");
|
|
100
|
+
console.log(" npm run lisa -- status --help");
|
|
101
|
+
output.blank();
|
|
102
|
+
}
|
|
103
|
+
function showStatusHelp() {
|
|
104
|
+
output.header("lisa status");
|
|
105
|
+
console.log("View project state, story details, and context information.");
|
|
106
|
+
output.blank();
|
|
107
|
+
output.subheader("Usage:");
|
|
108
|
+
console.log(" lisa status [subcommand] [options]");
|
|
109
|
+
output.blank();
|
|
110
|
+
output.subheader("Subcommands:");
|
|
111
|
+
console.log(" (none) Show project overview with phase and progress");
|
|
112
|
+
console.log(" board [epic] Show kanban board (optionally filter by epic)");
|
|
113
|
+
console.log(" show <id> Show detailed story information");
|
|
114
|
+
console.log(" context [target] Show context for project, milestone, epic, or story");
|
|
115
|
+
console.log(" why <id> Explain why a story exists (trace lineage)");
|
|
116
|
+
console.log(" how <id> Get implementation guidance for a story");
|
|
117
|
+
output.blank();
|
|
118
|
+
output.subheader("Options:");
|
|
119
|
+
console.log(" --help, -h Show this help");
|
|
120
|
+
console.log(" --full Show full output without truncation");
|
|
121
|
+
console.log(" --format json Output in JSON format");
|
|
122
|
+
output.blank();
|
|
123
|
+
output.subheader("Arguments:");
|
|
124
|
+
console.log(" <id> Story ID in format E1.S2 (Epic 1, Story 2)");
|
|
125
|
+
console.log(" [epic] Epic ID in format E1 (optional filter for board)");
|
|
126
|
+
console.log(" [target] M1 (milestone), E1 (epic), or E1.S2 (story)");
|
|
127
|
+
output.blank();
|
|
128
|
+
output.subheader("Examples:");
|
|
129
|
+
console.log(" lisa status Project overview");
|
|
130
|
+
console.log(" lisa status board Full kanban board");
|
|
131
|
+
console.log(" lisa status board E1 Board filtered to Epic 1");
|
|
132
|
+
console.log(" lisa status show E1.S3 Details for story E1.S3");
|
|
133
|
+
console.log(" lisa status context Full project context");
|
|
134
|
+
console.log(" lisa status context E1 --full Epic 1 context (untruncated)");
|
|
135
|
+
console.log(" lisa status why E2.S1 Why does this story exist?");
|
|
136
|
+
console.log(" lisa status how E1.S2 How to implement this story");
|
|
137
|
+
output.blank();
|
|
138
|
+
}
|
|
139
|
+
function showDiscoverHelp() {
|
|
140
|
+
output.header("lisa discover");
|
|
141
|
+
console.log("Gather project context through guided discovery sessions.");
|
|
142
|
+
output.blank();
|
|
143
|
+
output.subheader("Usage:");
|
|
144
|
+
console.log(" lisa discover [subcommand] [options]");
|
|
145
|
+
output.blank();
|
|
146
|
+
output.subheader("Subcommands:");
|
|
147
|
+
console.log(" (none) Start or continue discovery session");
|
|
148
|
+
console.log(" init <name> Initialize a new project");
|
|
149
|
+
console.log(" status Show discovery progress and gaps");
|
|
150
|
+
console.log(" complete Mark discovery phase as complete");
|
|
151
|
+
console.log(" add-entry Add a discovery entry (project-level)");
|
|
152
|
+
console.log(" epic <id> Start discovery for a specific epic");
|
|
153
|
+
console.log(" milestone <id> Start discovery for a milestone");
|
|
154
|
+
console.log(" add-element-entry Add entry to milestone/epic discovery");
|
|
155
|
+
console.log(" complete-element Complete milestone/epic discovery");
|
|
156
|
+
output.blank();
|
|
157
|
+
output.subheader("Discovery Depth Options:");
|
|
158
|
+
console.log(" --quick Essentials only (faster, less thorough)");
|
|
159
|
+
console.log(" --standard Balanced depth (default)");
|
|
160
|
+
console.log(" --deep Comprehensive discovery (more questions)");
|
|
161
|
+
output.blank();
|
|
162
|
+
output.subheader("Other Options:");
|
|
163
|
+
console.log(" --help, -h Show this help");
|
|
164
|
+
output.blank();
|
|
165
|
+
output.subheader("Add Entry Options (project-level):");
|
|
166
|
+
console.log(" --category <cat> Category: problem, vision, users, values,");
|
|
167
|
+
console.log(" constraints, success, other");
|
|
168
|
+
console.log(" --question '<q>' The discovery question");
|
|
169
|
+
console.log(" --answer '<a>' The answer/information gathered");
|
|
170
|
+
output.blank();
|
|
171
|
+
output.subheader("Add Element Entry Options (milestone/epic-level):");
|
|
172
|
+
console.log(" --element-type Type: milestone or epic");
|
|
173
|
+
console.log(" --element-id ID: M1, E1, etc.");
|
|
174
|
+
console.log(" --category <cat> Category: problem, vision, users, values,");
|
|
175
|
+
console.log(" constraints, success, other");
|
|
176
|
+
console.log(" --question '<q>' The discovery question");
|
|
177
|
+
console.log(" --answer '<a>' The answer/information gathered");
|
|
178
|
+
output.blank();
|
|
179
|
+
output.subheader("Examples:");
|
|
180
|
+
console.log(" lisa discover init \"E-commerce Platform\"");
|
|
181
|
+
console.log(" lisa discover Continue discovery");
|
|
182
|
+
console.log(" lisa discover --deep Deep discovery mode");
|
|
183
|
+
console.log(" lisa discover status Check progress");
|
|
184
|
+
console.log(" lisa discover epic E1 Discover for Epic 1");
|
|
185
|
+
console.log(" lisa discover milestone M1 Discover for Milestone 1");
|
|
186
|
+
console.log(" lisa discover add-entry \\");
|
|
187
|
+
console.log(" --category problem \\");
|
|
188
|
+
console.log(" --question 'What problem are we solving?' \\");
|
|
189
|
+
console.log(" --answer 'Users cannot track their orders'");
|
|
190
|
+
console.log(" lisa discover add-element-entry \\");
|
|
191
|
+
console.log(" --element-type milestone --element-id M1 \\");
|
|
192
|
+
console.log(" --category success \\");
|
|
193
|
+
console.log(" --question 'What are the success criteria for M1?' \\");
|
|
194
|
+
console.log(" --answer 'Users can complete checkout flow'");
|
|
195
|
+
console.log(" lisa discover complete-element \\");
|
|
196
|
+
console.log(" --element-type milestone --element-id M1");
|
|
197
|
+
output.blank();
|
|
198
|
+
}
|
|
199
|
+
function showPlanHelp() {
|
|
200
|
+
output.header("lisa plan");
|
|
201
|
+
console.log("Create and manage roadmap artifacts: milestones, epics, and stories.");
|
|
202
|
+
output.blank();
|
|
203
|
+
output.subheader("Usage:");
|
|
204
|
+
console.log(" lisa plan [subcommand] [options]");
|
|
205
|
+
output.blank();
|
|
206
|
+
output.subheader("Subcommands:");
|
|
207
|
+
console.log(" (none) Show milestones (same as 'milestones')");
|
|
208
|
+
console.log(" milestones List all milestones");
|
|
209
|
+
console.log(" add-milestone Add a new milestone");
|
|
210
|
+
console.log(" epics [M1] List epics (optionally filter by milestone)");
|
|
211
|
+
console.log(" add-epic Add a new epic to a milestone");
|
|
212
|
+
console.log(" epic <id> View/plan a specific epic");
|
|
213
|
+
console.log(" stories <id> List stories for an epic");
|
|
214
|
+
output.blank();
|
|
215
|
+
output.subheader("Options:");
|
|
216
|
+
console.log(" --help, -h Show this help");
|
|
217
|
+
output.blank();
|
|
218
|
+
output.subheader("Add Milestone Options:");
|
|
219
|
+
console.log(" --name '<name>' Milestone name (required)");
|
|
220
|
+
console.log(" --description '<desc>' Milestone description (required)");
|
|
221
|
+
output.blank();
|
|
222
|
+
output.subheader("Add Epic Options:");
|
|
223
|
+
console.log(" --milestone <M1> Parent milestone ID (required)");
|
|
224
|
+
console.log(" --name '<name>' Epic name (required)");
|
|
225
|
+
console.log(" --description '<desc>' Epic description (required)");
|
|
226
|
+
output.blank();
|
|
227
|
+
output.subheader("Examples:");
|
|
228
|
+
console.log(" lisa plan View milestones");
|
|
229
|
+
console.log(" lisa plan milestones Same as above");
|
|
230
|
+
console.log(" lisa plan add-milestone \\");
|
|
231
|
+
console.log(" --name 'MVP Launch' \\");
|
|
232
|
+
console.log(" --description 'Core features for initial release'");
|
|
233
|
+
console.log(" lisa plan epics View all epics");
|
|
234
|
+
console.log(" lisa plan epics M1 View epics in Milestone 1");
|
|
235
|
+
console.log(" lisa plan add-epic \\");
|
|
236
|
+
console.log(" --milestone M1 \\");
|
|
237
|
+
console.log(" --name 'User Authentication' \\");
|
|
238
|
+
console.log(" --description 'Login, signup, password reset'");
|
|
239
|
+
console.log(" lisa plan epic E1 View Epic 1 details");
|
|
240
|
+
console.log(" lisa plan stories E1 View stories in Epic 1");
|
|
241
|
+
output.blank();
|
|
242
|
+
}
|
|
243
|
+
function showFeedbackHelp() {
|
|
244
|
+
output.header("lisa feedback");
|
|
245
|
+
console.log("Track work progress and manage feedback items on stories.");
|
|
246
|
+
output.blank();
|
|
247
|
+
output.subheader("Usage:");
|
|
248
|
+
console.log(" lisa feedback [subcommand] [options]");
|
|
249
|
+
output.blank();
|
|
250
|
+
output.subheader("Subcommands:");
|
|
251
|
+
console.log(" (none) List all pending feedback items");
|
|
252
|
+
console.log(" mark <id> <status> Update story status");
|
|
253
|
+
console.log(" add <id> Add feedback to a story");
|
|
254
|
+
console.log(" resolve <fb-id> Mark feedback as resolved");
|
|
255
|
+
console.log(" dismiss <fb-id> Dismiss feedback without action");
|
|
256
|
+
output.blank();
|
|
257
|
+
output.subheader("Story Statuses (for 'mark'):");
|
|
258
|
+
console.log(" todo Not started");
|
|
259
|
+
console.log(" assigned Assigned to someone");
|
|
260
|
+
console.log(" in_progress Work in progress");
|
|
261
|
+
console.log(" review In review");
|
|
262
|
+
console.log(" done Completed");
|
|
263
|
+
console.log(" blocked Blocked by dependency/issue");
|
|
264
|
+
console.log(" deferred Postponed to later");
|
|
265
|
+
output.blank();
|
|
266
|
+
output.subheader("Feedback Types (for 'add'):");
|
|
267
|
+
console.log(" blocker Something blocking progress");
|
|
268
|
+
console.log(" gap Missing information or requirement");
|
|
269
|
+
console.log(" scope Scope change or clarification needed");
|
|
270
|
+
console.log(" conflict Conflicting requirements");
|
|
271
|
+
console.log(" question Question needing answer");
|
|
272
|
+
output.blank();
|
|
273
|
+
output.subheader("Options:");
|
|
274
|
+
console.log(" --help, -h Show this help");
|
|
275
|
+
console.log(" --reason '<text>' Reason for status change (mark)");
|
|
276
|
+
console.log(" --type <type> Feedback type (add)");
|
|
277
|
+
console.log(" --message '<text>' Feedback message (add)");
|
|
278
|
+
console.log(" --resolution '<t>' Resolution note (resolve)");
|
|
279
|
+
output.blank();
|
|
280
|
+
output.subheader("Examples:");
|
|
281
|
+
console.log(" lisa feedback List pending feedback");
|
|
282
|
+
console.log(" lisa feedback mark E1.S1 in_progress");
|
|
283
|
+
console.log(" lisa feedback mark E1.S2 done --reason 'PR merged'");
|
|
284
|
+
console.log(" lisa feedback mark E2.S1 blocked --reason 'Waiting on API'");
|
|
285
|
+
console.log(" lisa feedback add E1.S3 \\");
|
|
286
|
+
console.log(" --type blocker \\");
|
|
287
|
+
console.log(" --message 'Missing API documentation'");
|
|
288
|
+
console.log(" lisa feedback add E2.S1 \\");
|
|
289
|
+
console.log(" --type question \\");
|
|
290
|
+
console.log(" --message 'Should this support pagination?'");
|
|
291
|
+
console.log(" lisa feedback resolve fb-abc123 \\");
|
|
292
|
+
console.log(" --resolution 'Added pagination support'");
|
|
293
|
+
console.log(" lisa feedback dismiss fb-xyz789");
|
|
294
|
+
output.blank();
|
|
295
|
+
}
|
|
296
|
+
function showValidateHelp() {
|
|
297
|
+
output.header("lisa validate");
|
|
298
|
+
console.log("Check plan integrity, cross-references, and coverage.");
|
|
299
|
+
output.blank();
|
|
300
|
+
output.subheader("Usage:");
|
|
301
|
+
console.log(" lisa validate [subcommand] [options]");
|
|
302
|
+
output.blank();
|
|
303
|
+
output.subheader("Subcommands:");
|
|
304
|
+
console.log(" (none) Run full validation suite");
|
|
305
|
+
console.log(" links Check all cross-references are valid");
|
|
306
|
+
console.log(" coverage Check requirement coverage by stories");
|
|
307
|
+
console.log(" epic <id> Validate a specific epic");
|
|
308
|
+
output.blank();
|
|
309
|
+
output.subheader("Options:");
|
|
310
|
+
console.log(" --help, -h Show this help");
|
|
311
|
+
output.blank();
|
|
312
|
+
output.subheader("What Gets Validated:");
|
|
313
|
+
console.log(" • All story IDs reference valid epics");
|
|
314
|
+
console.log(" • All epic IDs reference valid milestones");
|
|
315
|
+
console.log(" • No orphaned or dangling references");
|
|
316
|
+
console.log(" • Requirements have implementing stories");
|
|
317
|
+
console.log(" • Stories have acceptance criteria");
|
|
318
|
+
console.log(" • Epic scope is complete and consistent");
|
|
319
|
+
output.blank();
|
|
320
|
+
output.subheader("Examples:");
|
|
321
|
+
console.log(" lisa validate Run all checks");
|
|
322
|
+
console.log(" lisa validate links Check references only");
|
|
323
|
+
console.log(" lisa validate coverage Check requirement coverage");
|
|
324
|
+
console.log(" lisa validate epic E1 Validate Epic 1 only");
|
|
325
|
+
console.log(" lisa validate E2 Shorthand for 'epic E2'");
|
|
326
|
+
output.blank();
|
|
327
|
+
}
|
|
328
|
+
function showCommandHelp(command) {
|
|
329
|
+
switch (command) {
|
|
330
|
+
case "status":
|
|
331
|
+
showStatusHelp();
|
|
332
|
+
return true;
|
|
333
|
+
case "discover":
|
|
334
|
+
showDiscoverHelp();
|
|
335
|
+
return true;
|
|
336
|
+
case "plan":
|
|
337
|
+
showPlanHelp();
|
|
338
|
+
return true;
|
|
339
|
+
case "feedback":
|
|
340
|
+
showFeedbackHelp();
|
|
341
|
+
return true;
|
|
342
|
+
case "validate":
|
|
343
|
+
showValidateHelp();
|
|
344
|
+
return true;
|
|
345
|
+
default:
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// ============================================================================
|
|
350
|
+
// Main
|
|
351
|
+
// ============================================================================
|
|
352
|
+
async function main() {
|
|
353
|
+
const args = parseArgs(process.argv.slice(2));
|
|
354
|
+
// Global help (no command)
|
|
355
|
+
if (!args.command && (args.flags.help || args.flags.h || process.argv.length <= 2)) {
|
|
356
|
+
showHelp();
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
// Command-specific help
|
|
360
|
+
if (args.command && (args.flags.help || args.flags.h)) {
|
|
361
|
+
if (showCommandHelp(args.command)) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
// Unknown command, fall through to show error
|
|
365
|
+
}
|
|
366
|
+
const engine = createEngine();
|
|
367
|
+
try {
|
|
368
|
+
switch (args.command) {
|
|
369
|
+
// ======================================================================
|
|
370
|
+
// Status Commands
|
|
371
|
+
// ======================================================================
|
|
372
|
+
case "status": {
|
|
373
|
+
switch (args.subcommand) {
|
|
374
|
+
case "board": {
|
|
375
|
+
const result = await engine.status.board(args.positional[0]);
|
|
376
|
+
handleResult(result);
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
case "show": {
|
|
380
|
+
const storyId = args.positional[0];
|
|
381
|
+
if (!storyId) {
|
|
382
|
+
output.error("Usage: lisa status show <story-id>");
|
|
383
|
+
process.exit(1);
|
|
384
|
+
}
|
|
385
|
+
const result = await engine.status.story(storyId);
|
|
386
|
+
handleResult(result);
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
case "context": {
|
|
390
|
+
const result = await engine.status.context({
|
|
391
|
+
target: args.positional[0],
|
|
392
|
+
full: Boolean(args.flags.full),
|
|
393
|
+
format: args.flags.format === "json" ? "json" : "text",
|
|
394
|
+
});
|
|
395
|
+
handleResult(result);
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
case "why": {
|
|
399
|
+
const storyId = args.positional[0];
|
|
400
|
+
if (!storyId) {
|
|
401
|
+
output.error("Usage: lisa status why <story-id>");
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
const result = await engine.status.why(storyId);
|
|
405
|
+
handleResult(result);
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
case "how": {
|
|
409
|
+
const storyId = args.positional[0];
|
|
410
|
+
if (!storyId) {
|
|
411
|
+
output.error("Usage: lisa status how <story-id>");
|
|
412
|
+
process.exit(1);
|
|
413
|
+
}
|
|
414
|
+
const result = await engine.status.how(storyId);
|
|
415
|
+
handleResult(result);
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
default: {
|
|
419
|
+
// Default: show overview
|
|
420
|
+
const result = await engine.status.overview();
|
|
421
|
+
handleResult(result);
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
// ======================================================================
|
|
428
|
+
// Discovery Commands
|
|
429
|
+
// ======================================================================
|
|
430
|
+
case "discover": {
|
|
431
|
+
switch (args.subcommand) {
|
|
432
|
+
case "init": {
|
|
433
|
+
const name = args.positional[0] || "Untitled Project";
|
|
434
|
+
const result = await engine.discover.init(name);
|
|
435
|
+
handleResult(result);
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
case "status": {
|
|
439
|
+
const result = await engine.discover.status();
|
|
440
|
+
handleResult(result);
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
case "complete": {
|
|
444
|
+
const result = await engine.discover.complete();
|
|
445
|
+
handleResult(result);
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
case "add-entry": {
|
|
449
|
+
const category = args.flags.category;
|
|
450
|
+
const question = args.flags.question;
|
|
451
|
+
const answer = args.flags.answer;
|
|
452
|
+
if (!category || !question || !answer) {
|
|
453
|
+
output.error("Usage: lisa discover add-entry --category <cat> --question '<q>' --answer '<a>'");
|
|
454
|
+
process.exit(1);
|
|
455
|
+
}
|
|
456
|
+
const result = await engine.discover.addEntry({
|
|
457
|
+
category: category,
|
|
458
|
+
question,
|
|
459
|
+
answer,
|
|
460
|
+
});
|
|
461
|
+
handleResult(result);
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
case "epic":
|
|
465
|
+
case "milestone": {
|
|
466
|
+
const elementId = args.positional[0];
|
|
467
|
+
if (!elementId) {
|
|
468
|
+
output.error(`Usage: lisa discover ${args.subcommand} <id>`);
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
471
|
+
const result = await engine.discover.element({
|
|
472
|
+
elementType: args.subcommand,
|
|
473
|
+
elementId,
|
|
474
|
+
});
|
|
475
|
+
handleResult(result);
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
case "add-element-entry": {
|
|
479
|
+
const elementType = args.flags["element-type"];
|
|
480
|
+
const elementId = args.flags["element-id"];
|
|
481
|
+
const category = args.flags.category;
|
|
482
|
+
const question = args.flags.question;
|
|
483
|
+
const answer = args.flags.answer;
|
|
484
|
+
if (!elementType || !elementId || !category || !question || !answer) {
|
|
485
|
+
output.error("Usage: lisa discover add-element-entry --element-type <milestone|epic> --element-id <id> --category <cat> --question '<q>' --answer '<a>'");
|
|
486
|
+
process.exit(1);
|
|
487
|
+
}
|
|
488
|
+
if (elementType !== "milestone" && elementType !== "epic") {
|
|
489
|
+
output.error("Invalid element-type. Must be 'milestone' or 'epic'");
|
|
490
|
+
process.exit(1);
|
|
491
|
+
}
|
|
492
|
+
const result = await engine.discover.addElementEntry({
|
|
493
|
+
elementType: elementType,
|
|
494
|
+
elementId,
|
|
495
|
+
category: category,
|
|
496
|
+
question,
|
|
497
|
+
answer,
|
|
498
|
+
});
|
|
499
|
+
handleResult(result);
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
case "complete-element": {
|
|
503
|
+
const elementType = args.flags["element-type"];
|
|
504
|
+
const elementId = args.flags["element-id"];
|
|
505
|
+
if (!elementType || !elementId) {
|
|
506
|
+
output.error("Usage: lisa discover complete-element --element-type <milestone|epic> --element-id <id>");
|
|
507
|
+
process.exit(1);
|
|
508
|
+
}
|
|
509
|
+
if (elementType !== "milestone" && elementType !== "epic") {
|
|
510
|
+
output.error("Invalid element-type. Must be 'milestone' or 'epic'");
|
|
511
|
+
process.exit(1);
|
|
512
|
+
}
|
|
513
|
+
const result = await engine.discover.completeElement({
|
|
514
|
+
elementType: elementType,
|
|
515
|
+
elementId,
|
|
516
|
+
});
|
|
517
|
+
handleResult(result);
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
default: {
|
|
521
|
+
// Default: start/continue discovery
|
|
522
|
+
let depth;
|
|
523
|
+
if (args.flags.quick)
|
|
524
|
+
depth = "quick";
|
|
525
|
+
else if (args.flags.deep)
|
|
526
|
+
depth = "deep";
|
|
527
|
+
else if (args.flags.standard)
|
|
528
|
+
depth = "standard";
|
|
529
|
+
const result = await engine.discover.start({ depth });
|
|
530
|
+
handleResult(result);
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
536
|
+
// ======================================================================
|
|
537
|
+
// Plan Commands
|
|
538
|
+
// ======================================================================
|
|
539
|
+
case "plan": {
|
|
540
|
+
switch (args.subcommand) {
|
|
541
|
+
case "milestones": {
|
|
542
|
+
const result = await engine.plan.milestones();
|
|
543
|
+
handleResult(result);
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
case "add-milestone": {
|
|
547
|
+
const name = args.flags.name;
|
|
548
|
+
const description = args.flags.description;
|
|
549
|
+
if (!name || !description) {
|
|
550
|
+
output.error("Usage: lisa plan add-milestone --name '<name>' --description '<desc>'");
|
|
551
|
+
process.exit(1);
|
|
552
|
+
}
|
|
553
|
+
const result = await engine.plan.addMilestone({ name, description });
|
|
554
|
+
handleResult(result);
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
case "epics": {
|
|
558
|
+
const result = await engine.plan.epics(args.positional[0]);
|
|
559
|
+
handleResult(result);
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
case "add-epic": {
|
|
563
|
+
const milestoneId = args.flags.milestone;
|
|
564
|
+
const name = args.flags.name;
|
|
565
|
+
const description = args.flags.description;
|
|
566
|
+
if (!milestoneId || !name || !description) {
|
|
567
|
+
output.error("Usage: lisa plan add-epic --milestone M1 --name '<name>' --description '<desc>'");
|
|
568
|
+
process.exit(1);
|
|
569
|
+
}
|
|
570
|
+
const result = await engine.plan.addEpic({ milestoneId, name, description });
|
|
571
|
+
handleResult(result);
|
|
572
|
+
break;
|
|
573
|
+
}
|
|
574
|
+
case "epic": {
|
|
575
|
+
const epicId = args.positional[0];
|
|
576
|
+
if (!epicId) {
|
|
577
|
+
output.error("Usage: lisa plan epic <E1>");
|
|
578
|
+
process.exit(1);
|
|
579
|
+
}
|
|
580
|
+
const result = await engine.plan.epic(epicId);
|
|
581
|
+
handleResult(result);
|
|
582
|
+
break;
|
|
583
|
+
}
|
|
584
|
+
case "stories": {
|
|
585
|
+
const epicId = args.positional[0];
|
|
586
|
+
if (!epicId) {
|
|
587
|
+
output.error("Usage: lisa plan stories <E1>");
|
|
588
|
+
process.exit(1);
|
|
589
|
+
}
|
|
590
|
+
const result = await engine.plan.stories(epicId);
|
|
591
|
+
handleResult(result);
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
case "savePrd": {
|
|
595
|
+
const epicId = args.positional[0];
|
|
596
|
+
const content = args.positional[1];
|
|
597
|
+
if (!epicId || !content) {
|
|
598
|
+
output.error("Usage: lisa plan savePrd <E1> '<prd-content>'");
|
|
599
|
+
process.exit(1);
|
|
600
|
+
}
|
|
601
|
+
const result = await engine.plan.savePrd({ epicId, content });
|
|
602
|
+
handleResult(result);
|
|
603
|
+
break;
|
|
604
|
+
}
|
|
605
|
+
case "saveArchitecture": {
|
|
606
|
+
const epicId = args.positional[0];
|
|
607
|
+
const content = args.positional[1];
|
|
608
|
+
if (!epicId || !content) {
|
|
609
|
+
output.error("Usage: lisa plan saveArchitecture <E1> '<architecture-content>'");
|
|
610
|
+
process.exit(1);
|
|
611
|
+
}
|
|
612
|
+
const result = await engine.plan.saveArchitecture({ epicId, content });
|
|
613
|
+
handleResult(result);
|
|
614
|
+
break;
|
|
615
|
+
}
|
|
616
|
+
case "saveStories": {
|
|
617
|
+
const epicId = args.positional[0];
|
|
618
|
+
const storiesJson = args.positional[1];
|
|
619
|
+
if (!epicId || !storiesJson) {
|
|
620
|
+
output.error("Usage: lisa plan saveStories <E1> '<stories-json>'");
|
|
621
|
+
process.exit(1);
|
|
622
|
+
}
|
|
623
|
+
try {
|
|
624
|
+
const stories = JSON.parse(storiesJson);
|
|
625
|
+
const result = await engine.plan.saveStories({ epicId, stories });
|
|
626
|
+
handleResult(result);
|
|
627
|
+
}
|
|
628
|
+
catch (e) {
|
|
629
|
+
output.error(`Invalid JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
630
|
+
process.exit(1);
|
|
631
|
+
}
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
default: {
|
|
635
|
+
// Default: show milestones
|
|
636
|
+
const result = await engine.plan.milestones();
|
|
637
|
+
handleResult(result);
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
// ======================================================================
|
|
644
|
+
// Feedback Commands
|
|
645
|
+
// ======================================================================
|
|
646
|
+
case "feedback": {
|
|
647
|
+
switch (args.subcommand) {
|
|
648
|
+
case "mark": {
|
|
649
|
+
const storyId = args.positional[0];
|
|
650
|
+
const status = args.positional[1];
|
|
651
|
+
const reason = args.flags.reason;
|
|
652
|
+
if (!storyId || !status) {
|
|
653
|
+
output.error("Usage: lisa feedback mark <E1.S2> <status> [--reason '...']");
|
|
654
|
+
output.dim(" Statuses: todo, assigned, in_progress, review, done, blocked, deferred");
|
|
655
|
+
process.exit(1);
|
|
656
|
+
}
|
|
657
|
+
const validStatuses = ["todo", "assigned", "in_progress", "review", "done", "blocked", "deferred"];
|
|
658
|
+
if (!validStatuses.includes(status)) {
|
|
659
|
+
output.error(`Invalid status: ${status}`);
|
|
660
|
+
output.dim(` Valid: ${validStatuses.join(", ")}`);
|
|
661
|
+
process.exit(1);
|
|
662
|
+
}
|
|
663
|
+
const result = await engine.feedback.mark({ storyId, status, reason });
|
|
664
|
+
handleResult(result);
|
|
665
|
+
break;
|
|
666
|
+
}
|
|
667
|
+
case "add": {
|
|
668
|
+
const storyId = args.positional[0];
|
|
669
|
+
const type = args.flags.type;
|
|
670
|
+
const message = args.flags.message;
|
|
671
|
+
if (!storyId || !type || !message) {
|
|
672
|
+
output.error("Usage: lisa feedback add <E1.S2> --type <type> --message '...'");
|
|
673
|
+
output.dim(" Types: blocker, gap, scope, conflict, question");
|
|
674
|
+
process.exit(1);
|
|
675
|
+
}
|
|
676
|
+
const validTypes = ["blocker", "gap", "scope", "conflict", "question"];
|
|
677
|
+
if (!validTypes.includes(type)) {
|
|
678
|
+
output.error(`Invalid type: ${type}`);
|
|
679
|
+
output.dim(` Valid: ${validTypes.join(", ")}`);
|
|
680
|
+
process.exit(1);
|
|
681
|
+
}
|
|
682
|
+
const result = await engine.feedback.add({ storyId, type, message });
|
|
683
|
+
handleResult(result);
|
|
684
|
+
break;
|
|
685
|
+
}
|
|
686
|
+
case "resolve": {
|
|
687
|
+
const feedbackId = args.positional[0];
|
|
688
|
+
const resolution = args.flags.resolution;
|
|
689
|
+
if (!feedbackId) {
|
|
690
|
+
output.error("Usage: lisa feedback resolve <fb-xxx> [--resolution '...']");
|
|
691
|
+
process.exit(1);
|
|
692
|
+
}
|
|
693
|
+
const result = await engine.feedback.resolve({ feedbackId, resolution });
|
|
694
|
+
handleResult(result);
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
case "dismiss": {
|
|
698
|
+
const feedbackId = args.positional[0];
|
|
699
|
+
if (!feedbackId) {
|
|
700
|
+
output.error("Usage: lisa feedback dismiss <fb-xxx>");
|
|
701
|
+
process.exit(1);
|
|
702
|
+
}
|
|
703
|
+
const result = await engine.feedback.dismiss(feedbackId);
|
|
704
|
+
handleResult(result);
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
default: {
|
|
708
|
+
// Default: list feedback
|
|
709
|
+
const result = await engine.feedback.list();
|
|
710
|
+
handleResult(result);
|
|
711
|
+
break;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
// ======================================================================
|
|
717
|
+
// Validate Commands
|
|
718
|
+
// ======================================================================
|
|
719
|
+
case "validate": {
|
|
720
|
+
switch (args.subcommand) {
|
|
721
|
+
case "links": {
|
|
722
|
+
const result = await engine.validate.links();
|
|
723
|
+
handleResult(result);
|
|
724
|
+
break;
|
|
725
|
+
}
|
|
726
|
+
case "coverage": {
|
|
727
|
+
const result = await engine.validate.coverage();
|
|
728
|
+
handleResult(result);
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
case "epic": {
|
|
732
|
+
const epicId = args.positional[0];
|
|
733
|
+
if (!epicId) {
|
|
734
|
+
output.error("Usage: lisa validate epic <E1>");
|
|
735
|
+
process.exit(1);
|
|
736
|
+
}
|
|
737
|
+
const result = await engine.validate.epic(epicId);
|
|
738
|
+
handleResult(result);
|
|
739
|
+
break;
|
|
740
|
+
}
|
|
741
|
+
default: {
|
|
742
|
+
// Check if subcommand looks like an epic ID
|
|
743
|
+
if (args.subcommand && args.subcommand.match(/^E\d+$/)) {
|
|
744
|
+
const result = await engine.validate.epic(args.subcommand);
|
|
745
|
+
handleResult(result);
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
// Default: full validation
|
|
749
|
+
const result = await engine.validate.all();
|
|
750
|
+
handleResult(result);
|
|
751
|
+
}
|
|
752
|
+
break;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
757
|
+
// ======================================================================
|
|
758
|
+
// Unknown Command
|
|
759
|
+
// ======================================================================
|
|
760
|
+
default: {
|
|
761
|
+
output.error(`Unknown command: ${args.command}`);
|
|
762
|
+
output.info("Run 'lisa --help' for usage information.");
|
|
763
|
+
process.exit(1);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
catch (err) {
|
|
768
|
+
if (err instanceof Error) {
|
|
769
|
+
output.error(err.message);
|
|
770
|
+
if (process.env.DEBUG) {
|
|
771
|
+
console.error(err.stack);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
output.error(String(err));
|
|
776
|
+
}
|
|
777
|
+
process.exit(1);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
main();
|
|
781
|
+
//# sourceMappingURL=index.js.map
|