@cleocode/adapters 2026.10.4 → 2026.10.5-rc.ci.672

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.
Files changed (37) hide show
  1. package/dist/index.js +1608 -1380
  2. package/dist/index.js.map +3 -3
  3. package/dist/providers/claude-code/adapter.d.ts.map +1 -1
  4. package/dist/providers/claude-code/hooks.d.ts +43 -17
  5. package/dist/providers/claude-code/hooks.d.ts.map +1 -1
  6. package/dist/providers/claude-code/install.d.ts +42 -14
  7. package/dist/providers/claude-code/install.d.ts.map +1 -1
  8. package/dist/providers/claude-code/paths.d.ts +77 -0
  9. package/dist/providers/claude-code/paths.d.ts.map +1 -1
  10. package/dist/providers/codex/install.d.ts.map +1 -1
  11. package/dist/providers/cursor/install.d.ts.map +1 -1
  12. package/dist/providers/gemini-cli/install.d.ts.map +1 -1
  13. package/dist/providers/kimi/install.d.ts.map +1 -1
  14. package/dist/providers/openai-sdk/install.d.ts.map +1 -1
  15. package/dist/providers/opencode/install.d.ts.map +1 -1
  16. package/dist/providers/pi/install.d.ts.map +1 -1
  17. package/dist/providers/shared/heavy-command-hook-install.d.ts.map +1 -1
  18. package/dist/providers/shared/project-instruction-file.d.ts +30 -0
  19. package/dist/providers/shared/project-instruction-file.d.ts.map +1 -0
  20. package/package.json +5 -5
  21. package/src/__tests__/claude-code-adapter.test.ts +11 -6
  22. package/src/providers/claude-code/__tests__/hooks-install.test.ts +20 -17
  23. package/src/providers/claude-code/__tests__/no-user-global-write.test.ts +293 -0
  24. package/src/providers/claude-code/adapter.ts +3 -1
  25. package/src/providers/claude-code/hooks.ts +138 -51
  26. package/src/providers/claude-code/install.ts +123 -52
  27. package/src/providers/claude-code/paths.ts +159 -1
  28. package/src/providers/codex/install.ts +4 -2
  29. package/src/providers/cursor/install.ts +26 -12
  30. package/src/providers/gemini-cli/install.ts +4 -2
  31. package/src/providers/kimi/install.ts +4 -2
  32. package/src/providers/openai-sdk/install.ts +5 -2
  33. package/src/providers/opencode/install.ts +4 -2
  34. package/src/providers/pi/install.ts +4 -2
  35. package/src/providers/shared/__tests__/heavy-command-hook-install.test.ts +20 -0
  36. package/src/providers/shared/heavy-command-hook-install.ts +6 -1
  37. package/src/providers/shared/project-instruction-file.ts +47 -0
package/dist/index.js CHANGED
@@ -1617,154 +1617,11 @@ var init_identity = __esm({
1617
1617
  }
1618
1618
  });
1619
1619
 
1620
- // packages/contracts/src/docs-taxonomy.ts
1621
- var BUILTIN_DOC_KINDS, BUILTIN_DOC_KIND_VALUES;
1622
- var init_docs_taxonomy = __esm({
1623
- "packages/contracts/src/docs-taxonomy.ts"() {
1620
+ // packages/contracts/src/operations/docs-lifecycle.ts
1621
+ var DOCS_LIFECYCLE_STATUSES;
1622
+ var init_docs_lifecycle = __esm({
1623
+ "packages/contracts/src/operations/docs-lifecycle.ts"() {
1624
1624
  "use strict";
1625
- BUILTIN_DOC_KINDS = [
1626
- {
1627
- kind: "adr",
1628
- label: "ADR",
1629
- description: "Architectural decision record",
1630
- defaultOwnerKind: "task",
1631
- publishDir: "docs/adr",
1632
- requiresEntityId: true,
1633
- entityIdPattern: /^adr-\d{3,4}-[a-z0-9-]+$/,
1634
- requiredSections: ["Status", "Date", "Context", "Decision", "Consequences"]
1635
- },
1636
- {
1637
- kind: "spec",
1638
- label: "Spec",
1639
- description: "Technical specification",
1640
- defaultOwnerKind: "task",
1641
- publishDir: "docs/spec",
1642
- requiresEntityId: false,
1643
- requiredSections: ["Goal", "Non-Goals", "Requirements", "Out-of-Scope"]
1644
- },
1645
- {
1646
- kind: "research",
1647
- label: "Research",
1648
- description: "Investigation / research note",
1649
- defaultOwnerKind: "task",
1650
- publishDir: "docs/research",
1651
- requiresEntityId: false,
1652
- requiredSections: ["Question", "Findings", "Sources"]
1653
- },
1654
- {
1655
- kind: "handoff",
1656
- label: "Handoff",
1657
- description: "Session / agent handoff",
1658
- defaultOwnerKind: "session",
1659
- publishDir: "docs/handoff",
1660
- requiresEntityId: false,
1661
- requiredSections: ["Context", "State", "Next-Steps"]
1662
- },
1663
- {
1664
- kind: "note",
1665
- label: "Note",
1666
- description: "Agent observation / informal note",
1667
- defaultOwnerKind: "observation",
1668
- publishDir: "docs/note",
1669
- requiresEntityId: false,
1670
- requiredSections: []
1671
- },
1672
- {
1673
- kind: "llm-readme",
1674
- label: "LLM README",
1675
- description: "Machine-readable README (llms.txt)",
1676
- defaultOwnerKind: "project",
1677
- publishDir: ".",
1678
- requiresEntityId: false,
1679
- requiredSections: []
1680
- },
1681
- {
1682
- kind: "changeset",
1683
- label: "Changeset",
1684
- description: "Atomic change entry (release-note input)",
1685
- defaultOwnerKind: "task",
1686
- publishDir: ".changeset",
1687
- requiresEntityId: true,
1688
- entityIdPattern: /^t\d+-[a-z0-9-]+$/,
1689
- requiredSections: []
1690
- },
1691
- {
1692
- kind: "release-note",
1693
- label: "Release Note",
1694
- description: "Composed release notes",
1695
- defaultOwnerKind: "project",
1696
- publishDir: "docs/release",
1697
- requiresEntityId: true,
1698
- entityIdPattern: /^v\d{4}\.\d+\.\d+(-[a-z0-9-]+)?$/,
1699
- requiredSections: ["Changes", "Migration"]
1700
- },
1701
- {
1702
- kind: "plan",
1703
- label: "Plan",
1704
- description: "Epic / saga decomposition plan",
1705
- defaultOwnerKind: "task",
1706
- publishDir: "docs/plan",
1707
- requiresEntityId: false,
1708
- requiredSections: ["Goal", "Steps", "Owners"]
1709
- },
1710
- {
1711
- kind: "rcasd",
1712
- label: "RCASD",
1713
- description: "Root-cause analysis + scoped delivery",
1714
- defaultOwnerKind: "task",
1715
- publishDir: ".cleo/rcasd",
1716
- requiresEntityId: true,
1717
- entityIdPattern: /^t\d+(-.+)?$/,
1718
- requiredSections: ["Root-Cause", "Action", "Schedule", "Detection"]
1719
- }
1720
- ];
1721
- BUILTIN_DOC_KIND_VALUES = Object.freeze(
1722
- BUILTIN_DOC_KINDS.map((d) => d.kind)
1723
- );
1724
- }
1725
- });
1726
-
1727
- // packages/contracts/src/operations/docs.ts
1728
- import { z as z7 } from "zod";
1729
- var DOCS_PROJECTION_PROPOSAL_SCHEMA, DOCS_PROJECTION_RECEIPT_SCHEMA, DOCS_LIFECYCLE_STATUSES;
1730
- var init_docs = __esm({
1731
- "packages/contracts/src/operations/docs.ts"() {
1732
- "use strict";
1733
- init_docs_taxonomy();
1734
- DOCS_PROJECTION_PROPOSAL_SCHEMA = z7.object({
1735
- version: z7.literal(1),
1736
- operation: z7.literal("docs.projection"),
1737
- identity: z7.object({
1738
- projectId: z7.string().min(1),
1739
- projectRoot: z7.string().min(1),
1740
- actor: z7.string().min(1),
1741
- operation: z7.literal("docs.projection"),
1742
- idempotencyKey: z7.string().min(1)
1743
- }).strict(),
1744
- source: z7.object({
1745
- attachmentId: z7.string().min(1),
1746
- sha256: z7.string().regex(/^[a-f0-9]{64}$/),
1747
- ownerId: z7.string().min(1),
1748
- ownerType: z7.enum(["task", "session", "observation", "decision", "learning", "pattern"]),
1749
- label: z7.string().min(1)
1750
- }).strict(),
1751
- observation: z7.object({
1752
- kind: z7.literal("doc-attachment"),
1753
- attachmentId: z7.string().min(1),
1754
- ownerId: z7.string().min(1),
1755
- addedAt: z7.string().min(1),
1756
- slug: z7.string().optional(),
1757
- type: z7.string().optional()
1758
- }).strict()
1759
- }).strict();
1760
- DOCS_PROJECTION_RECEIPT_SCHEMA = z7.object({
1761
- version: z7.literal(1),
1762
- sourceHash: z7.string().regex(/^[a-f0-9]{64}$/),
1763
- graph: z7.enum(["completed", "disabled"]),
1764
- observationId: z7.string().min(1),
1765
- verifiedAt: z7.string().min(1),
1766
- actor: z7.string().min(1)
1767
- }).strict();
1768
1625
  DOCS_LIFECYCLE_STATUSES = [
1769
1626
  "draft",
1770
1627
  "proposed",
@@ -2914,7 +2771,7 @@ var requirementTaskParam, OPERATIONS;
2914
2771
  var init_operations_registry = __esm({
2915
2772
  "packages/contracts/src/dispatch/operations-registry.ts"() {
2916
2773
  "use strict";
2917
- init_docs();
2774
+ init_docs_lifecycle();
2918
2775
  init_output_contracts_data();
2919
2776
  init_tasks();
2920
2777
  requirementTaskParam = {
@@ -13382,7 +13239,7 @@ var init_operations_registry = __esm({
13382
13239
  });
13383
13240
 
13384
13241
  // packages/contracts/src/docs/provenance.ts
13385
- import { z as z8 } from "zod";
13242
+ import { z as z7 } from "zod";
13386
13243
  var PROVENANCE_NODE_KINDS, PROVENANCE_EDGE_RELATIONS, DOC_LIFECYCLE_STATUSES, provenanceNodeKindSchema, provenanceEdgeRelationSchema, docLifecycleStatusSchema, provenanceNodeBaseFields, provenanceDocNodeSchema, provenanceTaskNodeSchema, provenanceDecisionNodeSchema, provenanceSessionNodeSchema, provenanceMemoryNodeSchema, provenanceNodeSchema, provenanceEdgeSchema, docProvenanceResponseSchema;
13387
13244
  var init_provenance = __esm({
13388
13245
  "packages/contracts/src/docs/provenance.ts"() {
@@ -13409,108 +13266,215 @@ var init_provenance = __esm({
13409
13266
  "archived",
13410
13267
  "draft"
13411
13268
  ];
13412
- provenanceNodeKindSchema = z8.enum(PROVENANCE_NODE_KINDS);
13413
- provenanceEdgeRelationSchema = z8.enum(PROVENANCE_EDGE_RELATIONS);
13414
- docLifecycleStatusSchema = z8.enum(DOC_LIFECYCLE_STATUSES);
13269
+ provenanceNodeKindSchema = z7.enum(PROVENANCE_NODE_KINDS);
13270
+ provenanceEdgeRelationSchema = z7.enum(PROVENANCE_EDGE_RELATIONS);
13271
+ docLifecycleStatusSchema = z7.enum(DOC_LIFECYCLE_STATUSES);
13415
13272
  provenanceNodeBaseFields = {
13416
- id: z8.string().min(1),
13417
- title: z8.string().min(1),
13418
- metadata: z8.record(z8.string(), z8.unknown()).optional()
13273
+ id: z7.string().min(1),
13274
+ title: z7.string().min(1),
13275
+ metadata: z7.record(z7.string(), z7.unknown()).optional()
13419
13276
  };
13420
- provenanceDocNodeSchema = z8.object({
13277
+ provenanceDocNodeSchema = z7.object({
13421
13278
  ...provenanceNodeBaseFields,
13422
- kind: z8.literal("doc"),
13423
- slug: z8.string().min(1),
13424
- docKind: z8.string().min(1),
13279
+ kind: z7.literal("doc"),
13280
+ slug: z7.string().min(1),
13281
+ docKind: z7.string().min(1),
13425
13282
  lifecycleStatus: docLifecycleStatusSchema,
13426
- publishedAt: z8.string().min(1),
13427
- supersededAt: z8.string().min(1).optional(),
13428
- summary: z8.string().optional()
13283
+ publishedAt: z7.string().min(1),
13284
+ supersededAt: z7.string().min(1).optional(),
13285
+ summary: z7.string().optional()
13429
13286
  });
13430
- provenanceTaskNodeSchema = z8.object({
13287
+ provenanceTaskNodeSchema = z7.object({
13431
13288
  ...provenanceNodeBaseFields,
13432
- kind: z8.literal("task"),
13433
- taskType: z8.enum(["saga", "epic", "task", "subtask"]),
13434
- status: z8.enum(["pending", "in_progress", "done", "blocked", "cancelled", "archived"])
13289
+ kind: z7.literal("task"),
13290
+ taskType: z7.enum(["saga", "epic", "task", "subtask"]),
13291
+ status: z7.enum(["pending", "in_progress", "done", "blocked", "cancelled", "archived"])
13435
13292
  });
13436
- provenanceDecisionNodeSchema = z8.object({
13293
+ provenanceDecisionNodeSchema = z7.object({
13437
13294
  ...provenanceNodeBaseFields,
13438
- kind: z8.literal("decision"),
13439
- outcome: z8.enum(["proposed", "accepted", "rejected", "superseded"]),
13440
- decidedAt: z8.string().min(1)
13295
+ kind: z7.literal("decision"),
13296
+ outcome: z7.enum(["proposed", "accepted", "rejected", "superseded"]),
13297
+ decidedAt: z7.string().min(1)
13441
13298
  });
13442
- provenanceSessionNodeSchema = z8.object({
13299
+ provenanceSessionNodeSchema = z7.object({
13443
13300
  ...provenanceNodeBaseFields,
13444
- kind: z8.literal("session"),
13445
- startedAt: z8.string().min(1),
13446
- endedAt: z8.string().min(1).optional()
13301
+ kind: z7.literal("session"),
13302
+ startedAt: z7.string().min(1),
13303
+ endedAt: z7.string().min(1).optional()
13447
13304
  });
13448
- provenanceMemoryNodeSchema = z8.object({
13305
+ provenanceMemoryNodeSchema = z7.object({
13449
13306
  ...provenanceNodeBaseFields,
13450
- kind: z8.literal("memory"),
13451
- memoryType: z8.enum(["observation", "pattern", "decision", "diary"]),
13452
- recordedAt: z8.string().min(1)
13307
+ kind: z7.literal("memory"),
13308
+ memoryType: z7.enum(["observation", "pattern", "decision", "diary"]),
13309
+ recordedAt: z7.string().min(1)
13453
13310
  });
13454
- provenanceNodeSchema = z8.discriminatedUnion("kind", [
13311
+ provenanceNodeSchema = z7.discriminatedUnion("kind", [
13455
13312
  provenanceDocNodeSchema,
13456
13313
  provenanceTaskNodeSchema,
13457
13314
  provenanceDecisionNodeSchema,
13458
13315
  provenanceSessionNodeSchema,
13459
13316
  provenanceMemoryNodeSchema
13460
13317
  ]);
13461
- provenanceEdgeSchema = z8.object({
13318
+ provenanceEdgeSchema = z7.object({
13462
13319
  relation: provenanceEdgeRelationSchema,
13463
- from: z8.string().min(1),
13320
+ from: z7.string().min(1),
13464
13321
  fromKind: provenanceNodeKindSchema,
13465
- to: z8.string().min(1),
13322
+ to: z7.string().min(1),
13466
13323
  toKind: provenanceNodeKindSchema,
13467
- addedAt: z8.string().min(1),
13468
- summary: z8.string().optional()
13324
+ addedAt: z7.string().min(1),
13325
+ summary: z7.string().optional()
13469
13326
  });
13470
- docProvenanceResponseSchema = z8.object({
13471
- nodes: z8.array(provenanceNodeSchema).readonly(),
13472
- edges: z8.array(provenanceEdgeSchema).readonly(),
13473
- totalNodes: z8.number().int().nonnegative(),
13474
- totalEdges: z8.number().int().nonnegative()
13327
+ docProvenanceResponseSchema = z7.object({
13328
+ nodes: z7.array(provenanceNodeSchema).readonly(),
13329
+ edges: z7.array(provenanceEdgeSchema).readonly(),
13330
+ totalNodes: z7.number().int().nonnegative(),
13331
+ totalEdges: z7.number().int().nonnegative()
13475
13332
  });
13476
13333
  }
13477
13334
  });
13478
13335
 
13479
13336
  // packages/contracts/src/docs/read.ts
13480
- import { z as z9 } from "zod";
13337
+ import { z as z8 } from "zod";
13481
13338
  var docFrontmatterSchema, docBodySchema, docReadResponseSchema;
13482
13339
  var init_read = __esm({
13483
13340
  "packages/contracts/src/docs/read.ts"() {
13484
13341
  "use strict";
13485
- docFrontmatterSchema = z9.object({
13486
- slug: z9.string(),
13487
- kind: z9.string().nullable(),
13488
- title: z9.string().nullable(),
13489
- summary: z9.string().nullable(),
13490
- lifecycleStatus: z9.string(),
13491
- docVersion: z9.number().int(),
13492
- ownerVersion: z9.string().nullable(),
13493
- supersedes: z9.string().nullable(),
13494
- supersededBy: z9.string().nullable(),
13495
- topics: z9.array(z9.string()).readonly(),
13496
- relatedTasks: z9.array(z9.string()).readonly(),
13497
- sha256: z9.string(),
13498
- createdAt: z9.string()
13499
- });
13500
- docBodySchema = z9.object({
13501
- encoding: z9.enum(["utf-8", "base64"]),
13502
- text: z9.string().optional(),
13503
- base64: z9.string().optional(),
13504
- sizeBytes: z9.number().int().nonnegative(),
13505
- mimeType: z9.string().nullable()
13506
- });
13507
- docReadResponseSchema = z9.object({
13342
+ docFrontmatterSchema = z8.object({
13343
+ slug: z8.string(),
13344
+ kind: z8.string().nullable(),
13345
+ title: z8.string().nullable(),
13346
+ summary: z8.string().nullable(),
13347
+ lifecycleStatus: z8.string(),
13348
+ docVersion: z8.number().int(),
13349
+ ownerVersion: z8.string().nullable(),
13350
+ supersedes: z8.string().nullable(),
13351
+ supersededBy: z8.string().nullable(),
13352
+ topics: z8.array(z8.string()).readonly(),
13353
+ relatedTasks: z8.array(z8.string()).readonly(),
13354
+ sha256: z8.string(),
13355
+ createdAt: z8.string()
13356
+ });
13357
+ docBodySchema = z8.object({
13358
+ encoding: z8.enum(["utf-8", "base64"]),
13359
+ text: z8.string().optional(),
13360
+ base64: z8.string().optional(),
13361
+ sizeBytes: z8.number().int().nonnegative(),
13362
+ mimeType: z8.string().nullable()
13363
+ });
13364
+ docReadResponseSchema = z8.object({
13508
13365
  frontmatter: docFrontmatterSchema,
13509
13366
  body: docBodySchema
13510
13367
  });
13511
13368
  }
13512
13369
  });
13513
13370
 
13371
+ // packages/contracts/src/docs-taxonomy.ts
13372
+ var BUILTIN_DOC_KINDS, BUILTIN_DOC_KIND_VALUES;
13373
+ var init_docs_taxonomy = __esm({
13374
+ "packages/contracts/src/docs-taxonomy.ts"() {
13375
+ "use strict";
13376
+ BUILTIN_DOC_KINDS = [
13377
+ {
13378
+ kind: "adr",
13379
+ label: "ADR",
13380
+ description: "Architectural decision record",
13381
+ defaultOwnerKind: "task",
13382
+ publishDir: "docs/adr",
13383
+ requiresEntityId: true,
13384
+ entityIdPattern: /^adr-\d{3,4}-[a-z0-9-]+$/,
13385
+ requiredSections: ["Status", "Date", "Context", "Decision", "Consequences"]
13386
+ },
13387
+ {
13388
+ kind: "spec",
13389
+ label: "Spec",
13390
+ description: "Technical specification",
13391
+ defaultOwnerKind: "task",
13392
+ publishDir: "docs/spec",
13393
+ requiresEntityId: false,
13394
+ requiredSections: ["Goal", "Non-Goals", "Requirements", "Out-of-Scope"]
13395
+ },
13396
+ {
13397
+ kind: "research",
13398
+ label: "Research",
13399
+ description: "Investigation / research note",
13400
+ defaultOwnerKind: "task",
13401
+ publishDir: "docs/research",
13402
+ requiresEntityId: false,
13403
+ requiredSections: ["Question", "Findings", "Sources"]
13404
+ },
13405
+ {
13406
+ kind: "handoff",
13407
+ label: "Handoff",
13408
+ description: "Session / agent handoff",
13409
+ defaultOwnerKind: "session",
13410
+ publishDir: "docs/handoff",
13411
+ requiresEntityId: false,
13412
+ requiredSections: ["Context", "State", "Next-Steps"]
13413
+ },
13414
+ {
13415
+ kind: "note",
13416
+ label: "Note",
13417
+ description: "Agent observation / informal note",
13418
+ defaultOwnerKind: "observation",
13419
+ publishDir: "docs/note",
13420
+ requiresEntityId: false,
13421
+ requiredSections: []
13422
+ },
13423
+ {
13424
+ kind: "llm-readme",
13425
+ label: "LLM README",
13426
+ description: "Machine-readable README (llms.txt)",
13427
+ defaultOwnerKind: "project",
13428
+ publishDir: ".",
13429
+ requiresEntityId: false,
13430
+ requiredSections: []
13431
+ },
13432
+ {
13433
+ kind: "changeset",
13434
+ label: "Changeset",
13435
+ description: "Atomic change entry (release-note input)",
13436
+ defaultOwnerKind: "task",
13437
+ publishDir: ".changeset",
13438
+ requiresEntityId: true,
13439
+ entityIdPattern: /^t\d+-[a-z0-9-]+$/,
13440
+ requiredSections: []
13441
+ },
13442
+ {
13443
+ kind: "release-note",
13444
+ label: "Release Note",
13445
+ description: "Composed release notes",
13446
+ defaultOwnerKind: "project",
13447
+ publishDir: "docs/release",
13448
+ requiresEntityId: true,
13449
+ entityIdPattern: /^v\d{4}\.\d+\.\d+(-[a-z0-9-]+)?$/,
13450
+ requiredSections: ["Changes", "Migration"]
13451
+ },
13452
+ {
13453
+ kind: "plan",
13454
+ label: "Plan",
13455
+ description: "Epic / saga decomposition plan",
13456
+ defaultOwnerKind: "task",
13457
+ publishDir: "docs/plan",
13458
+ requiresEntityId: false,
13459
+ requiredSections: ["Goal", "Steps", "Owners"]
13460
+ },
13461
+ {
13462
+ kind: "rcasd",
13463
+ label: "RCASD",
13464
+ description: "Root-cause analysis + scoped delivery",
13465
+ defaultOwnerKind: "task",
13466
+ publishDir: ".cleo/rcasd",
13467
+ requiresEntityId: true,
13468
+ entityIdPattern: /^t\d+(-.+)?$/,
13469
+ requiredSections: ["Root-Cause", "Action", "Schedule", "Detection"]
13470
+ }
13471
+ ];
13472
+ BUILTIN_DOC_KIND_VALUES = Object.freeze(
13473
+ BUILTIN_DOC_KINDS.map((d) => d.kind)
13474
+ );
13475
+ }
13476
+ });
13477
+
13514
13478
  // packages/contracts/src/engine-result.ts
13515
13479
  var init_engine_result = __esm({
13516
13480
  "packages/contracts/src/engine-result.ts"() {
@@ -13564,7 +13528,7 @@ var init_errors = __esm({
13564
13528
  });
13565
13529
 
13566
13530
  // packages/contracts/src/evidence-atom-schema.ts
13567
- import { z as z10 } from "zod";
13531
+ import { z as z9 } from "zod";
13568
13532
  var EVIDENCE_ATOM_KINDS, PARSER_PREFIXES, KIND_BOUNDARY_REGEX, commitAtomSchema, filesAtomSchema, testRunAtomSchema, toolAtomSchema, urlAtomSchema, noteAtomSchema, decisionAtomSchema, prAtomSchema, ciAtomSchema, locDropAtomSchema, callsiteCoverageAtomSchema, AC_UUID_REGEX, AC_ALIAS_REGEX, SATISFIES_TASK_ID_REGEX, SATISFIES_VERSION_PIN_REGEX, satisfiesAtomSchema, EvidenceAtomSchema, GATE_EVIDENCE_REQUIREMENTS, ATOM_EXAMPLES;
13569
13533
  var init_evidence_atom_schema = __esm({
13570
13534
  "packages/contracts/src/evidence-atom-schema.ts"() {
@@ -13585,73 +13549,73 @@ var init_evidence_atom_schema = __esm({
13585
13549
  ];
13586
13550
  PARSER_PREFIXES = [...EVIDENCE_ATOM_KINDS, "state"];
13587
13551
  KIND_BOUNDARY_REGEX = new RegExp(`;(?=\\s*(?:${PARSER_PREFIXES.join("|")})\\s*:)`, "g");
13588
- commitAtomSchema = z10.object({
13589
- kind: z10.literal("commit"),
13590
- sha: z10.string().regex(/^[0-9a-f]{7,40}$/i, "commit sha must be 7-40 hex characters")
13591
- });
13592
- filesAtomSchema = z10.object({
13593
- kind: z10.literal("files"),
13594
- paths: z10.array(z10.string().min(1)).min(1, "files atom requires at least one path")
13595
- });
13596
- testRunAtomSchema = z10.object({
13597
- kind: z10.literal("test-run"),
13598
- path: z10.string().min(1, "test-run atom requires a non-empty path")
13599
- });
13600
- toolAtomSchema = z10.object({
13601
- kind: z10.literal("tool"),
13602
- tool: z10.string().min(1, "tool atom requires a non-empty tool name")
13603
- });
13604
- urlAtomSchema = z10.object({
13605
- kind: z10.literal("url"),
13606
- url: z10.string().min(1).regex(/^https?:\/\//, "url atom must start with http:// or https://")
13607
- });
13608
- noteAtomSchema = z10.object({
13609
- kind: z10.literal("note"),
13610
- note: z10.string().min(1, "note atom must be non-empty").max(512, "note atom is too long (max 512 chars)")
13611
- });
13612
- decisionAtomSchema = z10.object({
13613
- kind: z10.literal("decision"),
13614
- decisionId: z10.string().min(1, "decision atom requires a non-empty decision ID")
13615
- });
13616
- prAtomSchema = z10.object({
13617
- kind: z10.literal("pr"),
13618
- prNumber: z10.number().int().positive("pr atom requires a positive integer PR number"),
13619
- componentPrNumber: z10.number().int().positive().optional()
13620
- });
13621
- ciAtomSchema = z10.object({
13622
- kind: z10.literal("ci"),
13623
- prNumber: z10.number().int().positive("ci atom requires a positive integer PR number"),
13624
- componentPrNumber: z10.number().int().positive().optional()
13625
- });
13626
- locDropAtomSchema = z10.object({
13627
- kind: z10.literal("loc-drop"),
13628
- fromLines: z10.number().int().nonnegative("loc-drop fromLines must be \u2265 0"),
13629
- toLines: z10.number().int().nonnegative("loc-drop toLines must be \u2265 0")
13630
- });
13631
- callsiteCoverageAtomSchema = z10.object({
13632
- kind: z10.literal("callsite-coverage"),
13633
- symbolName: z10.string().min(1, "callsite-coverage atom requires a non-empty symbolName"),
13634
- relativeSourcePath: z10.string().min(1, "callsite-coverage atom requires a non-empty relativeSourcePath")
13552
+ commitAtomSchema = z9.object({
13553
+ kind: z9.literal("commit"),
13554
+ sha: z9.string().regex(/^[0-9a-f]{7,40}$/i, "commit sha must be 7-40 hex characters")
13555
+ });
13556
+ filesAtomSchema = z9.object({
13557
+ kind: z9.literal("files"),
13558
+ paths: z9.array(z9.string().min(1)).min(1, "files atom requires at least one path")
13559
+ });
13560
+ testRunAtomSchema = z9.object({
13561
+ kind: z9.literal("test-run"),
13562
+ path: z9.string().min(1, "test-run atom requires a non-empty path")
13563
+ });
13564
+ toolAtomSchema = z9.object({
13565
+ kind: z9.literal("tool"),
13566
+ tool: z9.string().min(1, "tool atom requires a non-empty tool name")
13567
+ });
13568
+ urlAtomSchema = z9.object({
13569
+ kind: z9.literal("url"),
13570
+ url: z9.string().min(1).regex(/^https?:\/\//, "url atom must start with http:// or https://")
13571
+ });
13572
+ noteAtomSchema = z9.object({
13573
+ kind: z9.literal("note"),
13574
+ note: z9.string().min(1, "note atom must be non-empty").max(512, "note atom is too long (max 512 chars)")
13575
+ });
13576
+ decisionAtomSchema = z9.object({
13577
+ kind: z9.literal("decision"),
13578
+ decisionId: z9.string().min(1, "decision atom requires a non-empty decision ID")
13579
+ });
13580
+ prAtomSchema = z9.object({
13581
+ kind: z9.literal("pr"),
13582
+ prNumber: z9.number().int().positive("pr atom requires a positive integer PR number"),
13583
+ componentPrNumber: z9.number().int().positive().optional()
13584
+ });
13585
+ ciAtomSchema = z9.object({
13586
+ kind: z9.literal("ci"),
13587
+ prNumber: z9.number().int().positive("ci atom requires a positive integer PR number"),
13588
+ componentPrNumber: z9.number().int().positive().optional()
13589
+ });
13590
+ locDropAtomSchema = z9.object({
13591
+ kind: z9.literal("loc-drop"),
13592
+ fromLines: z9.number().int().nonnegative("loc-drop fromLines must be \u2265 0"),
13593
+ toLines: z9.number().int().nonnegative("loc-drop toLines must be \u2265 0")
13594
+ });
13595
+ callsiteCoverageAtomSchema = z9.object({
13596
+ kind: z9.literal("callsite-coverage"),
13597
+ symbolName: z9.string().min(1, "callsite-coverage atom requires a non-empty symbolName"),
13598
+ relativeSourcePath: z9.string().min(1, "callsite-coverage atom requires a non-empty relativeSourcePath")
13635
13599
  });
13636
13600
  AC_UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
13637
13601
  AC_ALIAS_REGEX = /^AC[0-9]{1,4}$/;
13638
13602
  SATISFIES_TASK_ID_REGEX = /^T[0-9]{1,7}$/;
13639
13603
  SATISFIES_VERSION_PIN_REGEX = /^[0-9]{14}$/;
13640
- satisfiesAtomSchema = z10.object({
13641
- kind: z10.literal("satisfies"),
13604
+ satisfiesAtomSchema = z9.object({
13605
+ kind: z9.literal("satisfies"),
13642
13606
  /** Target task ID — `T<1-7 digits>` per ADR-079-r2 §2.1. */
13643
- targetTaskId: z10.string().regex(SATISFIES_TASK_ID_REGEX, "satisfies atom targetTaskId must match /^T[0-9]{1,7}$/"),
13607
+ targetTaskId: z9.string().regex(SATISFIES_TASK_ID_REGEX, "satisfies atom targetTaskId must match /^T[0-9]{1,7}$/"),
13644
13608
  /** Lowercase UUIDv4/v5 — populated for the canonical form; undefined for alias form. */
13645
- targetAcId: z10.string().regex(AC_UUID_REGEX, "satisfies atom targetAcId must be a lowercase UUIDv4/v5").optional(),
13609
+ targetAcId: z9.string().regex(AC_UUID_REGEX, "satisfies atom targetAcId must be a lowercase UUIDv4/v5").optional(),
13646
13610
  /** Positional alias `AC<1-4 digits>` — populated for alias form; undefined for UUID form. */
13647
- targetAcAlias: z10.string().regex(AC_ALIAS_REGEX, "satisfies atom targetAcAlias must match /^AC[0-9]{1,4}$/").optional(),
13611
+ targetAcAlias: z9.string().regex(AC_ALIAS_REGEX, "satisfies atom targetAcAlias must match /^AC[0-9]{1,4}$/").optional(),
13648
13612
  /** Optional `@<14-digit YYYYMMDDhhmmss>` pin captured at mint time. */
13649
- versionPin: z10.string().regex(
13613
+ versionPin: z9.string().regex(
13650
13614
  SATISFIES_VERSION_PIN_REGEX,
13651
13615
  "satisfies atom versionPin must be 14 digits (YYYYMMDDhhmmss)"
13652
13616
  ).optional()
13653
13617
  });
13654
- EvidenceAtomSchema = z10.discriminatedUnion("kind", [
13618
+ EvidenceAtomSchema = z9.discriminatedUnion("kind", [
13655
13619
  commitAtomSchema,
13656
13620
  filesAtomSchema,
13657
13621
  testRunAtomSchema,
@@ -13703,58 +13667,58 @@ var init_evidence_atom_schema = __esm({
13703
13667
  });
13704
13668
 
13705
13669
  // packages/contracts/src/evidence-record-schema.ts
13706
- import { z as z11 } from "zod";
13670
+ import { z as z10 } from "zod";
13707
13671
  var evidenceBaseSchema, implDiffRecordSchema, validateSpecCheckRecordSchema, testOutputRecordSchema, lintReportRecordSchema, commandOutputRecordSchema, evidenceRecordSchema;
13708
13672
  var init_evidence_record_schema = __esm({
13709
13673
  "packages/contracts/src/evidence-record-schema.ts"() {
13710
13674
  "use strict";
13711
- evidenceBaseSchema = z11.object({
13675
+ evidenceBaseSchema = z10.object({
13712
13676
  /** Identity string of the agent that produced this record. */
13713
- agentIdentity: z11.string().min(1),
13677
+ agentIdentity: z10.string().min(1),
13714
13678
  /** SHA-256 hex digest (64 chars) of the attached artifact. */
13715
- attachmentSha256: z11.string().length(64),
13679
+ attachmentSha256: z10.string().length(64),
13716
13680
  /** ISO 8601 timestamp at which the action ran. */
13717
- ranAt: z11.string().datetime(),
13681
+ ranAt: z10.string().datetime(),
13718
13682
  /** Wall-clock duration of the action in milliseconds. */
13719
- durationMs: z11.number().nonnegative()
13683
+ durationMs: z10.number().nonnegative()
13720
13684
  });
13721
13685
  implDiffRecordSchema = evidenceBaseSchema.extend({
13722
- kind: z11.literal("impl-diff"),
13723
- phase: z11.literal("implement"),
13724
- filesChanged: z11.array(z11.string().min(1)).min(1),
13725
- linesAdded: z11.number().int().nonnegative(),
13726
- linesRemoved: z11.number().int().nonnegative()
13686
+ kind: z10.literal("impl-diff"),
13687
+ phase: z10.literal("implement"),
13688
+ filesChanged: z10.array(z10.string().min(1)).min(1),
13689
+ linesAdded: z10.number().int().nonnegative(),
13690
+ linesRemoved: z10.number().int().nonnegative()
13727
13691
  });
13728
13692
  validateSpecCheckRecordSchema = evidenceBaseSchema.extend({
13729
- kind: z11.literal("validate-spec-check"),
13730
- phase: z11.literal("validate"),
13731
- reqIdsChecked: z11.array(z11.string().min(1)).min(1),
13732
- passed: z11.boolean(),
13733
- details: z11.string().min(1)
13693
+ kind: z10.literal("validate-spec-check"),
13694
+ phase: z10.literal("validate"),
13695
+ reqIdsChecked: z10.array(z10.string().min(1)).min(1),
13696
+ passed: z10.boolean(),
13697
+ details: z10.string().min(1)
13734
13698
  });
13735
13699
  testOutputRecordSchema = evidenceBaseSchema.extend({
13736
- kind: z11.literal("test-output"),
13737
- phase: z11.literal("test"),
13738
- command: z11.string().min(1),
13739
- exitCode: z11.number().int(),
13740
- testsPassed: z11.number().int().nonnegative(),
13741
- testsFailed: z11.number().int().nonnegative()
13700
+ kind: z10.literal("test-output"),
13701
+ phase: z10.literal("test"),
13702
+ command: z10.string().min(1),
13703
+ exitCode: z10.number().int(),
13704
+ testsPassed: z10.number().int().nonnegative(),
13705
+ testsFailed: z10.number().int().nonnegative()
13742
13706
  });
13743
13707
  lintReportRecordSchema = evidenceBaseSchema.extend({
13744
- kind: z11.literal("lint-report"),
13745
- phase: z11.enum(["implement", "test"]),
13746
- tool: z11.string().min(1),
13747
- passed: z11.boolean(),
13748
- warnings: z11.number().int().nonnegative(),
13749
- errors: z11.number().int().nonnegative()
13708
+ kind: z10.literal("lint-report"),
13709
+ phase: z10.enum(["implement", "test"]),
13710
+ tool: z10.string().min(1),
13711
+ passed: z10.boolean(),
13712
+ warnings: z10.number().int().nonnegative(),
13713
+ errors: z10.number().int().nonnegative()
13750
13714
  });
13751
13715
  commandOutputRecordSchema = evidenceBaseSchema.extend({
13752
- kind: z11.literal("command-output"),
13753
- phase: z11.enum(["implement", "validate", "test"]),
13754
- cmd: z11.string().min(1),
13755
- exitCode: z11.number().int()
13716
+ kind: z10.literal("command-output"),
13717
+ phase: z10.enum(["implement", "validate", "test"]),
13718
+ cmd: z10.string().min(1),
13719
+ exitCode: z10.number().int()
13756
13720
  });
13757
- evidenceRecordSchema = z11.discriminatedUnion("kind", [
13721
+ evidenceRecordSchema = z10.discriminatedUnion("kind", [
13758
13722
  implDiffRecordSchema,
13759
13723
  validateSpecCheckRecordSchema,
13760
13724
  testOutputRecordSchema,
@@ -14223,6 +14187,21 @@ function checkPending(task) {
14223
14187
  function rulePending(task) {
14224
14188
  return { task, reason: "the typed merge-rule registry does not define it yet (T12344 item)" };
14225
14189
  }
14190
+ function implemented(entry) {
14191
+ const { pending: _pending, ...rest } = entry;
14192
+ return { ...rest, runtimeGate: MERGE_ENGINE_GATE };
14193
+ }
14194
+ function implementedCheck(entry, functionName) {
14195
+ const { pending: _pending, ...rest } = entry;
14196
+ return {
14197
+ ...rest,
14198
+ check: {
14199
+ module: "packages/core/src/store/sync/apply/post-apply.ts",
14200
+ functionName,
14201
+ footprint: entry.check?.footprint ?? []
14202
+ }
14203
+ };
14204
+ }
14226
14205
  function trigger(id, tables, triggers, inventory, reason) {
14227
14206
  return { id, class: "trigger-covered", tables, sites: [], triggers, inventory, reason };
14228
14207
  }
@@ -14250,10 +14229,14 @@ function rule(id, task, table, columns, inventory, reason, tables = [table]) {
14250
14229
  reason
14251
14230
  };
14252
14231
  }
14253
- var SYNC_WRITE_INVARIANTS;
14232
+ var MERGE_ENGINE_GATE, SYNC_WRITE_INVARIANTS;
14254
14233
  var init_sync_write_invariants = __esm({
14255
14234
  "packages/contracts/src/invariants/sync-write-invariants.ts"() {
14256
14235
  "use strict";
14236
+ MERGE_ENGINE_GATE = {
14237
+ module: "packages/core/src/store/sync/merge/engine.ts",
14238
+ functionName: "applyOp"
14239
+ };
14257
14240
  SYNC_WRITE_INVARIANTS = Object.freeze([
14258
14241
  // §3.6.2: RAISE guards and UNIQUE indexes a migration creates on synced tables.
14259
14242
  trigger(
@@ -14334,13 +14317,16 @@ var init_sync_write_invariants = __esm({
14334
14317
  "at most one active account per provider (partial UNIQUE)"
14335
14318
  ),
14336
14319
  // §3.6.5: post-apply check families (T12344 items).
14337
- pac(
14338
- "task.tree.shape",
14339
- "PAC-01",
14340
- "T12922",
14341
- ["tasks_tasks"],
14342
- ["rows with a changed parent_id or type", "their direct children and ancestor chain"],
14343
- "saga\u2192epic\u2192task\u2192subtask matrix, non-saga has a parent, depth \u2264 3, no self-parent"
14320
+ implementedCheck(
14321
+ pac(
14322
+ "task.tree.shape",
14323
+ "PAC-01",
14324
+ "T12922",
14325
+ ["tasks_tasks"],
14326
+ ["rows with a changed parent_id or type", "their direct children and ancestor chain"],
14327
+ "saga\u2192epic\u2192task\u2192subtask matrix, non-saga has a parent, depth \u2264 3, no self-parent"
14328
+ ),
14329
+ "checkTaskTreeShape"
14344
14330
  ),
14345
14331
  pac(
14346
14332
  "task.terminal-parent.live-children",
@@ -14350,13 +14336,12 @@ var init_sync_write_invariants = __esm({
14350
14336
  ["rows whose status, stage or parent changed", "their parent and siblings"],
14351
14337
  "no terminal parent with a live child; epic stage \u2265 children; rollup re-evaluated"
14352
14338
  ),
14353
- pac(
14339
+ trigger(
14354
14340
  "task.dependency.graph",
14355
- "PAC-03",
14356
- "T12924",
14357
14341
  ["tasks_task_dependencies", "tasks_tasks"],
14358
- ["dependency edges inserted in the page", "reachability from each depends_on"],
14359
- "dependencies are acyclic, with no self-edge"
14342
+ ["tasks_task_dependencies_cycle_guard_insert", "tasks_task_dependencies_cycle_guard_update"],
14343
+ ["PAC-03"],
14344
+ "dependencies are acyclic, with no self-edge: enforced by the T12886 cycle guards on apply (a guard conflict)"
14360
14345
  ),
14361
14346
  pac(
14362
14347
  "task.done.evidence",
@@ -14446,38 +14431,47 @@ var init_sync_write_invariants = __esm({
14446
14431
  ["the owning rows"],
14447
14432
  "derived counters and cross-column facts agree with their rows"
14448
14433
  ),
14449
- pac(
14450
- "apply.preconditions",
14451
- "PAC-15",
14452
- "T12936",
14453
- ["tasks_tasks"],
14454
- ["the whole page"],
14455
- "no apply while the local twin collapse has failed; restore is a re-baseline"
14434
+ implementedCheck(
14435
+ pac(
14436
+ "apply.preconditions",
14437
+ "PAC-15",
14438
+ "T12936",
14439
+ ["tasks_tasks"],
14440
+ ["the whole page"],
14441
+ "no apply while the local twin collapse has failed; restore is a re-baseline"
14442
+ ),
14443
+ "checkApplyPreconditions"
14456
14444
  ),
14457
14445
  // §3.6.6: typed merge rules (T12344).
14458
- rule(
14459
- "task.status.absorbing",
14460
- "T12937",
14461
- "tasks_tasks",
14462
- ["status", "completed_at", "cancelled_at", "cancellation_reason", "pipeline_stage"],
14463
- ["V18", "V20", "C22", "P40", "P46", "P47"],
14464
- "done, cancelled and archived are absorbing; leaving them needs an explicit op"
14446
+ implemented(
14447
+ rule(
14448
+ "task.status.absorbing",
14449
+ "T12937",
14450
+ "tasks_tasks",
14451
+ ["status", "completed_at", "cancelled_at", "cancellation_reason", "pipeline_stage"],
14452
+ ["V18", "V20", "C22", "P40", "P46", "P47"],
14453
+ "done, cancelled and archived are absorbing; leaving them needs an explicit op"
14454
+ )
14465
14455
  ),
14466
- rule(
14467
- "task.pipeline-stage.max",
14468
- "T12938",
14469
- "tasks_tasks",
14470
- ["pipeline_stage"],
14471
- ["V21", "C20", "P01", "F3"],
14472
- "pipeline_stage is the maximum by STAGE_ORDER, except an explicit restore"
14456
+ implemented(
14457
+ rule(
14458
+ "task.pipeline-stage.max",
14459
+ "T12938",
14460
+ "tasks_tasks",
14461
+ ["pipeline_stage"],
14462
+ ["V21", "C20", "P01", "F3"],
14463
+ "pipeline_stage is the maximum by STAGE_ORDER, except an explicit restore"
14464
+ )
14473
14465
  ),
14474
- rule(
14475
- "task.verification.frozen-on-done",
14476
- "T12939",
14477
- "tasks_tasks",
14478
- ["verification_json"],
14479
- ["C01", "C02", "C03", "C17"],
14480
- "verification is frozen once done; otherwise merged per gate"
14466
+ implemented(
14467
+ rule(
14468
+ "task.verification.frozen-on-done",
14469
+ "T12939",
14470
+ "tasks_tasks",
14471
+ ["verification_json"],
14472
+ ["C01", "C02", "C03", "C17"],
14473
+ "verification is frozen once done; otherwise merged per gate"
14474
+ )
14481
14475
  ),
14482
14476
  rule(
14483
14477
  "session.status.terminal",
@@ -14613,111 +14607,111 @@ var init_lafs = __esm({
14613
14607
  });
14614
14608
 
14615
14609
  // packages/contracts/src/lease-ipc/messages.ts
14616
- import { z as z12 } from "zod";
14610
+ import { z as z11 } from "zod";
14617
14611
  var LeaseScopeSchema, LeaseLaneSchema, LeaseAcquireRequestSchema, LeaseReleaseRequestSchema, LeaseRenewRequestSchema, RateCheckRequestSchema, ToolGrantRequestSchema, QueuePriorityClassSchema, QueueAdmitRequestSchema, WorkerHeartbeatRequestSchema, ResourceAdmitRequestSchema, ResourceReleaseRequestSchema, LeaseIpcRequestSchema, LeaseGrantedResponseSchema, LeaseQueuedResponseSchema, LeaseDeniedResponseSchema, RateResultResponseSchema, ToolGrantedResponseSchema, LeaseRevokedResponseSchema, ChildKilledUnresponsiveResponseSchema, QueueAdmitDispositionSchema, QueueAdmitResultResponseSchema, HeartbeatAckResponseSchema, ResourceAdmitDispositionSchema, ResourceAdmitResultResponseSchema, ResourceReleaseResultResponseSchema, LeaseErrorResponseSchema, LeaseIpcResponseSchema, LeaseIpcRequestEnvelopeSchema, LeaseIpcResponseEnvelopeSchema, LeaseIpcEnvelopeSchema, LEASE_IPC_REQUEST_KINDS, LEASE_IPC_RESPONSE_KINDS, LEASE_IPC_MESSAGE_KINDS;
14618
14612
  var init_messages2 = __esm({
14619
14613
  "packages/contracts/src/lease-ipc/messages.ts"() {
14620
14614
  "use strict";
14621
- LeaseScopeSchema = z12.enum(["project", "global"]);
14622
- LeaseLaneSchema = z12.enum(["tasks", "brain", "bulk"]);
14623
- LeaseAcquireRequestSchema = z12.object({
14615
+ LeaseScopeSchema = z11.enum(["project", "global"]);
14616
+ LeaseLaneSchema = z11.enum(["tasks", "brain", "bulk"]);
14617
+ LeaseAcquireRequestSchema = z11.object({
14624
14618
  /** Tag discriminating this request variant. */
14625
- kind: z12.literal("lease_acquire"),
14619
+ kind: z11.literal("lease_acquire"),
14626
14620
  /** The cleo.db scope being arbitrated. */
14627
14621
  scope: LeaseScopeSchema,
14628
14622
  /** The write lane within the scope. */
14629
14623
  lane: LeaseLaneSchema,
14630
14624
  /** Process+lane holder identity. */
14631
- holder_id: z12.string().min(1),
14625
+ holder_id: z11.string().min(1),
14632
14626
  /** Advisory priority — lower acquires sooner. `0` = highest. */
14633
- priority: z12.number().int().min(0).max(255),
14627
+ priority: z11.number().int().min(0).max(255),
14634
14628
  /** Lease time-to-live in milliseconds. */
14635
- ttl_ms: z12.number().int().nonnegative(),
14629
+ ttl_ms: z11.number().int().nonnegative(),
14636
14630
  /** When true, a same-holder acquire re-enters (refcount++) rather than queuing. */
14637
- reentrant: z12.boolean()
14631
+ reentrant: z11.boolean()
14638
14632
  }).strict();
14639
- LeaseReleaseRequestSchema = z12.object({
14633
+ LeaseReleaseRequestSchema = z11.object({
14640
14634
  /** Tag discriminating this request variant. */
14641
- kind: z12.literal("lease_release"),
14635
+ kind: z11.literal("lease_release"),
14642
14636
  /** The cleo.db scope being arbitrated. */
14643
14637
  scope: LeaseScopeSchema,
14644
14638
  /** The write lane within the scope. */
14645
14639
  lane: LeaseLaneSchema,
14646
14640
  /** Process+lane holder identity. */
14647
- holder_id: z12.string().min(1),
14641
+ holder_id: z11.string().min(1),
14648
14642
  /** The epoch fence the holder acquired — a stale epoch no-ops. */
14649
- epoch: z12.number().int().nonnegative()
14643
+ epoch: z11.number().int().nonnegative()
14650
14644
  }).strict();
14651
- LeaseRenewRequestSchema = z12.object({
14645
+ LeaseRenewRequestSchema = z11.object({
14652
14646
  /** Tag discriminating this request variant. */
14653
- kind: z12.literal("lease_renew"),
14647
+ kind: z11.literal("lease_renew"),
14654
14648
  /** The cleo.db scope being arbitrated. */
14655
14649
  scope: LeaseScopeSchema,
14656
14650
  /** The write lane within the scope. */
14657
14651
  lane: LeaseLaneSchema,
14658
14652
  /** Process+lane holder identity. */
14659
- holder_id: z12.string().min(1),
14653
+ holder_id: z11.string().min(1),
14660
14654
  /** The epoch fence the holder acquired (epoch-guarded renew). */
14661
- epoch: z12.number().int().nonnegative()
14655
+ epoch: z11.number().int().nonnegative()
14662
14656
  }).strict();
14663
- RateCheckRequestSchema = z12.object({
14657
+ RateCheckRequestSchema = z11.object({
14664
14658
  /** Tag discriminating this request variant. */
14665
- kind: z12.literal("rate_check"),
14659
+ kind: z11.literal("rate_check"),
14666
14660
  /** The cleo.db scope being checked. */
14667
14661
  scope: LeaseScopeSchema,
14668
14662
  /** The write lane within the scope. */
14669
14663
  lane: LeaseLaneSchema,
14670
14664
  /** Estimated bytes the caller intends to write. */
14671
- est_bytes: z12.number().int().nonnegative()
14665
+ est_bytes: z11.number().int().nonnegative()
14672
14666
  }).strict();
14673
- ToolGrantRequestSchema = z12.object({
14667
+ ToolGrantRequestSchema = z11.object({
14674
14668
  /** Tag discriminating this request variant. */
14675
- kind: z12.literal("tool_grant"),
14669
+ kind: z11.literal("tool_grant"),
14676
14670
  /** The tool name being requested. */
14677
- tool: z12.string().min(1),
14671
+ tool: z11.string().min(1),
14678
14672
  /** The requesting holder identity. */
14679
- holder_id: z12.string().min(1)
14673
+ holder_id: z11.string().min(1)
14680
14674
  }).strict();
14681
- QueuePriorityClassSchema = z12.enum(["lead", "worker", "background"]);
14682
- QueueAdmitRequestSchema = z12.object({
14675
+ QueuePriorityClassSchema = z11.enum(["lead", "worker", "background"]);
14676
+ QueueAdmitRequestSchema = z11.object({
14683
14677
  /** Tag discriminating this request variant. */
14684
- kind: z12.literal("queue_admit"),
14678
+ kind: z11.literal("queue_admit"),
14685
14679
  /** The LLM provider id the call targets (rate budget is per-provider). */
14686
- provider: z12.string().min(1),
14680
+ provider: z11.string().min(1),
14687
14681
  /** The caller's priority class (lead > worker > background). */
14688
14682
  priority_class: QueuePriorityClassSchema,
14689
14683
  /** The caller's estimate of the request's token cost (debited on admit). */
14690
- est_tokens: z12.number().int().nonnegative(),
14684
+ est_tokens: z11.number().int().nonnegative(),
14691
14685
  /** The child the call belongs to (in-flight tracking — the watchdog seam). */
14692
- child_id: z12.string().min(1)
14686
+ child_id: z11.string().min(1)
14693
14687
  }).strict();
14694
- WorkerHeartbeatRequestSchema = z12.object({
14688
+ WorkerHeartbeatRequestSchema = z11.object({
14695
14689
  /** Tag discriminating this request variant. */
14696
- kind: z12.literal("worker_heartbeat"),
14690
+ kind: z11.literal("worker_heartbeat"),
14697
14691
  /** The logical id of the heartbeating child (matches the registry key). */
14698
- child_id: z12.string().min(1),
14692
+ child_id: z11.string().min(1),
14699
14693
  /** The worker's own view of whether it is currently inside an LLM call. */
14700
- in_flight_llm: z12.boolean()
14694
+ in_flight_llm: z11.boolean()
14701
14695
  }).strict();
14702
- ResourceAdmitRequestSchema = z12.object({
14696
+ ResourceAdmitRequestSchema = z11.object({
14703
14697
  /** Tag discriminating this request variant. */
14704
- kind: z12.literal("resource_admit"),
14698
+ kind: z11.literal("resource_admit"),
14705
14699
  /** The resource class (e.g. `"db-heavy"`, `"full-build"`, `"test-run"`). */
14706
- class: z12.string().min(1),
14700
+ class: z11.string().min(1),
14707
14701
  /** The caller holding the slot — process/worktree-unique; the release key. */
14708
- holder_id: z12.string().min(1),
14702
+ holder_id: z11.string().min(1),
14709
14703
  /** The client-computed budget: the max concurrent holders for this class. */
14710
- budget: z12.number().int().nonnegative()
14704
+ budget: z11.number().int().nonnegative()
14711
14705
  }).strict();
14712
- ResourceReleaseRequestSchema = z12.object({
14706
+ ResourceReleaseRequestSchema = z11.object({
14713
14707
  /** Tag discriminating this request variant. */
14714
- kind: z12.literal("resource_release"),
14708
+ kind: z11.literal("resource_release"),
14715
14709
  /** The resource class the slot belongs to. */
14716
- class: z12.string().min(1),
14710
+ class: z11.string().min(1),
14717
14711
  /** The holder that was admitted (matches the admit `holder_id`). */
14718
- holder_id: z12.string().min(1)
14712
+ holder_id: z11.string().min(1)
14719
14713
  }).strict();
14720
- LeaseIpcRequestSchema = z12.discriminatedUnion("kind", [
14714
+ LeaseIpcRequestSchema = z11.discriminatedUnion("kind", [
14721
14715
  LeaseAcquireRequestSchema,
14722
14716
  LeaseReleaseRequestSchema,
14723
14717
  LeaseRenewRequestSchema,
@@ -14728,133 +14722,133 @@ var init_messages2 = __esm({
14728
14722
  ResourceAdmitRequestSchema,
14729
14723
  ResourceReleaseRequestSchema
14730
14724
  ]);
14731
- LeaseGrantedResponseSchema = z12.object({
14725
+ LeaseGrantedResponseSchema = z11.object({
14732
14726
  /** Tag discriminating this response variant. */
14733
- kind: z12.literal("lease_granted"),
14727
+ kind: z11.literal("lease_granted"),
14734
14728
  /** The granted cleo.db scope. */
14735
14729
  scope: LeaseScopeSchema,
14736
14730
  /** The granted write lane. */
14737
14731
  lane: LeaseLaneSchema,
14738
14732
  /** The holder the lease was granted to. */
14739
- holder_id: z12.string().min(1),
14733
+ holder_id: z11.string().min(1),
14740
14734
  /** The monotonic epoch fence assigned to this grant. */
14741
- epoch: z12.number().int().nonnegative(),
14735
+ epoch: z11.number().int().nonnegative(),
14742
14736
  /** The lease TTL in milliseconds. */
14743
- ttl_ms: z12.number().int().nonnegative(),
14737
+ ttl_ms: z11.number().int().nonnegative(),
14744
14738
  /** Absolute expiry timestamp (epoch ms) for this grant. */
14745
- expires_at_ms: z12.number().int().nonnegative()
14739
+ expires_at_ms: z11.number().int().nonnegative()
14746
14740
  }).strict();
14747
- LeaseQueuedResponseSchema = z12.object({
14741
+ LeaseQueuedResponseSchema = z11.object({
14748
14742
  /** Tag discriminating this response variant. */
14749
- kind: z12.literal("lease_queued"),
14743
+ kind: z11.literal("lease_queued"),
14750
14744
  /** The queued cleo.db scope. */
14751
14745
  scope: LeaseScopeSchema,
14752
14746
  /** The queued write lane. */
14753
14747
  lane: LeaseLaneSchema,
14754
14748
  /** The monotonic ticket assigned for FIFO tiebreak. */
14755
- ticket: z12.number().int().nonnegative(),
14749
+ ticket: z11.number().int().nonnegative(),
14756
14750
  /** Number of waiters ahead of this one. */
14757
- ahead: z12.number().int().nonnegative()
14751
+ ahead: z11.number().int().nonnegative()
14758
14752
  }).strict();
14759
- LeaseDeniedResponseSchema = z12.object({
14753
+ LeaseDeniedResponseSchema = z11.object({
14760
14754
  /** Tag discriminating this response variant. */
14761
- kind: z12.literal("lease_denied"),
14755
+ kind: z11.literal("lease_denied"),
14762
14756
  /** The denied cleo.db scope. */
14763
14757
  scope: LeaseScopeSchema,
14764
14758
  /** Machine-readable denial code (e.g. `E_LEASE_UNAVAILABLE`). */
14765
- code: z12.string().min(1),
14759
+ code: z11.string().min(1),
14766
14760
  /** Human-readable denial message. */
14767
- message: z12.string()
14761
+ message: z11.string()
14768
14762
  }).strict();
14769
- RateResultResponseSchema = z12.object({
14763
+ RateResultResponseSchema = z11.object({
14770
14764
  /** Tag discriminating this response variant. */
14771
- kind: z12.literal("rate_result"),
14765
+ kind: z11.literal("rate_result"),
14772
14766
  /** The checked cleo.db scope. */
14773
14767
  scope: LeaseScopeSchema,
14774
14768
  /** Whether the write is within budget. */
14775
- ok: z12.boolean(),
14769
+ ok: z11.boolean(),
14776
14770
  /** Suggested back-off in milliseconds when `ok` is false. */
14777
- retry_after_ms: z12.number().int().nonnegative(),
14771
+ retry_after_ms: z11.number().int().nonnegative(),
14778
14772
  /** Remaining token budget for the scope. */
14779
- tokens_remaining: z12.number().int().nonnegative()
14773
+ tokens_remaining: z11.number().int().nonnegative()
14780
14774
  }).strict();
14781
- ToolGrantedResponseSchema = z12.object({
14775
+ ToolGrantedResponseSchema = z11.object({
14782
14776
  /** Tag discriminating this response variant. */
14783
- kind: z12.literal("tool_granted"),
14777
+ kind: z11.literal("tool_granted"),
14784
14778
  /** The granted tool name. */
14785
- tool: z12.string().min(1),
14779
+ tool: z11.string().min(1),
14786
14780
  /** The holder the tool grant was issued to. */
14787
- holder_id: z12.string().min(1)
14781
+ holder_id: z11.string().min(1)
14788
14782
  }).strict();
14789
- LeaseRevokedResponseSchema = z12.object({
14783
+ LeaseRevokedResponseSchema = z11.object({
14790
14784
  /** Tag discriminating this response variant. */
14791
- kind: z12.literal("lease_revoked"),
14785
+ kind: z11.literal("lease_revoked"),
14792
14786
  /** The revoked cleo.db scope. */
14793
14787
  scope: LeaseScopeSchema,
14794
14788
  /** The revoked write lane. */
14795
14789
  lane: LeaseLaneSchema,
14796
14790
  /** The holder whose lease was revoked. */
14797
- holder_id: z12.string().min(1),
14791
+ holder_id: z11.string().min(1),
14798
14792
  /** Human-readable reason for the revocation. */
14799
- reason: z12.string()
14793
+ reason: z11.string()
14800
14794
  }).strict();
14801
- ChildKilledUnresponsiveResponseSchema = z12.object({
14795
+ ChildKilledUnresponsiveResponseSchema = z11.object({
14802
14796
  /** Tag discriminating this response variant. */
14803
- kind: z12.literal("child_killed_unresponsive"),
14797
+ kind: z11.literal("child_killed_unresponsive"),
14804
14798
  /** Logical id of the killed child. */
14805
- child_id: z12.string().min(1),
14799
+ child_id: z11.string().min(1),
14806
14800
  /** The holder identity the killed child held the lease as. */
14807
- holder_id: z12.string().min(1),
14801
+ holder_id: z11.string().min(1),
14808
14802
  /** The cleo.db scope the killed child held the lease in. */
14809
14803
  scope: LeaseScopeSchema,
14810
14804
  /** Human-readable reason for the kill. */
14811
- reason: z12.string()
14805
+ reason: z11.string()
14812
14806
  }).strict();
14813
- QueueAdmitDispositionSchema = z12.enum(["admitted", "deferred"]);
14814
- QueueAdmitResultResponseSchema = z12.object({
14807
+ QueueAdmitDispositionSchema = z11.enum(["admitted", "deferred"]);
14808
+ QueueAdmitResultResponseSchema = z11.object({
14815
14809
  /** Tag discriminating this response variant. */
14816
- kind: z12.literal("queue_admit_result"),
14810
+ kind: z11.literal("queue_admit_result"),
14817
14811
  /** Whether the LLM call was admitted or deferred. */
14818
14812
  disposition: QueueAdmitDispositionSchema,
14819
14813
  /** Back-off in ms before re-requesting (0 when admitted). */
14820
- retry_after_ms: z12.number().int().nonnegative(),
14814
+ retry_after_ms: z11.number().int().nonnegative(),
14821
14815
  /** Remaining provider token budget after this decision. */
14822
- tokens_remaining: z12.number().int().nonnegative(),
14816
+ tokens_remaining: z11.number().int().nonnegative(),
14823
14817
  /** Number of higher/equal-priority waiters ahead (0 when admitted). */
14824
- queue_position: z12.number().int().nonnegative()
14818
+ queue_position: z11.number().int().nonnegative()
14825
14819
  }).strict();
14826
- HeartbeatAckResponseSchema = z12.object({
14820
+ HeartbeatAckResponseSchema = z11.object({
14827
14821
  /** Tag discriminating this response variant. */
14828
- kind: z12.literal("heartbeat_ack")
14822
+ kind: z11.literal("heartbeat_ack")
14829
14823
  }).strict();
14830
- ResourceAdmitDispositionSchema = z12.enum(["admitted", "deferred"]);
14831
- ResourceAdmitResultResponseSchema = z12.object({
14824
+ ResourceAdmitDispositionSchema = z11.enum(["admitted", "deferred"]);
14825
+ ResourceAdmitResultResponseSchema = z11.object({
14832
14826
  /** Tag discriminating this response variant. */
14833
- kind: z12.literal("resource_admit_result"),
14827
+ kind: z11.literal("resource_admit_result"),
14834
14828
  /** Whether the heavy op was admitted or deferred. */
14835
14829
  disposition: ResourceAdmitDispositionSchema,
14836
14830
  /** Back-off in ms before re-requesting (0 when admitted). */
14837
- retry_after_ms: z12.number().int().nonnegative(),
14831
+ retry_after_ms: z11.number().int().nonnegative(),
14838
14832
  /** Remaining slots for the class after this decision. */
14839
- slots_remaining: z12.number().int().nonnegative()
14833
+ slots_remaining: z11.number().int().nonnegative()
14840
14834
  }).strict();
14841
- ResourceReleaseResultResponseSchema = z12.object({
14835
+ ResourceReleaseResultResponseSchema = z11.object({
14842
14836
  /** Tag discriminating this response variant. */
14843
- kind: z12.literal("resource_release_result"),
14837
+ kind: z11.literal("resource_release_result"),
14844
14838
  /** Whether a held slot was actually released (false = no such holder). */
14845
- released: z12.boolean(),
14839
+ released: z11.boolean(),
14846
14840
  /** Remaining in-flight holders for the class after the release. */
14847
- slots_remaining: z12.number().int().nonnegative()
14841
+ slots_remaining: z11.number().int().nonnegative()
14848
14842
  }).strict();
14849
- LeaseErrorResponseSchema = z12.object({
14843
+ LeaseErrorResponseSchema = z11.object({
14850
14844
  /** Tag discriminating this response variant. */
14851
- kind: z12.literal("error"),
14845
+ kind: z11.literal("error"),
14852
14846
  /** Machine-readable error code (e.g. `E_LEASE_BAD_VERSION`, `E_LEASE_UNIMPLEMENTED`). */
14853
- code: z12.string().min(1),
14847
+ code: z11.string().min(1),
14854
14848
  /** Human-readable error message. */
14855
- message: z12.string()
14849
+ message: z11.string()
14856
14850
  }).strict();
14857
- LeaseIpcResponseSchema = z12.discriminatedUnion("kind", [
14851
+ LeaseIpcResponseSchema = z11.discriminatedUnion("kind", [
14858
14852
  LeaseGrantedResponseSchema,
14859
14853
  LeaseQueuedResponseSchema,
14860
14854
  LeaseDeniedResponseSchema,
@@ -14868,27 +14862,27 @@ var init_messages2 = __esm({
14868
14862
  ResourceReleaseResultResponseSchema,
14869
14863
  LeaseErrorResponseSchema
14870
14864
  ]);
14871
- LeaseIpcRequestEnvelopeSchema = z12.object({
14865
+ LeaseIpcRequestEnvelopeSchema = z11.object({
14872
14866
  /** Parallel protocol version. */
14873
- protocol_version: z12.string(),
14867
+ protocol_version: z11.string(),
14874
14868
  /** Correlation id echoed back on the matching response. */
14875
- id: z12.string().min(1),
14869
+ id: z11.string().min(1),
14876
14870
  /** Direction discriminator. */
14877
- direction: z12.literal("request"),
14871
+ direction: z11.literal("request"),
14878
14872
  /** The request body. */
14879
14873
  request: LeaseIpcRequestSchema
14880
14874
  }).strict();
14881
- LeaseIpcResponseEnvelopeSchema = z12.object({
14875
+ LeaseIpcResponseEnvelopeSchema = z11.object({
14882
14876
  /** Parallel protocol version. */
14883
- protocol_version: z12.string(),
14877
+ protocol_version: z11.string(),
14884
14878
  /** Correlation id echoed from the originating request (or a fresh id for events). */
14885
- id: z12.string().min(1),
14879
+ id: z11.string().min(1),
14886
14880
  /** Direction discriminator. */
14887
- direction: z12.literal("response"),
14881
+ direction: z11.literal("response"),
14888
14882
  /** The response body. */
14889
14883
  response: LeaseIpcResponseSchema
14890
14884
  }).strict();
14891
- LeaseIpcEnvelopeSchema = z12.discriminatedUnion("direction", [
14885
+ LeaseIpcEnvelopeSchema = z11.discriminatedUnion("direction", [
14892
14886
  LeaseIpcRequestEnvelopeSchema,
14893
14887
  LeaseIpcResponseEnvelopeSchema
14894
14888
  ]);
@@ -14941,7 +14935,7 @@ var init_lease_ipc = __esm({
14941
14935
  });
14942
14936
 
14943
14937
  // packages/contracts/src/llm/catalog-schema.ts
14944
- import { z as z13 } from "zod";
14938
+ import { z as z12 } from "zod";
14945
14939
  var CATALOG_MODEL_STATUSES, CATALOG_AUTH_TYPES, isoDate, semver, catalogModalitiesSchema, catalogCostSchema, catalogLimitSchema, catalogModelProviderSchema, catalogModelEntrySchema, catalogProviderSchema, curatedCatalogSchema, modelsCatalogRowInsertSchema, modelsCatalogRowSelectSchema;
14946
14940
  var init_catalog_schema = __esm({
14947
14941
  "packages/contracts/src/llm/catalog-schema.ts"() {
@@ -14954,78 +14948,78 @@ var init_catalog_schema = __esm({
14954
14948
  "retired"
14955
14949
  ];
14956
14950
  CATALOG_AUTH_TYPES = ["api_key", "oauth", "bedrock", "vertex"];
14957
- isoDate = z13.string().regex(/^\d{4}-\d{2}-\d{2}$/, "must be an ISO date (YYYY-MM-DD)");
14958
- semver = z13.string().regex(/^\d+\.\d+\.\d+$/, "must be semver (MAJOR.MINOR.PATCH)");
14959
- catalogModalitiesSchema = z13.object({
14960
- input: z13.array(z13.string()),
14961
- output: z13.array(z13.string())
14951
+ isoDate = z12.string().regex(/^\d{4}-\d{2}-\d{2}$/, "must be an ISO date (YYYY-MM-DD)");
14952
+ semver = z12.string().regex(/^\d+\.\d+\.\d+$/, "must be semver (MAJOR.MINOR.PATCH)");
14953
+ catalogModalitiesSchema = z12.object({
14954
+ input: z12.array(z12.string()),
14955
+ output: z12.array(z12.string())
14962
14956
  }).strict();
14963
- catalogCostSchema = z13.object({
14964
- input: z13.number().optional(),
14965
- output: z13.number().optional(),
14966
- cache_read: z13.number().optional(),
14967
- cache_write: z13.number().optional(),
14968
- context_over_200k: z13.number().optional()
14957
+ catalogCostSchema = z12.object({
14958
+ input: z12.number().optional(),
14959
+ output: z12.number().optional(),
14960
+ cache_read: z12.number().optional(),
14961
+ cache_write: z12.number().optional(),
14962
+ context_over_200k: z12.number().optional()
14969
14963
  }).strict();
14970
- catalogLimitSchema = z13.object({
14971
- context: z13.number(),
14972
- output: z13.number()
14964
+ catalogLimitSchema = z12.object({
14965
+ context: z12.number(),
14966
+ output: z12.number()
14973
14967
  }).strict();
14974
- catalogModelProviderSchema = z13.object({
14975
- npm: z13.string(),
14976
- api: z13.string()
14968
+ catalogModelProviderSchema = z12.object({
14969
+ npm: z12.string(),
14970
+ api: z12.string()
14977
14971
  }).strict();
14978
- catalogModelEntrySchema = z13.object({
14979
- id: z13.string(),
14980
- name: z13.string(),
14981
- family: z13.string(),
14982
- attachment: z13.boolean(),
14983
- reasoning: z13.boolean(),
14984
- temperature: z13.boolean(),
14985
- interleaved: z13.boolean(),
14986
- tool_call: z13.boolean(),
14972
+ catalogModelEntrySchema = z12.object({
14973
+ id: z12.string(),
14974
+ name: z12.string(),
14975
+ family: z12.string(),
14976
+ attachment: z12.boolean(),
14977
+ reasoning: z12.boolean(),
14978
+ temperature: z12.boolean(),
14979
+ interleaved: z12.boolean(),
14980
+ tool_call: z12.boolean(),
14987
14981
  modalities: catalogModalitiesSchema,
14988
14982
  cost: catalogCostSchema,
14989
14983
  limit: catalogLimitSchema,
14990
- status: z13.enum(CATALOG_MODEL_STATUSES),
14984
+ status: z12.enum(CATALOG_MODEL_STATUSES),
14991
14985
  release_date: isoDate,
14992
14986
  provider: catalogModelProviderSchema
14993
14987
  }).strict();
14994
- catalogProviderSchema = z13.object({
14995
- id: z13.string(),
14996
- endpoint: z13.string(),
14997
- authTypes: z13.array(z13.enum(CATALOG_AUTH_TYPES)).min(1),
14998
- npm: z13.string().optional()
14988
+ catalogProviderSchema = z12.object({
14989
+ id: z12.string(),
14990
+ endpoint: z12.string(),
14991
+ authTypes: z12.array(z12.enum(CATALOG_AUTH_TYPES)).min(1),
14992
+ npm: z12.string().optional()
14999
14993
  }).strict();
15000
- curatedCatalogSchema = z13.object({
15001
- $schema: z13.string().optional(),
14994
+ curatedCatalogSchema = z12.object({
14995
+ $schema: z12.string().optional(),
15002
14996
  version: semver,
15003
14997
  lastUpdated: isoDate,
15004
- providers: z13.record(z13.string(), catalogProviderSchema),
15005
- models: z13.record(z13.string(), z13.record(z13.string(), catalogModelEntrySchema))
14998
+ providers: z12.record(z12.string(), catalogProviderSchema),
14999
+ models: z12.record(z12.string(), z12.record(z12.string(), catalogModelEntrySchema))
15006
15000
  }).strict();
15007
- modelsCatalogRowInsertSchema = z13.object({
15008
- id: z13.string(),
15009
- providerId: z13.string(),
15010
- name: z13.string(),
15011
- family: z13.string(),
15012
- attachment: z13.boolean(),
15013
- reasoning: z13.boolean(),
15014
- temperature: z13.boolean(),
15015
- interleaved: z13.boolean(),
15016
- toolCall: z13.boolean(),
15017
- modalities: z13.string(),
15018
- cost: z13.string(),
15019
- contextLimit: z13.number().nullable().optional(),
15020
- outputLimit: z13.number().nullable().optional(),
15021
- status: z13.enum(CATALOG_MODEL_STATUSES),
15001
+ modelsCatalogRowInsertSchema = z12.object({
15002
+ id: z12.string(),
15003
+ providerId: z12.string(),
15004
+ name: z12.string(),
15005
+ family: z12.string(),
15006
+ attachment: z12.boolean(),
15007
+ reasoning: z12.boolean(),
15008
+ temperature: z12.boolean(),
15009
+ interleaved: z12.boolean(),
15010
+ toolCall: z12.boolean(),
15011
+ modalities: z12.string(),
15012
+ cost: z12.string(),
15013
+ contextLimit: z12.number().nullable().optional(),
15014
+ outputLimit: z12.number().nullable().optional(),
15015
+ status: z12.enum(CATALOG_MODEL_STATUSES),
15022
15016
  releaseDate: isoDate,
15023
- modelsDevId: z13.string(),
15024
- source: z13.string(),
15025
- seededAt: z13.string().optional()
15017
+ modelsDevId: z12.string(),
15018
+ source: z12.string(),
15019
+ seededAt: z12.string().optional()
15026
15020
  }).strict();
15027
15021
  modelsCatalogRowSelectSchema = modelsCatalogRowInsertSchema.extend({
15028
- seededAt: z13.string()
15022
+ seededAt: z12.string()
15029
15023
  });
15030
15024
  }
15031
15025
  });
@@ -15140,7 +15134,7 @@ var init_status_registry = __esm({
15140
15134
  });
15141
15135
 
15142
15136
  // packages/contracts/src/workgraph.ts
15143
- import { z as z14 } from "zod";
15137
+ import { z as z13 } from "zod";
15144
15138
  var E_WORKGRAPH_PARENT_TYPE_MATRIX, taskTypeSchema, taskPrioritySchema, taskStatusSchema, verificationGateSchema, workGraphRelationKindSchema, workGraphTraversalDirectionSchema, workGraphEdgeDirectionSchema, paginationParamsSchema, workGraphNodeSchema, workGraphEdgeSchema, workGraphHierarchyEdgeSchema, workGraphPageInfoSchema, workGraphRollupCountsSchema, workGraphSubtreePercentagesSchema, workGraphProjectionMismatchSchema, workGraphReadyFrontierTaskSchema, workGraphRelationEdgeSchema, workGraphDependencyEdgeSchema, workGraphOmissionReasonSchema, workGraphContextBudgetSchema, workGraphOmissionSchema, workGraphDirectEdgeSchema, workGraphContextPackParamsSchema, workGraphSliceParamsSchema, workGraphSliceSchema, workGraphReadinessParamsSchema, workGraphReadinessResultSchema, workGraphContextPackSchema, workGraphScaffoldValidateParamsSchema, workGraphScaffoldValidationIssueSchema, workGraphScaffoldValidateResultSchema, workGraphScaffoldApplyParamsSchema, workGraphScaffoldApplyResultSchema, workGraphPlanningDocParamsSchema, workGraphPlanningDocSchema, tasksTraverseParamsSchema, tasksTraverseResultSchema, tasksTreeParamsSchema, tasksTreeResultSchema, tasksRollupParamsSchema, tasksRollupResultSchema, tasksFrontierParamsSchema, tasksFrontierResultSchema, tasksWorkGraphAuditParamsSchema, tasksWorkGraphAuditResultSchema;
15145
15139
  var init_workgraph = __esm({
15146
15140
  "packages/contracts/src/workgraph.ts"() {
@@ -15148,10 +15142,10 @@ var init_workgraph = __esm({
15148
15142
  init_enums();
15149
15143
  init_status_registry();
15150
15144
  E_WORKGRAPH_PARENT_TYPE_MATRIX = "E_WORKGRAPH_PARENT_TYPE_MATRIX";
15151
- taskTypeSchema = z14.enum(["saga", "epic", "task", "subtask"]);
15152
- taskPrioritySchema = z14.enum(["critical", "high", "medium", "low"]);
15153
- taskStatusSchema = z14.enum(TASK_STATUSES);
15154
- verificationGateSchema = z14.enum([
15145
+ taskTypeSchema = z13.enum(["saga", "epic", "task", "subtask"]);
15146
+ taskPrioritySchema = z13.enum(["critical", "high", "medium", "low"]);
15147
+ taskStatusSchema = z13.enum(TASK_STATUSES);
15148
+ verificationGateSchema = z13.enum([
15155
15149
  "implemented",
15156
15150
  "testsPassed",
15157
15151
  "qaPassed",
@@ -15160,7 +15154,7 @@ var init_workgraph = __esm({
15160
15154
  "documented",
15161
15155
  "nexusImpact"
15162
15156
  ]);
15163
- workGraphRelationKindSchema = z14.enum([
15157
+ workGraphRelationKindSchema = z13.enum([
15164
15158
  "contains",
15165
15159
  "depends_on",
15166
15160
  "blocks",
@@ -15168,317 +15162,317 @@ var init_workgraph = __esm({
15168
15162
  "groups",
15169
15163
  "satisfies"
15170
15164
  ]);
15171
- workGraphTraversalDirectionSchema = z14.enum([
15165
+ workGraphTraversalDirectionSchema = z13.enum([
15172
15166
  "ancestors",
15173
15167
  "descendants",
15174
15168
  "upstream",
15175
15169
  "downstream"
15176
15170
  ]);
15177
- workGraphEdgeDirectionSchema = z14.enum(["out", "in", "both"]);
15178
- paginationParamsSchema = z14.object({
15179
- cursor: z14.string().min(1).optional(),
15180
- limit: z14.number().int().positive().max(500).optional()
15171
+ workGraphEdgeDirectionSchema = z13.enum(["out", "in", "both"]);
15172
+ paginationParamsSchema = z13.object({
15173
+ cursor: z13.string().min(1).optional(),
15174
+ limit: z13.number().int().positive().max(500).optional()
15181
15175
  });
15182
- workGraphNodeSchema = z14.object({
15183
- id: z14.string().min(1),
15176
+ workGraphNodeSchema = z13.object({
15177
+ id: z13.string().min(1),
15184
15178
  type: taskTypeSchema,
15185
- title: z14.string(),
15179
+ title: z13.string(),
15186
15180
  status: taskStatusSchema,
15187
15181
  priority: taskPrioritySchema,
15188
- parentId: z14.string().min(1).optional()
15182
+ parentId: z13.string().min(1).optional()
15189
15183
  });
15190
- workGraphEdgeSchema = z14.object({
15191
- fromId: z14.string().min(1),
15192
- toId: z14.string().min(1),
15184
+ workGraphEdgeSchema = z13.object({
15185
+ fromId: z13.string().min(1),
15186
+ toId: z13.string().min(1),
15193
15187
  kind: workGraphRelationKindSchema
15194
15188
  });
15195
- workGraphHierarchyEdgeSchema = z14.object({
15196
- fromId: z14.string().min(1),
15197
- toId: z14.string().min(1),
15198
- kind: z14.literal("contains")
15189
+ workGraphHierarchyEdgeSchema = z13.object({
15190
+ fromId: z13.string().min(1),
15191
+ toId: z13.string().min(1),
15192
+ kind: z13.literal("contains")
15199
15193
  }).strict();
15200
- workGraphPageInfoSchema = z14.object({
15201
- nextCursor: z14.string().min(1).optional(),
15202
- hasMore: z14.boolean()
15203
- });
15204
- workGraphRollupCountsSchema = z14.object({
15205
- total: z14.number().int().nonnegative(),
15206
- byStatus: z14.partialRecord(taskStatusSchema, z14.number().int().nonnegative()),
15207
- byType: z14.partialRecord(taskTypeSchema, z14.number().int().nonnegative())
15208
- });
15209
- workGraphSubtreePercentagesSchema = z14.object({
15210
- done: z14.number().nonnegative(),
15211
- active: z14.number().nonnegative(),
15212
- blocked: z14.number().nonnegative(),
15213
- pending: z14.number().nonnegative(),
15214
- cancelled: z14.number().nonnegative()
15215
- });
15216
- workGraphProjectionMismatchSchema = z14.object({
15217
- field: z14.string().min(1),
15218
- expected: z14.number().int().nonnegative(),
15219
- actual: z14.number().int().nonnegative()
15194
+ workGraphPageInfoSchema = z13.object({
15195
+ nextCursor: z13.string().min(1).optional(),
15196
+ hasMore: z13.boolean()
15197
+ });
15198
+ workGraphRollupCountsSchema = z13.object({
15199
+ total: z13.number().int().nonnegative(),
15200
+ byStatus: z13.partialRecord(taskStatusSchema, z13.number().int().nonnegative()),
15201
+ byType: z13.partialRecord(taskTypeSchema, z13.number().int().nonnegative())
15202
+ });
15203
+ workGraphSubtreePercentagesSchema = z13.object({
15204
+ done: z13.number().nonnegative(),
15205
+ active: z13.number().nonnegative(),
15206
+ blocked: z13.number().nonnegative(),
15207
+ pending: z13.number().nonnegative(),
15208
+ cancelled: z13.number().nonnegative()
15209
+ });
15210
+ workGraphProjectionMismatchSchema = z13.object({
15211
+ field: z13.string().min(1),
15212
+ expected: z13.number().int().nonnegative(),
15213
+ actual: z13.number().int().nonnegative()
15220
15214
  });
15221
15215
  workGraphReadyFrontierTaskSchema = workGraphNodeSchema.extend({
15222
- role: z14.string().min(1).optional(),
15223
- dependencyBlockers: z14.array(z14.object({ taskId: z14.string().min(1), status: taskStatusSchema })),
15224
- gateBlockers: z14.array(z14.object({ gate: verificationGateSchema }))
15216
+ role: z13.string().min(1).optional(),
15217
+ dependencyBlockers: z13.array(z13.object({ taskId: z13.string().min(1), status: taskStatusSchema })),
15218
+ gateBlockers: z13.array(z13.object({ gate: verificationGateSchema }))
15225
15219
  });
15226
15220
  workGraphRelationEdgeSchema = workGraphEdgeSchema.extend({
15227
- source: z14.literal("relation"),
15228
- relationType: z14.enum(TASK_RELATION_TYPES),
15229
- reason: z14.string().min(1).optional()
15221
+ source: z13.literal("relation"),
15222
+ relationType: z13.enum(TASK_RELATION_TYPES),
15223
+ reason: z13.string().min(1).optional()
15230
15224
  });
15231
15225
  workGraphDependencyEdgeSchema = workGraphEdgeSchema.extend({
15232
- source: z14.literal("dependency"),
15233
- kind: z14.literal("depends_on")
15226
+ source: z13.literal("dependency"),
15227
+ kind: z13.literal("depends_on")
15234
15228
  });
15235
- workGraphOmissionReasonSchema = z14.enum([
15229
+ workGraphOmissionReasonSchema = z13.enum([
15236
15230
  "budget_exceeded",
15237
15231
  "not_requested",
15238
15232
  "not_available",
15239
15233
  "redacted",
15240
15234
  "truncated"
15241
15235
  ]);
15242
- workGraphContextBudgetSchema = z14.object({
15243
- tokenBudget: z14.number().int().nonnegative(),
15244
- estimatedTokens: z14.number().int().nonnegative(),
15245
- remainingTokens: z14.number().int().nonnegative(),
15246
- truncated: z14.boolean()
15247
- });
15248
- workGraphOmissionSchema = z14.object({
15249
- path: z14.string().min(1),
15236
+ workGraphContextBudgetSchema = z13.object({
15237
+ tokenBudget: z13.number().int().nonnegative(),
15238
+ estimatedTokens: z13.number().int().nonnegative(),
15239
+ remainingTokens: z13.number().int().nonnegative(),
15240
+ truncated: z13.boolean()
15241
+ });
15242
+ workGraphOmissionSchema = z13.object({
15243
+ path: z13.string().min(1),
15250
15244
  reason: workGraphOmissionReasonSchema,
15251
- message: z14.string().min(1),
15252
- estimatedTokens: z14.number().int().nonnegative().optional()
15245
+ message: z13.string().min(1),
15246
+ estimatedTokens: z13.number().int().nonnegative().optional()
15253
15247
  });
15254
- workGraphDirectEdgeSchema = z14.discriminatedUnion("source", [
15248
+ workGraphDirectEdgeSchema = z13.discriminatedUnion("source", [
15255
15249
  workGraphRelationEdgeSchema,
15256
15250
  workGraphDependencyEdgeSchema
15257
15251
  ]);
15258
15252
  workGraphContextPackParamsSchema = paginationParamsSchema.extend({
15259
- rootId: z14.string().min(1),
15260
- tokenBudget: z14.number().int().positive().optional(),
15261
- includeRelations: z14.boolean().optional(),
15262
- includeReadiness: z14.boolean().optional(),
15263
- includeRollup: z14.boolean().optional()
15253
+ rootId: z13.string().min(1),
15254
+ tokenBudget: z13.number().int().positive().optional(),
15255
+ includeRelations: z13.boolean().optional(),
15256
+ includeReadiness: z13.boolean().optional(),
15257
+ includeRollup: z13.boolean().optional()
15264
15258
  });
15265
15259
  workGraphSliceParamsSchema = paginationParamsSchema.extend({
15266
- rootId: z14.string().min(1),
15260
+ rootId: z13.string().min(1),
15267
15261
  direction: workGraphTraversalDirectionSchema.optional(),
15268
- maxDepth: z14.number().int().nonnegative().optional(),
15269
- includeRelations: z14.boolean().optional()
15262
+ maxDepth: z13.number().int().nonnegative().optional(),
15263
+ includeRelations: z13.boolean().optional()
15270
15264
  });
15271
- workGraphSliceSchema = z14.object({
15272
- rootId: z14.string().min(1),
15265
+ workGraphSliceSchema = z13.object({
15266
+ rootId: z13.string().min(1),
15273
15267
  direction: workGraphTraversalDirectionSchema,
15274
- nodes: z14.array(workGraphNodeSchema),
15275
- edges: z14.array(workGraphEdgeSchema),
15268
+ nodes: z13.array(workGraphNodeSchema),
15269
+ edges: z13.array(workGraphEdgeSchema),
15276
15270
  pageInfo: workGraphPageInfoSchema,
15277
- omissions: z14.array(workGraphOmissionSchema).optional()
15278
- });
15279
- workGraphReadinessParamsSchema = z14.object({
15280
- rootId: z14.string().min(1),
15281
- role: z14.string().min(1).optional(),
15282
- includeGateBlockers: z14.boolean().optional()
15283
- });
15284
- workGraphReadinessResultSchema = z14.object({
15285
- rootId: z14.string().min(1),
15286
- role: z14.string().min(1).optional(),
15287
- ready: z14.boolean(),
15288
- warnings: z14.array(z14.string()),
15289
- groups: z14.object({
15290
- ready: z14.array(workGraphReadyFrontierTaskSchema),
15291
- blocked: z14.array(workGraphReadyFrontierTaskSchema),
15292
- blockedBy: z14.array(
15293
- z14.discriminatedUnion("kind", [
15294
- z14.object({
15295
- kind: z14.literal("dependency"),
15296
- blockerId: z14.string().min(1),
15297
- blocks: z14.array(z14.string().min(1))
15271
+ omissions: z13.array(workGraphOmissionSchema).optional()
15272
+ });
15273
+ workGraphReadinessParamsSchema = z13.object({
15274
+ rootId: z13.string().min(1),
15275
+ role: z13.string().min(1).optional(),
15276
+ includeGateBlockers: z13.boolean().optional()
15277
+ });
15278
+ workGraphReadinessResultSchema = z13.object({
15279
+ rootId: z13.string().min(1),
15280
+ role: z13.string().min(1).optional(),
15281
+ ready: z13.boolean(),
15282
+ warnings: z13.array(z13.string()),
15283
+ groups: z13.object({
15284
+ ready: z13.array(workGraphReadyFrontierTaskSchema),
15285
+ blocked: z13.array(workGraphReadyFrontierTaskSchema),
15286
+ blockedBy: z13.array(
15287
+ z13.discriminatedUnion("kind", [
15288
+ z13.object({
15289
+ kind: z13.literal("dependency"),
15290
+ blockerId: z13.string().min(1),
15291
+ blocks: z13.array(z13.string().min(1))
15298
15292
  }),
15299
- z14.object({
15300
- kind: z14.literal("gate"),
15293
+ z13.object({
15294
+ kind: z13.literal("gate"),
15301
15295
  gate: verificationGateSchema,
15302
- blocks: z14.array(z14.string().min(1))
15296
+ blocks: z13.array(z13.string().min(1))
15303
15297
  })
15304
15298
  ])
15305
15299
  )
15306
15300
  })
15307
15301
  });
15308
- workGraphContextPackSchema = z14.object({
15309
- rootId: z14.string().min(1),
15310
- generatedAt: z14.string().min(1),
15302
+ workGraphContextPackSchema = z13.object({
15303
+ rootId: z13.string().min(1),
15304
+ generatedAt: z13.string().min(1),
15311
15305
  budget: workGraphContextBudgetSchema,
15312
15306
  slice: workGraphSliceSchema,
15313
- relationEdges: z14.object({
15314
- rootId: z14.string().min(1),
15307
+ relationEdges: z13.object({
15308
+ rootId: z13.string().min(1),
15315
15309
  direction: workGraphEdgeDirectionSchema,
15316
- edges: z14.array(workGraphDirectEdgeSchema)
15310
+ edges: z13.array(workGraphDirectEdgeSchema)
15317
15311
  }).optional(),
15318
15312
  readiness: workGraphReadinessResultSchema.optional(),
15319
- rollup: z14.lazy(() => tasksRollupResultSchema).optional(),
15320
- omissions: z14.array(workGraphOmissionSchema)
15321
- });
15322
- workGraphScaffoldValidateParamsSchema = z14.object({
15323
- rootId: z14.string().min(1),
15324
- nodes: z14.array(
15325
- z14.object({
15326
- id: z14.string().min(1),
15313
+ rollup: z13.lazy(() => tasksRollupResultSchema).optional(),
15314
+ omissions: z13.array(workGraphOmissionSchema)
15315
+ });
15316
+ workGraphScaffoldValidateParamsSchema = z13.object({
15317
+ rootId: z13.string().min(1),
15318
+ nodes: z13.array(
15319
+ z13.object({
15320
+ id: z13.string().min(1),
15327
15321
  type: taskTypeSchema,
15328
- parentId: z14.string().min(1).nullable().optional()
15322
+ parentId: z13.string().min(1).nullable().optional()
15329
15323
  })
15330
15324
  ),
15331
- edges: z14.array(workGraphDirectEdgeSchema).optional(),
15332
- dryRun: z14.boolean().optional()
15333
- });
15334
- workGraphScaffoldValidationIssueSchema = z14.object({
15335
- code: z14.string().min(1),
15336
- message: z14.string().min(1),
15337
- taskId: z14.string().min(1).optional(),
15338
- severity: z14.enum(["error", "warning"])
15339
- });
15340
- workGraphScaffoldValidateResultSchema = z14.object({
15341
- rootId: z14.string().min(1),
15342
- valid: z14.boolean(),
15343
- dryRun: z14.boolean(),
15344
- issues: z14.array(workGraphScaffoldValidationIssueSchema),
15345
- hierarchy: z14.object({
15346
- valid: z14.boolean(),
15347
- violations: z14.array(
15348
- z14.object({
15349
- code: z14.literal(E_WORKGRAPH_PARENT_TYPE_MATRIX),
15350
- taskId: z14.string().min(1),
15325
+ edges: z13.array(workGraphDirectEdgeSchema).optional(),
15326
+ dryRun: z13.boolean().optional()
15327
+ });
15328
+ workGraphScaffoldValidationIssueSchema = z13.object({
15329
+ code: z13.string().min(1),
15330
+ message: z13.string().min(1),
15331
+ taskId: z13.string().min(1).optional(),
15332
+ severity: z13.enum(["error", "warning"])
15333
+ });
15334
+ workGraphScaffoldValidateResultSchema = z13.object({
15335
+ rootId: z13.string().min(1),
15336
+ valid: z13.boolean(),
15337
+ dryRun: z13.boolean(),
15338
+ issues: z13.array(workGraphScaffoldValidationIssueSchema),
15339
+ hierarchy: z13.object({
15340
+ valid: z13.boolean(),
15341
+ violations: z13.array(
15342
+ z13.object({
15343
+ code: z13.literal(E_WORKGRAPH_PARENT_TYPE_MATRIX),
15344
+ taskId: z13.string().min(1),
15351
15345
  taskType: taskTypeSchema,
15352
- parentId: z14.string().min(1).nullable(),
15346
+ parentId: z13.string().min(1).nullable(),
15353
15347
  parentType: taskTypeSchema.optional(),
15354
- message: z14.string().min(1)
15348
+ message: z13.string().min(1)
15355
15349
  })
15356
15350
  )
15357
15351
  })
15358
15352
  });
15359
15353
  workGraphScaffoldApplyParamsSchema = workGraphScaffoldValidateParamsSchema.extend({
15360
- apply: z14.boolean().optional()
15354
+ apply: z13.boolean().optional()
15361
15355
  });
15362
15356
  workGraphScaffoldApplyResultSchema = workGraphScaffoldValidateResultSchema.extend({
15363
- applied: z14.boolean(),
15364
- nodesChanged: z14.number().int().nonnegative(),
15365
- edgesChanged: z14.number().int().nonnegative()
15366
- });
15367
- workGraphPlanningDocParamsSchema = z14.object({
15368
- rootId: z14.string().min(1),
15369
- audience: z14.enum(["agent", "maintainer"]),
15370
- tokenBudget: z14.number().int().positive().optional(),
15371
- includeRelations: z14.boolean().optional(),
15372
- includeReadiness: z14.boolean().optional(),
15373
- includeRollup: z14.boolean().optional()
15374
- });
15375
- workGraphPlanningDocSchema = z14.object({
15376
- rootId: z14.string().min(1),
15377
- generatedAt: z14.string().min(1),
15378
- audience: z14.enum(["agent", "maintainer"]),
15379
- title: z14.string().min(1),
15380
- content: z14.string(),
15381
- sections: z14.array(z14.string().min(1)),
15382
- estimatedTokens: z14.number().int().nonnegative(),
15383
- budget: z14.object({
15384
- tokenBudget: z14.number().int().positive(),
15385
- truncated: z14.boolean()
15357
+ applied: z13.boolean(),
15358
+ nodesChanged: z13.number().int().nonnegative(),
15359
+ edgesChanged: z13.number().int().nonnegative()
15360
+ });
15361
+ workGraphPlanningDocParamsSchema = z13.object({
15362
+ rootId: z13.string().min(1),
15363
+ audience: z13.enum(["agent", "maintainer"]),
15364
+ tokenBudget: z13.number().int().positive().optional(),
15365
+ includeRelations: z13.boolean().optional(),
15366
+ includeReadiness: z13.boolean().optional(),
15367
+ includeRollup: z13.boolean().optional()
15368
+ });
15369
+ workGraphPlanningDocSchema = z13.object({
15370
+ rootId: z13.string().min(1),
15371
+ generatedAt: z13.string().min(1),
15372
+ audience: z13.enum(["agent", "maintainer"]),
15373
+ title: z13.string().min(1),
15374
+ content: z13.string(),
15375
+ sections: z13.array(z13.string().min(1)),
15376
+ estimatedTokens: z13.number().int().nonnegative(),
15377
+ budget: z13.object({
15378
+ tokenBudget: z13.number().int().positive(),
15379
+ truncated: z13.boolean()
15386
15380
  }).optional()
15387
15381
  });
15388
15382
  tasksTraverseParamsSchema = paginationParamsSchema.extend({
15389
- rootId: z14.string().min(1),
15383
+ rootId: z13.string().min(1),
15390
15384
  direction: workGraphTraversalDirectionSchema,
15391
- maxDepth: z14.number().int().nonnegative().optional(),
15392
- includeRelations: z14.boolean().optional()
15385
+ maxDepth: z13.number().int().nonnegative().optional(),
15386
+ includeRelations: z13.boolean().optional()
15393
15387
  });
15394
- tasksTraverseResultSchema = z14.object({
15395
- rootId: z14.string().min(1),
15388
+ tasksTraverseResultSchema = z13.object({
15389
+ rootId: z13.string().min(1),
15396
15390
  direction: workGraphTraversalDirectionSchema,
15397
- nodes: z14.array(workGraphNodeSchema),
15398
- edges: z14.array(workGraphEdgeSchema),
15391
+ nodes: z13.array(workGraphNodeSchema),
15392
+ edges: z13.array(workGraphEdgeSchema),
15399
15393
  pageInfo: workGraphPageInfoSchema
15400
15394
  });
15401
15395
  tasksTreeParamsSchema = paginationParamsSchema.extend({
15402
- rootId: z14.string().min(1),
15403
- maxDepth: z14.number().int().nonnegative().optional()
15396
+ rootId: z13.string().min(1),
15397
+ maxDepth: z13.number().int().nonnegative().optional()
15404
15398
  });
15405
- tasksTreeResultSchema = z14.object({
15406
- rootId: z14.string().min(1),
15407
- nodes: z14.array(workGraphNodeSchema.extend({ depth: z14.number().int().positive() })),
15408
- edges: z14.array(workGraphHierarchyEdgeSchema),
15399
+ tasksTreeResultSchema = z13.object({
15400
+ rootId: z13.string().min(1),
15401
+ nodes: z13.array(workGraphNodeSchema.extend({ depth: z13.number().int().positive() })),
15402
+ edges: z13.array(workGraphHierarchyEdgeSchema),
15409
15403
  pageInfo: workGraphPageInfoSchema
15410
15404
  });
15411
- tasksRollupParamsSchema = z14.object({
15412
- rootId: z14.string().min(1),
15405
+ tasksRollupParamsSchema = z13.object({
15406
+ rootId: z13.string().min(1),
15413
15407
  expectedDirectRollup: workGraphRollupCountsSchema.optional()
15414
15408
  });
15415
- tasksRollupResultSchema = z14.object({
15416
- rootId: z14.string().min(1),
15409
+ tasksRollupResultSchema = z13.object({
15410
+ rootId: z13.string().min(1),
15417
15411
  direct: workGraphRollupCountsSchema,
15418
15412
  subtree: workGraphRollupCountsSchema,
15419
- percentDenominator: z14.object({
15420
- basis: z14.literal("subtree-total"),
15421
- total: z14.number().int().nonnegative(),
15422
- description: z14.string().min(1)
15413
+ percentDenominator: z13.object({
15414
+ basis: z13.literal("subtree-total"),
15415
+ total: z13.number().int().nonnegative(),
15416
+ description: z13.string().min(1)
15423
15417
  }),
15424
15418
  percentages: workGraphSubtreePercentagesSchema,
15425
- staleProjection: z14.boolean(),
15426
- projectionMismatches: z14.array(workGraphProjectionMismatchSchema)
15427
- });
15428
- tasksFrontierParamsSchema = z14.object({
15429
- rootId: z14.string().min(1),
15430
- role: z14.string().min(1).optional()
15431
- });
15432
- tasksFrontierResultSchema = z14.object({
15433
- rootId: z14.string().min(1),
15434
- role: z14.string().min(1).optional(),
15435
- groups: z14.object({
15436
- ready: z14.array(workGraphReadyFrontierTaskSchema),
15437
- blocked: z14.array(workGraphReadyFrontierTaskSchema),
15438
- blockedBy: z14.array(
15439
- z14.discriminatedUnion("kind", [
15440
- z14.object({
15441
- kind: z14.literal("dependency"),
15442
- blockerId: z14.string().min(1),
15443
- blocks: z14.array(z14.string().min(1))
15419
+ staleProjection: z13.boolean(),
15420
+ projectionMismatches: z13.array(workGraphProjectionMismatchSchema)
15421
+ });
15422
+ tasksFrontierParamsSchema = z13.object({
15423
+ rootId: z13.string().min(1),
15424
+ role: z13.string().min(1).optional()
15425
+ });
15426
+ tasksFrontierResultSchema = z13.object({
15427
+ rootId: z13.string().min(1),
15428
+ role: z13.string().min(1).optional(),
15429
+ groups: z13.object({
15430
+ ready: z13.array(workGraphReadyFrontierTaskSchema),
15431
+ blocked: z13.array(workGraphReadyFrontierTaskSchema),
15432
+ blockedBy: z13.array(
15433
+ z13.discriminatedUnion("kind", [
15434
+ z13.object({
15435
+ kind: z13.literal("dependency"),
15436
+ blockerId: z13.string().min(1),
15437
+ blocks: z13.array(z13.string().min(1))
15444
15438
  }),
15445
- z14.object({
15446
- kind: z14.literal("gate"),
15439
+ z13.object({
15440
+ kind: z13.literal("gate"),
15447
15441
  gate: verificationGateSchema,
15448
- blocks: z14.array(z14.string().min(1))
15442
+ blocks: z13.array(z13.string().min(1))
15449
15443
  })
15450
15444
  ])
15451
15445
  )
15452
15446
  })
15453
15447
  });
15454
15448
  tasksWorkGraphAuditParamsSchema = paginationParamsSchema.extend({
15455
- rootId: z14.string().min(1),
15456
- maxDepth: z14.number().int().nonnegative().optional(),
15457
- includeRelations: z14.boolean().optional()
15458
- });
15459
- tasksWorkGraphAuditResultSchema = z14.object({
15460
- rootId: z14.string().min(1),
15461
- hierarchy: z14.object({
15462
- valid: z14.boolean(),
15463
- violations: z14.array(
15464
- z14.object({
15465
- code: z14.literal(E_WORKGRAPH_PARENT_TYPE_MATRIX),
15466
- taskId: z14.string().min(1),
15449
+ rootId: z13.string().min(1),
15450
+ maxDepth: z13.number().int().nonnegative().optional(),
15451
+ includeRelations: z13.boolean().optional()
15452
+ });
15453
+ tasksWorkGraphAuditResultSchema = z13.object({
15454
+ rootId: z13.string().min(1),
15455
+ hierarchy: z13.object({
15456
+ valid: z13.boolean(),
15457
+ violations: z13.array(
15458
+ z13.object({
15459
+ code: z13.literal(E_WORKGRAPH_PARENT_TYPE_MATRIX),
15460
+ taskId: z13.string().min(1),
15467
15461
  taskType: taskTypeSchema,
15468
- parentId: z14.string().min(1).nullable(),
15462
+ parentId: z13.string().min(1).nullable(),
15469
15463
  parentType: taskTypeSchema.optional(),
15470
- message: z14.string().min(1)
15464
+ message: z13.string().min(1)
15471
15465
  })
15472
15466
  )
15473
15467
  }),
15474
15468
  traversal: tasksTraverseResultSchema,
15475
15469
  frontier: tasksFrontierResultSchema,
15476
15470
  rollup: tasksRollupResultSchema,
15477
- relationEdges: z14.object({
15478
- rootId: z14.string().min(1),
15471
+ relationEdges: z13.object({
15472
+ rootId: z13.string().min(1),
15479
15473
  direction: workGraphEdgeDirectionSchema,
15480
- edges: z14.array(
15481
- z14.discriminatedUnion("source", [
15474
+ edges: z13.array(
15475
+ z13.discriminatedUnion("source", [
15482
15476
  workGraphRelationEdgeSchema,
15483
15477
  workGraphDependencyEdgeSchema
15484
15478
  ])
@@ -15497,6 +15491,51 @@ var init_operation_envelope_validation = __esm({
15497
15491
  }
15498
15492
  });
15499
15493
 
15494
+ // packages/contracts/src/operations/docs.ts
15495
+ import { z as z14 } from "zod";
15496
+ var DOCS_PROJECTION_PROPOSAL_SCHEMA, DOCS_PROJECTION_RECEIPT_SCHEMA;
15497
+ var init_docs = __esm({
15498
+ "packages/contracts/src/operations/docs.ts"() {
15499
+ "use strict";
15500
+ init_docs_taxonomy();
15501
+ init_docs_lifecycle();
15502
+ DOCS_PROJECTION_PROPOSAL_SCHEMA = z14.object({
15503
+ version: z14.literal(1),
15504
+ operation: z14.literal("docs.projection"),
15505
+ identity: z14.object({
15506
+ projectId: z14.string().min(1),
15507
+ projectRoot: z14.string().min(1),
15508
+ actor: z14.string().min(1),
15509
+ operation: z14.literal("docs.projection"),
15510
+ idempotencyKey: z14.string().min(1)
15511
+ }).strict(),
15512
+ source: z14.object({
15513
+ attachmentId: z14.string().min(1),
15514
+ sha256: z14.string().regex(/^[a-f0-9]{64}$/),
15515
+ ownerId: z14.string().min(1),
15516
+ ownerType: z14.enum(["task", "session", "observation", "decision", "learning", "pattern"]),
15517
+ label: z14.string().min(1)
15518
+ }).strict(),
15519
+ observation: z14.object({
15520
+ kind: z14.literal("doc-attachment"),
15521
+ attachmentId: z14.string().min(1),
15522
+ ownerId: z14.string().min(1),
15523
+ addedAt: z14.string().min(1),
15524
+ slug: z14.string().optional(),
15525
+ type: z14.string().optional()
15526
+ }).strict()
15527
+ }).strict();
15528
+ DOCS_PROJECTION_RECEIPT_SCHEMA = z14.object({
15529
+ version: z14.literal(1),
15530
+ sourceHash: z14.string().regex(/^[a-f0-9]{64}$/),
15531
+ graph: z14.enum(["completed", "disabled"]),
15532
+ observationId: z14.string().min(1),
15533
+ verifiedAt: z14.string().min(1),
15534
+ actor: z14.string().min(1)
15535
+ }).strict();
15536
+ }
15537
+ });
15538
+
15500
15539
  // packages/contracts/src/operations/ensures-schema-registry.ts
15501
15540
  import { z as z15 } from "zod";
15502
15541
  var taskTreeEntrySchema, taskTreeSchema, evidenceSchema, passthroughSchema, LEGACY_PASSTHROUGH_SCHEMA_NAMES, ENSURES_SCHEMA_REGISTRY;
@@ -15866,11 +15905,7 @@ var init_evidence_atoms = __esm({
15866
15905
  }).passthrough()
15867
15906
  ).optional().default([])
15868
15907
  }).passthrough();
15869
- PR_REQUIRED_WORKFLOWS = Object.freeze([
15870
- "CI",
15871
- "Lockfile Check",
15872
- "Contracts Dep Lint"
15873
- ]);
15908
+ PR_REQUIRED_WORKFLOWS = Object.freeze(["CI", "Contracts Dep Lint"]);
15874
15909
  }
15875
15910
  });
15876
15911
 
@@ -18162,6 +18197,11 @@ var init_nexus_cloud = __esm({
18162
18197
  nexusCloudStatusSchema = z26.object({
18163
18198
  serverTime: isoTime.optional(),
18164
18199
  apiVersion: z26.string().optional(),
18200
+ /**
18201
+ * Optional server features (e.g. {@link NEXUS_FEATURE_PROJECT_INITIAL_KEY}). Absent from servers older
18202
+ * than the list, which therefore support none of them.
18203
+ */
18204
+ features: z26.array(z26.string()).optional(),
18165
18205
  user: nexusCloudUserSchema,
18166
18206
  credential: nexusCloudCredentialSchema,
18167
18207
  device: nexusCloudDeviceSchema.nullable(),
@@ -44457,18 +44497,6 @@ function appendHookEntry(hooks, event, entry) {
44457
44497
  }
44458
44498
  hooks[event] = [...existing ?? [], entry];
44459
44499
  }
44460
- function removeCleoHookEntries(hooks) {
44461
- let changed = false;
44462
- for (const [event, entries] of Object.entries(hooks)) {
44463
- if (!Array.isArray(entries)) continue;
44464
- const kept = entries.filter((e) => !isCleoHookEntry(e));
44465
- if (kept.length !== entries.length) {
44466
- hooks[event] = kept;
44467
- changed = true;
44468
- }
44469
- }
44470
- return changed;
44471
- }
44472
44500
  var CLEO_HOOK_MARKER;
44473
44501
  var init_hook_config = __esm({
44474
44502
  "packages/adapters/src/providers/shared/hook-config.ts"() {
@@ -44477,513 +44505,24 @@ var init_hook_config = __esm({
44477
44505
  }
44478
44506
  });
44479
44507
 
44480
- // packages/adapters/src/providers/claude-code/paths.ts
44481
- import { homedir as homedir2 } from "node:os";
44482
- import { join as join3 } from "node:path";
44483
- function claudeSettingsPath() {
44484
- return new ClaudeCodePathProvider().getSettingsPath() ?? join3(homedir2(), ".claude", "settings.json");
44485
- }
44486
- var ClaudeCodePathProvider;
44487
- var init_paths = __esm({
44488
- "packages/adapters/src/providers/claude-code/paths.ts"() {
44489
- "use strict";
44490
- init_hook_config();
44491
- ClaudeCodePathProvider = class {
44492
- /** Get the provider's root configuration directory. */
44493
- getProviderDir() {
44494
- return process.env["CLAUDE_HOME"] ?? join3(homedir2(), ".claude");
44495
- }
44496
- /** Get the path to the provider's settings file, or null if unavailable. */
44497
- getSettingsPath() {
44498
- return process.env["CLAUDE_SETTINGS"] ?? join3(this.getProviderDir(), "settings.json");
44499
- }
44500
- /** Get the directory where agents are installed, or null if unsupported. */
44501
- getAgentInstallDir() {
44502
- return join3(this.getProviderDir(), "agents");
44503
- }
44504
- /** Get the path to the provider's memory database, or null if unsupported. */
44505
- getMemoryDbPath() {
44506
- return process.env["CLAUDE_MEM_DB"] ?? join3(homedir2(), ".claude-mem", "claude-mem.db");
44507
- }
44508
- };
44509
- }
44510
- });
44511
-
44512
- // packages/adapters/src/providers/claude-code/context-monitor.ts
44513
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync } from "node:fs";
44514
- import { mkdir } from "node:fs/promises";
44515
- import { homedir as homedir3 } from "node:os";
44516
- import { dirname, join as join4 } from "node:path";
44517
- import { resolveLegacyCleoDir } from "@cleocode/paths";
44518
- function getContextStatusFromPercentage(percentage) {
44519
- if (percentage >= THRESHOLDS.EMERGENCY) return "emergency";
44520
- if (percentage >= THRESHOLDS.CRITICAL) return "critical";
44521
- if (percentage >= THRESHOLDS.CAUTION) return "caution";
44522
- if (percentage >= THRESHOLDS.WARNING) return "warning";
44523
- return "ok";
44524
- }
44525
- var THRESHOLDS, ClaudeCodeContextMonitorProvider;
44526
- var init_context_monitor = __esm({
44527
- "packages/adapters/src/providers/claude-code/context-monitor.ts"() {
44528
- "use strict";
44529
- init_paths();
44530
- THRESHOLDS = {
44531
- WARNING: 50,
44532
- CAUTION: 70,
44533
- CRITICAL: 85,
44534
- EMERGENCY: 95
44535
- };
44536
- ClaudeCodeContextMonitorProvider = class {
44537
- /** Path provider for resolving Claude Code directory locations. */
44538
- pathProvider = new ClaudeCodePathProvider();
44539
- /** Process raw context window JSON and return a formatted summary string. */
44540
- async processContextInput(input, cwd) {
44541
- const typed = input;
44542
- const contextSize = typed.context_window?.context_window_size ?? 2e5;
44543
- const usage = typed.context_window?.current_usage;
44544
- if (!usage) return "-- no data";
44545
- const inputTokens = usage.input_tokens ?? 0;
44546
- const outputTokens = usage.output_tokens ?? 0;
44547
- const cacheCreate = usage.cache_creation_input_tokens ?? 0;
44548
- const totalTokens = inputTokens + outputTokens + cacheCreate;
44549
- const percentage = Math.floor(totalTokens * 100 / contextSize);
44550
- const status = getContextStatusFromPercentage(percentage);
44551
- const cleoDir = cwd ? join4(cwd, ".cleo") : ".cleo";
44552
- if (existsSync3(cleoDir)) {
44553
- const stateDir = join4(cleoDir, "context-states");
44554
- const statePath = join4(stateDir, ".context-state.json");
44555
- const state = {
44556
- $schema: "https://cleo-dev.com/schemas/v1/context-state.schema.json",
44557
- version: "1.0.0",
44558
- timestamp: (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z"),
44559
- staleAfterMs: 5e3,
44560
- contextWindow: {
44561
- maxTokens: contextSize,
44562
- currentTokens: totalTokens,
44563
- percentage,
44564
- breakdown: {
44565
- inputTokens,
44566
- outputTokens,
44567
- cacheCreationTokens: cacheCreate,
44568
- cacheReadTokens: usage.cache_read_input_tokens ?? 0
44569
- }
44570
- },
44571
- thresholds: {
44572
- warning: THRESHOLDS.WARNING,
44573
- caution: THRESHOLDS.CAUTION,
44574
- critical: THRESHOLDS.CRITICAL,
44575
- emergency: THRESHOLDS.EMERGENCY
44576
- },
44577
- status,
44578
- cleoSessionId: ""
44579
- };
44580
- try {
44581
- await mkdir(dirname(statePath), { recursive: true });
44582
- writeFileSync(statePath, JSON.stringify(state, null, 2));
44583
- } catch {
44584
- }
44585
- }
44586
- return `${percentage}% | ${totalTokens}/${contextSize}`;
44587
- }
44588
- /** Check the current statusline integration status in Claude Code settings. */
44589
- checkStatuslineIntegration() {
44590
- const settingsPath = this.pathProvider.getSettingsPath();
44591
- if (!settingsPath || !existsSync3(settingsPath)) return "no_settings";
44592
- try {
44593
- const settings = JSON.parse(readFileSync3(settingsPath, "utf-8"));
44594
- const statusLine = settings.statusLine;
44595
- if (!statusLine?.type) return "not_configured";
44596
- if (statusLine.type !== "command") return "custom_no_cleo";
44597
- const cmd = statusLine.command ?? "";
44598
- if (cmd.includes("context-monitor.sh") || cmd.includes("cleo-statusline") || cmd.includes(".context-state.json") || cmd.includes("context-states")) {
44599
- return "configured";
44600
- }
44601
- const scriptPath = cmd.startsWith("~") ? cmd.replace("~", homedir3()) : cmd;
44602
- if (existsSync3(scriptPath)) {
44603
- try {
44604
- const content = readFileSync3(scriptPath, "utf-8");
44605
- if (content.includes("context-state.json")) return "configured";
44606
- } catch {
44607
- }
44608
- }
44609
- return "custom_no_cleo";
44610
- } catch {
44611
- return "no_settings";
44612
- }
44613
- }
44614
- /** Get the recommended statusline configuration object for Claude Code settings. */
44615
- getStatuslineConfig() {
44616
- return {
44617
- statusLine: {
44618
- type: "command",
44619
- command: join4(resolveLegacyCleoDir(), "lib", "session", "context-monitor.sh")
44620
- }
44621
- };
44622
- }
44623
- /** Get human-readable setup instructions for enabling context monitoring. */
44624
- getSetupInstructions() {
44625
- const settingsPath = this.pathProvider.getSettingsPath() ?? "~/.claude/settings.json";
44626
- return [
44627
- "To enable context monitoring, add to your Claude Code settings:",
44628
- `File: ${settingsPath}`,
44629
- "",
44630
- JSON.stringify(this.getStatuslineConfig(), null, 2),
44631
- "",
44632
- "This enables real-time context window tracking in the CLI."
44633
- ].join("\n");
44634
- }
44635
- };
44636
- }
44637
- });
44638
-
44639
- // packages/adapters/src/providers/claude-code/hooks.ts
44640
- import { existsSync as existsSync4 } from "node:fs";
44641
- import { readdir, readFile } from "node:fs/promises";
44642
- import { join as join5 } from "node:path";
44643
- import { updateJsonConfigFile } from "@cleocode/caamp";
44644
- var PROVIDER_ID, CLAUDE_CODE_EVENT_MAP, ClaudeCodeHookProvider;
44645
- var init_hooks = __esm({
44646
- "packages/adapters/src/providers/claude-code/hooks.ts"() {
44647
- "use strict";
44648
- init_paths();
44649
- PROVIDER_ID = "claude-code";
44650
- CLAUDE_CODE_EVENT_MAP = {
44651
- // CAAMP: toNative('SessionStart', 'claude-code') = 'SessionStart'
44652
- SessionStart: "SessionStart",
44653
- // CAAMP: toNative('SessionEnd', 'claude-code') = 'SessionEnd'
44654
- SessionEnd: "SessionEnd",
44655
- // CAAMP: toNative('PromptSubmit', 'claude-code') = 'UserPromptSubmit'
44656
- UserPromptSubmit: "PromptSubmit",
44657
- // CAAMP: toNative('ResponseComplete', 'claude-code') = 'Stop'
44658
- Stop: "ResponseComplete",
44659
- // CAAMP: toNative('PreToolUse', 'claude-code') = 'PreToolUse'
44660
- PreToolUse: "PreToolUse",
44661
- // CAAMP: toNative('PostToolUse', 'claude-code') = 'PostToolUse'
44662
- PostToolUse: "PostToolUse",
44663
- // CAAMP: toNative('PostToolUseFailure','claude-code') = 'PostToolUseFailure'
44664
- PostToolUseFailure: "PostToolUseFailure",
44665
- // CAAMP: toNative('PermissionRequest', 'claude-code') = 'PermissionRequest'
44666
- PermissionRequest: "PermissionRequest",
44667
- // CAAMP: toNative('SubagentStart', 'claude-code') = 'SubagentStart'
44668
- SubagentStart: "SubagentStart",
44669
- // CAAMP: toNative('SubagentStop', 'claude-code') = 'SubagentStop'
44670
- SubagentStop: "SubagentStop",
44671
- // CAAMP: toNative('PreCompact', 'claude-code') = 'PreCompact'
44672
- PreCompact: "PreCompact",
44673
- // CAAMP: toNative('PostCompact', 'claude-code') = 'PostCompact'
44674
- PostCompact: "PostCompact",
44675
- // CAAMP: toNative('Notification', 'claude-code') = 'Notification'
44676
- Notification: "Notification",
44677
- // CAAMP: toNative('ConfigChange', 'claude-code') = 'ConfigChange'
44678
- ConfigChange: "ConfigChange"
44679
- };
44680
- ClaudeCodeHookProvider = class {
44681
- /** Whether hooks have been registered for the current session. */
44682
- registered = false;
44683
- /**
44684
- * Map a Claude Code native event name to a CAAMP canonical hook event name.
44685
- *
44686
- * Looks up the native event name in the map derived from
44687
- * `getProviderHookProfile('claude-code').mappings` (CAAMP 1.9.1).
44688
- * Returns null for unrecognised events (e.g. PreModel, PostModel which
44689
- * Claude Code does not support).
44690
- *
44691
- * @param providerEvent - Claude Code native event (e.g. "UserPromptSubmit", "Stop")
44692
- * @returns CAAMP canonical event name, or null if unmapped
44693
- * @task T164
44694
- */
44695
- mapProviderEvent(providerEvent) {
44696
- return CLAUDE_CODE_EVENT_MAP[providerEvent] ?? null;
44697
- }
44698
- /** Project directory this hook provider was registered for. */
44699
- projectDir = null;
44700
- /**
44701
- * Register native hooks for a project.
44702
- *
44703
- * Writes CLEO hook entries to `~/.claude/settings.json` so that Claude Code's
44704
- * native event system calls cleo CLI commands when events fire. This bridges
44705
- * Claude Code's event loop to CLEO's internal hook dispatch.
44706
- *
44707
- * Idempotent: skips writing if CLEO hooks already exist in settings.json.
44708
- *
44709
- * Hook entries registered:
44710
- * - `Stop` → `cleo session end --quiet` (triggers LLM extraction, reflector, consolidation)
44711
- * - `PostToolUse` (Write|Edit) → brain observation for file modifications
44712
- * - `SubagentStop` → brain observation for agent completion
44713
- *
44714
- * @param projectDir - Project directory for context-scoped hook commands
44715
- * @task T164 @task T555
44716
- */
44717
- async registerNativeHooks(projectDir) {
44718
- this.projectDir = projectDir;
44719
- this.registered = true;
44720
- await this.updateSettings((settings) => {
44721
- const hooks = hookMap(settings);
44722
- if (Object.values(hooks).some((entries) => hasCleoHook(entries))) {
44723
- return false;
44724
- }
44725
- appendHookEntry(hooks, "Stop", {
44726
- matcher: "",
44727
- hooks: [{ type: "command", command: `cleo session end --quiet # cleo-hook` }]
44728
- });
44729
- appendHookEntry(hooks, "PostToolUse", {
44730
- matcher: "Write|Edit",
44731
- hooks: [
44732
- {
44733
- type: "command",
44734
- command: `cleo observe "File modified via $TOOL_NAME" --title "tool-use" --quiet # cleo-hook`
44735
- },
44736
- {
44737
- // NEXUS post-modification check: re-index changed files and flag regressions.
44738
- // $TOOL_INPUT_file_path is populated by Claude Code for Write/Edit events.
44739
- type: "command",
44740
- command: `cleo nexus analyze --incremental --json > /dev/null 2>&1 && cleo observe "NEXUS re-indexed after $TOOL_NAME on $TOOL_INPUT_file_path" --title "nexus-post-check" --quiet # cleo-hook`
44741
- }
44742
- ]
44743
- });
44744
- return true;
44745
- });
44746
- }
44747
- /**
44748
- * Unregister native hooks.
44749
- *
44750
- * Removes CLEO hook entries from Claude Code's `settings.json` by filtering
44751
- * out entries containing the `# cleo-hook` marker. Same locking, atomicity
44752
- * and parse-error rules as {@link registerNativeHooks}.
44753
- *
44754
- * @task T164 @task T555
44755
- */
44756
- async unregisterNativeHooks() {
44757
- this.registered = false;
44758
- this.projectDir = null;
44759
- if (!existsSync4(claudeSettingsPath())) return;
44760
- await this.updateSettings((settings) => {
44761
- if (settings.hooks === void 0) return false;
44762
- return removeCleoHookEntries(hookMap(settings));
44763
- });
44764
- }
44765
- /** The last settings.json failure, or `null` when the last update succeeded. */
44766
- settingsError = null;
44767
- /**
44768
- * Why the last settings.json update did not happen, or `null`.
44769
- *
44770
- * @remarks
44771
- * Hook registration stays non-fatal for adapter initialisation, so a
44772
- * refused write (malformed settings.json, lock timeout) is surfaced here and
44773
- * on stderr instead of being swallowed (T12385).
44774
- *
44775
- * @returns The failure message, or `null`
44776
- */
44777
- getSettingsError() {
44778
- return this.settingsError;
44779
- }
44780
- /** Apply `mutate` to settings.json via CAAMP's locked, atomic JSON writer. */
44781
- async updateSettings(mutate) {
44782
- const settingsPath = claudeSettingsPath();
44783
- try {
44784
- await updateJsonConfigFile(settingsPath, mutate);
44785
- this.settingsError = null;
44786
- } catch (err) {
44787
- this.settingsError = err instanceof Error ? err.message : String(err);
44788
- process.stderr.write(
44789
- `[cleo:claude-code] hooks not written to ${settingsPath}: ${this.settingsError}
44790
- `
44791
- );
44792
- }
44793
- }
44794
- /**
44795
- * Check whether hooks have been registered via `registerNativeHooks`.
44796
- */
44797
- isRegistered() {
44798
- return this.registered;
44799
- }
44800
- /**
44801
- * Get the project directory this hook provider was registered for.
44802
- *
44803
- * Returns null if hooks have not been registered yet.
44804
- */
44805
- getProjectDir() {
44806
- return this.projectDir;
44807
- }
44808
- /**
44809
- * Get the native→canonical event mapping for introspection and debugging.
44810
- *
44811
- * Returns the map derived from `getProviderHookProfile('claude-code').mappings`
44812
- * (CAAMP 1.9.1). Use `getSupportedCanonicalEvents()` to enumerate canonical
44813
- * names via live CAAMP APIs.
44814
- *
44815
- * @returns Immutable record of native event name → canonical event name
44816
- */
44817
- getEventMap() {
44818
- return { ...CLAUDE_CODE_EVENT_MAP };
44819
- }
44820
- /**
44821
- * Enumerate supported canonical events via CAAMP's `getSupportedEvents()`.
44822
- *
44823
- * Calls `getSupportedEvents('claude-code')` from the CAAMP normalizer to
44824
- * get the authoritative list. Claude Code supports 14 of 16 canonical events
44825
- * (PreModel and PostModel are not supported). Falls back to the values of
44826
- * the static event map when CAAMP is unavailable at runtime.
44827
- *
44828
- * @returns Array of CAAMP canonical event names supported by Claude Code
44829
- * @task T164
44830
- */
44831
- async getSupportedCanonicalEvents() {
44832
- try {
44833
- const { getSupportedEvents } = await import("@cleocode/caamp");
44834
- return getSupportedEvents(PROVIDER_ID);
44835
- } catch {
44836
- return [...new Set(Object.values(CLAUDE_CODE_EVENT_MAP))];
44837
- }
44838
- }
44839
- /**
44840
- * Retrieve the full provider hook profile from CAAMP.
44841
- *
44842
- * Calls `getProviderHookProfile('claude-code')` from the CAAMP normalizer to
44843
- * get the complete profile: hook system type (`config`), config path
44844
- * (`~/.claude/settings.json`), handler types, and all event mappings.
44845
- * Returns null when CAAMP is unavailable at runtime.
44846
- *
44847
- * @returns Provider hook profile or null if CAAMP is unavailable
44848
- * @task T164
44849
- */
44850
- async getProviderProfile() {
44851
- try {
44852
- const { getProviderHookProfile } = await import("@cleocode/caamp");
44853
- return getProviderHookProfile(PROVIDER_ID) ?? null;
44854
- } catch {
44855
- return null;
44856
- }
44857
- }
44858
- /**
44859
- * Translate a CAAMP canonical event to its Claude Code native name via CAAMP.
44860
- *
44861
- * Calls `toNative(canonical, 'claude-code')` from the CAAMP normalizer.
44862
- * Returns null for unsupported events (PreModel, PostModel) or when
44863
- * CAAMP is unavailable.
44864
- *
44865
- * @param canonical - CAAMP canonical event name (e.g. "PromptSubmit")
44866
- * @returns Claude Code native event name or null
44867
- * @task T164
44868
- */
44869
- async toNativeEvent(canonical2) {
44870
- try {
44871
- const { toNative } = await import("@cleocode/caamp");
44872
- return toNative(canonical2, PROVIDER_ID);
44873
- } catch {
44874
- const entry = Object.entries(CLAUDE_CODE_EVENT_MAP).find(([, v]) => v === canonical2);
44875
- return entry?.[0] ?? null;
44876
- }
44877
- }
44878
- /**
44879
- * Extract a plain-text transcript from Claude Code session JSONL files.
44880
- *
44881
- * Claude Code stores session data under `~/.claude/projects/<project-slug>/`:
44882
- * - Root-level session JSONLs: `<sessionId>.jsonl` (primary transcript)
44883
- * - UUID subdirectories contain `subagents/agent-*.jsonl` (subagent turns)
44884
- *
44885
- * Reads the most-recent root-level JSONL plus all subagent JSONLs and
44886
- * extracts user/assistant turn text into a flat string for brain
44887
- * observation extraction.
44888
- *
44889
- * Returns null when no session data is found or on any read error.
44890
- *
44891
- * @param sessionId - CLEO session ID (available for future subagent filtering)
44892
- * @param _projectDir - Project directory (unused; Claude Code uses global paths)
44893
- * @task T729 @task T144 @epic T134
44894
- */
44895
- async getTranscript(sessionId, _projectDir) {
44896
- try {
44897
- const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "/root";
44898
- const projectsDir = join5(homeDir, ".claude", "projects");
44899
- let rootFiles = [];
44900
- const subagentFiles = [];
44901
- try {
44902
- const projectDirs = await readdir(projectsDir, { withFileTypes: true });
44903
- for (const projectEntry of projectDirs) {
44904
- if (!projectEntry.isDirectory()) continue;
44905
- const projectDir = join5(projectsDir, projectEntry.name);
44906
- try {
44907
- const projectContents = await readdir(projectDir, { withFileTypes: true });
44908
- for (const entry of projectContents) {
44909
- if (entry.isFile() && entry.name.endsWith(".jsonl")) {
44910
- rootFiles.push({ path: join5(projectDir, entry.name) });
44911
- continue;
44912
- }
44913
- if (entry.isDirectory()) {
44914
- const subagentsDir = join5(projectDir, entry.name, "subagents");
44915
- try {
44916
- const subagentEntries = await readdir(subagentsDir);
44917
- for (const sa of subagentEntries) {
44918
- if (sa.startsWith("agent-") && sa.endsWith(".jsonl")) {
44919
- subagentFiles.push({ path: join5(subagentsDir, sa) });
44920
- }
44921
- }
44922
- } catch {
44923
- }
44924
- }
44925
- }
44926
- } catch {
44927
- }
44928
- }
44929
- } catch {
44930
- return null;
44931
- }
44932
- if (rootFiles.length === 0 && subagentFiles.length === 0) return null;
44933
- rootFiles = rootFiles.sort((a, b) => b.path.localeCompare(a.path));
44934
- const allPaths = [
44935
- ...rootFiles[0] ? [rootFiles[0].path] : [],
44936
- ...subagentFiles.map((f) => f.path)
44937
- ];
44938
- void sessionId;
44939
- const turns = [];
44940
- for (const filePath of allPaths) {
44941
- try {
44942
- const raw = await readFile(filePath, "utf-8");
44943
- const lines = raw.split("\n").filter((l) => l.trim());
44944
- for (const line of lines) {
44945
- try {
44946
- const entry = JSON.parse(line);
44947
- const role = entry.role;
44948
- const content = entry.content;
44949
- if (role === "assistant" && typeof content === "string") {
44950
- turns.push(`assistant: ${content}`);
44951
- } else if (role === "user" && typeof content === "string") {
44952
- turns.push(`user: ${content}`);
44953
- }
44954
- } catch {
44955
- }
44956
- }
44957
- } catch {
44958
- }
44959
- }
44960
- return turns.length > 0 ? turns.join("\n") : null;
44961
- } catch {
44962
- return null;
44963
- }
44964
- }
44965
- };
44966
- }
44967
- });
44968
-
44969
44508
  // packages/adapters/src/providers/shared/heavy-command-hook-install.ts
44970
44509
  import { execFileSync } from "node:child_process";
44971
44510
  import {
44972
- existsSync as existsSync5,
44511
+ existsSync as existsSync3,
44973
44512
  mkdirSync,
44974
44513
  readdirSync as readdirSync2,
44975
- readFileSync as readFileSync4,
44514
+ readFileSync as readFileSync3,
44976
44515
  realpathSync,
44977
44516
  rmSync,
44978
44517
  statSync,
44979
- writeFileSync as writeFileSync2
44518
+ writeFileSync
44980
44519
  } from "node:fs";
44981
- import { homedir as homedir4, tmpdir } from "node:os";
44982
- import { dirname as dirname2, isAbsolute, join as join6, resolve as resolve2 } from "node:path";
44983
- import { updateJsonConfigFile as updateJsonConfigFile2 } from "@cleocode/caamp";
44520
+ import { homedir as homedir2, tmpdir } from "node:os";
44521
+ import { dirname, isAbsolute, join as join3, resolve as resolve2 } from "node:path";
44522
+ import { updateJsonConfigFile } from "@cleocode/caamp";
44984
44523
  function canonical(path) {
44985
44524
  try {
44986
- return realpathSync(path);
44525
+ return realpathSync.native(path);
44987
44526
  } catch {
44988
44527
  return resolve2(path);
44989
44528
  }
@@ -44997,17 +44536,17 @@ function nonDirectoryAncestor(dir) {
44997
44536
  const code = err.code;
44998
44537
  if (code !== "ENOENT" && code !== "ENOTDIR") return null;
44999
44538
  }
45000
- const parent = dirname2(cur);
44539
+ const parent = dirname(cur);
45001
44540
  if (parent === cur) return null;
45002
44541
  cur = parent;
45003
44542
  }
45004
44543
  }
45005
44544
  function ensureParentDir(target) {
45006
- const blocked = nonDirectoryAncestor(dirname2(target));
44545
+ const blocked = nonDirectoryAncestor(dirname(target));
45007
44546
  if (blocked !== null) throw new HeavyHookPathBlockedError(blocked, target);
45008
- mkdirSync(dirname2(target), { recursive: true });
44547
+ mkdirSync(dirname(target), { recursive: true });
45009
44548
  }
45010
- function isUserHomeDir(projectDir, home = homedir4()) {
44549
+ function isUserHomeDir(projectDir, home = homedir2()) {
45011
44550
  return canonical(projectDir) === canonical(home);
45012
44551
  }
45013
44552
  function clearOlderCleoMarkers(dir = process.env.XDG_RUNTIME_DIR || tmpdir()) {
@@ -45021,7 +44560,7 @@ function clearOlderCleoMarkers(dir = process.env.XDG_RUNTIME_DIR || tmpdir()) {
45021
44560
  for (const name15 of names) {
45022
44561
  if (!name15.startsWith(OLDER_CLEO_MARKER_PREFIX)) continue;
45023
44562
  try {
45024
- rmSync(join6(dir, name15), { force: true });
44563
+ rmSync(join3(dir, name15), { force: true });
45025
44564
  removed++;
45026
44565
  } catch {
45027
44566
  }
@@ -45111,8 +44650,8 @@ function placeHeavyHook(hooks, desired) {
45111
44650
  }
45112
44651
  async function syncJsonHeavyCommandHook(configPath, provider, mode) {
45113
44652
  if (mode === "off") {
45114
- if (!existsSync5(configPath)) return "unchanged";
45115
- const removed = await updateJsonConfigFile2(configPath, (config2) => {
44653
+ if (!existsSync3(configPath)) return "unchanged";
44654
+ const removed = await updateJsonConfigFile(configPath, (config2) => {
45116
44655
  if (config2.hooks === void 0) return false;
45117
44656
  return placeHeavyHook(hookMap(config2), null).changed;
45118
44657
  });
@@ -45121,7 +44660,7 @@ async function syncJsonHeavyCommandHook(configPath, provider, mode) {
45121
44660
  ensureParentDir(configPath);
45122
44661
  clearOlderCleoMarkers();
45123
44662
  let result = "unchanged";
45124
- await updateJsonConfigFile2(configPath, (config2) => {
44663
+ await updateJsonConfigFile(configPath, (config2) => {
45125
44664
  const hooks = hookMap(config2);
45126
44665
  const placed = placeHeavyHook(hooks, heavyCommandHookObject(provider));
45127
44666
  if (placed.found) {
@@ -45153,7 +44692,7 @@ function excludeFile(projectDir) {
45153
44692
  if (gitOutput(projectDir, ["rev-parse", "--is-inside-work-tree"]) !== "true") return null;
45154
44693
  const path = gitOutput(projectDir, ["rev-parse", "--git-path", "info/exclude"]);
45155
44694
  if (path === null || path === "") return null;
45156
- return isAbsolute(path) ? path : join6(projectDir, path);
44695
+ return isAbsolute(path) ? path : join3(projectDir, path);
45157
44696
  }
45158
44697
  function excludeLine(projectDir, relPath) {
45159
44698
  const prefix = gitOutput(projectDir, ["rev-parse", "--show-prefix"]) ?? "";
@@ -45165,27 +44704,27 @@ function excludeHookFileFromGit(projectDir, relPath, marker16 = HOOK_FILE_EXCLUD
45165
44704
  if (gitOutput(projectDir, ["check-ignore", relPath]) !== null) return false;
45166
44705
  if (gitOutput(projectDir, ["ls-files", "--error-unmatch", relPath]) !== null) return false;
45167
44706
  const line = excludeLine(projectDir, relPath);
45168
- const text = existsSync5(exclude) ? readFileSync4(exclude, "utf-8") : "";
44707
+ const text = existsSync3(exclude) ? readFileSync3(exclude, "utf-8") : "";
45169
44708
  if (text.split("\n").includes(line)) return false;
45170
44709
  const block = `${marker16}
45171
44710
  ${line}
45172
44711
  `;
45173
- mkdirSync(dirname2(exclude), { recursive: true });
45174
- writeFileSync2(exclude, text === "" || text.endsWith("\n") ? text + block : `${text}
44712
+ mkdirSync(dirname(exclude), { recursive: true });
44713
+ writeFileSync(exclude, text === "" || text.endsWith("\n") ? text + block : `${text}
45175
44714
  ${block}`);
45176
44715
  return true;
45177
44716
  }
45178
44717
  function unexcludeHookFileFromGit(projectDir, relPath) {
45179
44718
  const exclude = excludeFile(projectDir);
45180
- if (exclude === null || !existsSync5(exclude)) return false;
45181
- const lines = readFileSync4(exclude, "utf-8").split("\n");
44719
+ if (exclude === null || !existsSync3(exclude)) return false;
44720
+ const lines = readFileSync3(exclude, "utf-8").split("\n");
45182
44721
  const at = lines.indexOf(excludeLine(projectDir, relPath));
45183
44722
  const above = lines[at - 1];
45184
44723
  if (at < 1 || above !== LOCAL_SETTINGS_EXCLUDE_MARKER && above !== HOOK_FILE_EXCLUDE_MARKER) {
45185
44724
  return false;
45186
44725
  }
45187
44726
  lines.splice(at - 1, 2);
45188
- writeFileSync2(exclude, lines.join("\n"));
44727
+ writeFileSync(exclude, lines.join("\n"));
45189
44728
  return true;
45190
44729
  }
45191
44730
  function hookFileVisibleToGit(projectDir, relPath) {
@@ -45218,14 +44757,14 @@ function cleoCreatedConfig(config2) {
45218
44757
  return mine > 0;
45219
44758
  }
45220
44759
  function codexHooksSharedReason(projectDir, checkGit = true) {
45221
- const file2 = join6(projectDir, CODEX_HOOKS_FILE);
44760
+ const file2 = join3(projectDir, CODEX_HOOKS_FILE);
45222
44761
  if (checkGit && gitOutput(projectDir, ["ls-files", "--error-unmatch", CODEX_HOOKS_FILE]) !== null) {
45223
44762
  return "is tracked by git (a shared team config)";
45224
44763
  }
45225
- if (!existsSync5(file2)) return null;
44764
+ if (!existsSync3(file2)) return null;
45226
44765
  let config2;
45227
44766
  try {
45228
- config2 = JSON.parse(readFileSync4(file2, "utf-8"));
44767
+ config2 = JSON.parse(readFileSync3(file2, "utf-8"));
45229
44768
  } catch {
45230
44769
  return "is the project's own Codex hook config (empty or not valid JSON)";
45231
44770
  }
@@ -45258,7 +44797,7 @@ function jsonEqual(a, b) {
45258
44797
  function restoreCommittedCodexHooks(projectDir) {
45259
44798
  if (gitOutput(projectDir, ["ls-files", "--error-unmatch", CODEX_HOOKS_FILE]) === null)
45260
44799
  return false;
45261
- const file2 = join6(projectDir, CODEX_HOOKS_FILE);
44800
+ const file2 = join3(projectDir, CODEX_HOOKS_FILE);
45262
44801
  let committed;
45263
44802
  let working;
45264
44803
  try {
@@ -45267,7 +44806,7 @@ function restoreCommittedCodexHooks(projectDir) {
45267
44806
  stdio: ["ignore", "pipe", "ignore"],
45268
44807
  timeout: 5e3
45269
44808
  });
45270
- working = JSON.parse(readFileSync4(file2, "utf-8"));
44809
+ working = JSON.parse(readFileSync3(file2, "utf-8"));
45271
44810
  } catch {
45272
44811
  return false;
45273
44812
  }
@@ -45279,13 +44818,13 @@ function restoreCommittedCodexHooks(projectDir) {
45279
44818
  } catch {
45280
44819
  return false;
45281
44820
  }
45282
- writeFileSync2(file2, committed);
44821
+ writeFileSync(file2, committed);
45283
44822
  return true;
45284
44823
  }
45285
44824
  function excludedByCleo(projectDir, relPath) {
45286
44825
  const exclude = excludeFile(projectDir);
45287
- if (exclude === null || !existsSync5(exclude)) return false;
45288
- const lines = readFileSync4(exclude, "utf-8").split("\n");
44826
+ if (exclude === null || !existsSync3(exclude)) return false;
44827
+ const lines = readFileSync3(exclude, "utf-8").split("\n");
45289
44828
  const at = lines.indexOf(excludeLine(projectDir, relPath));
45290
44829
  const above = lines[at - 1];
45291
44830
  return at >= 1 && (above === LOCAL_SETTINGS_EXCLUDE_MARKER || above === HOOK_FILE_EXCLUDE_MARKER);
@@ -45298,7 +44837,7 @@ function trackedFileModified(projectDir, relPath) {
45298
44837
  return (gitOutput(projectDir, ["diff", "--name-only", "HEAD", "--", relPath]) ?? "") !== "";
45299
44838
  }
45300
44839
  async function syncCodexHeavyCommandHook(projectDir, mode) {
45301
- const file2 = join6(projectDir, CODEX_HOOKS_FILE);
44840
+ const file2 = join3(projectDir, CODEX_HOOKS_FILE);
45302
44841
  if (mode !== "off") {
45303
44842
  const shared = codexHooksSharedReason(projectDir);
45304
44843
  if (shared !== null) {
@@ -45321,7 +44860,7 @@ async function syncCodexHeavyCommandHook(projectDir, mode) {
45321
44860
  }
45322
44861
  async function syncClaudeCodeHeavyCommandHook(projectDir, mode) {
45323
44862
  const result = await syncJsonHeavyCommandHook(
45324
- join6(projectDir, CLAUDE_LOCAL_SETTINGS),
44863
+ join3(projectDir, CLAUDE_LOCAL_SETTINGS),
45325
44864
  "claude-code",
45326
44865
  mode
45327
44866
  );
@@ -45329,7 +44868,7 @@ async function syncClaudeCodeHeavyCommandHook(projectDir, mode) {
45329
44868
  else excludeLocalSettingsFromGit(projectDir);
45330
44869
  try {
45331
44870
  await syncJsonHeavyCommandHook(
45332
- join6(projectDir, ".claude", "settings.json"),
44871
+ join3(projectDir, ".claude", "settings.json"),
45333
44872
  "claude-code",
45334
44873
  "off"
45335
44874
  );
@@ -45390,8 +44929,8 @@ function opencodeHeavyCommandPluginSource() {
45390
44929
  ].join("\n");
45391
44930
  }
45392
44931
  function syncOpencodeHeavyCommandPlugin(projectDir, mode) {
45393
- const pluginPath = join6(projectDir, OPENCODE_PLUGIN_FILE);
45394
- const exists = existsSync5(pluginPath);
44932
+ const pluginPath = join3(projectDir, OPENCODE_PLUGIN_FILE);
44933
+ const exists = existsSync3(pluginPath);
45395
44934
  if (mode === "off") {
45396
44935
  unexcludeHookFileFromGit(projectDir, OPENCODE_PLUGIN_FILE);
45397
44936
  if (!exists) return "unchanged";
@@ -45399,10 +44938,10 @@ function syncOpencodeHeavyCommandPlugin(projectDir, mode) {
45399
44938
  return "removed";
45400
44939
  }
45401
44940
  const source = opencodeHeavyCommandPluginSource();
45402
- const current = exists && readFileSync4(pluginPath, "utf-8") === source;
44941
+ const current = exists && readFileSync3(pluginPath, "utf-8") === source;
45403
44942
  if (!current) {
45404
44943
  ensureParentDir(pluginPath);
45405
- writeFileSync2(pluginPath, source, "utf-8");
44944
+ writeFileSync(pluginPath, source, "utf-8");
45406
44945
  }
45407
44946
  excludeHookFileFromGit(projectDir, OPENCODE_PLUGIN_FILE);
45408
44947
  return current ? "unchanged" : exists ? "updated" : "installed";
@@ -45488,13 +45027,617 @@ var init_heavy_command_hook_install = __esm({
45488
45027
  }
45489
45028
  });
45490
45029
 
45030
+ // packages/adapters/src/providers/claude-code/paths.ts
45031
+ import { realpathSync as realpathSync2 } from "node:fs";
45032
+ import { homedir as homedir3 } from "node:os";
45033
+ import { basename as basename2, dirname as dirname2, isAbsolute as isAbsolute2, join as join4, relative, resolve as resolve3, sep } from "node:path";
45034
+ function claudeSettingsPath() {
45035
+ return new ClaudeCodePathProvider().getSettingsPath() ?? join4(homedir3(), ".claude", "settings.json");
45036
+ }
45037
+ function canonicalPath(path) {
45038
+ const abs = resolve3(path);
45039
+ try {
45040
+ return realpathSync2.native(abs);
45041
+ } catch {
45042
+ const parent = dirname2(abs);
45043
+ return parent === abs ? abs : join4(canonicalPath(parent), basename2(abs));
45044
+ }
45045
+ }
45046
+ function comparable(path) {
45047
+ return CASE_INSENSITIVE_DEFAULT ? path.toLowerCase() : path;
45048
+ }
45049
+ function isAtOrInside(path, dir) {
45050
+ const rel = relative(comparable(dir), comparable(path));
45051
+ return rel === "" || rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute2(rel);
45052
+ }
45053
+ function assertProjectScoped(projectDir, target) {
45054
+ const abs = resolve3(target);
45055
+ if (isUserHomeDir(projectDir)) {
45056
+ throw new UserGlobalClaudeConfigError(abs, "the project is the home directory");
45057
+ }
45058
+ const canonical2 = canonicalPath(abs);
45059
+ if (comparable(canonical2) === comparable(canonicalPath(claudeSettingsPath()))) {
45060
+ throw new UserGlobalClaudeConfigError(abs, "it is the user-global Claude settings file");
45061
+ }
45062
+ if (isAtOrInside(canonical2, canonicalPath(new ClaudeCodePathProvider().getProviderDir()))) {
45063
+ throw new UserGlobalClaudeConfigError(abs, "it is inside the user-global Claude config dir");
45064
+ }
45065
+ return abs;
45066
+ }
45067
+ function projectClaudeSettingsPath(projectDir) {
45068
+ return assertProjectScoped(projectDir, join4(projectDir, CLAUDE_LOCAL_SETTINGS));
45069
+ }
45070
+ function projectClaudeHooksDir(projectDir) {
45071
+ return assertProjectScoped(projectDir, join4(projectDir, ".claude", "hooks"));
45072
+ }
45073
+ function assertProjectInstructionScope(projectDir) {
45074
+ assertProjectScoped(projectDir, join4(projectDir, "CLAUDE.md"));
45075
+ }
45076
+ function projectClaudeCommandsDir(projectDir) {
45077
+ return assertProjectScoped(projectDir, join4(projectDir, ".claude", "commands"));
45078
+ }
45079
+ var ClaudeCodePathProvider, CASE_INSENSITIVE_DEFAULT, UserGlobalClaudeConfigError;
45080
+ var init_paths = __esm({
45081
+ "packages/adapters/src/providers/claude-code/paths.ts"() {
45082
+ "use strict";
45083
+ init_heavy_command_hook_install();
45084
+ init_hook_config();
45085
+ ClaudeCodePathProvider = class {
45086
+ /** Get the provider's root configuration directory. */
45087
+ getProviderDir() {
45088
+ return process.env["CLAUDE_HOME"] ?? join4(homedir3(), ".claude");
45089
+ }
45090
+ /** Get the path to the provider's settings file, or null if unavailable. */
45091
+ getSettingsPath() {
45092
+ return process.env["CLAUDE_SETTINGS"] ?? join4(this.getProviderDir(), "settings.json");
45093
+ }
45094
+ /** Get the directory where agents are installed, or null if unsupported. */
45095
+ getAgentInstallDir() {
45096
+ return join4(this.getProviderDir(), "agents");
45097
+ }
45098
+ /** Get the path to the provider's memory database, or null if unsupported. */
45099
+ getMemoryDbPath() {
45100
+ return process.env["CLAUDE_MEM_DB"] ?? join4(homedir3(), ".claude-mem", "claude-mem.db");
45101
+ }
45102
+ };
45103
+ CASE_INSENSITIVE_DEFAULT = process.platform === "darwin" || process.platform === "win32";
45104
+ UserGlobalClaudeConfigError = class extends Error {
45105
+ /** The path that was refused. */
45106
+ path;
45107
+ /**
45108
+ * @param path - the refused target.
45109
+ * @param why - which user-global location it hits.
45110
+ */
45111
+ constructor(path, why) {
45112
+ super(`refusing to write ${path}: ${why}; CLEO only writes project-level Claude Code config`);
45113
+ this.name = "UserGlobalClaudeConfigError";
45114
+ this.path = path;
45115
+ }
45116
+ };
45117
+ }
45118
+ });
45119
+
45120
+ // packages/adapters/src/providers/claude-code/context-monitor.ts
45121
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
45122
+ import { mkdir } from "node:fs/promises";
45123
+ import { homedir as homedir4 } from "node:os";
45124
+ import { dirname as dirname3, join as join5 } from "node:path";
45125
+ import { resolveLegacyCleoDir } from "@cleocode/paths";
45126
+ function getContextStatusFromPercentage(percentage) {
45127
+ if (percentage >= THRESHOLDS.EMERGENCY) return "emergency";
45128
+ if (percentage >= THRESHOLDS.CRITICAL) return "critical";
45129
+ if (percentage >= THRESHOLDS.CAUTION) return "caution";
45130
+ if (percentage >= THRESHOLDS.WARNING) return "warning";
45131
+ return "ok";
45132
+ }
45133
+ var THRESHOLDS, ClaudeCodeContextMonitorProvider;
45134
+ var init_context_monitor = __esm({
45135
+ "packages/adapters/src/providers/claude-code/context-monitor.ts"() {
45136
+ "use strict";
45137
+ init_paths();
45138
+ THRESHOLDS = {
45139
+ WARNING: 50,
45140
+ CAUTION: 70,
45141
+ CRITICAL: 85,
45142
+ EMERGENCY: 95
45143
+ };
45144
+ ClaudeCodeContextMonitorProvider = class {
45145
+ /** Path provider for resolving Claude Code directory locations. */
45146
+ pathProvider = new ClaudeCodePathProvider();
45147
+ /** Process raw context window JSON and return a formatted summary string. */
45148
+ async processContextInput(input, cwd) {
45149
+ const typed = input;
45150
+ const contextSize = typed.context_window?.context_window_size ?? 2e5;
45151
+ const usage = typed.context_window?.current_usage;
45152
+ if (!usage) return "-- no data";
45153
+ const inputTokens = usage.input_tokens ?? 0;
45154
+ const outputTokens = usage.output_tokens ?? 0;
45155
+ const cacheCreate = usage.cache_creation_input_tokens ?? 0;
45156
+ const totalTokens = inputTokens + outputTokens + cacheCreate;
45157
+ const percentage = Math.floor(totalTokens * 100 / contextSize);
45158
+ const status = getContextStatusFromPercentage(percentage);
45159
+ const cleoDir = cwd ? join5(cwd, ".cleo") : ".cleo";
45160
+ if (existsSync4(cleoDir)) {
45161
+ const stateDir = join5(cleoDir, "context-states");
45162
+ const statePath = join5(stateDir, ".context-state.json");
45163
+ const state = {
45164
+ $schema: "https://cleo-dev.com/schemas/v1/context-state.schema.json",
45165
+ version: "1.0.0",
45166
+ timestamp: (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z"),
45167
+ staleAfterMs: 5e3,
45168
+ contextWindow: {
45169
+ maxTokens: contextSize,
45170
+ currentTokens: totalTokens,
45171
+ percentage,
45172
+ breakdown: {
45173
+ inputTokens,
45174
+ outputTokens,
45175
+ cacheCreationTokens: cacheCreate,
45176
+ cacheReadTokens: usage.cache_read_input_tokens ?? 0
45177
+ }
45178
+ },
45179
+ thresholds: {
45180
+ warning: THRESHOLDS.WARNING,
45181
+ caution: THRESHOLDS.CAUTION,
45182
+ critical: THRESHOLDS.CRITICAL,
45183
+ emergency: THRESHOLDS.EMERGENCY
45184
+ },
45185
+ status,
45186
+ cleoSessionId: ""
45187
+ };
45188
+ try {
45189
+ await mkdir(dirname3(statePath), { recursive: true });
45190
+ writeFileSync2(statePath, JSON.stringify(state, null, 2));
45191
+ } catch {
45192
+ }
45193
+ }
45194
+ return `${percentage}% | ${totalTokens}/${contextSize}`;
45195
+ }
45196
+ /** Check the current statusline integration status in Claude Code settings. */
45197
+ checkStatuslineIntegration() {
45198
+ const settingsPath = this.pathProvider.getSettingsPath();
45199
+ if (!settingsPath || !existsSync4(settingsPath)) return "no_settings";
45200
+ try {
45201
+ const settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
45202
+ const statusLine = settings.statusLine;
45203
+ if (!statusLine?.type) return "not_configured";
45204
+ if (statusLine.type !== "command") return "custom_no_cleo";
45205
+ const cmd = statusLine.command ?? "";
45206
+ if (cmd.includes("context-monitor.sh") || cmd.includes("cleo-statusline") || cmd.includes(".context-state.json") || cmd.includes("context-states")) {
45207
+ return "configured";
45208
+ }
45209
+ const scriptPath = cmd.startsWith("~") ? cmd.replace("~", homedir4()) : cmd;
45210
+ if (existsSync4(scriptPath)) {
45211
+ try {
45212
+ const content = readFileSync4(scriptPath, "utf-8");
45213
+ if (content.includes("context-state.json")) return "configured";
45214
+ } catch {
45215
+ }
45216
+ }
45217
+ return "custom_no_cleo";
45218
+ } catch {
45219
+ return "no_settings";
45220
+ }
45221
+ }
45222
+ /** Get the recommended statusline configuration object for Claude Code settings. */
45223
+ getStatuslineConfig() {
45224
+ return {
45225
+ statusLine: {
45226
+ type: "command",
45227
+ command: join5(resolveLegacyCleoDir(), "lib", "session", "context-monitor.sh")
45228
+ }
45229
+ };
45230
+ }
45231
+ /** Get human-readable setup instructions for enabling context monitoring. */
45232
+ getSetupInstructions() {
45233
+ const settingsPath = this.pathProvider.getSettingsPath() ?? "~/.claude/settings.json";
45234
+ return [
45235
+ "To enable context monitoring, add to your Claude Code settings:",
45236
+ `File: ${settingsPath}`,
45237
+ "",
45238
+ JSON.stringify(this.getStatuslineConfig(), null, 2),
45239
+ "",
45240
+ "This enables real-time context window tracking in the CLI."
45241
+ ].join("\n");
45242
+ }
45243
+ };
45244
+ }
45245
+ });
45246
+
45247
+ // packages/adapters/src/providers/claude-code/hooks.ts
45248
+ import { existsSync as existsSync5 } from "node:fs";
45249
+ import { readdir, readFile } from "node:fs/promises";
45250
+ import { join as join6 } from "node:path";
45251
+ import { updateJsonConfigFile as updateJsonConfigFile2 } from "@cleocode/caamp";
45252
+ function isNativeHookObject(hook) {
45253
+ return isPlainObject2(hook) && typeof hook.command === "string" && NATIVE_HOOK_COMMANDS.has(hook.command);
45254
+ }
45255
+ function hasNativeHooks(hooks) {
45256
+ return Object.values(hooks).some(
45257
+ (entries) => Array.isArray(entries) && entries.some(
45258
+ (entry) => isPlainObject2(entry) && Array.isArray(entry.hooks) && entry.hooks.some(isNativeHookObject)
45259
+ )
45260
+ );
45261
+ }
45262
+ function removeNativeHooks(hooks) {
45263
+ let changed = false;
45264
+ for (const [event, entries] of Object.entries(hooks)) {
45265
+ if (!Array.isArray(entries)) continue;
45266
+ const kept = [];
45267
+ let eventChanged = false;
45268
+ for (const entry of entries) {
45269
+ if (!isPlainObject2(entry) || !Array.isArray(entry.hooks) || !entry.hooks.some(isNativeHookObject)) {
45270
+ kept.push(entry);
45271
+ continue;
45272
+ }
45273
+ eventChanged = true;
45274
+ const rest = entry.hooks.filter((hook) => !isNativeHookObject(hook));
45275
+ if (rest.length > 0) kept.push({ ...entry, hooks: rest });
45276
+ }
45277
+ if (!eventChanged) continue;
45278
+ changed = true;
45279
+ if (kept.length === 0) delete hooks[event];
45280
+ else hooks[event] = kept;
45281
+ }
45282
+ return changed;
45283
+ }
45284
+ var NATIVE_STOP_HOOK_COMMAND, NATIVE_OBSERVE_HOOK_COMMAND, NATIVE_NEXUS_HOOK_COMMAND, NATIVE_HOOK_COMMANDS, PROVIDER_ID, CLAUDE_CODE_EVENT_MAP, ClaudeCodeHookProvider;
45285
+ var init_hooks = __esm({
45286
+ "packages/adapters/src/providers/claude-code/hooks.ts"() {
45287
+ "use strict";
45288
+ init_heavy_command_hook_install();
45289
+ init_paths();
45290
+ NATIVE_STOP_HOOK_COMMAND = "cleo session end --quiet # cleo-hook";
45291
+ NATIVE_OBSERVE_HOOK_COMMAND = 'cleo observe "File modified via $TOOL_NAME" --title "tool-use" --quiet # cleo-hook';
45292
+ NATIVE_NEXUS_HOOK_COMMAND = 'cleo nexus analyze --incremental --json > /dev/null 2>&1 && cleo observe "NEXUS re-indexed after $TOOL_NAME on $TOOL_INPUT_file_path" --title "nexus-post-check" --quiet # cleo-hook';
45293
+ NATIVE_HOOK_COMMANDS = /* @__PURE__ */ new Set([
45294
+ NATIVE_STOP_HOOK_COMMAND,
45295
+ NATIVE_OBSERVE_HOOK_COMMAND,
45296
+ NATIVE_NEXUS_HOOK_COMMAND
45297
+ ]);
45298
+ PROVIDER_ID = "claude-code";
45299
+ CLAUDE_CODE_EVENT_MAP = {
45300
+ // CAAMP: toNative('SessionStart', 'claude-code') = 'SessionStart'
45301
+ SessionStart: "SessionStart",
45302
+ // CAAMP: toNative('SessionEnd', 'claude-code') = 'SessionEnd'
45303
+ SessionEnd: "SessionEnd",
45304
+ // CAAMP: toNative('PromptSubmit', 'claude-code') = 'UserPromptSubmit'
45305
+ UserPromptSubmit: "PromptSubmit",
45306
+ // CAAMP: toNative('ResponseComplete', 'claude-code') = 'Stop'
45307
+ Stop: "ResponseComplete",
45308
+ // CAAMP: toNative('PreToolUse', 'claude-code') = 'PreToolUse'
45309
+ PreToolUse: "PreToolUse",
45310
+ // CAAMP: toNative('PostToolUse', 'claude-code') = 'PostToolUse'
45311
+ PostToolUse: "PostToolUse",
45312
+ // CAAMP: toNative('PostToolUseFailure','claude-code') = 'PostToolUseFailure'
45313
+ PostToolUseFailure: "PostToolUseFailure",
45314
+ // CAAMP: toNative('PermissionRequest', 'claude-code') = 'PermissionRequest'
45315
+ PermissionRequest: "PermissionRequest",
45316
+ // CAAMP: toNative('SubagentStart', 'claude-code') = 'SubagentStart'
45317
+ SubagentStart: "SubagentStart",
45318
+ // CAAMP: toNative('SubagentStop', 'claude-code') = 'SubagentStop'
45319
+ SubagentStop: "SubagentStop",
45320
+ // CAAMP: toNative('PreCompact', 'claude-code') = 'PreCompact'
45321
+ PreCompact: "PreCompact",
45322
+ // CAAMP: toNative('PostCompact', 'claude-code') = 'PostCompact'
45323
+ PostCompact: "PostCompact",
45324
+ // CAAMP: toNative('Notification', 'claude-code') = 'Notification'
45325
+ Notification: "Notification",
45326
+ // CAAMP: toNative('ConfigChange', 'claude-code') = 'ConfigChange'
45327
+ ConfigChange: "ConfigChange"
45328
+ };
45329
+ ClaudeCodeHookProvider = class {
45330
+ /** Whether hooks have been registered for the current session. */
45331
+ registered = false;
45332
+ /**
45333
+ * Map a Claude Code native event name to a CAAMP canonical hook event name.
45334
+ *
45335
+ * Looks up the native event name in the map derived from
45336
+ * `getProviderHookProfile('claude-code').mappings` (CAAMP 1.9.1).
45337
+ * Returns null for unrecognised events (e.g. PreModel, PostModel which
45338
+ * Claude Code does not support).
45339
+ *
45340
+ * @param providerEvent - Claude Code native event (e.g. "UserPromptSubmit", "Stop")
45341
+ * @returns CAAMP canonical event name, or null if unmapped
45342
+ * @task T164
45343
+ */
45344
+ mapProviderEvent(providerEvent) {
45345
+ return CLAUDE_CODE_EVENT_MAP[providerEvent] ?? null;
45346
+ }
45347
+ /** Project directory this hook provider was registered for. */
45348
+ projectDir = null;
45349
+ /**
45350
+ * Register native hooks for a project.
45351
+ *
45352
+ * Writes CLEO hook entries to the project's per-machine
45353
+ * `<project>/.claude/settings.local.json` so that Claude Code's native event
45354
+ * system calls cleo CLI commands when events fire in this project. This
45355
+ * bridges Claude Code's event loop to CLEO's internal hook dispatch.
45356
+ * CLEO never writes the user-global `~/.claude/settings.json` (T13227): a
45357
+ * project that is the home directory, or whose settings file resolves into
45358
+ * the user-global Claude config, is refused and nothing is written. When
45359
+ * git does not ignore `settings.local.json` yet, a marked `info/exclude`
45360
+ * block keeps it out of git (the T12983 heavy-command rule).
45361
+ *
45362
+ * Idempotent: skips writing if the native hooks are already present.
45363
+ *
45364
+ * Hook entries registered:
45365
+ * - `Stop` → `cleo session end --quiet` (triggers LLM extraction, reflector, consolidation)
45366
+ * - `PostToolUse` (Write|Edit) → brain observation for file modifications
45367
+ * and the NEXUS post-check
45368
+ *
45369
+ * @param projectDir - Project whose Claude Code settings receive the hooks
45370
+ * @task T164 @task T555 @task T13227
45371
+ */
45372
+ async registerNativeHooks(projectDir) {
45373
+ this.projectDir = projectDir;
45374
+ this.registered = true;
45375
+ const wrote = await this.updateSettings(projectDir, (settings) => {
45376
+ const hooks = hookMap(settings);
45377
+ if (hasNativeHooks(hooks)) return false;
45378
+ appendHookEntry(hooks, "Stop", {
45379
+ matcher: "",
45380
+ hooks: [{ type: "command", command: NATIVE_STOP_HOOK_COMMAND }]
45381
+ });
45382
+ appendHookEntry(hooks, "PostToolUse", {
45383
+ matcher: "Write|Edit",
45384
+ hooks: [
45385
+ { type: "command", command: NATIVE_OBSERVE_HOOK_COMMAND },
45386
+ { type: "command", command: NATIVE_NEXUS_HOOK_COMMAND }
45387
+ ]
45388
+ });
45389
+ return true;
45390
+ });
45391
+ if (wrote) excludeLocalSettingsFromGit(projectDir);
45392
+ }
45393
+ /**
45394
+ * Unregister native hooks.
45395
+ *
45396
+ * Removes the hook objects {@link registerNativeHooks} wrote from the
45397
+ * project's `settings.local.json`, and nothing else: the heavy-command hook
45398
+ * and the user's own hooks stay, and an entry or event is dropped only when
45399
+ * left empty. Same locking, atomicity, parse-error and project-scope rules
45400
+ * as {@link registerNativeHooks}.
45401
+ *
45402
+ * @task T164 @task T555 @task T13227
45403
+ */
45404
+ async unregisterNativeHooks() {
45405
+ const projectDir = this.projectDir;
45406
+ this.registered = false;
45407
+ this.projectDir = null;
45408
+ if (projectDir === null) return;
45409
+ let settingsPath;
45410
+ try {
45411
+ settingsPath = projectClaudeSettingsPath(projectDir);
45412
+ } catch {
45413
+ return;
45414
+ }
45415
+ if (!existsSync5(settingsPath)) return;
45416
+ await this.updateSettings(projectDir, (settings) => {
45417
+ if (settings.hooks === void 0) return false;
45418
+ return removeNativeHooks(hookMap(settings));
45419
+ });
45420
+ }
45421
+ /** The last settings.json failure, or `null` when the last update succeeded. */
45422
+ settingsError = null;
45423
+ /**
45424
+ * Why the last settings update did not happen, or `null`.
45425
+ *
45426
+ * @remarks
45427
+ * Hook registration stays non-fatal for adapter initialisation, so a
45428
+ * refused write (malformed settings file, lock timeout, a user-global
45429
+ * target) is surfaced here and on stderr instead of being swallowed
45430
+ * (T12385, T13227).
45431
+ *
45432
+ * @returns The failure message, or `null`
45433
+ */
45434
+ getSettingsError() {
45435
+ return this.settingsError;
45436
+ }
45437
+ /**
45438
+ * Apply `mutate` to the project's `settings.local.json` via CAAMP's locked,
45439
+ * atomic JSON writer.
45440
+ *
45441
+ * @returns whether the file was written.
45442
+ */
45443
+ async updateSettings(projectDir, mutate) {
45444
+ let settingsPath = `${projectDir}/.claude/settings.local.json`;
45445
+ try {
45446
+ settingsPath = projectClaudeSettingsPath(projectDir);
45447
+ const wrote = await updateJsonConfigFile2(settingsPath, mutate);
45448
+ this.settingsError = null;
45449
+ return wrote;
45450
+ } catch (err) {
45451
+ this.settingsError = err instanceof Error ? err.message : String(err);
45452
+ process.stderr.write(
45453
+ `[cleo:claude-code] hooks not written to ${settingsPath}: ${this.settingsError}
45454
+ `
45455
+ );
45456
+ return false;
45457
+ }
45458
+ }
45459
+ /**
45460
+ * Check whether hooks have been registered via `registerNativeHooks`.
45461
+ */
45462
+ isRegistered() {
45463
+ return this.registered;
45464
+ }
45465
+ /**
45466
+ * Get the project directory this hook provider was registered for.
45467
+ *
45468
+ * Returns null if hooks have not been registered yet.
45469
+ */
45470
+ getProjectDir() {
45471
+ return this.projectDir;
45472
+ }
45473
+ /**
45474
+ * Get the native→canonical event mapping for introspection and debugging.
45475
+ *
45476
+ * Returns the map derived from `getProviderHookProfile('claude-code').mappings`
45477
+ * (CAAMP 1.9.1). Use `getSupportedCanonicalEvents()` to enumerate canonical
45478
+ * names via live CAAMP APIs.
45479
+ *
45480
+ * @returns Immutable record of native event name → canonical event name
45481
+ */
45482
+ getEventMap() {
45483
+ return { ...CLAUDE_CODE_EVENT_MAP };
45484
+ }
45485
+ /**
45486
+ * Enumerate supported canonical events via CAAMP's `getSupportedEvents()`.
45487
+ *
45488
+ * Calls `getSupportedEvents('claude-code')` from the CAAMP normalizer to
45489
+ * get the authoritative list. Claude Code supports 14 of 16 canonical events
45490
+ * (PreModel and PostModel are not supported). Falls back to the values of
45491
+ * the static event map when CAAMP is unavailable at runtime.
45492
+ *
45493
+ * @returns Array of CAAMP canonical event names supported by Claude Code
45494
+ * @task T164
45495
+ */
45496
+ async getSupportedCanonicalEvents() {
45497
+ try {
45498
+ const { getSupportedEvents } = await import("@cleocode/caamp");
45499
+ return getSupportedEvents(PROVIDER_ID);
45500
+ } catch {
45501
+ return [...new Set(Object.values(CLAUDE_CODE_EVENT_MAP))];
45502
+ }
45503
+ }
45504
+ /**
45505
+ * Retrieve the full provider hook profile from CAAMP.
45506
+ *
45507
+ * Calls `getProviderHookProfile('claude-code')` from the CAAMP normalizer to
45508
+ * get the complete profile: hook system type (`config`), config path
45509
+ * (`~/.claude/settings.json`), handler types, and all event mappings.
45510
+ * Returns null when CAAMP is unavailable at runtime.
45511
+ *
45512
+ * @returns Provider hook profile or null if CAAMP is unavailable
45513
+ * @task T164
45514
+ */
45515
+ async getProviderProfile() {
45516
+ try {
45517
+ const { getProviderHookProfile } = await import("@cleocode/caamp");
45518
+ return getProviderHookProfile(PROVIDER_ID) ?? null;
45519
+ } catch {
45520
+ return null;
45521
+ }
45522
+ }
45523
+ /**
45524
+ * Translate a CAAMP canonical event to its Claude Code native name via CAAMP.
45525
+ *
45526
+ * Calls `toNative(canonical, 'claude-code')` from the CAAMP normalizer.
45527
+ * Returns null for unsupported events (PreModel, PostModel) or when
45528
+ * CAAMP is unavailable.
45529
+ *
45530
+ * @param canonical - CAAMP canonical event name (e.g. "PromptSubmit")
45531
+ * @returns Claude Code native event name or null
45532
+ * @task T164
45533
+ */
45534
+ async toNativeEvent(canonical2) {
45535
+ try {
45536
+ const { toNative } = await import("@cleocode/caamp");
45537
+ return toNative(canonical2, PROVIDER_ID);
45538
+ } catch {
45539
+ const entry = Object.entries(CLAUDE_CODE_EVENT_MAP).find(([, v]) => v === canonical2);
45540
+ return entry?.[0] ?? null;
45541
+ }
45542
+ }
45543
+ /**
45544
+ * Extract a plain-text transcript from Claude Code session JSONL files.
45545
+ *
45546
+ * Claude Code stores session data under `~/.claude/projects/<project-slug>/`:
45547
+ * - Root-level session JSONLs: `<sessionId>.jsonl` (primary transcript)
45548
+ * - UUID subdirectories contain `subagents/agent-*.jsonl` (subagent turns)
45549
+ *
45550
+ * Reads the most-recent root-level JSONL plus all subagent JSONLs and
45551
+ * extracts user/assistant turn text into a flat string for brain
45552
+ * observation extraction.
45553
+ *
45554
+ * Returns null when no session data is found or on any read error.
45555
+ *
45556
+ * @param sessionId - CLEO session ID (available for future subagent filtering)
45557
+ * @param _projectDir - Project directory (unused; Claude Code uses global paths)
45558
+ * @task T729 @task T144 @epic T134
45559
+ */
45560
+ async getTranscript(sessionId, _projectDir) {
45561
+ try {
45562
+ const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "/root";
45563
+ const projectsDir = join6(homeDir, ".claude", "projects");
45564
+ let rootFiles = [];
45565
+ const subagentFiles = [];
45566
+ try {
45567
+ const projectDirs = await readdir(projectsDir, { withFileTypes: true });
45568
+ for (const projectEntry of projectDirs) {
45569
+ if (!projectEntry.isDirectory()) continue;
45570
+ const projectDir = join6(projectsDir, projectEntry.name);
45571
+ try {
45572
+ const projectContents = await readdir(projectDir, { withFileTypes: true });
45573
+ for (const entry of projectContents) {
45574
+ if (entry.isFile() && entry.name.endsWith(".jsonl")) {
45575
+ rootFiles.push({ path: join6(projectDir, entry.name) });
45576
+ continue;
45577
+ }
45578
+ if (entry.isDirectory()) {
45579
+ const subagentsDir = join6(projectDir, entry.name, "subagents");
45580
+ try {
45581
+ const subagentEntries = await readdir(subagentsDir);
45582
+ for (const sa of subagentEntries) {
45583
+ if (sa.startsWith("agent-") && sa.endsWith(".jsonl")) {
45584
+ subagentFiles.push({ path: join6(subagentsDir, sa) });
45585
+ }
45586
+ }
45587
+ } catch {
45588
+ }
45589
+ }
45590
+ }
45591
+ } catch {
45592
+ }
45593
+ }
45594
+ } catch {
45595
+ return null;
45596
+ }
45597
+ if (rootFiles.length === 0 && subagentFiles.length === 0) return null;
45598
+ rootFiles = rootFiles.sort((a, b) => b.path.localeCompare(a.path));
45599
+ const allPaths = [
45600
+ ...rootFiles[0] ? [rootFiles[0].path] : [],
45601
+ ...subagentFiles.map((f) => f.path)
45602
+ ];
45603
+ void sessionId;
45604
+ const turns = [];
45605
+ for (const filePath of allPaths) {
45606
+ try {
45607
+ const raw = await readFile(filePath, "utf-8");
45608
+ const lines = raw.split("\n").filter((l) => l.trim());
45609
+ for (const line of lines) {
45610
+ try {
45611
+ const entry = JSON.parse(line);
45612
+ const role = entry.role;
45613
+ const content = entry.content;
45614
+ if (role === "assistant" && typeof content === "string") {
45615
+ turns.push(`assistant: ${content}`);
45616
+ } else if (role === "user" && typeof content === "string") {
45617
+ turns.push(`user: ${content}`);
45618
+ }
45619
+ } catch {
45620
+ }
45621
+ }
45622
+ } catch {
45623
+ }
45624
+ }
45625
+ return turns.length > 0 ? turns.join("\n") : null;
45626
+ } catch {
45627
+ return null;
45628
+ }
45629
+ }
45630
+ };
45631
+ }
45632
+ });
45633
+
45491
45634
  // packages/adapters/src/providers/shared/hook-template-installer.ts
45492
45635
  import { copyFileSync, existsSync as existsSync6, mkdirSync as mkdirSync2, statSync as statSync2 } from "node:fs";
45493
- import { dirname as dirname3, join as join7 } from "node:path";
45636
+ import { dirname as dirname4, join as join7 } from "node:path";
45494
45637
  import { fileURLToPath } from "node:url";
45495
45638
  function resolveProviderCandidates() {
45496
- const thisDir = dirname3(fileURLToPath(import.meta.url));
45497
- const here = dirname3(thisDir);
45639
+ const thisDir = dirname4(fileURLToPath(import.meta.url));
45640
+ const here = dirname4(thisDir);
45498
45641
  const fromDist = join7(here, "..", "..", "src", "providers");
45499
45642
  return [here, fromDist];
45500
45643
  }
@@ -45523,7 +45666,7 @@ function copyTemplate(src, dest, force) {
45523
45666
  return { wrote: false };
45524
45667
  }
45525
45668
  }
45526
- mkdirSync2(dirname3(dest), { recursive: true });
45669
+ mkdirSync2(dirname4(dest), { recursive: true });
45527
45670
  copyFileSync(src, dest);
45528
45671
  return { wrote: true };
45529
45672
  }
@@ -45569,25 +45712,28 @@ var init_hook_template_installer = __esm({
45569
45712
 
45570
45713
  // packages/adapters/src/providers/claude-code/install.ts
45571
45714
  import { copyFileSync as copyFileSync2, existsSync as existsSync7, mkdirSync as mkdirSync3, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
45572
- import { homedir as homedir5 } from "node:os";
45573
- import { dirname as dirname4, join as join8, resolve as resolve3 } from "node:path";
45715
+ import { dirname as dirname5, join as join8, resolve as resolve4 } from "node:path";
45574
45716
  import { fileURLToPath as fileURLToPath2 } from "node:url";
45575
45717
  import { ensureProviderInstructionFile, updateJsonConfigFile as updateJsonConfigFile3 } from "@cleocode/caamp";
45576
- function getClaudeConfigDir() {
45577
- return process.env["CLAUDE_HOME"] ?? join8(homedir5(), ".claude");
45578
- }
45579
45718
  function getAdapterCommandsDir() {
45580
- const thisDir = dirname4(fileURLToPath2(import.meta.url));
45719
+ const thisDir = dirname5(fileURLToPath2(import.meta.url));
45581
45720
  return join8(thisDir, "commands");
45582
45721
  }
45583
- var ClaudeCodeInstallProvider;
45722
+ var CLEO_PLUGIN_KEY, PROJECT_HOOK_FILES, ClaudeCodeInstallProvider;
45584
45723
  var init_install = __esm({
45585
45724
  "packages/adapters/src/providers/claude-code/install.ts"() {
45586
45725
  "use strict";
45587
45726
  init_heavy_command_hook_install();
45588
45727
  init_hook_template_installer();
45589
45728
  init_paths();
45729
+ CLEO_PLUGIN_KEY = "cleo@cleocode";
45730
+ PROJECT_HOOK_FILES = [
45731
+ ".claude/hooks/precompact-safestop.sh",
45732
+ ".claude/hooks/cleo-precompact-core.sh"
45733
+ ];
45590
45734
  ClaudeCodeInstallProvider = class {
45735
+ /** The project the last {@link install} ran for; {@link isInstalled} reads its settings. */
45736
+ projectDir = null;
45591
45737
  /**
45592
45738
  * Install CLEO into a Claude Code project.
45593
45739
  *
@@ -45596,38 +45742,52 @@ var init_install = __esm({
45596
45742
  */
45597
45743
  async install(options) {
45598
45744
  const { projectDir } = options;
45745
+ this.projectDir = projectDir;
45599
45746
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
45600
45747
  let instructionFileUpdated = false;
45601
45748
  const details = {};
45602
- const instructionResult = await ensureProviderInstructionFile("claude-code", projectDir, {});
45603
- instructionFileUpdated = instructionResult.action !== "intact";
45604
- if (instructionFileUpdated) {
45605
- details.instructionFile = instructionResult.filePath;
45749
+ try {
45750
+ assertProjectInstructionScope(projectDir);
45751
+ const instructionResult = await ensureProviderInstructionFile("claude-code", projectDir, {});
45752
+ instructionFileUpdated = instructionResult.action !== "intact";
45753
+ if (instructionFileUpdated) {
45754
+ details.instructionFile = instructionResult.filePath;
45755
+ }
45756
+ } catch (err) {
45757
+ if (!(err instanceof UserGlobalClaudeConfigError)) throw err;
45758
+ details.instructionFile = "skipped";
45606
45759
  }
45607
- const commandsInstalled = this.installCommands(projectDir);
45608
- if (commandsInstalled.length > 0) {
45609
- details.commands = commandsInstalled;
45760
+ try {
45761
+ const commandsInstalled = this.installCommands(projectDir);
45762
+ if (commandsInstalled.length > 0) {
45763
+ details.commands = commandsInstalled;
45764
+ }
45765
+ } catch (err) {
45766
+ if (!(err instanceof UserGlobalClaudeConfigError)) throw err;
45767
+ details.commands = "skipped";
45610
45768
  }
45611
45769
  const settingsErrors = [];
45612
45770
  try {
45613
- const pluginResult = await this.registerPlugin();
45771
+ const pluginResult = await this.registerPlugin(projectDir);
45614
45772
  if (pluginResult) {
45615
45773
  details.plugin = pluginResult;
45616
45774
  }
45617
45775
  } catch (err) {
45618
- settingsErrors.push(err instanceof Error ? err.message : String(err));
45776
+ if (err instanceof UserGlobalClaudeConfigError) details.plugin = "skipped";
45777
+ else settingsErrors.push(err instanceof Error ? err.message : String(err));
45619
45778
  }
45620
45779
  try {
45621
- const hookResult = await this.installHookTemplates();
45780
+ const hookResult = await this.installHookTemplates(projectDir);
45622
45781
  if (hookResult) {
45623
45782
  details.hookTemplates = hookResult;
45624
45783
  }
45625
45784
  } catch (err) {
45626
- settingsErrors.push(err instanceof Error ? err.message : String(err));
45785
+ if (err instanceof UserGlobalClaudeConfigError) details.hookTemplates = "skipped";
45786
+ else settingsErrors.push(err instanceof Error ? err.message : String(err));
45627
45787
  }
45628
45788
  if (options.heavyCommandHook !== void 0) {
45629
45789
  const projectSettings = join8(projectDir, ".claude", "settings.json");
45630
- if (isUserHomeDir(projectDir) || resolve3(projectSettings) === resolve3(claudeSettingsPath())) {
45790
+ if (isUserHomeDir(projectDir) || resolve4(projectSettings) === resolve4(claudeSettingsPath())) {
45631
45791
  details.heavyCommandHook = "skipped";
45632
45792
  } else {
45633
45793
  try {
@@ -45660,16 +45820,25 @@ var init_install = __esm({
45660
45820
  /**
45661
45821
  * Check whether CLEO is installed in the current environment.
45662
45822
  *
45663
- * Checks for plugin enabled in ~/.claude/settings.json.
45823
+ * Checks for the plugin enabled in the project's
45824
+ * `.claude/settings.local.json` — the project of the last {@link install},
45825
+ * else the working directory (T13227).
45664
45826
  */
45665
45827
  async isInstalled() {
45666
- const settingsPath = claudeSettingsPath();
45828
+ let settingsPath;
45829
+ try {
45830
+ settingsPath = projectClaudeSettingsPath(this.projectDir ?? process.cwd());
45831
+ } catch {
45832
+ return false;
45833
+ }
45667
45834
  if (existsSync7(settingsPath)) {
45668
45835
  try {
45669
45836
  const settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
45670
- const plugins = settings.enabledPlugins;
45671
- if (plugins && plugins["cleo@cleocode"] === true) {
45672
- return true;
45837
+ if (isPlainObject2(settings)) {
45838
+ const plugins = settings.enabledPlugins;
45839
+ if (isPlainObject2(plugins) && plugins[CLEO_PLUGIN_KEY] === true) {
45840
+ return true;
45841
+ }
45673
45842
  }
45674
45843
  } catch {
45675
45844
  }
@@ -45683,8 +45852,11 @@ var init_install = __esm({
45683
45852
  * and default references from the provider registry (T1919).
45684
45853
  *
45685
45854
  * @param projectDir - Project root directory
45855
+ * @throws {@link UserGlobalClaudeConfigError} when the project root is inside
45856
+ * the user-global Claude config dir (T13227); nothing is written.
45686
45857
  */
45687
45858
  async ensureInstructionReferences(projectDir) {
45859
+ assertProjectInstructionScope(projectDir);
45688
45860
  await ensureProviderInstructionFile("claude-code", projectDir, {});
45689
45861
  }
45690
45862
  /**
@@ -45695,13 +45867,14 @@ var init_install = __esm({
45695
45867
  *
45696
45868
  * @param projectDir - Project root directory
45697
45869
  * @returns Array of installed command filenames
45870
+ * @throws {@link UserGlobalClaudeConfigError} when the target is user-global
45698
45871
  */
45699
45872
  installCommands(projectDir) {
45700
45873
  const adapterCommandsDir = getAdapterCommandsDir();
45701
45874
  if (!existsSync7(adapterCommandsDir)) {
45702
45875
  return [];
45703
45876
  }
45704
- const targetDir = join8(projectDir, ".claude", "commands");
45877
+ const targetDir = projectClaudeCommandsDir(projectDir);
45705
45878
  mkdirSync3(targetDir, { recursive: true });
45706
45879
  const installed = [];
45707
45880
  const files = readdirSync3(adapterCommandsDir).filter((f) => f.endsWith(".md"));
@@ -45714,13 +45887,17 @@ var init_install = __esm({
45714
45887
  return installed;
45715
45888
  }
45716
45889
  /**
45717
- * Register the CLEO brain plugin in ~/.claude/settings.json.
45890
+ * Register the CLEO brain plugin in the project's
45891
+ * `.claude/settings.local.json` (T13227: never the user-global settings).
45718
45892
  *
45893
+ * @param projectDir - Project root directory
45719
45894
  * @returns Description of what was registered, or null if no change needed
45895
+ * @throws {@link UserGlobalClaudeConfigError} when the target is user-global
45720
45896
  */
45721
- async registerPlugin() {
45722
- const pluginKey = "cleo@cleocode";
45723
- const wrote = await updateJsonConfigFile3(claudeSettingsPath(), (settings) => {
45897
+ async registerPlugin(projectDir) {
45898
+ const pluginKey = CLEO_PLUGIN_KEY;
45899
+ const settingsPath = projectClaudeSettingsPath(projectDir);
45900
+ const wrote = await updateJsonConfigFile3(settingsPath, (settings) => {
45724
45901
  const enabledPlugins = settings.enabledPlugins ?? {};
45725
45902
  if (!isPlainObject2(enabledPlugins)) {
45726
45903
  throw new Error('settings.json "enabledPlugins" is not an object; not modifying it');
@@ -45735,31 +45912,38 @@ var init_install = __esm({
45735
45912
  settings.enabledPlugins = enabledPlugins;
45736
45913
  return true;
45737
45914
  });
45738
- return wrote ? `Enabled ${pluginKey} in ~/.claude/settings.json` : null;
45915
+ if (!wrote) return null;
45916
+ excludeLocalSettingsFromGit(projectDir);
45917
+ return `Enabled ${pluginKey} in ${settingsPath}`;
45739
45918
  }
45740
45919
  /**
45741
45920
  * Install the CLEO PreCompact hook templates for Claude Code (T1013).
45742
45921
  *
45743
- * Writes two files to `~/.claude/hooks/`:
45922
+ * Writes two files to the project's `.claude/hooks/`:
45744
45923
  * 1. `cleo-precompact-core.sh` — universal CLEO safestop helper (shared
45745
45924
  * across all providers; sourced by the provider-specific shim).
45746
45925
  * 2. `precompact-safestop.sh` — Claude-Code-flavoured wrapper that invokes
45747
45926
  * `cleo memory precompact-flush` and `cleo safestop`.
45748
45927
  *
45749
- * Also registers a `PreCompact` entry in `~/.claude/settings.json` so Claude
45750
- * Code runs the hook when auto-compact fires (at 95% context).
45928
+ * Also registers a `PreCompact` entry in the project's
45929
+ * `.claude/settings.local.json` so Claude Code runs the hook when
45930
+ * auto-compact fires (at 95% context). Files git does not ignore yet are
45931
+ * kept out of it with a marked `info/exclude` block. Nothing is written to
45932
+ * the user-global Claude config (T13227).
45751
45933
  *
45752
45934
  * Idempotent: subsequent installs skip unchanged files and do not duplicate
45753
- * the settings.json hook entry.
45935
+ * the settings hook entry.
45754
45936
  *
45937
+ * @param projectDir - Project root directory
45755
45938
  * @returns Install summary (paths written + config change description), or
45756
45939
  * `null` when no change was required.
45940
+ * @throws {@link UserGlobalClaudeConfigError} when the target is user-global
45757
45941
  *
45758
- * @task T1013
45942
+ * @task T1013 @task T13227
45759
45943
  */
45760
- async installHookTemplates() {
45761
- const claudeDir = getClaudeConfigDir();
45762
- const hooksDir = join8(claudeDir, "hooks");
45944
+ async installHookTemplates(projectDir) {
45945
+ const hooksDir = projectClaudeHooksDir(projectDir);
45946
+ const settingsPath = projectClaudeSettingsPath(projectDir);
45763
45947
  let templates;
45764
45948
  try {
45765
45949
  templates = installProviderHookTemplates({
@@ -45769,30 +45953,35 @@ var init_install = __esm({
45769
45953
  } catch {
45770
45954
  return null;
45771
45955
  }
45956
+ for (const file2 of PROJECT_HOOK_FILES) excludeHookFileFromGit(projectDir, file2);
45772
45957
  const settingsEntryAdded = await this.registerPreCompactHook(
45958
+ settingsPath,
45773
45959
  join8(hooksDir, "precompact-safestop.sh")
45774
45960
  );
45961
+ if (settingsEntryAdded) excludeLocalSettingsFromGit(projectDir);
45775
45962
  if (templates.installedFiles.length === 0 && !settingsEntryAdded) {
45776
45963
  return null;
45777
45964
  }
45778
45965
  return { templates, settingsEntryAdded };
45779
45966
  }
45780
45967
  /**
45781
- * Register the PreCompact hook command in `~/.claude/settings.json`.
45968
+ * Register the PreCompact hook command in the project's
45969
+ * `.claude/settings.local.json`.
45782
45970
  *
45783
45971
  * The Claude Code native event name for the canonical `PreCompact` event is
45784
45972
  * `PreCompact` (identity mapping — see `hook-mappings.json`). The entry is
45785
45973
  * tagged with `# cleo-hook` so the uninstall flow can identify and remove
45786
45974
  * our additions without touching user-authored hooks.
45787
45975
  *
45976
+ * @param settingsPath - The project settings file (already scope-checked).
45788
45977
  * @param shimPath - Absolute path to the installed `precompact-safestop.sh`.
45789
45978
  * @returns `true` when a new hook entry was written, `false` when an
45790
45979
  * equivalent entry was already present.
45791
45980
  *
45792
45981
  * @task T1013
45793
45982
  */
45794
- async registerPreCompactHook(shimPath) {
45795
- return updateJsonConfigFile3(claudeSettingsPath(), (settings) => {
45983
+ async registerPreCompactHook(settingsPath, shimPath) {
45984
+ return updateJsonConfigFile3(settingsPath, (settings) => {
45796
45985
  const hooks = hookMap(settings);
45797
45986
  if (hasCleoHook(hooks.PreCompact, "precompact-safestop.sh")) {
45798
45987
  return false;
@@ -45915,7 +46104,7 @@ var init_agent_spawn_wrapper = __esm({
45915
46104
  // packages/adapters/src/providers/shared/prompt-file.ts
45916
46105
  import { mkdtemp, rm, writeFile } from "node:fs/promises";
45917
46106
  import { tmpdir as tmpdir2 } from "node:os";
45918
- import { dirname as dirname5, join as join9 } from "node:path";
46107
+ import { dirname as dirname6, join as join9 } from "node:path";
45919
46108
  async function writeSpawnPromptFile(prefix, prompt) {
45920
46109
  const dir = await mkdtemp(join9(tmpdir2(), `cleo-${prefix}-`));
45921
46110
  const file2 = join9(dir, "prompt.txt");
@@ -45923,7 +46112,7 @@ async function writeSpawnPromptFile(prefix, prompt) {
45923
46112
  return file2;
45924
46113
  }
45925
46114
  async function removeSpawnPromptFile(file2) {
45926
- await rm(dirname5(file2), { recursive: true, force: true }).catch(() => void 0);
46115
+ await rm(dirname6(file2), { recursive: true, force: true }).catch(() => void 0);
45927
46116
  }
45928
46117
  var init_prompt_file = __esm({
45929
46118
  "packages/adapters/src/providers/shared/prompt-file.ts"() {
@@ -46015,7 +46204,7 @@ function isEsrch(err) {
46015
46204
  return false;
46016
46205
  }
46017
46206
  function sleep(ms) {
46018
- return new Promise((resolve5) => setTimeout(resolve5, ms));
46207
+ return new Promise((resolve6) => setTimeout(resolve6, ms));
46019
46208
  }
46020
46209
  var SIGTERM_GRACE_MS;
46021
46210
  var init_suite_reaper = __esm({
@@ -46309,7 +46498,7 @@ var init_transport = __esm({
46309
46498
 
46310
46499
  // packages/adapters/src/providers/claude-code/adapter.ts
46311
46500
  import { existsSync as existsSync8 } from "node:fs";
46312
- import { homedir as homedir6 } from "node:os";
46501
+ import { homedir as homedir5 } from "node:os";
46313
46502
  import { join as join11 } from "node:path";
46314
46503
  import { findOnPath as findOnPath2 } from "@cleocode/paths";
46315
46504
  var ClaudeCodeAdapter;
@@ -46463,7 +46652,7 @@ var init_adapter = __esm({
46463
46652
  cliAvailable = resolvedCli !== null;
46464
46653
  if (resolvedCli) details.cliPath = resolvedCli;
46465
46654
  else details.cliAvailable = false;
46466
- const claudeConfigDir = join11(homedir6(), ".claude");
46655
+ const claudeConfigDir = join11(homedir5(), ".claude");
46467
46656
  const configExists = existsSync8(claudeConfigDir);
46468
46657
  details.configDirExists = configExists;
46469
46658
  const entrypointSet = process.env.CLAUDE_CODE_ENTRYPOINT !== void 0;
@@ -46494,10 +46683,10 @@ var init_adapter = __esm({
46494
46683
 
46495
46684
  // packages/adapters/src/providers/claude-code/statusline.ts
46496
46685
  import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
46497
- import { homedir as homedir7 } from "node:os";
46686
+ import { homedir as homedir6 } from "node:os";
46498
46687
  import { join as join12 } from "node:path";
46499
46688
  function getClaudeSettingsPath() {
46500
- return process.env["CLAUDE_SETTINGS"] ?? join12(process.env["CLAUDE_HOME"] ?? join12(homedir7(), ".claude"), "settings.json");
46689
+ return process.env["CLAUDE_SETTINGS"] ?? join12(process.env["CLAUDE_HOME"] ?? join12(homedir6(), ".claude"), "settings.json");
46501
46690
  }
46502
46691
  function checkStatuslineIntegration() {
46503
46692
  const settingsPath = getClaudeSettingsPath();
@@ -46511,7 +46700,7 @@ function checkStatuslineIntegration() {
46511
46700
  if (cmd.includes("context-monitor.sh") || cmd.includes("cleo-statusline") || cmd.includes(".context-state.json") || cmd.includes("context-states")) {
46512
46701
  return "configured";
46513
46702
  }
46514
- const scriptPath = cmd.startsWith("~") ? cmd.replace("~", homedir7()) : cmd;
46703
+ const scriptPath = cmd.startsWith("~") ? cmd.replace("~", homedir6()) : cmd;
46515
46704
  if (existsSync9(scriptPath)) {
46516
46705
  try {
46517
46706
  const content = readFileSync7(scriptPath, "utf-8");
@@ -46593,6 +46782,25 @@ var init_paths2 = __esm({
46593
46782
  }
46594
46783
  });
46595
46784
 
46785
+ // packages/adapters/src/providers/shared/project-instruction-file.ts
46786
+ import {
46787
+ ensureProviderInstructionFile as ensureProviderInstructionFile2,
46788
+ HomeInstructionFileError
46789
+ } from "@cleocode/caamp";
46790
+ async function ensureProjectInstructionFile(providerId, projectDir, options) {
46791
+ try {
46792
+ return await ensureProviderInstructionFile2(providerId, projectDir, options);
46793
+ } catch (err) {
46794
+ if (err instanceof HomeInstructionFileError) return null;
46795
+ throw err;
46796
+ }
46797
+ }
46798
+ var init_project_instruction_file = __esm({
46799
+ "packages/adapters/src/providers/shared/project-instruction-file.ts"() {
46800
+ "use strict";
46801
+ }
46802
+ });
46803
+
46596
46804
  // packages/adapters/src/providers/shared/cli-spawn.ts
46597
46805
  import { spawn } from "node:child_process";
46598
46806
  import { resolveSpawnInvocation as resolveSpawnInvocation2 } from "@cleocode/paths";
@@ -46767,7 +46975,7 @@ var init_hooks2 = __esm({
46767
46975
  import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
46768
46976
  import { join as join18 } from "node:path";
46769
46977
  import {
46770
- ensureProviderInstructionFile as ensureProviderInstructionFile3,
46978
+ ensureProviderInstructionFile as ensureProviderInstructionFile4,
46771
46979
  ensureProviderRuleFile,
46772
46980
  updateJsonConfigFile as updateJsonConfigFile4
46773
46981
  } from "@cleocode/caamp";
@@ -46778,8 +46986,10 @@ var CLEO_MDC_FRONTMATTER, CursorInstallProvider;
46778
46986
  var init_install2 = __esm({
46779
46987
  "packages/adapters/src/providers/cursor/install.ts"() {
46780
46988
  "use strict";
46989
+ init_heavy_command_hook_install();
46781
46990
  init_hook_template_installer();
46782
46991
  init_paths2();
46992
+ init_project_instruction_file();
46783
46993
  CLEO_MDC_FRONTMATTER = [
46784
46994
  "---",
46785
46995
  "description: CLEO task management protocol references",
@@ -46800,21 +47010,29 @@ var init_install2 = __esm({
46800
47010
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
46801
47011
  let instructionFileUpdated = false;
46802
47012
  const details = {};
46803
- const instructionResult = await ensureProviderInstructionFile3("cursor", projectDir, {});
46804
- const cursorFilesUpdated = await this.updateInstructionFiles(projectDir);
46805
- instructionFileUpdated = instructionResult.action !== "intact" || cursorFilesUpdated;
46806
- if (instructionFileUpdated) {
46807
- details.instructionFiles = this.getUpdatedFileList(projectDir);
47013
+ const instructionResult = await ensureProjectInstructionFile("cursor", projectDir, {});
47014
+ if (instructionResult === null) {
47015
+ details.instructionFiles = "skipped";
47016
+ } else {
47017
+ const cursorFilesUpdated = await this.updateInstructionFiles(projectDir);
47018
+ instructionFileUpdated = instructionResult.action !== "intact" || cursorFilesUpdated;
47019
+ if (instructionFileUpdated) {
47020
+ details.instructionFiles = this.getUpdatedFileList(projectDir);
47021
+ }
46808
47022
  }
46809
47023
  let hooksError = null;
46810
- try {
46811
- const hookResult = await this.installHookTemplates(projectDir);
46812
- if (hookResult) {
46813
- details.hookTemplates = hookResult;
47024
+ if (isUserHomeDir(projectDir)) {
47025
+ details.hookTemplates = "skipped";
47026
+ } else {
47027
+ try {
47028
+ const hookResult = await this.installHookTemplates(projectDir);
47029
+ if (hookResult) {
47030
+ details.hookTemplates = hookResult;
47031
+ }
47032
+ } catch (err) {
47033
+ hooksError = err instanceof Error ? err.message : String(err);
47034
+ details.hooksError = hooksError;
46814
47035
  }
46815
- } catch (err) {
46816
- hooksError = err instanceof Error ? err.message : String(err);
46817
- details.hooksError = hooksError;
46818
47036
  }
46819
47037
  return {
46820
47038
  success: hooksError === null,
@@ -46862,7 +47080,7 @@ var init_install2 = __esm({
46862
47080
  * @param projectDir - Project root directory
46863
47081
  */
46864
47082
  async ensureInstructionReferences(projectDir) {
46865
- await ensureProviderInstructionFile3("cursor", projectDir, {});
47083
+ await ensureProviderInstructionFile4("cursor", projectDir, {});
46866
47084
  await this.updateInstructionFiles(projectDir);
46867
47085
  }
46868
47086
  /**
@@ -47294,7 +47512,7 @@ var init_hooks3 = __esm({
47294
47512
  // packages/adapters/src/providers/opencode/install.ts
47295
47513
  import { existsSync as existsSync18, mkdirSync as mkdirSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "node:fs";
47296
47514
  import { join as join25 } from "node:path";
47297
- import { ensureProviderInstructionFile as ensureProviderInstructionFile6 } from "@cleocode/caamp";
47515
+ import { ensureProviderInstructionFile as ensureProviderInstructionFile7 } from "@cleocode/caamp";
47298
47516
  var OpenCodeInstallProvider;
47299
47517
  var init_install3 = __esm({
47300
47518
  "packages/adapters/src/providers/opencode/install.ts"() {
@@ -47302,6 +47520,7 @@ var init_install3 = __esm({
47302
47520
  init_heavy_command_hook_install();
47303
47521
  init_hook_template_installer();
47304
47522
  init_paths2();
47523
+ init_project_instruction_file();
47305
47524
  OpenCodeInstallProvider = class {
47306
47525
  /**
47307
47526
  * Install CLEO into an OpenCode project.
@@ -47313,14 +47532,15 @@ var init_install3 = __esm({
47313
47532
  const { projectDir } = options;
47314
47533
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
47315
47534
  const details = {};
47316
- const instructResult = await ensureProviderInstructionFile6("opencode", projectDir, {
47535
+ const instructResult = await ensureProjectInstructionFile("opencode", projectDir, {
47317
47536
  scope: "project",
47318
47537
  references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"]
47319
47538
  });
47320
- const instructionFileUpdated = instructResult.action !== "intact";
47539
+ const instructionFileUpdated = instructResult !== null && instructResult.action !== "intact";
47321
47540
  if (instructionFileUpdated) {
47322
47541
  details.instructionFile = join25(projectDir, instructResult.instructFile);
47323
47542
  }
47543
+ if (instructResult === null) details.instructionFile = "skipped";
47324
47544
  const hookResult = this.installHookTemplates(projectDir);
47325
47545
  if (hookResult) {
47326
47546
  details.hookTemplates = hookResult;
@@ -47360,7 +47580,7 @@ var init_install3 = __esm({
47360
47580
  */
47361
47581
  async isInstalled() {
47362
47582
  try {
47363
- const result = await ensureProviderInstructionFile6("opencode", process.cwd(), {
47583
+ const result = await ensureProviderInstructionFile7("opencode", process.cwd(), {
47364
47584
  scope: "project",
47365
47585
  references: [
47366
47586
  `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
@@ -47380,7 +47600,7 @@ var init_install3 = __esm({
47380
47600
  * @param projectDir - Project root directory
47381
47601
  */
47382
47602
  async ensureInstructionReferences(projectDir) {
47383
- await ensureProviderInstructionFile6("opencode", projectDir, {
47603
+ await ensureProviderInstructionFile7("opencode", projectDir, {
47384
47604
  scope: "project",
47385
47605
  references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"]
47386
47606
  });
@@ -47988,7 +48208,7 @@ var init_hooks4 = __esm({
47988
48208
 
47989
48209
  // packages/adapters/src/providers/pi/install.ts
47990
48210
  import { join as join29 } from "node:path";
47991
- import { ensureProviderInstructionFile as ensureProviderInstructionFile7 } from "@cleocode/caamp";
48211
+ import { ensureProviderInstructionFile as ensureProviderInstructionFile8 } from "@cleocode/caamp";
47992
48212
  function getCleoReferences() {
47993
48213
  return [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"];
47994
48214
  }
@@ -47997,6 +48217,7 @@ var init_install4 = __esm({
47997
48217
  "packages/adapters/src/providers/pi/install.ts"() {
47998
48218
  "use strict";
47999
48219
  init_paths2();
48220
+ init_project_instruction_file();
48000
48221
  PiInstallProvider = class {
48001
48222
  /**
48002
48223
  * Install CLEO into a Pi coding agent project.
@@ -48008,17 +48229,18 @@ var init_install4 = __esm({
48008
48229
  const { projectDir } = options;
48009
48230
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
48010
48231
  const details = {};
48011
- const projectResult = await ensureProviderInstructionFile7("pi", projectDir, {
48232
+ const projectResult = await ensureProjectInstructionFile("pi", projectDir, {
48012
48233
  scope: "project",
48013
48234
  references: getCleoReferences()
48014
48235
  });
48015
- const projectUpdated = projectResult.action !== "intact";
48236
+ const projectUpdated = projectResult !== null && projectResult.action !== "intact";
48016
48237
  if (projectUpdated) {
48017
48238
  details.instructionFile = join29(projectDir, projectResult.instructFile);
48018
48239
  }
48240
+ if (projectResult === null) details.instructionFile = "skipped";
48019
48241
  let globalUpdated = false;
48020
48242
  try {
48021
- const globalResult = await ensureProviderInstructionFile7("pi", projectDir, {
48243
+ const globalResult = await ensureProviderInstructionFile8("pi", projectDir, {
48022
48244
  scope: "global",
48023
48245
  references: getCleoReferences()
48024
48246
  });
@@ -48050,7 +48272,7 @@ var init_install4 = __esm({
48050
48272
  */
48051
48273
  async isInstalled() {
48052
48274
  try {
48053
- const result = await ensureProviderInstructionFile7("pi", process.cwd(), {
48275
+ const result = await ensureProviderInstructionFile8("pi", process.cwd(), {
48054
48276
  scope: "project",
48055
48277
  references: getCleoReferences()
48056
48278
  });
@@ -48058,7 +48280,7 @@ var init_install4 = __esm({
48058
48280
  } catch {
48059
48281
  }
48060
48282
  try {
48061
- const result = await ensureProviderInstructionFile7("pi", process.cwd(), {
48283
+ const result = await ensureProviderInstructionFile8("pi", process.cwd(), {
48062
48284
  scope: "global",
48063
48285
  references: getCleoReferences()
48064
48286
  });
@@ -48075,7 +48297,7 @@ var init_install4 = __esm({
48075
48297
  * @param projectDir - Project root directory
48076
48298
  */
48077
48299
  async ensureInstructionReferences(projectDir) {
48078
- await ensureProviderInstructionFile7("pi", projectDir, {
48300
+ await ensureProviderInstructionFile8("pi", projectDir, {
48079
48301
  scope: "project",
48080
48302
  references: getCleoReferences()
48081
48303
  });
@@ -48220,21 +48442,21 @@ var init_spawn4 = __esm({
48220
48442
 
48221
48443
  // packages/adapters/src/providers/pi/adapter.ts
48222
48444
  import { existsSync as existsSync21 } from "node:fs";
48223
- import { homedir as homedir14 } from "node:os";
48445
+ import { homedir as homedir13 } from "node:os";
48224
48446
  import { join as join30 } from "node:path";
48225
48447
  import { findOnPath as findOnPath13 } from "@cleocode/paths";
48226
48448
  function getPiAgentDir() {
48227
48449
  const env = process.env["PI_CODING_AGENT_DIR"];
48228
48450
  if (env !== void 0 && env.length > 0) {
48229
- if (env === "~") return homedir14();
48230
- if (env.startsWith("~/")) return join30(homedir14(), env.slice(2));
48451
+ if (env === "~") return homedir13();
48452
+ if (env.startsWith("~/")) return join30(homedir13(), env.slice(2));
48231
48453
  return env;
48232
48454
  }
48233
48455
  const piHome = process.env["PI_HOME"];
48234
48456
  if (piHome !== void 0 && piHome.length > 0) {
48235
48457
  return join30(piHome, "agent");
48236
48458
  }
48237
- return join30(homedir14(), ".pi", "agent");
48459
+ return join30(homedir13(), ".pi", "agent");
48238
48460
  }
48239
48461
  var PiAdapter;
48240
48462
  var init_adapter4 = __esm({
@@ -48559,12 +48781,12 @@ function createAdapter2() {
48559
48781
 
48560
48782
  // packages/adapters/src/providers/codex/adapter.ts
48561
48783
  import { existsSync as existsSync11 } from "node:fs";
48562
- import { homedir as homedir9 } from "node:os";
48784
+ import { homedir as homedir8 } from "node:os";
48563
48785
  import { join as join17 } from "node:path";
48564
48786
  import { findOnPath as findOnPath3 } from "@cleocode/paths";
48565
48787
 
48566
48788
  // packages/adapters/src/providers/codex/hooks.ts
48567
- import { homedir as homedir8 } from "node:os";
48789
+ import { homedir as homedir7 } from "node:os";
48568
48790
  import { join as join15 } from "node:path";
48569
48791
 
48570
48792
  // packages/adapters/src/providers/shared/transcript-reader.ts
@@ -48684,15 +48906,16 @@ var CodexHookProvider = class {
48684
48906
  * @task T162 @epic T134
48685
48907
  */
48686
48908
  async getTranscript(_sessionId, _projectDir) {
48687
- return readLatestTranscript(join15(homedir8(), ".codex"));
48909
+ return readLatestTranscript(join15(homedir7(), ".codex"));
48688
48910
  }
48689
48911
  };
48690
48912
 
48691
48913
  // packages/adapters/src/providers/codex/install.ts
48692
48914
  init_heavy_command_hook_install();
48693
48915
  init_paths2();
48916
+ init_project_instruction_file();
48694
48917
  import { join as join16 } from "node:path";
48695
- import { ensureProviderInstructionFile as ensureProviderInstructionFile2 } from "@cleocode/caamp";
48918
+ import { ensureProviderInstructionFile as ensureProviderInstructionFile3 } from "@cleocode/caamp";
48696
48919
  var CodexInstallProvider = class {
48697
48920
  /**
48698
48921
  * Install CLEO into a Codex CLI environment.
@@ -48705,14 +48928,15 @@ var CodexInstallProvider = class {
48705
48928
  const { projectDir } = options;
48706
48929
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
48707
48930
  const details = {};
48708
- const result = await ensureProviderInstructionFile2("codex", projectDir, {
48931
+ const result = await ensureProjectInstructionFile("codex", projectDir, {
48709
48932
  scope: "project",
48710
48933
  references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"]
48711
48934
  });
48712
- const instructionFileUpdated = result.action !== "intact";
48935
+ const instructionFileUpdated = result !== null && result.action !== "intact";
48713
48936
  if (instructionFileUpdated) {
48714
48937
  details.instructionFile = join16(projectDir, result.instructFile);
48715
48938
  }
48939
+ if (result === null) details.instructionFile = "skipped";
48716
48940
  let success2 = true;
48717
48941
  if (options.heavyCommandHook !== void 0 && isUserHomeDir(projectDir)) {
48718
48942
  details.heavyCommandHook = "skipped";
@@ -48750,7 +48974,7 @@ var CodexInstallProvider = class {
48750
48974
  */
48751
48975
  async isInstalled() {
48752
48976
  try {
48753
- const result = await ensureProviderInstructionFile2("codex", process.cwd(), {
48977
+ const result = await ensureProviderInstructionFile3("codex", process.cwd(), {
48754
48978
  scope: "project",
48755
48979
  references: [
48756
48980
  `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
@@ -48771,7 +48995,7 @@ var CodexInstallProvider = class {
48771
48995
  * @task T162
48772
48996
  */
48773
48997
  async ensureInstructionReferences(projectDir) {
48774
- await ensureProviderInstructionFile2("codex", projectDir, {
48998
+ await ensureProviderInstructionFile3("codex", projectDir, {
48775
48999
  scope: "project",
48776
49000
  references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"]
48777
49001
  });
@@ -48859,7 +49083,7 @@ var CodexAdapter = class {
48859
49083
  cliAvailable = resolvedCli !== null;
48860
49084
  if (resolvedCli) details.cliPath = resolvedCli;
48861
49085
  else details.cliAvailable = false;
48862
- const codexConfigDir = join17(homedir9(), ".codex");
49086
+ const codexConfigDir = join17(homedir8(), ".codex");
48863
49087
  const configExists = existsSync11(codexConfigDir);
48864
49088
  details.configDirExists = configExists;
48865
49089
  const healthy = cliAvailable;
@@ -48902,12 +49126,12 @@ init_cursor();
48902
49126
 
48903
49127
  // packages/adapters/src/providers/gemini-cli/adapter.ts
48904
49128
  import { existsSync as existsSync15 } from "node:fs";
48905
- import { homedir as homedir11 } from "node:os";
49129
+ import { homedir as homedir10 } from "node:os";
48906
49130
  import { join as join22 } from "node:path";
48907
49131
  import { findOnPath as findOnPath5 } from "@cleocode/paths";
48908
49132
 
48909
49133
  // packages/adapters/src/providers/gemini-cli/hooks.ts
48910
- import { homedir as homedir10 } from "node:os";
49134
+ import { homedir as homedir9 } from "node:os";
48911
49135
  import { join as join20 } from "node:path";
48912
49136
  var GEMINI_CLI_EVENT_MAP = {
48913
49137
  SessionStart: "SessionStart",
@@ -48986,15 +49210,16 @@ var GeminiCliHookProvider = class {
48986
49210
  * @task T161 @epic T134
48987
49211
  */
48988
49212
  async getTranscript(_sessionId, _projectDir) {
48989
- return readLatestTranscript(join20(homedir10(), ".gemini"));
49213
+ return readLatestTranscript(join20(homedir9(), ".gemini"));
48990
49214
  }
48991
49215
  };
48992
49216
 
48993
49217
  // packages/adapters/src/providers/gemini-cli/install.ts
48994
49218
  init_paths2();
49219
+ init_project_instruction_file();
48995
49220
  import { existsSync as existsSync14, readFileSync as readFileSync9 } from "node:fs";
48996
49221
  import { join as join21 } from "node:path";
48997
- import { ensureProviderInstructionFile as ensureProviderInstructionFile4 } from "@cleocode/caamp";
49222
+ import { ensureProviderInstructionFile as ensureProviderInstructionFile5 } from "@cleocode/caamp";
48998
49223
  var GeminiCliInstallProvider = class {
48999
49224
  /**
49000
49225
  * Install CLEO into a Gemini CLI environment.
@@ -49007,14 +49232,15 @@ var GeminiCliInstallProvider = class {
49007
49232
  const { projectDir } = options;
49008
49233
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
49009
49234
  const details = {};
49010
- const result = await ensureProviderInstructionFile4("gemini-cli", projectDir, {
49235
+ const result = await ensureProjectInstructionFile("gemini-cli", projectDir, {
49011
49236
  references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"],
49012
49237
  scope: "project"
49013
49238
  });
49014
- const instructionFileUpdated = result.action !== "intact";
49239
+ const instructionFileUpdated = result !== null && result.action !== "intact";
49015
49240
  if (instructionFileUpdated) {
49016
49241
  details.instructionFile = result.filePath;
49017
49242
  }
49243
+ if (result === null) details.instructionFile = "skipped";
49018
49244
  return {
49019
49245
  success: true,
49020
49246
  installedAt,
@@ -49059,7 +49285,7 @@ var GeminiCliInstallProvider = class {
49059
49285
  * @task T161
49060
49286
  */
49061
49287
  async ensureInstructionReferences(projectDir) {
49062
- await ensureProviderInstructionFile4("gemini-cli", projectDir, {
49288
+ await ensureProviderInstructionFile5("gemini-cli", projectDir, {
49063
49289
  references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"],
49064
49290
  scope: "project"
49065
49291
  });
@@ -49158,7 +49384,7 @@ var GeminiCliAdapter = class {
49158
49384
  cliAvailable = resolvedCli !== null;
49159
49385
  if (resolvedCli) details.cliPath = resolvedCli;
49160
49386
  else details.cliAvailable = false;
49161
- const geminiConfigDir = join22(homedir11(), ".gemini");
49387
+ const geminiConfigDir = join22(homedir10(), ".gemini");
49162
49388
  const configExists = existsSync15(geminiConfigDir);
49163
49389
  details.configDirExists = configExists;
49164
49390
  const healthy = cliAvailable;
@@ -49197,7 +49423,7 @@ function createAdapter5() {
49197
49423
 
49198
49424
  // packages/adapters/src/providers/kimi/adapter.ts
49199
49425
  import { existsSync as existsSync17 } from "node:fs";
49200
- import { homedir as homedir12 } from "node:os";
49426
+ import { homedir as homedir11 } from "node:os";
49201
49427
  import { join as join24 } from "node:path";
49202
49428
  import { findOnPath as findOnPath7 } from "@cleocode/paths";
49203
49429
 
@@ -49258,9 +49484,10 @@ var KimiHookProvider = class {
49258
49484
 
49259
49485
  // packages/adapters/src/providers/kimi/install.ts
49260
49486
  init_paths2();
49487
+ init_project_instruction_file();
49261
49488
  import { existsSync as existsSync16, readFileSync as readFileSync10 } from "node:fs";
49262
49489
  import { join as join23 } from "node:path";
49263
- import { ensureProviderInstructionFile as ensureProviderInstructionFile5 } from "@cleocode/caamp";
49490
+ import { ensureProviderInstructionFile as ensureProviderInstructionFile6 } from "@cleocode/caamp";
49264
49491
  var KimiInstallProvider = class {
49265
49492
  /**
49266
49493
  * Install CLEO into a Kimi environment.
@@ -49273,14 +49500,15 @@ var KimiInstallProvider = class {
49273
49500
  const { projectDir } = options;
49274
49501
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
49275
49502
  const details = {};
49276
- const result = await ensureProviderInstructionFile5("kimi", projectDir, {
49503
+ const result = await ensureProjectInstructionFile("kimi", projectDir, {
49277
49504
  references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"],
49278
49505
  scope: "project"
49279
49506
  });
49280
- const instructionFileUpdated = result.action !== "intact";
49507
+ const instructionFileUpdated = result !== null && result.action !== "intact";
49281
49508
  if (instructionFileUpdated) {
49282
49509
  details.instructionFile = result.filePath;
49283
49510
  }
49511
+ if (result === null) details.instructionFile = "skipped";
49284
49512
  return {
49285
49513
  success: true,
49286
49514
  installedAt,
@@ -49325,7 +49553,7 @@ var KimiInstallProvider = class {
49325
49553
  * @task T163
49326
49554
  */
49327
49555
  async ensureInstructionReferences(projectDir) {
49328
- await ensureProviderInstructionFile5("kimi", projectDir, {
49556
+ await ensureProviderInstructionFile6("kimi", projectDir, {
49329
49557
  references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"],
49330
49558
  scope: "project"
49331
49559
  });
@@ -49411,7 +49639,7 @@ var KimiAdapter = class {
49411
49639
  cliAvailable = resolvedCli !== null;
49412
49640
  if (resolvedCli) details.cliPath = resolvedCli;
49413
49641
  else details.cliAvailable = false;
49414
- const kimiConfigDir = join24(homedir12(), ".kimi");
49642
+ const kimiConfigDir = join24(homedir11(), ".kimi");
49415
49643
  const configExists = existsSync17(kimiConfigDir);
49416
49644
  details.configDirExists = configExists;
49417
49645
  const healthy = cliAvailable;
@@ -49455,8 +49683,8 @@ init_heavy_command_hook_install();
49455
49683
  init_hook_config();
49456
49684
  import { execFileSync as execFileSync2, spawnSync as spawnSync3 } from "node:child_process";
49457
49685
  import { existsSync as existsSync20, lstatSync, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
49458
- import { homedir as homedir13 } from "node:os";
49459
- import { dirname as dirname6, join as join28 } from "node:path";
49686
+ import { homedir as homedir12 } from "node:os";
49687
+ import { dirname as dirname7, join as join28 } from "node:path";
49460
49688
  import { JsonConfigParseError } from "@cleocode/caamp";
49461
49689
  import { findOnPath as findOnPath11 } from "@cleocode/paths";
49462
49690
  var HEAVY_HOOK_DELIVERY_PROVIDERS = Object.freeze([
@@ -49470,7 +49698,7 @@ var CODEX_SHARED_REMEDY = "if the team wants Codex governed here, add CLEO's Pre
49470
49698
  var KIMI_REASON = "Kimi reads hooks only from its global ~/.kimi/config.toml, and CLEO never writes user-global configs";
49471
49699
  var KIMI_REMEDY = "add a [[hooks]] entry for PreToolUse that runs `cleo hook heavy-command --provider kimi` to ~/.kimi/config.toml yourself";
49472
49700
  function homeOf(env) {
49473
- return env.HOME || homedir13();
49701
+ return env.HOME || homedir12();
49474
49702
  }
49475
49703
  function heavyHookTarget(provider, projectDir, env = process.env) {
49476
49704
  switch (provider) {
@@ -49734,7 +49962,7 @@ function inspectProvider(provider, projectDir, mode, env, gitChecks) {
49734
49962
  snippet: codexHookSnippet()
49735
49963
  };
49736
49964
  }
49737
- const blocked = nonDirectoryAncestor(dirname6(target));
49965
+ const blocked = nonDirectoryAncestor(dirname7(target));
49738
49966
  if (blocked !== null) {
49739
49967
  return {
49740
49968
  ...base,
@@ -49838,12 +50066,12 @@ init_hook_template_installer();
49838
50066
 
49839
50067
  // packages/adapters/src/registry.ts
49840
50068
  import { readFileSync as readFileSync13 } from "node:fs";
49841
- import { dirname as dirname7, join as join31, resolve as resolve4 } from "node:path";
50069
+ import { dirname as dirname8, join as join31, resolve as resolve5 } from "node:path";
49842
50070
  import { fileURLToPath as fileURLToPath3 } from "node:url";
49843
50071
  var PROVIDER_IDS = ["claude-code", "opencode", "cursor", "pi"];
49844
50072
  function getProviderManifests() {
49845
50073
  const manifests = [];
49846
- const baseDir = resolve4(dirname7(fileURLToPath3(import.meta.url)), "providers");
50074
+ const baseDir = resolve5(dirname8(fileURLToPath3(import.meta.url)), "providers");
49847
50075
  for (const providerId of PROVIDER_IDS) {
49848
50076
  try {
49849
50077
  const manifestPath = join31(baseDir, providerId, "manifest.json");