craftar 0.0.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/core/frontmatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Layer order (weak → strong): base recipes → stack recipes → profile → workspace → local.
3
+ * Recipes are expanded depth-first through `extends`, each recipe applied once.
4
+ */
5
+ export function resolve(forge, ws) {
6
+ const profile = forge.profiles.get(ws.profile);
7
+ if (!profile)
8
+ throw new Error(`profile "${ws.profile}" not found in Forge (${[...forge.profiles.keys()].join(", ") || "none"})`);
9
+ const warnings = [];
10
+ const wanted = [...profile.recipes, ...ws.recipes.add].filter((r) => !ws.recipes.remove.includes(r));
11
+ const order = [];
12
+ const visiting = new Set();
13
+ const visit = (name, chain) => {
14
+ if (order.includes(name))
15
+ return;
16
+ if (visiting.has(name))
17
+ throw new Error(`recipe cycle: ${[...chain, name].join(" → ")}`);
18
+ const r = forge.recipes.get(name);
19
+ if (!r)
20
+ throw new Error(`recipe "${name}" not found (referenced by ${chain.at(-1) ?? "profile " + profile.name})`);
21
+ visiting.add(name);
22
+ for (const parent of r.extends)
23
+ visit(parent, [...chain, name]);
24
+ visiting.delete(name);
25
+ order.push(name);
26
+ };
27
+ for (const r of wanted)
28
+ visit(r, []);
29
+ // Slot exclusivity
30
+ const slots = new Map();
31
+ for (const name of order) {
32
+ const slot = forge.recipes.get(name).slot;
33
+ if (!slot)
34
+ continue;
35
+ const prev = slots.get(slot);
36
+ if (prev && prev !== name)
37
+ throw new Error(`recipes "${prev}" and "${name}" both occupy slot "${slot}"`);
38
+ slots.set(slot, name);
39
+ }
40
+ // Params: recipe defaults (in order) → profile → workspace overrides
41
+ const params = {};
42
+ for (const name of order) {
43
+ for (const [k, v] of Object.entries(forge.recipes.get(name).params))
44
+ if (v.default !== undefined)
45
+ params[k] = v.default;
46
+ }
47
+ Object.assign(params, profile.params, ws.overrides.params);
48
+ // Ingredients
49
+ const disabled = ws.overrides.ingredients.disable;
50
+ const picked = new Map();
51
+ for (const name of order) {
52
+ for (const refStr of forge.recipes.get(name).ingredients) {
53
+ const ref = refStr;
54
+ const ing = forge.ingredients.get(ref);
55
+ if (!ing) {
56
+ warnings.push(`recipe "${name}" references missing ingredient ${ref}`);
57
+ continue;
58
+ }
59
+ const prev = picked.get(ref);
60
+ picked.set(ref, { ...ing, via: prev ? [...prev.via, name] : [name] });
61
+ }
62
+ }
63
+ for (const d of disabled)
64
+ picked.delete(d);
65
+ const targets = [...new Set(ws.targets ?? profile.targets)];
66
+ return { profile, recipes: order, targets, params, ingredients: [...picked.values()], disabled, warnings };
67
+ }
68
+ /** Substitute `{{param}}` placeholders. Unknown placeholders are left untouched (and reported by the caller). */
69
+ export function substitute(text, params, missing) {
70
+ return text.replace(/\{\{\s*([A-Za-z0-9_.]+)\s*\}\}/g, (m, key) => {
71
+ if (key in params)
72
+ return String(params[key]);
73
+ missing?.add(key);
74
+ return m;
75
+ });
76
+ }
77
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/core/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ const PATTERNS = [
2
+ { kind: "github-token", re: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/ },
3
+ { kind: "github-token", re: /\bgithub_pat_[A-Za-z0-9_]{22,}\b/ },
4
+ { kind: "aws-access-key", re: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/ },
5
+ { kind: "slack-token", re: /\bxox[abprs]-[A-Za-z0-9-]{10,}/ },
6
+ { kind: "api-key", re: /\bsk-(?:ant-)?[A-Za-z0-9_-]{32,}/ },
7
+ { kind: "private-key", re: /-----BEGIN (?:[A-Z]+ )?PRIVATE KEY-----/ },
8
+ { kind: "azure-devops-pat", re: /(?<![A-Za-z0-9])[a-z0-9]{52}(?![A-Za-z0-9])/ },
9
+ ];
10
+ /** Scan text line by line with the known token patterns. */
11
+ export function findSecrets(text) {
12
+ const out = [];
13
+ text.split(/\r?\n/).forEach((line, i) => {
14
+ const hit = PATTERNS.find((p) => p.re.test(line));
15
+ if (hit)
16
+ out.push({ kind: hit.kind, line: i + 1 });
17
+ });
18
+ return out;
19
+ }
20
+ export function shannonEntropy(s) {
21
+ if (!s.length)
22
+ return 0;
23
+ const counts = new Map();
24
+ for (const ch of s)
25
+ counts.set(ch, (counts.get(ch) ?? 0) + 1);
26
+ let h = 0;
27
+ for (const n of counts.values()) {
28
+ const p = n / s.length;
29
+ h -= p * Math.log2(p);
30
+ }
31
+ return h;
32
+ }
33
+ const ENV_REF = /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/;
34
+ const TOKEN_CHARS = /^[A-Za-z0-9+/=_-]+$/;
35
+ /** Entropy rule for a single config value (MCP `env` / `args`); never used on markdown bodies. */
36
+ export function looksLikeSecretValue(value) {
37
+ if (ENV_REF.test(value))
38
+ return false;
39
+ return value.length >= 20 && TOKEN_CHARS.test(value) && /[A-Za-z]/.test(value) && /[0-9]/.test(value) && shannonEntropy(value) >= 4;
40
+ }
41
+ /** Kind of secret a config value looks like: a known pattern first, then the entropy rule. */
42
+ export function secretValueKind(value) {
43
+ const hit = findSecrets(value)[0];
44
+ if (hit)
45
+ return hit.kind;
46
+ return looksLikeSecretValue(value) ? "high-entropy-value" : null;
47
+ }
48
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/core/secrets.ts"],"names":[],"mappings":"AAUA,MAAM,QAAQ,GAAmC;IAC/C,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,8CAA8C,EAAE;IAC5E,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,kCAAkC,EAAE;IAChE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,+BAA+B,EAAE;IAC/D,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,gCAAgC,EAAE;IAC7D,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,kCAAkC,EAAE;IAC3D,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,yCAAyC,EAAE;IACtE,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,6CAA6C,EAAE;CAChF,CAAC;AAEF,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAClD,IAAI,GAAG;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,IAAI,CAAC,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,EAAE,IAAI,CAAC;QAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACvB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,OAAO,GAAG,gCAAgC,CAAC;AACjD,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAE1C,kGAAkG;AAClG,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,KAAK,CAAC,MAAM,IAAI,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACtI,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC;IACzB,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC"}
@@ -0,0 +1,231 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import YAML from "yaml";
4
+ import { loadForge, exists } from "./forge.js";
5
+ import { resolve, substitute } from "./resolve.js";
6
+ import { hashNormalized, stripBom, toLf } from "./text.js";
7
+ import { LockSchema, WorkspaceConfigSchema } from "../schema/index.js";
8
+ import { claudeCode } from "../emitters/claude-code.js";
9
+ import { kiro } from "../emitters/kiro.js";
10
+ import { agentsMd } from "../emitters/agents-md.js";
11
+ export const WORKSPACE_FILE = "craftar.yaml";
12
+ export const LOCAL_FILE = "craftar.local.yaml";
13
+ export const LOCK_FILE = "craftar.lock";
14
+ const EMITTERS = { "claude-code": claudeCode, kiro, "agents-md": agentsMd };
15
+ export async function loadWorkspace(root) {
16
+ root = path.resolve(root);
17
+ const file = path.join(root, WORKSPACE_FILE);
18
+ if (!(await exists(file)))
19
+ throw new Error(`${WORKSPACE_FILE} not found in ${root} — run \`craftar init\` or \`craftar import\` first`);
20
+ const base = YAML.parse(await fs.readFile(file, "utf8")) ?? {};
21
+ const localFile = path.join(root, LOCAL_FILE);
22
+ const local = (await exists(localFile)) ? YAML.parse(await fs.readFile(localFile, "utf8")) ?? {} : {};
23
+ const config = WorkspaceConfigSchema.parse(deepMerge(base, local));
24
+ const forgeRoot = /^[a-z]+:\/\/|^git@/.test(config.forge) ? config.forge : path.resolve(root, config.forge);
25
+ if (!(await exists(forgeRoot)))
26
+ throw new Error(`Forge not found at ${forgeRoot} (remote Forges are not supported yet — clone it and point \`forge:\` at the path)`);
27
+ return { root, config, forge: await loadForge(forgeRoot) };
28
+ }
29
+ /** Layer merge: objects merge key by key; arrays and scalars from the stronger layer replace the weaker one. */
30
+ function deepMerge(a, b) {
31
+ if (b === undefined)
32
+ return a;
33
+ if (Array.isArray(a) || Array.isArray(b))
34
+ return b;
35
+ if (a && b && typeof a === "object" && typeof b === "object") {
36
+ const out = { ...a };
37
+ for (const k of Object.keys(b))
38
+ out[k] = k in a ? deepMerge(a[k], b[k]) : b[k];
39
+ return out;
40
+ }
41
+ return b;
42
+ }
43
+ export async function plan(ws) {
44
+ const resolution = resolve(ws.forge, ws.config);
45
+ const warnings = [...resolution.warnings];
46
+ if (resolution.targets.length === 0) {
47
+ warnings.push("no targets resolved — nothing will be emitted and every file in craftar.lock becomes an orphan (an empty list in craftar.local.yaml replaces the workspace's)");
48
+ }
49
+ /** Unresolved placeholder → refs of the ingredients citing it. */
50
+ const missingParams = new Map();
51
+ const ctx = {
52
+ forge: ws.forge,
53
+ resolution,
54
+ workspaceRoot: ws.root,
55
+ async readExisting(rel) {
56
+ try {
57
+ return await fs.readFile(path.join(ws.root, rel));
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ },
63
+ async text(ing, file) {
64
+ const raw = await fs.readFile(path.join(ing.dir, file), "utf8");
65
+ const missing = new Set();
66
+ const out = substitute(toLf(stripBom(raw)), resolution.params, missing);
67
+ for (const key of missing)
68
+ missingParams.set(key, (missingParams.get(key) ?? new Set()).add(ing.ref));
69
+ return out;
70
+ },
71
+ bytes(ing, file) {
72
+ return fs.readFile(path.join(ing.dir, file));
73
+ },
74
+ warn(msg) {
75
+ warnings.push(msg);
76
+ },
77
+ };
78
+ const files = [];
79
+ for (const t of resolution.targets) {
80
+ const em = EMITTERS[t];
81
+ if (!em) {
82
+ warnings.push(`target "${t}" has no emitter yet`);
83
+ continue;
84
+ }
85
+ files.push(...(await em.emit(ctx)));
86
+ }
87
+ for (const [key, refs] of [...missingParams].sort(([a], [b]) => a.localeCompare(b))) {
88
+ warnings.push(`param "${key}" has no value in any layer — left verbatim (${[...refs].sort().join(", ")})`);
89
+ }
90
+ // Duplicate path guard
91
+ const seen = new Map();
92
+ for (const f of files) {
93
+ const prev = seen.get(f.path);
94
+ if (prev)
95
+ warnings.push(`two ingredients write ${f.path}: ${prev} and ${f.ingredient} (last wins)`);
96
+ seen.set(f.path, f.ingredient);
97
+ }
98
+ return { resolution, files: dedupeLastWins(files), warnings };
99
+ }
100
+ function dedupeLastWins(files) {
101
+ const m = new Map();
102
+ for (const f of files)
103
+ m.set(f.path, f);
104
+ return [...m.values()].sort((a, b) => a.path.localeCompare(b.path));
105
+ }
106
+ /* ------------------------------------------------------------------ */
107
+ /* Lock */
108
+ /* ------------------------------------------------------------------ */
109
+ export async function readLock(root) {
110
+ const f = path.join(root, LOCK_FILE);
111
+ if (!(await exists(f)))
112
+ return null;
113
+ return LockSchema.parse(JSON.parse(await fs.readFile(f, "utf8")));
114
+ }
115
+ export async function writeLock(root, lock) {
116
+ await fs.writeFile(path.join(root, LOCK_FILE), JSON.stringify(lock, null, 2) + "\n", "utf8");
117
+ }
118
+ export async function status(ws, p, lock) {
119
+ const out = [];
120
+ const lockByPath = new Map((lock?.files ?? []).map((e) => [e.path, e]));
121
+ for (const f of p.files) {
122
+ const disk = await readDisk(ws.root, f.path);
123
+ const entry = lockByPath.get(f.path);
124
+ const planHash = hashNormalized(f.content);
125
+ let state;
126
+ if (disk === null)
127
+ state = "new";
128
+ else if (entry) {
129
+ const diskHash = hashNormalized(disk);
130
+ if (diskHash !== entry.hash)
131
+ state = diskHash === planHash ? "unchanged" : "drift";
132
+ else
133
+ state = diskHash === planHash ? "unchanged" : "update";
134
+ }
135
+ else
136
+ state = hashNormalized(disk) === planHash || sameJson(f.path, disk, f.content) ? "adopt" : "collision";
137
+ out.push({ path: f.path, state, target: f.target, ingredient: f.ingredient, planned: f, lock: entry });
138
+ }
139
+ const planned = new Set(p.files.map((f) => f.path));
140
+ for (const e of lock?.files ?? []) {
141
+ if (planned.has(e.path))
142
+ continue;
143
+ const disk = await readDisk(ws.root, e.path);
144
+ if (disk === null)
145
+ continue; // already gone
146
+ out.push({ path: e.path, state: hashNormalized(disk) === e.hash ? "orphan" : "orphan-drift", target: e.target, ingredient: e.ingredient, lock: e });
147
+ }
148
+ return out.sort((a, b) => a.path.localeCompare(b.path));
149
+ }
150
+ /** Formatting-insensitive equality for JSON files (e.g. a hand-formatted .mcp.json). */
151
+ function sameJson(rel, a, b) {
152
+ if (!rel.endsWith(".json"))
153
+ return false;
154
+ try {
155
+ return JSON.stringify(JSON.parse(stripBom(a.toString("utf8")))) === JSON.stringify(JSON.parse(stripBom(b.toString("utf8"))));
156
+ }
157
+ catch {
158
+ return false;
159
+ }
160
+ }
161
+ async function readDisk(root, rel) {
162
+ try {
163
+ return await fs.readFile(path.join(root, rel));
164
+ }
165
+ catch {
166
+ return null;
167
+ }
168
+ }
169
+ export async function apply(ws, p, statuses, opts = {}) {
170
+ const written = [];
171
+ const removed = [];
172
+ const skipped = [];
173
+ const entries = [];
174
+ for (const s of statuses) {
175
+ switch (s.state) {
176
+ case "new":
177
+ case "update":
178
+ case "adopt":
179
+ if (!opts.dryRun)
180
+ await writeFile(ws.root, s.planned);
181
+ written.push(s.path);
182
+ entries.push(entry(s.planned));
183
+ break;
184
+ case "unchanged":
185
+ entries.push(entry(s.planned));
186
+ break;
187
+ case "drift":
188
+ if (opts.overwriteDrift) {
189
+ if (!opts.dryRun)
190
+ await writeFile(ws.root, s.planned);
191
+ written.push(s.path);
192
+ entries.push(entry(s.planned));
193
+ }
194
+ else {
195
+ skipped.push(s);
196
+ entries.push(s.lock); // keep the old hash so the drift stays visible
197
+ }
198
+ break;
199
+ case "collision":
200
+ skipped.push(s);
201
+ break;
202
+ case "orphan":
203
+ if (!opts.dryRun)
204
+ await fs.rm(path.join(ws.root, s.path), { force: true });
205
+ removed.push(s.path);
206
+ break;
207
+ case "orphan-drift":
208
+ skipped.push(s);
209
+ break;
210
+ }
211
+ }
212
+ const lock = {
213
+ schema: 1,
214
+ forge: { source: ws.config.forge, commit: ws.forge.commit },
215
+ profile: ws.config.profile,
216
+ generatedAt: new Date().toISOString(),
217
+ files: entries.sort((a, b) => a.path.localeCompare(b.path)),
218
+ };
219
+ if (!opts.dryRun)
220
+ await writeLock(ws.root, lock);
221
+ return { written, removed, skipped, lock };
222
+ }
223
+ function entry(f) {
224
+ return { path: f.path, hash: hashNormalized(f.content), target: f.target, ingredient: f.ingredient };
225
+ }
226
+ async function writeFile(root, f) {
227
+ const abs = path.join(root, f.path);
228
+ await fs.mkdir(path.dirname(abs), { recursive: true });
229
+ await fs.writeFile(abs, f.content);
230
+ }
231
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/core/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { createHash } from "node:crypto";
2
+ /** Strip a leading UTF-8 BOM, if any. */
3
+ export function stripBom(s) {
4
+ return s.charCodeAt(0) === 0xfeff ? s.slice(1) : s;
5
+ }
6
+ /** Normalize CRLF and lone CR to LF. */
7
+ export function toLf(s) {
8
+ return s.replace(/\r\n?/g, "\n");
9
+ }
10
+ /** Convert LF to CRLF (input is normalized first, so CRLF is never doubled). */
11
+ export function toCrlf(s) {
12
+ return toLf(s).replace(/\n/g, "\r\n");
13
+ }
14
+ /**
15
+ * Content hash that is stable across Windows/Unix checkouts.
16
+ * This is the lesson from the previous generator: hashing raw bytes while git
17
+ * rewrites CRLF on checkout made every managed file look hand-edited.
18
+ */
19
+ export function hashNormalized(content) {
20
+ const text = Buffer.isBuffer(content) ? content.toString("utf8") : content;
21
+ return "sha256:" + createHash("sha256").update(toLf(stripBom(text)), "utf8").digest("hex");
22
+ }
23
+ export function detectEol(s) {
24
+ const crlf = (s.match(/\r\n/g) ?? []).length;
25
+ const lf = (s.match(/(?<!\r)\n/g) ?? []).length;
26
+ return crlf > lf ? "crlf" : "lf";
27
+ }
28
+ export function withEol(s, eol) {
29
+ return eol === "crlf" ? toCrlf(s) : toLf(s);
30
+ }
31
+ export function hasBom(buf) {
32
+ return buf.length >= 3 && buf[0] === 0xef && buf[1] === 0xbb && buf[2] === 0xbf;
33
+ }
34
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/core/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,yCAAyC;AACzC,MAAM,UAAU,QAAQ,CAAC,CAAS;IAChC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,MAAM,CAAC,CAAS;IAC9B,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAwB;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC3E,OAAO,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC7F,CAAC;AAID,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IAChD,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,CAAS,EAAE,GAAQ;IACzC,OAAO,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAW;IAChC,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAClF,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { appliesTo, outName, textFile } from "./shared.js";
2
+ /**
3
+ * AGENTS.md target (open standard read by Codex, Cursor, Warp, Copilot, Kiro, Kimi…).
4
+ * Concatenates the `always` rules into one file; `fileMatch`/`manual` rules are listed with their scope
5
+ * so agents that only read AGENTS.md still know where the detailed conventions live.
6
+ */
7
+ export const agentsMd = {
8
+ target: "agents-md",
9
+ async emit(ctx) {
10
+ const rules = ctx.resolution.ingredients.filter((i) => i.meta.type === "rule" && appliesTo(i.meta.targets, "agents-md"));
11
+ if (!rules.length)
12
+ return [];
13
+ const parts = [
14
+ "<!-- GENERATED by craftar from the Forge. Edit the rule ingredients, not this file. -->",
15
+ "",
16
+ `# AGENTS.md — ${ctx.resolution.profile.name}`,
17
+ "",
18
+ "Conventions for coding agents working in this workspace. Sections below are the always-on rules;",
19
+ "scoped rules are listed at the end with the paths they apply to.",
20
+ "",
21
+ ];
22
+ const scoped = [];
23
+ for (const ing of rules) {
24
+ if (ing.meta.type !== "rule")
25
+ continue;
26
+ const body = (await ctx.text(ing, ing.meta.file)).replace(/\n+$/, "");
27
+ if (ing.meta.inclusion === "always") {
28
+ parts.push(`<!-- rule: ${outName(ing.meta)} -->`, body, "");
29
+ }
30
+ else {
31
+ const scope = ing.meta.inclusion === "fileMatch" ? ` — applies to \`${[ing.meta.fileMatchPattern].flat().join("`, `")}\`` : ` — ${ing.meta.inclusion}`;
32
+ scoped.push(`- \`.claude/rules/${outName(ing.meta)}.md\`${scope}`);
33
+ }
34
+ }
35
+ if (scoped.length)
36
+ parts.push("## Scoped rules", "", ...scoped, "");
37
+ return [await textFile(ctx, "AGENTS.md", parts.join("\n"), "agents-md", "rule/*")];
38
+ },
39
+ };
40
+ //# sourceMappingURL=agents-md.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../../src/emitters/agents-md.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAY;IAC/B,MAAM,EAAE,WAAW;IACnB,KAAK,CAAC,IAAI,CAAC,GAAG;QACZ,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QACzH,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAa;YACtB,yFAAyF;YACzF,EAAE;YACF,iBAAiB,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE;YAC9C,EAAE;YACF,kGAAkG;YAClG,kEAAkE;YAClE,EAAE;SACH,CAAC;QACF,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YACvC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACtE,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;gBACpC,KAAK,CAAC,IAAI,CAAC,cAAc,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACvJ,MAAM,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QACpE,OAAO,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrF,CAAC;CACF,CAAC"}
@@ -0,0 +1,76 @@
1
+ import { serializeFrontmatter } from "../core/frontmatter.js";
2
+ import { listFiles } from "../core/forge.js";
3
+ import { appliesTo, outName, textFile } from "./shared.js";
4
+ /**
5
+ * Claude Code target: `.claude/{rules,agents,commands,skills,scripts,hooks}` + `.mcp.json`.
6
+ * Files are emitted verbatim from the Forge so that `import` → `sync` on the source workspace is a no-op.
7
+ */
8
+ export const claudeCode = {
9
+ target: "claude-code",
10
+ async emit(ctx) {
11
+ const out = [];
12
+ const mcp = {};
13
+ const t = "claude-code";
14
+ for (const ing of ctx.resolution.ingredients) {
15
+ if (!appliesTo(ing.meta.targets, t))
16
+ continue;
17
+ const m = ing.meta;
18
+ switch (m.type) {
19
+ case "rule":
20
+ out.push(await textFile(ctx, `.claude/rules/${outName(m)}.md`, await ctx.text(ing, m.file), t, ing.ref));
21
+ break;
22
+ case "agent": {
23
+ const body = await ctx.text(ing, m.file);
24
+ const fm = m.frontmatterRaw ?? null;
25
+ const doc = serializeFrontmatter({ name: outName(m), description: m.description, tools: m.tools, model: m.model }, body, { raw: fm });
26
+ out.push(await textFile(ctx, `.claude/agents/${outName(m)}.md`, doc, t, ing.ref));
27
+ break;
28
+ }
29
+ case "command": {
30
+ const body = await ctx.text(ing, m.file);
31
+ const doc = serializeFrontmatter({ description: m.description, "argument-hint": m.argumentHint, "allowed-tools": m.allowedTools }, body, { raw: m.frontmatterRaw ?? null });
32
+ out.push(await textFile(ctx, `.claude/commands/${outName(m)}.md`, doc, t, ing.ref));
33
+ break;
34
+ }
35
+ case "skill": {
36
+ if (m.layout === "file") {
37
+ out.push(await textFile(ctx, `.claude/skills/${outName(m)}.md`, await ctx.text(ing, "SKILL.md"), t, ing.ref));
38
+ }
39
+ else {
40
+ for (const f of await listFiles(ing.dir)) {
41
+ if (f === "ingredient.yaml")
42
+ continue;
43
+ out.push(await anyFile(ctx, ing, f, `.claude/skills/${outName(m)}/${f}`, t));
44
+ }
45
+ }
46
+ break;
47
+ }
48
+ case "script":
49
+ for (const f of m.files)
50
+ out.push(await anyFile(ctx, ing, f, `.claude/scripts/${f}`, t));
51
+ break;
52
+ case "hook":
53
+ for (const f of m.files)
54
+ out.push(await anyFile(ctx, ing, f, `.claude/hooks/${f}`, t));
55
+ break;
56
+ case "mcp":
57
+ mcp[m.name] = m.server;
58
+ break;
59
+ case "steering":
60
+ break; // Kiro-only by nature
61
+ }
62
+ }
63
+ if (Object.keys(mcp).length) {
64
+ const json = JSON.stringify({ mcpServers: mcp }, null, 2) + "\n";
65
+ out.push(await textFile(ctx, ".mcp.json", json, t, "mcp/*"));
66
+ }
67
+ return out;
68
+ },
69
+ };
70
+ const TEXT_EXT = /\.(md|txt|json|ya?ml|ps1|py|sh|js|ts|cjs|mjs|toml|xml|csv)$/i;
71
+ async function anyFile(ctx, ing, file, relPath, target) {
72
+ if (TEXT_EXT.test(file))
73
+ return textFile(ctx, relPath, await ctx.text(ing, file), target, ing.ref);
74
+ return { path: relPath, content: await ctx.bytes(ing, file), target, ingredient: ing.ref };
75
+ }
76
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/emitters/claude-code.ts"],"names":[],"mappings":"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"}