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.
- package/README.md +214 -323
- package/bin/cli.js +21 -0
- package/flows/aidlc/README.md +372 -0
- package/flows/aidlc/agents/construction-agent.md +79 -0
- package/flows/aidlc/agents/inception-agent.md +97 -0
- package/flows/aidlc/agents/master-agent.md +61 -0
- package/flows/aidlc/agents/operations-agent.md +89 -0
- package/flows/aidlc/commands/construction-agent.md +63 -0
- package/flows/aidlc/commands/inception-agent.md +55 -0
- package/flows/aidlc/commands/master-agent.md +47 -0
- package/flows/aidlc/commands/operations-agent.md +77 -0
- package/flows/aidlc/context-config.yaml +67 -0
- package/flows/aidlc/memory-bank.yaml +104 -0
- package/flows/aidlc/quick-start.md +322 -0
- package/flows/aidlc/skills/construction/bolt-list.md +163 -0
- package/flows/aidlc/skills/construction/bolt-replan.md +345 -0
- package/flows/aidlc/skills/construction/bolt-start.md +442 -0
- package/flows/aidlc/skills/construction/bolt-status.md +185 -0
- package/flows/aidlc/skills/construction/navigator.md +196 -0
- package/flows/aidlc/skills/inception/bolt-plan.md +372 -0
- package/flows/aidlc/skills/inception/context.md +171 -0
- package/flows/aidlc/skills/inception/intent-create.md +211 -0
- package/flows/aidlc/skills/inception/intent-list.md +124 -0
- package/flows/aidlc/skills/inception/navigator.md +207 -0
- package/flows/aidlc/skills/inception/requirements.md +227 -0
- package/flows/aidlc/skills/inception/review.md +248 -0
- package/flows/aidlc/skills/inception/story-create.md +304 -0
- package/flows/aidlc/skills/inception/units.md +278 -0
- package/flows/aidlc/skills/master/analyze-context.md +239 -0
- package/flows/aidlc/skills/master/answer-question.md +141 -0
- package/flows/aidlc/skills/master/explain-flow.md +158 -0
- package/flows/aidlc/skills/master/project-init.md +281 -0
- package/flows/aidlc/skills/master/route-request.md +126 -0
- package/flows/aidlc/skills/operations/build.md +237 -0
- package/flows/aidlc/skills/operations/deploy.md +259 -0
- package/flows/aidlc/skills/operations/monitor.md +265 -0
- package/flows/aidlc/skills/operations/navigator.md +209 -0
- package/flows/aidlc/skills/operations/verify.md +224 -0
- package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt.md +3 -3
- package/{dist → flows/aidlc}/templates/construction/bolt-types/spike-bolt.md +2 -2
- package/flows/aidlc/templates/construction/construction-log-template.md +129 -0
- package/flows/aidlc/templates/construction/standards/coding-standards.md +29 -0
- package/flows/aidlc/templates/construction/standards/system-architecture.md +22 -0
- package/flows/aidlc/templates/construction/standards/tech-stack.md +19 -0
- package/flows/aidlc/templates/inception/inception-log-template.md +134 -0
- package/flows/aidlc/templates/inception/project/README.md +55 -0
- package/flows/aidlc/templates/standards/catalog.yaml +345 -0
- package/flows/aidlc/templates/standards/coding-standards.guide.md +553 -0
- package/flows/aidlc/templates/standards/data-stack.guide.md +162 -0
- package/flows/aidlc/templates/standards/tech-stack.guide.md +280 -0
- package/lib/InstallerFactory.js +36 -0
- package/lib/analytics/env-detector.js +92 -0
- package/lib/analytics/index.js +22 -0
- package/lib/analytics/machine-id.js +33 -0
- package/lib/analytics/tracker.js +232 -0
- package/lib/cli-utils.js +342 -0
- package/lib/constants.js +32 -0
- package/lib/installer.js +402 -0
- package/lib/installers/AntigravityInstaller.js +22 -0
- package/lib/installers/ClaudeInstaller.js +85 -0
- package/lib/installers/ClineInstaller.js +21 -0
- package/lib/installers/CodexInstaller.js +21 -0
- package/lib/installers/CopilotInstaller.js +113 -0
- package/lib/installers/CursorInstaller.js +63 -0
- package/lib/installers/GeminiInstaller.js +75 -0
- package/lib/installers/KiroInstaller.js +22 -0
- package/lib/installers/OpenCodeInstaller.js +22 -0
- package/lib/installers/RooInstaller.js +22 -0
- package/lib/installers/ToolInstaller.js +73 -0
- package/lib/installers/WindsurfInstaller.js +22 -0
- package/lib/markdown-validator.ts +175 -0
- package/lib/yaml-validator.ts +99 -0
- package/package.json +105 -32
- package/scripts/artifact-validator.js +594 -0
- package/scripts/bolt-complete.js +606 -0
- package/scripts/status-integrity.js +598 -0
- package/dist/bridge/agent-runner.js +0 -190
- package/dist/bridge/connector-factory.js +0 -31
- package/dist/bridge/connectors/antigravity-connector.js +0 -18
- package/dist/bridge/connectors/cursor-connector.js +0 -31
- package/dist/bridge/connectors/in-process-connector.js +0 -29
- package/dist/bridge/connectors/vscode-connector.js +0 -31
- package/dist/bridge/connectors/windsurf-connector.js +0 -23
- package/dist/bridge/filesystem-connector.js +0 -110
- package/dist/bridge/helper.js +0 -203
- package/dist/bridge/types.js +0 -10
- package/dist/cli.js +0 -40
- package/dist/commands/ask.js +0 -259
- package/dist/commands/bridge.js +0 -88
- package/dist/commands/create.js +0 -25
- package/dist/commands/develop.js +0 -141
- package/dist/commands/doctor.js +0 -102
- package/dist/commands/flow.js +0 -301
- package/dist/commands/framework.js +0 -273
- package/dist/commands/generate.js +0 -59
- package/dist/commands/install.js +0 -100
- package/dist/commands/pack.js +0 -33
- package/dist/commands/phase.js +0 -38
- package/dist/commands/run.js +0 -199
- package/dist/commands/status.js +0 -114
- package/dist/commands/uninstall.js +0 -14
- package/dist/commands/use.js +0 -20
- package/dist/commands/validate.js +0 -102
- package/dist/framework/framework-loader.js +0 -97
- package/dist/framework/framework-paths.js +0 -48
- package/dist/framework/framework-types.js +0 -15
- package/dist/iris/artifact-checker.js +0 -78
- package/dist/iris/artifacts/config.js +0 -68
- package/dist/iris/artifacts/generator.js +0 -88
- package/dist/iris/artifacts/types.js +0 -1
- package/dist/iris/bundle.js +0 -44
- package/dist/iris/doctrine/collector.js +0 -124
- package/dist/iris/fixer.js +0 -149
- package/dist/iris/flows/manifest.js +0 -124
- package/dist/iris/framework-context.js +0 -49
- package/dist/iris/framework-manager.js +0 -215
- package/dist/iris/fs/atomic.js +0 -22
- package/dist/iris/guard.js +0 -38
- package/dist/iris/importers/index.js +0 -9
- package/dist/iris/importers/types.js +0 -8
- package/dist/iris/importers/writer.js +0 -139
- package/dist/iris/include.js +0 -49
- package/dist/iris/installer.js +0 -334
- package/dist/iris/interactive/env.js +0 -21
- package/dist/iris/interactive/intent-interview.js +0 -345
- package/dist/iris/interactive/intent-schema.js +0 -28
- package/dist/iris/interactive/interview-io.js +0 -22
- package/dist/iris/interview/config.js +0 -71
- package/dist/iris/interview/types.js +0 -16
- package/dist/iris/interview/utils.js +0 -38
- package/dist/iris/manifest.js +0 -54
- package/dist/iris/packer.js +0 -325
- package/dist/iris/parsers/unit-parser.js +0 -43
- package/dist/iris/paths.js +0 -18
- package/dist/iris/policy.js +0 -133
- package/dist/iris/proc.js +0 -56
- package/dist/iris/report.js +0 -53
- package/dist/iris/resolver.js +0 -66
- package/dist/iris/router.js +0 -114
- package/dist/iris/routes.js +0 -189
- package/dist/iris/run-state.js +0 -146
- package/dist/iris/state.js +0 -113
- package/dist/iris/templates.js +0 -70
- package/dist/iris/tmp.js +0 -24
- package/dist/iris/uninstaller.js +0 -181
- package/dist/iris/utils/interpolate.js +0 -42
- package/dist/iris/validator.js +0 -391
- package/dist/iris/workflow/config.js +0 -51
- package/dist/iris/workflow/engine.js +0 -129
- package/dist/iris/workflow/steps.js +0 -448
- package/dist/iris/workflow/types.js +0 -1
- package/dist/iris_bundle/frameworks/iris-core/framework.yaml +0 -9
- package/dist/iris_bundle/frameworks/iris-core/memory/memory-bank.yaml +0 -1
- package/dist/iris_bundle/frameworks/iris-core/policy.yaml +0 -7
- package/dist/iris_bundle/frameworks/iris-core/templates/config/memory-bank.yaml +0 -1
- package/dist/iris_bundle/frameworks/iris-core/templates/construction/bolt-types/spike-bolt.md +0 -240
- package/dist/lib.js +0 -96
- package/dist/templates/construction/bolt-template.md +0 -226
- package/dist/templates/construction/bolt-types/ddd-construction-bolt/adr-template.md +0 -49
- package/dist/templates/construction/bolt-types/ddd-construction-bolt/ddd-01-domain-model-template.md +0 -55
- package/dist/templates/construction/bolt-types/ddd-construction-bolt/ddd-02-technical-design-template.md +0 -67
- package/dist/templates/construction/bolt-types/ddd-construction-bolt/ddd-03-test-report-template.md +0 -62
- package/dist/templates/construction/bolt-types/ddd-construction-bolt.md +0 -528
- package/dist/templates/construction/bolt-types/simple-construction-bolt.md +0 -347
- package/dist/templates/inception/requirements-template.md +0 -144
- package/dist/templates/inception/stories-template.md +0 -38
- package/dist/templates/inception/story-template.md +0 -147
- package/dist/templates/inception/system-context-template.md +0 -29
- package/dist/templates/inception/unit-brief-template.md +0 -177
- package/dist/templates/inception/units-template.md +0 -52
- package/dist/utils/exit-codes.js +0 -7
- package/dist/utils/logo.js +0 -17
- package/dist/workflows/bolt-execution.js +0 -238
- package/dist/workflows/bolt-plan.js +0 -221
- package/dist/workflows/intent-inception.js +0 -285
- package/dist/workflows/memory-bank-generator.js +0 -180
- package/dist/workflows/reporting.js +0 -74
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt/adr-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt/ddd-01-domain-model-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt/ddd-02-technical-design-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/ddd-construction-bolt/ddd-03-test-report-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/construction/bolt-types/simple-construction-bolt.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/requirements-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/stories-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/story-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/system-context-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/unit-brief-template.md +0 -0
- /package/{dist/iris_bundle/frameworks/iris-core → flows/aidlc}/templates/inception/units-template.md +0 -0
package/dist/commands/flow.js
DELETED
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import kleur from "kleur";
|
|
3
|
-
import { repoRoot, ensureDir } from "../lib.js";
|
|
4
|
-
import { loadState, saveState } from "../iris/state.js";
|
|
5
|
-
import { listInstalledFlows, loadFlowManifest } from "../iris/flows/manifest.js";
|
|
6
|
-
import { loadEffectivePolicy } from "../iris/policy.js";
|
|
7
|
-
import { loadEffectiveRoutes } from "../iris/routes.js";
|
|
8
|
-
import { validate } from "../iris/validator.js";
|
|
9
|
-
import { printReport } from "../iris/report.js";
|
|
10
|
-
import { EXIT_CODES } from "../utils/exit-codes.js";
|
|
11
|
-
import { getBundledFlowsDir, listBundledFlows } from "../iris/bundle.js";
|
|
12
|
-
import fs from "fs";
|
|
13
|
-
import path from "path";
|
|
14
|
-
import { getImporter } from "../iris/importers/index.js";
|
|
15
|
-
import { ensureDoctrineOnlyFlowInstalled } from "../iris/importers/writer.js";
|
|
16
|
-
import { makeTempDir, removeTempDir } from "../iris/tmp.js";
|
|
17
|
-
import { ImporterError } from "../iris/importers/types.js";
|
|
18
|
-
const importFlowCommand = new Command("import")
|
|
19
|
-
.description("Import an external methodology as a doctrine-only flow (DEPRECATED)")
|
|
20
|
-
.argument("<provider>", "Provider ID")
|
|
21
|
-
.option("-f, --force", "Overwrite existing files", false)
|
|
22
|
-
.option("-d, --dry-run", "Simulate import without writing files", false)
|
|
23
|
-
.option("-v, --verbose", "Show detailed output", false)
|
|
24
|
-
.action(async (providerId, options) => {
|
|
25
|
-
const root = repoRoot();
|
|
26
|
-
const importer = getImporter(providerId);
|
|
27
|
-
if (!importer) {
|
|
28
|
-
console.error(kleur.red(`No import providers available.`));
|
|
29
|
-
console.log(kleur.yellow("IRIS ships only iris-core. External imports are not supported for now."));
|
|
30
|
-
process.exit(1);
|
|
31
|
-
}
|
|
32
|
-
console.log(kleur.bold(`Importing '${importer.displayName}'...`));
|
|
33
|
-
if (options.dryRun)
|
|
34
|
-
console.log(kleur.yellow("[Dry Run Mode]"));
|
|
35
|
-
console.warn(kleur.yellow("IRIS_WARNING IRIS_FLOW_IMPORT_DEPRECATED: use \"iris framework install <id>\" instead."));
|
|
36
|
-
let tempDir = "";
|
|
37
|
-
try {
|
|
38
|
-
tempDir = makeTempDir(providerId);
|
|
39
|
-
if (options.verbose)
|
|
40
|
-
console.log(kleur.dim(`Temporary workspace: ${tempDir}`));
|
|
41
|
-
// 1. Run Installer
|
|
42
|
-
try {
|
|
43
|
-
await importer.runInstaller({
|
|
44
|
-
repoRoot: root,
|
|
45
|
-
tempDir,
|
|
46
|
-
provider: providerId,
|
|
47
|
-
force: options.force,
|
|
48
|
-
dryRun: options.dryRun,
|
|
49
|
-
verbose: options.verbose
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
catch (e) {
|
|
53
|
-
if (e instanceof ImporterError && e.exitCode === 4) {
|
|
54
|
-
// Policy/Not Supported error (e.g. Speckit)
|
|
55
|
-
// Print friendly message and exit cleanly without stack trace
|
|
56
|
-
console.error(kleur.yellow(e.message));
|
|
57
|
-
process.exit(4);
|
|
58
|
-
}
|
|
59
|
-
throw e;
|
|
60
|
-
}
|
|
61
|
-
// 2. Detect Templates
|
|
62
|
-
const { templateDirs } = await importer.detectDoctrineRoots({
|
|
63
|
-
repoRoot: root,
|
|
64
|
-
tempDir,
|
|
65
|
-
provider: providerId,
|
|
66
|
-
force: options.force,
|
|
67
|
-
dryRun: options.dryRun,
|
|
68
|
-
verbose: options.verbose
|
|
69
|
-
});
|
|
70
|
-
if (options.verbose) {
|
|
71
|
-
console.log(kleur.dim(`Detected template roots: ${templateDirs.length > 0 ? templateDirs.join(", ") : "None"}`));
|
|
72
|
-
}
|
|
73
|
-
// 3. Install
|
|
74
|
-
const result = ensureDoctrineOnlyFlowInstalled({
|
|
75
|
-
repoRoot: root,
|
|
76
|
-
flowId: providerId,
|
|
77
|
-
displayName: importer.displayName,
|
|
78
|
-
sourceTemplateDirs: templateDirs,
|
|
79
|
-
force: options.force,
|
|
80
|
-
dryRun: options.dryRun,
|
|
81
|
-
verbose: options.verbose
|
|
82
|
-
});
|
|
83
|
-
if (result.installedDir && !options.dryRun) {
|
|
84
|
-
// 4. Validate
|
|
85
|
-
try {
|
|
86
|
-
loadFlowManifest(root, providerId);
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
console.warn(kleur.yellow("\nWarning: Imported flow structure seems invalid:"));
|
|
90
|
-
console.warn(kleur.red(e.message));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
// Summary
|
|
94
|
-
console.log(kleur.green(`\n✓ Imported ${importer.displayName} as flow '${providerId}'`));
|
|
95
|
-
if (options.dryRun) {
|
|
96
|
-
console.log(kleur.dim(` [Dry Run] Would copy: ${result.copiedFiles}, Skip: ${result.skippedFiles}, Overwrite: ${result.overwrittenFiles}`));
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
console.log(kleur.dim(` Files: ${result.copiedFiles} created, ${result.skippedFiles} skipped, ${result.overwrittenFiles} overwritten.`));
|
|
100
|
-
console.log(kleur.dim(` Templates: .iris/flows/${providerId}/doctrine/templates/${providerId}/...`));
|
|
101
|
-
console.log(`\nTo activate, run: ${kleur.cyan(`iris flow use ${providerId}`)}`);
|
|
102
|
-
console.log(kleur.gray(`This will make the '${importer.displayName}' templates available to doctrine.`));
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch (e) {
|
|
106
|
-
console.error(kleur.red(`\nImport failed: ${e.message}`));
|
|
107
|
-
if (options.verbose && e.stack)
|
|
108
|
-
console.error(kleur.dim(e.stack));
|
|
109
|
-
// Rollback: If we created a directory but failed, remove it
|
|
110
|
-
// We need to know the target dir. It's safe to assume .iris/flows/<providerId>
|
|
111
|
-
const flowDir = path.join(root, ".iris/flows", providerId);
|
|
112
|
-
if (!options.dryRun && fs.existsSync(flowDir)) {
|
|
113
|
-
// Only rollback if we created it in this run?
|
|
114
|
-
// It's hard to track perfectly without more state, but for safety in "import"
|
|
115
|
-
// if it failed, leaving a partial flow is bad.
|
|
116
|
-
// Limitation: If we were updating (--force) and failed, we might lose the original flow.
|
|
117
|
-
// Risk acceptance: --force implies destructive.
|
|
118
|
-
// For new installs, this is safe.
|
|
119
|
-
try {
|
|
120
|
-
// Check if it looks like a partial install? or just nuke it.
|
|
121
|
-
console.log(kleur.yellow(`Rolling back partial installation at ${flowDir}...`));
|
|
122
|
-
fs.rmSync(flowDir, { recursive: true, force: true });
|
|
123
|
-
}
|
|
124
|
-
catch (cleanupErr) {
|
|
125
|
-
console.error(kleur.red(`Failed to rollback: ${cleanupErr}`));
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
// Ensure we don't return 0
|
|
129
|
-
process.exit(1);
|
|
130
|
-
}
|
|
131
|
-
finally {
|
|
132
|
-
if (tempDir) {
|
|
133
|
-
removeTempDir(tempDir);
|
|
134
|
-
if (options.verbose)
|
|
135
|
-
console.log(kleur.dim("Cleaned up temp workspace."));
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
const installCommand = new Command("install")
|
|
140
|
-
.description("Install a flow from the bundle")
|
|
141
|
-
.argument("<flowId>", "ID of the flow to install")
|
|
142
|
-
.option("-f, --force", "Overwrite existing files", false)
|
|
143
|
-
.action((flowId, options) => {
|
|
144
|
-
const root = repoRoot();
|
|
145
|
-
const bundledFlowsDir = getBundledFlowsDir();
|
|
146
|
-
const sourceDir = path.join(bundledFlowsDir, flowId);
|
|
147
|
-
// 1. Check Source
|
|
148
|
-
if (!fs.existsSync(sourceDir)) {
|
|
149
|
-
console.error(kleur.red(`Bundled flow '${flowId}' not found.`));
|
|
150
|
-
const available = listBundledFlows();
|
|
151
|
-
if (available.length > 0) {
|
|
152
|
-
console.log(kleur.cyan("Available flows:"));
|
|
153
|
-
available.forEach(id => console.log(` - ${id}`));
|
|
154
|
-
}
|
|
155
|
-
process.exit(1);
|
|
156
|
-
}
|
|
157
|
-
const targetDir = path.join(root, ".iris/flows", flowId);
|
|
158
|
-
console.log(kleur.bold(`Installing flow '${flowId}' to .iris/flows/${flowId}...`));
|
|
159
|
-
// 2. Install (Recursive Copy with stats)
|
|
160
|
-
const stats = { installed: 0, skipped: 0, overwritten: 0 };
|
|
161
|
-
function copyRec(src, dest) {
|
|
162
|
-
ensureDir(dest);
|
|
163
|
-
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
164
|
-
for (const entry of entries) {
|
|
165
|
-
const srcPath = path.join(src, entry.name);
|
|
166
|
-
const destPath = path.join(dest, entry.name);
|
|
167
|
-
if (entry.isDirectory()) {
|
|
168
|
-
copyRec(srcPath, destPath);
|
|
169
|
-
}
|
|
170
|
-
else if (entry.isFile()) {
|
|
171
|
-
if (fs.existsSync(destPath)) {
|
|
172
|
-
if (options.force) {
|
|
173
|
-
fs.copyFileSync(srcPath, destPath);
|
|
174
|
-
stats.overwritten++;
|
|
175
|
-
// console.log(kleur.gray(` Overwrote ${entry.name}`));
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
stats.skipped++;
|
|
179
|
-
// console.log(kleur.gray(` Skipped ${entry.name} (exists)`));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
fs.copyFileSync(srcPath, destPath);
|
|
184
|
-
stats.installed++;
|
|
185
|
-
// console.log(kleur.green(` Created ${entry.name}`));
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
try {
|
|
191
|
-
copyRec(sourceDir, targetDir);
|
|
192
|
-
}
|
|
193
|
-
catch (e) {
|
|
194
|
-
console.error(kleur.red(`Installation failed: ${e.message}`));
|
|
195
|
-
process.exit(1);
|
|
196
|
-
}
|
|
197
|
-
// 3. Post-Install Validation
|
|
198
|
-
try {
|
|
199
|
-
loadFlowManifest(root, flowId);
|
|
200
|
-
// Optional: Check existence of overlays explicitly if manifest says so?
|
|
201
|
-
// loadFlowManifest checks structure.
|
|
202
|
-
// We can trust it for now or do improved checks later.
|
|
203
|
-
}
|
|
204
|
-
catch (e) {
|
|
205
|
-
console.error(kleur.yellow(`\nWarning: Installed flow '${flowId}' seems invalid:`));
|
|
206
|
-
console.error(kleur.red(e.message));
|
|
207
|
-
console.log("Installation completed but flow may not work.");
|
|
208
|
-
process.exit(1);
|
|
209
|
-
}
|
|
210
|
-
console.log(kleur.green(`\n✓ Flow '${flowId}' installed successfully.`));
|
|
211
|
-
console.log(kleur.dim(` Files: ${stats.installed} created, ${stats.overwritten} overwritten, ${stats.skipped} skipped.`));
|
|
212
|
-
console.log(`\nTo activate, run: ${kleur.cyan(`iris flow use ${flowId}`)}`);
|
|
213
|
-
});
|
|
214
|
-
const listCommand = new Command("list")
|
|
215
|
-
.description("List installed flows")
|
|
216
|
-
.action(() => {
|
|
217
|
-
const root = repoRoot();
|
|
218
|
-
const state = loadState();
|
|
219
|
-
const flows = listInstalledFlows(root);
|
|
220
|
-
if (flows.length === 0) {
|
|
221
|
-
console.log(kleur.gray("No flows installed."));
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
console.log(kleur.bold("\nInstalled Flows:"));
|
|
225
|
-
for (const flow of flows) {
|
|
226
|
-
const isActive = state.active.flow === flow.id;
|
|
227
|
-
const status = isActive ? kleur.green("(active)") : "";
|
|
228
|
-
const line = `${kleur.cyan(flow.id.padEnd(20))} ${flow.name} ${kleur.dim(flow.version)} ${status}`;
|
|
229
|
-
console.log(line);
|
|
230
|
-
}
|
|
231
|
-
console.log("");
|
|
232
|
-
});
|
|
233
|
-
const useCommand = new Command("use")
|
|
234
|
-
.description("Switch the active flow")
|
|
235
|
-
.argument("<flowId>", "ID of the flow to switch to")
|
|
236
|
-
.action(async (flowId) => {
|
|
237
|
-
const root = repoRoot();
|
|
238
|
-
const state = loadState();
|
|
239
|
-
if (state.active.flow === flowId) {
|
|
240
|
-
console.log(kleur.yellow(`Flow '${flowId}' is already active.`));
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
// 1. Safety Check (Dry Run)
|
|
244
|
-
// Verify we can load policy and routes BEFORE switching
|
|
245
|
-
try {
|
|
246
|
-
console.log(kleur.dim(`Verifying flow '${flowId}' integrity...`));
|
|
247
|
-
// Check manifest existence implicit in these loaders (via loadFlowManifest)
|
|
248
|
-
// Resolve framework to ensure compatibility (best effort check)
|
|
249
|
-
// We import resolveActiveFramework dynamically or add import?
|
|
250
|
-
// Better to rely on null if we don't want to async resolve here?
|
|
251
|
-
// Actually useCommand IS async action.
|
|
252
|
-
// But we need to import resolveActiveFramework.
|
|
253
|
-
// Let's pass null for framework for now to just check OVERLAY existence,
|
|
254
|
-
// unless we want strict framework compatibility check.
|
|
255
|
-
// Step 1 logic implies overlays are valid if files exist.
|
|
256
|
-
// NOTE: Changing signature to (null, root, flowId) due to refactor
|
|
257
|
-
loadEffectivePolicy(null, root, flowId);
|
|
258
|
-
console.log(kleur.dim(" Policy overlay: OK"));
|
|
259
|
-
loadEffectiveRoutes(null, root, flowId);
|
|
260
|
-
console.log(kleur.dim(" Routes overlay: OK"));
|
|
261
|
-
}
|
|
262
|
-
catch (e) {
|
|
263
|
-
console.error(kleur.red(`\nCannot switch to flow '${flowId}':`));
|
|
264
|
-
if (e.name === "PolicyOverlayMissingError" || e.name === "RoutesOverlayMissingError") {
|
|
265
|
-
console.error(kleur.red(` ${e.message}`));
|
|
266
|
-
console.error(kleur.yellow(" This flow is broken (missing required overlay). Fix it or reinstall."));
|
|
267
|
-
}
|
|
268
|
-
else if (e.name === "FlowNotFoundError") {
|
|
269
|
-
console.error(kleur.red(` Flow '${flowId}' is not installed.`));
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
console.error(kleur.red(` ${e.message}`));
|
|
273
|
-
if (e.cause)
|
|
274
|
-
console.error(kleur.gray(` Cause: ${e.cause}`));
|
|
275
|
-
}
|
|
276
|
-
process.exit(EXIT_CODES.POLICY_ERROR);
|
|
277
|
-
}
|
|
278
|
-
// 2. Update State
|
|
279
|
-
state.active.flow = flowId;
|
|
280
|
-
saveState(state);
|
|
281
|
-
console.log(kleur.green(`Switched to flow: ${flowId}`));
|
|
282
|
-
// 3. Run Validation (Info only)
|
|
283
|
-
console.log(kleur.dim("Validating new requirements..."));
|
|
284
|
-
const result = await validate({
|
|
285
|
-
apply: false,
|
|
286
|
-
strict: false,
|
|
287
|
-
writeBack: false // Don't verify/update validation timestamp just for this check? Or yes?
|
|
288
|
-
// "validates manifest exists and sets state... then runs validate (non-fix) to show new requirements"
|
|
289
|
-
// Usually we want to show the report.
|
|
290
|
-
});
|
|
291
|
-
printReport(result, false);
|
|
292
|
-
if (!result.valid) {
|
|
293
|
-
console.log(kleur.yellow("\nNote: You may need to satisfy new requirements. Run 'iris fix' or 'iris validate'."));
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
export const flowCommand = new Command("flow")
|
|
297
|
-
.description("Manage active flows")
|
|
298
|
-
.addCommand(listCommand)
|
|
299
|
-
.addCommand(installCommand)
|
|
300
|
-
.addCommand(importFlowCommand)
|
|
301
|
-
.addCommand(useCommand);
|
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import kleur from "kleur";
|
|
3
|
-
import { loadState, getActiveFramework, setActiveFramework } from "../iris/state.js";
|
|
4
|
-
import { loadFramework } from "../framework/framework-loader.js";
|
|
5
|
-
import { repoRoot } from "../lib.js";
|
|
6
|
-
import { listInstalledFrameworks, listBundledFrameworks, installFrameworkFromPath, installBundledFramework, removeFramework, validateFrameworkParams } from "../iris/framework-manager.js";
|
|
7
|
-
export const frameworkCommand = new Command("framework")
|
|
8
|
-
.description("Manage IRIS frameworks");
|
|
9
|
-
frameworkCommand
|
|
10
|
-
.command("current")
|
|
11
|
-
.description("Show the currently active framework")
|
|
12
|
-
.option("--json", "Output as JSON")
|
|
13
|
-
.action(async (options) => {
|
|
14
|
-
const state = loadState();
|
|
15
|
-
const active = getActiveFramework(state);
|
|
16
|
-
const root = repoRoot();
|
|
17
|
-
let resolution = null;
|
|
18
|
-
let error = null;
|
|
19
|
-
try {
|
|
20
|
-
resolution = await loadFramework(active.current, { repoRoot: root });
|
|
21
|
-
}
|
|
22
|
-
catch (e) {
|
|
23
|
-
error = e;
|
|
24
|
-
}
|
|
25
|
-
if (options.json) {
|
|
26
|
-
console.log(JSON.stringify({
|
|
27
|
-
schemaVersion: 1,
|
|
28
|
-
active: {
|
|
29
|
-
id: active.current,
|
|
30
|
-
version: active.version
|
|
31
|
-
},
|
|
32
|
-
resolved: !!resolution,
|
|
33
|
-
rootDir: resolution?.rootDir || null,
|
|
34
|
-
source: resolution ? {
|
|
35
|
-
kind: resolution.source.kind,
|
|
36
|
-
path: resolution.source.path,
|
|
37
|
-
...(resolution.source.id ? { id: resolution.source.id } : {})
|
|
38
|
-
} : null,
|
|
39
|
-
error: error ? {
|
|
40
|
-
code: error.code || 'UNKNOWN',
|
|
41
|
-
path: error.path || null,
|
|
42
|
-
hint: error.hint || null
|
|
43
|
-
} : null
|
|
44
|
-
}, null, 2));
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
// Human output
|
|
48
|
-
console.log("");
|
|
49
|
-
if (resolution) {
|
|
50
|
-
console.log(kleur.bold(`Active Framework: ${kleur.green(active.current)}`));
|
|
51
|
-
if (active.version) {
|
|
52
|
-
console.log(`Version Pin: ${kleur.cyan(active.version)}`);
|
|
53
|
-
}
|
|
54
|
-
console.log(kleur.gray(`Location: ${resolution.rootDir}`));
|
|
55
|
-
if (resolution.manifest.version) {
|
|
56
|
-
console.log(`Manifest Version: ${resolution.manifest.version}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
console.log(kleur.bold(`Active Framework: ${kleur.yellow(active.current)} (Not Found)`));
|
|
61
|
-
if (active.version) {
|
|
62
|
-
console.log(`Version Pin: ${kleur.cyan(active.version)}`);
|
|
63
|
-
}
|
|
64
|
-
console.log(kleur.red(`Error: ${error?.message || "Could not resolve framework"}`));
|
|
65
|
-
if (error?.hint) {
|
|
66
|
-
console.log(kleur.gray(`Hint: ${error.hint}`));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
frameworkCommand
|
|
71
|
-
.command("use")
|
|
72
|
-
.description("Switch the active framework")
|
|
73
|
-
.argument("<id>", "Framework ID (can include @version)")
|
|
74
|
-
.option("--strict", "Fail if framework cannot be resolved")
|
|
75
|
-
.action(async (idStr, options) => {
|
|
76
|
-
// Parse ID and Version
|
|
77
|
-
const lastAt = idStr.lastIndexOf('@');
|
|
78
|
-
let id = idStr;
|
|
79
|
-
let version = null;
|
|
80
|
-
if (lastAt > 0) {
|
|
81
|
-
id = idStr.substring(0, lastAt);
|
|
82
|
-
version = idStr.substring(lastAt + 1);
|
|
83
|
-
}
|
|
84
|
-
const root = repoRoot();
|
|
85
|
-
const state = loadState();
|
|
86
|
-
// Check if resolvable
|
|
87
|
-
try {
|
|
88
|
-
await loadFramework(id, { repoRoot: root });
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
if (options.strict) {
|
|
92
|
-
console.error(kleur.red(`Error: Framework '${id}' not found.`));
|
|
93
|
-
console.error(kleur.gray(error.message));
|
|
94
|
-
process.exit(1);
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
console.warn(kleur.yellow(`Warning: Framework '${id}' could not be resolved. Setting anyway.`));
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
setActiveFramework(state, id, version);
|
|
101
|
-
console.log(kleur.green(`✓ Set active framework to: ${kleur.bold(id)}`));
|
|
102
|
-
if (version) {
|
|
103
|
-
console.log(kleur.cyan(` Pinned version: ${version}`));
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
frameworkCommand
|
|
107
|
-
.command("list")
|
|
108
|
-
.description("List installed and available frameworks")
|
|
109
|
-
.action(async () => {
|
|
110
|
-
const root = repoRoot();
|
|
111
|
-
const installed = await listInstalledFrameworks(root);
|
|
112
|
-
const bundled = await listBundledFrameworks();
|
|
113
|
-
// Merge strategy: map by ID
|
|
114
|
-
const map = new Map();
|
|
115
|
-
for (const i of installed) {
|
|
116
|
-
if (!map.has(i.id))
|
|
117
|
-
map.set(i.id, {});
|
|
118
|
-
map.get(i.id).installed = i;
|
|
119
|
-
}
|
|
120
|
-
for (const b of bundled) {
|
|
121
|
-
if (!map.has(b.id))
|
|
122
|
-
map.set(b.id, {});
|
|
123
|
-
map.get(b.id).bundled = b;
|
|
124
|
-
}
|
|
125
|
-
console.log(kleur.bold("\nFrameworks:\n"));
|
|
126
|
-
// Output format
|
|
127
|
-
// ID Version Status
|
|
128
|
-
const sortedIds = Array.from(map.keys()).sort();
|
|
129
|
-
for (const id of sortedIds) {
|
|
130
|
-
const entry = map.get(id);
|
|
131
|
-
const inst = entry.installed;
|
|
132
|
-
const bund = entry.bundled;
|
|
133
|
-
let status = "";
|
|
134
|
-
let version = "";
|
|
135
|
-
let meta = "";
|
|
136
|
-
if (inst) {
|
|
137
|
-
version = inst.version || "???";
|
|
138
|
-
if (inst.active)
|
|
139
|
-
status = kleur.green("Active");
|
|
140
|
-
else if (inst.valid)
|
|
141
|
-
status = "Installed";
|
|
142
|
-
else
|
|
143
|
-
status = kleur.red("Broken");
|
|
144
|
-
if (bund)
|
|
145
|
-
meta = kleur.gray("(Bundled available)");
|
|
146
|
-
}
|
|
147
|
-
else if (bund) {
|
|
148
|
-
version = bund.version || "bundled";
|
|
149
|
-
status = kleur.dim("Bundled");
|
|
150
|
-
meta = kleur.gray("(Use 'iris framework install' to install)");
|
|
151
|
-
}
|
|
152
|
-
console.log(` ${kleur.bold(id.padEnd(20))} ${version.padEnd(10)} ${status.padEnd(15)} ${meta}`);
|
|
153
|
-
if (inst?.error) {
|
|
154
|
-
console.log(kleur.red(` Error: ${inst.error.message}`));
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
console.log("");
|
|
158
|
-
});
|
|
159
|
-
frameworkCommand
|
|
160
|
-
.command("add")
|
|
161
|
-
.description("Install a framework from a local directory")
|
|
162
|
-
.argument("<path>", "Path to framework folder")
|
|
163
|
-
.option("-f, --force", "Overwrite existing framework if present")
|
|
164
|
-
.action(async (srcPath, options) => {
|
|
165
|
-
const root = repoRoot();
|
|
166
|
-
try {
|
|
167
|
-
const result = await installFrameworkFromPath(root, srcPath, { force: options.force });
|
|
168
|
-
console.log(kleur.green(`✓ Added framework '${result.id}' (v${result.version})`));
|
|
169
|
-
console.log(kleur.gray(` Installed to: ${result.path}`));
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
console.error(kleur.red(`Error: ${error.message}`));
|
|
173
|
-
if (error.hint)
|
|
174
|
-
console.error(kleur.gray(`Hint: ${error.hint}`));
|
|
175
|
-
process.exit(1);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
frameworkCommand
|
|
179
|
-
.command("install")
|
|
180
|
-
.description("Install a bundled framework")
|
|
181
|
-
.argument("<id>", "Framework ID")
|
|
182
|
-
.option("-f, --force", "Overwrite existing framework if present")
|
|
183
|
-
.action(async (id, options) => {
|
|
184
|
-
const root = repoRoot();
|
|
185
|
-
try {
|
|
186
|
-
const result = await installBundledFramework(root, id, { force: options.force });
|
|
187
|
-
console.log(kleur.green(`✓ Installed framework '${result.id}' (v${result.version})`));
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
console.error(kleur.red(`Error: ${error.message}`));
|
|
191
|
-
process.exit(1);
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
frameworkCommand
|
|
195
|
-
.command("remove")
|
|
196
|
-
.description("Remove an installed framework")
|
|
197
|
-
.argument("<id>", "Framework ID")
|
|
198
|
-
.action((id) => {
|
|
199
|
-
const root = repoRoot();
|
|
200
|
-
try {
|
|
201
|
-
removeFramework(root, id);
|
|
202
|
-
console.log(kleur.green(`✓ Removed framework '${id}'`));
|
|
203
|
-
}
|
|
204
|
-
catch (error) {
|
|
205
|
-
console.error(kleur.red(`Error: ${error.message}`));
|
|
206
|
-
if (error.hint)
|
|
207
|
-
console.error(kleur.gray(`Hint: ${error.hint}`));
|
|
208
|
-
process.exit(1);
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
frameworkCommand
|
|
212
|
-
.command("validate")
|
|
213
|
-
.description("Validate a framework")
|
|
214
|
-
.argument("<input>", "Framework ID or Path")
|
|
215
|
-
.option("--json", "Output as JSON")
|
|
216
|
-
.action(async (input, options) => {
|
|
217
|
-
const root = repoRoot();
|
|
218
|
-
let result = null;
|
|
219
|
-
let error = null;
|
|
220
|
-
try {
|
|
221
|
-
result = await validateFrameworkParams(input, root);
|
|
222
|
-
}
|
|
223
|
-
catch (e) {
|
|
224
|
-
error = e;
|
|
225
|
-
}
|
|
226
|
-
if (options.json) {
|
|
227
|
-
console.log(JSON.stringify({
|
|
228
|
-
schemaVersion: 1,
|
|
229
|
-
ok: !error,
|
|
230
|
-
id: result?.manifest?.id || null,
|
|
231
|
-
rootDir: result?.rootDir || null,
|
|
232
|
-
files: result?.files ? {
|
|
233
|
-
policy: !!result.files.policy,
|
|
234
|
-
routes: !!result.files.routes,
|
|
235
|
-
interview: !!result.files.interview,
|
|
236
|
-
pack: !!result.files.pack,
|
|
237
|
-
templates: !!result.files.templates
|
|
238
|
-
} : null,
|
|
239
|
-
warnings: [], // Todo: collecting warnings?
|
|
240
|
-
error: error ? {
|
|
241
|
-
code: error.code || 'UNKNOWN',
|
|
242
|
-
message: error.message,
|
|
243
|
-
path: error.path
|
|
244
|
-
} : null
|
|
245
|
-
}, null, 2));
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (error) {
|
|
249
|
-
console.error(kleur.red(`Validation Failed:`));
|
|
250
|
-
console.error(kleur.red(` ${error.message}`));
|
|
251
|
-
if (error.path)
|
|
252
|
-
console.error(` Path: ${error.path}`);
|
|
253
|
-
if (error.hint)
|
|
254
|
-
console.error(kleur.gray(` Hint: ${error.hint}`));
|
|
255
|
-
process.exit(1);
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
console.log(kleur.green(`✓ Framework '${result.manifest.id}' is valid.`));
|
|
259
|
-
console.log(kleur.gray(` Location: ${result.rootDir}`));
|
|
260
|
-
console.log(` Version: ${result.manifest.version}`);
|
|
261
|
-
// List found files?
|
|
262
|
-
const files = [];
|
|
263
|
-
if (result.files.policy)
|
|
264
|
-
files.push("Policy");
|
|
265
|
-
if (result.files.routes)
|
|
266
|
-
files.push("Routes");
|
|
267
|
-
if (result.files.interview)
|
|
268
|
-
files.push("Interview");
|
|
269
|
-
if (result.files.templates)
|
|
270
|
-
files.push("Templates");
|
|
271
|
-
console.log(` Components: ${files.join(", ")}`);
|
|
272
|
-
}
|
|
273
|
-
});
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import kleur from "kleur";
|
|
5
|
-
import { resolveActiveFramework } from "../iris/framework-context.js";
|
|
6
|
-
import { loadEffectiveArtifactsConfig } from "../iris/artifacts/config.js";
|
|
7
|
-
import { generateArtifacts } from "../iris/artifacts/generator.js";
|
|
8
|
-
export const generateCommand = new Command("generate")
|
|
9
|
-
.alias("gen")
|
|
10
|
-
.description("Synthesize artifacts from an intent draft")
|
|
11
|
-
.option("-i, --in <path>", "Input draft file (default: .iris/inbox/intent-draft.latest.json)")
|
|
12
|
-
.option("-o, --out <path>", "Output artifacts file")
|
|
13
|
-
.option("--json", "Output JSON to stdout")
|
|
14
|
-
.action(async (opts) => {
|
|
15
|
-
try {
|
|
16
|
-
// 1. Resolve Framework
|
|
17
|
-
const root = process.cwd();
|
|
18
|
-
const projectRoot = root; // Assume CWD is root for now
|
|
19
|
-
const { resolution } = await resolveActiveFramework(projectRoot);
|
|
20
|
-
// resolveActiveFramework returns { resolution, activeFlowId? }
|
|
21
|
-
const artifactsConfig = loadEffectiveArtifactsConfig(resolution);
|
|
22
|
-
// 2. Load Draft
|
|
23
|
-
let draftPath = opts.in;
|
|
24
|
-
if (!draftPath) {
|
|
25
|
-
draftPath = path.join(projectRoot, ".iris", "inbox", "intent-draft.latest.json");
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
draftPath = path.resolve(process.cwd(), draftPath); // Resolve relative to CWD
|
|
29
|
-
}
|
|
30
|
-
if (!fs.existsSync(draftPath)) {
|
|
31
|
-
console.error(kleur.red(`Error: Draft file not found at ${draftPath}`));
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
const draftContent = fs.readFileSync(draftPath, "utf8");
|
|
35
|
-
const draft = JSON.parse(draftContent);
|
|
36
|
-
// 3. Generate
|
|
37
|
-
const output = generateArtifacts(draft, artifactsConfig, resolution);
|
|
38
|
-
// 4. Output
|
|
39
|
-
const jsonStr = JSON.stringify(output, null, 2);
|
|
40
|
-
if (opts.out) {
|
|
41
|
-
const outPath = path.resolve(process.cwd(), opts.out);
|
|
42
|
-
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
43
|
-
fs.writeFileSync(outPath, jsonStr);
|
|
44
|
-
if (!opts.json) {
|
|
45
|
-
console.log(kleur.green(`Artifacts generated at ${outPath}`));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else if (!opts.json) {
|
|
49
|
-
console.log(jsonStr);
|
|
50
|
-
}
|
|
51
|
-
if (opts.json) {
|
|
52
|
-
console.log(jsonStr);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
console.error(kleur.red(`Generation Failed: ${error.message}`));
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
});
|