@wairon/cli 5.1.1-dev.60 → 5.1.1-dev.61
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/dist/cli/index.js +384 -371
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +521 -537
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -65,7 +65,7 @@ var init_defaults = __esm({
|
|
|
65
65
|
copilot: ".github/prompts",
|
|
66
66
|
codex: ".codex/agents"
|
|
67
67
|
};
|
|
68
|
-
WAIRON_VERSION = "5.1.1-dev.
|
|
68
|
+
WAIRON_VERSION = "5.1.1-dev.61";
|
|
69
69
|
GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
70
70
|
SUPPORTED_ALIASES = ["wai"];
|
|
71
71
|
SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -23826,313 +23826,6 @@ var init_skills = __esm({
|
|
|
23826
23826
|
}
|
|
23827
23827
|
});
|
|
23828
23828
|
|
|
23829
|
-
// src/core/stamp.ts
|
|
23830
|
-
function versionStamp() {
|
|
23831
|
-
return `<!-- wairon-version: ${WAIRON_VERSION} -->`;
|
|
23832
|
-
}
|
|
23833
|
-
function readStampVersion(content) {
|
|
23834
|
-
const m = content.match(STAMP_RE);
|
|
23835
|
-
return m ? m[1] : null;
|
|
23836
|
-
}
|
|
23837
|
-
var STAMP_RE;
|
|
23838
|
-
var init_stamp = __esm({
|
|
23839
|
-
"src/core/stamp.ts"() {
|
|
23840
|
-
"use strict";
|
|
23841
|
-
init_defaults();
|
|
23842
|
-
STAMP_RE = /<!--\s*wairon-version:\s*([^\s]+)\s*-->/;
|
|
23843
|
-
}
|
|
23844
|
-
});
|
|
23845
|
-
|
|
23846
|
-
// src/utils/ai-guide.ts
|
|
23847
|
-
function globalGuideFilePath(targetType) {
|
|
23848
|
-
if (targetType === "claude") return path24.join(process.env["CLAUDE_CONFIG_DIR"] || path24.join(os5.homedir(), ".claude"), "CLAUDE.md");
|
|
23849
|
-
if (targetType === "gemini") return path24.join(process.env["GEMINI_CONFIG_DIR"] || path24.join(os5.homedir(), ".gemini"), "GEMINI.md");
|
|
23850
|
-
return null;
|
|
23851
|
-
}
|
|
23852
|
-
function localGuideFilePath(projectRoot2, targetType) {
|
|
23853
|
-
if (targetType === "claude") return path24.join(projectRoot2, ".claude", "CLAUDE.md");
|
|
23854
|
-
if (targetType === "gemini" || targetType === "agy") return path24.join(projectRoot2, ".gemini", "GEMINI.md");
|
|
23855
|
-
return null;
|
|
23856
|
-
}
|
|
23857
|
-
function injectGuide(filePath, scope) {
|
|
23858
|
-
const body = scope === "global" ? GLOBAL_GUIDE_BODY : LOCAL_GUIDE_BODY;
|
|
23859
|
-
const section = `
|
|
23860
|
-
|
|
23861
|
-
${GUIDE_MARKER_START}
|
|
23862
|
-
${versionStamp()}
|
|
23863
|
-
${body}
|
|
23864
|
-
${GUIDE_MARKER_END}
|
|
23865
|
-
`;
|
|
23866
|
-
const existing = fs19.existsSync(filePath) ? fs19.readFileSync(filePath, "utf-8") : "";
|
|
23867
|
-
const stripped = stripGuideSection(existing);
|
|
23868
|
-
const newContent = stripped.trimEnd() + section;
|
|
23869
|
-
fs19.mkdirSync(path24.dirname(filePath), { recursive: true });
|
|
23870
|
-
fs19.writeFileSync(filePath, newContent, "utf-8");
|
|
23871
|
-
}
|
|
23872
|
-
function stripGuideSection(content) {
|
|
23873
|
-
const start2 = content.indexOf(GUIDE_MARKER_START);
|
|
23874
|
-
const end = content.indexOf(GUIDE_MARKER_END);
|
|
23875
|
-
if (start2 === -1 || end === -1) return content;
|
|
23876
|
-
return content.slice(0, start2) + content.slice(end + GUIDE_MARKER_END.length);
|
|
23877
|
-
}
|
|
23878
|
-
function writeRootGuideDelegator(projectRoot2, targetType) {
|
|
23879
|
-
if (targetType === "claude") {
|
|
23880
|
-
const filePath = path24.join(projectRoot2, "CLAUDE.md");
|
|
23881
|
-
const content = `@.claude/CLAUDE.md
|
|
23882
|
-
|
|
23883
|
-
# Wairon SDD Project
|
|
23884
|
-
|
|
23885
|
-
This project uses the Wairon Spec-Driven Development (SDD) framework. The imported
|
|
23886
|
-
\`.claude/CLAUDE.md\` above is your complete operating guide \u2014 you already have the
|
|
23887
|
-
full context, so don't search the project to learn how wairon or SDD works.
|
|
23888
|
-
|
|
23889
|
-
To design or modify the system, invoke the **\`sdd-architect\`** skill
|
|
23890
|
-
(in \`.claude/skills/\`). Author and validate specs with the \`sdd_*\` MCP tools;
|
|
23891
|
-
the \`wairon\` CLI is the human developer's tool, not yours.
|
|
23892
|
-
`;
|
|
23893
|
-
fs19.writeFileSync(filePath, content, "utf-8");
|
|
23894
|
-
} else if (targetType === "gemini" || targetType === "agy") {
|
|
23895
|
-
const filePath = path24.join(projectRoot2, "GEMINI.md");
|
|
23896
|
-
const content = `# Wairon SDD Project
|
|
23897
|
-
${GUIDE_MARKER_START}
|
|
23898
|
-
${versionStamp()}
|
|
23899
|
-
${LOCAL_GUIDE_BODY}
|
|
23900
|
-
${GUIDE_MARKER_END}
|
|
23901
|
-
`;
|
|
23902
|
-
fs19.writeFileSync(filePath, content, "utf-8");
|
|
23903
|
-
} else if (targetType === "cursor") {
|
|
23904
|
-
const filePath = path24.join(projectRoot2, ".cursorrules");
|
|
23905
|
-
const content = `# Wairon SDD Project
|
|
23906
|
-
|
|
23907
|
-
This project uses the Wairon Spec-Driven Development (SDD) framework.
|
|
23908
|
-
|
|
23909
|
-
Refer to the rules in [.cursor/rules/](.cursor/rules/) for full instructions.
|
|
23910
|
-
`;
|
|
23911
|
-
fs19.writeFileSync(filePath, content, "utf-8");
|
|
23912
|
-
} else if (targetType === "copilot") {
|
|
23913
|
-
const filePath = path24.join(projectRoot2, ".github", "copilot-instructions.md");
|
|
23914
|
-
fs19.mkdirSync(path24.dirname(filePath), { recursive: true });
|
|
23915
|
-
const content = `# Wairon SDD Project
|
|
23916
|
-
|
|
23917
|
-
This project uses the Wairon Spec-Driven Development (SDD) framework.
|
|
23918
|
-
|
|
23919
|
-
Refer to the prompts in [.github/prompts/](.github/prompts/) for instructions.
|
|
23920
|
-
`;
|
|
23921
|
-
fs19.writeFileSync(filePath, content, "utf-8");
|
|
23922
|
-
} else if (targetType === "codex") {
|
|
23923
|
-
const filePath = path24.join(projectRoot2, ".codexrules");
|
|
23924
|
-
const content = `# Wairon SDD Project
|
|
23925
|
-
|
|
23926
|
-
Refer to [.codex/agents/](.codex/agents/) for full instructions.
|
|
23927
|
-
`;
|
|
23928
|
-
fs19.writeFileSync(filePath, content, "utf-8");
|
|
23929
|
-
}
|
|
23930
|
-
}
|
|
23931
|
-
function reinjectLocalGuides(projectRoot2, targetTypes) {
|
|
23932
|
-
const written = [];
|
|
23933
|
-
for (const type of targetTypes) {
|
|
23934
|
-
if (!GUIDE_TARGETS.includes(type)) continue;
|
|
23935
|
-
const guidePath = localGuideFilePath(projectRoot2, type);
|
|
23936
|
-
if (guidePath) {
|
|
23937
|
-
injectGuide(guidePath, "local");
|
|
23938
|
-
if (!written.includes(guidePath)) written.push(guidePath);
|
|
23939
|
-
}
|
|
23940
|
-
writeRootGuideDelegator(projectRoot2, type);
|
|
23941
|
-
}
|
|
23942
|
-
return written;
|
|
23943
|
-
}
|
|
23944
|
-
var fs19, os5, path24, GUIDE_MARKER_START, GUIDE_MARKER_END, GLOBAL_GUIDE_BODY, LOCAL_GUIDE_BODY, GUIDE_TARGETS;
|
|
23945
|
-
var init_ai_guide = __esm({
|
|
23946
|
-
"src/utils/ai-guide.ts"() {
|
|
23947
|
-
"use strict";
|
|
23948
|
-
fs19 = __toESM(require("fs"));
|
|
23949
|
-
os5 = __toESM(require("os"));
|
|
23950
|
-
path24 = __toESM(require("path"));
|
|
23951
|
-
init_stamp();
|
|
23952
|
-
GUIDE_MARKER_START = "<!-- wairon-guide-start -->";
|
|
23953
|
-
GUIDE_MARKER_END = "<!-- wairon-guide-end -->";
|
|
23954
|
-
GLOBAL_GUIDE_BODY = `## wairon \u2014 Spec-Driven Development (optional)
|
|
23955
|
-
|
|
23956
|
-
If \`.wai/specs/\` exists, the wairon SDD workflow is active; otherwise ignore it. wairon does not orchestrate sessions \u2014 it equips yours.
|
|
23957
|
-
|
|
23958
|
-
### In SDD Projects:
|
|
23959
|
-
- **Source of Truth**: All architecture lives in the spec tree under \`.wai/specs/\` (L0 System \u2192 L1 Subsystem \u2192 L2 Component \u2192 L3 Interface \u2192 L4 Implementation \u2192 L5 Narrative). Do not edit generated agent config files under \`.claude/agents/\` (rebuilt via \`wairon generate\`).
|
|
23960
|
-
- **Validation**: Conformance checks (stereotype rules, cycle checks, reference integrity) are run via the \`sdd_validate_tree\` MCP tool.
|
|
23961
|
-
- **Operating Rules**:
|
|
23962
|
-
1. **Skills**: Use \`sdd-architect\` to design (and \`sdd-implement\`, \`sdd-narrative\`, \`sdd-auditor\`). Refer to project's local guide file for detailed constraints.
|
|
23963
|
-
2. **MCP Tools Only**: Author/validate specs *only* via \`sdd_*\` tools (e.g. \`sdd_initialize_system\`, \`sdd_validate_tree\`).
|
|
23964
|
-
3. **No CLI Exec**: Do not run the \`wairon\` CLI (human tool). Use MCP tools \`sdd_validate_tree\` and \`sdd_get_status\` instead.
|
|
23965
|
-
4. **Delegation**: Delegate implementation via the \`sdd-delegate\` skill \u2014 live agent briefs (\`sdd_get_agent_brief\` MCP tool / \`wairon-agent://\` resource) are composed per call and always current; no session restart. Generated agent files are an optional materialized view of the same topology. User-owned per-agent guidance may live in \`.wai/agents/<agent-id>.md\` (folded into every brief; scaffold via \`wairon agent customize <id>\`).
|
|
23966
|
-
5. **Design First**: Complete spec and pass \`sdd_validate_tree\` before writing code.
|
|
23967
|
-
6. **Consistency**: Code must match L3 interfaces and L5 narratives exactly. If the spec is wrong, stop and update the spec.
|
|
23968
|
-
7. **Subprojects & Namespacing**: If a subsystem uses \`projectPath\` delegation, target its specs using namespaced IDs (e.g. \`subsystem::component\`). Use leading \`::\` to target root (e.g. \`::shared::type\`) and \`super::\` to go up a level (e.g. \`super::sibling\`). wairon automatically resolves the path and strips the prefix on writes.`;
|
|
23969
|
-
LOCAL_GUIDE_BODY = `## Wairon \u2014 Spec-Driven Development (you are operating inside it)
|
|
23970
|
-
|
|
23971
|
-
This project uses **wairon**. System specs live under \`.wai/specs/\` (L0 System \u2192 L1 Subsystem \u2192 L2 Component \u2192 L3 Interface \u2192 L4 Implementation \u2192 Narrative); agent topology and code are derived from it.
|
|
23972
|
-
|
|
23973
|
-
**Do NOT search files or read agent configs to learn about wairon or SDD. Use the context here and the \`sdd-architect\` skill to start.**
|
|
23974
|
-
|
|
23975
|
-
**Your first move: call the \`sdd_get_status\` MCP tool** (or \`wairon/sdd_get_status\`) to see the spec tree. Do not parse files or run CLI commands manually.
|
|
23976
|
-
|
|
23977
|
-
### How you operate
|
|
23978
|
-
- **To design/modify specs**: Use **\`sdd-architect\`** skill (in \`.claude/skills/\` or \`.gemini/skills/\`).
|
|
23979
|
-
- **Manage specs via MCP tools only**: Use \`sdd_initialize_system\`, \`sdd_add_subsystem\`, \`sdd_add_component\`, \`sdd_define_interface\`, \`sdd_write_narrative\`, \`sdd_add_type\`, \`sdd_get_spec\`, \`sdd_delete_spec\`, \`sdd_validate_tree\`, and \`sdd_get_status\` (namespaced if needed). Do not edit specs manually.
|
|
23980
|
-
- **Subprojects & Namespacing (Chaining)**: If a subsystem defines a \`projectPath\`, its entire \`.wai/\` spec tree is recursively loaded and namespaced with the subsystem ID as a prefix (using \`::\`, e.g. \`billing::invoice::invoice_portal\`). Use the qualified namespaced ID with the parent MCP tools; wairon will resolve the path and strip the prefix automatically.
|
|
23981
|
-
- **Leading \`::\`**: Bypasses the local subsystem prefix to resolve absolute from the system root (e.g. \`::shared::error-type\`).
|
|
23982
|
-
- **\`super::\`**: Goes up one parent subsystem level (e.g. \`super::sibling_comp\`, \`super::super::parent_sibling\`).
|
|
23983
|
-
- **Do not run the \`wairon\` CLI**: Use \`sdd_validate_tree\` and \`sdd_get_status\` instead of CLI commands.
|
|
23984
|
-
- **Handoff to implementation**: Once design is complete and validates cleanly, tell the human: *"The specs are complete and validate. Please run \`wairon lock\` to confirm and freeze them."* No session restart is needed after the lock \u2014 delegate implementation right away via the \`sdd-delegate\` skill.
|
|
23985
|
-
- **To implement code**: Delegate via the \`sdd-delegate\` skill: fetch the component's live brief with the \`sdd_get_agent_brief\` MCP tool (or the \`wairon-agent://\` resource) and spawn a subagent from it. Briefs are composed per call from the current spec tree, so they are always current \u2014 never wait for a restart. Implementations must match L3 interfaces and L5 narratives exactly. Generated agent files under \`.claude/agents/\` are an optional materialized view of the same topology \u2014 the live briefs are canonical.
|
|
23986
|
-
|
|
23987
|
-
### Rules (enforced by \`sdd_validate_tree\`)
|
|
23988
|
-
1. **Design before code**: Complete spec and pass validator before writing source code.
|
|
23989
|
-
2. **Human-in-the-loop**: Ask user approval for each spec layer before proceeding.
|
|
23990
|
-
3. **Spec consistency**: If a 1:1 narrative match is incorrect or conflicts with L0 requirements, escalate a spec revision first. Never ship mismatched code.
|
|
23991
|
-
4. **No persistence shortcuts & strict layers**: A Portal must never depend directly on a Store, Registry, or Adapter. Portal reads MAY go through a Repository/Index facade (passthrough reads need no per-entity Orchestrator ceremony), but a Portal narrative call or dispatch-table binding that reaches a write-effect facade method is an error (\`PORTAL_WRITE_SHORTCUT\`) \u2014 writes always route through an Orchestrator. Held domain state always lives in a dedicated data component, never as fields inside an Orchestrator. Two sanctioned shapes: the RECOMMENDED Repository pattern (owns Store + Registry + Index; consumers depend on the facade), or \u2014 for genuinely simple state \u2014 a deliberately standalone Store (workflow-layer consumers only, acknowledged with a lint.allow reason on the UNOWNED_STORE warning). Never combine Store/Registry/Index roles into one component, and never fold state into a consuming component because a link was refused.
|
|
23992
|
-
|
|
23993
|
-
### Component Vocabulary
|
|
23994
|
-
* **Blocks**: Portal, Orchestrator, Supervisor, Actor, Store, Index, Query, Registry, Adapter, Observer.
|
|
23995
|
-
* **Patterns**: Repository \u2014 the composable pattern that \`owns\` its member blocks: one Store with its Registry, Indexes and Queries, and optionally an Adapter.
|
|
23996
|
-
* **Variants**: \`gateway\`, a Portal that authenticates, authorizes, validates or rate-limits before it dispatches. Logic is an Orchestrator, and \`dependencyClass: pure | read\` bounds what it may depend on (unset = a workflow). Specialist and Gateway are retired stereotypes.
|
|
23997
|
-
* Use \`owns\` for private member containment (exactly one hop) and \`dependsOn\` for collaborators. Never use generic suffixes like "Manager", "Helper", or "Utils".`;
|
|
23998
|
-
GUIDE_TARGETS = ["claude", "gemini", "agy", "cursor", "copilot", "codex"];
|
|
23999
|
-
}
|
|
24000
|
-
});
|
|
24001
|
-
|
|
24002
|
-
// src/core/context.ts
|
|
24003
|
-
function contextDir(...segments) {
|
|
24004
|
-
return aiDir("context", ...segments);
|
|
24005
|
-
}
|
|
24006
|
-
function hasContext() {
|
|
24007
|
-
return pathExists(CONTEXT_PATHS.projectMd());
|
|
24008
|
-
}
|
|
24009
|
-
function readProjectContext() {
|
|
24010
|
-
return readFileOrNull(CONTEXT_PATHS.projectMd());
|
|
24011
|
-
}
|
|
24012
|
-
function readArchitectureContext() {
|
|
24013
|
-
return readFileOrNull(CONTEXT_PATHS.architectureMd());
|
|
24014
|
-
}
|
|
24015
|
-
function renderDomainsDoc() {
|
|
24016
|
-
const domains = resolveDomains();
|
|
24017
|
-
const lines = [
|
|
24018
|
-
versionStamp(),
|
|
24019
|
-
`# Domains`,
|
|
24020
|
-
``,
|
|
24021
|
-
`> Auto-generated by wairon. The human developer rebuilds this with \`wairon generate\`. `,
|
|
24022
|
-
``
|
|
24023
|
-
];
|
|
24024
|
-
if (domains.length === 0) {
|
|
24025
|
-
lines.push("_No domains yet. Define subsystems in the spec tree, or add free-standing domains with `wairon domains add`._");
|
|
24026
|
-
} else {
|
|
24027
|
-
lines.push(`**${domains.length} domain(s).**`);
|
|
24028
|
-
lines.push("");
|
|
24029
|
-
lines.push("| ID | Name | Source | Owned paths |");
|
|
24030
|
-
lines.push("|----|------|--------|-------------|");
|
|
24031
|
-
for (const d of domains) {
|
|
24032
|
-
const name = d.name ?? d.id;
|
|
24033
|
-
const source = d.boundTo ? `subsystem \`${d.boundTo}\`` : "free-standing";
|
|
24034
|
-
lines.push(`| \`${d.id}\` | ${name} | ${source} | \`${d.ownedPaths.join("`, `") || "\u2014"}\` |`);
|
|
24035
|
-
}
|
|
24036
|
-
}
|
|
24037
|
-
return lines.join("\n") + "\n";
|
|
24038
|
-
}
|
|
24039
|
-
function renderWaironGuide() {
|
|
24040
|
-
const domains = resolveDomains();
|
|
24041
|
-
let projectName = "this project";
|
|
24042
|
-
try {
|
|
24043
|
-
projectName = projectConfigRepository.load()?.name ?? projectName;
|
|
24044
|
-
} catch {
|
|
24045
|
-
}
|
|
24046
|
-
const projectCtx = readProjectContext();
|
|
24047
|
-
const archCtx = readArchitectureContext();
|
|
24048
|
-
const lines = [
|
|
24049
|
-
versionStamp(),
|
|
24050
|
-
`<!-- wairon-generated \u2014 do not edit directly; the human developer rebuilds this with \`wairon generate\` -->`,
|
|
24051
|
-
``
|
|
24052
|
-
];
|
|
24053
|
-
if (projectCtx) {
|
|
24054
|
-
lines.push(`# Project Context \u2014 ${projectName}`);
|
|
24055
|
-
lines.push("");
|
|
24056
|
-
lines.push(projectCtx.trim());
|
|
24057
|
-
lines.push("");
|
|
24058
|
-
lines.push("---");
|
|
24059
|
-
lines.push("");
|
|
24060
|
-
}
|
|
24061
|
-
if (archCtx) {
|
|
24062
|
-
lines.push("# Architecture");
|
|
24063
|
-
lines.push("");
|
|
24064
|
-
lines.push(archCtx.trim());
|
|
24065
|
-
lines.push("");
|
|
24066
|
-
lines.push("---");
|
|
24067
|
-
lines.push("");
|
|
24068
|
-
}
|
|
24069
|
-
lines.push(`# Domain Map (${domains.length} domain${domains.length !== 1 ? "s" : ""})`);
|
|
24070
|
-
lines.push("");
|
|
24071
|
-
if (domains.length === 0) {
|
|
24072
|
-
lines.push("_No domains yet._");
|
|
24073
|
-
} else {
|
|
24074
|
-
lines.push("| ID | Source | Name |");
|
|
24075
|
-
lines.push("|----|--------|------|");
|
|
24076
|
-
for (const d of domains) {
|
|
24077
|
-
const name = d.name ?? d.id;
|
|
24078
|
-
const source = d.boundTo ? `subsystem \`${d.boundTo}\`` : "free-standing";
|
|
24079
|
-
lines.push(`| \`${d.id}\` | ${source} | ${name} |`);
|
|
24080
|
-
}
|
|
24081
|
-
}
|
|
24082
|
-
lines.push("");
|
|
24083
|
-
lines.push("---");
|
|
24084
|
-
lines.push("");
|
|
24085
|
-
const mcpSettingsPath = require("path").join(process.cwd(), ".claude", "settings.json");
|
|
24086
|
-
let mcpInstalled = false;
|
|
24087
|
-
try {
|
|
24088
|
-
const s = JSON.parse(require("fs").readFileSync(mcpSettingsPath, "utf8"));
|
|
24089
|
-
mcpInstalled = !!s?.mcpServers?.wairon;
|
|
24090
|
-
} catch {
|
|
24091
|
-
}
|
|
24092
|
-
if (mcpInstalled) {
|
|
24093
|
-
lines.push("# wairon MCP Tools");
|
|
24094
|
-
lines.push("");
|
|
24095
|
-
lines.push("The **wairon MCP server** is active in this project. The tools are self-describing; call them directly:");
|
|
24096
|
-
lines.push("");
|
|
24097
|
-
lines.push("- Authoring: `sdd_initialize_system`, `sdd_add_subsystem`, `sdd_set_public_interfaces`, `sdd_set_subsystem_project_path`, `sdd_add_component`, `sdd_define_interface`, `sdd_set_endpoints`, `sdd_write_narrative`, `sdd_add_type`.");
|
|
24098
|
-
lines.push("- Reading & maintenance: `sdd_get_spec`, `sdd_update_spec`, `sdd_delete_spec`, `sdd_validate_tree`, `sdd_get_status`.");
|
|
24099
|
-
lines.push("- Topology: `listAgents`, `getAgent`, `listDomains`, `validateTopology`, `getProjectConfig`.");
|
|
24100
|
-
lines.push("");
|
|
24101
|
-
lines.push("Use these MCP tools to query and change project state \u2014 never the `wairon` CLI (that is the human developer's tool).");
|
|
24102
|
-
lines.push("");
|
|
24103
|
-
lines.push("---");
|
|
24104
|
-
lines.push("");
|
|
24105
|
-
}
|
|
24106
|
-
lines.push(GLOBAL_GUIDE_BODY);
|
|
24107
|
-
lines.push("");
|
|
24108
|
-
return lines.join("\n");
|
|
24109
|
-
}
|
|
24110
|
-
function syncContextFiles() {
|
|
24111
|
-
const domainsContent = renderDomainsDoc();
|
|
24112
|
-
const guideContent = renderWaironGuide();
|
|
24113
|
-
const domainsUpdated = writeFileIfChanged(CONTEXT_PATHS.domainsMd(), domainsContent);
|
|
24114
|
-
const guideUpdated = writeFileIfChanged(CONTEXT_PATHS.waironGuideMd(), guideContent);
|
|
24115
|
-
return { domainsUpdated, guideUpdated };
|
|
24116
|
-
}
|
|
24117
|
-
var CONTEXT_PATHS;
|
|
24118
|
-
var init_context = __esm({
|
|
24119
|
-
"src/core/context.ts"() {
|
|
24120
|
-
"use strict";
|
|
24121
|
-
init_fs();
|
|
24122
|
-
init_ai_guide();
|
|
24123
|
-
init_stamp();
|
|
24124
|
-
init_domain_projector();
|
|
24125
|
-
init_project_config();
|
|
24126
|
-
CONTEXT_PATHS = {
|
|
24127
|
-
dir: () => contextDir(),
|
|
24128
|
-
projectMd: () => contextDir("project.md"),
|
|
24129
|
-
architectureMd: () => contextDir("architecture.md"),
|
|
24130
|
-
domainsMd: () => contextDir("domains.md"),
|
|
24131
|
-
waironGuideMd: () => contextDir("wairon-guide.md")
|
|
24132
|
-
};
|
|
24133
|
-
}
|
|
24134
|
-
});
|
|
24135
|
-
|
|
24136
23829
|
// node_modules/fflate/lib/node.cjs
|
|
24137
23830
|
var require_node = __commonJS({
|
|
24138
23831
|
"node_modules/fflate/lib/node.cjs"(exports2) {
|
|
@@ -27508,41 +27201,41 @@ function hasAuthoredSpecs(root) {
|
|
|
27508
27201
|
if (!pathExists(specsDir)) {
|
|
27509
27202
|
return false;
|
|
27510
27203
|
}
|
|
27511
|
-
const systemIndex =
|
|
27204
|
+
const systemIndex = path24.resolve(paths.specsSystem());
|
|
27512
27205
|
for (const file of listFilesRecursive(specsDir, ".yaml")) {
|
|
27513
|
-
if (
|
|
27206
|
+
if (path24.resolve(file) !== systemIndex) {
|
|
27514
27207
|
return true;
|
|
27515
27208
|
}
|
|
27516
27209
|
}
|
|
27517
27210
|
return false;
|
|
27518
27211
|
}
|
|
27519
27212
|
function createStagingDir(destDir) {
|
|
27520
|
-
const root =
|
|
27521
|
-
|
|
27522
|
-
const stagingDir =
|
|
27213
|
+
const root = path24.resolve(destDir);
|
|
27214
|
+
fs19.mkdirSync(root, { recursive: true });
|
|
27215
|
+
const stagingDir = fs19.mkdtempSync(path24.join(root, STAGING_PREFIX));
|
|
27523
27216
|
return stagingDir;
|
|
27524
27217
|
}
|
|
27525
27218
|
function commitStagedTree(stagingDir, destDir, roots, backupExisting) {
|
|
27526
|
-
const root =
|
|
27527
|
-
const backupDir =
|
|
27219
|
+
const root = path24.resolve(destDir);
|
|
27220
|
+
const backupDir = path24.join(root, BACKUP_DIR, timestampSlug());
|
|
27528
27221
|
let backedUp = false;
|
|
27529
27222
|
for (const rootRel of roots) {
|
|
27530
27223
|
const relative15 = rootRel === "." ? "" : rootRel;
|
|
27531
|
-
const stagedSpecDir =
|
|
27532
|
-
if (!
|
|
27533
|
-
const liveSpecDir = liveSpecDirFor(
|
|
27534
|
-
if (backupExisting && liveSpecDir &&
|
|
27535
|
-
const backupTarget =
|
|
27536
|
-
|
|
27537
|
-
|
|
27224
|
+
const stagedSpecDir = path24.join(stagingDir, relative15, ".wai");
|
|
27225
|
+
if (!fs19.existsSync(stagedSpecDir)) continue;
|
|
27226
|
+
const liveSpecDir = liveSpecDirFor(path24.join(root, relative15));
|
|
27227
|
+
if (backupExisting && liveSpecDir && fs19.existsSync(liveSpecDir)) {
|
|
27228
|
+
const backupTarget = path24.join(backupDir, relative15, path24.basename(liveSpecDir));
|
|
27229
|
+
fs19.mkdirSync(path24.dirname(backupTarget), { recursive: true });
|
|
27230
|
+
fs19.renameSync(liveSpecDir, backupTarget);
|
|
27538
27231
|
backedUp = true;
|
|
27539
|
-
} else if (liveSpecDir &&
|
|
27540
|
-
|
|
27232
|
+
} else if (liveSpecDir && fs19.existsSync(liveSpecDir)) {
|
|
27233
|
+
fs19.rmSync(liveSpecDir, { recursive: true, force: true });
|
|
27541
27234
|
}
|
|
27542
|
-
const target =
|
|
27543
|
-
|
|
27544
|
-
if (
|
|
27545
|
-
|
|
27235
|
+
const target = path24.join(root, relative15, ".wai");
|
|
27236
|
+
fs19.mkdirSync(path24.dirname(target), { recursive: true });
|
|
27237
|
+
if (fs19.existsSync(target)) fs19.rmSync(target, { recursive: true, force: true });
|
|
27238
|
+
fs19.renameSync(stagedSpecDir, target);
|
|
27546
27239
|
}
|
|
27547
27240
|
if (backedUp) {
|
|
27548
27241
|
return backupDir;
|
|
@@ -27551,7 +27244,7 @@ function commitStagedTree(stagingDir, destDir, roots, backupExisting) {
|
|
|
27551
27244
|
}
|
|
27552
27245
|
function discardStagingDir(stagingDir) {
|
|
27553
27246
|
try {
|
|
27554
|
-
|
|
27247
|
+
fs19.rmSync(stagingDir, { recursive: true, force: true });
|
|
27555
27248
|
} catch {
|
|
27556
27249
|
}
|
|
27557
27250
|
}
|
|
@@ -27565,7 +27258,7 @@ function exportSpecTree(includeDerived, allowPartial) {
|
|
|
27565
27258
|
const skipped = [...inspection.skipped];
|
|
27566
27259
|
const roots = [{ relativePath: ".", waiDir: aiPathsAt(root).root() }];
|
|
27567
27260
|
for (const rel2 of inspection.roots) {
|
|
27568
|
-
const waiDir = aiPathsAt(
|
|
27261
|
+
const waiDir = aiPathsAt(path24.resolve(root, rel2)).root();
|
|
27569
27262
|
if (pathExists(waiDir)) {
|
|
27570
27263
|
roots.push({ relativePath: rel2, waiDir });
|
|
27571
27264
|
} else {
|
|
@@ -27596,7 +27289,7 @@ function importSpecTree(archive, options) {
|
|
|
27596
27289
|
if (!info.compatible) {
|
|
27597
27290
|
throw new Error("incompatible .waitree archive (format or minimum wairon version)");
|
|
27598
27291
|
}
|
|
27599
|
-
const destDir =
|
|
27292
|
+
const destDir = path24.resolve(options.destDir ?? getProjectRoot());
|
|
27600
27293
|
const occupied = hasSpecTree(destDir);
|
|
27601
27294
|
const authored = hasAuthoredSpecs(destDir);
|
|
27602
27295
|
if (authored && options.replaceExisting !== true) {
|
|
@@ -27627,21 +27320,21 @@ function importSpecTree(archive, options) {
|
|
|
27627
27320
|
return result;
|
|
27628
27321
|
}
|
|
27629
27322
|
function liveSpecDirFor(rootDir) {
|
|
27630
|
-
const modern =
|
|
27631
|
-
if (
|
|
27632
|
-
const legacy =
|
|
27633
|
-
if (
|
|
27323
|
+
const modern = path24.join(rootDir, ".wai");
|
|
27324
|
+
if (fs19.existsSync(modern)) return modern;
|
|
27325
|
+
const legacy = path24.join(rootDir, ".wairon");
|
|
27326
|
+
if (fs19.existsSync(legacy)) return legacy;
|
|
27634
27327
|
return null;
|
|
27635
27328
|
}
|
|
27636
27329
|
function timestampSlug() {
|
|
27637
27330
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
27638
27331
|
}
|
|
27639
|
-
var
|
|
27332
|
+
var fs19, path24, sdkPortal, STAGING_PREFIX, BACKUP_DIR;
|
|
27640
27333
|
var init_treetransfer = __esm({
|
|
27641
27334
|
"src/core/treetransfer.ts"() {
|
|
27642
27335
|
"use strict";
|
|
27643
|
-
|
|
27644
|
-
|
|
27336
|
+
fs19 = __toESM(require("fs"));
|
|
27337
|
+
path24 = __toESM(require("path"));
|
|
27645
27338
|
sdkPortal = __toESM(require_dist());
|
|
27646
27339
|
init_paths();
|
|
27647
27340
|
init_fs();
|
|
@@ -27670,11 +27363,11 @@ function mcpServersFor(access) {
|
|
|
27670
27363
|
function yamlScalar(value) {
|
|
27671
27364
|
return /[:#\n]/.test(value) ? `"${value.replace(/"/g, '\\"')}"` : value;
|
|
27672
27365
|
}
|
|
27673
|
-
var
|
|
27366
|
+
var path25, MODEL_BY_TIER, TOOLS_BY_CLASS, ClaudeExporter;
|
|
27674
27367
|
var init_claude = __esm({
|
|
27675
27368
|
"src/exporters/claude.ts"() {
|
|
27676
27369
|
"use strict";
|
|
27677
|
-
|
|
27370
|
+
path25 = __toESM(require("path"));
|
|
27678
27371
|
init_fs();
|
|
27679
27372
|
MODEL_BY_TIER = {
|
|
27680
27373
|
small: "haiku",
|
|
@@ -27697,7 +27390,7 @@ var init_claude = __esm({
|
|
|
27697
27390
|
outputPath(ctx) {
|
|
27698
27391
|
const { agent, target, projectRoot: projectRoot2 } = ctx;
|
|
27699
27392
|
const outputDir = "outputDir" in target ? target.outputDir : ".claude/agents";
|
|
27700
|
-
return
|
|
27393
|
+
return path25.resolve(projectRoot2, outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
27701
27394
|
}
|
|
27702
27395
|
export(ctx) {
|
|
27703
27396
|
const { agent, renderedInstructions, budget } = ctx;
|
|
@@ -27724,11 +27417,11 @@ var init_claude = __esm({
|
|
|
27724
27417
|
});
|
|
27725
27418
|
|
|
27726
27419
|
// src/exporters/custom.ts
|
|
27727
|
-
var
|
|
27420
|
+
var path26, CustomExporter;
|
|
27728
27421
|
var init_custom = __esm({
|
|
27729
27422
|
"src/exporters/custom.ts"() {
|
|
27730
27423
|
"use strict";
|
|
27731
|
-
|
|
27424
|
+
path26 = __toESM(require("path"));
|
|
27732
27425
|
init_fs();
|
|
27733
27426
|
CustomExporter = class {
|
|
27734
27427
|
constructor() {
|
|
@@ -27739,7 +27432,7 @@ var init_custom = __esm({
|
|
|
27739
27432
|
if (!("outputDir" in target)) {
|
|
27740
27433
|
throw new Error("CustomExporter requires target.outputDir");
|
|
27741
27434
|
}
|
|
27742
|
-
return
|
|
27435
|
+
return path26.resolve(projectRoot2, target.outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
27743
27436
|
}
|
|
27744
27437
|
export(ctx) {
|
|
27745
27438
|
const { agent, target, renderedInstructions } = ctx;
|
|
@@ -27770,11 +27463,11 @@ function yamlString(value) {
|
|
|
27770
27463
|
}
|
|
27771
27464
|
return value;
|
|
27772
27465
|
}
|
|
27773
|
-
var
|
|
27466
|
+
var path27, GeminiExporter;
|
|
27774
27467
|
var init_gemini = __esm({
|
|
27775
27468
|
"src/exporters/gemini.ts"() {
|
|
27776
27469
|
"use strict";
|
|
27777
|
-
|
|
27470
|
+
path27 = __toESM(require("path"));
|
|
27778
27471
|
init_fs();
|
|
27779
27472
|
GeminiExporter = class {
|
|
27780
27473
|
constructor() {
|
|
@@ -27783,7 +27476,7 @@ var init_gemini = __esm({
|
|
|
27783
27476
|
outputPath(ctx) {
|
|
27784
27477
|
const { agent, target, projectRoot: projectRoot2 } = ctx;
|
|
27785
27478
|
const outputDir = "outputDir" in target ? target.outputDir : ".gemini/agents";
|
|
27786
|
-
return
|
|
27479
|
+
return path27.resolve(projectRoot2, outputDir, `${agent.id.replace(/::/g, "--")}.yaml`);
|
|
27787
27480
|
}
|
|
27788
27481
|
export(ctx) {
|
|
27789
27482
|
const { agent, renderedInstructions } = ctx;
|
|
@@ -27889,7 +27582,7 @@ function resolveExpectedOutputPaths(agents, projectConfig, projectRoot2 = getPro
|
|
|
27889
27582
|
const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
|
|
27890
27583
|
if (!targetConfig) continue;
|
|
27891
27584
|
const ctx = { agent, projectRoot: projectRoot2, target: targetConfig };
|
|
27892
|
-
expected.add(
|
|
27585
|
+
expected.add(path28.resolve(getExporter(targetConfig).outputPath(ctx)));
|
|
27893
27586
|
}
|
|
27894
27587
|
}
|
|
27895
27588
|
return expected;
|
|
@@ -27901,11 +27594,11 @@ function resolveTargetConfig(agentTarget, projectConfig) {
|
|
|
27901
27594
|
return t.type === targetType;
|
|
27902
27595
|
});
|
|
27903
27596
|
}
|
|
27904
|
-
var
|
|
27597
|
+
var path28;
|
|
27905
27598
|
var init_generate = __esm({
|
|
27906
27599
|
"src/exporters/generate.ts"() {
|
|
27907
27600
|
"use strict";
|
|
27908
|
-
|
|
27601
|
+
path28 = __toESM(require("path"));
|
|
27909
27602
|
init_templates();
|
|
27910
27603
|
init_agent_resolver();
|
|
27911
27604
|
init_execution_profile();
|
|
@@ -28072,12 +27765,12 @@ function digest(content) {
|
|
|
28072
27765
|
return crypto4.createHash("sha256").update(normalized, "utf8").digest("hex");
|
|
28073
27766
|
}
|
|
28074
27767
|
function currentSpecDigests(root = getProjectRoot()) {
|
|
28075
|
-
const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${
|
|
27768
|
+
const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${path29.resolve(root, s.projectPath).split(path29.sep).join("/")}/`);
|
|
28076
27769
|
const out = {};
|
|
28077
27770
|
for (const [abs, content] of snapshotSpecFiles()) {
|
|
28078
|
-
const normalized =
|
|
27771
|
+
const normalized = path29.resolve(abs).split(path29.sep).join("/");
|
|
28079
27772
|
if (mountDirs.some((dir) => normalized.startsWith(dir))) continue;
|
|
28080
|
-
out[
|
|
27773
|
+
out[path29.relative(root, abs).split(path29.sep).join("/")] = digest(content);
|
|
28081
27774
|
}
|
|
28082
27775
|
return out;
|
|
28083
27776
|
}
|
|
@@ -28135,7 +27828,7 @@ function currentChildPins(mounts, root = getProjectRoot()) {
|
|
|
28135
27828
|
const pins = {};
|
|
28136
27829
|
for (const mount of mounts) {
|
|
28137
27830
|
if (!mount.projectPath || mount.id.includes("::")) continue;
|
|
28138
|
-
const child = readLockRecordAt(
|
|
27831
|
+
const child = readLockRecordAt(path29.resolve(root, mount.projectPath));
|
|
28139
27832
|
if (child) pins[mount.id] = pinOf(child.stateId);
|
|
28140
27833
|
}
|
|
28141
27834
|
return pins;
|
|
@@ -28151,12 +27844,12 @@ function movedChildren(mounts, root = getProjectRoot()) {
|
|
|
28151
27844
|
}
|
|
28152
27845
|
return moved;
|
|
28153
27846
|
}
|
|
28154
|
-
var crypto4,
|
|
27847
|
+
var crypto4, path29;
|
|
28155
27848
|
var init_approval = __esm({
|
|
28156
27849
|
"src/core/approval.ts"() {
|
|
28157
27850
|
"use strict";
|
|
28158
27851
|
crypto4 = __toESM(require("crypto"));
|
|
28159
|
-
|
|
27852
|
+
path29 = __toESM(require("path"));
|
|
28160
27853
|
init_fs();
|
|
28161
27854
|
init_specs2();
|
|
28162
27855
|
init_lockfile();
|
|
@@ -28179,12 +27872,12 @@ function gitConfig(key) {
|
|
|
28179
27872
|
function machineIdentity() {
|
|
28180
27873
|
let user = "unknown";
|
|
28181
27874
|
try {
|
|
28182
|
-
user =
|
|
27875
|
+
user = os5.userInfo().username || user;
|
|
28183
27876
|
} catch {
|
|
28184
27877
|
}
|
|
28185
27878
|
let host = "";
|
|
28186
27879
|
try {
|
|
28187
|
-
host =
|
|
27880
|
+
host = os5.hostname();
|
|
28188
27881
|
} catch {
|
|
28189
27882
|
}
|
|
28190
27883
|
return { id: host ? `${user}@${host}` : user, source: "os" };
|
|
@@ -28196,12 +27889,328 @@ function localApprover() {
|
|
|
28196
27889
|
if (email) return { id: email, source: "git" };
|
|
28197
27890
|
return machineIdentity();
|
|
28198
27891
|
}
|
|
28199
|
-
var import_child_process2,
|
|
27892
|
+
var import_child_process2, os5;
|
|
28200
27893
|
var init_approver = __esm({
|
|
28201
27894
|
"src/core/approver.ts"() {
|
|
28202
27895
|
"use strict";
|
|
28203
27896
|
import_child_process2 = require("child_process");
|
|
27897
|
+
os5 = __toESM(require("os"));
|
|
27898
|
+
}
|
|
27899
|
+
});
|
|
27900
|
+
|
|
27901
|
+
// src/core/stamp.ts
|
|
27902
|
+
function versionStamp() {
|
|
27903
|
+
return `<!-- wairon-version: ${WAIRON_VERSION} -->`;
|
|
27904
|
+
}
|
|
27905
|
+
function readStampVersion(content) {
|
|
27906
|
+
const m = content.match(STAMP_RE);
|
|
27907
|
+
return m ? m[1] : null;
|
|
27908
|
+
}
|
|
27909
|
+
var STAMP_RE;
|
|
27910
|
+
var init_stamp = __esm({
|
|
27911
|
+
"src/core/stamp.ts"() {
|
|
27912
|
+
"use strict";
|
|
27913
|
+
init_defaults();
|
|
27914
|
+
STAMP_RE = /<!--\s*wairon-version:\s*([^\s]+)\s*-->/;
|
|
27915
|
+
}
|
|
27916
|
+
});
|
|
27917
|
+
|
|
27918
|
+
// src/utils/ai-guide.ts
|
|
27919
|
+
function globalGuideFilePath(targetType) {
|
|
27920
|
+
if (targetType === "claude") return path30.join(process.env["CLAUDE_CONFIG_DIR"] || path30.join(os6.homedir(), ".claude"), "CLAUDE.md");
|
|
27921
|
+
if (targetType === "gemini") return path30.join(process.env["GEMINI_CONFIG_DIR"] || path30.join(os6.homedir(), ".gemini"), "GEMINI.md");
|
|
27922
|
+
return null;
|
|
27923
|
+
}
|
|
27924
|
+
function localGuideFilePath(projectRoot2, targetType) {
|
|
27925
|
+
if (targetType === "claude") return path30.join(projectRoot2, ".claude", "CLAUDE.md");
|
|
27926
|
+
if (targetType === "gemini" || targetType === "agy") return path30.join(projectRoot2, ".gemini", "GEMINI.md");
|
|
27927
|
+
return null;
|
|
27928
|
+
}
|
|
27929
|
+
function injectGuide(filePath, scope) {
|
|
27930
|
+
const body = scope === "global" ? GLOBAL_GUIDE_BODY : LOCAL_GUIDE_BODY;
|
|
27931
|
+
const section = `
|
|
27932
|
+
|
|
27933
|
+
${GUIDE_MARKER_START}
|
|
27934
|
+
${versionStamp()}
|
|
27935
|
+
${body}
|
|
27936
|
+
${GUIDE_MARKER_END}
|
|
27937
|
+
`;
|
|
27938
|
+
const existing = fs20.existsSync(filePath) ? fs20.readFileSync(filePath, "utf-8") : "";
|
|
27939
|
+
const stripped = stripGuideSection(existing);
|
|
27940
|
+
const newContent = stripped.trimEnd() + section;
|
|
27941
|
+
fs20.mkdirSync(path30.dirname(filePath), { recursive: true });
|
|
27942
|
+
fs20.writeFileSync(filePath, newContent, "utf-8");
|
|
27943
|
+
}
|
|
27944
|
+
function stripGuideSection(content) {
|
|
27945
|
+
const start2 = content.indexOf(GUIDE_MARKER_START);
|
|
27946
|
+
const end = content.indexOf(GUIDE_MARKER_END);
|
|
27947
|
+
if (start2 === -1 || end === -1) return content;
|
|
27948
|
+
return content.slice(0, start2) + content.slice(end + GUIDE_MARKER_END.length);
|
|
27949
|
+
}
|
|
27950
|
+
function writeRootGuideDelegator(projectRoot2, targetType) {
|
|
27951
|
+
if (targetType === "claude") {
|
|
27952
|
+
const filePath = path30.join(projectRoot2, "CLAUDE.md");
|
|
27953
|
+
const content = `@.claude/CLAUDE.md
|
|
27954
|
+
|
|
27955
|
+
# Wairon SDD Project
|
|
27956
|
+
|
|
27957
|
+
This project uses the Wairon Spec-Driven Development (SDD) framework. The imported
|
|
27958
|
+
\`.claude/CLAUDE.md\` above is your complete operating guide \u2014 you already have the
|
|
27959
|
+
full context, so don't search the project to learn how wairon or SDD works.
|
|
27960
|
+
|
|
27961
|
+
To design or modify the system, invoke the **\`sdd-architect\`** skill
|
|
27962
|
+
(in \`.claude/skills/\`). Author and validate specs with the \`sdd_*\` MCP tools;
|
|
27963
|
+
the \`wairon\` CLI is the human developer's tool, not yours.
|
|
27964
|
+
`;
|
|
27965
|
+
fs20.writeFileSync(filePath, content, "utf-8");
|
|
27966
|
+
} else if (targetType === "gemini" || targetType === "agy") {
|
|
27967
|
+
const filePath = path30.join(projectRoot2, "GEMINI.md");
|
|
27968
|
+
const content = `# Wairon SDD Project
|
|
27969
|
+
${GUIDE_MARKER_START}
|
|
27970
|
+
${versionStamp()}
|
|
27971
|
+
${LOCAL_GUIDE_BODY}
|
|
27972
|
+
${GUIDE_MARKER_END}
|
|
27973
|
+
`;
|
|
27974
|
+
fs20.writeFileSync(filePath, content, "utf-8");
|
|
27975
|
+
} else if (targetType === "cursor") {
|
|
27976
|
+
const filePath = path30.join(projectRoot2, ".cursorrules");
|
|
27977
|
+
const content = `# Wairon SDD Project
|
|
27978
|
+
|
|
27979
|
+
This project uses the Wairon Spec-Driven Development (SDD) framework.
|
|
27980
|
+
|
|
27981
|
+
Refer to the rules in [.cursor/rules/](.cursor/rules/) for full instructions.
|
|
27982
|
+
`;
|
|
27983
|
+
fs20.writeFileSync(filePath, content, "utf-8");
|
|
27984
|
+
} else if (targetType === "copilot") {
|
|
27985
|
+
const filePath = path30.join(projectRoot2, ".github", "copilot-instructions.md");
|
|
27986
|
+
fs20.mkdirSync(path30.dirname(filePath), { recursive: true });
|
|
27987
|
+
const content = `# Wairon SDD Project
|
|
27988
|
+
|
|
27989
|
+
This project uses the Wairon Spec-Driven Development (SDD) framework.
|
|
27990
|
+
|
|
27991
|
+
Refer to the prompts in [.github/prompts/](.github/prompts/) for instructions.
|
|
27992
|
+
`;
|
|
27993
|
+
fs20.writeFileSync(filePath, content, "utf-8");
|
|
27994
|
+
} else if (targetType === "codex") {
|
|
27995
|
+
const filePath = path30.join(projectRoot2, ".codexrules");
|
|
27996
|
+
const content = `# Wairon SDD Project
|
|
27997
|
+
|
|
27998
|
+
Refer to [.codex/agents/](.codex/agents/) for full instructions.
|
|
27999
|
+
`;
|
|
28000
|
+
fs20.writeFileSync(filePath, content, "utf-8");
|
|
28001
|
+
}
|
|
28002
|
+
}
|
|
28003
|
+
function reinjectLocalGuides(projectRoot2, targetTypes) {
|
|
28004
|
+
const written = [];
|
|
28005
|
+
for (const type of targetTypes) {
|
|
28006
|
+
if (!GUIDE_TARGETS.includes(type)) continue;
|
|
28007
|
+
const guidePath = localGuideFilePath(projectRoot2, type);
|
|
28008
|
+
if (guidePath) {
|
|
28009
|
+
injectGuide(guidePath, "local");
|
|
28010
|
+
if (!written.includes(guidePath)) written.push(guidePath);
|
|
28011
|
+
}
|
|
28012
|
+
writeRootGuideDelegator(projectRoot2, type);
|
|
28013
|
+
}
|
|
28014
|
+
return written;
|
|
28015
|
+
}
|
|
28016
|
+
var fs20, os6, path30, GUIDE_MARKER_START, GUIDE_MARKER_END, GLOBAL_GUIDE_BODY, LOCAL_GUIDE_BODY, GUIDE_TARGETS;
|
|
28017
|
+
var init_ai_guide = __esm({
|
|
28018
|
+
"src/utils/ai-guide.ts"() {
|
|
28019
|
+
"use strict";
|
|
28020
|
+
fs20 = __toESM(require("fs"));
|
|
28204
28021
|
os6 = __toESM(require("os"));
|
|
28022
|
+
path30 = __toESM(require("path"));
|
|
28023
|
+
init_stamp();
|
|
28024
|
+
GUIDE_MARKER_START = "<!-- wairon-guide-start -->";
|
|
28025
|
+
GUIDE_MARKER_END = "<!-- wairon-guide-end -->";
|
|
28026
|
+
GLOBAL_GUIDE_BODY = `## wairon \u2014 Spec-Driven Development (optional)
|
|
28027
|
+
|
|
28028
|
+
If \`.wai/specs/\` exists, the wairon SDD workflow is active; otherwise ignore it. wairon does not orchestrate sessions \u2014 it equips yours.
|
|
28029
|
+
|
|
28030
|
+
### In SDD Projects:
|
|
28031
|
+
- **Source of Truth**: All architecture lives in the spec tree under \`.wai/specs/\` (L0 System \u2192 L1 Subsystem \u2192 L2 Component \u2192 L3 Interface \u2192 L4 Implementation \u2192 L5 Narrative). Do not edit generated agent config files under \`.claude/agents/\` (rebuilt via \`wairon generate\`).
|
|
28032
|
+
- **Validation**: Conformance checks (stereotype rules, cycle checks, reference integrity) are run via the \`sdd_validate_tree\` MCP tool.
|
|
28033
|
+
- **Operating Rules**:
|
|
28034
|
+
1. **Skills**: Use \`sdd-architect\` to design (and \`sdd-implement\`, \`sdd-narrative\`, \`sdd-auditor\`). Refer to project's local guide file for detailed constraints.
|
|
28035
|
+
2. **MCP Tools Only**: Author/validate specs *only* via \`sdd_*\` tools (e.g. \`sdd_initialize_system\`, \`sdd_validate_tree\`).
|
|
28036
|
+
3. **No CLI Exec**: Do not run the \`wairon\` CLI (human tool). Use MCP tools \`sdd_validate_tree\` and \`sdd_get_status\` instead.
|
|
28037
|
+
4. **Delegation**: Delegate implementation via the \`sdd-delegate\` skill \u2014 live agent briefs (\`sdd_get_agent_brief\` MCP tool / \`wairon-agent://\` resource) are composed per call and always current; no session restart. Generated agent files are an optional materialized view of the same topology. User-owned per-agent guidance may live in \`.wai/agents/<agent-id>.md\` (folded into every brief; scaffold via \`wairon agent customize <id>\`).
|
|
28038
|
+
5. **Design First**: Complete spec and pass \`sdd_validate_tree\` before writing code.
|
|
28039
|
+
6. **Consistency**: Code must match L3 interfaces and L5 narratives exactly. If the spec is wrong, stop and update the spec.
|
|
28040
|
+
7. **Subprojects & Namespacing**: If a subsystem uses \`projectPath\` delegation, target its specs using namespaced IDs (e.g. \`subsystem::component\`). Use leading \`::\` to target root (e.g. \`::shared::type\`) and \`super::\` to go up a level (e.g. \`super::sibling\`). wairon automatically resolves the path and strips the prefix on writes.`;
|
|
28041
|
+
LOCAL_GUIDE_BODY = `## Wairon \u2014 Spec-Driven Development (you are operating inside it)
|
|
28042
|
+
|
|
28043
|
+
This project uses **wairon**. System specs live under \`.wai/specs/\` (L0 System \u2192 L1 Subsystem \u2192 L2 Component \u2192 L3 Interface \u2192 L4 Implementation \u2192 Narrative); agent topology and code are derived from it.
|
|
28044
|
+
|
|
28045
|
+
**Do NOT search files or read agent configs to learn about wairon or SDD. Use the context here and the \`sdd-architect\` skill to start.**
|
|
28046
|
+
|
|
28047
|
+
**Your first move: call the \`sdd_get_status\` MCP tool** (or \`wairon/sdd_get_status\`) to see the spec tree. Do not parse files or run CLI commands manually.
|
|
28048
|
+
|
|
28049
|
+
### How you operate
|
|
28050
|
+
- **To design/modify specs**: Use **\`sdd-architect\`** skill (in \`.claude/skills/\` or \`.gemini/skills/\`).
|
|
28051
|
+
- **Manage specs via MCP tools only**: Use \`sdd_initialize_system\`, \`sdd_add_subsystem\`, \`sdd_add_component\`, \`sdd_define_interface\`, \`sdd_write_narrative\`, \`sdd_add_type\`, \`sdd_get_spec\`, \`sdd_delete_spec\`, \`sdd_validate_tree\`, and \`sdd_get_status\` (namespaced if needed). Do not edit specs manually.
|
|
28052
|
+
- **Subprojects & Namespacing (Chaining)**: If a subsystem defines a \`projectPath\`, its entire \`.wai/\` spec tree is recursively loaded and namespaced with the subsystem ID as a prefix (using \`::\`, e.g. \`billing::invoice::invoice_portal\`). Use the qualified namespaced ID with the parent MCP tools; wairon will resolve the path and strip the prefix automatically.
|
|
28053
|
+
- **Leading \`::\`**: Bypasses the local subsystem prefix to resolve absolute from the system root (e.g. \`::shared::error-type\`).
|
|
28054
|
+
- **\`super::\`**: Goes up one parent subsystem level (e.g. \`super::sibling_comp\`, \`super::super::parent_sibling\`).
|
|
28055
|
+
- **Do not run the \`wairon\` CLI**: Use \`sdd_validate_tree\` and \`sdd_get_status\` instead of CLI commands.
|
|
28056
|
+
- **Handoff to implementation**: Once design is complete and validates cleanly, tell the human: *"The specs are complete and validate. Please run \`wairon lock\` to confirm and freeze them."* No session restart is needed after the lock \u2014 delegate implementation right away via the \`sdd-delegate\` skill.
|
|
28057
|
+
- **To implement code**: Delegate via the \`sdd-delegate\` skill: fetch the component's live brief with the \`sdd_get_agent_brief\` MCP tool (or the \`wairon-agent://\` resource) and spawn a subagent from it. Briefs are composed per call from the current spec tree, so they are always current \u2014 never wait for a restart. Implementations must match L3 interfaces and L5 narratives exactly. Generated agent files under \`.claude/agents/\` are an optional materialized view of the same topology \u2014 the live briefs are canonical.
|
|
28058
|
+
|
|
28059
|
+
### Rules (enforced by \`sdd_validate_tree\`)
|
|
28060
|
+
1. **Design before code**: Complete spec and pass validator before writing source code.
|
|
28061
|
+
2. **Human-in-the-loop**: Ask user approval for each spec layer before proceeding.
|
|
28062
|
+
3. **Spec consistency**: If a 1:1 narrative match is incorrect or conflicts with L0 requirements, escalate a spec revision first. Never ship mismatched code.
|
|
28063
|
+
4. **No persistence shortcuts & strict layers**: A Portal must never depend directly on a Store, Registry, or Adapter. Portal reads MAY go through a Repository/Index facade (passthrough reads need no per-entity Orchestrator ceremony), but a Portal narrative call or dispatch-table binding that reaches a write-effect facade method is an error (\`PORTAL_WRITE_SHORTCUT\`) \u2014 writes always route through an Orchestrator. Held domain state always lives in a dedicated data component, never as fields inside an Orchestrator. Two sanctioned shapes: the RECOMMENDED Repository pattern (owns Store + Registry + Index; consumers depend on the facade), or \u2014 for genuinely simple state \u2014 a deliberately standalone Store (workflow-layer consumers only, acknowledged with a lint.allow reason on the UNOWNED_STORE warning). Never combine Store/Registry/Index roles into one component, and never fold state into a consuming component because a link was refused.
|
|
28064
|
+
|
|
28065
|
+
### Component Vocabulary
|
|
28066
|
+
* **Blocks**: Portal, Orchestrator, Supervisor, Actor, Store, Index, Query, Registry, Adapter, Observer.
|
|
28067
|
+
* **Patterns**: Repository \u2014 the composable pattern that \`owns\` its member blocks: one Store with its Registry, Indexes and Queries, and optionally an Adapter.
|
|
28068
|
+
* **Variants**: \`gateway\`, a Portal that authenticates, authorizes, validates or rate-limits before it dispatches. Logic is an Orchestrator, and \`dependencyClass: pure | read\` bounds what it may depend on (unset = a workflow). Specialist and Gateway are retired stereotypes.
|
|
28069
|
+
* Use \`owns\` for private member containment (exactly one hop) and \`dependsOn\` for collaborators. Never use generic suffixes like "Manager", "Helper", or "Utils".`;
|
|
28070
|
+
GUIDE_TARGETS = ["claude", "gemini", "agy", "cursor", "copilot", "codex"];
|
|
28071
|
+
}
|
|
28072
|
+
});
|
|
28073
|
+
|
|
28074
|
+
// src/core/context.ts
|
|
28075
|
+
function contextDir(...segments) {
|
|
28076
|
+
return aiDir("context", ...segments);
|
|
28077
|
+
}
|
|
28078
|
+
function hasContext() {
|
|
28079
|
+
return pathExists(CONTEXT_PATHS.projectMd());
|
|
28080
|
+
}
|
|
28081
|
+
function readProjectContext() {
|
|
28082
|
+
return readFileOrNull(CONTEXT_PATHS.projectMd());
|
|
28083
|
+
}
|
|
28084
|
+
function readArchitectureContext() {
|
|
28085
|
+
return readFileOrNull(CONTEXT_PATHS.architectureMd());
|
|
28086
|
+
}
|
|
28087
|
+
function writeDomainsDoc(content) {
|
|
28088
|
+
return writeFileIfChanged(CONTEXT_PATHS.domainsMd(), content);
|
|
28089
|
+
}
|
|
28090
|
+
function writeGuideDoc(content) {
|
|
28091
|
+
return writeFileIfChanged(CONTEXT_PATHS.waironGuideMd(), content);
|
|
28092
|
+
}
|
|
28093
|
+
function derivedDocPaths() {
|
|
28094
|
+
return [CONTEXT_PATHS.waironGuideMd(), CONTEXT_PATHS.domainsMd()];
|
|
28095
|
+
}
|
|
28096
|
+
function renderDomainsDoc() {
|
|
28097
|
+
const domains = resolveDomains();
|
|
28098
|
+
const lines = [
|
|
28099
|
+
versionStamp(),
|
|
28100
|
+
`# Domains`,
|
|
28101
|
+
``,
|
|
28102
|
+
`> Auto-generated by wairon. The human developer rebuilds this with \`wairon generate\`. `,
|
|
28103
|
+
``
|
|
28104
|
+
];
|
|
28105
|
+
if (domains.length === 0) {
|
|
28106
|
+
lines.push("_No domains yet. Define subsystems in the spec tree, or add free-standing domains with `wairon domains add`._");
|
|
28107
|
+
} else {
|
|
28108
|
+
lines.push(`**${domains.length} domain(s).**`);
|
|
28109
|
+
lines.push("");
|
|
28110
|
+
lines.push("| ID | Name | Source | Owned paths |");
|
|
28111
|
+
lines.push("|----|------|--------|-------------|");
|
|
28112
|
+
for (const d of domains) {
|
|
28113
|
+
const name = d.name ?? d.id;
|
|
28114
|
+
const source = d.boundTo ? `subsystem \`${d.boundTo}\`` : "free-standing";
|
|
28115
|
+
lines.push(`| \`${d.id}\` | ${name} | ${source} | \`${d.ownedPaths.join("`, `") || "\u2014"}\` |`);
|
|
28116
|
+
}
|
|
28117
|
+
}
|
|
28118
|
+
return lines.join("\n") + "\n";
|
|
28119
|
+
}
|
|
28120
|
+
function renderWaironGuide() {
|
|
28121
|
+
const domains = resolveDomains();
|
|
28122
|
+
let projectName = "this project";
|
|
28123
|
+
try {
|
|
28124
|
+
projectName = projectConfigRepository.load()?.name ?? projectName;
|
|
28125
|
+
} catch {
|
|
28126
|
+
}
|
|
28127
|
+
const projectCtx = readProjectContext();
|
|
28128
|
+
const archCtx = readArchitectureContext();
|
|
28129
|
+
const lines = [
|
|
28130
|
+
versionStamp(),
|
|
28131
|
+
`<!-- wairon-generated \u2014 do not edit directly; the human developer rebuilds this with \`wairon generate\` -->`,
|
|
28132
|
+
``
|
|
28133
|
+
];
|
|
28134
|
+
if (projectCtx) {
|
|
28135
|
+
lines.push(`# Project Context \u2014 ${projectName}`);
|
|
28136
|
+
lines.push("");
|
|
28137
|
+
lines.push(projectCtx.trim());
|
|
28138
|
+
lines.push("");
|
|
28139
|
+
lines.push("---");
|
|
28140
|
+
lines.push("");
|
|
28141
|
+
}
|
|
28142
|
+
if (archCtx) {
|
|
28143
|
+
lines.push("# Architecture");
|
|
28144
|
+
lines.push("");
|
|
28145
|
+
lines.push(archCtx.trim());
|
|
28146
|
+
lines.push("");
|
|
28147
|
+
lines.push("---");
|
|
28148
|
+
lines.push("");
|
|
28149
|
+
}
|
|
28150
|
+
lines.push(`# Domain Map (${domains.length} domain${domains.length !== 1 ? "s" : ""})`);
|
|
28151
|
+
lines.push("");
|
|
28152
|
+
if (domains.length === 0) {
|
|
28153
|
+
lines.push("_No domains yet._");
|
|
28154
|
+
} else {
|
|
28155
|
+
lines.push("| ID | Source | Name |");
|
|
28156
|
+
lines.push("|----|--------|------|");
|
|
28157
|
+
for (const d of domains) {
|
|
28158
|
+
const name = d.name ?? d.id;
|
|
28159
|
+
const source = d.boundTo ? `subsystem \`${d.boundTo}\`` : "free-standing";
|
|
28160
|
+
lines.push(`| \`${d.id}\` | ${source} | ${name} |`);
|
|
28161
|
+
}
|
|
28162
|
+
}
|
|
28163
|
+
lines.push("");
|
|
28164
|
+
lines.push("---");
|
|
28165
|
+
lines.push("");
|
|
28166
|
+
const mcpSettingsPath = require("path").join(process.cwd(), ".claude", "settings.json");
|
|
28167
|
+
let mcpInstalled = false;
|
|
28168
|
+
try {
|
|
28169
|
+
const s = JSON.parse(require("fs").readFileSync(mcpSettingsPath, "utf8"));
|
|
28170
|
+
mcpInstalled = !!s?.mcpServers?.wairon;
|
|
28171
|
+
} catch {
|
|
28172
|
+
}
|
|
28173
|
+
if (mcpInstalled) {
|
|
28174
|
+
lines.push("# wairon MCP Tools");
|
|
28175
|
+
lines.push("");
|
|
28176
|
+
lines.push("The **wairon MCP server** is active in this project. The tools are self-describing; call them directly:");
|
|
28177
|
+
lines.push("");
|
|
28178
|
+
lines.push("- Authoring: `sdd_initialize_system`, `sdd_add_subsystem`, `sdd_set_public_interfaces`, `sdd_set_subsystem_project_path`, `sdd_add_component`, `sdd_define_interface`, `sdd_set_endpoints`, `sdd_write_narrative`, `sdd_add_type`.");
|
|
28179
|
+
lines.push("- Reading & maintenance: `sdd_get_spec`, `sdd_update_spec`, `sdd_delete_spec`, `sdd_validate_tree`, `sdd_get_status`.");
|
|
28180
|
+
lines.push("- Topology: `listAgents`, `getAgent`, `listDomains`, `validateTopology`, `getProjectConfig`.");
|
|
28181
|
+
lines.push("");
|
|
28182
|
+
lines.push("Use these MCP tools to query and change project state \u2014 never the `wairon` CLI (that is the human developer's tool).");
|
|
28183
|
+
lines.push("");
|
|
28184
|
+
lines.push("---");
|
|
28185
|
+
lines.push("");
|
|
28186
|
+
}
|
|
28187
|
+
lines.push(GLOBAL_GUIDE_BODY);
|
|
28188
|
+
lines.push("");
|
|
28189
|
+
return lines.join("\n");
|
|
28190
|
+
}
|
|
28191
|
+
function syncContextFiles() {
|
|
28192
|
+
const domainsContent = renderDomainsDoc();
|
|
28193
|
+
const guideContent = renderWaironGuide();
|
|
28194
|
+
const domainsUpdated = writeDomainsDoc(domainsContent);
|
|
28195
|
+
const guideUpdated = writeGuideDoc(guideContent);
|
|
28196
|
+
return { domainsUpdated, guideUpdated };
|
|
28197
|
+
}
|
|
28198
|
+
var CONTEXT_PATHS;
|
|
28199
|
+
var init_context = __esm({
|
|
28200
|
+
"src/core/context.ts"() {
|
|
28201
|
+
"use strict";
|
|
28202
|
+
init_fs();
|
|
28203
|
+
init_ai_guide();
|
|
28204
|
+
init_stamp();
|
|
28205
|
+
init_domain_projector();
|
|
28206
|
+
init_project_config();
|
|
28207
|
+
CONTEXT_PATHS = {
|
|
28208
|
+
dir: () => contextDir(),
|
|
28209
|
+
projectMd: () => contextDir("project.md"),
|
|
28210
|
+
architectureMd: () => contextDir("architecture.md"),
|
|
28211
|
+
domainsMd: () => contextDir("domains.md"),
|
|
28212
|
+
waironGuideMd: () => contextDir("wairon-guide.md")
|
|
28213
|
+
};
|
|
28205
28214
|
}
|
|
28206
28215
|
});
|
|
28207
28216
|
|
|
@@ -28240,7 +28249,6 @@ var init_core = __esm({
|
|
|
28240
28249
|
init_statehash();
|
|
28241
28250
|
init_agent_resolver();
|
|
28242
28251
|
init_skills();
|
|
28243
|
-
init_context();
|
|
28244
28252
|
init_surfaces();
|
|
28245
28253
|
init_openapi();
|
|
28246
28254
|
init_packstore();
|
|
@@ -28260,6 +28268,7 @@ var init_core = __esm({
|
|
|
28260
28268
|
init_budget_policy();
|
|
28261
28269
|
init_ai_guide();
|
|
28262
28270
|
init_stamp();
|
|
28271
|
+
init_context();
|
|
28263
28272
|
}
|
|
28264
28273
|
});
|
|
28265
28274
|
|
|
@@ -31132,6 +31141,15 @@ function reinjectLocalGuides2(projectRoot2, targets) {
|
|
|
31132
31141
|
function readStampVersion2(content) {
|
|
31133
31142
|
return readStampVersion(content);
|
|
31134
31143
|
}
|
|
31144
|
+
function syncContextFiles2() {
|
|
31145
|
+
return syncContextFiles();
|
|
31146
|
+
}
|
|
31147
|
+
function hasContext2() {
|
|
31148
|
+
return hasContext();
|
|
31149
|
+
}
|
|
31150
|
+
function derivedDocPaths2() {
|
|
31151
|
+
return derivedDocPaths();
|
|
31152
|
+
}
|
|
31135
31153
|
async function runSubsystemAdd(id, options = {}) {
|
|
31136
31154
|
logger.header("wairon subsystem add");
|
|
31137
31155
|
if (!projectConfigExists2()) {
|
|
@@ -31240,7 +31258,6 @@ async function runSkillsInstall() {
|
|
|
31240
31258
|
// src/commands/init.ts
|
|
31241
31259
|
init_defaults();
|
|
31242
31260
|
init_project();
|
|
31243
|
-
init_context();
|
|
31244
31261
|
async function runInit(options = {}) {
|
|
31245
31262
|
logger.header("wairon init");
|
|
31246
31263
|
const cwd = process.cwd();
|
|
@@ -31531,7 +31548,7 @@ async function executeInit(projectName, projectConfig, guidePlan) {
|
|
|
31531
31548
|
logger.warn(`Failed to automatically register MCP server for Antigravity: ${err}`);
|
|
31532
31549
|
}
|
|
31533
31550
|
}
|
|
31534
|
-
|
|
31551
|
+
syncContextFiles2();
|
|
31535
31552
|
logger.verbose("Context files seeded in .wai/context/");
|
|
31536
31553
|
try {
|
|
31537
31554
|
ensureProjectInitialized2(projectName);
|
|
@@ -31720,7 +31737,6 @@ init_logger();
|
|
|
31720
31737
|
init_paths();
|
|
31721
31738
|
init_errors();
|
|
31722
31739
|
init_base();
|
|
31723
|
-
init_context();
|
|
31724
31740
|
init_fs();
|
|
31725
31741
|
init_project();
|
|
31726
31742
|
var WAIRON_AGENT_FILE = /-(owner|implementer|architect)\.md$/;
|
|
@@ -31789,8 +31805,8 @@ async function generateLayer(options = {}) {
|
|
|
31789
31805
|
}
|
|
31790
31806
|
}
|
|
31791
31807
|
if (options.dryRun) return;
|
|
31792
|
-
if (
|
|
31793
|
-
|
|
31808
|
+
if (hasContext2()) {
|
|
31809
|
+
syncContextFiles2();
|
|
31794
31810
|
logger.verbose("Context files synced.");
|
|
31795
31811
|
}
|
|
31796
31812
|
if (pathExists(AI_PATHS.specsSystem())) {
|
|
@@ -32964,7 +32980,6 @@ init_paths();
|
|
|
32964
32980
|
init_errors();
|
|
32965
32981
|
init_fs();
|
|
32966
32982
|
init_provision();
|
|
32967
|
-
init_context();
|
|
32968
32983
|
init_skills();
|
|
32969
32984
|
init_specs2();
|
|
32970
32985
|
init_lockfile();
|
|
@@ -33107,10 +33122,8 @@ async function runDoctor(options = {}) {
|
|
|
33107
33122
|
}
|
|
33108
33123
|
}
|
|
33109
33124
|
console.log(import_chalk12.default.bold(`Generated files ${import_chalk12.default.gray("(stale = older than installed)")}`));
|
|
33110
|
-
for (const
|
|
33111
|
-
|
|
33112
|
-
[".wai/context/domains.md", CONTEXT_PATHS.domainsMd()]
|
|
33113
|
-
]) {
|
|
33125
|
+
for (const p of derivedDocPaths2()) {
|
|
33126
|
+
const label = path38.relative(getProjectRoot(), p).replace(/\\/g, "/");
|
|
33114
33127
|
if (!pathExists(p)) {
|
|
33115
33128
|
line(tally, "warn", `${label} \u2014 not generated yet (run \`wairon generate\`)`);
|
|
33116
33129
|
continue;
|
|
@@ -33252,7 +33265,7 @@ async function applyFixes() {
|
|
|
33252
33265
|
}
|
|
33253
33266
|
console.log(import_chalk12.default.bold("Applying fixes\u2026"));
|
|
33254
33267
|
try {
|
|
33255
|
-
|
|
33268
|
+
syncContextFiles2();
|
|
33256
33269
|
exportSddSkills(targets);
|
|
33257
33270
|
const guides = reinjectLocalGuides2(process.cwd(), targets);
|
|
33258
33271
|
console.log(` ${icon("ok")} Regenerated context files, skills, and ${guides.length} local guide(s).`);
|