project-iris 0.0.6 → 0.0.8

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
@@ -14,7 +14,7 @@ mkdir my-project
14
14
  cd my-project
15
15
 
16
16
  # Install IRIS
17
- npx iris@latest install
17
+ npx project-iris@latest install
18
18
  ```
19
19
 
20
20
  The installer will:
@@ -28,19 +28,29 @@ The installer will:
28
28
 
29
29
  ```bash
30
30
  # Check IRIS is working
31
- npx iris --help
32
- npx iris validate
31
+ npx project-iris --help
32
+ npx project-iris validate
33
33
 
34
34
  # Start using IRIS
35
- npx iris ask "scaffold a new login system"
35
+ npx project-iris ask "scaffold a new login system"
36
36
  ```
37
37
 
38
+ > [!IMPORTANT]
39
+ > **Package Name vs Command Name**
40
+ >
41
+ > The npm package is named `project-iris`, but when installed globally, the command is `iris`.
42
+ >
43
+ > - **With npx** (no global install): Use `npx project-iris <command>`
44
+ > - **After global install**: Use `iris <command>`
45
+ >
46
+ > This is why `npx iris` won't work - there's no package named `iris` on npm.
47
+
38
48
  ### For Existing Projects
39
49
 
40
50
  If you already have a `package.json`, just run:
41
51
 
42
52
  ```bash
43
- npx iris@latest install
53
+ npx project-iris@latest install
44
54
  ```
45
55
 
46
56
  IRIS will integrate with your existing project without breaking anything.
@@ -52,12 +62,12 @@ IRIS will integrate with your existing project without breaking anything.
52
62
  For convenience, you can install IRIS globally:
53
63
 
54
64
  ```bash
55
- npm install -g iris@latest
65
+ npm install -g project-iris@latest
56
66
 
57
- # Now use 'iris' directly
58
- iris --version
59
- iris install
60
- iris ask "create a new feature"
67
+ # Now use 'project-iris' directly
68
+ project-iris --version
69
+ project-iris install
70
+ project-iris ask "create a new feature"
61
71
  ```
62
72
 
63
73
  ---
@@ -82,7 +92,7 @@ A standardized documentation structure enforced by Navi. The following minimal b
82
92
  * **`memory-bank/standards/`**: Coding and documentation standards (`README.md` required).
83
93
  * **`memory-bank/operations/`**: Runbooks and maintenance guides (`README.md` required).
84
94
 
85
- Navi ensures these files always exist. If missing, `navi validate` fails. Use `navi validate --fix` to restore them.
95
+ IRIS ensures these files always exist. If missing, `project-iris validate` fails. Use `project-iris validate --fix` to restore them.
86
96
 
87
97
  ---
88
98
 
@@ -92,7 +102,7 @@ Navi ensures these files always exist. If missing, `navi validate` fails. Use `n
92
102
  Don't guess which agent or prompt to use. Just ask IRIS.
93
103
 
94
104
  ```bash
95
- iris ask "I need to fix the auth bug in login"
105
+ project-iris ask "I need to fix the auth bug in login"
96
106
  ```
97
107
  * **Result**: IRIS analyzes `.iris/routes.yaml`, picks the right agent (e.g., `inception` vs `construction`), generates a context pack, and tells you exactly what command to run.
98
108
  * **Artifact**: Creates `.iris/inbox/next.md` with instructions.
@@ -101,7 +111,7 @@ iris ask "I need to fix the auth bug in login"
101
111
  If you just need the context for an agent manually:
102
112
 
103
113
  ```bash
104
- iris pack --agent inception
114
+ project-iris pack --agent inception
105
115
  ```
106
116
  * **Result**: Generates a single Markdown file containing all relevant project context, rules, and active tasks.
107
117
 
@@ -109,29 +119,29 @@ iris pack --agent inception
109
119
  Ensure your project complies with the defined policies (e.g., "Designs must be approved before coding").
110
120
 
111
121
  ```bash
112
- iris validate
122
+ project-iris validate
113
123
  ```
114
124
 
115
125
  **Auto-Fix**: IRIS can repair missing directories and file structures automatically.
116
126
  ```bash
117
- iris validate --fix
127
+ project-iris validate --fix
118
128
  ```
119
129
 
120
130
  **Strict Mode (CI)**:
121
131
  Use strict mode to fail (exit non-zero) on quality warnings (e.g. placeholders, empty files).
122
132
  ```bash
123
- iris validate --strict
133
+ project-iris validate --strict
124
134
  ```
125
135
 
126
136
  ---
127
137
 
128
- ## šŸ¤– Automated Workflows with `iris develop`
138
+ ## šŸ¤– Automated Workflows with `project-iris develop`
129
139
 
130
140
  **NEW**: Automate the complete IRIS workflow from Intent → Bolt Plan → Execution with IDE agent integration.
131
141
 
132
142
  ### Overview
133
143
 
134
- `iris develop` orchestrates the entire IRIS workflow automatically:
144
+ `project-iris develop` orchestrates the entire IRIS workflow automatically:
135
145
  1. **Intent Inception** - Clarifies requirements through questions, generates intent artifacts
136
146
  2. **Bolt Plan** - Creates implementation plan and individual bolt files
137
147
  3. **Bolt Execution** - Executes each bolt (design → implement → test)
@@ -142,10 +152,10 @@ All stages interact with your IDE agent via a bridge protocol, with approval gat
142
152
 
143
153
  ```bash
144
154
  # Terminal 1: Start bridge helper (recommended)
145
- iris bridge run
155
+ project-iris bridge run
146
156
 
147
157
  # Terminal 2: Run workflow
148
- iris develop "Build a dashboard UI to track IRIS progress"
158
+ project-iris develop "Build a dashboard UI to track IRIS progress"
149
159
  ```
150
160
 
151
161
  The workflow will:
@@ -160,27 +170,27 @@ The workflow will:
160
170
 
161
171
  **Basic workflow:**
162
172
  ```bash
163
- iris develop "Your intent description"
173
+ project-iris develop "Your intent description"
164
174
  ```
165
175
 
166
176
  **Resume interrupted workflow:**
167
177
  ```bash
168
- iris develop --resume <runId>
178
+ project-iris develop --resume <runId>
169
179
  ```
170
180
 
171
181
  **Auto-approve gates (no prompts):**
172
182
  ```bash
173
- iris develop --gate auto "Your intent"
183
+ project-iris develop --gate auto "Your intent"
174
184
  ```
175
185
 
176
186
  **Override IDE selection:**
177
187
  ```bash
178
- iris develop --ide cursor "Your intent"
188
+ project-iris develop --ide cursor "Your intent"
179
189
  ```
180
190
 
181
191
  **No-bridge mode (manual result creation):**
182
192
  ```bash
183
- iris develop --no-bridge "Your intent"
193
+ project-iris develop --no-bridge "Your intent"
184
194
  ```
185
195
 
186
196
  ### Bridge Helper
@@ -189,12 +199,12 @@ The bridge helper watches for workflow tasks and opens them in your IDE:
189
199
 
190
200
  **Start the helper:**
191
201
  ```bash
192
- iris bridge run
202
+ project-iris bridge run
193
203
  ```
194
204
 
195
205
  **Check bridge status:**
196
206
  ```bash
197
- iris bridge status
207
+ project-iris bridge status
198
208
  ```
199
209
 
200
210
  The helper will:
@@ -281,12 +291,12 @@ cat .iris/runs/<runId>.md
281
291
 
282
292
  **Bridge helper not finding tasks:**
283
293
  - Check `.iris/bridge/inbox/` for task files
284
- - Ensure bridge helper is running (`navi bridge run`)
294
+ - Ensure bridge helper is running (`iris bridge run`)
285
295
 
286
296
  **IDE not opening automatically:**
287
297
  - Verify IDE CLI is available (`which cursor`, `which code`)
288
298
  - Use `--no-bridge` mode and open files manually
289
- - Check `navi bridge status` for connector info
299
+ - Check `iris bridge status` for connector info
290
300
 
291
301
  **Workflow stuck waiting:**
292
302
  - Create result file manually in `.iris/bridge/outbox/<taskId>.json`
@@ -308,7 +318,7 @@ cat .iris/runs/<runId>.md
308
318
  * **`pack`**: focused context bundle generator.
309
319
  * `--agent <name>`: Target specific agent context.
310
320
  * `--auth`: Include sensitive rules (optional).
311
- * **`run <workflow>`**: Execute a named workflow (e.g., `npm run navi run deploy`).
321
+ * **`run <workflow>`**: Execute a named workflow (e.g., `iris run deploy`).
312
322
  * **`develop [intent]`**: **NEW** - Automated workflow orchestration (Intent → Bolt Plan → Execution).
313
323
  * `--resume <runId>`: Resume interrupted workflow.
314
324
  * `--ide <ideId>`: Override IDE selection.
@@ -339,7 +349,7 @@ This section is for developers who want to contribute to IRIS itself (not for us
339
349
  ```bash
340
350
  # Clone the repository
341
351
  git clone <repo-url>
342
- cd iris-beta
352
+ cd project-iris
343
353
 
344
354
  # Install dependencies
345
355
  npm ci
@@ -1,5 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
+ import { processInboxTasks } from "./helper.js";
4
+ import { getSelectedIde } from "../iris/state.js";
3
5
  const BRIDGE_DIR = path.join(process.cwd(), ".iris/bridge");
4
6
  const INBOX_DIR = path.join(BRIDGE_DIR, "inbox");
5
7
  const OUTBOX_DIR = path.join(BRIDGE_DIR, "outbox");
@@ -27,10 +29,6 @@ export class FilesystemBridgeConnector {
27
29
  await this.ensureRunning();
28
30
  const inboxPath = path.join(INBOX_DIR, `${packet.taskId}.json`);
29
31
  fs.writeFileSync(inboxPath, JSON.stringify(packet, null, 2), "utf8");
30
- // Also create a human-readable prompt file
31
- const promptPath = path.join(STATE_DIR, `${packet.taskId}.md`);
32
- const promptContent = this.generatePrompt(packet);
33
- fs.writeFileSync(promptPath, promptContent, "utf8");
34
32
  return { taskId: packet.taskId };
35
33
  }
36
34
  async waitResult(taskId, opts) {
@@ -38,7 +36,9 @@ export class FilesystemBridgeConnector {
38
36
  const pollIntervalMs = opts?.pollIntervalMs || 1000; // 1 second
39
37
  const outboxPath = path.join(OUTBOX_DIR, `${taskId}.json`);
40
38
  const startTime = Date.now();
39
+ const processedTasks = new Set(); // Track state for this wait cycle
41
40
  while (Date.now() - startTime < timeoutMs) {
41
+ // Check for result logic...
42
42
  if (fs.existsSync(outboxPath)) {
43
43
  const content = fs.readFileSync(outboxPath, "utf8");
44
44
  const result = JSON.parse(content);
@@ -50,6 +50,11 @@ export class FilesystemBridgeConnector {
50
50
  }
51
51
  return result;
52
52
  }
53
+ // AUTO-BRIDGE: Act as the bridge while waiting
54
+ const ideId = getSelectedIde();
55
+ if (ideId) {
56
+ await processInboxTasks(ideId, processedTasks, false);
57
+ }
53
58
  // Wait before next poll
54
59
  await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
55
60
  }
@@ -0,0 +1,203 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import kleur from "kleur";
4
+ import { execSync } from "child_process";
5
+ import { getSelectedIde } from "../iris/state.js";
6
+ const BRIDGE_DIR = path.join(process.cwd(), ".iris/bridge");
7
+ export const INBOX_DIR = path.join(BRIDGE_DIR, "inbox");
8
+ export const OUTBOX_DIR = path.join(BRIDGE_DIR, "outbox");
9
+ export const STATE_DIR = path.join(BRIDGE_DIR, "state");
10
+ /**
11
+ * Start the bridge helper loop
12
+ */
13
+ /**
14
+ * Start the bridge helper loop
15
+ */
16
+ export async function startBridgeHelper(options = {}) {
17
+ const { pollInterval = 2000, verbose = false, stopSignal } = options;
18
+ if (verbose) {
19
+ console.log(kleur.bold("IRIS Bridge Helper"));
20
+ console.log(kleur.dim("Watching for workflow tasks...\n"));
21
+ }
22
+ const ideId = getSelectedIde();
23
+ if (!ideId) {
24
+ if (verbose)
25
+ console.error(kleur.red("No IDE selected. Run 'iris install' first."));
26
+ return;
27
+ }
28
+ if (verbose) {
29
+ console.log(kleur.gray(`IDE: ${ideId}`));
30
+ console.log(kleur.gray(`Inbox: ${INBOX_DIR}`));
31
+ console.log(kleur.gray(`Polling: every ${pollInterval}ms\n`));
32
+ }
33
+ ensureBridgeDirs();
34
+ const processedTasks = new Set();
35
+ let running = true;
36
+ while (running) {
37
+ if (stopSignal && stopSignal()) {
38
+ running = false;
39
+ break;
40
+ }
41
+ await processInboxTasks(ideId, processedTasks, verbose);
42
+ if (options.runOnce) {
43
+ running = false;
44
+ }
45
+ else {
46
+ await new Promise(resolve => setTimeout(resolve, pollInterval));
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * Process all tasks in the inbox once
52
+ */
53
+ export async function processInboxTasks(ideId, processedTasks, verbose = false) {
54
+ try {
55
+ // Ensure dirs exist (safe to call repeatedly)
56
+ if (!fs.existsSync(INBOX_DIR))
57
+ return;
58
+ const files = fs.readdirSync(INBOX_DIR);
59
+ const taskFiles = files.filter(f => f.endsWith(".json"));
60
+ for (const file of taskFiles) {
61
+ const taskId = file.replace(".json", "");
62
+ if (processedTasks.has(taskId))
63
+ continue;
64
+ // Allow check against outbox to skip already completed tasks
65
+ if (fs.existsSync(path.join(OUTBOX_DIR, `${taskId}.json`))) {
66
+ processedTasks.add(taskId);
67
+ continue;
68
+ }
69
+ if (verbose)
70
+ console.log(kleur.cyan(`\n→ New task: ${taskId}`));
71
+ const taskPath = path.join(INBOX_DIR, file);
72
+ let task;
73
+ try {
74
+ task = JSON.parse(fs.readFileSync(taskPath, "utf8"));
75
+ }
76
+ catch (e) {
77
+ if (verbose)
78
+ console.error(`Failed to parse task ${taskId}`, e);
79
+ continue;
80
+ }
81
+ const promptPath = path.join(STATE_DIR, `${taskId}.md`);
82
+ if (!fs.existsSync(promptPath)) {
83
+ const prompt = generatePrompt(task);
84
+ fs.writeFileSync(promptPath, prompt, "utf8");
85
+ if (verbose)
86
+ console.log(kleur.dim(` Prompt: ${promptPath}`));
87
+ }
88
+ const opened = await tryOpenInIDE(ideId, promptPath);
89
+ if (verbose) {
90
+ if (opened)
91
+ console.log(kleur.green(` āœ“ Opened in ${ideId}`));
92
+ else {
93
+ console.log(kleur.yellow(` ⚠ Could not auto-open. Please open manually:`));
94
+ console.log(kleur.dim(` ${promptPath}`));
95
+ }
96
+ console.log(kleur.dim(` Waiting for result in: ${OUTBOX_DIR}/${taskId}.json`));
97
+ }
98
+ processedTasks.add(taskId);
99
+ }
100
+ }
101
+ catch (error) {
102
+ if (verbose)
103
+ console.error(kleur.red(`Error: ${error.message}`));
104
+ }
105
+ }
106
+ export function ensureBridgeDirs() {
107
+ for (const dir of [INBOX_DIR, OUTBOX_DIR, STATE_DIR]) {
108
+ if (!fs.existsSync(dir)) {
109
+ fs.mkdirSync(dir, { recursive: true });
110
+ }
111
+ }
112
+ }
113
+ function generatePrompt(task) {
114
+ return `# IRIS Workflow Task
115
+
116
+ **Task ID:** ${task.taskId}
117
+ **Stage:** ${task.stage}
118
+ **Agent:** ${task.agent}
119
+
120
+ ## Intent
121
+
122
+ ${task.intent}
123
+
124
+ ## Instructions
125
+
126
+ ${task.instructions}
127
+
128
+ ## Input Files
129
+
130
+ ${task.inputs && task.inputs.length > 0
131
+ ? task.inputs.map((p) => `- [\`${path.basename(p)}\`](file://${path.resolve(p)})`).join("\n")
132
+ : "*No input files*"}
133
+
134
+ ## Expected Outputs
135
+
136
+ ${task.expectedOutputs && task.expectedOutputs.length > 0
137
+ ? task.expectedOutputs.map((p) => `- \`${p}\``).join("\n")
138
+ : "*No specific outputs required*"}
139
+
140
+ ${task.gates ? `\n## Gates\n\n${task.gates.join("\n")}\n` : ""}
141
+
142
+ ---
143
+
144
+ **When complete, create a result file at:**
145
+ \`.iris/bridge/outbox/${task.taskId}.json\`
146
+
147
+ **Result format:**
148
+ \`\`\`json
149
+ {
150
+ "taskId": "${task.taskId}",
151
+ "status": "ok" | "needs_user" | "error",
152
+ "message": "Description of what was done or questions/errors",
153
+ "filesChanged": ["path/to/file1.md", "path/to/file2.md"],
154
+ "logs": ["Optional log messages"]
155
+ }
156
+ \`\`\`
157
+ `;
158
+ }
159
+ async function tryOpenInIDE(ideId, filePath) {
160
+ try {
161
+ switch (ideId.toLowerCase()) {
162
+ case "cursor":
163
+ execSync(`cursor "${filePath}"`, { stdio: "ignore" });
164
+ return true;
165
+ case "vscode":
166
+ case "code":
167
+ execSync(`code "${filePath}"`, { stdio: "ignore" });
168
+ return true;
169
+ case "antigravity":
170
+ case "gemini":
171
+ try {
172
+ execSync(`code "${filePath}"`, { stdio: "ignore" });
173
+ return true;
174
+ }
175
+ catch { }
176
+ break;
177
+ case "windsurf":
178
+ try {
179
+ execSync(`windsurf "${filePath}"`, { stdio: "ignore" });
180
+ return true;
181
+ }
182
+ catch { }
183
+ break;
184
+ }
185
+ const platform = process.platform;
186
+ if (platform === "darwin") {
187
+ execSync(`open "${filePath}"`, { stdio: "ignore" });
188
+ return true;
189
+ }
190
+ else if (platform === "win32") {
191
+ execSync(`start "" "${filePath}"`, { stdio: "ignore" });
192
+ return true;
193
+ }
194
+ else if (platform === "linux") {
195
+ execSync(`xdg-open "${filePath}"`, { stdio: "ignore" });
196
+ return true;
197
+ }
198
+ return false;
199
+ }
200
+ catch (error) {
201
+ return false;
202
+ }
203
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Bridge types for navi develop workflow
2
+ * Bridge types for iris develop workflow
3
3
  */
4
4
  export var WorkflowStage;
5
5
  (function (WorkflowStage) {
package/dist/cli.js CHANGED
@@ -15,7 +15,7 @@ const program = new Command();
15
15
  program
16
16
  .name("iris")
17
17
  .description("IRIS CLI - Intelligent Repository for Intent-driven Systems")
18
- .version("0.0.06")
18
+ .version("0.0.08")
19
19
  .addCommand(installCommand)
20
20
  .addCommand(uninstallCommand)
21
21
  .addCommand(phaseCommand)
@@ -1,17 +1,20 @@
1
1
  import { Command } from "commander";
2
2
  import inquirer from "inquirer";
3
3
  import kleur from "kleur";
4
- import path from "path";
5
4
  import fs from "fs";
6
- import { repoRoot, writeFile, ensureDir } from "../lib.js";
5
+ import { repoRoot } from "../lib.js";
7
6
  import { getIrisDebugInfo } from "../iris/resolver.js";
8
7
  import { loadRoutes } from "../iris/routes.js";
9
8
  import { routeIntent } from "../iris/router.js";
10
- import { generatePack } from "../iris/packer.js";
11
9
  import { checkArtifact } from "../iris/artifact-checker.js";
12
10
  import { loadPolicy } from "../iris/policy.js";
13
11
  import { loadState } from "../iris/state.js";
14
12
  import { EXIT_CODES } from "../utils/exit-codes.js";
13
+ import { createConnector } from "../bridge/connector-factory.js";
14
+ import { getSelectedIde } from "../iris/state.js";
15
+ import { executeIntentInception } from "../workflows/intent-inception.js";
16
+ import { executeBoltPlan } from "../workflows/bolt-plan.js";
17
+ import { createRun } from "../iris/run-state.js";
15
18
  export const askCommand = new Command("ask")
16
19
  .description("Route intent to an agent and generate context pack")
17
20
  .argument("[intent...]", "Natural language request intent")
@@ -77,146 +80,43 @@ export const askCommand = new Command("ask")
77
80
  // 2. Load Routes
78
81
  const routesConfig = loadRoutes();
79
82
  if (!routesConfig) {
80
- console.error(kleur.red("Routes not found. Run `navi install` or create .iris/routes.yaml"));
83
+ console.error(kleur.red("Routes not found. Run `iris install` or create .iris/routes.yaml"));
81
84
  process.exit(EXIT_CODES.POLICY_ERROR);
82
85
  }
83
86
  // 3. Route
84
87
  const routing = routeIntent(intent, routesConfig);
85
88
  const routeId = routing.route === "default" ? "default" : routing.route.route_id;
86
- // 4. Decide Context
87
- let agent = opts.agent;
88
- let phase = opts.phase;
89
- let command = "";
90
- if (routing.route === "default") {
91
- if (!agent)
92
- agent = routesConfig.default.agent;
93
- if (!phase)
94
- phase = routesConfig.default.phase;
95
- command = routesConfig.default.command;
96
- }
97
- else {
98
- const selectedRoute = routing.route;
99
- // If agent missing in route, try to infer or fallback
100
- if (!agent)
101
- agent = selectedRoute.agent || inferAgentFromPhase(selectedRoute.phase);
102
- if (!phase)
103
- phase = selectedRoute.phase ? selectedRoute.phase.toLowerCase() : "";
104
- command = selectedRoute.command;
105
- }
106
- // Fallback inference if agent is still missing (e.g. default route missing fields)
107
- if (!agent && command) {
108
- if (command.includes("inception"))
109
- agent = "inception";
110
- else if (command.includes("construction"))
111
- agent = "construction";
112
- else if (command.includes("operations"))
113
- agent = "operations";
114
- else if (command.includes("master"))
115
- agent = "master";
116
- }
117
- // Override command logic if agent/phase changed via flags
118
- if (opts.agent) {
119
- switch (opts.agent) {
120
- case "master":
121
- command = "/iris-master-agent";
122
- break;
123
- case "inception":
124
- command = "/iris-inception-agent";
125
- break;
126
- case "construction":
127
- command = "/iris-construction-agent";
128
- break;
129
- case "operations":
130
- command = "/iris-operations-agent";
131
- break;
132
- }
133
- }
134
- // 5. Pack
135
- let packPath = "";
136
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
137
- if (opts.out) {
138
- packPath = opts.out;
139
- }
140
- else {
141
- packPath = path.join(root, `.iris/inbox/context-pack.${agent}.${phase}.${timestamp}.md`);
142
- }
143
- if (!opts.dryRun) {
144
- try {
145
- await generatePack({
146
- agent,
147
- phase,
148
- output: opts.stdout ? undefined : packPath,
149
- stdout: opts.stdout,
150
- strict: false
151
- });
152
- }
153
- catch (e) {
154
- console.error("Packing failed:", e);
155
- process.exit(EXIT_CODES.INVALID);
156
- }
157
- }
158
- // 6. Write Next Action
159
- const nextPath = path.join(root, ".iris/inbox/next.md");
160
- const nextHistoryPath = path.join(root, `.iris/inbox/next.${timestamp}.md`);
161
- const nextContent = `# IRIS Next Action
162
-
163
- ## Intent
164
- ${intent}
165
-
166
- ## Routing Decision
167
- - Route: ${routeId}
168
- - Agent: ${agent}
169
- - Phase: ${phase}
170
- - Command: ${command}
171
- - Score: ${routing.score}
172
- - Matched: ${routing.matches.join(", ")}
173
- ${routing.excludedBy ? `- Excluded By: ${routing.excludedBy}` : ""}
174
-
175
- ## Context Pack
176
- - Path: ${opts.stdout ? "(stdout)" : path.relative(root, packPath)}
177
- - Generated: ${new Date().toISOString()}
178
-
179
- ## Do this now
180
- 1) Open your IDE agent tool
181
- 2) Run: \`${command}\`
182
- 3) Provide the context pack at: \`${opts.stdout ? "(stdout)" : path.relative(root, packPath)}\`
183
-
184
- ## Notes
185
- - If validation fails, run: \`navi validate\`
186
- `;
187
- if (!opts.dryRun) {
188
- ensureDir(path.dirname(nextPath));
189
- writeFile(nextPath, nextContent);
190
- writeFile(nextHistoryPath, nextContent);
191
- }
192
- // 7. Output
193
- if (opts.json) {
194
- console.log(JSON.stringify({
195
- intent,
196
- route: routeId,
197
- agent,
198
- phase,
199
- command,
200
- score: routing.score,
201
- matches: routing.matches,
202
- pack_path: opts.stdout ? null : packPath,
203
- next_path: nextPath
204
- }, null, 2));
205
- }
206
- else if (!opts.stdout) {
89
+ // 4. Execution Workflow (Inception + Planning)
90
+ console.log(kleur.bold("Starting IRIS Inception & Planning"));
91
+ console.log(kleur.dim("This process will clarify your intent and generate an implementation plan.\n"));
92
+ // Initialize Bridge/IDE
93
+ const ideId = getSelectedIde() || "antigravity"; // Default or prompt?
94
+ // If not selected, we might want to prompt, but for now fallback to antigravity or error?
95
+ // The bridge helper handles "run 'iris install'" error.
96
+ // Create new run
97
+ const runState = createRun(intent, ideId, "manual");
98
+ const connector = createConnector(ideId);
99
+ try {
100
+ // Phase 1: Inception (Clarify + Artifacts)
101
+ await executeIntentInception(runState, connector, {
102
+ gate: "manual",
103
+ noBridge: false
104
+ });
105
+ // Phase 2: Bolt Plan (Stories -> Bolts)
106
+ await executeBoltPlan(runState, connector, {
107
+ gate: "manual",
108
+ noBridge: false
109
+ });
207
110
  console.log("");
208
- console.log(kleur.bold("Routing: ") + kleur.cyan(routeId) + kleur.dim(` (conf: ${routing.score})`));
209
- console.log(kleur.bold("Command: ") + kleur.green(command));
210
- if (opts.dryRun) {
211
- console.log(kleur.yellow("[DRY RUN] No files written."));
212
- console.log(`Would satisfy intent '${intent}' with agent ${agent}.`);
213
- }
214
- else {
215
- console.log(kleur.bold("Context: ") + kleur.gray(path.relative(root, packPath)));
216
- console.log(kleur.bold("Next: ") + kleur.gray(path.relative(root, nextPath)));
217
- }
111
+ console.log(kleur.bold(kleur.green("āœ“ Plan Created Successfully!")));
112
+ console.log("To start execution, run:");
113
+ console.log(kleur.cyan(` iris develop --resume ${runState.runId}`));
218
114
  console.log("");
219
115
  }
116
+ catch (error) {
117
+ console.error(kleur.red(`\nāœ— Planning Failed: ${error.message}`));
118
+ process.exit(1);
119
+ }
220
120
  });
221
121
  function inferAgentFromPhase(phase) {
222
122
  if (!phase)