opencode-lisa 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  An intelligent epic workflow plugin for [OpenCode](https://opencode.ai). Like the Ralph Wiggum pattern, but smarter.
6
6
 
7
- **Latest version: 0.2.0** - Now fully self-contained for npm installation!
7
+ **Latest version: 0.3.0** - Simplified one-command installation!
8
8
 
9
9
  ## Why Lisa?
10
10
 
@@ -25,31 +25,33 @@ The **Ralph Wiggum pattern** is a simple bash loop that keeps feeding prompts to
25
25
 
26
26
  ## Install
27
27
 
28
+ One command to install Lisa in your project:
29
+
30
+ ```bash
31
+ npx opencode-lisa --opencode
32
+ ```
33
+
34
+ Or with Bun:
35
+
28
36
  ```bash
29
- npm install -D opencode-lisa
30
- npx opencode-lisa init
37
+ bunx opencode-lisa --opencode
31
38
  ```
32
39
 
33
- This will:
34
- - Install command and skill files to `.opencode/`
35
- - Add the plugin to your `opencode.json`
36
- - Set up Lisa for use in your project
40
+ This creates an `opencode.json` file with Lisa configured. The plugin will be automatically downloaded by OpenCode when you start it.
37
41
 
38
42
  Requires [OpenCode](https://opencode.ai) 1.0+.
39
43
 
40
44
  ### Global Installation
41
45
 
42
- To install Lisa globally for all projects:
46
+ To use Lisa in all your projects, add to your global OpenCode config:
43
47
 
44
48
  ```bash
45
- npm install -g opencode-lisa
46
- npx opencode-lisa init --global
49
+ # Create or edit ~/.config/opencode/opencode.json
47
50
  ```
48
51
 
49
- Add to your global `~/.config/opencode/opencode.json`:
50
-
51
52
  ```json
52
53
  {
54
+ "$schema": "https://opencode.ai/config.json",
53
55
  "plugin": ["opencode-lisa"]
54
56
  }
55
57
  ```
package/bin/cli.js CHANGED
@@ -1,15 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from 'fs';
3
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, rmSync, copyFileSync, mkdirSync, statSync } from 'fs';
4
4
  import { join, dirname } from 'path';
5
5
  import { fileURLToPath } from 'url';
6
- import { createInterface } from 'readline';
7
6
 
8
7
  const __filename = fileURLToPath(import.meta.url);
9
8
  const __dirname = dirname(__filename);
10
- const ASSETS_DIR = join(__dirname, '..', 'assets');
11
9
 
12
- // ANSI colors
10
+ const PLUGIN_NAME = 'opencode-lisa';
11
+
13
12
  const colors = {
14
13
  green: (s) => `\x1b[32m${s}\x1b[0m`,
15
14
  yellow: (s) => `\x1b[33m${s}\x1b[0m`,
@@ -18,232 +17,196 @@ const colors = {
18
17
  dim: (s) => `\x1b[2m${s}\x1b[0m`,
19
18
  };
20
19
 
21
- async function prompt(question) {
22
- const rl = createInterface({
23
- input: process.stdin,
24
- output: process.stdout,
25
- });
26
-
27
- return new Promise((resolve) => {
28
- rl.question(question, (answer) => {
29
- rl.close();
30
- resolve(answer.toLowerCase().trim());
31
- });
32
- });
33
- }
34
-
35
- async function confirmOverwrite(filePath, force) {
36
- if (!existsSync(filePath)) return true;
37
- if (force) return true;
20
+ function printHelp() {
21
+ console.log(`
22
+ ${colors.cyan('Lisa - Intelligent Epic Workflow Plugin')}
38
23
 
39
- const answer = await prompt(
40
- `${colors.yellow('?')} ${filePath} already exists. Overwrite? (y/N) `
41
- );
42
- return answer === 'y' || answer === 'yes';
43
- }
24
+ Usage:
25
+ npx ${PLUGIN_NAME} --opencode
44
26
 
45
- function ensureDir(filePath) {
46
- const dir = dirname(filePath);
47
- if (!existsSync(dir)) {
48
- mkdirSync(dir, { recursive: true });
49
- }
50
- }
27
+ Options:
28
+ --opencode Install Lisa for OpenCode in current directory
29
+ --help, -h Show this help message
51
30
 
52
- function copyAsset(srcRelative, destPath, force) {
53
- return async () => {
54
- const srcPath = join(ASSETS_DIR, srcRelative);
55
-
56
- if (!existsSync(srcPath)) {
57
- console.error(colors.red(`Error: Source file not found: ${srcPath}`));
58
- process.exit(1);
59
- }
31
+ Example:
32
+ npx ${PLUGIN_NAME} --opencode
60
33
 
61
- const shouldWrite = await confirmOverwrite(destPath, force);
62
- if (!shouldWrite) {
63
- console.log(colors.dim(` Skipped: ${destPath}`));
64
- return false;
65
- }
34
+ After installation, run ${colors.cyan('opencode')} and type ${colors.cyan('/lisa help')} to get started!
35
+ `);
36
+ }
66
37
 
67
- ensureDir(destPath);
68
- copyFileSync(srcPath, destPath);
69
- console.log(colors.green(` Created: ${destPath}`));
38
+ async function checkOpenCodeInstalled() {
39
+ try {
40
+ // Check if opencode command exists
41
+ const { execSync } = await import('child_process');
42
+ execSync('which opencode', { stdio: 'ignore' });
70
43
  return true;
71
- };
44
+ } catch {
45
+ return false;
46
+ }
72
47
  }
73
48
 
74
- function updateOpencodeJson(targetDir, force) {
75
- return async () => {
76
- const configPath = join(targetDir, 'opencode.json');
77
- let config = {};
78
- let existed = false;
79
-
80
- if (existsSync(configPath)) {
81
- existed = true;
82
- try {
83
- const content = readFileSync(configPath, 'utf-8');
84
- config = JSON.parse(content);
85
- } catch (e) {
86
- console.error(colors.red(`Error parsing ${configPath}: ${e.message}`));
87
- const answer = await prompt(
88
- `${colors.yellow('?')} Create a new opencode.json? (y/N) `
89
- );
90
- if (answer !== 'y' && answer !== 'yes') {
91
- console.log(colors.dim(` Skipped: opencode.json update`));
92
- return false;
49
+ function cleanupOldInstalls(targetDir) {
50
+ // Remove old file-based installations from previous versions
51
+ const oldPaths = [
52
+ join(targetDir, '.opencode', 'skills', 'lisa'),
53
+ join(targetDir, '.opencode', 'skill', 'lisa'), // old singular path
54
+ join(targetDir, '.opencode', 'command', 'lisa.md'), // old singular path
55
+ ];
56
+
57
+ for (const oldPath of oldPaths) {
58
+ try {
59
+ if (existsSync(oldPath)) {
60
+ const stat = statSync(oldPath);
61
+ if (stat.isDirectory()) {
62
+ rmSync(oldPath, { recursive: true, force: true });
63
+ } else {
64
+ unlinkSync(oldPath);
93
65
  }
94
- config = {};
66
+ console.log(colors.dim(` Cleaned up old install: ${oldPath}`));
95
67
  }
68
+ } catch {
69
+ // Ignore errors during cleanup
96
70
  }
97
-
98
- // Ensure plugin array exists
99
- if (!config.plugin) {
100
- config.plugin = [];
101
- }
102
-
103
- // Check if already has the plugin
104
- if (config.plugin.includes('opencode-lisa')) {
105
- console.log(colors.dim(` Already configured: opencode-lisa in plugins`));
106
- return false;
107
- }
108
-
109
- // Add the plugin
110
- config.plugin.push('opencode-lisa');
111
-
112
- // Add schema if not present
113
- if (!config.$schema) {
114
- config.$schema = 'https://opencode.ai/config.json';
115
- }
116
-
117
- ensureDir(configPath);
118
- writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
119
-
120
- if (existed) {
121
- console.log(colors.green(` Updated: opencode.json (added opencode-lisa to plugins)`));
122
- } else {
123
- console.log(colors.green(` Created: opencode.json`));
124
- }
125
- return true;
126
- };
71
+ }
127
72
  }
128
73
 
129
- async function init(targetDir, options) {
130
- const { force, global: isGlobal } = options;
74
+ function installCommandFile(targetDir) {
75
+ // Source: command file in the npm package
76
+ const sourcePath = join(__dirname, '..', 'assets', 'commands', 'lisa.md');
77
+
78
+ // Destination: where OpenCode looks for slash commands
79
+ const destPath = join(targetDir, '.opencode', 'commands', 'lisa.md');
80
+
81
+ // Verify source file exists
82
+ if (!existsSync(sourcePath)) {
83
+ throw new Error(`Source command file not found: ${sourcePath}`);
84
+ }
85
+
86
+ // Create directory if needed
87
+ const destDir = dirname(destPath);
88
+ if (!existsSync(destDir)) {
89
+ mkdirSync(destDir, { recursive: true });
90
+ }
91
+
92
+ // Copy file (overwrite if exists to ensure latest version)
93
+ copyFileSync(sourcePath, destPath);
94
+ console.log(colors.green(` Created: ${destPath}`));
95
+ }
131
96
 
97
+ async function install(targetDir) {
132
98
  console.log('');
133
99
  console.log(colors.cyan('Lisa - Intelligent Epic Workflow Plugin'));
134
- console.log(colors.dim('Installing command and skill files...'));
135
100
  console.log('');
136
101
 
137
- const tasks = [
138
- {
139
- name: 'skill',
140
- run: copyAsset(
141
- 'skills/lisa/SKILL.md',
142
- join(targetDir, '.opencode', 'skills', 'lisa', 'SKILL.md'),
143
- force
144
- ),
145
- },
146
- {
147
- name: 'command',
148
- run: copyAsset(
149
- 'commands/lisa.md',
150
- join(targetDir, '.opencode', 'commands', 'lisa.md'),
151
- force
152
- ),
153
- },
154
- ];
102
+ // Check if OpenCode is installed
103
+ const isOpenCodeInstalled = checkOpenCodeInstalled();
104
+ if (!isOpenCodeInstalled) {
105
+ console.log(colors.red('Error: OpenCode is not installed or not in PATH.'));
106
+ console.log('');
107
+ console.log('Please install OpenCode first:');
108
+ console.log(` ${colors.cyan('brew install opencode')} (macOS)`);
109
+ console.log(` ${colors.cyan('npm install -g @opencode-ai/cli')} (other platforms)`);
110
+ console.log('');
111
+ console.log('Then run this installer again.');
112
+ process.exit(1);
113
+ }
155
114
 
156
- // Only update opencode.json for local installs (not global)
157
- if (!isGlobal) {
158
- tasks.push({
159
- name: 'config',
160
- run: updateOpencodeJson(targetDir, force),
161
- });
115
+ // Cleanup old file-based installs
116
+ cleanupOldInstalls(targetDir);
117
+
118
+ // Install command file for slash command autocomplete
119
+ try {
120
+ installCommandFile(targetDir);
121
+ } catch (err) {
122
+ console.log(colors.red(`Error: Failed to install command file.`));
123
+ console.log(colors.dim(` ${err.message}`));
124
+ console.log('');
125
+ console.log('Lisa cannot be installed without the command file.');
126
+ console.log('Please report this issue at https://github.com/fractalswift/lisa-simpson/issues');
127
+ process.exit(1);
162
128
  }
163
129
 
164
- let anyCreated = false;
165
- for (const task of tasks) {
166
- const created = await task.run();
167
- if (created) anyCreated = true;
130
+ // Update or create opencode.json
131
+ const configPath = join(targetDir, 'opencode.json');
132
+ let config = {};
133
+ let configExisted = false;
134
+
135
+ if (existsSync(configPath)) {
136
+ configExisted = true;
137
+ try {
138
+ const content = readFileSync(configPath, 'utf-8');
139
+ config = JSON.parse(content);
140
+ } catch (e) {
141
+ console.log(colors.red(`Error: ${configPath} exists but is not valid JSON.`));
142
+ console.log(colors.dim(` ${e.message}`));
143
+ process.exit(1);
144
+ }
168
145
  }
169
146
 
170
- console.log('');
147
+ // Ensure plugin array exists
148
+ if (!config.plugin) {
149
+ config.plugin = [];
150
+ }
171
151
 
172
- if (anyCreated) {
173
- console.log(colors.green('Done!'));
174
- console.log('');
175
- console.log('Lisa is now installed. You can use:');
152
+ // Check if already installed
153
+ if (config.plugin.includes(PLUGIN_NAME)) {
154
+ console.log(colors.yellow(`Lisa is already configured in this project.`));
176
155
  console.log('');
177
- console.log(` ${colors.cyan('/lisa')} - Run Lisa commands in OpenCode`);
178
- console.log(` ${colors.cyan('/lisa help')} - Show available Lisa commands`);
179
- console.log(` ${colors.cyan('/lisa list')} - List all your epics`);
156
+ console.log(`Run ${colors.cyan('opencode')} and type ${colors.cyan('/lisa help')} to get started!`);
180
157
  console.log('');
181
- console.log(colors.dim('Start by running /lisa <epic-name> to create your first epic!'));
182
- } else {
183
- console.log(colors.dim('Nothing to do - everything is already set up.'));
158
+ return;
184
159
  }
185
160
 
186
- console.log('');
187
- }
161
+ // Add the plugin
162
+ config.plugin.push(PLUGIN_NAME);
188
163
 
189
- function printHelp() {
190
- console.log(`
191
- ${colors.cyan('Lisa - Intelligent Epic Workflow Plugin')}
192
-
193
- Like Ralph Wiggum, but smarter. Lisa plans before she acts.
194
-
195
- Usage:
196
- npx opencode-lisa init [options]
164
+ // Add schema if not present
165
+ if (!config.$schema) {
166
+ config.$schema = 'https://opencode.ai/config.json';
167
+ }
197
168
 
198
- Commands:
199
- init Install the Lisa command and skill files
169
+ // Write config
170
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
200
171
 
201
- Options:
202
- --force Overwrite existing files without asking
203
- --global Install to ~/.config/opencode/ instead of current directory
204
- --help, -h Show this help message
205
-
206
- Examples:
207
- npx opencode-lisa init
208
- npx opencode-lisa init --force
209
- npx opencode-lisa init --global
172
+ if (configExisted) {
173
+ console.log(colors.green(` Updated: ${configPath} (added ${PLUGIN_NAME} to plugins)`));
174
+ } else {
175
+ console.log(colors.green(` Created: ${configPath}`));
176
+ }
210
177
 
211
- After installation, use /lisa in OpenCode to get started!
212
- `);
178
+ console.log('');
179
+ console.log(colors.green('Done!'));
180
+ console.log('');
181
+ console.log('Lisa is now installed and will be auto-downloaded by OpenCode.');
182
+ console.log('');
183
+ console.log('Next steps:');
184
+ console.log(` 1. Run ${colors.cyan('opencode')} to start OpenCode`);
185
+ console.log(` 2. Type ${colors.cyan('/lisa help')} to see available commands`);
186
+ console.log(` 3. Type ${colors.cyan('/lisa <epic-name>}')} to create your first epic`);
187
+ console.log('');
213
188
  }
214
189
 
215
190
  async function main() {
216
191
  const args = process.argv.slice(2);
217
192
 
218
193
  // Parse flags
219
- const force = args.includes('--force') || args.includes('-f');
220
- const isGlobal = args.includes('--global') || args.includes('-g');
194
+ const opencodeFlag = args.includes('--opencode');
221
195
  const help = args.includes('--help') || args.includes('-h');
222
-
223
- // Get command (first non-flag argument)
224
- const command = args.find((arg) => !arg.startsWith('-'));
225
196
 
226
- if (help || (!command && args.length === 0)) {
197
+ if (help || args.length === 0) {
227
198
  printHelp();
228
199
  process.exit(0);
229
200
  }
230
201
 
231
- if (command !== 'init') {
232
- console.error(colors.red(`Unknown command: ${command}`));
233
- console.error(`Run ${colors.cyan('npx opencode-lisa --help')} for usage.`);
202
+ if (!opencodeFlag) {
203
+ console.log(colors.red(`Unknown flag: ${args.find(a => a.startsWith('--')) || args[0]}`));
204
+ console.log(`Run ${colors.cyan(`npx ${PLUGIN_NAME} --help`)} for usage.`);
234
205
  process.exit(1);
235
206
  }
236
207
 
237
- // Determine target directory
238
- let targetDir;
239
- if (isGlobal) {
240
- const home = process.env.HOME || process.env.USERPROFILE;
241
- targetDir = join(home, '.config', 'opencode');
242
- } else {
243
- targetDir = process.cwd();
244
- }
245
-
246
- await init(targetDir, { force, global: isGlobal });
208
+ const targetDir = process.cwd();
209
+ await install(targetDir);
247
210
  }
248
211
 
249
212
  main().catch((err) => {
package/dist/index.js CHANGED
@@ -12390,31 +12390,33 @@ The input format is: \`<epic-name> [mode]\`
12390
12390
 
12391
12391
  ### If no arguments or \`help\`:
12392
12392
 
12393
- If the user runs \`/lisa\` with no arguments, or \`/lisa help\`, immediately respond with this help menu (no tool calls needed):
12393
+ If the user runs \`/lisa\` with no arguments, or \`/lisa help\`, IMMEDIATELY output EXACTLY this text (verbatim, no modifications, no tool calls):
12394
12394
 
12395
- \`\`\`
12396
- Lisa - Intelligent Epic Workflow
12395
+ ---
12397
12396
 
12398
- Available Commands:
12397
+ **Lisa - Intelligent Epic Workflow**
12399
12398
 
12400
- /lisa list - List all epics and their status
12401
- /lisa <name> - Continue or create an epic (interactive)
12402
- /lisa <name> spec - Create/view the spec only
12403
- /lisa <name> status - Show detailed epic status
12404
- /lisa <name> yolo - Auto-execute mode (no confirmations)
12405
- /lisa config view - View current configuration
12406
- /lisa config init - Initialize config with defaults
12407
- /lisa config reset - Reset config to defaults
12399
+ **Available Commands:**
12408
12400
 
12409
- Examples:
12410
- /lisa list - See all your epics
12411
- /lisa auth-system - Start or continue the auth-system epic
12412
- /lisa auth-system yolo - Run auth-system in full auto mode
12401
+ \`/lisa list\` - List all epics and their status
12402
+ \`/lisa <name>\` - Continue or create an epic (interactive)
12403
+ \`/lisa <name> spec\` - Create/view the spec only
12404
+ \`/lisa <name> status\` - Show detailed epic status
12405
+ \`/lisa <name> yolo\` - Auto-execute mode (no confirmations)
12406
+ \`/lisa config view\` - View current configuration
12407
+ \`/lisa config init\` - Initialize config with defaults
12408
+ \`/lisa config reset\` - Reset config to defaults
12413
12409
 
12414
- Get started: /lisa <epic-name>
12415
- \`\`\`
12410
+ **Examples:**
12411
+ - \`/lisa list\` - See all your epics
12412
+ - \`/lisa auth-system\` - Start or continue the auth-system epic
12413
+ - \`/lisa auth-system yolo\` - Run auth-system in full auto mode
12414
+
12415
+ **Get started:** \`/lisa <epic-name>\`
12416
+
12417
+ ---
12416
12418
 
12417
- **Stop here. Do not call any tools or do anything else.**
12419
+ **CRITICAL: Output the above help text EXACTLY as shown. Do not add explanations, do not call tools, do not be creative. Just show the menu and stop.**
12418
12420
 
12419
12421
  ### Otherwise, parse the arguments:
12420
12422
 
package/package.json CHANGED
@@ -1,17 +1,12 @@
1
1
  {
2
2
  "name": "opencode-lisa",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Lisa - intelligent epic workflow plugin for OpenCode. Like Ralph Wiggum, but smarter.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "opencode-lisa": "./bin/cli.js"
9
9
  },
10
- "exports": {
11
- ".": {
12
- "import": "./dist/index.js"
13
- }
14
- },
15
10
  "files": [
16
11
  "dist",
17
12
  "bin",
@@ -45,14 +40,8 @@
45
40
  "engines": {
46
41
  "node": ">=18.0.0"
47
42
  },
48
- "peerDependencies": {
49
- "@opencode-ai/plugin": ">=1.0.0"
50
- },
51
43
  "devDependencies": {
52
44
  "@opencode-ai/plugin": "^1.1.25",
53
45
  "typescript": "^5.0.0"
54
- },
55
- "dependencies": {
56
- "opencode-lisa": "^0.2.1"
57
46
  }
58
47
  }
@@ -1,841 +0,0 @@
1
- ---
2
- name: lisa
3
- description: Lisa - intelligent epic workflow with spec, research, plan, and execute phases. Smarter than Ralph.
4
- ---
5
-
6
- # Lisa - Intelligent Epic Workflow
7
-
8
- A structured approach to implementing large features by breaking them into phases: spec, research, plan, and execute.
9
-
10
- Like the Ralph Wiggum pattern, but smarter. Lisa plans before she acts.
11
-
12
- ## Working Directory
13
-
14
- Epics are stored in `.lisa/epics/` relative to **where you run `opencode`**.
15
-
16
- Run opencode from your project root and epics will be at `your-project/.lisa/epics/`.
17
-
18
- **Example structure:**
19
- ```
20
- my-project/ <- run `opencode` from here
21
- ├── .lisa/
22
- │ ├── config.jsonc
23
- │ ├── .gitignore
24
- │ └── epics/
25
- │ └── my-feature/
26
- │ ├── .state
27
- │ ├── spec.md
28
- │ └── tasks/
29
- ├── src/
30
- └── package.json
31
- ```
32
-
33
- ---
34
-
35
- ## Parse Arguments
36
-
37
- The input format is: `<epic-name> [mode]`
38
-
39
- ### If no arguments or `help`:
40
-
41
- If the user runs `/lisa` with no arguments, or `/lisa help`, immediately respond with this help menu (no tool calls needed):
42
-
43
- ```
44
- Lisa - Intelligent Epic Workflow
45
-
46
- Available Commands:
47
-
48
- /lisa list - List all epics and their status
49
- /lisa <name> - Continue or create an epic (interactive)
50
- /lisa <name> spec - Create/view the spec only
51
- /lisa <name> status - Show detailed epic status
52
- /lisa <name> yolo - Auto-execute mode (no confirmations)
53
- /lisa config view - View current configuration
54
- /lisa config init - Initialize config with defaults
55
- /lisa config reset - Reset config to defaults
56
-
57
- Examples:
58
- /lisa list - See all your epics
59
- /lisa auth-system - Start or continue the auth-system epic
60
- /lisa auth-system yolo - Run auth-system in full auto mode
61
-
62
- Get started: /lisa <epic-name>
63
- ```
64
-
65
- **Stop here. Do not call any tools or do anything else.**
66
-
67
- ### Otherwise, parse the arguments:
68
-
69
- **Modes:**
70
- - `list` → List all epics
71
- - `config <action>` → Config management (view/init/reset)
72
- - `<name>` (no mode) → Default mode with checkpoints
73
- - `<name> spec` → Just create/view spec
74
- - `<name> yolo` → Full auto, no checkpoints
75
- - `<name> status` → Show status
76
-
77
- **Examples:**
78
- - `list` → list all epics
79
- - `config view` → show config
80
- - `my-feature` → default mode
81
- - `my-feature spec` → spec only
82
- - `my-feature yolo` → full auto
83
- - `my-feature status` → show status
84
-
85
- ---
86
-
87
- ## Mode: config
88
-
89
- Handle config subcommands using the `lisa_config` tool:
90
-
91
- - `config view` → Call `lisa_config(action: "view")` and display the result
92
- - `config init` → Call `lisa_config(action: "init")` and confirm creation
93
- - `config reset` → Call `lisa_config(action: "reset")` and confirm reset
94
-
95
- After the tool returns, display the result in a user-friendly format.
96
-
97
- ---
98
-
99
- ## Mode: list
100
-
101
- **Use the `list_epics` tool** to quickly get all epics and their status.
102
-
103
- Display the results in a formatted list showing:
104
- - Epic name
105
- - Current phase (spec/research/plan/execute/complete)
106
- - Task progress (X/Y done) if in execute phase
107
- - Whether yolo mode is active
108
-
109
- **If no epics found:**
110
- > "No epics found. Start one with `/lisa <name>`"
111
-
112
- ---
113
-
114
- ## Mode: status
115
-
116
- **Use the `get_epic_status` tool** to quickly get detailed status.
117
-
118
- Display the results showing:
119
- - Current phase
120
- - Which artifacts exist (spec.md, research.md, plan.md)
121
- - Task breakdown: done, in-progress, pending, blocked
122
- - Yolo mode status (if active)
123
- - Suggested next action
124
-
125
- **If epic doesn't exist:**
126
- > "Epic '<name>' not found. Start it with `/lisa <name>`"
127
-
128
- ---
129
-
130
- ## Mode: spec
131
-
132
- Interactive spec creation only. Does NOT continue to research/plan/execute.
133
-
134
- ### If spec already exists:
135
-
136
- Read and display the existing spec, then:
137
-
138
- > "Spec already exists at `.lisa/epics/<name>/spec.md`. You can:
139
- > - Edit it directly in your editor
140
- > - Delete it and run `/lisa <name> spec` again to start over
141
- > - Run `/lisa <name>` to continue with research and planning"
142
-
143
- ### If no spec exists:
144
-
145
- Have an interactive conversation to define the spec. Cover:
146
-
147
- 1. **Goal** - What are we trying to achieve? Why?
148
- 2. **Scope** - What's included? What's explicitly out of scope?
149
- 3. **Acceptance Criteria** - How do we know when it's done?
150
- 4. **Technical Constraints** - Any specific technologies, patterns, or limitations?
151
-
152
- Be conversational. Ask clarifying questions. Push back if scope is too large or vague.
153
-
154
- **Keep it concise** - aim for 20-50 lines. Focus on "what" and "why", not "how".
155
-
156
- ### When conversation is complete:
157
-
158
- Summarize the spec and ask:
159
-
160
- > "Here's the spec:
161
- >
162
- > [formatted spec]
163
- >
164
- > Ready to save to `.lisa/epics/<name>/spec.md`?"
165
-
166
- On confirmation, create the directory and save:
167
-
168
- ```
169
- .lisa/epics/<name>/
170
- spec.md
171
- .state
172
- ```
173
-
174
- **spec.md format:**
175
- ```markdown
176
- # Epic: <name>
177
-
178
- ## Goal
179
- [What we're building and why - 1-2 sentences]
180
-
181
- ## Scope
182
- - [What's included]
183
- - [What's included]
184
-
185
- ### Out of Scope
186
- - [What we're NOT doing]
187
-
188
- ## Acceptance Criteria
189
- - [ ] [Measurable criterion]
190
- - [ ] [Measurable criterion]
191
-
192
- ## Technical Constraints
193
- - [Any constraints, or "None"]
194
- ```
195
-
196
- **.state format (JSON):**
197
- ```json
198
- {
199
- "name": "<name>",
200
- "currentPhase": "spec",
201
- "specComplete": true,
202
- "researchComplete": false,
203
- "planComplete": false,
204
- "executeComplete": false,
205
- "lastUpdated": "<timestamp>"
206
- }
207
- ```
208
-
209
- After saving:
210
- > "Spec saved to `.lisa/epics/<name>/spec.md`
211
- >
212
- > Next steps:
213
- > - Run `/lisa <name>` to continue with research and planning
214
- > - Run `/lisa <name> yolo` for full auto execution"
215
-
216
- ---
217
-
218
- ## Mode: default (with checkpoints)
219
-
220
- This is the main interactive mode. It guides you through each phase with approval checkpoints.
221
-
222
- ### Step 1: Ensure spec exists
223
-
224
- **If no spec:**
225
- Run the spec conversation (same as spec mode). After saving, continue to step 2.
226
-
227
- **If spec exists:**
228
- Read and briefly summarize it, then continue to step 2.
229
-
230
- ### Step 2: Research phase
231
-
232
- **If research.md already exists:**
233
- > "Research already complete. Proceeding to planning..."
234
- Skip to step 3.
235
-
236
- **If research not done:**
237
- > "Ready to start research? I'll explore the codebase to understand what's needed for this epic."
238
-
239
- Wait for confirmation. On "yes" or similar:
240
-
241
- 1. Read spec.md
242
- 2. Explore the codebase using available tools (LSP, grep, glob, file reads)
243
- 3. Document findings
244
- 4. Save to `.lisa/epics/<name>/research.md`
245
- 5. Update .state
246
-
247
- **research.md format:**
248
- ```markdown
249
- # Research: <name>
250
-
251
- ## Overview
252
- [1-2 sentence summary of findings]
253
-
254
- ## Relevant Files
255
- - `path/to/file.ts` - [why it's relevant]
256
- - `path/to/file.ts` - [why it's relevant]
257
-
258
- ## Existing Patterns
259
- [How similar things are done in this codebase]
260
-
261
- ## Dependencies
262
- [External packages or internal modules needed]
263
-
264
- ## Technical Findings
265
- [Key discoveries that affect implementation]
266
-
267
- ## Recommendations
268
- [Suggested approach based on findings]
269
- ```
270
-
271
- After saving:
272
- > "Research complete and saved. Found X relevant files. Key insight: [one line summary]"
273
-
274
- ### Step 3: Plan phase
275
-
276
- **If plan.md already exists:**
277
- > "Plan already complete with X tasks. Proceeding to execution..."
278
- Skip to step 4.
279
-
280
- **If plan not done:**
281
- > "Ready to create the implementation plan?"
282
-
283
- Wait for confirmation. On "yes" or similar:
284
-
285
- 1. Read spec.md and research.md
286
- 2. Break down into discrete tasks (aim for 1-5 files per task, ~30 min of work each)
287
- 3. Define dependencies between tasks
288
- 4. Save plan.md and individual task files
289
- 5. Update .state
290
-
291
- **plan.md format:**
292
- ```markdown
293
- # Plan: <name>
294
-
295
- ## Overview
296
- [1-2 sentence summary of approach]
297
-
298
- ## Tasks
299
-
300
- 1. [Task name] - tasks/01-[slug].md
301
- 2. [Task name] - tasks/02-[slug].md
302
- 3. [Task name] - tasks/03-[slug].md
303
-
304
- ## Dependencies
305
-
306
- - 01: []
307
- - 02: [01]
308
- - 03: [01]
309
- - 04: [02, 03]
310
-
311
- ## Risks
312
- - [Risk and mitigation, or "None identified"]
313
- ```
314
-
315
- **Task file format (tasks/XX-slug.md):**
316
- ```markdown
317
- # Task X: [Name]
318
-
319
- ## Status: pending
320
-
321
- ## Goal
322
- [What this task accomplishes - 1-2 sentences]
323
-
324
- ## Files
325
- - path/to/file1.ts
326
- - path/to/file2.ts
327
-
328
- ## Steps
329
- 1. [Concrete step]
330
- 2. [Concrete step]
331
- 3. [Concrete step]
332
-
333
- ## Done When
334
- - [ ] [Testable criterion]
335
- - [ ] [Testable criterion]
336
- ```
337
-
338
- After saving:
339
- > "Plan created with X tasks:
340
- > 1. [task 1 name]
341
- > 2. [task 2 name]
342
- > ...
343
- >
344
- > Saved to `.lisa/epics/<name>/plan.md`"
345
-
346
- ### Step 4: Execute phase
347
-
348
- **Use `get_available_tasks` tool** to quickly see what's ready to run.
349
-
350
- **If all tasks done (available and blocked both empty):**
351
- > "All tasks complete! Epic finished."
352
- Stop.
353
-
354
- **If tasks remain:**
355
- Show task summary from the tool output and ask:
356
- > "Ready to execute? X tasks remaining:
357
- > - Available now: [from available list]
358
- > - Blocked by dependencies: [from blocked list]"
359
-
360
- Wait for confirmation. On "yes" or similar:
361
-
362
- **Execute tasks using `build_task_context` + Task tool:**
363
-
364
- Tasks with satisfied dependencies can be executed in **parallel** (the `available` list from `get_available_tasks` shows all tasks that are ready). Tasks whose dependencies aren't met yet are in the `blocked` list and must wait.
365
-
366
- For each task in the `available` list:
367
- 1. Call `build_task_context(epicName, taskId)` to get the prompt
368
- 2. Call the Task tool with the prompt to spawn a sub-agent
369
- 3. After sub-agent(s) complete, call `get_available_tasks` again to refresh the list
370
- 4. If a task isn't done, retry up to 3 times, then mark blocked
371
- 5. Repeat until all tasks done
372
-
373
- **Note:** If executing in parallel, each sub-agent gets the same context snapshot. Their reports will be available for subsequent tasks.
374
-
375
- **On task failure (after 3 attempts):**
376
- - Mark task as `blocked` in the task file
377
- - Add `## Blocked Reason: [why]`
378
- - Continue with other available tasks
379
-
380
- **On all tasks complete:**
381
- > "Epic complete! All X tasks finished.
382
- >
383
- > Summary of changes:
384
- > - [file]: [what changed]
385
- > - [file]: [what changed]"
386
-
387
- ---
388
-
389
- ## Mode: yolo (full auto)
390
-
391
- Full automatic execution with no checkpoints. Requires spec to exist.
392
-
393
- **IMPORTANT:** In yolo mode, the Lisa plugin monitors for session idle events and automatically continues execution until all tasks are complete. You don't need to worry about session limits - just keep working and the plugin handles continuation.
394
-
395
- ### YOLO MODE RULES - READ CAREFULLY
396
-
397
- When in yolo mode, you MUST follow these rules strictly:
398
-
399
- 1. **NEVER stop to summarize progress** - Don't say "I've completed X, Y tasks remain". Just keep working.
400
-
401
- 2. **NEVER ask for confirmation** - Don't say "Ready to continue?" or "Should I proceed?". Just proceed.
402
-
403
- 3. **NEVER explain what you're about to do** - Don't narrate. Execute.
404
-
405
- 4. **ALWAYS execute the next task immediately** - After one task completes, immediately call `get_available_tasks` and start the next one.
406
-
407
- 5. **ONLY stop when truly done** - You stop ONLY when:
408
- - All tasks have `## Status: done`, OR
409
- - All remaining tasks are `## Status: blocked`
410
-
411
- 6. **Treat each response as a work session** - Your goal is to make maximum progress before your response ends. Execute as many tasks as possible.
412
-
413
- **Why these rules matter:** Yolo mode is for autonomous, unattended execution. The user has walked away. Every time you stop to summarize or ask a question, you break the automation and waste the user's time.
414
-
415
- **If you're unsure, keep working.** It's better to complete an extra task than to stop and ask.
416
-
417
- ### If no spec exists:
418
-
419
- > "No spec found at `.lisa/epics/<name>/spec.md`.
420
- >
421
- > Create one first:
422
- > - Interactively: `/lisa <name> spec`
423
- > - Manually: Create `.lisa/epics/<name>/spec.md`"
424
-
425
- Stop. Do not proceed.
426
-
427
- ### If spec exists:
428
-
429
- **Step 1: Activate yolo mode in .state**
430
-
431
- Read the current `.lisa/epics/<name>/.state` file and add the `yolo` configuration:
432
-
433
- ```json
434
- {
435
- "name": "<name>",
436
- "currentPhase": "...",
437
- "specComplete": true,
438
- "researchComplete": false,
439
- "planComplete": false,
440
- "executeComplete": false,
441
- "lastUpdated": "<timestamp>",
442
- "yolo": {
443
- "active": true,
444
- "iteration": 1,
445
- "maxIterations": 100,
446
- "startedAt": "<current ISO timestamp>"
447
- }
448
- }
449
- ```
450
-
451
- This tells the Lisa plugin to automatically continue the session when you finish responding.
452
-
453
- **Step 2: Run all phases without asking for confirmation:**
454
-
455
- 1. **Research** (if not done) - explore codebase, save research.md
456
- 2. **Plan** (if not done) - create plan.md and task files
457
- 3. **Execute** - use `get_available_tasks` + `build_task_context` + Task tool
458
-
459
- **Execute tasks using `build_task_context` + Task tool:**
460
-
461
- Tasks with satisfied dependencies can be executed in **parallel** if desired.
462
-
463
- 1. Call `get_available_tasks(epicName)` to get the list of ready tasks
464
- 2. For each task in the `available` list (can parallelize):
465
- - Call `build_task_context(epicName, taskId)` to get the prompt
466
- - Call the Task tool with the prompt to spawn a sub-agent
467
- 3. After sub-agent(s) complete, call `get_available_tasks` again to refresh
468
- 4. If a task isn't done, retry up to 3 times, then mark blocked
469
- 5. Repeat until all tasks done or all blocked
470
-
471
- The plugin will automatically continue the session if context fills up.
472
-
473
- **REMEMBER THE YOLO RULES:** Don't stop to summarize. Don't ask questions. Just keep executing tasks until they're all done or blocked.
474
-
475
- **On all tasks complete:**
476
- - Update .state: set `executeComplete: true` and `yolo.active: false`
477
- > "Epic complete! All X tasks finished."
478
-
479
- **On task blocked (after 3 attempts):**
480
- - Mark as blocked in the task file, continue with others
481
- - If all remaining tasks blocked:
482
- - Update .state: set `yolo.active: false`
483
- - Report which tasks are blocked and why
484
-
485
- ---
486
-
487
- ## Shared: Task Execution Logic
488
-
489
- **IMPORTANT: Use the `build_task_context` tool + Task tool for each task.**
490
-
491
- This pattern ensures each task runs with fresh context in a sub-agent:
492
- - Fresh context for each task (no accumulated cruft)
493
- - Proper handoff between tasks via reports
494
- - Consistent execution pattern
495
-
496
- ### Execution Flow (Orchestrator)
497
-
498
- As the orchestrator, you manage the overall flow:
499
-
500
- 1. **Read plan.md** to understand task order and dependencies
501
- 2. **For each available task** (dependencies satisfied, not blocked):
502
-
503
- **Step A: Build context**
504
- ```
505
- Call build_task_context with:
506
- - epicName: the epic name
507
- - taskId: the task number (e.g., "01", "02")
508
- ```
509
- This returns a `prompt` field with the full context.
510
-
511
- **Step B: Execute with sub-agent**
512
- ```
513
- Call the Task tool with:
514
- - description: "Execute task {taskId} of epic {epicName}"
515
- - prompt: [the prompt returned from build_task_context]
516
- ```
517
-
518
- 3. **After sub-agent completes**, check the task file:
519
- - If `## Status: done` → Move to next task
520
- - If not done → Retry (up to 3 times) or mark blocked
521
- 4. **Repeat** until all tasks done or all remaining tasks blocked
522
-
523
- ### What the Sub-Agent Does
524
-
525
- The sub-agent (spawned via Task tool) receives full context and:
526
-
527
- 1. **Reads the context**: spec, research, plan, all previous task files with reports
528
- 2. **Executes the task steps**
529
- 3. **Updates the task file**:
530
- - Changes `## Status: pending` to `## Status: done`
531
- - Adds a `## Report` section (see format below)
532
- 4. **May update future tasks** if the plan needs changes
533
- 5. **Confirms completion** when done
534
-
535
- ### Task File Format (with Report)
536
-
537
- After completion, a task file should look like:
538
-
539
- ```markdown
540
- # Task 01: [Name]
541
-
542
- ## Status: done
543
-
544
- ## Goal
545
- [What this task accomplishes]
546
-
547
- ## Files
548
- - path/to/file1.ts
549
- - path/to/file2.ts
550
-
551
- ## Steps
552
- 1. [Concrete step]
553
- 2. [Concrete step]
554
-
555
- ## Done When
556
- - [x] [Criterion - now checked]
557
- - [x] [Criterion - now checked]
558
-
559
- ## Report
560
-
561
- ### What Was Done
562
- - Created X component
563
- - Added Y functionality
564
- - Configured Z
565
-
566
- ### Decisions Made
567
- - Chose approach A over B because [reason]
568
- - Used library X for [reason]
569
-
570
- ### Issues / Notes for Next Task
571
- - The API returns data in format X, next task should handle this
572
- - Found that Y needs to be done differently than planned
573
-
574
- ### Files Changed
575
- - src/components/Foo.tsx (new)
576
- - src/hooks/useBar.ts (modified)
577
- - package.json (added dependency)
578
- ```
579
-
580
- ### Handling Failures
581
-
582
- When `execute_epic_task` returns `status: "failed"`:
583
-
584
- 1. **Check the summary** for what went wrong
585
- 2. **Decide**:
586
- - Retry (up to 3 times) if it seems like a transient issue
587
- - Mark as blocked if fundamentally broken
588
- - Revise the plan if the approach is wrong
589
-
590
- To mark as blocked:
591
- ```markdown
592
- ## Status: blocked
593
-
594
- ## Blocked Reason
595
- [Explanation of why this task cannot proceed]
596
- ```
597
-
598
- ### On discovering the plan needs changes:
599
-
600
- If during execution you realize:
601
- - A task's approach is fundamentally wrong (not just a bug to fix)
602
- - Tasks are missing that should have been included
603
- - Dependencies are incorrect
604
- - The order should change
605
- - New information invalidates earlier assumptions
606
-
607
- **You may update the plan. The plan is a living document, not a rigid contract.**
608
-
609
- 1. **Update the affected task file(s)** in `tasks/`:
610
- - Revise steps if the approach needs changing
611
- - Update "Files" if different files are involved
612
- - Update "Done When" if criteria need adjusting
613
-
614
- 2. **Update `plan.md`** if:
615
- - Adding new tasks (create new task files too)
616
- - Removing tasks (mark as `## Status: cancelled` with reason)
617
- - Changing dependencies
618
-
619
- 3. **Document the change** in the task file:
620
- ```markdown
621
- ## Plan Revision
622
- - Changed: [what changed]
623
- - Reason: [why the original approach didn't work]
624
- - Timestamp: [now]
625
- ```
626
-
627
- 4. **Continue execution** with the revised plan
628
-
629
- **Key principle:** Do NOT keep retrying a broken approach. If something fundamentally doesn't work, adapt the plan. It's better to revise and succeed than to stubbornly fail.
630
-
631
- ---
632
-
633
- ## Shared: Parsing Dependencies
634
-
635
- The plan.md Dependencies section looks like:
636
- ```markdown
637
- ## Dependencies
638
- - 01: []
639
- - 02: [01]
640
- - 03: [01, 02]
641
- ```
642
-
643
- A task is **available** when:
644
- 1. Status is `pending` (or `in-progress` with progress notes)
645
- 2. All tasks in its dependency list have status `done`
646
-
647
- A task is **blocked** when:
648
- 1. Status is `blocked`, OR
649
- 2. Any dependency is not `done` and not expected to complete
650
-
651
- ---
652
-
653
- ## State File (.state)
654
-
655
- Track epic progress in `.lisa/epics/<name>/.state`:
656
-
657
- ```json
658
- {
659
- "name": "<name>",
660
- "currentPhase": "execute",
661
- "specComplete": true,
662
- "researchComplete": true,
663
- "planComplete": true,
664
- "executeComplete": false,
665
- "lastUpdated": "2026-01-16T10:00:00Z"
666
- }
667
- ```
668
-
669
- **With yolo mode active:**
670
- ```json
671
- {
672
- "name": "<name>",
673
- "currentPhase": "execute",
674
- "specComplete": true,
675
- "researchComplete": true,
676
- "planComplete": true,
677
- "executeComplete": false,
678
- "lastUpdated": "2026-01-16T10:00:00Z",
679
- "yolo": {
680
- "active": true,
681
- "iteration": 1,
682
- "maxIterations": 100,
683
- "startedAt": "2026-01-16T10:00:00Z"
684
- }
685
- }
686
- ```
687
-
688
- **Yolo fields:**
689
- - `active`: Set to `true` when yolo mode starts, `false` when complete or stopped
690
- - `iteration`: Current iteration count (plugin increments this on each continuation)
691
- - `maxIterations`: Safety limit. Use the value from config (`yolo.defaultMaxIterations`). Set to 0 for unlimited.
692
- - `startedAt`: ISO timestamp when yolo mode was activated
693
-
694
- Update this file after each phase completes. The Lisa plugin reads this file to determine whether to auto-continue.
695
-
696
- ---
697
-
698
- ## Configuration
699
-
700
- Lisa settings are stored in `.lisa/config.jsonc`. The config is automatically created with safe defaults when you first create an epic.
701
-
702
- **Config locations (merged in order):**
703
- 1. `~/.config/lisa/config.jsonc` - Global user defaults
704
- 2. `.lisa/config.jsonc` - Project settings (commit this)
705
- 3. `.lisa/config.local.jsonc` - Personal overrides (gitignored)
706
-
707
- **Use the `get_lisa_config` tool** to read current config settings.
708
-
709
- **Use the `lisa_config` tool** to view or manage config:
710
- - `lisa_config(action: "view")` - Show current config and sources
711
- - `lisa_config(action: "init")` - Create config if it doesn't exist
712
- - `lisa_config(action: "reset")` - Reset config to defaults
713
-
714
- ### Config Schema
715
-
716
- ```jsonc
717
- {
718
- "execution": {
719
- "maxRetries": 3 // Retries for failed tasks before marking blocked
720
- },
721
- "git": {
722
- "completionMode": "none", // "pr" | "commit" | "none"
723
- "branchPrefix": "epic/", // Branch naming prefix
724
- "autoPush": true // Auto-push when completionMode is "pr"
725
- },
726
- "yolo": {
727
- "defaultMaxIterations": 100 // Default max iterations (0 = unlimited)
728
- }
729
- }
730
- ```
731
-
732
- ### Completion Modes
733
-
734
- The `git.completionMode` setting controls what happens when an epic completes:
735
-
736
- - **`"none"`** (default, safest): No git operations. You manage git entirely.
737
- - **`"commit"`**: Create a branch and commits, but don't push. You handle push/PR.
738
- - **`"pr"`**: Create branch, commits, push, and open a PR via `gh` CLI.
739
-
740
- ---
741
-
742
- ## Epic Completion
743
-
744
- When all tasks are done and the epic is complete, follow this completion flow based on the config:
745
-
746
- ### Step 1: Check config
747
-
748
- Call `get_lisa_config()` to read the current `git.completionMode`.
749
-
750
- ### Step 2: Execute completion based on mode
751
-
752
- **If `git.completionMode` is `"none"`:**
753
- - Update `.state` with `executeComplete: true`
754
- - Report completion to user:
755
- > "Epic complete! All X tasks finished.
756
- >
757
- > Changes have been made but not committed. You can review and commit them manually."
758
-
759
- **If `git.completionMode` is `"commit"`:**
760
- 1. Create a new branch if not already on one:
761
- ```bash
762
- git checkout -b {branchPrefix}{epicName}
763
- ```
764
- 2. Stage and commit all changes:
765
- ```bash
766
- git add -A
767
- git commit -m "feat: {epic goal summary}"
768
- ```
769
- 3. Update `.state` with `executeComplete: true`
770
- 4. Report completion:
771
- > "Epic complete! All X tasks finished.
772
- >
773
- > Changes committed to branch `{branchPrefix}{epicName}`.
774
- > Push and create a PR when ready:
775
- > ```
776
- > git push -u origin {branchPrefix}{epicName}
777
- > gh pr create
778
- > ```"
779
-
780
- **If `git.completionMode` is `"pr"`:**
781
- 1. Create a new branch if not already on one:
782
- ```bash
783
- git checkout -b {branchPrefix}{epicName}
784
- ```
785
- 2. Stage and commit all changes:
786
- ```bash
787
- git add -A
788
- git commit -m "feat: {epic goal summary}"
789
- ```
790
- 3. Check if `gh` CLI is available:
791
- ```bash
792
- which gh
793
- ```
794
- 4. **If `gh` is available and `autoPush` is true:**
795
- ```bash
796
- git push -u origin {branchPrefix}{epicName}
797
- gh pr create --title "{epic goal}" --body "## Summary\n\n{epic description}\n\n## Tasks Completed\n\n{task list}"
798
- ```
799
- Report:
800
- > "Epic complete! All X tasks finished.
801
- >
802
- > PR created: {PR URL}"
803
-
804
- 5. **If `gh` is NOT available:**
805
- Report:
806
- > "Epic complete! All X tasks finished.
807
- >
808
- > Changes committed to branch `{branchPrefix}{epicName}`.
809
- >
810
- > Note: GitHub CLI (`gh`) not found. Install it to enable automatic PR creation:
811
- > - macOS: `brew install gh`
812
- > - Then: `gh auth login`
813
- >
814
- > To create a PR manually:
815
- > ```
816
- > git push -u origin {branchPrefix}{epicName}
817
- > gh pr create
818
- > ```"
819
-
820
- ### Commit Message Format
821
-
822
- Use conventional commits format for the commit message:
823
- - `feat: {epic goal}` for new features
824
- - `fix: {epic goal}` for bug fixes
825
- - `refactor: {epic goal}` for refactoring
826
-
827
- Include a brief body with the tasks completed if helpful.
828
-
829
- ---
830
-
831
- ## First Epic Setup
832
-
833
- When creating the first epic in a project (when `.lisa/` doesn't exist):
834
-
835
- 1. Create `.lisa/` directory
836
- 2. Create `.lisa/config.jsonc` with default settings
837
- 3. Create `.lisa/.gitignore` containing `config.local.jsonc`
838
- 4. Create `.lisa/epics/` directory
839
- 5. Create the epic directory `.lisa/epics/{epicName}/`
840
-
841
- This ensures config is always present with safe defaults.