@markjaquith/agency 1.5.2 → 1.6.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markjaquith/agency",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Manages personal agents files",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Mark Jaquith",
|
|
@@ -45,21 +45,21 @@
|
|
|
45
45
|
"personal-agents"
|
|
46
46
|
],
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/bun": "
|
|
49
|
-
"knip": "^5.
|
|
50
|
-
"prettier": "^3.
|
|
48
|
+
"@types/bun": "^1.3.6",
|
|
49
|
+
"knip": "^5.82.1",
|
|
50
|
+
"prettier": "^3.8.1"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"typescript": "^5"
|
|
53
|
+
"typescript": "^5.9.3"
|
|
54
54
|
},
|
|
55
55
|
"engines": {
|
|
56
56
|
"bun": ">=1.0.0"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@effect/schema": "^0.75.5",
|
|
60
|
-
"effect": "^3.19.
|
|
60
|
+
"effect": "^3.19.15",
|
|
61
61
|
"jsonc-parser": "^3.3.1",
|
|
62
|
-
"ora": "^8.
|
|
62
|
+
"ora": "^8.2.0"
|
|
63
63
|
},
|
|
64
64
|
"trustedDependencies": [
|
|
65
65
|
"@triggi/native-exec"
|
|
@@ -224,7 +224,7 @@ describe("emit command - integration tests (requires git-filter-repo)", () => {
|
|
|
224
224
|
// Create a new feature branch
|
|
225
225
|
await createBranch(tempDir, "agency/claude-test")
|
|
226
226
|
|
|
227
|
-
// Initialize agency on this branch (
|
|
227
|
+
// Initialize agency on this branch - first commit has agency files (NOT including CLAUDE.md)
|
|
228
228
|
await Bun.write(
|
|
229
229
|
join(tempDir, "agency.json"),
|
|
230
230
|
JSON.stringify({
|
|
@@ -235,22 +235,27 @@ describe("emit command - integration tests (requires git-filter-repo)", () => {
|
|
|
235
235
|
}),
|
|
236
236
|
)
|
|
237
237
|
await Bun.write(join(tempDir, "AGENTS.md"), "# Test AGENTS\n")
|
|
238
|
+
await addAndCommit(
|
|
239
|
+
tempDir,
|
|
240
|
+
"agency.json AGENTS.md",
|
|
241
|
+
"Initialize agency files",
|
|
242
|
+
)
|
|
238
243
|
|
|
239
|
-
// Simulate what agency task does -
|
|
244
|
+
// Simulate what agency task now does - CLAUDE.md modification in a separate commit
|
|
245
|
+
// with AGENCY_REMOVE_COMMIT marker so the commit gets dropped during emit
|
|
240
246
|
const originalClaude = await Bun.file(join(tempDir, "CLAUDE.md")).text()
|
|
241
247
|
const modifiedClaude = `${originalClaude}\n# Agency References\n@AGENTS.md\n@TASK.md\n`
|
|
242
248
|
await Bun.write(join(tempDir, "CLAUDE.md"), modifiedClaude)
|
|
243
|
-
|
|
244
249
|
await addAndCommit(
|
|
245
250
|
tempDir,
|
|
246
|
-
"
|
|
247
|
-
"
|
|
251
|
+
"CLAUDE.md",
|
|
252
|
+
"chore: agency edit CLAUDE.md\n\nAGENCY_REMOVE_COMMIT",
|
|
248
253
|
)
|
|
249
254
|
|
|
250
255
|
// Add a feature file
|
|
251
256
|
await createCommit(tempDir, "Feature commit")
|
|
252
257
|
|
|
253
|
-
// Create emit branch (this should
|
|
258
|
+
// Create emit branch (this should drop the CLAUDE.md modification commit)
|
|
254
259
|
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
255
260
|
|
|
256
261
|
// Should still be on source branch
|
|
@@ -274,4 +279,271 @@ describe("emit command - integration tests (requires git-filter-repo)", () => {
|
|
|
274
279
|
expect(claudeContent).not.toContain("@AGENTS.md")
|
|
275
280
|
expect(claudeContent).not.toContain("@TASK.md")
|
|
276
281
|
})
|
|
282
|
+
|
|
283
|
+
describe("AGENCY_REMOVE_COMMIT edge cases", () => {
|
|
284
|
+
test("handles two contiguous AGENCY_REMOVE_COMMIT commits", async () => {
|
|
285
|
+
if (!hasGitFilterRepo) {
|
|
286
|
+
console.log("Skipping test: git-filter-repo not installed")
|
|
287
|
+
return
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
await checkoutBranch(tempDir, "main")
|
|
291
|
+
|
|
292
|
+
// Create two files on main that will be modified
|
|
293
|
+
await Bun.write(join(tempDir, "FILE1.md"), "Original content 1\n")
|
|
294
|
+
await Bun.write(join(tempDir, "FILE2.md"), "Original content 2\n")
|
|
295
|
+
await addAndCommit(tempDir, "FILE1.md FILE2.md", "Add files")
|
|
296
|
+
|
|
297
|
+
await createBranch(tempDir, "agency/contiguous-test")
|
|
298
|
+
|
|
299
|
+
// Create agency.json
|
|
300
|
+
await Bun.write(
|
|
301
|
+
join(tempDir, "agency.json"),
|
|
302
|
+
JSON.stringify({
|
|
303
|
+
version: 1,
|
|
304
|
+
injectedFiles: [],
|
|
305
|
+
template: "test",
|
|
306
|
+
createdAt: new Date().toISOString(),
|
|
307
|
+
}),
|
|
308
|
+
)
|
|
309
|
+
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
310
|
+
|
|
311
|
+
// Two contiguous AGENCY_REMOVE_COMMIT commits
|
|
312
|
+
await Bun.write(join(tempDir, "FILE1.md"), "Modified content 1\n")
|
|
313
|
+
await addAndCommit(
|
|
314
|
+
tempDir,
|
|
315
|
+
"FILE1.md",
|
|
316
|
+
"chore: edit FILE1\n\nAGENCY_REMOVE_COMMIT",
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
await Bun.write(join(tempDir, "FILE2.md"), "Modified content 2\n")
|
|
320
|
+
await addAndCommit(
|
|
321
|
+
tempDir,
|
|
322
|
+
"FILE2.md",
|
|
323
|
+
"chore: edit FILE2\n\nAGENCY_REMOVE_COMMIT",
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
// Add a feature commit after
|
|
327
|
+
await createCommit(tempDir, "Feature commit")
|
|
328
|
+
|
|
329
|
+
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
330
|
+
await checkoutBranch(tempDir, "contiguous-test")
|
|
331
|
+
|
|
332
|
+
// Both files should be reverted to original
|
|
333
|
+
const file1 = await Bun.file(join(tempDir, "FILE1.md")).text()
|
|
334
|
+
const file2 = await Bun.file(join(tempDir, "FILE2.md")).text()
|
|
335
|
+
expect(file1).toBe("Original content 1\n")
|
|
336
|
+
expect(file2).toBe("Original content 2\n")
|
|
337
|
+
|
|
338
|
+
// Feature commit should still exist
|
|
339
|
+
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
340
|
+
expect(files).toContain("test.txt")
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
test("handles two non-contiguous AGENCY_REMOVE_COMMIT commits", async () => {
|
|
344
|
+
if (!hasGitFilterRepo) {
|
|
345
|
+
console.log("Skipping test: git-filter-repo not installed")
|
|
346
|
+
return
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
await checkoutBranch(tempDir, "main")
|
|
350
|
+
|
|
351
|
+
await Bun.write(join(tempDir, "FILE1.md"), "Original content 1\n")
|
|
352
|
+
await Bun.write(join(tempDir, "FILE2.md"), "Original content 2\n")
|
|
353
|
+
await addAndCommit(tempDir, "FILE1.md FILE2.md", "Add files")
|
|
354
|
+
|
|
355
|
+
await createBranch(tempDir, "agency/non-contiguous-test")
|
|
356
|
+
|
|
357
|
+
await Bun.write(
|
|
358
|
+
join(tempDir, "agency.json"),
|
|
359
|
+
JSON.stringify({
|
|
360
|
+
version: 1,
|
|
361
|
+
injectedFiles: [],
|
|
362
|
+
template: "test",
|
|
363
|
+
createdAt: new Date().toISOString(),
|
|
364
|
+
}),
|
|
365
|
+
)
|
|
366
|
+
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
367
|
+
|
|
368
|
+
// First AGENCY_REMOVE_COMMIT
|
|
369
|
+
await Bun.write(join(tempDir, "FILE1.md"), "Modified content 1\n")
|
|
370
|
+
await addAndCommit(
|
|
371
|
+
tempDir,
|
|
372
|
+
"FILE1.md",
|
|
373
|
+
"chore: edit FILE1\n\nAGENCY_REMOVE_COMMIT",
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
// Regular commit in between
|
|
377
|
+
await Bun.write(join(tempDir, "feature1.txt"), "feature 1\n")
|
|
378
|
+
await addAndCommit(tempDir, "feature1.txt", "Add feature 1")
|
|
379
|
+
|
|
380
|
+
// Second AGENCY_REMOVE_COMMIT
|
|
381
|
+
await Bun.write(join(tempDir, "FILE2.md"), "Modified content 2\n")
|
|
382
|
+
await addAndCommit(
|
|
383
|
+
tempDir,
|
|
384
|
+
"FILE2.md",
|
|
385
|
+
"chore: edit FILE2\n\nAGENCY_REMOVE_COMMIT",
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
// Another regular commit
|
|
389
|
+
await Bun.write(join(tempDir, "feature2.txt"), "feature 2\n")
|
|
390
|
+
await addAndCommit(tempDir, "feature2.txt", "Add feature 2")
|
|
391
|
+
|
|
392
|
+
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
393
|
+
await checkoutBranch(tempDir, "non-contiguous-test")
|
|
394
|
+
|
|
395
|
+
// Both files should be reverted to original
|
|
396
|
+
const file1 = await Bun.file(join(tempDir, "FILE1.md")).text()
|
|
397
|
+
const file2 = await Bun.file(join(tempDir, "FILE2.md")).text()
|
|
398
|
+
expect(file1).toBe("Original content 1\n")
|
|
399
|
+
expect(file2).toBe("Original content 2\n")
|
|
400
|
+
|
|
401
|
+
// Feature commits should still exist
|
|
402
|
+
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
403
|
+
expect(files).toContain("feature1.txt")
|
|
404
|
+
expect(files).toContain("feature2.txt")
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
test("handles AGENCY_REMOVE_COMMIT as first commit after fork point", async () => {
|
|
408
|
+
if (!hasGitFilterRepo) {
|
|
409
|
+
console.log("Skipping test: git-filter-repo not installed")
|
|
410
|
+
return
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
await checkoutBranch(tempDir, "main")
|
|
414
|
+
|
|
415
|
+
await Bun.write(join(tempDir, "EXISTING.md"), "Original content\n")
|
|
416
|
+
await addAndCommit(tempDir, "EXISTING.md", "Add existing file")
|
|
417
|
+
|
|
418
|
+
await createBranch(tempDir, "agency/first-commit-test")
|
|
419
|
+
|
|
420
|
+
// First commit is AGENCY_REMOVE_COMMIT (modifying existing file)
|
|
421
|
+
await Bun.write(join(tempDir, "EXISTING.md"), "Modified content\n")
|
|
422
|
+
await addAndCommit(
|
|
423
|
+
tempDir,
|
|
424
|
+
"EXISTING.md",
|
|
425
|
+
"chore: edit EXISTING\n\nAGENCY_REMOVE_COMMIT",
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
// Then agency.json
|
|
429
|
+
await Bun.write(
|
|
430
|
+
join(tempDir, "agency.json"),
|
|
431
|
+
JSON.stringify({
|
|
432
|
+
version: 1,
|
|
433
|
+
injectedFiles: [],
|
|
434
|
+
template: "test",
|
|
435
|
+
createdAt: new Date().toISOString(),
|
|
436
|
+
}),
|
|
437
|
+
)
|
|
438
|
+
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
439
|
+
|
|
440
|
+
// Feature commit
|
|
441
|
+
await createCommit(tempDir, "Feature commit")
|
|
442
|
+
|
|
443
|
+
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
444
|
+
await checkoutBranch(tempDir, "first-commit-test")
|
|
445
|
+
|
|
446
|
+
// File should be reverted to original
|
|
447
|
+
const content = await Bun.file(join(tempDir, "EXISTING.md")).text()
|
|
448
|
+
expect(content).toBe("Original content\n")
|
|
449
|
+
|
|
450
|
+
// Feature commit should exist
|
|
451
|
+
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
452
|
+
expect(files).toContain("test.txt")
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
test("handles AGENCY_REMOVE_COMMIT as last commit", async () => {
|
|
456
|
+
if (!hasGitFilterRepo) {
|
|
457
|
+
console.log("Skipping test: git-filter-repo not installed")
|
|
458
|
+
return
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
await checkoutBranch(tempDir, "main")
|
|
462
|
+
|
|
463
|
+
await Bun.write(join(tempDir, "EXISTING.md"), "Original content\n")
|
|
464
|
+
await addAndCommit(tempDir, "EXISTING.md", "Add existing file")
|
|
465
|
+
|
|
466
|
+
await createBranch(tempDir, "agency/last-commit-test")
|
|
467
|
+
|
|
468
|
+
// agency.json first
|
|
469
|
+
await Bun.write(
|
|
470
|
+
join(tempDir, "agency.json"),
|
|
471
|
+
JSON.stringify({
|
|
472
|
+
version: 1,
|
|
473
|
+
injectedFiles: [],
|
|
474
|
+
template: "test",
|
|
475
|
+
createdAt: new Date().toISOString(),
|
|
476
|
+
}),
|
|
477
|
+
)
|
|
478
|
+
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
479
|
+
|
|
480
|
+
// Feature commit
|
|
481
|
+
await Bun.write(join(tempDir, "feature.txt"), "feature\n")
|
|
482
|
+
await addAndCommit(tempDir, "feature.txt", "Add feature")
|
|
483
|
+
|
|
484
|
+
// Last commit is AGENCY_REMOVE_COMMIT
|
|
485
|
+
await Bun.write(join(tempDir, "EXISTING.md"), "Modified content\n")
|
|
486
|
+
await addAndCommit(
|
|
487
|
+
tempDir,
|
|
488
|
+
"EXISTING.md",
|
|
489
|
+
"chore: edit EXISTING\n\nAGENCY_REMOVE_COMMIT",
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
493
|
+
await checkoutBranch(tempDir, "last-commit-test")
|
|
494
|
+
|
|
495
|
+
// File should be reverted to original
|
|
496
|
+
const content = await Bun.file(join(tempDir, "EXISTING.md")).text()
|
|
497
|
+
expect(content).toBe("Original content\n")
|
|
498
|
+
|
|
499
|
+
// Feature commit should exist
|
|
500
|
+
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
501
|
+
expect(files).toContain("feature.txt")
|
|
502
|
+
})
|
|
503
|
+
|
|
504
|
+
test("handles AGENCY_REMOVE_COMMIT as only commit (besides agency.json)", async () => {
|
|
505
|
+
if (!hasGitFilterRepo) {
|
|
506
|
+
console.log("Skipping test: git-filter-repo not installed")
|
|
507
|
+
return
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
await checkoutBranch(tempDir, "main")
|
|
511
|
+
|
|
512
|
+
await Bun.write(join(tempDir, "EXISTING.md"), "Original content\n")
|
|
513
|
+
await addAndCommit(tempDir, "EXISTING.md", "Add existing file")
|
|
514
|
+
|
|
515
|
+
await createBranch(tempDir, "agency/only-commit-test")
|
|
516
|
+
|
|
517
|
+
// agency.json
|
|
518
|
+
await Bun.write(
|
|
519
|
+
join(tempDir, "agency.json"),
|
|
520
|
+
JSON.stringify({
|
|
521
|
+
version: 1,
|
|
522
|
+
injectedFiles: [],
|
|
523
|
+
template: "test",
|
|
524
|
+
createdAt: new Date().toISOString(),
|
|
525
|
+
}),
|
|
526
|
+
)
|
|
527
|
+
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
528
|
+
|
|
529
|
+
// Only other commit is AGENCY_REMOVE_COMMIT
|
|
530
|
+
await Bun.write(join(tempDir, "EXISTING.md"), "Modified content\n")
|
|
531
|
+
await addAndCommit(
|
|
532
|
+
tempDir,
|
|
533
|
+
"EXISTING.md",
|
|
534
|
+
"chore: edit EXISTING\n\nAGENCY_REMOVE_COMMIT",
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
538
|
+
await checkoutBranch(tempDir, "only-commit-test")
|
|
539
|
+
|
|
540
|
+
// File should be reverted to original
|
|
541
|
+
const content = await Bun.file(join(tempDir, "EXISTING.md")).text()
|
|
542
|
+
expect(content).toBe("Original content\n")
|
|
543
|
+
|
|
544
|
+
// Emit branch should exist and have the file
|
|
545
|
+
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
546
|
+
expect(files).toContain("EXISTING.md")
|
|
547
|
+
})
|
|
548
|
+
})
|
|
277
549
|
})
|
|
@@ -305,12 +305,13 @@ describe("emit command", () => {
|
|
|
305
305
|
const lastCall = getLastCapturedFilterRepoCall()
|
|
306
306
|
expect(lastCall).toBeDefined()
|
|
307
307
|
|
|
308
|
-
// Should include paths for base files (TASK.md, AGENCY.md,
|
|
308
|
+
// Should include paths for base files (TASK.md, AGENCY.md, agency.json)
|
|
309
|
+
// Note: CLAUDE.md is NOT in base files - it's only filtered if it was created
|
|
310
|
+
// by agency (in which case it would be in injectedFiles)
|
|
309
311
|
// and injected files (AGENTS.md)
|
|
310
312
|
expect(lastCall!.args).toContain("--path")
|
|
311
313
|
expect(lastCall!.args).toContain("TASK.md")
|
|
312
314
|
expect(lastCall!.args).toContain("AGENCY.md")
|
|
313
|
-
expect(lastCall!.args).toContain("CLAUDE.md")
|
|
314
315
|
expect(lastCall!.args).toContain("agency.json")
|
|
315
316
|
expect(lastCall!.args).toContain("AGENTS.md")
|
|
316
317
|
|
|
@@ -336,12 +337,12 @@ describe("emit command", () => {
|
|
|
336
337
|
// Create CLAUDE.md as a symlink to AGENTS.md
|
|
337
338
|
await symlink("AGENTS.md", join(tempDir, "CLAUDE.md"))
|
|
338
339
|
|
|
339
|
-
// Create agency.json
|
|
340
|
+
// Create agency.json with CLAUDE.md in injectedFiles (since it's no longer in baseFiles)
|
|
340
341
|
await Bun.write(
|
|
341
342
|
join(tempDir, "agency.json"),
|
|
342
343
|
JSON.stringify({
|
|
343
344
|
version: 1,
|
|
344
|
-
injectedFiles: [],
|
|
345
|
+
injectedFiles: ["CLAUDE.md"],
|
|
345
346
|
template: "test",
|
|
346
347
|
createdAt: new Date().toISOString(),
|
|
347
348
|
}),
|
package/src/commands/emit.ts
CHANGED
|
@@ -197,10 +197,17 @@ const emitCore = (gitRoot: string, options: EmitOptions) =>
|
|
|
197
197
|
})
|
|
198
198
|
verboseLog(`Files to filter: ${filesToFilter.join(", ")}`)
|
|
199
199
|
|
|
200
|
-
// Run git-filter-repo
|
|
200
|
+
// Run git-filter-repo with:
|
|
201
|
+
// 1. Path filtering to remove backpack files
|
|
202
|
+
// 2. Commit callback to drop file changes from commits marked with AGENCY_REMOVE_COMMIT
|
|
203
|
+
// (clearing file_changes makes the commit empty and it gets pruned, while preserving tree state)
|
|
201
204
|
const filterRepoArgs = [
|
|
202
205
|
...filesToFilter.flatMap((f) => ["--path", f]),
|
|
203
206
|
"--invert-paths",
|
|
207
|
+
"--commit-callback",
|
|
208
|
+
// Clear file changes from commits with AGENCY_REMOVE_COMMIT marker
|
|
209
|
+
// This makes the commit empty (which gets pruned) while preserving the tree state
|
|
210
|
+
`if b"AGENCY_REMOVE_COMMIT" in commit.message: commit.file_changes = []`,
|
|
204
211
|
"--force",
|
|
205
212
|
"--refs",
|
|
206
213
|
`${forkPoint}..${emitBranchName}`,
|
package/src/commands/task.ts
CHANGED
|
@@ -731,12 +731,18 @@ export const task = (options: TaskOptions = {}) =>
|
|
|
731
731
|
}
|
|
732
732
|
|
|
733
733
|
// Handle CLAUDE.md injection
|
|
734
|
+
// If CLAUDE.md is created (new file), include it in main commit and add to injectedFiles
|
|
735
|
+
// If CLAUDE.md is modified (existing file), commit separately with AGENCY_REMOVE_COMMIT marker
|
|
736
|
+
// so it can be completely removed during emission
|
|
734
737
|
const claudeResult = yield* claudeService.injectAgencySection(targetPath)
|
|
738
|
+
let claudeModifiedExisting = false
|
|
735
739
|
if (claudeResult.created) {
|
|
736
740
|
createdFiles.push("CLAUDE.md")
|
|
741
|
+
injectedFiles.push("CLAUDE.md")
|
|
737
742
|
log(done(`Created ${highlight.file("CLAUDE.md")}`))
|
|
738
743
|
} else if (claudeResult.modified) {
|
|
739
|
-
|
|
744
|
+
// Mark that we need a separate commit for CLAUDE.md modification
|
|
745
|
+
claudeModifiedExisting = true
|
|
740
746
|
log(done(`Updated ${highlight.file("CLAUDE.md")}`))
|
|
741
747
|
}
|
|
742
748
|
|
|
@@ -814,6 +820,27 @@ export const task = (options: TaskOptions = {}) =>
|
|
|
814
820
|
}),
|
|
815
821
|
)
|
|
816
822
|
}
|
|
823
|
+
|
|
824
|
+
// Create separate commit for CLAUDE.md modification with AGENCY_REMOVE_COMMIT marker
|
|
825
|
+
// This commit will be completely removed during emission
|
|
826
|
+
if (claudeModifiedExisting) {
|
|
827
|
+
yield* Effect.gen(function* () {
|
|
828
|
+
yield* git.gitAdd(["CLAUDE.md"], targetPath)
|
|
829
|
+
// The AGENCY_REMOVE_COMMIT marker in the commit body tells emit to drop this commit entirely
|
|
830
|
+
const commitMessage = `chore: agency edit CLAUDE.md\n\nAGENCY_REMOVE_COMMIT`
|
|
831
|
+
yield* git.gitCommit(commitMessage, targetPath, {
|
|
832
|
+
noVerify: true,
|
|
833
|
+
})
|
|
834
|
+
verboseLog(
|
|
835
|
+
"Created CLAUDE.md modification commit (will be removed on emit)",
|
|
836
|
+
)
|
|
837
|
+
}).pipe(
|
|
838
|
+
Effect.catchAll((err) => {
|
|
839
|
+
verboseLog(`Failed to commit CLAUDE.md modification: ${err}`)
|
|
840
|
+
return Effect.void
|
|
841
|
+
}),
|
|
842
|
+
)
|
|
843
|
+
}
|
|
817
844
|
})
|
|
818
845
|
|
|
819
846
|
// Helper: Create feature branch with interactive prompts
|
|
@@ -49,7 +49,7 @@ export class AgencyMetadataService extends Context.Tag("AgencyMetadataService")<
|
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Get list of files to filter during PR/merge operations.
|
|
52
|
-
* Always includes TASK.md, AGENCY.md,
|
|
52
|
+
* Always includes TASK.md, AGENCY.md, and agency.json, plus any injectedFiles from metadata.
|
|
53
53
|
*/
|
|
54
54
|
readonly getFilesToFilter: (
|
|
55
55
|
gitRoot: string,
|
|
@@ -204,7 +204,7 @@ export const AgencyMetadataServiceLive = Layer.succeed(
|
|
|
204
204
|
const metadataPath = join(gitRoot, "agency.json")
|
|
205
205
|
|
|
206
206
|
const exists = yield* fs.exists(metadataPath)
|
|
207
|
-
const baseFiles = ["TASK.md", "AGENCY.md", "
|
|
207
|
+
const baseFiles = ["TASK.md", "AGENCY.md", "agency.json"]
|
|
208
208
|
|
|
209
209
|
if (!exists) {
|
|
210
210
|
// Resolve symlinks even for base files
|
|
@@ -236,7 +236,7 @@ export const AgencyMetadataServiceLive = Layer.succeed(
|
|
|
236
236
|
return yield* resolveSymlinkTargets(fs, gitRoot, expandedFiles)
|
|
237
237
|
}).pipe(
|
|
238
238
|
Effect.catchAll(() =>
|
|
239
|
-
Effect.succeed(["TASK.md", "AGENCY.md", "
|
|
239
|
+
Effect.succeed(["TASK.md", "AGENCY.md", "agency.json"]),
|
|
240
240
|
),
|
|
241
241
|
),
|
|
242
242
|
|
package/src/utils/process.ts
CHANGED
|
@@ -23,7 +23,7 @@ interface SpawnOptions {
|
|
|
23
23
|
/**
|
|
24
24
|
* Generic error for process execution failures
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
class ProcessError extends Data.TaggedError("ProcessError")<{
|
|
27
27
|
command: string
|
|
28
28
|
exitCode: number
|
|
29
29
|
stderr: string
|