mulch-cli 0.3.0 → 0.4.0

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 CHANGED
@@ -68,12 +68,12 @@ Everything is git-tracked. Clone a repo and your agents immediately have the pro
68
68
  |---------|-------------|
69
69
  | `mulch init` | Initialize `.mulch/` in the current project |
70
70
  | `mulch add <domain>` | Add a new expertise domain |
71
- | `mulch record <domain> --type <type>` | Record an expertise record (`--tags`, `--force`, `--relates-to`, `--supersedes`, `--stdin`, `--evidence-bead`) |
71
+ | `mulch record <domain> --type <type>` | Record an expertise record (`--tags`, `--force`, `--relates-to`, `--supersedes`, `--batch`, `--stdin`, `--dry-run`, `--evidence-bead`) |
72
72
  | `mulch edit <domain> <id>` | Edit an existing record by ID or 1-based index |
73
73
  | `mulch delete <domain> <id>` | Delete a record by ID or 1-based index |
74
74
  | `mulch query [domain]` | Query expertise (use `--all` for all domains) |
75
75
  | `mulch prime [domains...]` | Output AI-optimized expertise context (`--budget`, `--no-limit`, `--context`, `--files`, `--exclude-domain`, `--format`, `--export`) |
76
- | `mulch search [query]` | Search records across domains (`--domain`, `--type`, `--tag` filters) |
76
+ | `mulch search [query]` | Search records across domains with BM25 ranking (`--domain`, `--type`, `--tag` filters) |
77
77
  | `mulch compact [domain]` | Analyze compaction candidates or apply a compaction (`--analyze`, `--auto`, `--apply`, `--dry-run`, `--min-group`, `--max-records`) |
78
78
  | `mulch diff [ref]` | Show expertise changes between git refs (`mulch diff HEAD~3`, `mulch diff main..feature`) |
79
79
  | `mulch status` | Show expertise freshness and counts (`--json` for health metrics) |
@@ -97,7 +97,7 @@ Everything is git-tracked. Clone a repo and your agents immediately have the pro
97
97
  | `reference` | name, description | Key files, endpoints, or resources worth remembering |
98
98
  | `guide` | name, description | Step-by-step procedures for recurring tasks |
99
99
 
100
- All records support optional `--classification` (foundational / tactical / observational), evidence flags (`--evidence-commit`, `--evidence-issue`, `--evidence-file`), `--tags`, `--relates-to`, and `--supersedes` for linking.
100
+ All records support optional `--classification` (foundational / tactical / observational), evidence flags (`--evidence-commit`, `--evidence-issue`, `--evidence-file`), `--tags`, `--relates-to`, and `--supersedes` for linking. Cross-domain references use `domain:mx-hash` format (e.g., `--relates-to api:mx-abc123`).
101
101
 
102
102
  ## Example Output
103
103
 
@@ -161,6 +161,23 @@ Locks ensure correctness automatically. If two agents record to the same domain
161
161
 
162
162
  Each agent works in its own git worktree. On merge, `merge=union` combines all JSONL lines. Run `mulch doctor --fix` after merge to deduplicate if needed.
163
163
 
164
+ ### Batch recording
165
+
166
+ For recording multiple records atomically (e.g., at session end), use `--batch` or `--stdin`:
167
+
168
+ ```bash
169
+ # From a JSON file (single object or array of objects)
170
+ mulch record api --batch records.json
171
+
172
+ # From stdin
173
+ echo '[{"type":"convention","content":"Use UTC timestamps"}]' | mulch record api --stdin
174
+
175
+ # Preview first
176
+ mulch record api --batch records.json --dry-run
177
+ ```
178
+
179
+ Batch recording uses file locking — safe for concurrent use. Invalid records are skipped with errors; valid records in the same batch still succeed.
180
+
164
181
  **Maintenance during swarm work**:
165
182
 
166
183
  ```bash
package/dist/cli.js CHANGED
@@ -24,7 +24,7 @@ const program = new Command();
24
24
  program
25
25
  .name("mulch")
26
26
  .description("Let your agents grow 🌱")
27
- .version("0.3.0")
27
+ .version("0.4.0")
28
28
  .option("--json", "output as structured JSON");
29
29
  registerInitCommand(program);
30
30
  registerAddCommand(program);
@@ -1 +1 @@
1
- {"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkLpC,wBAAsB,UAAU,CAAC,OAAO,EAAE;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiIhB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyB7D"}
1
+ {"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyLpC,wBAAsB,UAAU,CAAC,OAAO,EAAE;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiIhB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyB7D"}
@@ -13,6 +13,7 @@ mulch prime
13
13
  \`\`\`
14
14
 
15
15
  This injects project-specific conventions, patterns, decisions, and other learnings into your context.
16
+ Use \`mulch prime --files src/foo.ts\` to load only records relevant to specific files.
16
17
 
17
18
  **Before completing your task**, review your work for insights worth preserving — conventions discovered,
18
19
  patterns applied, failures encountered, or decisions made — and record them:
@@ -20,19 +21,25 @@ patterns applied, failures encountered, or decisions made — and record them:
20
21
  mulch record <domain> --type <convention|pattern|failure|decision|reference|guide> --description "..."
21
22
  \`\`\`
22
23
 
24
+ Link evidence when available: \`--evidence-commit <sha>\`, \`--evidence-bead <id>\`
25
+
23
26
  Run \`mulch status\` to check domain health and entry counts.
24
27
  Run \`mulch --help\` for full usage.
25
28
  Mulch write commands use file locking and atomic writes — multiple agents can safely record to the same domain concurrently.
26
29
 
27
30
  ### Before You Finish
28
31
 
29
- 1. Store insights from this work session:
32
+ 1. Discover what to record:
33
+ \`\`\`bash
34
+ mulch learn
35
+ \`\`\`
36
+ 2. Store insights from this work session:
30
37
  \`\`\`bash
31
38
  mulch record <domain> --type <convention|pattern|failure|decision|reference|guide> --description "..."
32
39
  \`\`\`
33
- 2. Validate and commit:
40
+ 3. Validate and commit:
34
41
  \`\`\`bash
35
- mulch validate && git add .mulch/ && git commit -m "mulch: record learnings"
42
+ mulch sync
36
43
  \`\`\`
37
44
  `;
38
45
  const LEGACY_HEADER = "## Project Expertise (Mulch)";
@@ -1 +1 @@
1
- {"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { Command } from "commander";
3
3
  * Process records from stdin (JSON single object or array)
4
4
  * Validates, dedups, and appends with file locking
5
5
  */
6
- export declare function processStdinRecords(domain: string, jsonMode: boolean, force: boolean, stdinData?: string, cwd?: string): Promise<{
6
+ export declare function processStdinRecords(domain: string, jsonMode: boolean, force: boolean, dryRun: boolean, stdinData?: string, cwd?: string): Promise<{
7
7
  created: number;
8
8
  updated: number;
9
9
  skipped: number;
@@ -1 +1 @@
1
- {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../src/commands/record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAsB5C;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA+FlF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6b5D"}
1
+ {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../src/commands/record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAsB5C;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA0HlF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAumB5D"}
@@ -7,12 +7,12 @@ import { appendRecord, readExpertiseFile, writeExpertiseFile, findDuplicate, } f
7
7
  import { withFileLock } from "../utils/lock.js";
8
8
  import { recordSchema } from "../schemas/record-schema.js";
9
9
  import { outputJson, outputJsonError } from "../utils/json-output.js";
10
- import { readFileSync } from "node:fs";
10
+ import { readFileSync, existsSync } from "node:fs";
11
11
  /**
12
12
  * Process records from stdin (JSON single object or array)
13
13
  * Validates, dedups, and appends with file locking
14
14
  */
15
- export async function processStdinRecords(domain, jsonMode, force, stdinData, cwd) {
15
+ export async function processStdinRecords(domain, jsonMode, force, dryRun, stdinData, cwd) {
16
16
  const config = await readConfig(cwd);
17
17
  if (!config.domains.includes(domain)) {
18
18
  throw new Error(`Domain "${domain}" not found in config. Available domains: ${config.domains.join(", ") || "(none)"}`);
@@ -55,14 +55,15 @@ export async function processStdinRecords(domain, jsonMode, force, stdinData, cw
55
55
  if (validRecords.length === 0) {
56
56
  return { created: 0, updated: 0, skipped: 0, errors };
57
57
  }
58
- // Process valid records with file locking
58
+ // Process valid records with file locking (skip write in dry-run mode)
59
59
  const filePath = getExpertisePath(domain, cwd);
60
60
  let created = 0;
61
61
  let updated = 0;
62
62
  let skipped = 0;
63
- await withFileLock(filePath, async () => {
63
+ if (dryRun) {
64
+ // Dry-run: check for duplicates without writing
64
65
  const existing = await readExpertiseFile(filePath);
65
- let currentRecords = [...existing];
66
+ const currentRecords = [...existing];
66
67
  for (const record of validRecords) {
67
68
  const dup = findDuplicate(currentRecords, record);
68
69
  if (dup && !force) {
@@ -71,26 +72,51 @@ export async function processStdinRecords(domain, jsonMode, force, stdinData, cw
71
72
  record.type === "reference" ||
72
73
  record.type === "guide";
73
74
  if (isNamed) {
74
- // Upsert: replace in place
75
- currentRecords[dup.index] = record;
76
75
  updated++;
77
76
  }
78
77
  else {
79
- // Exact match: skip
80
78
  skipped++;
81
79
  }
82
80
  }
83
81
  else {
84
- // New record: append
85
- currentRecords.push(record);
86
82
  created++;
87
83
  }
88
84
  }
89
- // Write all changes at once
90
- if (created > 0 || updated > 0) {
91
- await writeExpertiseFile(filePath, currentRecords);
92
- }
93
- });
85
+ }
86
+ else {
87
+ // Normal mode: write with file locking
88
+ await withFileLock(filePath, async () => {
89
+ const existing = await readExpertiseFile(filePath);
90
+ let currentRecords = [...existing];
91
+ for (const record of validRecords) {
92
+ const dup = findDuplicate(currentRecords, record);
93
+ if (dup && !force) {
94
+ const isNamed = record.type === "pattern" ||
95
+ record.type === "decision" ||
96
+ record.type === "reference" ||
97
+ record.type === "guide";
98
+ if (isNamed) {
99
+ // Upsert: replace in place
100
+ currentRecords[dup.index] = record;
101
+ updated++;
102
+ }
103
+ else {
104
+ // Exact match: skip
105
+ skipped++;
106
+ }
107
+ }
108
+ else {
109
+ // New record: append
110
+ currentRecords.push(record);
111
+ created++;
112
+ }
113
+ }
114
+ // Write all changes at once
115
+ if (created > 0 || updated > 0) {
116
+ await writeExpertiseFile(filePath, currentRecords);
117
+ }
118
+ });
119
+ }
94
120
  return { created, updated, skipped, errors };
95
121
  }
96
122
  export function registerRecordCommand(program) {
@@ -119,12 +145,116 @@ export function registerRecordCommand(program) {
119
145
  .option("--supersedes <ids>", "comma-separated record IDs this supersedes")
120
146
  .option("--force", "force recording even if duplicate exists")
121
147
  .option("--stdin", "read JSON record(s) from stdin (single object or array)")
148
+ .option("--batch <file>", "read JSON record(s) from file (single object or array)")
149
+ .option("--dry-run", "preview what would be recorded without writing")
150
+ .addHelpText("after", `
151
+ Required fields per record type:
152
+ convention [content] or --description
153
+ pattern --name, --description (or [content])
154
+ failure --description, --resolution
155
+ decision --title, --rationale
156
+ reference --name, --description (or [content])
157
+ guide --name, --description (or [content])
158
+
159
+ Batch recording examples:
160
+ mulch record cli --batch records.json
161
+ mulch record cli --batch records.json --dry-run
162
+ echo '[{"type":"convention","content":"test"}]' > batch.json && mulch record cli --batch batch.json
163
+ `)
122
164
  .action(async (domain, content, options) => {
123
165
  const jsonMode = program.opts().json === true;
166
+ // Handle --batch mode
167
+ if (options.batch) {
168
+ const batchFile = options.batch;
169
+ const dryRun = options.dryRun === true;
170
+ if (!existsSync(batchFile)) {
171
+ if (jsonMode) {
172
+ outputJsonError("record", `Batch file not found: ${batchFile}`);
173
+ }
174
+ else {
175
+ console.error(chalk.red(`Error: batch file not found: ${batchFile}`));
176
+ }
177
+ process.exitCode = 1;
178
+ return;
179
+ }
180
+ try {
181
+ const fileContent = readFileSync(batchFile, "utf-8");
182
+ const result = await processStdinRecords(domain, jsonMode, options.force === true, dryRun, fileContent);
183
+ if (result.errors.length > 0) {
184
+ if (jsonMode) {
185
+ outputJsonError("record", `Validation errors: ${result.errors.join("; ")}`);
186
+ }
187
+ else {
188
+ console.error(chalk.red("Validation errors:"));
189
+ for (const error of result.errors) {
190
+ console.error(chalk.red(` ${error}`));
191
+ }
192
+ }
193
+ }
194
+ if (jsonMode) {
195
+ outputJson({
196
+ success: result.errors.length === 0 || result.created + result.updated > 0,
197
+ command: "record",
198
+ action: dryRun ? "dry-run" : "batch",
199
+ domain,
200
+ created: result.created,
201
+ updated: result.updated,
202
+ skipped: result.skipped,
203
+ errors: result.errors,
204
+ });
205
+ }
206
+ else {
207
+ if (dryRun) {
208
+ const total = result.created + result.updated;
209
+ if (total > 0 || result.skipped > 0) {
210
+ console.log(chalk.green(`✓ Dry-run complete. Would process ${total} record(s) in ${domain}:`));
211
+ if (result.created > 0) {
212
+ console.log(chalk.dim(` Create: ${result.created}`));
213
+ }
214
+ if (result.updated > 0) {
215
+ console.log(chalk.dim(` Update: ${result.updated}`));
216
+ }
217
+ if (result.skipped > 0) {
218
+ console.log(chalk.dim(` Skip: ${result.skipped}`));
219
+ }
220
+ console.log(chalk.dim(" Run without --dry-run to apply changes."));
221
+ }
222
+ else {
223
+ console.log(chalk.yellow("No records would be processed."));
224
+ }
225
+ }
226
+ else {
227
+ if (result.created > 0) {
228
+ console.log(chalk.green(`✔ Created ${result.created} record(s) in ${domain}`));
229
+ }
230
+ if (result.updated > 0) {
231
+ console.log(chalk.green(`✔ Updated ${result.updated} record(s) in ${domain}`));
232
+ }
233
+ if (result.skipped > 0) {
234
+ console.log(chalk.yellow(`Skipped ${result.skipped} duplicate(s) in ${domain}`));
235
+ }
236
+ }
237
+ }
238
+ if (result.errors.length > 0 && result.created + result.updated === 0) {
239
+ process.exitCode = 1;
240
+ }
241
+ }
242
+ catch (err) {
243
+ if (jsonMode) {
244
+ outputJsonError("record", err instanceof Error ? err.message : String(err));
245
+ }
246
+ else {
247
+ console.error(chalk.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
248
+ }
249
+ process.exitCode = 1;
250
+ }
251
+ return;
252
+ }
124
253
  // Handle --stdin mode
125
254
  if (options.stdin === true) {
255
+ const dryRun = options.dryRun === true;
126
256
  try {
127
- const result = await processStdinRecords(domain, jsonMode, options.force === true);
257
+ const result = await processStdinRecords(domain, jsonMode, options.force === true, dryRun);
128
258
  if (result.errors.length > 0) {
129
259
  if (jsonMode) {
130
260
  outputJsonError("record", `Validation errors: ${result.errors.join("; ")}`);
@@ -140,6 +270,7 @@ export function registerRecordCommand(program) {
140
270
  outputJson({
141
271
  success: result.errors.length === 0 || result.created + result.updated > 0,
142
272
  command: "record",
273
+ action: dryRun ? "dry-run" : "stdin",
143
274
  domain,
144
275
  created: result.created,
145
276
  updated: result.updated,
@@ -148,14 +279,35 @@ export function registerRecordCommand(program) {
148
279
  });
149
280
  }
150
281
  else {
151
- if (result.created > 0) {
152
- console.log(chalk.green(`✔ Created ${result.created} record(s) in ${domain}`));
153
- }
154
- if (result.updated > 0) {
155
- console.log(chalk.green(`✔ Updated ${result.updated} record(s) in ${domain}`));
282
+ if (dryRun) {
283
+ const total = result.created + result.updated;
284
+ if (total > 0 || result.skipped > 0) {
285
+ console.log(chalk.green(`✓ Dry-run complete. Would process ${total} record(s) in ${domain}:`));
286
+ if (result.created > 0) {
287
+ console.log(chalk.dim(` Create: ${result.created}`));
288
+ }
289
+ if (result.updated > 0) {
290
+ console.log(chalk.dim(` Update: ${result.updated}`));
291
+ }
292
+ if (result.skipped > 0) {
293
+ console.log(chalk.dim(` Skip: ${result.skipped}`));
294
+ }
295
+ console.log(chalk.dim(" Run without --dry-run to apply changes."));
296
+ }
297
+ else {
298
+ console.log(chalk.yellow("No records would be processed."));
299
+ }
156
300
  }
157
- if (result.skipped > 0) {
158
- console.log(chalk.yellow(`Skipped ${result.skipped} duplicate(s) in ${domain}`));
301
+ else {
302
+ if (result.created > 0) {
303
+ console.log(chalk.green(`✔ Created ${result.created} record(s) in ${domain}`));
304
+ }
305
+ if (result.updated > 0) {
306
+ console.log(chalk.green(`✔ Updated ${result.updated} record(s) in ${domain}`));
307
+ }
308
+ if (result.skipped > 0) {
309
+ console.log(chalk.yellow(`Skipped ${result.skipped} duplicate(s) in ${domain}`));
310
+ }
159
311
  }
160
312
  }
161
313
  if (result.errors.length > 0 && result.created + result.updated === 0) {
@@ -411,65 +563,103 @@ export function registerRecordCommand(program) {
411
563
  return;
412
564
  }
413
565
  const filePath = getExpertisePath(domain);
414
- await withFileLock(filePath, async () => {
566
+ const dryRun = options.dryRun === true;
567
+ if (dryRun) {
568
+ // Dry-run: check for duplicates without writing
415
569
  const existing = await readExpertiseFile(filePath);
416
570
  const dup = findDuplicate(existing, record);
571
+ let action = "created";
417
572
  if (dup && !options.force) {
418
573
  const isNamed = record.type === "pattern" || record.type === "decision" ||
419
574
  record.type === "reference" || record.type === "guide";
420
- if (isNamed) {
421
- // Upsert: replace in place
422
- existing[dup.index] = record;
423
- await writeExpertiseFile(filePath, existing);
424
- if (jsonMode) {
425
- outputJson({
426
- success: true,
427
- command: "record",
428
- action: "updated",
429
- domain,
430
- type: recordType,
431
- index: dup.index + 1,
432
- record,
433
- });
575
+ action = isNamed ? "updated" : "skipped";
576
+ }
577
+ if (jsonMode) {
578
+ outputJson({
579
+ success: true,
580
+ command: "record",
581
+ action: "dry-run",
582
+ wouldDo: action,
583
+ domain,
584
+ type: recordType,
585
+ record,
586
+ });
587
+ }
588
+ else {
589
+ if (action === "created") {
590
+ console.log(chalk.green(`✓ Dry-run: Would create ${recordType} in ${domain}`));
591
+ }
592
+ else if (action === "updated") {
593
+ console.log(chalk.green(`✓ Dry-run: Would update existing ${recordType} in ${domain}`));
594
+ }
595
+ else {
596
+ console.log(chalk.yellow(`Dry-run: Duplicate ${recordType} already exists in ${domain}. Would skip.`));
597
+ }
598
+ console.log(chalk.dim(" Run without --dry-run to apply changes."));
599
+ }
600
+ }
601
+ else {
602
+ // Normal mode: write with file locking
603
+ await withFileLock(filePath, async () => {
604
+ const existing = await readExpertiseFile(filePath);
605
+ const dup = findDuplicate(existing, record);
606
+ if (dup && !options.force) {
607
+ const isNamed = record.type === "pattern" || record.type === "decision" ||
608
+ record.type === "reference" || record.type === "guide";
609
+ if (isNamed) {
610
+ // Upsert: replace in place
611
+ existing[dup.index] = record;
612
+ await writeExpertiseFile(filePath, existing);
613
+ if (jsonMode) {
614
+ outputJson({
615
+ success: true,
616
+ command: "record",
617
+ action: "updated",
618
+ domain,
619
+ type: recordType,
620
+ index: dup.index + 1,
621
+ record,
622
+ });
623
+ }
624
+ else {
625
+ console.log(chalk.green(`\u2714 Updated existing ${recordType} in ${domain} (record #${dup.index + 1})`));
626
+ }
434
627
  }
435
628
  else {
436
- console.log(chalk.green(`\u2714 Updated existing ${recordType} in ${domain} (record #${dup.index + 1})`));
629
+ // Exact match: skip
630
+ if (jsonMode) {
631
+ outputJson({
632
+ success: true,
633
+ command: "record",
634
+ action: "skipped",
635
+ domain,
636
+ type: recordType,
637
+ index: dup.index + 1,
638
+ });
639
+ }
640
+ else {
641
+ console.log(chalk.yellow(`Duplicate ${recordType} already exists in ${domain} (record #${dup.index + 1}). Use --force to add anyway.`));
642
+ }
437
643
  }
438
644
  }
439
645
  else {
440
- // Exact match: skip
646
+ await appendRecord(filePath, record);
441
647
  if (jsonMode) {
442
648
  outputJson({
443
649
  success: true,
444
650
  command: "record",
445
- action: "skipped",
651
+ action: "created",
446
652
  domain,
447
653
  type: recordType,
448
- index: dup.index + 1,
654
+ record,
449
655
  });
450
656
  }
451
657
  else {
452
- console.log(chalk.yellow(`Duplicate ${recordType} already exists in ${domain} (record #${dup.index + 1}). Use --force to add anyway.`));
658
+ console.log(chalk.green(`\u2714 Recorded ${recordType} in ${domain}`));
453
659
  }
454
660
  }
455
- }
456
- else {
457
- await appendRecord(filePath, record);
458
- if (jsonMode) {
459
- outputJson({
460
- success: true,
461
- command: "record",
462
- action: "created",
463
- domain,
464
- type: recordType,
465
- record,
466
- });
467
- }
468
- else {
469
- console.log(chalk.green(`\u2714 Recorded ${recordType} in ${domain}`));
470
- }
471
- }
472
- });
661
+ });
662
+ }
473
663
  });
474
664
  }
475
665
  //# sourceMappingURL=record.js.map