@wkronmiller/lisa 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/LICENSE +21 -0
- package/README.md +407 -0
- package/bin/lisa-runtime.js +8797 -0
- package/bin/lisa.js +21 -0
- package/completion.ts +58 -0
- package/install.ps1 +51 -0
- package/install.sh +93 -0
- package/lisa.ts +6 -0
- package/package.json +66 -0
- package/skills/README.md +28 -0
- package/skills/claude-code/CLAUDE.md +151 -0
- package/skills/codex/AGENTS.md +151 -0
- package/skills/gemini/GEMINI.md +151 -0
- package/skills/opencode/AGENTS.md +152 -0
- package/src/cli.ts +85 -0
- package/src/harness/base-adapter.ts +47 -0
- package/src/harness/claude-code.ts +106 -0
- package/src/harness/codex.ts +80 -0
- package/src/harness/command.ts +173 -0
- package/src/harness/gemini.ts +74 -0
- package/src/harness/opencode.ts +84 -0
- package/src/harness/registry.ts +29 -0
- package/src/harness/runner.ts +19 -0
- package/src/harness/types.ts +73 -0
- package/src/output-mode.ts +32 -0
- package/src/skill/artifacts.ts +174 -0
- package/src/skill/cli.ts +29 -0
- package/src/skill/install.ts +317 -0
- package/src/spec/agent-guidance.ts +466 -0
- package/src/spec/cli.ts +151 -0
- package/src/spec/commands/check.ts +1 -0
- package/src/spec/commands/config.ts +146 -0
- package/src/spec/commands/diff.ts +1 -0
- package/src/spec/commands/generate.ts +1 -0
- package/src/spec/commands/guide.ts +1 -0
- package/src/spec/commands/harness-list.ts +36 -0
- package/src/spec/commands/implement.ts +1 -0
- package/src/spec/commands/import.ts +1 -0
- package/src/spec/commands/init.ts +1 -0
- package/src/spec/commands/status.ts +87 -0
- package/src/spec/config.ts +63 -0
- package/src/spec/diff.ts +791 -0
- package/src/spec/extensions/benchmark.ts +347 -0
- package/src/spec/extensions/registry.ts +59 -0
- package/src/spec/extensions/types.ts +56 -0
- package/src/spec/grammar/index.ts +14 -0
- package/src/spec/grammar/parser.ts +443 -0
- package/src/spec/grammar/types.ts +70 -0
- package/src/spec/grammar/validator.ts +104 -0
- package/src/spec/loader.ts +174 -0
- package/src/spec/local-config.ts +59 -0
- package/src/spec/parser.ts +226 -0
- package/src/spec/path-utils.ts +73 -0
- package/src/spec/planner.ts +299 -0
- package/src/spec/prompt-renderer.ts +318 -0
- package/src/spec/skill-content.ts +119 -0
- package/src/spec/types.ts +239 -0
- package/src/spec/validator.ts +443 -0
- package/src/spec/workflows/check.ts +1534 -0
- package/src/spec/workflows/diff.ts +209 -0
- package/src/spec/workflows/generate.ts +1270 -0
- package/src/spec/workflows/guide.ts +190 -0
- package/src/spec/workflows/implement.ts +797 -0
- package/src/spec/workflows/import.ts +986 -0
- package/src/spec/workflows/init.ts +548 -0
- package/src/spec/workflows/status.ts +22 -0
- package/src/spec/workspace.ts +541 -0
- package/uninstall.ps1 +21 -0
- package/uninstall.sh +22 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic Lisa skill content for repos that use Lisa.
|
|
3
|
+
* This is NOT the Lisa-repo-specific skill - it's what gets written
|
|
4
|
+
* into any repo that runs `lisa spec init`.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const LISA_SKILL_FRONTMATTER = `---
|
|
8
|
+
name: lisa
|
|
9
|
+
description: Spec-driven development workflow using Lisa. Use this skill when working with specs, implementing features, or verifying code against specs in this repo.
|
|
10
|
+
---`;
|
|
11
|
+
|
|
12
|
+
export const LISA_SKILL_BODY = `# Lisa
|
|
13
|
+
|
|
14
|
+
This project uses Lisa for spec-driven development. Specs in .specs/ are the source of truth for intended behavior.
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
\`\`\`text
|
|
19
|
+
specs -> git diff -> structured deltas -> plan -> implementation -> tests/benchmarks -> verification -> reports
|
|
20
|
+
\`\`\`
|
|
21
|
+
|
|
22
|
+
Typical loop:
|
|
23
|
+
|
|
24
|
+
1. Write or update a spec under .specs/backend/ or .specs/frontend/.
|
|
25
|
+
2. Run \`lisa spec diff\` to see what changed and the derived plan.
|
|
26
|
+
3. Run \`lisa spec implement\` to apply code and test changes.
|
|
27
|
+
4. Run \`lisa spec check --changed\` to verify conformance.
|
|
28
|
+
|
|
29
|
+
## Commands
|
|
30
|
+
|
|
31
|
+
\`\`\`text
|
|
32
|
+
lisa spec init Scaffold a .specs workspace
|
|
33
|
+
lisa spec status Show workspace and harness status
|
|
34
|
+
lisa spec config --harness <id> Set local harness override
|
|
35
|
+
lisa spec guide [backend|frontend] [name] Create a seed spec with guided next steps
|
|
36
|
+
lisa spec generate [backend|frontend] [name] Draft a spec with preview and approval
|
|
37
|
+
lisa spec diff Show changed spec deltas and plan
|
|
38
|
+
lisa spec implement Implement code changes from spec deltas
|
|
39
|
+
lisa spec check --changed Verify only changed specs
|
|
40
|
+
lisa spec check --all Verify all active specs
|
|
41
|
+
lisa spec import <path...> Draft specs from existing code
|
|
42
|
+
\`\`\`
|
|
43
|
+
|
|
44
|
+
## Spec layout
|
|
45
|
+
|
|
46
|
+
\`\`\`text
|
|
47
|
+
.specs/
|
|
48
|
+
backend/
|
|
49
|
+
<spec-name>.md
|
|
50
|
+
<spec-name>.bench.<environment>.md
|
|
51
|
+
frontend/
|
|
52
|
+
<spec-name>.md
|
|
53
|
+
environments/
|
|
54
|
+
<environment>.yaml
|
|
55
|
+
config.yaml
|
|
56
|
+
config.local.yaml (gitignored, local harness override)
|
|
57
|
+
\`\`\`
|
|
58
|
+
|
|
59
|
+
## Spec format
|
|
60
|
+
|
|
61
|
+
Active base specs are markdown with YAML frontmatter:
|
|
62
|
+
|
|
63
|
+
\`\`\`md
|
|
64
|
+
---
|
|
65
|
+
id: backend.example
|
|
66
|
+
status: active
|
|
67
|
+
code_paths:
|
|
68
|
+
- src/example/**
|
|
69
|
+
test_paths:
|
|
70
|
+
- tests/example/**
|
|
71
|
+
test_commands:
|
|
72
|
+
- npm test -- example
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
# Summary
|
|
76
|
+
What this feature does.
|
|
77
|
+
|
|
78
|
+
## Use Cases
|
|
79
|
+
- Primary user or system flows.
|
|
80
|
+
|
|
81
|
+
## Invariants
|
|
82
|
+
- Behavior that must always remain true.
|
|
83
|
+
|
|
84
|
+
## Failure Modes
|
|
85
|
+
- Edge cases and error handling.
|
|
86
|
+
|
|
87
|
+
## Acceptance Criteria
|
|
88
|
+
- Observable outcomes that prove the behavior works.
|
|
89
|
+
|
|
90
|
+
## Out of Scope
|
|
91
|
+
- What this spec does not cover.
|
|
92
|
+
\`\`\`
|
|
93
|
+
|
|
94
|
+
Required frontmatter: \`id\`, \`status\`, \`code_paths\`, and at least one of \`test_paths\` or \`test_commands\`.
|
|
95
|
+
|
|
96
|
+
Required sections for active specs: Summary, Use Cases, Invariants, Acceptance Criteria, Out of Scope.
|
|
97
|
+
|
|
98
|
+
Statuses: \`draft\` (not enforced), \`active\` (source of truth), \`deprecated\` (historical).
|
|
99
|
+
|
|
100
|
+
## Working with specs
|
|
101
|
+
|
|
102
|
+
- Review active specs before changing behavior in their \`code_paths\`.
|
|
103
|
+
- When changing behavior, update the spec, code, and tests together.
|
|
104
|
+
- Do not treat spec deletion as permission to silently remove code.
|
|
105
|
+
- Keep edits within the mapped \`code_paths\` unless a supporting change is clearly required.
|
|
106
|
+
- Use \`lisa spec guide\` to scaffold a new spec with placeholders, then fill it in before running implement.
|
|
107
|
+
|
|
108
|
+
## Verification
|
|
109
|
+
|
|
110
|
+
\`lisa spec check\` produces reports at .lisa/spec-report.json and .lisa/spec-report.md.
|
|
111
|
+
|
|
112
|
+
Verdicts per spec: \`PASS\`, \`FAIL\`, \`UNSURE\`, \`SKIPPED\`.
|
|
113
|
+
`;
|
|
114
|
+
|
|
115
|
+
export const LISA_ROOT_GUIDANCE = `This project uses [Lisa](https://github.com/wkronmiller/lisa) for spec-driven development.
|
|
116
|
+
|
|
117
|
+
Behavioral specs live in .specs/ and are the source of truth for intended behavior. Before making changes, review the relevant specs. Use \`lisa spec\` commands to implement and verify against specs.
|
|
118
|
+
|
|
119
|
+
For full Lisa workflow guidance, see the Lisa skill.`;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import type { Stage } from "../harness/types";
|
|
2
|
+
import type { LisaStorageMode } from "./workspace";
|
|
3
|
+
|
|
4
|
+
export const SPEC_AREAS = ["backend", "frontend"] as const;
|
|
5
|
+
export const SPEC_KINDS = ["base", "benchmark", "extension"] as const;
|
|
6
|
+
export const SPEC_STATUSES = ["draft", "active", "deprecated"] as const;
|
|
7
|
+
export const SPEC_STAGES: Stage[] = ["generate", "implement", "check", "import"];
|
|
8
|
+
export const SPEC_IMPORT_UNCERTAINTY_LEVELS = ["low", "medium", "high"] as const;
|
|
9
|
+
|
|
10
|
+
export type SpecArea = (typeof SPEC_AREAS)[number];
|
|
11
|
+
export type SpecKind = (typeof SPEC_KINDS)[number];
|
|
12
|
+
export type SpecStatus = (typeof SPEC_STATUSES)[number];
|
|
13
|
+
export type SpecImportUncertaintyLevel = (typeof SPEC_IMPORT_UNCERTAINTY_LEVELS)[number];
|
|
14
|
+
|
|
15
|
+
export interface ParsedMarkdownSection {
|
|
16
|
+
title: string;
|
|
17
|
+
level: number;
|
|
18
|
+
content: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ParsedSpecDocument {
|
|
22
|
+
path: string;
|
|
23
|
+
filename: string;
|
|
24
|
+
area?: SpecArea;
|
|
25
|
+
kind: SpecKind;
|
|
26
|
+
extensionKind?: string;
|
|
27
|
+
id?: string;
|
|
28
|
+
status?: string;
|
|
29
|
+
frontmatter: Record<string, unknown>;
|
|
30
|
+
body: string;
|
|
31
|
+
sections: ParsedMarkdownSection[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ParsedEnvironmentConfig {
|
|
35
|
+
path: string;
|
|
36
|
+
name?: string;
|
|
37
|
+
runtime?: Record<string, unknown>;
|
|
38
|
+
resources?: Record<string, unknown>;
|
|
39
|
+
notes?: string;
|
|
40
|
+
raw: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ParsedStageProfile {
|
|
44
|
+
harness?: string;
|
|
45
|
+
model?: string;
|
|
46
|
+
allowEdits?: boolean;
|
|
47
|
+
raw: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ParsedHarnessConfig {
|
|
51
|
+
command?: string;
|
|
52
|
+
args: string[];
|
|
53
|
+
raw: Record<string, unknown>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ParsedAgentGuidanceConfig {
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
target?: string;
|
|
59
|
+
targets?: string[];
|
|
60
|
+
raw: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ParsedSpecConfig {
|
|
64
|
+
path: string;
|
|
65
|
+
raw: Record<string, unknown>;
|
|
66
|
+
defaultStageProfiles: Partial<Record<Stage, string>>;
|
|
67
|
+
profiles: Record<string, ParsedStageProfile>;
|
|
68
|
+
harnesses: Record<string, ParsedHarnessConfig>;
|
|
69
|
+
agentGuidance?: ParsedAgentGuidanceConfig;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface StageProfileOverrides {
|
|
73
|
+
profile?: string;
|
|
74
|
+
harness?: string;
|
|
75
|
+
model?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface ResolvedStageProfile {
|
|
79
|
+
stage: Stage;
|
|
80
|
+
profileName: string;
|
|
81
|
+
harness: string;
|
|
82
|
+
model?: string;
|
|
83
|
+
allowEdits: boolean;
|
|
84
|
+
command?: string;
|
|
85
|
+
args: string[];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type SpecFileChange = "added" | "modified" | "deleted";
|
|
89
|
+
|
|
90
|
+
export interface SpecSectionChange {
|
|
91
|
+
section: string;
|
|
92
|
+
changeType: string;
|
|
93
|
+
oldText?: string;
|
|
94
|
+
newText?: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface SpecDelta {
|
|
98
|
+
specId: string;
|
|
99
|
+
path: string;
|
|
100
|
+
kind: SpecKind;
|
|
101
|
+
extensionKind?: string;
|
|
102
|
+
fileChange: SpecFileChange;
|
|
103
|
+
sectionChanges: SpecSectionChange[];
|
|
104
|
+
previousDocument?: ParsedSpecDocument;
|
|
105
|
+
nextDocument?: ParsedSpecDocument;
|
|
106
|
+
extendsSpecId?: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface SpecDiffReport {
|
|
110
|
+
workspacePath: string;
|
|
111
|
+
baseRef: string;
|
|
112
|
+
headRef: string;
|
|
113
|
+
deltas: SpecDelta[];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface PlannedTask {
|
|
117
|
+
id: string;
|
|
118
|
+
specId: string;
|
|
119
|
+
type: "code" | "test" | "benchmark" | "review" | "doc";
|
|
120
|
+
description: string;
|
|
121
|
+
targets?: string[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface PlannedBenchmarkContext {
|
|
125
|
+
id: string;
|
|
126
|
+
path: string;
|
|
127
|
+
fileChange: SpecFileChange;
|
|
128
|
+
environment?: string;
|
|
129
|
+
required?: boolean;
|
|
130
|
+
command?: string;
|
|
131
|
+
metrics: Record<string, string>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface PlannedSpecTarget {
|
|
135
|
+
specId: string;
|
|
136
|
+
path: string;
|
|
137
|
+
fileChange: SpecFileChange;
|
|
138
|
+
codePaths: string[];
|
|
139
|
+
testPaths: string[];
|
|
140
|
+
testCommands: string[];
|
|
141
|
+
invariants: string[];
|
|
142
|
+
acceptanceCriteria: string[];
|
|
143
|
+
benchmarkSidecars: PlannedBenchmarkContext[];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface SpecImplementationPlan {
|
|
147
|
+
diff: SpecDiffReport;
|
|
148
|
+
tasks: PlannedTask[];
|
|
149
|
+
impactedSpecs: PlannedSpecTarget[];
|
|
150
|
+
testCommands: string[];
|
|
151
|
+
deletedSpecIds: string[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface ValidationIssue {
|
|
155
|
+
severity: "error" | "warning";
|
|
156
|
+
path: string;
|
|
157
|
+
message: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export type SpecCheckMode = "changed" | "all";
|
|
161
|
+
export type SpecCheckStatus = "PASS" | "FAIL" | "UNSURE" | "SKIPPED";
|
|
162
|
+
export type SpecCheckEvidenceType = "test" | "benchmark" | "code-audit" | "config";
|
|
163
|
+
|
|
164
|
+
export interface SpecCheckEvidence {
|
|
165
|
+
type: SpecCheckEvidenceType;
|
|
166
|
+
detail: string;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface SpecCheckResult {
|
|
170
|
+
specId: string;
|
|
171
|
+
path: string;
|
|
172
|
+
status: SpecCheckStatus;
|
|
173
|
+
summary: string;
|
|
174
|
+
evidence: SpecCheckEvidence[];
|
|
175
|
+
issues: string[];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface SpecDriftWarning {
|
|
179
|
+
specId: string;
|
|
180
|
+
path: string;
|
|
181
|
+
changedPaths: string[];
|
|
182
|
+
message: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface SpecCheckReport {
|
|
186
|
+
workspacePath: string;
|
|
187
|
+
mode: SpecCheckMode;
|
|
188
|
+
baseRef?: string;
|
|
189
|
+
headRef?: string;
|
|
190
|
+
generatedAt: string;
|
|
191
|
+
profile: string;
|
|
192
|
+
harness: string;
|
|
193
|
+
results: SpecCheckResult[];
|
|
194
|
+
driftWarnings: SpecDriftWarning[];
|
|
195
|
+
summary: {
|
|
196
|
+
pass: number;
|
|
197
|
+
fail: number;
|
|
198
|
+
unsure: number;
|
|
199
|
+
skipped: number;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export interface LoadedSpecWorkspace {
|
|
204
|
+
workspacePath: string;
|
|
205
|
+
storageMode: LisaStorageMode;
|
|
206
|
+
specRoot: string;
|
|
207
|
+
repoSpecRoot: string;
|
|
208
|
+
worktreeSpecRoot?: string;
|
|
209
|
+
configPath: string;
|
|
210
|
+
localConfigRoot: string;
|
|
211
|
+
runtimeRoot: string;
|
|
212
|
+
snapshotRoot: string;
|
|
213
|
+
metadataPath?: string;
|
|
214
|
+
globalPackRoots: string[];
|
|
215
|
+
config?: ParsedSpecConfig;
|
|
216
|
+
environments: ParsedEnvironmentConfig[];
|
|
217
|
+
documents: ParsedSpecDocument[];
|
|
218
|
+
issues: ValidationIssue[];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export interface SpecImportUncertainty {
|
|
222
|
+
path?: string;
|
|
223
|
+
specId?: string;
|
|
224
|
+
level: SpecImportUncertaintyLevel;
|
|
225
|
+
detail: string;
|
|
226
|
+
question?: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export interface SpecImportReport {
|
|
230
|
+
workspacePath: string;
|
|
231
|
+
generatedAt: string;
|
|
232
|
+
selectedPaths: string[];
|
|
233
|
+
profile: string;
|
|
234
|
+
harness: string;
|
|
235
|
+
files: string[];
|
|
236
|
+
notes: string[];
|
|
237
|
+
uncertainties: SpecImportUncertainty[];
|
|
238
|
+
dryRun: boolean;
|
|
239
|
+
}
|