smartlisa 0.1.0 → 0.1.7
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/.claude-plugin/plugin.json +9 -0
- package/README.md +25 -0
- package/dist/cli.js +37 -39
- package/package.json +8 -3
- package/skills/lisa/SKILL.md +67 -0
- package/skills/lisa/references/commands.md +201 -0
- package/skills/lisa/references/examples.md +277 -0
- package/skills/lisa-work/SKILL.md +98 -0
- package/skills/lisa-work/references/workflow.md +226 -0
- package/dist/src/adapters/cli/formatter.d.ts +0 -34
- package/dist/src/adapters/cli/formatter.d.ts.map +0 -1
- package/dist/src/adapters/cli/formatter.js +0 -254
- package/dist/src/adapters/cli/formatter.js.map +0 -1
- package/dist/src/adapters/cli/index.d.ts +0 -14
- package/dist/src/adapters/cli/index.d.ts.map +0 -1
- package/dist/src/adapters/cli/index.js +0 -781
- package/dist/src/adapters/cli/index.js.map +0 -1
- package/dist/src/adapters/state/__tests__/api.test.d.ts +0 -8
- package/dist/src/adapters/state/__tests__/api.test.d.ts.map +0 -1
- package/dist/src/adapters/state/__tests__/api.test.js +0 -500
- package/dist/src/adapters/state/__tests__/api.test.js.map +0 -1
- package/dist/src/adapters/state/__tests__/filesystem.test.d.ts +0 -7
- package/dist/src/adapters/state/__tests__/filesystem.test.d.ts.map +0 -1
- package/dist/src/adapters/state/__tests__/filesystem.test.js +0 -418
- package/dist/src/adapters/state/__tests__/filesystem.test.js.map +0 -1
- package/dist/src/adapters/state/api.d.ts +0 -148
- package/dist/src/adapters/state/api.d.ts.map +0 -1
- package/dist/src/adapters/state/api.js +0 -337
- package/dist/src/adapters/state/api.js.map +0 -1
- package/dist/src/adapters/state/filesystem.d.ts +0 -80
- package/dist/src/adapters/state/filesystem.d.ts.map +0 -1
- package/dist/src/adapters/state/filesystem.js +0 -228
- package/dist/src/adapters/state/filesystem.js.map +0 -1
- package/dist/src/adapters/state/index.d.ts +0 -9
- package/dist/src/adapters/state/index.d.ts.map +0 -1
- package/dist/src/adapters/state/index.js +0 -10
- package/dist/src/adapters/state/index.js.map +0 -1
- package/dist/src/adapters/state/types.d.ts +0 -131
- package/dist/src/adapters/state/types.d.ts.map +0 -1
- package/dist/src/adapters/state/types.js +0 -11
- package/dist/src/adapters/state/types.js.map +0 -1
- package/dist/src/core/__tests__/context.test.d.ts +0 -12
- package/dist/src/core/__tests__/context.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/context.test.js +0 -528
- package/dist/src/core/__tests__/context.test.js.map +0 -1
- package/dist/src/core/__tests__/discover.test.d.ts +0 -2
- package/dist/src/core/__tests__/discover.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/discover.test.js +0 -667
- package/dist/src/core/__tests__/discover.test.js.map +0 -1
- package/dist/src/core/__tests__/engine.test.d.ts +0 -2
- package/dist/src/core/__tests__/engine.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/engine.test.js +0 -444
- package/dist/src/core/__tests__/engine.test.js.map +0 -1
- package/dist/src/core/__tests__/feedback.test.d.ts +0 -2
- package/dist/src/core/__tests__/feedback.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/feedback.test.js +0 -351
- package/dist/src/core/__tests__/feedback.test.js.map +0 -1
- package/dist/src/core/__tests__/plan.test.d.ts +0 -2
- package/dist/src/core/__tests__/plan.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/plan.test.js +0 -429
- package/dist/src/core/__tests__/plan.test.js.map +0 -1
- package/dist/src/core/__tests__/schemas.test.d.ts +0 -2
- package/dist/src/core/__tests__/schemas.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/schemas.test.js +0 -614
- package/dist/src/core/__tests__/schemas.test.js.map +0 -1
- package/dist/src/core/__tests__/state.test.d.ts +0 -2
- package/dist/src/core/__tests__/state.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/state.test.js +0 -1107
- package/dist/src/core/__tests__/state.test.js.map +0 -1
- package/dist/src/core/__tests__/status.test.d.ts +0 -2
- package/dist/src/core/__tests__/status.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/status.test.js +0 -600
- package/dist/src/core/__tests__/status.test.js.map +0 -1
- package/dist/src/core/__tests__/test-helpers.d.ts +0 -28
- package/dist/src/core/__tests__/test-helpers.d.ts.map +0 -1
- package/dist/src/core/__tests__/test-helpers.js +0 -185
- package/dist/src/core/__tests__/test-helpers.js.map +0 -1
- package/dist/src/core/__tests__/utils.test.d.ts +0 -2
- package/dist/src/core/__tests__/utils.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/utils.test.js +0 -276
- package/dist/src/core/__tests__/utils.test.js.map +0 -1
- package/dist/src/core/__tests__/validate.test.d.ts +0 -2
- package/dist/src/core/__tests__/validate.test.d.ts.map +0 -1
- package/dist/src/core/__tests__/validate.test.js +0 -354
- package/dist/src/core/__tests__/validate.test.js.map +0 -1
- package/dist/src/core/commands/discover.d.ts +0 -71
- package/dist/src/core/commands/discover.d.ts.map +0 -1
- package/dist/src/core/commands/discover.js +0 -687
- package/dist/src/core/commands/discover.js.map +0 -1
- package/dist/src/core/commands/feedback.d.ts +0 -49
- package/dist/src/core/commands/feedback.d.ts.map +0 -1
- package/dist/src/core/commands/feedback.js +0 -283
- package/dist/src/core/commands/feedback.js.map +0 -1
- package/dist/src/core/commands/index.d.ts +0 -11
- package/dist/src/core/commands/index.d.ts.map +0 -1
- package/dist/src/core/commands/index.js +0 -11
- package/dist/src/core/commands/index.js.map +0 -1
- package/dist/src/core/commands/plan.d.ts +0 -108
- package/dist/src/core/commands/plan.d.ts.map +0 -1
- package/dist/src/core/commands/plan.js +0 -621
- package/dist/src/core/commands/plan.js.map +0 -1
- package/dist/src/core/commands/status.d.ts +0 -72
- package/dist/src/core/commands/status.d.ts.map +0 -1
- package/dist/src/core/commands/status.js +0 -720
- package/dist/src/core/commands/status.js.map +0 -1
- package/dist/src/core/commands/validate.d.ts +0 -47
- package/dist/src/core/commands/validate.d.ts.map +0 -1
- package/dist/src/core/commands/validate.js +0 -608
- package/dist/src/core/commands/validate.js.map +0 -1
- package/dist/src/core/engine.d.ts +0 -294
- package/dist/src/core/engine.d.ts.map +0 -1
- package/dist/src/core/engine.js +0 -219
- package/dist/src/core/engine.js.map +0 -1
- package/dist/src/core/index.d.ts +0 -14
- package/dist/src/core/index.d.ts.map +0 -1
- package/dist/src/core/index.js +0 -18
- package/dist/src/core/index.js.map +0 -1
- package/dist/src/core/prompts/context-helpers.d.ts +0 -48
- package/dist/src/core/prompts/context-helpers.d.ts.map +0 -1
- package/dist/src/core/prompts/context-helpers.js +0 -206
- package/dist/src/core/prompts/context-helpers.js.map +0 -1
- package/dist/src/core/prompts/discovery.d.ts +0 -11
- package/dist/src/core/prompts/discovery.d.ts.map +0 -1
- package/dist/src/core/prompts/discovery.js +0 -179
- package/dist/src/core/prompts/discovery.js.map +0 -1
- package/dist/src/core/prompts/feedback.d.ts +0 -38
- package/dist/src/core/prompts/feedback.d.ts.map +0 -1
- package/dist/src/core/prompts/feedback.js +0 -292
- package/dist/src/core/prompts/feedback.js.map +0 -1
- package/dist/src/core/prompts/index.d.ts +0 -12
- package/dist/src/core/prompts/index.d.ts.map +0 -1
- package/dist/src/core/prompts/index.js +0 -12
- package/dist/src/core/prompts/index.js.map +0 -1
- package/dist/src/core/prompts/planning.d.ts +0 -15
- package/dist/src/core/prompts/planning.d.ts.map +0 -1
- package/dist/src/core/prompts/planning.js +0 -293
- package/dist/src/core/prompts/planning.js.map +0 -1
- package/dist/src/core/prompts/status.d.ts +0 -41
- package/dist/src/core/prompts/status.d.ts.map +0 -1
- package/dist/src/core/prompts/status.js +0 -270
- package/dist/src/core/prompts/status.js.map +0 -1
- package/dist/src/core/prompts/validate.d.ts +0 -62
- package/dist/src/core/prompts/validate.d.ts.map +0 -1
- package/dist/src/core/prompts/validate.js +0 -302
- package/dist/src/core/prompts/validate.js.map +0 -1
- package/dist/src/core/schemas.d.ts +0 -5045
- package/dist/src/core/schemas.d.ts.map +0 -1
- package/dist/src/core/schemas.js +0 -492
- package/dist/src/core/schemas.js.map +0 -1
- package/dist/src/core/state.d.ts +0 -156
- package/dist/src/core/state.d.ts.map +0 -1
- package/dist/src/core/state.js +0 -608
- package/dist/src/core/state.js.map +0 -1
- package/dist/src/core/types.d.ts +0 -167
- package/dist/src/core/types.d.ts.map +0 -1
- package/dist/src/core/types.js +0 -102
- package/dist/src/core/types.js.map +0 -1
- package/dist/src/core/utils.d.ts +0 -39
- package/dist/src/core/utils.d.ts.map +0 -1
- package/dist/src/core/utils.js +0 -208
- package/dist/src/core/utils.js.map +0 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lisa",
|
|
3
|
+
"description": "Project planning with milestones, epics, and stories. Break down work, track progress, and implement with full context.",
|
|
4
|
+
"version": "0.1.7",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Rodrigo Klosowski",
|
|
7
|
+
"url": "https://rklosowski.com/"
|
|
8
|
+
}
|
|
9
|
+
}
|
package/README.md
CHANGED
|
@@ -16,10 +16,35 @@ Lisa is the smart one. She breaks down complex projects into **Milestones → Ep
|
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
19
|
+
### CLI Tool
|
|
20
|
+
|
|
19
21
|
```bash
|
|
20
22
|
npm install -g smartlisa
|
|
21
23
|
```
|
|
22
24
|
|
|
25
|
+
### Claude Code Skills
|
|
26
|
+
|
|
27
|
+
Lisa works as a Claude Code skill. Choose one installation method:
|
|
28
|
+
|
|
29
|
+
**Via Plugin (Recommended)**
|
|
30
|
+
```bash
|
|
31
|
+
/plugin install github:klosowsk/lisa
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**As Project Skills** (anyone cloning repo gets them)
|
|
35
|
+
```bash
|
|
36
|
+
# Copy to your project
|
|
37
|
+
cp -r path/to/lisa/skills/lisa your-project/.claude/skills/
|
|
38
|
+
cp -r path/to/lisa/skills/lisa-work your-project/.claude/skills/
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**As Personal Skills** (available in all your projects)
|
|
42
|
+
```bash
|
|
43
|
+
# Symlink to your personal skills directory
|
|
44
|
+
ln -s $(pwd)/skills/lisa ~/.claude/skills/lisa
|
|
45
|
+
ln -s $(pwd)/skills/lisa-work ~/.claude/skills/lisa-work
|
|
46
|
+
```
|
|
47
|
+
|
|
23
48
|
## Using with Claude Code
|
|
24
49
|
|
|
25
50
|
Lisa is a Claude Code skill. Just ask:
|
package/dist/cli.js
CHANGED
|
@@ -468,7 +468,6 @@ var LisaError = class extends Error {
|
|
|
468
468
|
this.name = "LisaError";
|
|
469
469
|
}
|
|
470
470
|
};
|
|
471
|
-
var RalphError = LisaError;
|
|
472
471
|
function generateId(prefix) {
|
|
473
472
|
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 6)}`;
|
|
474
473
|
}
|
|
@@ -582,7 +581,6 @@ import * as fs from "fs/promises";
|
|
|
582
581
|
import * as path from "path";
|
|
583
582
|
import YAML from "yaml";
|
|
584
583
|
var LISA_DIR = ".lisa";
|
|
585
|
-
var RALPH_DIR = LISA_DIR;
|
|
586
584
|
var FileSystemStateAdapter = class {
|
|
587
585
|
rootDir;
|
|
588
586
|
lisaDir;
|
|
@@ -842,7 +840,7 @@ var StateManager = class {
|
|
|
842
840
|
// Path Helpers
|
|
843
841
|
// --------------------------------------------------------------------------
|
|
844
842
|
getPath(relativePath) {
|
|
845
|
-
return path2.join(this.adapter.getRootDir(),
|
|
843
|
+
return path2.join(this.adapter.getRootDir(), LISA_DIR, relativePath);
|
|
846
844
|
}
|
|
847
845
|
getEpicDir(epicId, slug) {
|
|
848
846
|
return this.getPath(path2.join(PATHS.epics.dir, `${epicId}-${slug}`));
|
|
@@ -1130,7 +1128,7 @@ var StateManager = class {
|
|
|
1130
1128
|
async assembleProjectContext() {
|
|
1131
1129
|
const project = await this.readProject();
|
|
1132
1130
|
if (!project) {
|
|
1133
|
-
throw new
|
|
1131
|
+
throw new LisaError("Project not initialized", "NOT_INITIALIZED");
|
|
1134
1132
|
}
|
|
1135
1133
|
return {
|
|
1136
1134
|
project,
|
|
@@ -1148,7 +1146,7 @@ var StateManager = class {
|
|
|
1148
1146
|
const index = await this.readMilestoneIndex();
|
|
1149
1147
|
const milestone = index?.milestones.find((m) => m.id === milestoneId);
|
|
1150
1148
|
if (!milestone) {
|
|
1151
|
-
throw new
|
|
1149
|
+
throw new LisaError(`Milestone ${milestoneId} not found`, "NOT_FOUND");
|
|
1152
1150
|
}
|
|
1153
1151
|
const milestoneDiscovery = await this.readMilestoneDiscovery(milestoneId);
|
|
1154
1152
|
const siblingEpics = [];
|
|
@@ -1182,18 +1180,18 @@ var StateManager = class {
|
|
|
1182
1180
|
const epicDirs = await this.listEpicDirs();
|
|
1183
1181
|
const epicDir = epicDirs.find((d) => d.startsWith(`${epicId}-`));
|
|
1184
1182
|
if (!epicDir) {
|
|
1185
|
-
throw new
|
|
1183
|
+
throw new LisaError(`Epic ${epicId} not found`, "NOT_FOUND");
|
|
1186
1184
|
}
|
|
1187
1185
|
const slug = epicDir.split("-").slice(1).join("-");
|
|
1188
1186
|
const epic = await this.readEpic(epicId, slug);
|
|
1189
1187
|
if (!epic) {
|
|
1190
|
-
throw new
|
|
1188
|
+
throw new LisaError(`Epic ${epicId} not found`, "NOT_FOUND");
|
|
1191
1189
|
}
|
|
1192
1190
|
const projectContext = await this.assembleProjectContext();
|
|
1193
1191
|
const index = await this.readMilestoneIndex();
|
|
1194
1192
|
const milestone = index?.milestones.find((m) => m.id === epic.milestone);
|
|
1195
1193
|
if (!milestone) {
|
|
1196
|
-
throw new
|
|
1194
|
+
throw new LisaError(`Milestone ${epic.milestone} not found`, "NOT_FOUND");
|
|
1197
1195
|
}
|
|
1198
1196
|
const milestoneDiscovery = await this.readMilestoneDiscovery(epic.milestone);
|
|
1199
1197
|
const epicDiscovery = await this.readEpicDiscovery(epicId, slug);
|
|
@@ -1232,19 +1230,19 @@ var StateManager = class {
|
|
|
1232
1230
|
const epicDirs = await this.listEpicDirs();
|
|
1233
1231
|
const epicDir = epicDirs.find((d) => d.startsWith(`${epicId}-`));
|
|
1234
1232
|
if (!epicDir) {
|
|
1235
|
-
throw new
|
|
1233
|
+
throw new LisaError(`Epic ${epicId} not found`, "NOT_FOUND");
|
|
1236
1234
|
}
|
|
1237
1235
|
const slug = epicDir.split("-").slice(1).join("-");
|
|
1238
1236
|
const prd = await this.readPrd(epicId, slug);
|
|
1239
1237
|
if (!prd) {
|
|
1240
|
-
throw new
|
|
1238
|
+
throw new LisaError(
|
|
1241
1239
|
`PRD not found for ${epicId}. Generate PRD first.`,
|
|
1242
1240
|
"MISSING_PRD"
|
|
1243
1241
|
);
|
|
1244
1242
|
}
|
|
1245
1243
|
const architecture = await this.readArchitecture(epicId, slug);
|
|
1246
1244
|
if (!architecture) {
|
|
1247
|
-
throw new
|
|
1245
|
+
throw new LisaError(
|
|
1248
1246
|
`Architecture not found for ${epicId}. Generate architecture first.`,
|
|
1249
1247
|
"MISSING_ARCH"
|
|
1250
1248
|
);
|
|
@@ -1746,7 +1744,7 @@ function getHowGuidance(storyId, hasArchitecture) {
|
|
|
1746
1744
|
// src/core/commands/status.ts
|
|
1747
1745
|
async function overview(state) {
|
|
1748
1746
|
if (!await state.isInitialized()) {
|
|
1749
|
-
return error("No
|
|
1747
|
+
return error("No Lisa project found. Run 'discover init' first.", "NOT_INITIALIZED");
|
|
1750
1748
|
}
|
|
1751
1749
|
const project = await state.readProject();
|
|
1752
1750
|
const index = await state.readMilestoneIndex();
|
|
@@ -1820,7 +1818,7 @@ async function overview(state) {
|
|
|
1820
1818
|
}
|
|
1821
1819
|
};
|
|
1822
1820
|
const sections = [
|
|
1823
|
-
section.header("
|
|
1821
|
+
section.header("Lisa Status"),
|
|
1824
1822
|
section.subheader(`Project: ${project.name}`),
|
|
1825
1823
|
section.dim(` Status: ${project.status}`),
|
|
1826
1824
|
section.dim(` Updated: ${timeAgo(project.updated)}`)
|
|
@@ -1902,7 +1900,7 @@ async function overview(state) {
|
|
|
1902
1900
|
}
|
|
1903
1901
|
async function board(state, options = {}) {
|
|
1904
1902
|
if (!await state.isInitialized()) {
|
|
1905
|
-
return error("No
|
|
1903
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
1906
1904
|
}
|
|
1907
1905
|
const allStories = [];
|
|
1908
1906
|
const epicDirs = await state.listEpicDirs();
|
|
@@ -1935,7 +1933,7 @@ async function board(state, options = {}) {
|
|
|
1935
1933
|
blocked: columns.blocked,
|
|
1936
1934
|
deferred: columns.deferred
|
|
1937
1935
|
};
|
|
1938
|
-
const sections = [section.header("
|
|
1936
|
+
const sections = [section.header("Lisa Board")];
|
|
1939
1937
|
if (allStories.length === 0) {
|
|
1940
1938
|
sections.push(section.info("No stories found."));
|
|
1941
1939
|
return success(data, sections);
|
|
@@ -2068,7 +2066,7 @@ async function story(state, options) {
|
|
|
2068
2066
|
}
|
|
2069
2067
|
async function context(state, options = {}) {
|
|
2070
2068
|
if (!await state.isInitialized()) {
|
|
2071
|
-
return error("No
|
|
2069
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
2072
2070
|
}
|
|
2073
2071
|
const { target, full, format } = options;
|
|
2074
2072
|
if (!target) {
|
|
@@ -2780,8 +2778,8 @@ async function init(state, options) {
|
|
|
2780
2778
|
const projectName = options.name || "Untitled Project";
|
|
2781
2779
|
const project = await state.initialize(projectName);
|
|
2782
2780
|
const sections = [
|
|
2783
|
-
section.header("Initializing
|
|
2784
|
-
section.success(`Created .
|
|
2781
|
+
section.header("Initializing Lisa"),
|
|
2782
|
+
section.success(`Created .lisa/ directory`),
|
|
2785
2783
|
section.success(`Project: ${project.name}`),
|
|
2786
2784
|
section.success(`ID: ${project.id}`),
|
|
2787
2785
|
section.blank(),
|
|
@@ -2806,7 +2804,7 @@ async function init(state, options) {
|
|
|
2806
2804
|
}
|
|
2807
2805
|
async function status(state) {
|
|
2808
2806
|
if (!await state.isInitialized()) {
|
|
2809
|
-
return error("No
|
|
2807
|
+
return error("No Lisa project found. Run 'discover init' first.", "NOT_INITIALIZED");
|
|
2810
2808
|
}
|
|
2811
2809
|
const context2 = await state.readDiscoveryContext();
|
|
2812
2810
|
const constraints = await state.readConstraints();
|
|
@@ -2874,7 +2872,7 @@ async function status(state) {
|
|
|
2874
2872
|
}
|
|
2875
2873
|
async function start(state, options = {}) {
|
|
2876
2874
|
if (!await state.isInitialized()) {
|
|
2877
|
-
return error("No
|
|
2875
|
+
return error("No Lisa project found. Run 'discover init' first.", "NOT_INITIALIZED");
|
|
2878
2876
|
}
|
|
2879
2877
|
const history = await state.readDiscoveryHistory();
|
|
2880
2878
|
const context2 = await state.readDiscoveryContext();
|
|
@@ -2956,7 +2954,7 @@ async function start(state, options = {}) {
|
|
|
2956
2954
|
}
|
|
2957
2955
|
async function addEntry(state, options) {
|
|
2958
2956
|
if (!await state.isInitialized()) {
|
|
2959
|
-
return error("No
|
|
2957
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
2960
2958
|
}
|
|
2961
2959
|
let history = await state.readDiscoveryHistory();
|
|
2962
2960
|
if (!history) {
|
|
@@ -2982,7 +2980,7 @@ async function addEntry(state, options) {
|
|
|
2982
2980
|
}
|
|
2983
2981
|
async function complete(state) {
|
|
2984
2982
|
if (!await state.isInitialized()) {
|
|
2985
|
-
return error("No
|
|
2983
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
2986
2984
|
}
|
|
2987
2985
|
const history = await state.readDiscoveryHistory();
|
|
2988
2986
|
if (!history) {
|
|
@@ -3041,7 +3039,7 @@ async function findMilestoneById(state, milestoneId) {
|
|
|
3041
3039
|
}
|
|
3042
3040
|
async function element(state, options) {
|
|
3043
3041
|
if (!await state.isInitialized()) {
|
|
3044
|
-
return error("No
|
|
3042
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
3045
3043
|
}
|
|
3046
3044
|
const { elementType, elementId } = options;
|
|
3047
3045
|
if (elementType === "epic") {
|
|
@@ -3099,7 +3097,7 @@ async function element(state, options) {
|
|
|
3099
3097
|
}
|
|
3100
3098
|
async function addElementEntry(state, options) {
|
|
3101
3099
|
if (!await state.isInitialized()) {
|
|
3102
|
-
return error("No
|
|
3100
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
3103
3101
|
}
|
|
3104
3102
|
const entry = {
|
|
3105
3103
|
timestamp: now(),
|
|
@@ -3157,7 +3155,7 @@ function updateElementDiscoveryFromEntry(discovery, entry, question) {
|
|
|
3157
3155
|
}
|
|
3158
3156
|
async function completeElement(state, options) {
|
|
3159
3157
|
if (!await state.isInitialized()) {
|
|
3160
|
-
return error("No
|
|
3158
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
3161
3159
|
}
|
|
3162
3160
|
if (options.elementType === "epic") {
|
|
3163
3161
|
const epicInfo = await findEpicByIdOrSlug(state, options.elementId);
|
|
@@ -3461,7 +3459,7 @@ function getStoriesGuidance(ctx) {
|
|
|
3461
3459
|
// src/core/commands/plan.ts
|
|
3462
3460
|
async function showMilestones(state) {
|
|
3463
3461
|
if (!await state.isInitialized()) {
|
|
3464
|
-
return error("No
|
|
3462
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
3465
3463
|
}
|
|
3466
3464
|
const index = await state.readMilestoneIndex();
|
|
3467
3465
|
const context2 = await state.readDiscoveryContext();
|
|
@@ -3531,7 +3529,7 @@ async function showMilestones(state) {
|
|
|
3531
3529
|
}
|
|
3532
3530
|
async function addMilestone(state, options) {
|
|
3533
3531
|
if (!await state.isInitialized()) {
|
|
3534
|
-
return error("No
|
|
3532
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
3535
3533
|
}
|
|
3536
3534
|
let index = await state.readMilestoneIndex();
|
|
3537
3535
|
if (!index) {
|
|
@@ -3557,7 +3555,7 @@ async function addMilestone(state, options) {
|
|
|
3557
3555
|
}
|
|
3558
3556
|
async function showEpics(state, options = {}) {
|
|
3559
3557
|
if (!await state.isInitialized()) {
|
|
3560
|
-
return error("No
|
|
3558
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
3561
3559
|
}
|
|
3562
3560
|
const index = await state.readMilestoneIndex();
|
|
3563
3561
|
if (!index?.milestones || index.milestones.length === 0) {
|
|
@@ -3661,7 +3659,7 @@ async function showEpics(state, options = {}) {
|
|
|
3661
3659
|
}
|
|
3662
3660
|
async function addEpic(state, options) {
|
|
3663
3661
|
if (!await state.isInitialized()) {
|
|
3664
|
-
return error("No
|
|
3662
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
3665
3663
|
}
|
|
3666
3664
|
const index = await state.readMilestoneIndex();
|
|
3667
3665
|
if (!index) {
|
|
@@ -3737,7 +3735,7 @@ async function addEpic(state, options) {
|
|
|
3737
3735
|
}
|
|
3738
3736
|
async function planEpic(state, options) {
|
|
3739
3737
|
if (!await state.isInitialized()) {
|
|
3740
|
-
return error("No
|
|
3738
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
3741
3739
|
}
|
|
3742
3740
|
const ctx = await state.assembleEpicContext(options.epicId);
|
|
3743
3741
|
const epicDirs = await state.listEpicDirs();
|
|
@@ -4331,7 +4329,7 @@ function getDismissFeedbackGuidance(feedbackId) {
|
|
|
4331
4329
|
// src/core/commands/feedback.ts
|
|
4332
4330
|
async function markStory(state, options) {
|
|
4333
4331
|
if (!await state.isInitialized()) {
|
|
4334
|
-
return error("No
|
|
4332
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
4335
4333
|
}
|
|
4336
4334
|
const parsed = parseStoryId(options.storyId);
|
|
4337
4335
|
if (!parsed) {
|
|
@@ -4399,7 +4397,7 @@ async function markStory(state, options) {
|
|
|
4399
4397
|
}
|
|
4400
4398
|
async function addFeedback(state, options) {
|
|
4401
4399
|
if (!await state.isInitialized()) {
|
|
4402
|
-
return error("No
|
|
4400
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
4403
4401
|
}
|
|
4404
4402
|
const parsed = parseStoryId(options.storyId);
|
|
4405
4403
|
if (!parsed) {
|
|
@@ -4450,7 +4448,7 @@ async function addFeedback(state, options) {
|
|
|
4450
4448
|
}
|
|
4451
4449
|
async function listFeedback(state) {
|
|
4452
4450
|
if (!await state.isInitialized()) {
|
|
4453
|
-
return error("No
|
|
4451
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
4454
4452
|
}
|
|
4455
4453
|
const feedbackQueue = await state.readFeedbackQueue();
|
|
4456
4454
|
const stuckQueue = await state.readStuckQueue();
|
|
@@ -4516,7 +4514,7 @@ async function listFeedback(state) {
|
|
|
4516
4514
|
}
|
|
4517
4515
|
async function resolveFeedback(state, options) {
|
|
4518
4516
|
if (!await state.isInitialized()) {
|
|
4519
|
-
return error("No
|
|
4517
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
4520
4518
|
}
|
|
4521
4519
|
const feedbackQueue = await state.readFeedbackQueue();
|
|
4522
4520
|
if (!feedbackQueue) {
|
|
@@ -4558,7 +4556,7 @@ async function resolveFeedback(state, options) {
|
|
|
4558
4556
|
}
|
|
4559
4557
|
async function dismissFeedback(state, options) {
|
|
4560
4558
|
if (!await state.isInitialized()) {
|
|
4561
|
-
return error("No
|
|
4559
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
4562
4560
|
}
|
|
4563
4561
|
const feedbackQueue = await state.readFeedbackQueue();
|
|
4564
4562
|
if (!feedbackQueue) {
|
|
@@ -5032,7 +5030,7 @@ async function validateCoverageInternal(state) {
|
|
|
5032
5030
|
}
|
|
5033
5031
|
async function runFullValidation(state) {
|
|
5034
5032
|
if (!await state.isInitialized()) {
|
|
5035
|
-
return error("No
|
|
5033
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
5036
5034
|
}
|
|
5037
5035
|
const issues = [];
|
|
5038
5036
|
const sections = [section.header("Validation")];
|
|
@@ -5159,7 +5157,7 @@ async function runFullValidation(state) {
|
|
|
5159
5157
|
}
|
|
5160
5158
|
async function validateLinks(state) {
|
|
5161
5159
|
if (!await state.isInitialized()) {
|
|
5162
|
-
return error("No
|
|
5160
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
5163
5161
|
}
|
|
5164
5162
|
const linksResult = await validateLinksInternal(state);
|
|
5165
5163
|
await state.writeLinks(linksResult);
|
|
@@ -5195,7 +5193,7 @@ async function validateLinks(state) {
|
|
|
5195
5193
|
}
|
|
5196
5194
|
async function validateCoverage(state) {
|
|
5197
5195
|
if (!await state.isInitialized()) {
|
|
5198
|
-
return error("No
|
|
5196
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
5199
5197
|
}
|
|
5200
5198
|
const coverageResult = await validateCoverageInternal(state);
|
|
5201
5199
|
await state.writeCoverage(coverageResult);
|
|
@@ -5257,7 +5255,7 @@ async function validateCoverage(state) {
|
|
|
5257
5255
|
}
|
|
5258
5256
|
async function validateEpic(state, options) {
|
|
5259
5257
|
if (!await state.isInitialized()) {
|
|
5260
|
-
return error("No
|
|
5258
|
+
return error("No Lisa project found.", "NOT_INITIALIZED");
|
|
5261
5259
|
}
|
|
5262
5260
|
const epicDirs = await state.listEpicDirs();
|
|
5263
5261
|
const epicDir = epicDirs.find((d) => d.startsWith(`${options.epicId}-`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smartlisa",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "AI-powered planning system for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,9 +38,11 @@
|
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
40
|
"dist",
|
|
41
|
-
".claude"
|
|
41
|
+
".claude-plugin",
|
|
42
|
+
"skills"
|
|
42
43
|
],
|
|
43
44
|
"scripts": {
|
|
45
|
+
"init:claude": "node scripts/init-claude.js",
|
|
44
46
|
"lisa": "tsx src/adapters/cli/index.ts",
|
|
45
47
|
"build": "node esbuild.config.js",
|
|
46
48
|
"build:watch": "node esbuild.config.js --watch",
|
|
@@ -53,7 +55,10 @@
|
|
|
53
55
|
"test": "vitest run",
|
|
54
56
|
"test:watch": "vitest",
|
|
55
57
|
"test:coverage": "vitest run --coverage",
|
|
56
|
-
"ci": "npm run typecheck && npm run lint && npm run test"
|
|
58
|
+
"ci": "npm run typecheck && npm run lint && npm run test",
|
|
59
|
+
"version:patch": "node scripts/bump-version.js patch",
|
|
60
|
+
"version:minor": "node scripts/bump-version.js minor",
|
|
61
|
+
"version:major": "node scripts/bump-version.js major"
|
|
57
62
|
},
|
|
58
63
|
"dependencies": {
|
|
59
64
|
"chalk": "^5.3.0",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lisa
|
|
3
|
+
description: Plan and organize projects into milestones, epics, and stories. Use when breaking down work, creating roadmaps, planning features, asking "what should I work on?", "lisa status", "show me the board", organizing a project, or when user wants to scope and structure development work. Also triggers on "help me plan", "break this down", "create a roadmap", or "add milestone/epic/story".
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Lisa - Planning Mode
|
|
8
|
+
|
|
9
|
+
Plan and organize projects into milestones, epics, and stories.
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Check project status
|
|
15
|
+
lisa status
|
|
16
|
+
|
|
17
|
+
# Start a new project
|
|
18
|
+
lisa discover init "Project Name"
|
|
19
|
+
|
|
20
|
+
# View the board
|
|
21
|
+
lisa status board
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
### New Project
|
|
27
|
+
|
|
28
|
+
1. **Ask for project name** - Confirm what they're building
|
|
29
|
+
2. **Initialize**: `lisa discover init "Project Name"`
|
|
30
|
+
3. **Check for existing code** - Read key files to understand patterns
|
|
31
|
+
4. **Discovery conversation** - Natural Q&A about problem, vision, constraints
|
|
32
|
+
- For brownfield: suggest answers based on what you read
|
|
33
|
+
|
|
34
|
+
### Existing Project
|
|
35
|
+
|
|
36
|
+
1. **Check status**: `lisa status`
|
|
37
|
+
2. **View board**: `lisa status board`
|
|
38
|
+
3. **Add to plan** or **work on stories** as needed
|
|
39
|
+
|
|
40
|
+
## Commands Reference
|
|
41
|
+
|
|
42
|
+
| Action | Command |
|
|
43
|
+
|--------|---------|
|
|
44
|
+
| Project overview | `lisa status` |
|
|
45
|
+
| Kanban board | `lisa status board` |
|
|
46
|
+
| Story details | `lisa status show <id>` |
|
|
47
|
+
| Start discovery | `lisa discover init "Name"` |
|
|
48
|
+
| Continue discovery | `lisa discover` |
|
|
49
|
+
| View milestones | `lisa plan milestones` |
|
|
50
|
+
| Add milestone | `lisa plan add-milestone --name 'Name' --description 'Desc'` |
|
|
51
|
+
| Add epic | `lisa plan add-epic --milestone M1 --name 'Name' --description 'Desc'` |
|
|
52
|
+
| Generate stories | `lisa plan stories E1` |
|
|
53
|
+
| Mark progress | `lisa feedback mark <id> <status>` |
|
|
54
|
+
| Validate plan | `lisa validate` |
|
|
55
|
+
|
|
56
|
+
## ID Formats
|
|
57
|
+
|
|
58
|
+
| Type | Format | Example |
|
|
59
|
+
|------|--------|---------|
|
|
60
|
+
| Milestone | `M#` | `M1` |
|
|
61
|
+
| Epic | `E#` | `E1` |
|
|
62
|
+
| Story | `E#.S#` | `E1.S2` |
|
|
63
|
+
|
|
64
|
+
## References
|
|
65
|
+
|
|
66
|
+
- [commands.md](references/commands.md) - Full command reference
|
|
67
|
+
- [examples.md](references/examples.md) - Workflow examples
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Lisa Command Reference
|
|
2
|
+
|
|
3
|
+
Complete reference for all Lisa CLI commands. Use `--help` with any command for quick help.
|
|
4
|
+
|
|
5
|
+
## Discovery Commands
|
|
6
|
+
|
|
7
|
+
Gather project context through guided discovery sessions.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
lisa discover [subcommand] [options]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
| Subcommand | Description |
|
|
14
|
+
|------------|-------------|
|
|
15
|
+
| *(none)* | Start or continue discovery session |
|
|
16
|
+
| `init <name>` | Initialize new project |
|
|
17
|
+
| `status` | Show discovery progress and gaps |
|
|
18
|
+
| `complete` | Mark discovery phase complete |
|
|
19
|
+
| `add-entry` | Add discovery entry manually |
|
|
20
|
+
| `epic <id>` | Start discovery for specific epic |
|
|
21
|
+
| `milestone <id>` | Start discovery for milestone |
|
|
22
|
+
|
|
23
|
+
### Discovery Options
|
|
24
|
+
|
|
25
|
+
| Option | Description |
|
|
26
|
+
|--------|-------------|
|
|
27
|
+
| `--quick` | Essentials only (problem, vision, success) |
|
|
28
|
+
| `--standard` | Balanced depth (default) |
|
|
29
|
+
| `--deep` | Comprehensive discovery |
|
|
30
|
+
|
|
31
|
+
### Add Entry Options
|
|
32
|
+
|
|
33
|
+
| Option | Description |
|
|
34
|
+
|--------|-------------|
|
|
35
|
+
| `--category <cat>` | Category: `problem`, `goals`, `users`, `constraints`, `scope`, `technical`, `risks`, `success` |
|
|
36
|
+
| `--question '<q>'` | The discovery question |
|
|
37
|
+
| `--answer '<a>'` | The answer/information |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Plan Commands
|
|
42
|
+
|
|
43
|
+
Create and manage roadmap artifacts.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
lisa plan [subcommand] [options]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
| Subcommand | Description |
|
|
50
|
+
|------------|-------------|
|
|
51
|
+
| *(none)* | Show milestones |
|
|
52
|
+
| `milestones` | List all milestones |
|
|
53
|
+
| `add-milestone` | Add new milestone |
|
|
54
|
+
| `epics [M1]` | List epics (optionally filter by milestone) |
|
|
55
|
+
| `add-epic` | Add new epic to milestone |
|
|
56
|
+
| `epic <id>` | View/plan specific epic |
|
|
57
|
+
| `stories <id>` | List stories for epic |
|
|
58
|
+
|
|
59
|
+
### Add Milestone Options
|
|
60
|
+
|
|
61
|
+
| Option | Description |
|
|
62
|
+
|--------|-------------|
|
|
63
|
+
| `--name '<name>'` | Milestone name (required) |
|
|
64
|
+
| `--description '<desc>'` | Milestone description (required) |
|
|
65
|
+
|
|
66
|
+
### Add Epic Options
|
|
67
|
+
|
|
68
|
+
| Option | Description |
|
|
69
|
+
|--------|-------------|
|
|
70
|
+
| `--milestone <M1>` | Parent milestone ID (required) |
|
|
71
|
+
| `--name '<name>'` | Epic name (required) |
|
|
72
|
+
| `--description '<desc>'` | Epic description (required) |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Status Commands
|
|
77
|
+
|
|
78
|
+
View project state and story details.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
lisa status [subcommand] [options]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
| Subcommand | Description |
|
|
85
|
+
|------------|-------------|
|
|
86
|
+
| *(none)* | Project overview with phase and progress |
|
|
87
|
+
| `board [epic]` | Kanban board (optionally filter by epic) |
|
|
88
|
+
| `show <id>` | Detailed story information |
|
|
89
|
+
| `context [target]` | Context for project, milestone, epic, or story |
|
|
90
|
+
| `why <id>` | Explain story lineage (trace requirements) |
|
|
91
|
+
| `how <id>` | Implementation guidance |
|
|
92
|
+
|
|
93
|
+
### Status Options
|
|
94
|
+
|
|
95
|
+
| Option | Description |
|
|
96
|
+
|--------|-------------|
|
|
97
|
+
| `--full` | Full output without truncation |
|
|
98
|
+
| `--format json` | Output in JSON format |
|
|
99
|
+
|
|
100
|
+
### ID Formats
|
|
101
|
+
|
|
102
|
+
| Format | Example | Description |
|
|
103
|
+
|--------|---------|-------------|
|
|
104
|
+
| Milestone | `M1` | Milestone 1 |
|
|
105
|
+
| Epic | `E1` | Epic 1 |
|
|
106
|
+
| Story | `E1.S2` | Epic 1, Story 2 |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Feedback Commands
|
|
111
|
+
|
|
112
|
+
Track progress and manage feedback items.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
lisa feedback [subcommand] [options]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
| Subcommand | Description |
|
|
119
|
+
|------------|-------------|
|
|
120
|
+
| *(none)* | List all pending feedback items |
|
|
121
|
+
| `mark <id> <status>` | Update story status |
|
|
122
|
+
| `add <id>` | Add feedback to story |
|
|
123
|
+
| `resolve <fb-id>` | Mark feedback as resolved |
|
|
124
|
+
| `dismiss <fb-id>` | Dismiss feedback without action |
|
|
125
|
+
|
|
126
|
+
### Story Statuses
|
|
127
|
+
|
|
128
|
+
| Status | Description |
|
|
129
|
+
|--------|-------------|
|
|
130
|
+
| `todo` | Not started |
|
|
131
|
+
| `assigned` | Assigned to someone |
|
|
132
|
+
| `in_progress` | Work in progress |
|
|
133
|
+
| `review` | In review |
|
|
134
|
+
| `done` | Completed |
|
|
135
|
+
| `blocked` | Blocked by dependency/issue |
|
|
136
|
+
| `deferred` | Postponed to later |
|
|
137
|
+
|
|
138
|
+
### Feedback Types
|
|
139
|
+
|
|
140
|
+
| Type | Description |
|
|
141
|
+
|------|-------------|
|
|
142
|
+
| `blocker` | Something blocking progress |
|
|
143
|
+
| `gap` | Missing information or requirement |
|
|
144
|
+
| `scope` | Scope change or clarification needed |
|
|
145
|
+
| `conflict` | Conflicting requirements |
|
|
146
|
+
| `question` | Question needing answer |
|
|
147
|
+
|
|
148
|
+
### Feedback Options
|
|
149
|
+
|
|
150
|
+
| Option | Description |
|
|
151
|
+
|--------|-------------|
|
|
152
|
+
| `--reason '<text>'` | Reason for status change (mark) |
|
|
153
|
+
| `--type <type>` | Feedback type (add) |
|
|
154
|
+
| `--message '<text>'` | Feedback message (add) |
|
|
155
|
+
| `--resolution '<text>'` | Resolution note (resolve) |
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Validate Commands
|
|
160
|
+
|
|
161
|
+
Check plan integrity and coverage.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
lisa validate [subcommand]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
| Subcommand | Description |
|
|
168
|
+
|------------|-------------|
|
|
169
|
+
| *(none)* | Run full validation suite |
|
|
170
|
+
| `links` | Check all cross-references |
|
|
171
|
+
| `coverage` | Check requirement coverage |
|
|
172
|
+
| `epic <id>` | Validate specific epic |
|
|
173
|
+
|
|
174
|
+
### What Gets Validated
|
|
175
|
+
|
|
176
|
+
- All story IDs reference valid epics
|
|
177
|
+
- All epic IDs reference valid milestones
|
|
178
|
+
- No orphaned or dangling references
|
|
179
|
+
- Requirements have implementing stories
|
|
180
|
+
- Stories have acceptance criteria
|
|
181
|
+
- Epic scope is complete and consistent
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Global Options
|
|
186
|
+
|
|
187
|
+
Available on all commands:
|
|
188
|
+
|
|
189
|
+
| Option | Description |
|
|
190
|
+
|--------|-------------|
|
|
191
|
+
| `--help`, `-h` | Show help for command |
|
|
192
|
+
| `--full` | Show full output without truncation |
|
|
193
|
+
| `--format json` | Output in JSON format |
|
|
194
|
+
|
|
195
|
+
## Examples
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
lisa status --help
|
|
199
|
+
lisa discover --deep
|
|
200
|
+
lisa feedback mark E1.S2 done
|
|
201
|
+
```
|