project-iris 0.0.12 → 0.0.14

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 (189) hide show
  1. package/README.md +214 -323
  2. package/bin/cli.js +21 -0
  3. package/flows/aidlc/README.md +372 -0
  4. package/flows/aidlc/agents/construction-agent.md +79 -0
  5. package/flows/aidlc/agents/inception-agent.md +97 -0
  6. package/flows/aidlc/agents/master-agent.md +61 -0
  7. package/flows/aidlc/agents/operations-agent.md +89 -0
  8. package/flows/aidlc/commands/construction-agent.md +63 -0
  9. package/flows/aidlc/commands/inception-agent.md +55 -0
  10. package/flows/aidlc/commands/master-agent.md +47 -0
  11. package/flows/aidlc/commands/operations-agent.md +77 -0
  12. package/flows/aidlc/context-config.yaml +67 -0
  13. package/flows/aidlc/memory-bank.yaml +104 -0
  14. package/flows/aidlc/quick-start.md +322 -0
  15. package/flows/aidlc/skills/construction/bolt-list.md +163 -0
  16. package/flows/aidlc/skills/construction/bolt-replan.md +345 -0
  17. package/flows/aidlc/skills/construction/bolt-start.md +442 -0
  18. package/flows/aidlc/skills/construction/bolt-status.md +185 -0
  19. package/flows/aidlc/skills/construction/navigator.md +196 -0
  20. package/flows/aidlc/skills/inception/bolt-plan.md +372 -0
  21. package/flows/aidlc/skills/inception/context.md +171 -0
  22. package/flows/aidlc/skills/inception/intent-create.md +211 -0
  23. package/flows/aidlc/skills/inception/intent-list.md +124 -0
  24. package/flows/aidlc/skills/inception/navigator.md +207 -0
  25. package/flows/aidlc/skills/inception/requirements.md +227 -0
  26. package/flows/aidlc/skills/inception/review.md +248 -0
  27. package/flows/aidlc/skills/inception/story-create.md +304 -0
  28. package/flows/aidlc/skills/inception/units.md +278 -0
  29. package/flows/aidlc/skills/master/analyze-context.md +239 -0
  30. package/flows/aidlc/skills/master/answer-question.md +141 -0
  31. package/flows/aidlc/skills/master/explain-flow.md +158 -0
  32. package/flows/aidlc/skills/master/project-init.md +281 -0
  33. package/flows/aidlc/skills/master/route-request.md +126 -0
  34. package/flows/aidlc/skills/operations/build.md +237 -0
  35. package/flows/aidlc/skills/operations/deploy.md +259 -0
  36. package/flows/aidlc/skills/operations/monitor.md +265 -0
  37. package/flows/aidlc/skills/operations/navigator.md +209 -0
  38. package/flows/aidlc/skills/operations/verify.md +224 -0
  39. package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt.md +3 -3
  40. package/{dist → flows/aidlc}/templates/construction/bolt-types/spike-bolt.md +2 -2
  41. package/flows/aidlc/templates/construction/construction-log-template.md +129 -0
  42. package/flows/aidlc/templates/construction/standards/coding-standards.md +29 -0
  43. package/flows/aidlc/templates/construction/standards/system-architecture.md +22 -0
  44. package/flows/aidlc/templates/construction/standards/tech-stack.md +19 -0
  45. package/flows/aidlc/templates/inception/inception-log-template.md +134 -0
  46. package/flows/aidlc/templates/inception/project/README.md +55 -0
  47. package/flows/aidlc/templates/standards/catalog.yaml +345 -0
  48. package/flows/aidlc/templates/standards/coding-standards.guide.md +553 -0
  49. package/flows/aidlc/templates/standards/data-stack.guide.md +162 -0
  50. package/flows/aidlc/templates/standards/tech-stack.guide.md +280 -0
  51. package/lib/InstallerFactory.js +36 -0
  52. package/lib/analytics/env-detector.js +92 -0
  53. package/lib/analytics/index.js +22 -0
  54. package/lib/analytics/machine-id.js +33 -0
  55. package/lib/analytics/tracker.js +232 -0
  56. package/lib/cli-utils.js +342 -0
  57. package/lib/constants.js +32 -0
  58. package/lib/installer.js +402 -0
  59. package/lib/installers/AntigravityInstaller.js +22 -0
  60. package/lib/installers/ClaudeInstaller.js +85 -0
  61. package/lib/installers/ClineInstaller.js +21 -0
  62. package/lib/installers/CodexInstaller.js +21 -0
  63. package/lib/installers/CopilotInstaller.js +113 -0
  64. package/lib/installers/CursorInstaller.js +63 -0
  65. package/lib/installers/GeminiInstaller.js +75 -0
  66. package/lib/installers/KiroInstaller.js +22 -0
  67. package/lib/installers/OpenCodeInstaller.js +22 -0
  68. package/lib/installers/RooInstaller.js +22 -0
  69. package/lib/installers/ToolInstaller.js +73 -0
  70. package/lib/installers/WindsurfInstaller.js +22 -0
  71. package/lib/markdown-validator.ts +175 -0
  72. package/lib/yaml-validator.ts +99 -0
  73. package/package.json +105 -32
  74. package/scripts/artifact-validator.js +594 -0
  75. package/scripts/bolt-complete.js +606 -0
  76. package/scripts/status-integrity.js +598 -0
  77. package/dist/bridge/agent-runner.js +0 -190
  78. package/dist/bridge/connector-factory.js +0 -31
  79. package/dist/bridge/connectors/antigravity-connector.js +0 -18
  80. package/dist/bridge/connectors/cursor-connector.js +0 -31
  81. package/dist/bridge/connectors/in-process-connector.js +0 -29
  82. package/dist/bridge/connectors/vscode-connector.js +0 -31
  83. package/dist/bridge/connectors/windsurf-connector.js +0 -23
  84. package/dist/bridge/filesystem-connector.js +0 -110
  85. package/dist/bridge/helper.js +0 -203
  86. package/dist/bridge/types.js +0 -10
  87. package/dist/cli.js +0 -40
  88. package/dist/commands/ask.js +0 -259
  89. package/dist/commands/bridge.js +0 -88
  90. package/dist/commands/create.js +0 -25
  91. package/dist/commands/develop.js +0 -141
  92. package/dist/commands/doctor.js +0 -102
  93. package/dist/commands/flow.js +0 -301
  94. package/dist/commands/framework.js +0 -273
  95. package/dist/commands/generate.js +0 -59
  96. package/dist/commands/install.js +0 -100
  97. package/dist/commands/pack.js +0 -33
  98. package/dist/commands/phase.js +0 -38
  99. package/dist/commands/run.js +0 -199
  100. package/dist/commands/status.js +0 -114
  101. package/dist/commands/uninstall.js +0 -14
  102. package/dist/commands/use.js +0 -20
  103. package/dist/commands/validate.js +0 -102
  104. package/dist/framework/framework-loader.js +0 -97
  105. package/dist/framework/framework-paths.js +0 -48
  106. package/dist/framework/framework-types.js +0 -15
  107. package/dist/iris/artifact-checker.js +0 -78
  108. package/dist/iris/artifacts/config.js +0 -68
  109. package/dist/iris/artifacts/generator.js +0 -88
  110. package/dist/iris/artifacts/types.js +0 -1
  111. package/dist/iris/bundle.js +0 -44
  112. package/dist/iris/doctrine/collector.js +0 -124
  113. package/dist/iris/fixer.js +0 -149
  114. package/dist/iris/flows/manifest.js +0 -124
  115. package/dist/iris/framework-context.js +0 -49
  116. package/dist/iris/framework-manager.js +0 -215
  117. package/dist/iris/fs/atomic.js +0 -22
  118. package/dist/iris/guard.js +0 -38
  119. package/dist/iris/importers/index.js +0 -9
  120. package/dist/iris/importers/types.js +0 -8
  121. package/dist/iris/importers/writer.js +0 -139
  122. package/dist/iris/include.js +0 -49
  123. package/dist/iris/installer.js +0 -334
  124. package/dist/iris/interactive/env.js +0 -21
  125. package/dist/iris/interactive/intent-interview.js +0 -345
  126. package/dist/iris/interactive/intent-schema.js +0 -28
  127. package/dist/iris/interactive/interview-io.js +0 -22
  128. package/dist/iris/interview/config.js +0 -71
  129. package/dist/iris/interview/types.js +0 -16
  130. package/dist/iris/interview/utils.js +0 -38
  131. package/dist/iris/manifest.js +0 -54
  132. package/dist/iris/packer.js +0 -325
  133. package/dist/iris/parsers/unit-parser.js +0 -43
  134. package/dist/iris/paths.js +0 -18
  135. package/dist/iris/policy.js +0 -133
  136. package/dist/iris/proc.js +0 -56
  137. package/dist/iris/report.js +0 -53
  138. package/dist/iris/resolver.js +0 -66
  139. package/dist/iris/router.js +0 -114
  140. package/dist/iris/routes.js +0 -189
  141. package/dist/iris/run-state.js +0 -146
  142. package/dist/iris/state.js +0 -113
  143. package/dist/iris/templates.js +0 -70
  144. package/dist/iris/tmp.js +0 -24
  145. package/dist/iris/uninstaller.js +0 -181
  146. package/dist/iris/utils/interpolate.js +0 -42
  147. package/dist/iris/validator.js +0 -391
  148. package/dist/iris/workflow/config.js +0 -51
  149. package/dist/iris/workflow/engine.js +0 -129
  150. package/dist/iris/workflow/steps.js +0 -448
  151. package/dist/iris/workflow/types.js +0 -1
  152. package/dist/iris_bundle/frameworks/iris-core/framework.yaml +0 -9
  153. package/dist/iris_bundle/frameworks/iris-core/memory/memory-bank.yaml +0 -1
  154. package/dist/iris_bundle/frameworks/iris-core/policy.yaml +0 -7
  155. package/dist/iris_bundle/frameworks/iris-core/templates/config/memory-bank.yaml +0 -1
  156. package/dist/iris_bundle/frameworks/iris-core/templates/construction/bolt-types/spike-bolt.md +0 -240
  157. package/dist/lib.js +0 -96
  158. package/dist/templates/construction/bolt-template.md +0 -226
  159. package/dist/templates/construction/bolt-types/ddd-construction-bolt/adr-template.md +0 -49
  160. package/dist/templates/construction/bolt-types/ddd-construction-bolt/ddd-01-domain-model-template.md +0 -55
  161. package/dist/templates/construction/bolt-types/ddd-construction-bolt/ddd-02-technical-design-template.md +0 -67
  162. package/dist/templates/construction/bolt-types/ddd-construction-bolt/ddd-03-test-report-template.md +0 -62
  163. package/dist/templates/construction/bolt-types/ddd-construction-bolt.md +0 -528
  164. package/dist/templates/construction/bolt-types/simple-construction-bolt.md +0 -347
  165. package/dist/templates/inception/requirements-template.md +0 -144
  166. package/dist/templates/inception/stories-template.md +0 -38
  167. package/dist/templates/inception/story-template.md +0 -147
  168. package/dist/templates/inception/system-context-template.md +0 -29
  169. package/dist/templates/inception/unit-brief-template.md +0 -177
  170. package/dist/templates/inception/units-template.md +0 -52
  171. package/dist/utils/exit-codes.js +0 -7
  172. package/dist/utils/logo.js +0 -17
  173. package/dist/workflows/bolt-execution.js +0 -238
  174. package/dist/workflows/bolt-plan.js +0 -221
  175. package/dist/workflows/intent-inception.js +0 -285
  176. package/dist/workflows/memory-bank-generator.js +0 -180
  177. package/dist/workflows/reporting.js +0 -74
  178. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-template.md +0 -0
  179. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt/adr-template.md +0 -0
  180. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt/ddd-01-domain-model-template.md +0 -0
  181. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt/ddd-02-technical-design-template.md +0 -0
  182. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt/ddd-03-test-report-template.md +0 -0
  183. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/simple-construction-bolt.md +0 -0
  184. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/requirements-template.md +0 -0
  185. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/stories-template.md +0 -0
  186. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/story-template.md +0 -0
  187. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/system-context-template.md +0 -0
  188. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/unit-brief-template.md +0 -0
  189. /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/units-template.md +0 -0
@@ -1,190 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import kleur from "kleur";
4
- import { INBOX_DIR, OUTBOX_DIR } from "./helper.js";
5
- export async function startAgentRunner(options = {}) {
6
- const pollInterval = options.pollInterval || 2000;
7
- const verbose = options.verbose !== false;
8
- console.log(kleur.bold("🤖 IRIS Automated Agent Started"));
9
- console.log(kleur.dim(` Watching: ${INBOX_DIR}`));
10
- console.log(kleur.dim(` Answering to: ${OUTBOX_DIR}\n`));
11
- // Ensure directories
12
- fs.mkdirSync(INBOX_DIR, { recursive: true });
13
- fs.mkdirSync(OUTBOX_DIR, { recursive: true });
14
- const processed = new Set();
15
- // Polling Loop
16
- setInterval(async () => {
17
- try {
18
- const files = fs.readdirSync(INBOX_DIR).filter(f => f.endsWith(".json"));
19
- for (const file of files) {
20
- if (processed.has(file))
21
- continue;
22
- const filePath = path.join(INBOX_DIR, file);
23
- try {
24
- const content = fs.readFileSync(filePath, "utf8");
25
- const task = JSON.parse(content);
26
- processed.add(file);
27
- const outPath = path.join(OUTBOX_DIR, file);
28
- if (fs.existsSync(outPath)) {
29
- processed.add(file);
30
- continue;
31
- }
32
- if (verbose) {
33
- console.log(kleur.cyan(`\n[Active] Processing task: ${task.taskId}`));
34
- console.log(kleur.dim(` Stage: ${task.stage}`));
35
- console.log(kleur.dim(` Intent: ${task.intent}`));
36
- }
37
- // Think...
38
- await new Promise(r => setTimeout(r, 1000)); // Simulate latency
39
- // Handle
40
- const result = await handleTask(task);
41
- // Respond
42
- fs.writeFileSync(outPath, JSON.stringify(result, null, 2));
43
- console.log(kleur.green(` ✓ Responded to ${task.taskId}`));
44
- }
45
- catch (err) {
46
- console.error(kleur.red(` ✗ Failed to process ${file}: ${err.message}`));
47
- }
48
- }
49
- }
50
- catch (e) {
51
- // Ignore read errors
52
- }
53
- }, pollInterval);
54
- }
55
- // Heuristic Intelligence
56
- export async function handleTask(task) {
57
- // 1. Intent Inception (Ping-Pong)
58
- if (task.stage === "INTENT_INCEPTION" && task.metadata?.step === "clarify_turn") {
59
- return handleClarification(task);
60
- }
61
- // 2. Artifact Generation
62
- if (task.stage === "INTENT_INCEPTION" && task.metadata?.step === "generate_artifacts") {
63
- return handleArtifactGeneration(task);
64
- }
65
- // 3. Bolt Plan
66
- if (task.stage === "BOLT_PLAN" && task.metadata?.step === "generate_bolt_plan") {
67
- return handleBoltPlan(task);
68
- }
69
- // Default fallback
70
- return {
71
- taskId: task.taskId,
72
- status: "ok",
73
- message: "DONE",
74
- filesChanged: []
75
- };
76
- }
77
- function handleClarification(task) {
78
- const instructions = task.instructions || "";
79
- const historyLines = instructions.split("\n").filter(l => l.trim().startsWith("Q:"));
80
- const turnCount = historyLines.length;
81
- let message = "DONE";
82
- // Simple Script
83
- if (turnCount === 0) {
84
- message = "\"Who is the primary user for this application?\"";
85
- }
86
- else if (turnCount === 1) {
87
- message = "\"What are the key technical constraints (Language, DB)?\"";
88
- }
89
- else if (turnCount === 2) {
90
- message = "\"What are the success criteria for this project?\"";
91
- }
92
- else if (turnCount === 3) {
93
- message = "\"What are the non-goals (what should we NOT build)?\"";
94
- }
95
- else {
96
- message = "\"DONE\"";
97
- }
98
- return {
99
- taskId: task.taskId,
100
- status: "ok",
101
- message,
102
- filesChanged: []
103
- };
104
- }
105
- function handleArtifactGeneration(task) {
106
- const intentSlug = task.metadata?.intentSlug || "default";
107
- const prompt = task.instructions || "";
108
- // 1. Parse Inputs (Poor man's extraction from "User Answers" section of prompt)
109
- let targetUser = "Unknown User";
110
- let techStack = "Node.js (Default)";
111
- let successCriteria = "- Standard success criteria";
112
- let nonGoals = "- None specified";
113
- // Extract Answers
114
- const qaRegex = /Q: (.*?)\nA: (.*?)(?=\nQ:|\n$)/gs;
115
- const matches = [...prompt.matchAll(qaRegex)];
116
- matches.forEach(([, q, a]) => {
117
- const qLower = q.toLowerCase();
118
- if (qLower.includes("primary user"))
119
- targetUser = a.trim();
120
- else if (qLower.includes("technical constraints"))
121
- techStack = a.trim();
122
- else if (qLower.includes("success criteria"))
123
- successCriteria = a.trim().split('.').map(s => s.trim()).filter(Boolean).map(s => `- ${s}`).join("\n");
124
- else if (qLower.includes("non-goals"))
125
- nonGoals = a.trim().split('.').map(s => s.trim()).filter(Boolean).map(s => `- ${s}`).join("\n");
126
- });
127
- // 2. Generate Requirements
128
- const reqContent = `# Requirements: ${task.intent}
129
-
130
- ## Goal
131
- ${task.intent}
132
-
133
- ## Target User
134
- ${targetUser}
135
-
136
- ## Success Criteria
137
- ${successCriteria}
138
-
139
- ## Non-Goals
140
- ${nonGoals}
141
-
142
- ## Functional Requirements (Inferred)
143
- - User should be able to complete the core workflows described in criteria.
144
- - System should be performant and reliable.
145
- `;
146
- // 3. Generate System Context
147
- const sysContent = `# System Context
148
-
149
- ## Tech Stack
150
- ${techStack}
151
-
152
- ## Architecture Decisions
153
- - **Frontend / Backend Split**: as implied by tech stack.
154
- - **Data Persistence**: ${techStack.includes("firebase") ? "Firebase" : "Local/File-based (Default)"}.
155
-
156
- ## Constraints
157
- - ${techStack}
158
- `;
159
- const root = process.cwd();
160
- const reqPath = `memory-bank/intents/${intentSlug}/requirements.md`;
161
- const sysPath = `memory-bank/intents/${intentSlug}/system-context.md`;
162
- ensureFile(path.join(root, reqPath), reqContent);
163
- ensureFile(path.join(root, sysPath), sysContent);
164
- return {
165
- taskId: task.taskId,
166
- status: "ok",
167
- message: "Artifacts generated.",
168
- filesChanged: [reqPath, sysPath]
169
- };
170
- }
171
- function handleBoltPlan(task) {
172
- const root = process.cwd();
173
- const planPath = "memory-bank/operations/bolts/plan.md";
174
- const boltPath = "memory-bank/operations/bolts/b001-bootstrap.md";
175
- const planContent = `# Bolt Plan\n\n- [ ] [B001] [Bootstrap Project](./b001-bootstrap.md)\n`;
176
- const boltContent = `# Bolt: Bootstrap\n\n## Tasks\n- [ ] Init project\n\n## Acceptance\n- runs\n`;
177
- ensureFile(path.join(root, planPath), planContent);
178
- ensureFile(path.join(root, boltPath), boltContent);
179
- return {
180
- taskId: task.taskId,
181
- status: "ok",
182
- message: "Plan generated.",
183
- filesChanged: [planPath, boltPath]
184
- };
185
- }
186
- function ensureFile(p, content) {
187
- const dir = path.dirname(p);
188
- fs.mkdirSync(dir, { recursive: true });
189
- fs.writeFileSync(p, content);
190
- }
@@ -1,31 +0,0 @@
1
- import { FilesystemBridgeConnector } from "./filesystem-connector.js";
2
- import { CursorConnector } from "./connectors/cursor-connector.js";
3
- import { VSCodeConnector } from "./connectors/vscode-connector.js";
4
- import { AntigravityConnector } from "./connectors/antigravity-connector.js";
5
- import { WindsurfConnector } from "./connectors/windsurf-connector.js";
6
- import { InProcessBridgeConnector } from "./connectors/in-process-connector.js";
7
- /**
8
- * Create a bridge connector based on IDE id
9
- */
10
- export function createConnector(ideId) {
11
- switch (ideId.toLowerCase()) {
12
- case "cursor":
13
- return new CursorConnector();
14
- case "vscode":
15
- case "code":
16
- return new VSCodeConnector();
17
- case "antigravity":
18
- case "gemini":
19
- return new AntigravityConnector();
20
- case "windsurf":
21
- return new WindsurfConnector();
22
- case "auto":
23
- case "internal":
24
- return new InProcessBridgeConnector();
25
- case "claude":
26
- case "codex":
27
- default:
28
- // Fallback to filesystem bridge for unsupported IDEs
29
- return new FilesystemBridgeConnector();
30
- }
31
- }
@@ -1,18 +0,0 @@
1
- import { FilesystemBridgeConnector } from "../filesystem-connector.js";
2
- /**
3
- * Antigravity connector
4
- * Uses filesystem bridge (Antigravity doesn't have a standalone CLI)
5
- */
6
- export class AntigravityConnector extends FilesystemBridgeConnector {
7
- id = "antigravity";
8
- displayName = "Antigravity (Google Gemini)";
9
- async isAvailable() {
10
- // Antigravity is always "available" via filesystem bridge
11
- // The user interacts through the Gemini interface
12
- return true;
13
- }
14
- async ensureRunning() {
15
- await super.ensureRunning();
16
- // No additional setup needed for Antigravity
17
- }
18
- }
@@ -1,31 +0,0 @@
1
- import { execSync } from "child_process";
2
- import { FilesystemBridgeConnector } from "../filesystem-connector.js";
3
- /**
4
- * Cursor IDE connector
5
- * Extends filesystem bridge with Cursor CLI integration
6
- */
7
- export class CursorConnector extends FilesystemBridgeConnector {
8
- id = "cursor";
9
- displayName = "Cursor IDE";
10
- async isAvailable() {
11
- try {
12
- execSync("which cursor", { stdio: "ignore" });
13
- return true;
14
- }
15
- catch {
16
- return false;
17
- }
18
- }
19
- async ensureRunning() {
20
- await super.ensureRunning();
21
- // Try to open Cursor if available
22
- if (await this.isAvailable()) {
23
- try {
24
- execSync("cursor --version", { stdio: "ignore" });
25
- }
26
- catch {
27
- // Cursor not running or not available, continue anyway
28
- }
29
- }
30
- }
31
- }
@@ -1,29 +0,0 @@
1
- import { handleTask } from "../agent-runner.js";
2
- export class InProcessBridgeConnector {
3
- id = "in-process";
4
- displayName = "Internal Agent";
5
- pendingTasks = new Map();
6
- async isAvailable() {
7
- return true;
8
- }
9
- async ensureRunning() {
10
- // No-op
11
- }
12
- async sendTask(packet) {
13
- this.pendingTasks.set(packet.taskId, packet);
14
- return { taskId: packet.taskId };
15
- }
16
- async waitResult(taskId, opts) {
17
- const packet = this.pendingTasks.get(taskId);
18
- if (!packet) {
19
- throw new Error(`Task ${taskId} not found in process memory`);
20
- }
21
- // Simulate async processing (think time)
22
- await new Promise(resolve => setTimeout(resolve, 500));
23
- // Execute logic directly
24
- const result = await handleTask(packet);
25
- // Cleanup
26
- this.pendingTasks.delete(taskId);
27
- return result;
28
- }
29
- }
@@ -1,31 +0,0 @@
1
- import { execSync } from "child_process";
2
- import { FilesystemBridgeConnector } from "../filesystem-connector.js";
3
- /**
4
- * VS Code connector
5
- * Extends filesystem bridge with VS Code CLI integration
6
- */
7
- export class VSCodeConnector extends FilesystemBridgeConnector {
8
- id = "vscode";
9
- displayName = "Visual Studio Code";
10
- async isAvailable() {
11
- try {
12
- execSync("which code", { stdio: "ignore" });
13
- return true;
14
- }
15
- catch {
16
- return false;
17
- }
18
- }
19
- async ensureRunning() {
20
- await super.ensureRunning();
21
- // Try to verify VS Code is available
22
- if (await this.isAvailable()) {
23
- try {
24
- execSync("code --version", { stdio: "ignore" });
25
- }
26
- catch {
27
- // VS Code not running or not available, continue anyway
28
- }
29
- }
30
- }
31
- }
@@ -1,23 +0,0 @@
1
- import { execSync } from "child_process";
2
- import { FilesystemBridgeConnector } from "../filesystem-connector.js";
3
- /**
4
- * Windsurf connector
5
- * Extends filesystem bridge with Windsurf CLI integration (if available)
6
- */
7
- export class WindsurfConnector extends FilesystemBridgeConnector {
8
- id = "windsurf";
9
- displayName = "Windsurf";
10
- async isAvailable() {
11
- try {
12
- execSync("which windsurf", { stdio: "ignore" });
13
- return true;
14
- }
15
- catch {
16
- // Fallback to filesystem bridge
17
- return true;
18
- }
19
- }
20
- async ensureRunning() {
21
- await super.ensureRunning();
22
- }
23
- }
@@ -1,110 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { processInboxTasks } from "./helper.js";
4
- import { getSelectedIde } from "../iris/state.js";
5
- import kleur from "kleur";
6
- const BRIDGE_DIR = path.join(process.cwd(), ".iris/bridge");
7
- const INBOX_DIR = path.join(BRIDGE_DIR, "inbox");
8
- const OUTBOX_DIR = path.join(BRIDGE_DIR, "outbox");
9
- const STATE_DIR = path.join(BRIDGE_DIR, "state");
10
- /**
11
- * Filesystem-based bridge connector (baseline implementation)
12
- * Works by writing/reading JSON files in .iris/bridge/
13
- */
14
- export class FilesystemBridgeConnector {
15
- id = "filesystem";
16
- displayName = "Filesystem Bridge";
17
- async isAvailable() {
18
- // Always available - just needs filesystem
19
- return true;
20
- }
21
- async ensureRunning() {
22
- // Ensure bridge directories exist
23
- for (const dir of [INBOX_DIR, OUTBOX_DIR, STATE_DIR]) {
24
- if (!fs.existsSync(dir)) {
25
- fs.mkdirSync(dir, { recursive: true });
26
- }
27
- }
28
- }
29
- async sendTask(packet) {
30
- await this.ensureRunning();
31
- const inboxPath = path.join(INBOX_DIR, `${packet.taskId}.json`);
32
- fs.writeFileSync(inboxPath, JSON.stringify(packet, null, 2), "utf8");
33
- return { taskId: packet.taskId };
34
- }
35
- async waitResult(taskId, opts) {
36
- const timeoutMs = opts?.timeoutMs || 300000; // 5 minutes default
37
- const pollIntervalMs = opts?.pollIntervalMs || 1000; // 1 second
38
- const outboxPath = path.join(OUTBOX_DIR, `${taskId}.json`);
39
- const startTime = Date.now();
40
- const processedTasks = new Set(); // Track state for this wait cycle
41
- while (Date.now() - startTime < timeoutMs) {
42
- // Check for result logic...
43
- if (fs.existsSync(outboxPath)) {
44
- console.log(kleur.dim(` [Debug] Found result at: ${outboxPath}`));
45
- const content = fs.readFileSync(outboxPath, "utf8");
46
- const result = JSON.parse(content);
47
- // Clean up
48
- fs.unlinkSync(outboxPath);
49
- const inboxPath = path.join(INBOX_DIR, `${taskId}.json`);
50
- if (fs.existsSync(inboxPath)) {
51
- fs.unlinkSync(inboxPath);
52
- }
53
- return result;
54
- }
55
- else {
56
- // console.log(kleur.dim(` [Debug] Waiting... Checked: ${outboxPath}`));
57
- }
58
- // AUTO-BRIDGE: Act as the bridge while waiting
59
- const ideId = getSelectedIde();
60
- if (ideId) {
61
- await processInboxTasks(ideId, processedTasks, false);
62
- }
63
- // Wait before next poll
64
- await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
65
- }
66
- throw new Error(`Timeout waiting for result: ${taskId}`);
67
- }
68
- generatePrompt(packet) {
69
- return `# IRIS Workflow Task
70
-
71
- **Task ID:** ${packet.taskId}
72
- **Stage:** ${packet.stage}
73
- **Agent:** ${packet.agent}
74
-
75
- ## Intent
76
-
77
- ${packet.intent}
78
-
79
- ## Instructions
80
-
81
- ${packet.instructions}
82
-
83
- ## Input Files
84
-
85
- ${packet.inputs.map(p => `- [\`${path.basename(p)}\`](file://${path.resolve(p)})`).join("\n")}
86
-
87
- ## Expected Outputs
88
-
89
- ${packet.expectedOutputs.map(p => `- \`${p}\``).join("\n")}
90
-
91
- ${packet.gates ? `\n## Gates\n\n${packet.gates.join("\n")}\n` : ""}
92
-
93
- ---
94
-
95
- **When complete, create a result file at:**
96
- \`.iris/bridge/outbox/${packet.taskId}.json\`
97
-
98
- **Result format:**
99
- \`\`\`json
100
- {
101
- "taskId": "${packet.taskId}",
102
- "status": "ok" | "needs_user" | "error",
103
- "message": "Description of what was done",
104
- "filesChanged": ["path/to/file1.md", "path/to/file2.md"],
105
- "logs": ["Optional log messages"]
106
- }
107
- \`\`\`
108
- `;
109
- }
110
- }
@@ -1,203 +0,0 @@
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,10 +0,0 @@
1
- /**
2
- * Bridge types for iris develop workflow
3
- */
4
- export var WorkflowStage;
5
- (function (WorkflowStage) {
6
- WorkflowStage["INTENT_INCEPTION"] = "INTENT_INCEPTION";
7
- WorkflowStage["BOLT_PLAN"] = "BOLT_PLAN";
8
- WorkflowStage["BOLT_EXECUTION"] = "BOLT_EXECUTION";
9
- WorkflowStage["DONE"] = "DONE";
10
- })(WorkflowStage || (WorkflowStage = {}));