@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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +407 -0
  3. package/bin/lisa-runtime.js +8797 -0
  4. package/bin/lisa.js +21 -0
  5. package/completion.ts +58 -0
  6. package/install.ps1 +51 -0
  7. package/install.sh +93 -0
  8. package/lisa.ts +6 -0
  9. package/package.json +66 -0
  10. package/skills/README.md +28 -0
  11. package/skills/claude-code/CLAUDE.md +151 -0
  12. package/skills/codex/AGENTS.md +151 -0
  13. package/skills/gemini/GEMINI.md +151 -0
  14. package/skills/opencode/AGENTS.md +152 -0
  15. package/src/cli.ts +85 -0
  16. package/src/harness/base-adapter.ts +47 -0
  17. package/src/harness/claude-code.ts +106 -0
  18. package/src/harness/codex.ts +80 -0
  19. package/src/harness/command.ts +173 -0
  20. package/src/harness/gemini.ts +74 -0
  21. package/src/harness/opencode.ts +84 -0
  22. package/src/harness/registry.ts +29 -0
  23. package/src/harness/runner.ts +19 -0
  24. package/src/harness/types.ts +73 -0
  25. package/src/output-mode.ts +32 -0
  26. package/src/skill/artifacts.ts +174 -0
  27. package/src/skill/cli.ts +29 -0
  28. package/src/skill/install.ts +317 -0
  29. package/src/spec/agent-guidance.ts +466 -0
  30. package/src/spec/cli.ts +151 -0
  31. package/src/spec/commands/check.ts +1 -0
  32. package/src/spec/commands/config.ts +146 -0
  33. package/src/spec/commands/diff.ts +1 -0
  34. package/src/spec/commands/generate.ts +1 -0
  35. package/src/spec/commands/guide.ts +1 -0
  36. package/src/spec/commands/harness-list.ts +36 -0
  37. package/src/spec/commands/implement.ts +1 -0
  38. package/src/spec/commands/import.ts +1 -0
  39. package/src/spec/commands/init.ts +1 -0
  40. package/src/spec/commands/status.ts +87 -0
  41. package/src/spec/config.ts +63 -0
  42. package/src/spec/diff.ts +791 -0
  43. package/src/spec/extensions/benchmark.ts +347 -0
  44. package/src/spec/extensions/registry.ts +59 -0
  45. package/src/spec/extensions/types.ts +56 -0
  46. package/src/spec/grammar/index.ts +14 -0
  47. package/src/spec/grammar/parser.ts +443 -0
  48. package/src/spec/grammar/types.ts +70 -0
  49. package/src/spec/grammar/validator.ts +104 -0
  50. package/src/spec/loader.ts +174 -0
  51. package/src/spec/local-config.ts +59 -0
  52. package/src/spec/parser.ts +226 -0
  53. package/src/spec/path-utils.ts +73 -0
  54. package/src/spec/planner.ts +299 -0
  55. package/src/spec/prompt-renderer.ts +318 -0
  56. package/src/spec/skill-content.ts +119 -0
  57. package/src/spec/types.ts +239 -0
  58. package/src/spec/validator.ts +443 -0
  59. package/src/spec/workflows/check.ts +1534 -0
  60. package/src/spec/workflows/diff.ts +209 -0
  61. package/src/spec/workflows/generate.ts +1270 -0
  62. package/src/spec/workflows/guide.ts +190 -0
  63. package/src/spec/workflows/implement.ts +797 -0
  64. package/src/spec/workflows/import.ts +986 -0
  65. package/src/spec/workflows/init.ts +548 -0
  66. package/src/spec/workflows/status.ts +22 -0
  67. package/src/spec/workspace.ts +541 -0
  68. package/uninstall.ps1 +21 -0
  69. 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
+ }