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/iris/packer.js
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import kleur from "kleur";
|
|
4
|
-
import { repoRoot, writeFile, ensureDir } from "../lib.js";
|
|
5
|
-
import { loadState } from "./state.js";
|
|
6
|
-
import { loadEffectivePolicy } from "./policy.js";
|
|
7
|
-
import { validate } from "./validator.js";
|
|
8
|
-
import { resolveIncludes, getFileContent } from "./include.js";
|
|
9
|
-
import { checkArtifact } from "./artifact-checker.js";
|
|
10
|
-
import { collectDoctrineFiles } from "./doctrine/collector.js";
|
|
11
|
-
export async function generatePack(options) {
|
|
12
|
-
const root = repoRoot();
|
|
13
|
-
// 1. Validate Repo (Guardrail)
|
|
14
|
-
try {
|
|
15
|
-
const result = await validate({
|
|
16
|
-
apply: false,
|
|
17
|
-
strict: false,
|
|
18
|
-
writeBack: false,
|
|
19
|
-
frameworkResolution: options.frameworkResolution
|
|
20
|
-
});
|
|
21
|
-
if (!result.valid) {
|
|
22
|
-
const msg = !options.quiet ? kleur.red("Repo is INVALID. Fix issues before packing.") : "Repo is INVALID";
|
|
23
|
-
if (!options.quiet)
|
|
24
|
-
console.error(msg);
|
|
25
|
-
throw new Error(typeof msg === 'string' ? msg : "Repo is INVALID");
|
|
26
|
-
}
|
|
27
|
-
if (options.strict && result.warnings) {
|
|
28
|
-
const msg = !options.quiet ? kleur.red("Repo has warnings and strict mode is on.") : "Repo has warnings";
|
|
29
|
-
if (!options.quiet)
|
|
30
|
-
console.error(msg);
|
|
31
|
-
throw new Error(typeof msg === 'string' ? msg : "Repo has warnings");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
catch (e) {
|
|
35
|
-
// If policy loading fails, we should catch it here
|
|
36
|
-
if (!options.quiet)
|
|
37
|
-
console.error("Validation failed:", e);
|
|
38
|
-
throw new Error(`Validation failed: ${e.message}`);
|
|
39
|
-
}
|
|
40
|
-
// 2. Load State & Determine Context
|
|
41
|
-
const state = loadState();
|
|
42
|
-
const phase = options.phase || state.phase.current;
|
|
43
|
-
const agent = options.agent || inferAgent(phase);
|
|
44
|
-
// 3. Collect Candidates
|
|
45
|
-
// Doctrine
|
|
46
|
-
const doctrineFiles = collectDoctrine(root, state.active.flow);
|
|
47
|
-
// Required Artifacts
|
|
48
|
-
const requiredArtifacts = collectRequiredArtifacts(phase, state, options.frameworkResolution);
|
|
49
|
-
// Optional Artifacts
|
|
50
|
-
const optionalArtifacts = collectOptionalArtifacts(phase);
|
|
51
|
-
// Included Artifacts
|
|
52
|
-
const includedFiles = options.includes && options.includes.length > 0
|
|
53
|
-
? await resolveIncludes(options.includes, options.excludes)
|
|
54
|
-
: [];
|
|
55
|
-
// 4. Read & Assemble
|
|
56
|
-
// Core (Doctrine + Required) - Must be included
|
|
57
|
-
const coreContent = [];
|
|
58
|
-
for (const p of [...doctrineFiles, ...requiredArtifacts]) {
|
|
59
|
-
// Required files generally SHOULD exist, but if missing, we record them
|
|
60
|
-
// Doctrine: "If a file is missing, skip it but record in the bundle '(missing)' list."
|
|
61
|
-
// Required Artifacts: "If required file missing -> pack must fail (exit 2)"
|
|
62
|
-
const res = getFileContent(p);
|
|
63
|
-
// Check requirement for artifacts (not doctrine)
|
|
64
|
-
if (requiredArtifacts.includes(p)) {
|
|
65
|
-
// Use artifact checker for proper validation
|
|
66
|
-
const check = checkArtifact(root, p);
|
|
67
|
-
if (!check.exists) {
|
|
68
|
-
const msg = `Missing required artifact: ${check.normalized}`;
|
|
69
|
-
if (!options.quiet)
|
|
70
|
-
console.error(kleur.red(msg));
|
|
71
|
-
throw new Error(msg);
|
|
72
|
-
}
|
|
73
|
-
// For files, also check if content was readable
|
|
74
|
-
// Absolute path fix in resolver.ts implies this works now
|
|
75
|
-
if (check.isFile && res.skipped === "read_error") {
|
|
76
|
-
const msg = `Cannot read required artifact: ${check.normalized}`;
|
|
77
|
-
if (!options.quiet)
|
|
78
|
-
console.error(kleur.red(msg));
|
|
79
|
-
throw new Error(msg);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
coreContent.push(res);
|
|
83
|
-
}
|
|
84
|
-
// Optional - Can be dropped
|
|
85
|
-
const optionalContent = [];
|
|
86
|
-
for (const p of optionalArtifacts) {
|
|
87
|
-
// Optional artifacts usually are logs/bolts which are repo-local.
|
|
88
|
-
// getFileContent resolves them. If they don't exist, we skip.
|
|
89
|
-
const res = getFileContent(p);
|
|
90
|
-
if (res.skipped === "read_error" || res.size === 0)
|
|
91
|
-
continue;
|
|
92
|
-
optionalContent.push(res);
|
|
93
|
-
}
|
|
94
|
-
// Includes - Can be dropped
|
|
95
|
-
const extraContent = [];
|
|
96
|
-
for (const p of includedFiles) {
|
|
97
|
-
extraContent.push(getFileContent(p));
|
|
98
|
-
}
|
|
99
|
-
// 5. Enforce Limits
|
|
100
|
-
const maxBytes = options.maxBytes || 1_500_000;
|
|
101
|
-
const finalSelection = enforceLimits(coreContent, optionalContent, extraContent, maxBytes, options.quiet);
|
|
102
|
-
// 6. Format
|
|
103
|
-
const markdown = formatBundle(finalSelection, {
|
|
104
|
-
repo: path.basename(root),
|
|
105
|
-
phase,
|
|
106
|
-
agent,
|
|
107
|
-
generatedAt: new Date().toISOString()
|
|
108
|
-
});
|
|
109
|
-
// 7. Output
|
|
110
|
-
if (options.stdout && !options.json) {
|
|
111
|
-
console.log(markdown);
|
|
112
|
-
if (options.output) {
|
|
113
|
-
writeFile(options.output, markdown);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
const outFile = options.output || path.join(root, `.iris/inbox/context-${phase}-${agent}.md`);
|
|
118
|
-
let fileWritten = false;
|
|
119
|
-
if (!options.stdout) {
|
|
120
|
-
writeFile(outFile, markdown);
|
|
121
|
-
// Write LATEST
|
|
122
|
-
const latestFile = path.join(root, ".iris/inbox/LATEST.md");
|
|
123
|
-
ensureDir(path.dirname(latestFile));
|
|
124
|
-
const relPath = path.relative(path.dirname(latestFile), outFile);
|
|
125
|
-
writeFile(latestFile, relPath);
|
|
126
|
-
fileWritten = true;
|
|
127
|
-
}
|
|
128
|
-
const allCount = finalSelection.core.length + finalSelection.optional.length + finalSelection.extra.length;
|
|
129
|
-
const result = {
|
|
130
|
-
path: fileWritten ? outFile : "stdout",
|
|
131
|
-
size: markdown.length,
|
|
132
|
-
fileCount: allCount
|
|
133
|
-
};
|
|
134
|
-
if (options.json && !options.quiet) {
|
|
135
|
-
console.log(JSON.stringify(result, null, 2));
|
|
136
|
-
}
|
|
137
|
-
else if (!options.stdout && !options.quiet) {
|
|
138
|
-
console.log(kleur.green(`Packed context bundle to: ${outFile}`));
|
|
139
|
-
console.log(kleur.gray(`Size: ${(markdown.length / 1024).toFixed(1)} KB`));
|
|
140
|
-
}
|
|
141
|
-
return result;
|
|
142
|
-
}
|
|
143
|
-
return {
|
|
144
|
-
path: options.output || "stdout",
|
|
145
|
-
size: markdown.length,
|
|
146
|
-
fileCount: finalSelection.core.length + finalSelection.optional.length + finalSelection.extra.length
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
function inferAgent(phase) {
|
|
150
|
-
switch (phase) {
|
|
151
|
-
case "inception": return "inception";
|
|
152
|
-
case "construction": return "construction";
|
|
153
|
-
case "operations": return "operations";
|
|
154
|
-
default: return "master";
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function collectDoctrine(root, activeFlowId) {
|
|
158
|
-
// Replaced legacy hardcoded list with flow-aware collector
|
|
159
|
-
return collectDoctrineFiles(root, activeFlowId);
|
|
160
|
-
}
|
|
161
|
-
function collectRequiredArtifacts(phase, state, framework) {
|
|
162
|
-
const list = [
|
|
163
|
-
".iris/state.yaml",
|
|
164
|
-
".iris/policy.yaml"
|
|
165
|
-
];
|
|
166
|
-
if (fs.existsSync(path.join(repoRoot(), ".iris/routes.yaml")))
|
|
167
|
-
list.push(".iris/routes.yaml");
|
|
168
|
-
if (fs.existsSync(path.join(repoRoot(), ".iris/manifest.yaml")))
|
|
169
|
-
list.push(".iris/manifest.yaml");
|
|
170
|
-
// Use Policy Source of Truth
|
|
171
|
-
try {
|
|
172
|
-
const policy = loadEffectivePolicy(framework, undefined, state.active.flow);
|
|
173
|
-
if (policy.phases[phase] && policy.phases[phase].requires) {
|
|
174
|
-
for (const req of policy.phases[phase].requires) {
|
|
175
|
-
list.push(req.path);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
catch (e) {
|
|
180
|
-
// Fallback or ignore if policy broken (validator should have caught it)
|
|
181
|
-
}
|
|
182
|
-
return list;
|
|
183
|
-
}
|
|
184
|
-
function collectOptionalArtifacts(phase) {
|
|
185
|
-
const list = [];
|
|
186
|
-
const root = repoRoot();
|
|
187
|
-
if (phase === "inception") {
|
|
188
|
-
if (fs.existsSync(path.join(root, "memory-bank/intents/intent.md"))) {
|
|
189
|
-
list.push("memory-bank/intents/intent.md");
|
|
190
|
-
}
|
|
191
|
-
list.push(...getLatestFiles(path.join(root, "memory-bank/logs"), 5));
|
|
192
|
-
}
|
|
193
|
-
else if (phase === "construction") {
|
|
194
|
-
list.push(...getLatestFiles(path.join(root, "memory-bank/bolts"), 5));
|
|
195
|
-
list.push(...getLatestFiles(path.join(root, "memory-bank/logs"), 5));
|
|
196
|
-
}
|
|
197
|
-
else if (phase === "operations") {
|
|
198
|
-
list.push(...getLatestFiles(path.join(root, "memory-bank/logs"), 10));
|
|
199
|
-
list.push(...getLatestFiles(path.join(root, "memory-bank/standards"), 5));
|
|
200
|
-
}
|
|
201
|
-
return list;
|
|
202
|
-
}
|
|
203
|
-
function getLatestFiles(dir, count) {
|
|
204
|
-
const root = repoRoot();
|
|
205
|
-
if (!fs.existsSync(dir))
|
|
206
|
-
return [];
|
|
207
|
-
const files = fs.readdirSync(dir)
|
|
208
|
-
.map(f => path.join(dir, f))
|
|
209
|
-
.filter(f => fs.statSync(f).isFile())
|
|
210
|
-
.map(f => ({ path: path.relative(root, f), mtime: fs.statSync(f).mtime.getTime() }))
|
|
211
|
-
.sort((a, b) => {
|
|
212
|
-
if (b.mtime !== a.mtime)
|
|
213
|
-
return b.mtime - a.mtime; // Descending time
|
|
214
|
-
return a.path.localeCompare(b.path); // Tie-break name
|
|
215
|
-
});
|
|
216
|
-
return files.slice(0, count).map(f => f.path);
|
|
217
|
-
}
|
|
218
|
-
function enforceLimits(core, optional, extra, maxBytes, quiet) {
|
|
219
|
-
let currentSize = sumSize(core) + sumSize(optional) + sumSize(extra);
|
|
220
|
-
const errors = [];
|
|
221
|
-
const skipped = [];
|
|
222
|
-
// 1. Reduce Optional
|
|
223
|
-
while (currentSize > maxBytes && optional.length > 0) {
|
|
224
|
-
const removed = optional.pop(); // Remove from end (which are older logs/bolts usually!)
|
|
225
|
-
// Wait, collectOptionalArtifacts sorted by latest first.
|
|
226
|
-
// So pop() removes the OLDEST (least relevant). Correct.
|
|
227
|
-
if (removed) {
|
|
228
|
-
currentSize -= (removed.size || 0);
|
|
229
|
-
skipped.push(removed.path);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
// 2. Reduce Extra
|
|
233
|
-
while (currentSize > maxBytes && extra.length > 0) {
|
|
234
|
-
const removed = extra.pop(); // Remove from end of glob list (arbitrary?)
|
|
235
|
-
if (removed) {
|
|
236
|
-
currentSize -= (removed.size || 0);
|
|
237
|
-
skipped.push(removed.path);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
if (currentSize > maxBytes) {
|
|
241
|
-
// Hard fail if Core is too big?
|
|
242
|
-
if (!quiet)
|
|
243
|
-
console.error(kleur.red(`Bundle size (${currentSize}) exceeds --max-bytes limit (${maxBytes}) even after trimming optional content.`));
|
|
244
|
-
if (!quiet)
|
|
245
|
-
console.error("Required content is too large. Increase limit or clean up artifacts.");
|
|
246
|
-
throw new Error(`Bundle size exceeds limit ${maxBytes}`);
|
|
247
|
-
}
|
|
248
|
-
return {
|
|
249
|
-
core,
|
|
250
|
-
optional,
|
|
251
|
-
extra,
|
|
252
|
-
skipped
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
function sumSize(files) {
|
|
256
|
-
return files.reduce((acc, f) => acc + (f.content ? f.content.length : 0), 0);
|
|
257
|
-
}
|
|
258
|
-
function formatBundle(selection, meta) {
|
|
259
|
-
const { core, optional, extra, skipped } = selection;
|
|
260
|
-
let out = `# IRIS Context Pack\n\n`;
|
|
261
|
-
out += `## Metadata\n`;
|
|
262
|
-
out += `- Generated: ${meta.generatedAt}\n`;
|
|
263
|
-
out += `- Repo: ${meta.repo}\n`;
|
|
264
|
-
out += `- Phase: ${meta.phase}\n`;
|
|
265
|
-
out += `- Agent: ${meta.agent}\n`;
|
|
266
|
-
out += `- Navi: 0.0.07\n\n`; // Hardcoded version for now or read pkg
|
|
267
|
-
out += `## How to use\n`;
|
|
268
|
-
out += `- Run: /iris-${meta.agent}-agent\n`;
|
|
269
|
-
out += `- This bundle contains doctrine + required artifacts.\n\n`;
|
|
270
|
-
// Groups
|
|
271
|
-
const all = [...core, ...optional, ...extra];
|
|
272
|
-
const doctrine = all.filter(f => f.path.startsWith(".iris/aidlc"));
|
|
273
|
-
const stateFiles = all.filter(f => f.path.startsWith(".iris/") && !f.path.startsWith(".iris/aidlc"));
|
|
274
|
-
const memory = all.filter(f => f.path.startsWith("memory-bank/"));
|
|
275
|
-
const others = all.filter(f => !f.path.startsWith(".iris/") && !f.path.startsWith("memory-bank/"));
|
|
276
|
-
const printer = (title, files) => {
|
|
277
|
-
if (files.length === 0)
|
|
278
|
-
return;
|
|
279
|
-
out += `## ${title}\n\n`;
|
|
280
|
-
files.forEach((f, idx) => {
|
|
281
|
-
if (f.skipped) {
|
|
282
|
-
// Should list in skipped section?
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
if (!f.content && !f.skipped) {
|
|
286
|
-
// Missing file (e.g. Doctrine missing)
|
|
287
|
-
out += `### [${idx + 1}] ${f.path} (MISSING)\n\n`;
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
out += `### [${idx + 1}] ${f.path}\n`;
|
|
291
|
-
out += "```" + detectLang(f.path) + "\n";
|
|
292
|
-
out += f.content + "\n";
|
|
293
|
-
out += "```\n\n";
|
|
294
|
-
});
|
|
295
|
-
};
|
|
296
|
-
printer("Doctrine (Load Order)", doctrine);
|
|
297
|
-
printer("Repo State", stateFiles);
|
|
298
|
-
printer("Memory Bank", memory);
|
|
299
|
-
printer("Included Context", others);
|
|
300
|
-
// Missing / Skipped
|
|
301
|
-
const missing = all.filter(f => !f.content && !f.skipped).map(f => f.path);
|
|
302
|
-
const skippedReasons = all.filter(f => f.skipped).map(f => `${f.path} (${f.skipped})`);
|
|
303
|
-
const droppedLimits = skipped;
|
|
304
|
-
if (missing.length > 0 || skippedReasons.length > 0 || droppedLimits.length > 0) {
|
|
305
|
-
out += `## Missing / Skipped Files\n\n`;
|
|
306
|
-
missing.forEach(p => out += `* ${p} (missing)\n`);
|
|
307
|
-
skippedReasons.forEach(p => out += `* ${p}\n`);
|
|
308
|
-
droppedLimits.forEach(p => out += `* ${p} (dropped for size)\n`);
|
|
309
|
-
}
|
|
310
|
-
return out;
|
|
311
|
-
}
|
|
312
|
-
function detectLang(p) {
|
|
313
|
-
const ext = path.extname(p);
|
|
314
|
-
if (ext === ".md")
|
|
315
|
-
return "markdown";
|
|
316
|
-
if (ext === ".yaml")
|
|
317
|
-
return "yaml";
|
|
318
|
-
if (ext === ".json")
|
|
319
|
-
return "json";
|
|
320
|
-
if (ext === ".ts")
|
|
321
|
-
return "typescript";
|
|
322
|
-
if (ext === ".js")
|
|
323
|
-
return "javascript";
|
|
324
|
-
return "";
|
|
325
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export function parseUnitList(content) {
|
|
2
|
-
const lines = content.split('\n');
|
|
3
|
-
const units = [];
|
|
4
|
-
let currentUnit = null;
|
|
5
|
-
for (const line of lines) {
|
|
6
|
-
// 1. Check for Unit Header: - [ ] U001: Title
|
|
7
|
-
const headerMatch = line.match(/^- \[([ x])\] (U\d+): (.+)$/);
|
|
8
|
-
if (headerMatch) {
|
|
9
|
-
if (currentUnit) {
|
|
10
|
-
units.push(currentUnit);
|
|
11
|
-
}
|
|
12
|
-
const isChecked = headerMatch[1] === 'x';
|
|
13
|
-
currentUnit = {
|
|
14
|
-
id: headerMatch[2],
|
|
15
|
-
title: headerMatch[3].trim(),
|
|
16
|
-
summary: '',
|
|
17
|
-
status: isChecked ? 'done' : 'todo'
|
|
18
|
-
};
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
// 2. Check for Summary: summary: ... (must be indented)
|
|
22
|
-
// We only accept lines starting with whitespace + "summary:"
|
|
23
|
-
if (currentUnit) {
|
|
24
|
-
const summaryMatch = line.match(/^\s+summary:\s*(.+)$/);
|
|
25
|
-
if (summaryMatch) {
|
|
26
|
-
currentUnit.summary = summaryMatch[1].trim();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// Ignore other lines
|
|
30
|
-
}
|
|
31
|
-
if (currentUnit) {
|
|
32
|
-
units.push(currentUnit);
|
|
33
|
-
}
|
|
34
|
-
// Validate unique IDs
|
|
35
|
-
const ids = new Set();
|
|
36
|
-
for (const u of units) {
|
|
37
|
-
if (ids.has(u.id)) {
|
|
38
|
-
throw new Error(`Duplicate Unit ID found: ${u.id}`);
|
|
39
|
-
}
|
|
40
|
-
ids.add(u.id);
|
|
41
|
-
}
|
|
42
|
-
return units;
|
|
43
|
-
}
|
package/dist/iris/paths.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
export const IRIS_DOT_DIR = ".iris";
|
|
3
|
-
export const IRIS_INBOX_DIR = path.join(IRIS_DOT_DIR, "inbox");
|
|
4
|
-
export const INTENT_DRAFT_LATEST_FILE = "intent-draft.latest.json";
|
|
5
|
-
export const INTENT_DRAFT_LEGACY_FILE = "intent-draft.json";
|
|
6
|
-
export function getInboxPath(root) {
|
|
7
|
-
return path.join(root, IRIS_INBOX_DIR);
|
|
8
|
-
}
|
|
9
|
-
export function getLatestDraftPath(root) {
|
|
10
|
-
return path.join(getInboxPath(root), INTENT_DRAFT_LATEST_FILE);
|
|
11
|
-
}
|
|
12
|
-
export function getLegacyDraftPath(root) {
|
|
13
|
-
return path.join(getInboxPath(root), INTENT_DRAFT_LEGACY_FILE);
|
|
14
|
-
}
|
|
15
|
-
export function getHistoryDraftPath(root, timestamp) {
|
|
16
|
-
const ts = timestamp.toISOString().replace(/[-:T]/g, "").split(".")[0];
|
|
17
|
-
return path.join(getInboxPath(root), `intent-draft-${ts}.json`);
|
|
18
|
-
}
|
package/dist/iris/policy.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import yaml from "js-yaml";
|
|
4
|
-
import kleur from "kleur";
|
|
5
|
-
export class PolicyError extends Error {
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = "PolicyError";
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
export class PolicyLoadError extends PolicyError {
|
|
12
|
-
cause;
|
|
13
|
-
constructor(message, cause) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.cause = cause;
|
|
16
|
-
this.name = "PolicyLoadError";
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
import { resolveArtifactPath } from "./resolver.js";
|
|
20
|
-
import { repoRoot } from "../lib.js";
|
|
21
|
-
// --- Loaders ---
|
|
22
|
-
/**
|
|
23
|
-
* Loads the base policy from the active framework OR fallback to legacy .iris/policy.yaml.
|
|
24
|
-
*/
|
|
25
|
-
export function loadBasePolicy(framework, root) {
|
|
26
|
-
try {
|
|
27
|
-
const r = root || repoRoot();
|
|
28
|
-
// 1. Framework Priority
|
|
29
|
-
if (framework && framework.files.policy && fs.existsSync(framework.files.policy)) {
|
|
30
|
-
const content = fs.readFileSync(framework.files.policy, "utf8");
|
|
31
|
-
return parsePolicy(content);
|
|
32
|
-
}
|
|
33
|
-
// 2. Legacy Fallback
|
|
34
|
-
const legacyPath = resolveArtifactPath(r, ".iris/policy.yaml");
|
|
35
|
-
if (fs.existsSync(legacyPath)) {
|
|
36
|
-
if (framework) {
|
|
37
|
-
console.error(kleur.yellow(`IRIS_WARNING IRIS_DEPRECATED_LEGACY_POLICY: framework=${framework.manifest.id} missing policy.yaml; using .iris/policy.yaml`));
|
|
38
|
-
}
|
|
39
|
-
const content = fs.readFileSync(legacyPath, "utf8");
|
|
40
|
-
return parsePolicy(content);
|
|
41
|
-
}
|
|
42
|
-
// 3. Hard Failure
|
|
43
|
-
throw new PolicyLoadError(`Missing required policy file. No active framework policy and no .iris/policy.yaml found at ${legacyPath}`);
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
if (error instanceof PolicyError)
|
|
47
|
-
throw error;
|
|
48
|
-
throw new PolicyLoadError("Failed to load base policy", error);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function parsePolicy(content) {
|
|
52
|
-
const doc = yaml.load(content);
|
|
53
|
-
// Basic structural check
|
|
54
|
-
if (!doc || !doc.phases || !doc.transitions) {
|
|
55
|
-
throw new PolicyLoadError("Invalid base policy format: 'phases' and 'transitions' are required.");
|
|
56
|
-
}
|
|
57
|
-
return doc;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Legacy alias for backward compatibility or simple usage.
|
|
61
|
-
*/
|
|
62
|
-
export const loadPolicy = (root) => loadBasePolicy(null, root);
|
|
63
|
-
/**
|
|
64
|
-
* Loads the Effective Policy: Base + User Repo Overlay.
|
|
65
|
-
*/
|
|
66
|
-
export function loadEffectivePolicy(framework, root, activeFlowId) {
|
|
67
|
-
const r = root || repoRoot();
|
|
68
|
-
const base = loadBasePolicy(framework, r);
|
|
69
|
-
// Determine Overlay Namespace: Flow ID (if active) OR Framework ID (if loaded)
|
|
70
|
-
const overlayNamespace = activeFlowId || framework?.manifest.id;
|
|
71
|
-
if (!overlayNamespace) {
|
|
72
|
-
return base;
|
|
73
|
-
}
|
|
74
|
-
try {
|
|
75
|
-
// User Repo Overlay: .iris/overlays/<namespace>/policy.yaml
|
|
76
|
-
const overlayPath = path.join(r, ".iris/overlays", overlayNamespace, "policy.yaml");
|
|
77
|
-
if (fs.existsSync(overlayPath)) {
|
|
78
|
-
const content = fs.readFileSync(overlayPath, "utf8");
|
|
79
|
-
const overlay = (yaml.load(content) || {});
|
|
80
|
-
return mergePolicies(base, overlay);
|
|
81
|
-
}
|
|
82
|
-
// Return base if no overlay
|
|
83
|
-
return base;
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
if (error instanceof PolicyError)
|
|
87
|
-
throw error;
|
|
88
|
-
throw new PolicyLoadError(`Failed to load effective policy for namespace '${overlayNamespace}'`, error);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Merges a base policy with an overlay policy purely.
|
|
93
|
-
*/
|
|
94
|
-
export function mergePolicies(base, overlay) {
|
|
95
|
-
// Deep clone base using JSON serialization
|
|
96
|
-
const result = JSON.parse(JSON.stringify(base));
|
|
97
|
-
if (!overlay.phases)
|
|
98
|
-
return result;
|
|
99
|
-
for (const [phaseName, overlayPhase] of Object.entries(overlay.phases)) {
|
|
100
|
-
if (!overlayPhase)
|
|
101
|
-
continue;
|
|
102
|
-
// If base doesn't have this phase, initialize it
|
|
103
|
-
if (!result.phases[phaseName]) {
|
|
104
|
-
result.phases[phaseName] = { requires: [], gates: [] };
|
|
105
|
-
}
|
|
106
|
-
const basePhase = result.phases[phaseName];
|
|
107
|
-
// 1. Merge Requirements (Union by path)
|
|
108
|
-
if (overlayPhase.requires && Array.isArray(overlayPhase.requires)) {
|
|
109
|
-
const baseMap = new Map();
|
|
110
|
-
(basePhase.requires || []).forEach((r, idx) => baseMap.set(r.path, idx));
|
|
111
|
-
if (!basePhase.requires)
|
|
112
|
-
basePhase.requires = [];
|
|
113
|
-
for (const req of overlayPhase.requires) {
|
|
114
|
-
if (baseMap.has(req.path)) {
|
|
115
|
-
// OVERRIDE in place
|
|
116
|
-
const idx = baseMap.get(req.path);
|
|
117
|
-
basePhase.requires[idx] = { ...basePhase.requires[idx], ...req };
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
// APPEND
|
|
121
|
-
basePhase.requires.push(req);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
// 2. Merge Gates (Concatenate)
|
|
126
|
-
if (overlayPhase.gates && Array.isArray(overlayPhase.gates)) {
|
|
127
|
-
if (!basePhase.gates)
|
|
128
|
-
basePhase.gates = [];
|
|
129
|
-
basePhase.gates.push(...overlayPhase.gates);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return result;
|
|
133
|
-
}
|
package/dist/iris/proc.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'child_process';
|
|
2
|
-
export class ExecError extends Error {
|
|
3
|
-
command;
|
|
4
|
-
args;
|
|
5
|
-
result;
|
|
6
|
-
constructor(command, args, result) {
|
|
7
|
-
super(`Command failed with code ${result.code}: ${command} ${args.join(' ')}\nStderr: ${result.stderr}`);
|
|
8
|
-
this.command = command;
|
|
9
|
-
this.args = args;
|
|
10
|
-
this.result = result;
|
|
11
|
-
this.name = 'ExecError';
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export async function runCmd(cmd, args, opts = { cwd: process.cwd() }) {
|
|
15
|
-
return new Promise((resolve, reject) => {
|
|
16
|
-
if (opts.verbose) {
|
|
17
|
-
console.log(`> ${cmd} ${args.join(' ')} (in ${opts.cwd})`);
|
|
18
|
-
}
|
|
19
|
-
const child = spawn(cmd, args, {
|
|
20
|
-
cwd: opts.cwd,
|
|
21
|
-
env: { ...process.env, ...opts.env },
|
|
22
|
-
shell: false, // Safer to not use shell
|
|
23
|
-
stdio: 'pipe',
|
|
24
|
-
});
|
|
25
|
-
let stdout = '';
|
|
26
|
-
let stderr = '';
|
|
27
|
-
child.stdout.on('data', (data) => {
|
|
28
|
-
const chunk = data.toString();
|
|
29
|
-
stdout += chunk;
|
|
30
|
-
if (opts.verbose)
|
|
31
|
-
process.stdout.write(chunk);
|
|
32
|
-
});
|
|
33
|
-
child.stderr.on('data', (data) => {
|
|
34
|
-
const chunk = data.toString();
|
|
35
|
-
stderr += chunk;
|
|
36
|
-
if (opts.verbose)
|
|
37
|
-
process.stderr.write(chunk);
|
|
38
|
-
});
|
|
39
|
-
child.on('error', (err) => {
|
|
40
|
-
reject(err);
|
|
41
|
-
});
|
|
42
|
-
child.on('close', (code) => {
|
|
43
|
-
const result = {
|
|
44
|
-
code: code ?? 1, // Treat signal termination as error code 1
|
|
45
|
-
stdout,
|
|
46
|
-
stderr,
|
|
47
|
-
};
|
|
48
|
-
if (code === 0) {
|
|
49
|
-
resolve(result);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
reject(new ExecError(cmd, args, result));
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
}
|
package/dist/iris/report.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import kleur from "kleur";
|
|
2
|
-
export function printReport(result, json = false, fixResult, strict = false) {
|
|
3
|
-
if (json) {
|
|
4
|
-
console.log(JSON.stringify({
|
|
5
|
-
valid: result.valid,
|
|
6
|
-
warnings: result.warnings,
|
|
7
|
-
errors: result.errors,
|
|
8
|
-
fix_result: fixResult // Optional
|
|
9
|
-
}, null, 2));
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
if (fixResult) {
|
|
13
|
-
console.log("");
|
|
14
|
-
console.log(kleur.bold().green("Applied fixes:"));
|
|
15
|
-
if (fixResult.paths.length === 0) {
|
|
16
|
-
console.log(kleur.gray(" (None needed)"));
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
for (const p of fixResult.paths) {
|
|
20
|
-
console.log(kleur.green(` + Created: ${p}`));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
console.log("");
|
|
24
|
-
console.log(kleur.bold(`Remaining issues (${result.errors.length}):`));
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
if (result.valid && !result.warnings) {
|
|
28
|
-
console.log(kleur.green("✓ Repository is valid."));
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (!result.valid) {
|
|
32
|
-
console.log(kleur.red(`✗ Validation failed with ${result.errors.length} error(s):`));
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
if (strict) {
|
|
36
|
-
console.log(kleur.red("✗ Validation FAILED (strict) due to warnings:"));
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
console.log(kleur.yellow("! Validation PASSED with warnings:"));
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// Print errors
|
|
44
|
-
for (const err of result.errors) {
|
|
45
|
-
const icon = err.severity === "warning" ? kleur.yellow("!") : kleur.red("x");
|
|
46
|
-
const code = kleur.dim(`[${err.code}]`);
|
|
47
|
-
// If fixed, skip? No, this function prints current result.
|
|
48
|
-
// If called after fix, these are remaining errors.
|
|
49
|
-
console.log(` ${icon} ${code} ${err.message}`);
|
|
50
|
-
if (err.path)
|
|
51
|
-
console.log(kleur.dim(` Path: ${err.path}`));
|
|
52
|
-
}
|
|
53
|
-
}
|