@cleocode/adapters 2026.10.3 → 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.
- package/dist/heavy-command-hook.d.ts +12 -0
- package/dist/heavy-command-hook.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2095 -1269
- package/dist/index.js.map +3 -3
- package/dist/providers/claude-code/adapter.d.ts.map +1 -1
- package/dist/providers/claude-code/hooks.d.ts +43 -17
- package/dist/providers/claude-code/hooks.d.ts.map +1 -1
- package/dist/providers/claude-code/install.d.ts +42 -14
- package/dist/providers/claude-code/install.d.ts.map +1 -1
- package/dist/providers/claude-code/paths.d.ts +77 -0
- package/dist/providers/claude-code/paths.d.ts.map +1 -1
- package/dist/providers/codex/install.d.ts.map +1 -1
- package/dist/providers/cursor/install.d.ts.map +1 -1
- package/dist/providers/gemini-cli/install.d.ts.map +1 -1
- package/dist/providers/kimi/install.d.ts.map +1 -1
- package/dist/providers/openai-sdk/install.d.ts.map +1 -1
- package/dist/providers/opencode/install.d.ts.map +1 -1
- package/dist/providers/pi/install.d.ts.map +1 -1
- package/dist/providers/shared/heavy-command-hook-delivery.d.ts +97 -0
- package/dist/providers/shared/heavy-command-hook-delivery.d.ts.map +1 -0
- package/dist/providers/shared/heavy-command-hook-install.d.ts +153 -7
- package/dist/providers/shared/heavy-command-hook-install.d.ts.map +1 -1
- package/dist/providers/shared/project-instruction-file.d.ts +30 -0
- package/dist/providers/shared/project-instruction-file.d.ts.map +1 -0
- package/package.json +9 -5
- package/src/__tests__/claude-code-adapter.test.ts +11 -6
- package/src/heavy-command-hook.ts +21 -0
- package/src/index.ts +12 -0
- package/src/providers/claude-code/__tests__/hooks-install.test.ts +20 -17
- package/src/providers/claude-code/__tests__/no-user-global-write.test.ts +293 -0
- package/src/providers/claude-code/adapter.ts +3 -1
- package/src/providers/claude-code/hooks.ts +138 -51
- package/src/providers/claude-code/install.ts +123 -52
- package/src/providers/claude-code/paths.ts +159 -1
- package/src/providers/codex/install.ts +7 -6
- package/src/providers/cursor/install.ts +26 -12
- package/src/providers/gemini-cli/install.ts +4 -2
- package/src/providers/kimi/install.ts +4 -2
- package/src/providers/openai-sdk/install.ts +5 -2
- package/src/providers/opencode/install.ts +4 -2
- package/src/providers/pi/install.ts +4 -2
- package/src/providers/shared/__tests__/heavy-command-hook-delivery.test.ts +580 -0
- package/src/providers/shared/__tests__/heavy-command-hook-install.test.ts +20 -0
- package/src/providers/shared/heavy-command-hook-delivery.ts +620 -0
- package/src/providers/shared/heavy-command-hook-install.ts +401 -32
- 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-
|
|
1621
|
-
var
|
|
1622
|
-
var
|
|
1623
|
-
"packages/contracts/src/docs-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
13413
|
-
provenanceEdgeRelationSchema =
|
|
13414
|
-
docLifecycleStatusSchema =
|
|
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:
|
|
13417
|
-
title:
|
|
13418
|
-
metadata:
|
|
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 =
|
|
13277
|
+
provenanceDocNodeSchema = z7.object({
|
|
13421
13278
|
...provenanceNodeBaseFields,
|
|
13422
|
-
kind:
|
|
13423
|
-
slug:
|
|
13424
|
-
docKind:
|
|
13279
|
+
kind: z7.literal("doc"),
|
|
13280
|
+
slug: z7.string().min(1),
|
|
13281
|
+
docKind: z7.string().min(1),
|
|
13425
13282
|
lifecycleStatus: docLifecycleStatusSchema,
|
|
13426
|
-
publishedAt:
|
|
13427
|
-
supersededAt:
|
|
13428
|
-
summary:
|
|
13283
|
+
publishedAt: z7.string().min(1),
|
|
13284
|
+
supersededAt: z7.string().min(1).optional(),
|
|
13285
|
+
summary: z7.string().optional()
|
|
13429
13286
|
});
|
|
13430
|
-
provenanceTaskNodeSchema =
|
|
13287
|
+
provenanceTaskNodeSchema = z7.object({
|
|
13431
13288
|
...provenanceNodeBaseFields,
|
|
13432
|
-
kind:
|
|
13433
|
-
taskType:
|
|
13434
|
-
status:
|
|
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 =
|
|
13293
|
+
provenanceDecisionNodeSchema = z7.object({
|
|
13437
13294
|
...provenanceNodeBaseFields,
|
|
13438
|
-
kind:
|
|
13439
|
-
outcome:
|
|
13440
|
-
decidedAt:
|
|
13295
|
+
kind: z7.literal("decision"),
|
|
13296
|
+
outcome: z7.enum(["proposed", "accepted", "rejected", "superseded"]),
|
|
13297
|
+
decidedAt: z7.string().min(1)
|
|
13441
13298
|
});
|
|
13442
|
-
provenanceSessionNodeSchema =
|
|
13299
|
+
provenanceSessionNodeSchema = z7.object({
|
|
13443
13300
|
...provenanceNodeBaseFields,
|
|
13444
|
-
kind:
|
|
13445
|
-
startedAt:
|
|
13446
|
-
endedAt:
|
|
13301
|
+
kind: z7.literal("session"),
|
|
13302
|
+
startedAt: z7.string().min(1),
|
|
13303
|
+
endedAt: z7.string().min(1).optional()
|
|
13447
13304
|
});
|
|
13448
|
-
provenanceMemoryNodeSchema =
|
|
13305
|
+
provenanceMemoryNodeSchema = z7.object({
|
|
13449
13306
|
...provenanceNodeBaseFields,
|
|
13450
|
-
kind:
|
|
13451
|
-
memoryType:
|
|
13452
|
-
recordedAt:
|
|
13307
|
+
kind: z7.literal("memory"),
|
|
13308
|
+
memoryType: z7.enum(["observation", "pattern", "decision", "diary"]),
|
|
13309
|
+
recordedAt: z7.string().min(1)
|
|
13453
13310
|
});
|
|
13454
|
-
provenanceNodeSchema =
|
|
13311
|
+
provenanceNodeSchema = z7.discriminatedUnion("kind", [
|
|
13455
13312
|
provenanceDocNodeSchema,
|
|
13456
13313
|
provenanceTaskNodeSchema,
|
|
13457
13314
|
provenanceDecisionNodeSchema,
|
|
13458
13315
|
provenanceSessionNodeSchema,
|
|
13459
13316
|
provenanceMemoryNodeSchema
|
|
13460
13317
|
]);
|
|
13461
|
-
provenanceEdgeSchema =
|
|
13318
|
+
provenanceEdgeSchema = z7.object({
|
|
13462
13319
|
relation: provenanceEdgeRelationSchema,
|
|
13463
|
-
from:
|
|
13320
|
+
from: z7.string().min(1),
|
|
13464
13321
|
fromKind: provenanceNodeKindSchema,
|
|
13465
|
-
to:
|
|
13322
|
+
to: z7.string().min(1),
|
|
13466
13323
|
toKind: provenanceNodeKindSchema,
|
|
13467
|
-
addedAt:
|
|
13468
|
-
summary:
|
|
13324
|
+
addedAt: z7.string().min(1),
|
|
13325
|
+
summary: z7.string().optional()
|
|
13469
13326
|
});
|
|
13470
|
-
docProvenanceResponseSchema =
|
|
13471
|
-
nodes:
|
|
13472
|
-
edges:
|
|
13473
|
-
totalNodes:
|
|
13474
|
-
totalEdges:
|
|
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
|
|
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 =
|
|
13486
|
-
slug:
|
|
13487
|
-
kind:
|
|
13488
|
-
title:
|
|
13489
|
-
summary:
|
|
13490
|
-
lifecycleStatus:
|
|
13491
|
-
docVersion:
|
|
13492
|
-
ownerVersion:
|
|
13493
|
-
supersedes:
|
|
13494
|
-
supersededBy:
|
|
13495
|
-
topics:
|
|
13496
|
-
relatedTasks:
|
|
13497
|
-
sha256:
|
|
13498
|
-
createdAt:
|
|
13499
|
-
});
|
|
13500
|
-
docBodySchema =
|
|
13501
|
-
encoding:
|
|
13502
|
-
text:
|
|
13503
|
-
base64:
|
|
13504
|
-
sizeBytes:
|
|
13505
|
-
mimeType:
|
|
13506
|
-
});
|
|
13507
|
-
docReadResponseSchema =
|
|
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
|
|
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 =
|
|
13589
|
-
kind:
|
|
13590
|
-
sha:
|
|
13591
|
-
});
|
|
13592
|
-
filesAtomSchema =
|
|
13593
|
-
kind:
|
|
13594
|
-
paths:
|
|
13595
|
-
});
|
|
13596
|
-
testRunAtomSchema =
|
|
13597
|
-
kind:
|
|
13598
|
-
path:
|
|
13599
|
-
});
|
|
13600
|
-
toolAtomSchema =
|
|
13601
|
-
kind:
|
|
13602
|
-
tool:
|
|
13603
|
-
});
|
|
13604
|
-
urlAtomSchema =
|
|
13605
|
-
kind:
|
|
13606
|
-
url:
|
|
13607
|
-
});
|
|
13608
|
-
noteAtomSchema =
|
|
13609
|
-
kind:
|
|
13610
|
-
note:
|
|
13611
|
-
});
|
|
13612
|
-
decisionAtomSchema =
|
|
13613
|
-
kind:
|
|
13614
|
-
decisionId:
|
|
13615
|
-
});
|
|
13616
|
-
prAtomSchema =
|
|
13617
|
-
kind:
|
|
13618
|
-
prNumber:
|
|
13619
|
-
componentPrNumber:
|
|
13620
|
-
});
|
|
13621
|
-
ciAtomSchema =
|
|
13622
|
-
kind:
|
|
13623
|
-
prNumber:
|
|
13624
|
-
componentPrNumber:
|
|
13625
|
-
});
|
|
13626
|
-
locDropAtomSchema =
|
|
13627
|
-
kind:
|
|
13628
|
-
fromLines:
|
|
13629
|
-
toLines:
|
|
13630
|
-
});
|
|
13631
|
-
callsiteCoverageAtomSchema =
|
|
13632
|
-
kind:
|
|
13633
|
-
symbolName:
|
|
13634
|
-
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 =
|
|
13641
|
-
kind:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
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
|
|
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 =
|
|
13675
|
+
evidenceBaseSchema = z10.object({
|
|
13712
13676
|
/** Identity string of the agent that produced this record. */
|
|
13713
|
-
agentIdentity:
|
|
13677
|
+
agentIdentity: z10.string().min(1),
|
|
13714
13678
|
/** SHA-256 hex digest (64 chars) of the attached artifact. */
|
|
13715
|
-
attachmentSha256:
|
|
13679
|
+
attachmentSha256: z10.string().length(64),
|
|
13716
13680
|
/** ISO 8601 timestamp at which the action ran. */
|
|
13717
|
-
ranAt:
|
|
13681
|
+
ranAt: z10.string().datetime(),
|
|
13718
13682
|
/** Wall-clock duration of the action in milliseconds. */
|
|
13719
|
-
durationMs:
|
|
13683
|
+
durationMs: z10.number().nonnegative()
|
|
13720
13684
|
});
|
|
13721
13685
|
implDiffRecordSchema = evidenceBaseSchema.extend({
|
|
13722
|
-
kind:
|
|
13723
|
-
phase:
|
|
13724
|
-
filesChanged:
|
|
13725
|
-
linesAdded:
|
|
13726
|
-
linesRemoved:
|
|
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:
|
|
13730
|
-
phase:
|
|
13731
|
-
reqIdsChecked:
|
|
13732
|
-
passed:
|
|
13733
|
-
details:
|
|
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:
|
|
13737
|
-
phase:
|
|
13738
|
-
command:
|
|
13739
|
-
exitCode:
|
|
13740
|
-
testsPassed:
|
|
13741
|
-
testsFailed:
|
|
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:
|
|
13745
|
-
phase:
|
|
13746
|
-
tool:
|
|
13747
|
-
passed:
|
|
13748
|
-
warnings:
|
|
13749
|
-
errors:
|
|
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:
|
|
13753
|
-
phase:
|
|
13754
|
-
cmd:
|
|
13755
|
-
exitCode:
|
|
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 =
|
|
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
|
-
|
|
14338
|
-
|
|
14339
|
-
|
|
14340
|
-
|
|
14341
|
-
|
|
14342
|
-
|
|
14343
|
-
|
|
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
|
-
|
|
14339
|
+
trigger(
|
|
14354
14340
|
"task.dependency.graph",
|
|
14355
|
-
"PAC-03",
|
|
14356
|
-
"T12924",
|
|
14357
14341
|
["tasks_task_dependencies", "tasks_tasks"],
|
|
14358
|
-
["
|
|
14359
|
-
"
|
|
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
|
-
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
|
|
14455
|
-
|
|
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
|
-
|
|
14459
|
-
|
|
14460
|
-
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
|
|
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
|
-
|
|
14467
|
-
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
|
|
14472
|
-
|
|
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
|
-
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
|
|
14480
|
-
|
|
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
|
|
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 =
|
|
14622
|
-
LeaseLaneSchema =
|
|
14623
|
-
LeaseAcquireRequestSchema =
|
|
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:
|
|
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:
|
|
14625
|
+
holder_id: z11.string().min(1),
|
|
14632
14626
|
/** Advisory priority — lower acquires sooner. `0` = highest. */
|
|
14633
|
-
priority:
|
|
14627
|
+
priority: z11.number().int().min(0).max(255),
|
|
14634
14628
|
/** Lease time-to-live in milliseconds. */
|
|
14635
|
-
ttl_ms:
|
|
14629
|
+
ttl_ms: z11.number().int().nonnegative(),
|
|
14636
14630
|
/** When true, a same-holder acquire re-enters (refcount++) rather than queuing. */
|
|
14637
|
-
reentrant:
|
|
14631
|
+
reentrant: z11.boolean()
|
|
14638
14632
|
}).strict();
|
|
14639
|
-
LeaseReleaseRequestSchema =
|
|
14633
|
+
LeaseReleaseRequestSchema = z11.object({
|
|
14640
14634
|
/** Tag discriminating this request variant. */
|
|
14641
|
-
kind:
|
|
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:
|
|
14641
|
+
holder_id: z11.string().min(1),
|
|
14648
14642
|
/** The epoch fence the holder acquired — a stale epoch no-ops. */
|
|
14649
|
-
epoch:
|
|
14643
|
+
epoch: z11.number().int().nonnegative()
|
|
14650
14644
|
}).strict();
|
|
14651
|
-
LeaseRenewRequestSchema =
|
|
14645
|
+
LeaseRenewRequestSchema = z11.object({
|
|
14652
14646
|
/** Tag discriminating this request variant. */
|
|
14653
|
-
kind:
|
|
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:
|
|
14653
|
+
holder_id: z11.string().min(1),
|
|
14660
14654
|
/** The epoch fence the holder acquired (epoch-guarded renew). */
|
|
14661
|
-
epoch:
|
|
14655
|
+
epoch: z11.number().int().nonnegative()
|
|
14662
14656
|
}).strict();
|
|
14663
|
-
RateCheckRequestSchema =
|
|
14657
|
+
RateCheckRequestSchema = z11.object({
|
|
14664
14658
|
/** Tag discriminating this request variant. */
|
|
14665
|
-
kind:
|
|
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:
|
|
14665
|
+
est_bytes: z11.number().int().nonnegative()
|
|
14672
14666
|
}).strict();
|
|
14673
|
-
ToolGrantRequestSchema =
|
|
14667
|
+
ToolGrantRequestSchema = z11.object({
|
|
14674
14668
|
/** Tag discriminating this request variant. */
|
|
14675
|
-
kind:
|
|
14669
|
+
kind: z11.literal("tool_grant"),
|
|
14676
14670
|
/** The tool name being requested. */
|
|
14677
|
-
tool:
|
|
14671
|
+
tool: z11.string().min(1),
|
|
14678
14672
|
/** The requesting holder identity. */
|
|
14679
|
-
holder_id:
|
|
14673
|
+
holder_id: z11.string().min(1)
|
|
14680
14674
|
}).strict();
|
|
14681
|
-
QueuePriorityClassSchema =
|
|
14682
|
-
QueueAdmitRequestSchema =
|
|
14675
|
+
QueuePriorityClassSchema = z11.enum(["lead", "worker", "background"]);
|
|
14676
|
+
QueueAdmitRequestSchema = z11.object({
|
|
14683
14677
|
/** Tag discriminating this request variant. */
|
|
14684
|
-
kind:
|
|
14678
|
+
kind: z11.literal("queue_admit"),
|
|
14685
14679
|
/** The LLM provider id the call targets (rate budget is per-provider). */
|
|
14686
|
-
provider:
|
|
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:
|
|
14684
|
+
est_tokens: z11.number().int().nonnegative(),
|
|
14691
14685
|
/** The child the call belongs to (in-flight tracking — the watchdog seam). */
|
|
14692
|
-
child_id:
|
|
14686
|
+
child_id: z11.string().min(1)
|
|
14693
14687
|
}).strict();
|
|
14694
|
-
WorkerHeartbeatRequestSchema =
|
|
14688
|
+
WorkerHeartbeatRequestSchema = z11.object({
|
|
14695
14689
|
/** Tag discriminating this request variant. */
|
|
14696
|
-
kind:
|
|
14690
|
+
kind: z11.literal("worker_heartbeat"),
|
|
14697
14691
|
/** The logical id of the heartbeating child (matches the registry key). */
|
|
14698
|
-
child_id:
|
|
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:
|
|
14694
|
+
in_flight_llm: z11.boolean()
|
|
14701
14695
|
}).strict();
|
|
14702
|
-
ResourceAdmitRequestSchema =
|
|
14696
|
+
ResourceAdmitRequestSchema = z11.object({
|
|
14703
14697
|
/** Tag discriminating this request variant. */
|
|
14704
|
-
kind:
|
|
14698
|
+
kind: z11.literal("resource_admit"),
|
|
14705
14699
|
/** The resource class (e.g. `"db-heavy"`, `"full-build"`, `"test-run"`). */
|
|
14706
|
-
class:
|
|
14700
|
+
class: z11.string().min(1),
|
|
14707
14701
|
/** The caller holding the slot — process/worktree-unique; the release key. */
|
|
14708
|
-
holder_id:
|
|
14702
|
+
holder_id: z11.string().min(1),
|
|
14709
14703
|
/** The client-computed budget: the max concurrent holders for this class. */
|
|
14710
|
-
budget:
|
|
14704
|
+
budget: z11.number().int().nonnegative()
|
|
14711
14705
|
}).strict();
|
|
14712
|
-
ResourceReleaseRequestSchema =
|
|
14706
|
+
ResourceReleaseRequestSchema = z11.object({
|
|
14713
14707
|
/** Tag discriminating this request variant. */
|
|
14714
|
-
kind:
|
|
14708
|
+
kind: z11.literal("resource_release"),
|
|
14715
14709
|
/** The resource class the slot belongs to. */
|
|
14716
|
-
class:
|
|
14710
|
+
class: z11.string().min(1),
|
|
14717
14711
|
/** The holder that was admitted (matches the admit `holder_id`). */
|
|
14718
|
-
holder_id:
|
|
14712
|
+
holder_id: z11.string().min(1)
|
|
14719
14713
|
}).strict();
|
|
14720
|
-
LeaseIpcRequestSchema =
|
|
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 =
|
|
14725
|
+
LeaseGrantedResponseSchema = z11.object({
|
|
14732
14726
|
/** Tag discriminating this response variant. */
|
|
14733
|
-
kind:
|
|
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:
|
|
14733
|
+
holder_id: z11.string().min(1),
|
|
14740
14734
|
/** The monotonic epoch fence assigned to this grant. */
|
|
14741
|
-
epoch:
|
|
14735
|
+
epoch: z11.number().int().nonnegative(),
|
|
14742
14736
|
/** The lease TTL in milliseconds. */
|
|
14743
|
-
ttl_ms:
|
|
14737
|
+
ttl_ms: z11.number().int().nonnegative(),
|
|
14744
14738
|
/** Absolute expiry timestamp (epoch ms) for this grant. */
|
|
14745
|
-
expires_at_ms:
|
|
14739
|
+
expires_at_ms: z11.number().int().nonnegative()
|
|
14746
14740
|
}).strict();
|
|
14747
|
-
LeaseQueuedResponseSchema =
|
|
14741
|
+
LeaseQueuedResponseSchema = z11.object({
|
|
14748
14742
|
/** Tag discriminating this response variant. */
|
|
14749
|
-
kind:
|
|
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:
|
|
14749
|
+
ticket: z11.number().int().nonnegative(),
|
|
14756
14750
|
/** Number of waiters ahead of this one. */
|
|
14757
|
-
ahead:
|
|
14751
|
+
ahead: z11.number().int().nonnegative()
|
|
14758
14752
|
}).strict();
|
|
14759
|
-
LeaseDeniedResponseSchema =
|
|
14753
|
+
LeaseDeniedResponseSchema = z11.object({
|
|
14760
14754
|
/** Tag discriminating this response variant. */
|
|
14761
|
-
kind:
|
|
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:
|
|
14759
|
+
code: z11.string().min(1),
|
|
14766
14760
|
/** Human-readable denial message. */
|
|
14767
|
-
message:
|
|
14761
|
+
message: z11.string()
|
|
14768
14762
|
}).strict();
|
|
14769
|
-
RateResultResponseSchema =
|
|
14763
|
+
RateResultResponseSchema = z11.object({
|
|
14770
14764
|
/** Tag discriminating this response variant. */
|
|
14771
|
-
kind:
|
|
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:
|
|
14769
|
+
ok: z11.boolean(),
|
|
14776
14770
|
/** Suggested back-off in milliseconds when `ok` is false. */
|
|
14777
|
-
retry_after_ms:
|
|
14771
|
+
retry_after_ms: z11.number().int().nonnegative(),
|
|
14778
14772
|
/** Remaining token budget for the scope. */
|
|
14779
|
-
tokens_remaining:
|
|
14773
|
+
tokens_remaining: z11.number().int().nonnegative()
|
|
14780
14774
|
}).strict();
|
|
14781
|
-
ToolGrantedResponseSchema =
|
|
14775
|
+
ToolGrantedResponseSchema = z11.object({
|
|
14782
14776
|
/** Tag discriminating this response variant. */
|
|
14783
|
-
kind:
|
|
14777
|
+
kind: z11.literal("tool_granted"),
|
|
14784
14778
|
/** The granted tool name. */
|
|
14785
|
-
tool:
|
|
14779
|
+
tool: z11.string().min(1),
|
|
14786
14780
|
/** The holder the tool grant was issued to. */
|
|
14787
|
-
holder_id:
|
|
14781
|
+
holder_id: z11.string().min(1)
|
|
14788
14782
|
}).strict();
|
|
14789
|
-
LeaseRevokedResponseSchema =
|
|
14783
|
+
LeaseRevokedResponseSchema = z11.object({
|
|
14790
14784
|
/** Tag discriminating this response variant. */
|
|
14791
|
-
kind:
|
|
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:
|
|
14791
|
+
holder_id: z11.string().min(1),
|
|
14798
14792
|
/** Human-readable reason for the revocation. */
|
|
14799
|
-
reason:
|
|
14793
|
+
reason: z11.string()
|
|
14800
14794
|
}).strict();
|
|
14801
|
-
ChildKilledUnresponsiveResponseSchema =
|
|
14795
|
+
ChildKilledUnresponsiveResponseSchema = z11.object({
|
|
14802
14796
|
/** Tag discriminating this response variant. */
|
|
14803
|
-
kind:
|
|
14797
|
+
kind: z11.literal("child_killed_unresponsive"),
|
|
14804
14798
|
/** Logical id of the killed child. */
|
|
14805
|
-
child_id:
|
|
14799
|
+
child_id: z11.string().min(1),
|
|
14806
14800
|
/** The holder identity the killed child held the lease as. */
|
|
14807
|
-
holder_id:
|
|
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:
|
|
14805
|
+
reason: z11.string()
|
|
14812
14806
|
}).strict();
|
|
14813
|
-
QueueAdmitDispositionSchema =
|
|
14814
|
-
QueueAdmitResultResponseSchema =
|
|
14807
|
+
QueueAdmitDispositionSchema = z11.enum(["admitted", "deferred"]);
|
|
14808
|
+
QueueAdmitResultResponseSchema = z11.object({
|
|
14815
14809
|
/** Tag discriminating this response variant. */
|
|
14816
|
-
kind:
|
|
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:
|
|
14814
|
+
retry_after_ms: z11.number().int().nonnegative(),
|
|
14821
14815
|
/** Remaining provider token budget after this decision. */
|
|
14822
|
-
tokens_remaining:
|
|
14816
|
+
tokens_remaining: z11.number().int().nonnegative(),
|
|
14823
14817
|
/** Number of higher/equal-priority waiters ahead (0 when admitted). */
|
|
14824
|
-
queue_position:
|
|
14818
|
+
queue_position: z11.number().int().nonnegative()
|
|
14825
14819
|
}).strict();
|
|
14826
|
-
HeartbeatAckResponseSchema =
|
|
14820
|
+
HeartbeatAckResponseSchema = z11.object({
|
|
14827
14821
|
/** Tag discriminating this response variant. */
|
|
14828
|
-
kind:
|
|
14822
|
+
kind: z11.literal("heartbeat_ack")
|
|
14829
14823
|
}).strict();
|
|
14830
|
-
ResourceAdmitDispositionSchema =
|
|
14831
|
-
ResourceAdmitResultResponseSchema =
|
|
14824
|
+
ResourceAdmitDispositionSchema = z11.enum(["admitted", "deferred"]);
|
|
14825
|
+
ResourceAdmitResultResponseSchema = z11.object({
|
|
14832
14826
|
/** Tag discriminating this response variant. */
|
|
14833
|
-
kind:
|
|
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:
|
|
14831
|
+
retry_after_ms: z11.number().int().nonnegative(),
|
|
14838
14832
|
/** Remaining slots for the class after this decision. */
|
|
14839
|
-
slots_remaining:
|
|
14833
|
+
slots_remaining: z11.number().int().nonnegative()
|
|
14840
14834
|
}).strict();
|
|
14841
|
-
ResourceReleaseResultResponseSchema =
|
|
14835
|
+
ResourceReleaseResultResponseSchema = z11.object({
|
|
14842
14836
|
/** Tag discriminating this response variant. */
|
|
14843
|
-
kind:
|
|
14837
|
+
kind: z11.literal("resource_release_result"),
|
|
14844
14838
|
/** Whether a held slot was actually released (false = no such holder). */
|
|
14845
|
-
released:
|
|
14839
|
+
released: z11.boolean(),
|
|
14846
14840
|
/** Remaining in-flight holders for the class after the release. */
|
|
14847
|
-
slots_remaining:
|
|
14841
|
+
slots_remaining: z11.number().int().nonnegative()
|
|
14848
14842
|
}).strict();
|
|
14849
|
-
LeaseErrorResponseSchema =
|
|
14843
|
+
LeaseErrorResponseSchema = z11.object({
|
|
14850
14844
|
/** Tag discriminating this response variant. */
|
|
14851
|
-
kind:
|
|
14845
|
+
kind: z11.literal("error"),
|
|
14852
14846
|
/** Machine-readable error code (e.g. `E_LEASE_BAD_VERSION`, `E_LEASE_UNIMPLEMENTED`). */
|
|
14853
|
-
code:
|
|
14847
|
+
code: z11.string().min(1),
|
|
14854
14848
|
/** Human-readable error message. */
|
|
14855
|
-
message:
|
|
14849
|
+
message: z11.string()
|
|
14856
14850
|
}).strict();
|
|
14857
|
-
LeaseIpcResponseSchema =
|
|
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 =
|
|
14865
|
+
LeaseIpcRequestEnvelopeSchema = z11.object({
|
|
14872
14866
|
/** Parallel protocol version. */
|
|
14873
|
-
protocol_version:
|
|
14867
|
+
protocol_version: z11.string(),
|
|
14874
14868
|
/** Correlation id echoed back on the matching response. */
|
|
14875
|
-
id:
|
|
14869
|
+
id: z11.string().min(1),
|
|
14876
14870
|
/** Direction discriminator. */
|
|
14877
|
-
direction:
|
|
14871
|
+
direction: z11.literal("request"),
|
|
14878
14872
|
/** The request body. */
|
|
14879
14873
|
request: LeaseIpcRequestSchema
|
|
14880
14874
|
}).strict();
|
|
14881
|
-
LeaseIpcResponseEnvelopeSchema =
|
|
14875
|
+
LeaseIpcResponseEnvelopeSchema = z11.object({
|
|
14882
14876
|
/** Parallel protocol version. */
|
|
14883
|
-
protocol_version:
|
|
14877
|
+
protocol_version: z11.string(),
|
|
14884
14878
|
/** Correlation id echoed from the originating request (or a fresh id for events). */
|
|
14885
|
-
id:
|
|
14879
|
+
id: z11.string().min(1),
|
|
14886
14880
|
/** Direction discriminator. */
|
|
14887
|
-
direction:
|
|
14881
|
+
direction: z11.literal("response"),
|
|
14888
14882
|
/** The response body. */
|
|
14889
14883
|
response: LeaseIpcResponseSchema
|
|
14890
14884
|
}).strict();
|
|
14891
|
-
LeaseIpcEnvelopeSchema =
|
|
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
|
|
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 =
|
|
14958
|
-
semver =
|
|
14959
|
-
catalogModalitiesSchema =
|
|
14960
|
-
input:
|
|
14961
|
-
output:
|
|
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 =
|
|
14964
|
-
input:
|
|
14965
|
-
output:
|
|
14966
|
-
cache_read:
|
|
14967
|
-
cache_write:
|
|
14968
|
-
context_over_200k:
|
|
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 =
|
|
14971
|
-
context:
|
|
14972
|
-
output:
|
|
14964
|
+
catalogLimitSchema = z12.object({
|
|
14965
|
+
context: z12.number(),
|
|
14966
|
+
output: z12.number()
|
|
14973
14967
|
}).strict();
|
|
14974
|
-
catalogModelProviderSchema =
|
|
14975
|
-
npm:
|
|
14976
|
-
api:
|
|
14968
|
+
catalogModelProviderSchema = z12.object({
|
|
14969
|
+
npm: z12.string(),
|
|
14970
|
+
api: z12.string()
|
|
14977
14971
|
}).strict();
|
|
14978
|
-
catalogModelEntrySchema =
|
|
14979
|
-
id:
|
|
14980
|
-
name:
|
|
14981
|
-
family:
|
|
14982
|
-
attachment:
|
|
14983
|
-
reasoning:
|
|
14984
|
-
temperature:
|
|
14985
|
-
interleaved:
|
|
14986
|
-
tool_call:
|
|
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:
|
|
14984
|
+
status: z12.enum(CATALOG_MODEL_STATUSES),
|
|
14991
14985
|
release_date: isoDate,
|
|
14992
14986
|
provider: catalogModelProviderSchema
|
|
14993
14987
|
}).strict();
|
|
14994
|
-
catalogProviderSchema =
|
|
14995
|
-
id:
|
|
14996
|
-
endpoint:
|
|
14997
|
-
authTypes:
|
|
14998
|
-
npm:
|
|
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 =
|
|
15001
|
-
$schema:
|
|
14994
|
+
curatedCatalogSchema = z12.object({
|
|
14995
|
+
$schema: z12.string().optional(),
|
|
15002
14996
|
version: semver,
|
|
15003
14997
|
lastUpdated: isoDate,
|
|
15004
|
-
providers:
|
|
15005
|
-
models:
|
|
14998
|
+
providers: z12.record(z12.string(), catalogProviderSchema),
|
|
14999
|
+
models: z12.record(z12.string(), z12.record(z12.string(), catalogModelEntrySchema))
|
|
15006
15000
|
}).strict();
|
|
15007
|
-
modelsCatalogRowInsertSchema =
|
|
15008
|
-
id:
|
|
15009
|
-
providerId:
|
|
15010
|
-
name:
|
|
15011
|
-
family:
|
|
15012
|
-
attachment:
|
|
15013
|
-
reasoning:
|
|
15014
|
-
temperature:
|
|
15015
|
-
interleaved:
|
|
15016
|
-
toolCall:
|
|
15017
|
-
modalities:
|
|
15018
|
-
cost:
|
|
15019
|
-
contextLimit:
|
|
15020
|
-
outputLimit:
|
|
15021
|
-
status:
|
|
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:
|
|
15024
|
-
source:
|
|
15025
|
-
seededAt:
|
|
15017
|
+
modelsDevId: z12.string(),
|
|
15018
|
+
source: z12.string(),
|
|
15019
|
+
seededAt: z12.string().optional()
|
|
15026
15020
|
}).strict();
|
|
15027
15021
|
modelsCatalogRowSelectSchema = modelsCatalogRowInsertSchema.extend({
|
|
15028
|
-
seededAt:
|
|
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
|
|
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 =
|
|
15152
|
-
taskPrioritySchema =
|
|
15153
|
-
taskStatusSchema =
|
|
15154
|
-
verificationGateSchema =
|
|
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 =
|
|
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 =
|
|
15165
|
+
workGraphTraversalDirectionSchema = z13.enum([
|
|
15172
15166
|
"ancestors",
|
|
15173
15167
|
"descendants",
|
|
15174
15168
|
"upstream",
|
|
15175
15169
|
"downstream"
|
|
15176
15170
|
]);
|
|
15177
|
-
workGraphEdgeDirectionSchema =
|
|
15178
|
-
paginationParamsSchema =
|
|
15179
|
-
cursor:
|
|
15180
|
-
limit:
|
|
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 =
|
|
15183
|
-
id:
|
|
15176
|
+
workGraphNodeSchema = z13.object({
|
|
15177
|
+
id: z13.string().min(1),
|
|
15184
15178
|
type: taskTypeSchema,
|
|
15185
|
-
title:
|
|
15179
|
+
title: z13.string(),
|
|
15186
15180
|
status: taskStatusSchema,
|
|
15187
15181
|
priority: taskPrioritySchema,
|
|
15188
|
-
parentId:
|
|
15182
|
+
parentId: z13.string().min(1).optional()
|
|
15189
15183
|
});
|
|
15190
|
-
workGraphEdgeSchema =
|
|
15191
|
-
fromId:
|
|
15192
|
-
toId:
|
|
15184
|
+
workGraphEdgeSchema = z13.object({
|
|
15185
|
+
fromId: z13.string().min(1),
|
|
15186
|
+
toId: z13.string().min(1),
|
|
15193
15187
|
kind: workGraphRelationKindSchema
|
|
15194
15188
|
});
|
|
15195
|
-
workGraphHierarchyEdgeSchema =
|
|
15196
|
-
fromId:
|
|
15197
|
-
toId:
|
|
15198
|
-
kind:
|
|
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 =
|
|
15201
|
-
nextCursor:
|
|
15202
|
-
hasMore:
|
|
15203
|
-
});
|
|
15204
|
-
workGraphRollupCountsSchema =
|
|
15205
|
-
total:
|
|
15206
|
-
byStatus:
|
|
15207
|
-
byType:
|
|
15208
|
-
});
|
|
15209
|
-
workGraphSubtreePercentagesSchema =
|
|
15210
|
-
done:
|
|
15211
|
-
active:
|
|
15212
|
-
blocked:
|
|
15213
|
-
pending:
|
|
15214
|
-
cancelled:
|
|
15215
|
-
});
|
|
15216
|
-
workGraphProjectionMismatchSchema =
|
|
15217
|
-
field:
|
|
15218
|
-
expected:
|
|
15219
|
-
actual:
|
|
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:
|
|
15223
|
-
dependencyBlockers:
|
|
15224
|
-
gateBlockers:
|
|
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:
|
|
15228
|
-
relationType:
|
|
15229
|
-
reason:
|
|
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:
|
|
15233
|
-
kind:
|
|
15226
|
+
source: z13.literal("dependency"),
|
|
15227
|
+
kind: z13.literal("depends_on")
|
|
15234
15228
|
});
|
|
15235
|
-
workGraphOmissionReasonSchema =
|
|
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 =
|
|
15243
|
-
tokenBudget:
|
|
15244
|
-
estimatedTokens:
|
|
15245
|
-
remainingTokens:
|
|
15246
|
-
truncated:
|
|
15247
|
-
});
|
|
15248
|
-
workGraphOmissionSchema =
|
|
15249
|
-
path:
|
|
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:
|
|
15252
|
-
estimatedTokens:
|
|
15245
|
+
message: z13.string().min(1),
|
|
15246
|
+
estimatedTokens: z13.number().int().nonnegative().optional()
|
|
15253
15247
|
});
|
|
15254
|
-
workGraphDirectEdgeSchema =
|
|
15248
|
+
workGraphDirectEdgeSchema = z13.discriminatedUnion("source", [
|
|
15255
15249
|
workGraphRelationEdgeSchema,
|
|
15256
15250
|
workGraphDependencyEdgeSchema
|
|
15257
15251
|
]);
|
|
15258
15252
|
workGraphContextPackParamsSchema = paginationParamsSchema.extend({
|
|
15259
|
-
rootId:
|
|
15260
|
-
tokenBudget:
|
|
15261
|
-
includeRelations:
|
|
15262
|
-
includeReadiness:
|
|
15263
|
-
includeRollup:
|
|
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:
|
|
15260
|
+
rootId: z13.string().min(1),
|
|
15267
15261
|
direction: workGraphTraversalDirectionSchema.optional(),
|
|
15268
|
-
maxDepth:
|
|
15269
|
-
includeRelations:
|
|
15262
|
+
maxDepth: z13.number().int().nonnegative().optional(),
|
|
15263
|
+
includeRelations: z13.boolean().optional()
|
|
15270
15264
|
});
|
|
15271
|
-
workGraphSliceSchema =
|
|
15272
|
-
rootId:
|
|
15265
|
+
workGraphSliceSchema = z13.object({
|
|
15266
|
+
rootId: z13.string().min(1),
|
|
15273
15267
|
direction: workGraphTraversalDirectionSchema,
|
|
15274
|
-
nodes:
|
|
15275
|
-
edges:
|
|
15268
|
+
nodes: z13.array(workGraphNodeSchema),
|
|
15269
|
+
edges: z13.array(workGraphEdgeSchema),
|
|
15276
15270
|
pageInfo: workGraphPageInfoSchema,
|
|
15277
|
-
omissions:
|
|
15278
|
-
});
|
|
15279
|
-
workGraphReadinessParamsSchema =
|
|
15280
|
-
rootId:
|
|
15281
|
-
role:
|
|
15282
|
-
includeGateBlockers:
|
|
15283
|
-
});
|
|
15284
|
-
workGraphReadinessResultSchema =
|
|
15285
|
-
rootId:
|
|
15286
|
-
role:
|
|
15287
|
-
ready:
|
|
15288
|
-
warnings:
|
|
15289
|
-
groups:
|
|
15290
|
-
ready:
|
|
15291
|
-
blocked:
|
|
15292
|
-
blockedBy:
|
|
15293
|
-
|
|
15294
|
-
|
|
15295
|
-
kind:
|
|
15296
|
-
blockerId:
|
|
15297
|
-
blocks:
|
|
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
|
-
|
|
15300
|
-
kind:
|
|
15293
|
+
z13.object({
|
|
15294
|
+
kind: z13.literal("gate"),
|
|
15301
15295
|
gate: verificationGateSchema,
|
|
15302
|
-
blocks:
|
|
15296
|
+
blocks: z13.array(z13.string().min(1))
|
|
15303
15297
|
})
|
|
15304
15298
|
])
|
|
15305
15299
|
)
|
|
15306
15300
|
})
|
|
15307
15301
|
});
|
|
15308
|
-
workGraphContextPackSchema =
|
|
15309
|
-
rootId:
|
|
15310
|
-
generatedAt:
|
|
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:
|
|
15314
|
-
rootId:
|
|
15307
|
+
relationEdges: z13.object({
|
|
15308
|
+
rootId: z13.string().min(1),
|
|
15315
15309
|
direction: workGraphEdgeDirectionSchema,
|
|
15316
|
-
edges:
|
|
15310
|
+
edges: z13.array(workGraphDirectEdgeSchema)
|
|
15317
15311
|
}).optional(),
|
|
15318
15312
|
readiness: workGraphReadinessResultSchema.optional(),
|
|
15319
|
-
rollup:
|
|
15320
|
-
omissions:
|
|
15321
|
-
});
|
|
15322
|
-
workGraphScaffoldValidateParamsSchema =
|
|
15323
|
-
rootId:
|
|
15324
|
-
nodes:
|
|
15325
|
-
|
|
15326
|
-
id:
|
|
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:
|
|
15322
|
+
parentId: z13.string().min(1).nullable().optional()
|
|
15329
15323
|
})
|
|
15330
15324
|
),
|
|
15331
|
-
edges:
|
|
15332
|
-
dryRun:
|
|
15333
|
-
});
|
|
15334
|
-
workGraphScaffoldValidationIssueSchema =
|
|
15335
|
-
code:
|
|
15336
|
-
message:
|
|
15337
|
-
taskId:
|
|
15338
|
-
severity:
|
|
15339
|
-
});
|
|
15340
|
-
workGraphScaffoldValidateResultSchema =
|
|
15341
|
-
rootId:
|
|
15342
|
-
valid:
|
|
15343
|
-
dryRun:
|
|
15344
|
-
issues:
|
|
15345
|
-
hierarchy:
|
|
15346
|
-
valid:
|
|
15347
|
-
violations:
|
|
15348
|
-
|
|
15349
|
-
code:
|
|
15350
|
-
taskId:
|
|
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:
|
|
15346
|
+
parentId: z13.string().min(1).nullable(),
|
|
15353
15347
|
parentType: taskTypeSchema.optional(),
|
|
15354
|
-
message:
|
|
15348
|
+
message: z13.string().min(1)
|
|
15355
15349
|
})
|
|
15356
15350
|
)
|
|
15357
15351
|
})
|
|
15358
15352
|
});
|
|
15359
15353
|
workGraphScaffoldApplyParamsSchema = workGraphScaffoldValidateParamsSchema.extend({
|
|
15360
|
-
apply:
|
|
15354
|
+
apply: z13.boolean().optional()
|
|
15361
15355
|
});
|
|
15362
15356
|
workGraphScaffoldApplyResultSchema = workGraphScaffoldValidateResultSchema.extend({
|
|
15363
|
-
applied:
|
|
15364
|
-
nodesChanged:
|
|
15365
|
-
edgesChanged:
|
|
15366
|
-
});
|
|
15367
|
-
workGraphPlanningDocParamsSchema =
|
|
15368
|
-
rootId:
|
|
15369
|
-
audience:
|
|
15370
|
-
tokenBudget:
|
|
15371
|
-
includeRelations:
|
|
15372
|
-
includeReadiness:
|
|
15373
|
-
includeRollup:
|
|
15374
|
-
});
|
|
15375
|
-
workGraphPlanningDocSchema =
|
|
15376
|
-
rootId:
|
|
15377
|
-
generatedAt:
|
|
15378
|
-
audience:
|
|
15379
|
-
title:
|
|
15380
|
-
content:
|
|
15381
|
-
sections:
|
|
15382
|
-
estimatedTokens:
|
|
15383
|
-
budget:
|
|
15384
|
-
tokenBudget:
|
|
15385
|
-
truncated:
|
|
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:
|
|
15383
|
+
rootId: z13.string().min(1),
|
|
15390
15384
|
direction: workGraphTraversalDirectionSchema,
|
|
15391
|
-
maxDepth:
|
|
15392
|
-
includeRelations:
|
|
15385
|
+
maxDepth: z13.number().int().nonnegative().optional(),
|
|
15386
|
+
includeRelations: z13.boolean().optional()
|
|
15393
15387
|
});
|
|
15394
|
-
tasksTraverseResultSchema =
|
|
15395
|
-
rootId:
|
|
15388
|
+
tasksTraverseResultSchema = z13.object({
|
|
15389
|
+
rootId: z13.string().min(1),
|
|
15396
15390
|
direction: workGraphTraversalDirectionSchema,
|
|
15397
|
-
nodes:
|
|
15398
|
-
edges:
|
|
15391
|
+
nodes: z13.array(workGraphNodeSchema),
|
|
15392
|
+
edges: z13.array(workGraphEdgeSchema),
|
|
15399
15393
|
pageInfo: workGraphPageInfoSchema
|
|
15400
15394
|
});
|
|
15401
15395
|
tasksTreeParamsSchema = paginationParamsSchema.extend({
|
|
15402
|
-
rootId:
|
|
15403
|
-
maxDepth:
|
|
15396
|
+
rootId: z13.string().min(1),
|
|
15397
|
+
maxDepth: z13.number().int().nonnegative().optional()
|
|
15404
15398
|
});
|
|
15405
|
-
tasksTreeResultSchema =
|
|
15406
|
-
rootId:
|
|
15407
|
-
nodes:
|
|
15408
|
-
edges:
|
|
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 =
|
|
15412
|
-
rootId:
|
|
15405
|
+
tasksRollupParamsSchema = z13.object({
|
|
15406
|
+
rootId: z13.string().min(1),
|
|
15413
15407
|
expectedDirectRollup: workGraphRollupCountsSchema.optional()
|
|
15414
15408
|
});
|
|
15415
|
-
tasksRollupResultSchema =
|
|
15416
|
-
rootId:
|
|
15409
|
+
tasksRollupResultSchema = z13.object({
|
|
15410
|
+
rootId: z13.string().min(1),
|
|
15417
15411
|
direct: workGraphRollupCountsSchema,
|
|
15418
15412
|
subtree: workGraphRollupCountsSchema,
|
|
15419
|
-
percentDenominator:
|
|
15420
|
-
basis:
|
|
15421
|
-
total:
|
|
15422
|
-
description:
|
|
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:
|
|
15426
|
-
projectionMismatches:
|
|
15427
|
-
});
|
|
15428
|
-
tasksFrontierParamsSchema =
|
|
15429
|
-
rootId:
|
|
15430
|
-
role:
|
|
15431
|
-
});
|
|
15432
|
-
tasksFrontierResultSchema =
|
|
15433
|
-
rootId:
|
|
15434
|
-
role:
|
|
15435
|
-
groups:
|
|
15436
|
-
ready:
|
|
15437
|
-
blocked:
|
|
15438
|
-
blockedBy:
|
|
15439
|
-
|
|
15440
|
-
|
|
15441
|
-
kind:
|
|
15442
|
-
blockerId:
|
|
15443
|
-
blocks:
|
|
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
|
-
|
|
15446
|
-
kind:
|
|
15439
|
+
z13.object({
|
|
15440
|
+
kind: z13.literal("gate"),
|
|
15447
15441
|
gate: verificationGateSchema,
|
|
15448
|
-
blocks:
|
|
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:
|
|
15456
|
-
maxDepth:
|
|
15457
|
-
includeRelations:
|
|
15458
|
-
});
|
|
15459
|
-
tasksWorkGraphAuditResultSchema =
|
|
15460
|
-
rootId:
|
|
15461
|
-
hierarchy:
|
|
15462
|
-
valid:
|
|
15463
|
-
violations:
|
|
15464
|
-
|
|
15465
|
-
code:
|
|
15466
|
-
taskId:
|
|
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:
|
|
15462
|
+
parentId: z13.string().min(1).nullable(),
|
|
15469
15463
|
parentType: taskTypeSchema.optional(),
|
|
15470
|
-
message:
|
|
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:
|
|
15478
|
-
rootId:
|
|
15471
|
+
relationEdges: z13.object({
|
|
15472
|
+
rootId: z13.string().min(1),
|
|
15479
15473
|
direction: workGraphEdgeDirectionSchema,
|
|
15480
|
-
edges:
|
|
15481
|
-
|
|
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
|
|
|
@@ -18088,8 +18123,15 @@ var init_nexus_cloud = __esm({
|
|
|
18088
18123
|
nexusCloudProjectListItemSchema = z26.object({
|
|
18089
18124
|
...projectFields,
|
|
18090
18125
|
role: z26.string(),
|
|
18126
|
+
/**
|
|
18127
|
+
* The project name sealed with the project data key (`Project.encryptedName`), base64;
|
|
18128
|
+
* only a holder of the account key can open it (T13102).
|
|
18129
|
+
*/
|
|
18130
|
+
encryptedName: z26.string().nullable().optional(),
|
|
18091
18131
|
streamId: z26.string().optional(),
|
|
18092
18132
|
headSeq: z26.number().int().nonnegative().nullable().optional(),
|
|
18133
|
+
/** The stream's head snapshot; null when nothing was ever pushed (T13102: restorable or not). */
|
|
18134
|
+
headCheckpointId: z26.string().nullable().optional(),
|
|
18093
18135
|
openConflicts: z26.number().int().nonnegative().optional(),
|
|
18094
18136
|
replicas: z26.array(nexusCloudReplicaSchema).default([]),
|
|
18095
18137
|
devices: nexusCloudDeviceCountsSchema.optional(),
|
|
@@ -18155,6 +18197,11 @@ var init_nexus_cloud = __esm({
|
|
|
18155
18197
|
nexusCloudStatusSchema = z26.object({
|
|
18156
18198
|
serverTime: isoTime.optional(),
|
|
18157
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(),
|
|
18158
18205
|
user: nexusCloudUserSchema,
|
|
18159
18206
|
credential: nexusCloudCredentialSchema,
|
|
18160
18207
|
device: nexusCloudDeviceSchema.nullable(),
|
|
@@ -18235,6 +18282,13 @@ var init_nexus_cloud = __esm({
|
|
|
18235
18282
|
}
|
|
18236
18283
|
});
|
|
18237
18284
|
|
|
18285
|
+
// packages/contracts/src/nexus-first-run.ts
|
|
18286
|
+
var init_nexus_first_run = __esm({
|
|
18287
|
+
"packages/contracts/src/nexus-first-run.ts"() {
|
|
18288
|
+
"use strict";
|
|
18289
|
+
}
|
|
18290
|
+
});
|
|
18291
|
+
|
|
18238
18292
|
// packages/contracts/src/nexus-vault.ts
|
|
18239
18293
|
import { z as z27 } from "zod";
|
|
18240
18294
|
var isoTime2, uuid, nexusUserKeysSchema, nexusProjectKeysSchema, nexusLeaseSchema, nexusLeaseAcquireSchema, nexusStreamHeadSchema, nexusActivityEventSchema, nexusActivityPageSchema;
|
|
@@ -18380,6 +18434,7 @@ var init_src = __esm({
|
|
|
18380
18434
|
init_decide_sites();
|
|
18381
18435
|
init_nexus_account();
|
|
18382
18436
|
init_nexus_cloud();
|
|
18437
|
+
init_nexus_first_run();
|
|
18383
18438
|
init_nexus_vault();
|
|
18384
18439
|
init_sync_schema();
|
|
18385
18440
|
init_task_id();
|
|
@@ -44442,18 +44497,6 @@ function appendHookEntry(hooks, event, entry) {
|
|
|
44442
44497
|
}
|
|
44443
44498
|
hooks[event] = [...existing ?? [], entry];
|
|
44444
44499
|
}
|
|
44445
|
-
function removeCleoHookEntries(hooks) {
|
|
44446
|
-
let changed = false;
|
|
44447
|
-
for (const [event, entries] of Object.entries(hooks)) {
|
|
44448
|
-
if (!Array.isArray(entries)) continue;
|
|
44449
|
-
const kept = entries.filter((e) => !isCleoHookEntry(e));
|
|
44450
|
-
if (kept.length !== entries.length) {
|
|
44451
|
-
hooks[event] = kept;
|
|
44452
|
-
changed = true;
|
|
44453
|
-
}
|
|
44454
|
-
}
|
|
44455
|
-
return changed;
|
|
44456
|
-
}
|
|
44457
44500
|
var CLEO_HOOK_MARKER;
|
|
44458
44501
|
var init_hook_config = __esm({
|
|
44459
44502
|
"packages/adapters/src/providers/shared/hook-config.ts"() {
|
|
@@ -44462,43 +44505,623 @@ var init_hook_config = __esm({
|
|
|
44462
44505
|
}
|
|
44463
44506
|
});
|
|
44464
44507
|
|
|
44508
|
+
// packages/adapters/src/providers/shared/heavy-command-hook-install.ts
|
|
44509
|
+
import { execFileSync } from "node:child_process";
|
|
44510
|
+
import {
|
|
44511
|
+
existsSync as existsSync3,
|
|
44512
|
+
mkdirSync,
|
|
44513
|
+
readdirSync as readdirSync2,
|
|
44514
|
+
readFileSync as readFileSync3,
|
|
44515
|
+
realpathSync,
|
|
44516
|
+
rmSync,
|
|
44517
|
+
statSync,
|
|
44518
|
+
writeFileSync
|
|
44519
|
+
} from "node:fs";
|
|
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";
|
|
44523
|
+
function canonical(path) {
|
|
44524
|
+
try {
|
|
44525
|
+
return realpathSync.native(path);
|
|
44526
|
+
} catch {
|
|
44527
|
+
return resolve2(path);
|
|
44528
|
+
}
|
|
44529
|
+
}
|
|
44530
|
+
function nonDirectoryAncestor(dir) {
|
|
44531
|
+
let cur = resolve2(dir);
|
|
44532
|
+
for (; ; ) {
|
|
44533
|
+
try {
|
|
44534
|
+
return statSync(cur).isDirectory() ? null : cur;
|
|
44535
|
+
} catch (err) {
|
|
44536
|
+
const code = err.code;
|
|
44537
|
+
if (code !== "ENOENT" && code !== "ENOTDIR") return null;
|
|
44538
|
+
}
|
|
44539
|
+
const parent = dirname(cur);
|
|
44540
|
+
if (parent === cur) return null;
|
|
44541
|
+
cur = parent;
|
|
44542
|
+
}
|
|
44543
|
+
}
|
|
44544
|
+
function ensureParentDir(target) {
|
|
44545
|
+
const blocked = nonDirectoryAncestor(dirname(target));
|
|
44546
|
+
if (blocked !== null) throw new HeavyHookPathBlockedError(blocked, target);
|
|
44547
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
44548
|
+
}
|
|
44549
|
+
function isUserHomeDir(projectDir, home = homedir2()) {
|
|
44550
|
+
return canonical(projectDir) === canonical(home);
|
|
44551
|
+
}
|
|
44552
|
+
function clearOlderCleoMarkers(dir = process.env.XDG_RUNTIME_DIR || tmpdir()) {
|
|
44553
|
+
let removed = 0;
|
|
44554
|
+
let names;
|
|
44555
|
+
try {
|
|
44556
|
+
names = readdirSync2(dir);
|
|
44557
|
+
} catch {
|
|
44558
|
+
return 0;
|
|
44559
|
+
}
|
|
44560
|
+
for (const name15 of names) {
|
|
44561
|
+
if (!name15.startsWith(OLDER_CLEO_MARKER_PREFIX)) continue;
|
|
44562
|
+
try {
|
|
44563
|
+
rmSync(join3(dir, name15), { force: true });
|
|
44564
|
+
removed++;
|
|
44565
|
+
} catch {
|
|
44566
|
+
}
|
|
44567
|
+
}
|
|
44568
|
+
return removed;
|
|
44569
|
+
}
|
|
44570
|
+
function shellWord(text) {
|
|
44571
|
+
return `'${text.replace(/'/g, `'\\''`)}'`;
|
|
44572
|
+
}
|
|
44573
|
+
function heavyCommandGuardScript(provider) {
|
|
44574
|
+
const words = HEAVY_TOOL_WORDS.join("|");
|
|
44575
|
+
const old = `printf '%s\\n' '${OLDER_CLEO_HOOK_ANSWER}'`;
|
|
44576
|
+
return [
|
|
44577
|
+
"command -v cleo >/dev/null 2>&1 || exit 0",
|
|
44578
|
+
'in="$(cat)"',
|
|
44579
|
+
"set -f",
|
|
44580
|
+
"hit=",
|
|
44581
|
+
// `[\]` (not `\\`) matches a backslash: it survives fish's quoting under Codex.
|
|
44582
|
+
`for w in $(printf '%s' "$in" | sed 's/[\\][nrt]/ /g; s/[^A-Za-z0-9_./@+-]/ /g'); do case "\${w##*/}" in ${words}) hit=1; break;; esac; done`,
|
|
44583
|
+
'[ -n "$hit" ] || exit 0',
|
|
44584
|
+
'p="$(command -v cleo)"',
|
|
44585
|
+
`d="\${XDG_RUNTIME_DIR:-\${TMPDIR:-/tmp}}"`,
|
|
44586
|
+
`k="$d/${OLDER_CLEO_MARKER_PREFIX}$(printf '%s|%s' "$p" "$PWD" | cksum | tr -c '0-9' '-')"`,
|
|
44587
|
+
`if [ -f "$k" ] && [ ! -L "$k" ] && [ -O "$k" ] && ! [ "$p" -nt "$k" ] && [ -n "$(find "$k" -mmin -60 2>/dev/null)" ]; then ${old}; exit 0; fi`,
|
|
44588
|
+
'e="$(mktemp 2>/dev/null)" || e=',
|
|
44589
|
+
// Only the older-CLEO signature (exit 127, "Unknown command hook") writes the
|
|
44590
|
+
// marker; a crash or kill of a current CLEO fails open and asks again next time.
|
|
44591
|
+
`if out="$(printf '%s' "$in" | ${HEAVY_COMMAND_HOOK_ID} --provider ${provider} 2>"\${e:-/dev/null}")"; then case "$out" in "{"*) printf '%s\\n' "$out";; esac; else rc=$?; if [ "$rc" = 127 ] && [ -n "$e" ] && grep -q 'Unknown command' "$e" 2>/dev/null; then t="$(mktemp "$k.XXXXXX" 2>/dev/null)" && mv -f "$t" "$k"; ${old}; fi; fi`,
|
|
44592
|
+
'[ -z "$e" ] || rm -f "$e"',
|
|
44593
|
+
"exit 0"
|
|
44594
|
+
].join("; ");
|
|
44595
|
+
}
|
|
44596
|
+
function heavyCommandHookCommand(provider) {
|
|
44597
|
+
const script = heavyCommandGuardScript(provider);
|
|
44598
|
+
const line = provider === "codex" ? `/bin/sh -c ${shellWord(script)}` : script;
|
|
44599
|
+
return `${line} ${CLEO_HOOK_MARKER}`;
|
|
44600
|
+
}
|
|
44601
|
+
function heavyCommandHookObject(provider) {
|
|
44602
|
+
return {
|
|
44603
|
+
type: "command",
|
|
44604
|
+
command: heavyCommandHookCommand(provider),
|
|
44605
|
+
timeout: HEAVY_COMMAND_HOOK_TIMEOUT_SEC
|
|
44606
|
+
};
|
|
44607
|
+
}
|
|
44608
|
+
function heavyCommandHookEntry(provider) {
|
|
44609
|
+
return { matcher: "Bash", hooks: [heavyCommandHookObject(provider)] };
|
|
44610
|
+
}
|
|
44611
|
+
function isHeavyHookObject(hook) {
|
|
44612
|
+
return isPlainObject2(hook) && typeof hook.command === "string" && hook.command.includes(CLEO_HOOK_MARKER) && hook.command.includes(HEAVY_COMMAND_HOOK_ID);
|
|
44613
|
+
}
|
|
44614
|
+
function placeHeavyHook(hooks, desired) {
|
|
44615
|
+
const groups = hooks.PreToolUse;
|
|
44616
|
+
if (groups === void 0) return { changed: false, found: false };
|
|
44617
|
+
if (!Array.isArray(groups)) {
|
|
44618
|
+
throw new Error('hooks "PreToolUse" is not an array; not modifying it');
|
|
44619
|
+
}
|
|
44620
|
+
let changed = false;
|
|
44621
|
+
let found = false;
|
|
44622
|
+
const next = [];
|
|
44623
|
+
for (const group of groups) {
|
|
44624
|
+
if (!isPlainObject2(group) || !Array.isArray(group.hooks)) {
|
|
44625
|
+
next.push(group);
|
|
44626
|
+
continue;
|
|
44627
|
+
}
|
|
44628
|
+
const kept = [];
|
|
44629
|
+
let groupChanged = false;
|
|
44630
|
+
for (const hook of group.hooks) {
|
|
44631
|
+
if (!isHeavyHookObject(hook)) {
|
|
44632
|
+
kept.push(hook);
|
|
44633
|
+
} else if (desired !== null && !found) {
|
|
44634
|
+
found = true;
|
|
44635
|
+
if (JSON.stringify(hook) !== JSON.stringify(desired)) groupChanged = true;
|
|
44636
|
+
kept.push(desired);
|
|
44637
|
+
} else {
|
|
44638
|
+
groupChanged = true;
|
|
44639
|
+
}
|
|
44640
|
+
}
|
|
44641
|
+
if (!groupChanged) {
|
|
44642
|
+
next.push(group);
|
|
44643
|
+
continue;
|
|
44644
|
+
}
|
|
44645
|
+
changed = true;
|
|
44646
|
+
if (kept.length > 0) next.push({ ...group, hooks: kept });
|
|
44647
|
+
}
|
|
44648
|
+
if (changed) hooks.PreToolUse = next;
|
|
44649
|
+
return { changed, found };
|
|
44650
|
+
}
|
|
44651
|
+
async function syncJsonHeavyCommandHook(configPath, provider, mode) {
|
|
44652
|
+
if (mode === "off") {
|
|
44653
|
+
if (!existsSync3(configPath)) return "unchanged";
|
|
44654
|
+
const removed = await updateJsonConfigFile(configPath, (config2) => {
|
|
44655
|
+
if (config2.hooks === void 0) return false;
|
|
44656
|
+
return placeHeavyHook(hookMap(config2), null).changed;
|
|
44657
|
+
});
|
|
44658
|
+
return removed ? "removed" : "unchanged";
|
|
44659
|
+
}
|
|
44660
|
+
ensureParentDir(configPath);
|
|
44661
|
+
clearOlderCleoMarkers();
|
|
44662
|
+
let result = "unchanged";
|
|
44663
|
+
await updateJsonConfigFile(configPath, (config2) => {
|
|
44664
|
+
const hooks = hookMap(config2);
|
|
44665
|
+
const placed = placeHeavyHook(hooks, heavyCommandHookObject(provider));
|
|
44666
|
+
if (placed.found) {
|
|
44667
|
+
if (placed.changed) result = "updated";
|
|
44668
|
+
return placed.changed;
|
|
44669
|
+
}
|
|
44670
|
+
const existing = hooks.PreToolUse;
|
|
44671
|
+
hooks.PreToolUse = [
|
|
44672
|
+
...Array.isArray(existing) ? existing : [],
|
|
44673
|
+
heavyCommandHookEntry(provider)
|
|
44674
|
+
];
|
|
44675
|
+
result = "installed";
|
|
44676
|
+
return true;
|
|
44677
|
+
});
|
|
44678
|
+
return result;
|
|
44679
|
+
}
|
|
44680
|
+
function gitOutput(projectDir, args) {
|
|
44681
|
+
try {
|
|
44682
|
+
return execFileSync("git", ["-C", projectDir, ...args], {
|
|
44683
|
+
encoding: "utf-8",
|
|
44684
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
44685
|
+
timeout: 5e3
|
|
44686
|
+
}).trim();
|
|
44687
|
+
} catch {
|
|
44688
|
+
return null;
|
|
44689
|
+
}
|
|
44690
|
+
}
|
|
44691
|
+
function excludeFile(projectDir) {
|
|
44692
|
+
if (gitOutput(projectDir, ["rev-parse", "--is-inside-work-tree"]) !== "true") return null;
|
|
44693
|
+
const path = gitOutput(projectDir, ["rev-parse", "--git-path", "info/exclude"]);
|
|
44694
|
+
if (path === null || path === "") return null;
|
|
44695
|
+
return isAbsolute(path) ? path : join3(projectDir, path);
|
|
44696
|
+
}
|
|
44697
|
+
function excludeLine(projectDir, relPath) {
|
|
44698
|
+
const prefix = gitOutput(projectDir, ["rev-parse", "--show-prefix"]) ?? "";
|
|
44699
|
+
return `/${prefix}${relPath}`;
|
|
44700
|
+
}
|
|
44701
|
+
function excludeHookFileFromGit(projectDir, relPath, marker16 = HOOK_FILE_EXCLUDE_MARKER) {
|
|
44702
|
+
const exclude = excludeFile(projectDir);
|
|
44703
|
+
if (exclude === null) return false;
|
|
44704
|
+
if (gitOutput(projectDir, ["check-ignore", relPath]) !== null) return false;
|
|
44705
|
+
if (gitOutput(projectDir, ["ls-files", "--error-unmatch", relPath]) !== null) return false;
|
|
44706
|
+
const line = excludeLine(projectDir, relPath);
|
|
44707
|
+
const text = existsSync3(exclude) ? readFileSync3(exclude, "utf-8") : "";
|
|
44708
|
+
if (text.split("\n").includes(line)) return false;
|
|
44709
|
+
const block = `${marker16}
|
|
44710
|
+
${line}
|
|
44711
|
+
`;
|
|
44712
|
+
mkdirSync(dirname(exclude), { recursive: true });
|
|
44713
|
+
writeFileSync(exclude, text === "" || text.endsWith("\n") ? text + block : `${text}
|
|
44714
|
+
${block}`);
|
|
44715
|
+
return true;
|
|
44716
|
+
}
|
|
44717
|
+
function unexcludeHookFileFromGit(projectDir, relPath) {
|
|
44718
|
+
const exclude = excludeFile(projectDir);
|
|
44719
|
+
if (exclude === null || !existsSync3(exclude)) return false;
|
|
44720
|
+
const lines = readFileSync3(exclude, "utf-8").split("\n");
|
|
44721
|
+
const at = lines.indexOf(excludeLine(projectDir, relPath));
|
|
44722
|
+
const above = lines[at - 1];
|
|
44723
|
+
if (at < 1 || above !== LOCAL_SETTINGS_EXCLUDE_MARKER && above !== HOOK_FILE_EXCLUDE_MARKER) {
|
|
44724
|
+
return false;
|
|
44725
|
+
}
|
|
44726
|
+
lines.splice(at - 1, 2);
|
|
44727
|
+
writeFileSync(exclude, lines.join("\n"));
|
|
44728
|
+
return true;
|
|
44729
|
+
}
|
|
44730
|
+
function hookFileVisibleToGit(projectDir, relPath) {
|
|
44731
|
+
if (gitOutput(projectDir, ["rev-parse", "--is-inside-work-tree"]) !== "true") return false;
|
|
44732
|
+
if (gitOutput(projectDir, ["check-ignore", relPath]) !== null) return false;
|
|
44733
|
+
return gitOutput(projectDir, ["ls-files", "--error-unmatch", relPath]) === null;
|
|
44734
|
+
}
|
|
44735
|
+
function excludeLocalSettingsFromGit(projectDir) {
|
|
44736
|
+
return excludeHookFileFromGit(projectDir, CLAUDE_LOCAL_SETTINGS, LOCAL_SETTINGS_EXCLUDE_MARKER);
|
|
44737
|
+
}
|
|
44738
|
+
function unexcludeLocalSettingsFromGit(projectDir) {
|
|
44739
|
+
return unexcludeHookFileFromGit(projectDir, CLAUDE_LOCAL_SETTINGS);
|
|
44740
|
+
}
|
|
44741
|
+
function cleoCreatedConfig(config2) {
|
|
44742
|
+
if (!isPlainObject2(config2) || Object.keys(config2).some((k) => k !== "hooks")) return false;
|
|
44743
|
+
if (!isPlainObject2(config2.hooks)) return false;
|
|
44744
|
+
let mine = 0;
|
|
44745
|
+
for (const groups of Object.values(config2.hooks)) {
|
|
44746
|
+
if (!Array.isArray(groups)) return false;
|
|
44747
|
+
for (const group of groups) {
|
|
44748
|
+
if (!isPlainObject2(group) || !Array.isArray(group.hooks)) return false;
|
|
44749
|
+
for (const hook of group.hooks) {
|
|
44750
|
+
if (!isPlainObject2(hook) || typeof hook.command !== "string" || !hook.command.includes(CLEO_HOOK_MARKER)) {
|
|
44751
|
+
return false;
|
|
44752
|
+
}
|
|
44753
|
+
mine++;
|
|
44754
|
+
}
|
|
44755
|
+
}
|
|
44756
|
+
}
|
|
44757
|
+
return mine > 0;
|
|
44758
|
+
}
|
|
44759
|
+
function codexHooksSharedReason(projectDir, checkGit = true) {
|
|
44760
|
+
const file2 = join3(projectDir, CODEX_HOOKS_FILE);
|
|
44761
|
+
if (checkGit && gitOutput(projectDir, ["ls-files", "--error-unmatch", CODEX_HOOKS_FILE]) !== null) {
|
|
44762
|
+
return "is tracked by git (a shared team config)";
|
|
44763
|
+
}
|
|
44764
|
+
if (!existsSync3(file2)) return null;
|
|
44765
|
+
let config2;
|
|
44766
|
+
try {
|
|
44767
|
+
config2 = JSON.parse(readFileSync3(file2, "utf-8"));
|
|
44768
|
+
} catch {
|
|
44769
|
+
return "is the project's own Codex hook config (empty or not valid JSON)";
|
|
44770
|
+
}
|
|
44771
|
+
return cleoCreatedConfig(config2) ? null : "is the project's own Codex hook config";
|
|
44772
|
+
}
|
|
44773
|
+
function committedCodexHookHoldsCleo(projectDir) {
|
|
44774
|
+
const committed = gitOutput(projectDir, ["show", `HEAD:./${CODEX_HOOKS_FILE}`]);
|
|
44775
|
+
if (committed === null || committed === "") return false;
|
|
44776
|
+
try {
|
|
44777
|
+
const config2 = JSON.parse(committed);
|
|
44778
|
+
if (!isPlainObject2(config2)) return false;
|
|
44779
|
+
const groups = isPlainObject2(config2.hooks) ? config2.hooks.PreToolUse : void 0;
|
|
44780
|
+
return Array.isArray(groups) && groups.some(
|
|
44781
|
+
(g) => isPlainObject2(g) && Array.isArray(g.hooks) && g.hooks.some(isHeavyHookObject)
|
|
44782
|
+
);
|
|
44783
|
+
} catch {
|
|
44784
|
+
return false;
|
|
44785
|
+
}
|
|
44786
|
+
}
|
|
44787
|
+
function jsonEqual(a, b) {
|
|
44788
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
44789
|
+
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((v, i) => jsonEqual(v, b[i]));
|
|
44790
|
+
}
|
|
44791
|
+
if (isPlainObject2(a) && isPlainObject2(b)) {
|
|
44792
|
+
const keys = Object.keys(a);
|
|
44793
|
+
return keys.length === Object.keys(b).length && keys.every((k) => Object.hasOwn(b, k) && jsonEqual(a[k], b[k]));
|
|
44794
|
+
}
|
|
44795
|
+
return a === b;
|
|
44796
|
+
}
|
|
44797
|
+
function restoreCommittedCodexHooks(projectDir) {
|
|
44798
|
+
if (gitOutput(projectDir, ["ls-files", "--error-unmatch", CODEX_HOOKS_FILE]) === null)
|
|
44799
|
+
return false;
|
|
44800
|
+
const file2 = join3(projectDir, CODEX_HOOKS_FILE);
|
|
44801
|
+
let committed;
|
|
44802
|
+
let working;
|
|
44803
|
+
try {
|
|
44804
|
+
committed = execFileSync("git", ["-C", projectDir, "show", `HEAD:./${CODEX_HOOKS_FILE}`], {
|
|
44805
|
+
encoding: "utf-8",
|
|
44806
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
44807
|
+
timeout: 5e3
|
|
44808
|
+
});
|
|
44809
|
+
working = JSON.parse(readFileSync3(file2, "utf-8"));
|
|
44810
|
+
} catch {
|
|
44811
|
+
return false;
|
|
44812
|
+
}
|
|
44813
|
+
if (!isPlainObject2(working)) return false;
|
|
44814
|
+
const hooks = hookMap(working);
|
|
44815
|
+
if (!placeHeavyHook(hooks, null).changed) return false;
|
|
44816
|
+
try {
|
|
44817
|
+
if (!jsonEqual(working, JSON.parse(committed))) return false;
|
|
44818
|
+
} catch {
|
|
44819
|
+
return false;
|
|
44820
|
+
}
|
|
44821
|
+
writeFileSync(file2, committed);
|
|
44822
|
+
return true;
|
|
44823
|
+
}
|
|
44824
|
+
function excludedByCleo(projectDir, relPath) {
|
|
44825
|
+
const exclude = excludeFile(projectDir);
|
|
44826
|
+
if (exclude === null || !existsSync3(exclude)) return false;
|
|
44827
|
+
const lines = readFileSync3(exclude, "utf-8").split("\n");
|
|
44828
|
+
const at = lines.indexOf(excludeLine(projectDir, relPath));
|
|
44829
|
+
const above = lines[at - 1];
|
|
44830
|
+
return at >= 1 && (above === LOCAL_SETTINGS_EXCLUDE_MARKER || above === HOOK_FILE_EXCLUDE_MARKER);
|
|
44831
|
+
}
|
|
44832
|
+
function codexHookSnippet() {
|
|
44833
|
+
return JSON.stringify(heavyCommandHookEntry("codex"));
|
|
44834
|
+
}
|
|
44835
|
+
function trackedFileModified(projectDir, relPath) {
|
|
44836
|
+
if (gitOutput(projectDir, ["ls-files", "--error-unmatch", relPath]) === null) return false;
|
|
44837
|
+
return (gitOutput(projectDir, ["diff", "--name-only", "HEAD", "--", relPath]) ?? "") !== "";
|
|
44838
|
+
}
|
|
44839
|
+
async function syncCodexHeavyCommandHook(projectDir, mode) {
|
|
44840
|
+
const file2 = join3(projectDir, CODEX_HOOKS_FILE);
|
|
44841
|
+
if (mode !== "off") {
|
|
44842
|
+
const shared = codexHooksSharedReason(projectDir);
|
|
44843
|
+
if (shared !== null) {
|
|
44844
|
+
unexcludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
|
|
44845
|
+
throw new HeavyHookSharedConfigError(file2, shared);
|
|
44846
|
+
}
|
|
44847
|
+
} else if (committedCodexHookHoldsCleo(projectDir)) {
|
|
44848
|
+
throw new HeavyHookSharedConfigError(
|
|
44849
|
+
file2,
|
|
44850
|
+
"holds CLEO's hook as the team committed it (removing it is a team change)"
|
|
44851
|
+
);
|
|
44852
|
+
} else if (restoreCommittedCodexHooks(projectDir)) {
|
|
44853
|
+
unexcludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
|
|
44854
|
+
return "removed";
|
|
44855
|
+
}
|
|
44856
|
+
const result = await syncJsonHeavyCommandHook(file2, "codex", mode);
|
|
44857
|
+
if (mode === "off") unexcludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
|
|
44858
|
+
else excludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
|
|
44859
|
+
return result;
|
|
44860
|
+
}
|
|
44861
|
+
async function syncClaudeCodeHeavyCommandHook(projectDir, mode) {
|
|
44862
|
+
const result = await syncJsonHeavyCommandHook(
|
|
44863
|
+
join3(projectDir, CLAUDE_LOCAL_SETTINGS),
|
|
44864
|
+
"claude-code",
|
|
44865
|
+
mode
|
|
44866
|
+
);
|
|
44867
|
+
if (mode === "off") unexcludeLocalSettingsFromGit(projectDir);
|
|
44868
|
+
else excludeLocalSettingsFromGit(projectDir);
|
|
44869
|
+
try {
|
|
44870
|
+
await syncJsonHeavyCommandHook(
|
|
44871
|
+
join3(projectDir, ".claude", "settings.json"),
|
|
44872
|
+
"claude-code",
|
|
44873
|
+
"off"
|
|
44874
|
+
);
|
|
44875
|
+
} catch {
|
|
44876
|
+
}
|
|
44877
|
+
return result;
|
|
44878
|
+
}
|
|
44879
|
+
function opencodeHeavyCommandPluginSource() {
|
|
44880
|
+
return [
|
|
44881
|
+
"// CLEO heavy-command plugin for OpenCode (generated by @cleocode/adapters, T12983).",
|
|
44882
|
+
"// Routes heavy shell commands (tests, builds, typechecks, installs) through",
|
|
44883
|
+
"// `cleo run`, the machine-wide resource budget. Opt out with",
|
|
44884
|
+
'// CLEO_HEAVY_COMMAND_HOOK=off, or set resources.heavyCommandHook to "off" and',
|
|
44885
|
+
"// run `cleo upgrade` (which deletes this file). Fails open: on any error the",
|
|
44886
|
+
"// command runs unchanged.",
|
|
44887
|
+
"",
|
|
44888
|
+
"import { execFile } from 'node:child_process';",
|
|
44889
|
+
"",
|
|
44890
|
+
`const HEAVY = /(?:^|[^A-Za-z0-9_.@+-])(?:${HEAVY_TOOL_WORDS.join("|")})(?=$|[^A-Za-z0-9_.@+-])/;`,
|
|
44891
|
+
"const contexts = new Map();",
|
|
44892
|
+
"",
|
|
44893
|
+
"function ask(payload) {",
|
|
44894
|
+
" return new Promise((done) => {",
|
|
44895
|
+
" const child = execFile(",
|
|
44896
|
+
" 'cleo',",
|
|
44897
|
+
" ['hook', 'heavy-command', '--provider', 'opencode'],",
|
|
44898
|
+
` { timeout: ${HEAVY_COMMAND_HOOK_TIMEOUT_SEC * 1e3} },`,
|
|
44899
|
+
" (err, stdout) => done(err ? '' : stdout),",
|
|
44900
|
+
" );",
|
|
44901
|
+
" child.on('error', () => done(''));",
|
|
44902
|
+
" child.stdin?.end(JSON.stringify(payload));",
|
|
44903
|
+
" });",
|
|
44904
|
+
"}",
|
|
44905
|
+
"",
|
|
44906
|
+
"export const CleoHeavyCommand = async ({ directory }) => ({",
|
|
44907
|
+
" 'tool.execute.before': async (input, output) => {",
|
|
44908
|
+
" if (input?.tool !== 'bash' || typeof output?.args?.command !== 'string') return;",
|
|
44909
|
+
" if (process.env.CLEO_HEAVY_COMMAND_HOOK === 'off') return;",
|
|
44910
|
+
" if (!HEAVY.test(output.args.command)) return;",
|
|
44911
|
+
" try {",
|
|
44912
|
+
" const text = await ask({ tool_name: 'bash', tool_input: output.args, cwd: directory });",
|
|
44913
|
+
" const answer = JSON.parse(text || '{}');",
|
|
44914
|
+
" if (typeof answer.command === 'string') output.args.command = answer.command;",
|
|
44915
|
+
" if (typeof answer.timeout === 'number') output.args.timeout = answer.timeout;",
|
|
44916
|
+
" if (typeof answer.context === 'string' && input.callID) contexts.set(input.callID, answer.context);",
|
|
44917
|
+
" } catch {",
|
|
44918
|
+
" // Fail open.",
|
|
44919
|
+
" }",
|
|
44920
|
+
" },",
|
|
44921
|
+
" 'tool.execute.after': async (input, output) => {",
|
|
44922
|
+
" const context = input?.callID ? contexts.get(input.callID) : undefined;",
|
|
44923
|
+
" if (context === undefined) return;",
|
|
44924
|
+
" contexts.delete(input.callID);",
|
|
44925
|
+
" if (typeof output?.output === 'string') output.output += '\\n\\n' + context;",
|
|
44926
|
+
" },",
|
|
44927
|
+
"});",
|
|
44928
|
+
""
|
|
44929
|
+
].join("\n");
|
|
44930
|
+
}
|
|
44931
|
+
function syncOpencodeHeavyCommandPlugin(projectDir, mode) {
|
|
44932
|
+
const pluginPath = join3(projectDir, OPENCODE_PLUGIN_FILE);
|
|
44933
|
+
const exists = existsSync3(pluginPath);
|
|
44934
|
+
if (mode === "off") {
|
|
44935
|
+
unexcludeHookFileFromGit(projectDir, OPENCODE_PLUGIN_FILE);
|
|
44936
|
+
if (!exists) return "unchanged";
|
|
44937
|
+
rmSync(pluginPath, { force: true });
|
|
44938
|
+
return "removed";
|
|
44939
|
+
}
|
|
44940
|
+
const source = opencodeHeavyCommandPluginSource();
|
|
44941
|
+
const current = exists && readFileSync3(pluginPath, "utf-8") === source;
|
|
44942
|
+
if (!current) {
|
|
44943
|
+
ensureParentDir(pluginPath);
|
|
44944
|
+
writeFileSync(pluginPath, source, "utf-8");
|
|
44945
|
+
}
|
|
44946
|
+
excludeHookFileFromGit(projectDir, OPENCODE_PLUGIN_FILE);
|
|
44947
|
+
return current ? "unchanged" : exists ? "updated" : "installed";
|
|
44948
|
+
}
|
|
44949
|
+
var HEAVY_COMMAND_HOOK_ID, HEAVY_COMMAND_HOOK_TIMEOUT_SEC, OPENCODE_HEAVY_COMMAND_PLUGIN, HEAVY_TOOL_WORDS, HeavyHookPathBlockedError, OLDER_CLEO_HOOK_ANSWER, OLDER_CLEO_MARKER_PREFIX, CLAUDE_LOCAL_SETTINGS, LOCAL_SETTINGS_EXCLUDE_MARKER, HOOK_FILE_EXCLUDE_MARKER, CODEX_HOOKS_FILE, OPENCODE_PLUGIN_FILE, HeavyHookSharedConfigError;
|
|
44950
|
+
var init_heavy_command_hook_install = __esm({
|
|
44951
|
+
"packages/adapters/src/providers/shared/heavy-command-hook-install.ts"() {
|
|
44952
|
+
"use strict";
|
|
44953
|
+
init_hook_config();
|
|
44954
|
+
HEAVY_COMMAND_HOOK_ID = "cleo hook heavy-command";
|
|
44955
|
+
HEAVY_COMMAND_HOOK_TIMEOUT_SEC = 20;
|
|
44956
|
+
OPENCODE_HEAVY_COMMAND_PLUGIN = "cleo-heavy-command.js";
|
|
44957
|
+
HEAVY_TOOL_WORDS = Object.freeze([
|
|
44958
|
+
"vitest",
|
|
44959
|
+
"jest",
|
|
44960
|
+
"mocha",
|
|
44961
|
+
"ava",
|
|
44962
|
+
"tap",
|
|
44963
|
+
"playwright",
|
|
44964
|
+
"pytest",
|
|
44965
|
+
"rspec",
|
|
44966
|
+
"phpunit",
|
|
44967
|
+
"tsc",
|
|
44968
|
+
"tsup",
|
|
44969
|
+
"turbo",
|
|
44970
|
+
"vite",
|
|
44971
|
+
"esbuild",
|
|
44972
|
+
"webpack",
|
|
44973
|
+
"rollup",
|
|
44974
|
+
"next",
|
|
44975
|
+
"nx",
|
|
44976
|
+
"biome",
|
|
44977
|
+
"eslint",
|
|
44978
|
+
"svelte-check",
|
|
44979
|
+
"npm",
|
|
44980
|
+
"pnpm",
|
|
44981
|
+
"yarn",
|
|
44982
|
+
"bun",
|
|
44983
|
+
"npx",
|
|
44984
|
+
"pnpx",
|
|
44985
|
+
"bunx",
|
|
44986
|
+
"cargo",
|
|
44987
|
+
"go"
|
|
44988
|
+
]);
|
|
44989
|
+
HeavyHookPathBlockedError = class extends Error {
|
|
44990
|
+
/** The existing path that is not a directory. */
|
|
44991
|
+
path;
|
|
44992
|
+
/**
|
|
44993
|
+
* @param path - the existing non-directory path.
|
|
44994
|
+
* @param target - the config file that would have lived under it.
|
|
44995
|
+
*/
|
|
44996
|
+
constructor(path, target) {
|
|
44997
|
+
super(`${path} exists but is not a directory, so ${target} cannot be created under it`);
|
|
44998
|
+
this.name = "HeavyHookPathBlockedError";
|
|
44999
|
+
this.path = path;
|
|
45000
|
+
}
|
|
45001
|
+
};
|
|
45002
|
+
OLDER_CLEO_HOOK_ANSWER = JSON.stringify({
|
|
45003
|
+
hookSpecificOutput: {
|
|
45004
|
+
hookEventName: "PreToolUse",
|
|
45005
|
+
additionalContext: "[cleo] This may be a heavy command, but the cleo on PATH predates cleo hook and cleo run, so it runs outside the machine-wide resource budget. Upgrade CLEO to govern it."
|
|
45006
|
+
}
|
|
45007
|
+
});
|
|
45008
|
+
OLDER_CLEO_MARKER_PREFIX = "cleo-hook-unsupported-";
|
|
45009
|
+
CLAUDE_LOCAL_SETTINGS = ".claude/settings.local.json";
|
|
45010
|
+
LOCAL_SETTINGS_EXCLUDE_MARKER = "# cleo-hook: keep the per-machine heavy-command hook settings out of git (T12983)";
|
|
45011
|
+
HOOK_FILE_EXCLUDE_MARKER = "# cleo-hook: keep a per-machine heavy-command hook file out of git (T13124)";
|
|
45012
|
+
CODEX_HOOKS_FILE = ".codex/hooks.json";
|
|
45013
|
+
OPENCODE_PLUGIN_FILE = `.opencode/plugins/${OPENCODE_HEAVY_COMMAND_PLUGIN}`;
|
|
45014
|
+
HeavyHookSharedConfigError = class extends Error {
|
|
45015
|
+
/** The project's own config file. */
|
|
45016
|
+
path;
|
|
45017
|
+
/**
|
|
45018
|
+
* @param path - the config file.
|
|
45019
|
+
* @param why - what makes it the project's own.
|
|
45020
|
+
*/
|
|
45021
|
+
constructor(path, why) {
|
|
45022
|
+
super(`${path} ${why}, so CLEO does not write or hide it`);
|
|
45023
|
+
this.name = "HeavyHookSharedConfigError";
|
|
45024
|
+
this.path = path;
|
|
45025
|
+
}
|
|
45026
|
+
};
|
|
45027
|
+
}
|
|
45028
|
+
});
|
|
45029
|
+
|
|
44465
45030
|
// packages/adapters/src/providers/claude-code/paths.ts
|
|
44466
|
-
import {
|
|
44467
|
-
import {
|
|
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";
|
|
44468
45034
|
function claudeSettingsPath() {
|
|
44469
|
-
return new ClaudeCodePathProvider().getSettingsPath() ??
|
|
45035
|
+
return new ClaudeCodePathProvider().getSettingsPath() ?? join4(homedir3(), ".claude", "settings.json");
|
|
44470
45036
|
}
|
|
44471
|
-
|
|
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;
|
|
44472
45080
|
var init_paths = __esm({
|
|
44473
45081
|
"packages/adapters/src/providers/claude-code/paths.ts"() {
|
|
44474
45082
|
"use strict";
|
|
45083
|
+
init_heavy_command_hook_install();
|
|
44475
45084
|
init_hook_config();
|
|
44476
45085
|
ClaudeCodePathProvider = class {
|
|
44477
45086
|
/** Get the provider's root configuration directory. */
|
|
44478
45087
|
getProviderDir() {
|
|
44479
|
-
return process.env["CLAUDE_HOME"] ??
|
|
45088
|
+
return process.env["CLAUDE_HOME"] ?? join4(homedir3(), ".claude");
|
|
44480
45089
|
}
|
|
44481
45090
|
/** Get the path to the provider's settings file, or null if unavailable. */
|
|
44482
45091
|
getSettingsPath() {
|
|
44483
|
-
return process.env["CLAUDE_SETTINGS"] ??
|
|
45092
|
+
return process.env["CLAUDE_SETTINGS"] ?? join4(this.getProviderDir(), "settings.json");
|
|
44484
45093
|
}
|
|
44485
45094
|
/** Get the directory where agents are installed, or null if unsupported. */
|
|
44486
45095
|
getAgentInstallDir() {
|
|
44487
|
-
return
|
|
45096
|
+
return join4(this.getProviderDir(), "agents");
|
|
44488
45097
|
}
|
|
44489
45098
|
/** Get the path to the provider's memory database, or null if unsupported. */
|
|
44490
45099
|
getMemoryDbPath() {
|
|
44491
|
-
return process.env["CLAUDE_MEM_DB"] ??
|
|
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;
|
|
44492
45115
|
}
|
|
44493
45116
|
};
|
|
44494
45117
|
}
|
|
44495
45118
|
});
|
|
44496
45119
|
|
|
44497
45120
|
// packages/adapters/src/providers/claude-code/context-monitor.ts
|
|
44498
|
-
import { existsSync as
|
|
45121
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
44499
45122
|
import { mkdir } from "node:fs/promises";
|
|
44500
|
-
import { homedir as
|
|
44501
|
-
import { dirname, join as
|
|
45123
|
+
import { homedir as homedir4 } from "node:os";
|
|
45124
|
+
import { dirname as dirname3, join as join5 } from "node:path";
|
|
44502
45125
|
import { resolveLegacyCleoDir } from "@cleocode/paths";
|
|
44503
45126
|
function getContextStatusFromPercentage(percentage) {
|
|
44504
45127
|
if (percentage >= THRESHOLDS.EMERGENCY) return "emergency";
|
|
@@ -44533,10 +45156,10 @@ var init_context_monitor = __esm({
|
|
|
44533
45156
|
const totalTokens = inputTokens + outputTokens + cacheCreate;
|
|
44534
45157
|
const percentage = Math.floor(totalTokens * 100 / contextSize);
|
|
44535
45158
|
const status = getContextStatusFromPercentage(percentage);
|
|
44536
|
-
const cleoDir = cwd ?
|
|
44537
|
-
if (
|
|
44538
|
-
const stateDir =
|
|
44539
|
-
const statePath =
|
|
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");
|
|
44540
45163
|
const state = {
|
|
44541
45164
|
$schema: "https://cleo-dev.com/schemas/v1/context-state.schema.json",
|
|
44542
45165
|
version: "1.0.0",
|
|
@@ -44563,8 +45186,8 @@ var init_context_monitor = __esm({
|
|
|
44563
45186
|
cleoSessionId: ""
|
|
44564
45187
|
};
|
|
44565
45188
|
try {
|
|
44566
|
-
await mkdir(
|
|
44567
|
-
|
|
45189
|
+
await mkdir(dirname3(statePath), { recursive: true });
|
|
45190
|
+
writeFileSync2(statePath, JSON.stringify(state, null, 2));
|
|
44568
45191
|
} catch {
|
|
44569
45192
|
}
|
|
44570
45193
|
}
|
|
@@ -44573,9 +45196,9 @@ var init_context_monitor = __esm({
|
|
|
44573
45196
|
/** Check the current statusline integration status in Claude Code settings. */
|
|
44574
45197
|
checkStatuslineIntegration() {
|
|
44575
45198
|
const settingsPath = this.pathProvider.getSettingsPath();
|
|
44576
|
-
if (!settingsPath || !
|
|
45199
|
+
if (!settingsPath || !existsSync4(settingsPath)) return "no_settings";
|
|
44577
45200
|
try {
|
|
44578
|
-
const settings = JSON.parse(
|
|
45201
|
+
const settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
44579
45202
|
const statusLine = settings.statusLine;
|
|
44580
45203
|
if (!statusLine?.type) return "not_configured";
|
|
44581
45204
|
if (statusLine.type !== "command") return "custom_no_cleo";
|
|
@@ -44583,10 +45206,10 @@ var init_context_monitor = __esm({
|
|
|
44583
45206
|
if (cmd.includes("context-monitor.sh") || cmd.includes("cleo-statusline") || cmd.includes(".context-state.json") || cmd.includes("context-states")) {
|
|
44584
45207
|
return "configured";
|
|
44585
45208
|
}
|
|
44586
|
-
const scriptPath = cmd.startsWith("~") ? cmd.replace("~",
|
|
44587
|
-
if (
|
|
45209
|
+
const scriptPath = cmd.startsWith("~") ? cmd.replace("~", homedir4()) : cmd;
|
|
45210
|
+
if (existsSync4(scriptPath)) {
|
|
44588
45211
|
try {
|
|
44589
|
-
const content =
|
|
45212
|
+
const content = readFileSync4(scriptPath, "utf-8");
|
|
44590
45213
|
if (content.includes("context-state.json")) return "configured";
|
|
44591
45214
|
} catch {
|
|
44592
45215
|
}
|
|
@@ -44601,7 +45224,7 @@ var init_context_monitor = __esm({
|
|
|
44601
45224
|
return {
|
|
44602
45225
|
statusLine: {
|
|
44603
45226
|
type: "command",
|
|
44604
|
-
command:
|
|
45227
|
+
command: join5(resolveLegacyCleoDir(), "lib", "session", "context-monitor.sh")
|
|
44605
45228
|
}
|
|
44606
45229
|
};
|
|
44607
45230
|
}
|
|
@@ -44622,15 +45245,56 @@ var init_context_monitor = __esm({
|
|
|
44622
45245
|
});
|
|
44623
45246
|
|
|
44624
45247
|
// packages/adapters/src/providers/claude-code/hooks.ts
|
|
44625
|
-
import { existsSync as
|
|
45248
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
44626
45249
|
import { readdir, readFile } from "node:fs/promises";
|
|
44627
|
-
import { join as
|
|
44628
|
-
import { updateJsonConfigFile } from "@cleocode/caamp";
|
|
44629
|
-
|
|
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;
|
|
44630
45285
|
var init_hooks = __esm({
|
|
44631
45286
|
"packages/adapters/src/providers/claude-code/hooks.ts"() {
|
|
44632
45287
|
"use strict";
|
|
45288
|
+
init_heavy_command_hook_install();
|
|
44633
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
|
+
]);
|
|
44634
45298
|
PROVIDER_ID = "claude-code";
|
|
44635
45299
|
CLAUDE_CODE_EVENT_MAP = {
|
|
44636
45300
|
// CAAMP: toNative('SessionStart', 'claude-code') = 'SessionStart'
|
|
@@ -44685,95 +45349,111 @@ var init_hooks = __esm({
|
|
|
44685
45349
|
/**
|
|
44686
45350
|
* Register native hooks for a project.
|
|
44687
45351
|
*
|
|
44688
|
-
* Writes CLEO hook entries to
|
|
44689
|
-
*
|
|
44690
|
-
*
|
|
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).
|
|
44691
45361
|
*
|
|
44692
|
-
* Idempotent: skips writing if
|
|
45362
|
+
* Idempotent: skips writing if the native hooks are already present.
|
|
44693
45363
|
*
|
|
44694
45364
|
* Hook entries registered:
|
|
44695
45365
|
* - `Stop` → `cleo session end --quiet` (triggers LLM extraction, reflector, consolidation)
|
|
44696
45366
|
* - `PostToolUse` (Write|Edit) → brain observation for file modifications
|
|
44697
|
-
*
|
|
45367
|
+
* and the NEXUS post-check
|
|
44698
45368
|
*
|
|
44699
|
-
* @param projectDir - Project
|
|
44700
|
-
* @task T164 @task T555
|
|
45369
|
+
* @param projectDir - Project whose Claude Code settings receive the hooks
|
|
45370
|
+
* @task T164 @task T555 @task T13227
|
|
44701
45371
|
*/
|
|
44702
45372
|
async registerNativeHooks(projectDir) {
|
|
44703
45373
|
this.projectDir = projectDir;
|
|
44704
45374
|
this.registered = true;
|
|
44705
|
-
await this.updateSettings((settings) => {
|
|
45375
|
+
const wrote = await this.updateSettings(projectDir, (settings) => {
|
|
44706
45376
|
const hooks = hookMap(settings);
|
|
44707
|
-
if (
|
|
44708
|
-
return false;
|
|
44709
|
-
}
|
|
45377
|
+
if (hasNativeHooks(hooks)) return false;
|
|
44710
45378
|
appendHookEntry(hooks, "Stop", {
|
|
44711
45379
|
matcher: "",
|
|
44712
|
-
hooks: [{ type: "command", command:
|
|
45380
|
+
hooks: [{ type: "command", command: NATIVE_STOP_HOOK_COMMAND }]
|
|
44713
45381
|
});
|
|
44714
45382
|
appendHookEntry(hooks, "PostToolUse", {
|
|
44715
45383
|
matcher: "Write|Edit",
|
|
44716
45384
|
hooks: [
|
|
44717
|
-
{
|
|
44718
|
-
|
|
44719
|
-
command: `cleo observe "File modified via $TOOL_NAME" --title "tool-use" --quiet # cleo-hook`
|
|
44720
|
-
},
|
|
44721
|
-
{
|
|
44722
|
-
// NEXUS post-modification check: re-index changed files and flag regressions.
|
|
44723
|
-
// $TOOL_INPUT_file_path is populated by Claude Code for Write/Edit events.
|
|
44724
|
-
type: "command",
|
|
44725
|
-
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`
|
|
44726
|
-
}
|
|
45385
|
+
{ type: "command", command: NATIVE_OBSERVE_HOOK_COMMAND },
|
|
45386
|
+
{ type: "command", command: NATIVE_NEXUS_HOOK_COMMAND }
|
|
44727
45387
|
]
|
|
44728
45388
|
});
|
|
44729
45389
|
return true;
|
|
44730
45390
|
});
|
|
45391
|
+
if (wrote) excludeLocalSettingsFromGit(projectDir);
|
|
44731
45392
|
}
|
|
44732
45393
|
/**
|
|
44733
45394
|
* Unregister native hooks.
|
|
44734
45395
|
*
|
|
44735
|
-
* Removes
|
|
44736
|
-
*
|
|
44737
|
-
* and
|
|
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}.
|
|
44738
45401
|
*
|
|
44739
|
-
* @task T164 @task T555
|
|
45402
|
+
* @task T164 @task T555 @task T13227
|
|
44740
45403
|
*/
|
|
44741
45404
|
async unregisterNativeHooks() {
|
|
45405
|
+
const projectDir = this.projectDir;
|
|
44742
45406
|
this.registered = false;
|
|
44743
45407
|
this.projectDir = null;
|
|
44744
|
-
if (
|
|
44745
|
-
|
|
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) => {
|
|
44746
45417
|
if (settings.hooks === void 0) return false;
|
|
44747
|
-
return
|
|
45418
|
+
return removeNativeHooks(hookMap(settings));
|
|
44748
45419
|
});
|
|
44749
45420
|
}
|
|
44750
45421
|
/** The last settings.json failure, or `null` when the last update succeeded. */
|
|
44751
45422
|
settingsError = null;
|
|
44752
45423
|
/**
|
|
44753
|
-
* Why the last settings
|
|
45424
|
+
* Why the last settings update did not happen, or `null`.
|
|
44754
45425
|
*
|
|
44755
45426
|
* @remarks
|
|
44756
45427
|
* Hook registration stays non-fatal for adapter initialisation, so a
|
|
44757
|
-
* refused write (malformed settings
|
|
44758
|
-
* on stderr instead of being swallowed
|
|
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).
|
|
44759
45431
|
*
|
|
44760
45432
|
* @returns The failure message, or `null`
|
|
44761
45433
|
*/
|
|
44762
45434
|
getSettingsError() {
|
|
44763
45435
|
return this.settingsError;
|
|
44764
45436
|
}
|
|
44765
|
-
/**
|
|
44766
|
-
|
|
44767
|
-
|
|
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`;
|
|
44768
45445
|
try {
|
|
44769
|
-
|
|
45446
|
+
settingsPath = projectClaudeSettingsPath(projectDir);
|
|
45447
|
+
const wrote = await updateJsonConfigFile2(settingsPath, mutate);
|
|
44770
45448
|
this.settingsError = null;
|
|
45449
|
+
return wrote;
|
|
44771
45450
|
} catch (err) {
|
|
44772
45451
|
this.settingsError = err instanceof Error ? err.message : String(err);
|
|
44773
45452
|
process.stderr.write(
|
|
44774
45453
|
`[cleo:claude-code] hooks not written to ${settingsPath}: ${this.settingsError}
|
|
44775
45454
|
`
|
|
44776
45455
|
);
|
|
45456
|
+
return false;
|
|
44777
45457
|
}
|
|
44778
45458
|
}
|
|
44779
45459
|
/**
|
|
@@ -44880,28 +45560,28 @@ var init_hooks = __esm({
|
|
|
44880
45560
|
async getTranscript(sessionId, _projectDir) {
|
|
44881
45561
|
try {
|
|
44882
45562
|
const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "/root";
|
|
44883
|
-
const projectsDir =
|
|
45563
|
+
const projectsDir = join6(homeDir, ".claude", "projects");
|
|
44884
45564
|
let rootFiles = [];
|
|
44885
45565
|
const subagentFiles = [];
|
|
44886
45566
|
try {
|
|
44887
45567
|
const projectDirs = await readdir(projectsDir, { withFileTypes: true });
|
|
44888
45568
|
for (const projectEntry of projectDirs) {
|
|
44889
45569
|
if (!projectEntry.isDirectory()) continue;
|
|
44890
|
-
const projectDir =
|
|
45570
|
+
const projectDir = join6(projectsDir, projectEntry.name);
|
|
44891
45571
|
try {
|
|
44892
45572
|
const projectContents = await readdir(projectDir, { withFileTypes: true });
|
|
44893
45573
|
for (const entry of projectContents) {
|
|
44894
45574
|
if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
44895
|
-
rootFiles.push({ path:
|
|
45575
|
+
rootFiles.push({ path: join6(projectDir, entry.name) });
|
|
44896
45576
|
continue;
|
|
44897
45577
|
}
|
|
44898
45578
|
if (entry.isDirectory()) {
|
|
44899
|
-
const subagentsDir =
|
|
45579
|
+
const subagentsDir = join6(projectDir, entry.name, "subagents");
|
|
44900
45580
|
try {
|
|
44901
45581
|
const subagentEntries = await readdir(subagentsDir);
|
|
44902
45582
|
for (const sa of subagentEntries) {
|
|
44903
45583
|
if (sa.startsWith("agent-") && sa.endsWith(".jsonl")) {
|
|
44904
|
-
subagentFiles.push({ path:
|
|
45584
|
+
subagentFiles.push({ path: join6(subagentsDir, sa) });
|
|
44905
45585
|
}
|
|
44906
45586
|
}
|
|
44907
45587
|
} catch {
|
|
@@ -44951,344 +45631,13 @@ var init_hooks = __esm({
|
|
|
44951
45631
|
}
|
|
44952
45632
|
});
|
|
44953
45633
|
|
|
44954
|
-
// packages/adapters/src/providers/shared/heavy-command-hook-install.ts
|
|
44955
|
-
import { execFileSync } from "node:child_process";
|
|
44956
|
-
import {
|
|
44957
|
-
existsSync as existsSync5,
|
|
44958
|
-
mkdirSync,
|
|
44959
|
-
readdirSync as readdirSync2,
|
|
44960
|
-
readFileSync as readFileSync4,
|
|
44961
|
-
realpathSync,
|
|
44962
|
-
rmSync,
|
|
44963
|
-
writeFileSync as writeFileSync2
|
|
44964
|
-
} from "node:fs";
|
|
44965
|
-
import { homedir as homedir4, tmpdir } from "node:os";
|
|
44966
|
-
import { dirname as dirname2, isAbsolute, join as join6, resolve as resolve2 } from "node:path";
|
|
44967
|
-
import { updateJsonConfigFile as updateJsonConfigFile2 } from "@cleocode/caamp";
|
|
44968
|
-
function canonical(path) {
|
|
44969
|
-
try {
|
|
44970
|
-
return realpathSync(path);
|
|
44971
|
-
} catch {
|
|
44972
|
-
return resolve2(path);
|
|
44973
|
-
}
|
|
44974
|
-
}
|
|
44975
|
-
function isUserHomeDir(projectDir, home = homedir4()) {
|
|
44976
|
-
return canonical(projectDir) === canonical(home);
|
|
44977
|
-
}
|
|
44978
|
-
function clearOlderCleoMarkers(dir = process.env.XDG_RUNTIME_DIR || tmpdir()) {
|
|
44979
|
-
let removed = 0;
|
|
44980
|
-
let names;
|
|
44981
|
-
try {
|
|
44982
|
-
names = readdirSync2(dir);
|
|
44983
|
-
} catch {
|
|
44984
|
-
return 0;
|
|
44985
|
-
}
|
|
44986
|
-
for (const name15 of names) {
|
|
44987
|
-
if (!name15.startsWith(OLDER_CLEO_MARKER_PREFIX)) continue;
|
|
44988
|
-
try {
|
|
44989
|
-
rmSync(join6(dir, name15), { force: true });
|
|
44990
|
-
removed++;
|
|
44991
|
-
} catch {
|
|
44992
|
-
}
|
|
44993
|
-
}
|
|
44994
|
-
return removed;
|
|
44995
|
-
}
|
|
44996
|
-
function shellWord(text) {
|
|
44997
|
-
return `'${text.replace(/'/g, `'\\''`)}'`;
|
|
44998
|
-
}
|
|
44999
|
-
function heavyCommandGuardScript(provider) {
|
|
45000
|
-
const words = HEAVY_TOOL_WORDS.join("|");
|
|
45001
|
-
const old = `printf '%s\\n' '${OLDER_CLEO_HOOK_ANSWER}'`;
|
|
45002
|
-
return [
|
|
45003
|
-
"command -v cleo >/dev/null 2>&1 || exit 0",
|
|
45004
|
-
'in="$(cat)"',
|
|
45005
|
-
"set -f",
|
|
45006
|
-
"hit=",
|
|
45007
|
-
// `[\]` (not `\\`) matches a backslash: it survives fish's quoting under Codex.
|
|
45008
|
-
`for w in $(printf '%s' "$in" | sed 's/[\\][nrt]/ /g; s/[^A-Za-z0-9_./@+-]/ /g'); do case "\${w##*/}" in ${words}) hit=1; break;; esac; done`,
|
|
45009
|
-
'[ -n "$hit" ] || exit 0',
|
|
45010
|
-
'p="$(command -v cleo)"',
|
|
45011
|
-
`d="\${XDG_RUNTIME_DIR:-\${TMPDIR:-/tmp}}"`,
|
|
45012
|
-
`k="$d/${OLDER_CLEO_MARKER_PREFIX}$(printf '%s|%s' "$p" "$PWD" | cksum | tr -c '0-9' '-')"`,
|
|
45013
|
-
`if [ -f "$k" ] && [ ! -L "$k" ] && [ -O "$k" ] && ! [ "$p" -nt "$k" ] && [ -n "$(find "$k" -mmin -60 2>/dev/null)" ]; then ${old}; exit 0; fi`,
|
|
45014
|
-
'e="$(mktemp 2>/dev/null)" || e=',
|
|
45015
|
-
// Only the older-CLEO signature (exit 127, "Unknown command hook") writes the
|
|
45016
|
-
// marker; a crash or kill of a current CLEO fails open and asks again next time.
|
|
45017
|
-
`if out="$(printf '%s' "$in" | ${HEAVY_COMMAND_HOOK_ID} --provider ${provider} 2>"\${e:-/dev/null}")"; then case "$out" in "{"*) printf '%s\\n' "$out";; esac; else rc=$?; if [ "$rc" = 127 ] && [ -n "$e" ] && grep -q 'Unknown command' "$e" 2>/dev/null; then t="$(mktemp "$k.XXXXXX" 2>/dev/null)" && mv -f "$t" "$k"; ${old}; fi; fi`,
|
|
45018
|
-
'[ -z "$e" ] || rm -f "$e"',
|
|
45019
|
-
"exit 0"
|
|
45020
|
-
].join("; ");
|
|
45021
|
-
}
|
|
45022
|
-
function heavyCommandHookCommand(provider) {
|
|
45023
|
-
const script = heavyCommandGuardScript(provider);
|
|
45024
|
-
const line = provider === "codex" ? `/bin/sh -c ${shellWord(script)}` : script;
|
|
45025
|
-
return `${line} ${CLEO_HOOK_MARKER}`;
|
|
45026
|
-
}
|
|
45027
|
-
function heavyCommandHookObject(provider) {
|
|
45028
|
-
return {
|
|
45029
|
-
type: "command",
|
|
45030
|
-
command: heavyCommandHookCommand(provider),
|
|
45031
|
-
timeout: HEAVY_COMMAND_HOOK_TIMEOUT_SEC
|
|
45032
|
-
};
|
|
45033
|
-
}
|
|
45034
|
-
function heavyCommandHookEntry(provider) {
|
|
45035
|
-
return { matcher: "Bash", hooks: [heavyCommandHookObject(provider)] };
|
|
45036
|
-
}
|
|
45037
|
-
function isHeavyHookObject(hook) {
|
|
45038
|
-
return isPlainObject2(hook) && typeof hook.command === "string" && hook.command.includes(CLEO_HOOK_MARKER) && hook.command.includes(HEAVY_COMMAND_HOOK_ID);
|
|
45039
|
-
}
|
|
45040
|
-
function placeHeavyHook(hooks, desired) {
|
|
45041
|
-
const groups = hooks.PreToolUse;
|
|
45042
|
-
if (groups === void 0) return { changed: false, found: false };
|
|
45043
|
-
if (!Array.isArray(groups)) {
|
|
45044
|
-
throw new Error('hooks "PreToolUse" is not an array; not modifying it');
|
|
45045
|
-
}
|
|
45046
|
-
let changed = false;
|
|
45047
|
-
let found = false;
|
|
45048
|
-
const next = [];
|
|
45049
|
-
for (const group of groups) {
|
|
45050
|
-
if (!isPlainObject2(group) || !Array.isArray(group.hooks)) {
|
|
45051
|
-
next.push(group);
|
|
45052
|
-
continue;
|
|
45053
|
-
}
|
|
45054
|
-
const kept = [];
|
|
45055
|
-
let groupChanged = false;
|
|
45056
|
-
for (const hook of group.hooks) {
|
|
45057
|
-
if (!isHeavyHookObject(hook)) {
|
|
45058
|
-
kept.push(hook);
|
|
45059
|
-
} else if (desired !== null && !found) {
|
|
45060
|
-
found = true;
|
|
45061
|
-
if (JSON.stringify(hook) !== JSON.stringify(desired)) groupChanged = true;
|
|
45062
|
-
kept.push(desired);
|
|
45063
|
-
} else {
|
|
45064
|
-
groupChanged = true;
|
|
45065
|
-
}
|
|
45066
|
-
}
|
|
45067
|
-
if (!groupChanged) {
|
|
45068
|
-
next.push(group);
|
|
45069
|
-
continue;
|
|
45070
|
-
}
|
|
45071
|
-
changed = true;
|
|
45072
|
-
if (kept.length > 0) next.push({ ...group, hooks: kept });
|
|
45073
|
-
}
|
|
45074
|
-
if (changed) hooks.PreToolUse = next;
|
|
45075
|
-
return { changed, found };
|
|
45076
|
-
}
|
|
45077
|
-
async function syncJsonHeavyCommandHook(configPath, provider, mode) {
|
|
45078
|
-
if (mode === "off") {
|
|
45079
|
-
if (!existsSync5(configPath)) return "unchanged";
|
|
45080
|
-
const removed = await updateJsonConfigFile2(configPath, (config2) => {
|
|
45081
|
-
if (config2.hooks === void 0) return false;
|
|
45082
|
-
return placeHeavyHook(hookMap(config2), null).changed;
|
|
45083
|
-
});
|
|
45084
|
-
return removed ? "removed" : "unchanged";
|
|
45085
|
-
}
|
|
45086
|
-
mkdirSync(dirname2(configPath), { recursive: true });
|
|
45087
|
-
clearOlderCleoMarkers();
|
|
45088
|
-
let result = "unchanged";
|
|
45089
|
-
await updateJsonConfigFile2(configPath, (config2) => {
|
|
45090
|
-
const hooks = hookMap(config2);
|
|
45091
|
-
const placed = placeHeavyHook(hooks, heavyCommandHookObject(provider));
|
|
45092
|
-
if (placed.found) {
|
|
45093
|
-
if (placed.changed) result = "updated";
|
|
45094
|
-
return placed.changed;
|
|
45095
|
-
}
|
|
45096
|
-
const existing = hooks.PreToolUse;
|
|
45097
|
-
hooks.PreToolUse = [
|
|
45098
|
-
...Array.isArray(existing) ? existing : [],
|
|
45099
|
-
heavyCommandHookEntry(provider)
|
|
45100
|
-
];
|
|
45101
|
-
result = "installed";
|
|
45102
|
-
return true;
|
|
45103
|
-
});
|
|
45104
|
-
return result;
|
|
45105
|
-
}
|
|
45106
|
-
function gitOutput(projectDir, args) {
|
|
45107
|
-
try {
|
|
45108
|
-
return execFileSync("git", ["-C", projectDir, ...args], {
|
|
45109
|
-
encoding: "utf-8",
|
|
45110
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
45111
|
-
timeout: 5e3
|
|
45112
|
-
}).trim();
|
|
45113
|
-
} catch {
|
|
45114
|
-
return null;
|
|
45115
|
-
}
|
|
45116
|
-
}
|
|
45117
|
-
function excludeFile(projectDir) {
|
|
45118
|
-
if (gitOutput(projectDir, ["rev-parse", "--is-inside-work-tree"]) !== "true") return null;
|
|
45119
|
-
const path = gitOutput(projectDir, ["rev-parse", "--git-path", "info/exclude"]);
|
|
45120
|
-
if (path === null || path === "") return null;
|
|
45121
|
-
return isAbsolute(path) ? path : join6(projectDir, path);
|
|
45122
|
-
}
|
|
45123
|
-
function excludeLine(projectDir) {
|
|
45124
|
-
const prefix = gitOutput(projectDir, ["rev-parse", "--show-prefix"]) ?? "";
|
|
45125
|
-
return `/${prefix}${CLAUDE_LOCAL_SETTINGS}`;
|
|
45126
|
-
}
|
|
45127
|
-
function excludeLocalSettingsFromGit(projectDir) {
|
|
45128
|
-
const exclude = excludeFile(projectDir);
|
|
45129
|
-
if (exclude === null) return false;
|
|
45130
|
-
if (gitOutput(projectDir, ["check-ignore", CLAUDE_LOCAL_SETTINGS]) !== null) return false;
|
|
45131
|
-
const line = excludeLine(projectDir);
|
|
45132
|
-
const text = existsSync5(exclude) ? readFileSync4(exclude, "utf-8") : "";
|
|
45133
|
-
if (text.split("\n").includes(line)) return false;
|
|
45134
|
-
const block = `${LOCAL_SETTINGS_EXCLUDE_MARKER}
|
|
45135
|
-
${line}
|
|
45136
|
-
`;
|
|
45137
|
-
mkdirSync(dirname2(exclude), { recursive: true });
|
|
45138
|
-
writeFileSync2(exclude, text === "" || text.endsWith("\n") ? text + block : `${text}
|
|
45139
|
-
${block}`);
|
|
45140
|
-
return true;
|
|
45141
|
-
}
|
|
45142
|
-
function unexcludeLocalSettingsFromGit(projectDir) {
|
|
45143
|
-
const exclude = excludeFile(projectDir);
|
|
45144
|
-
if (exclude === null || !existsSync5(exclude)) return false;
|
|
45145
|
-
const lines = readFileSync4(exclude, "utf-8").split("\n");
|
|
45146
|
-
const at = lines.indexOf(excludeLine(projectDir));
|
|
45147
|
-
if (at < 1 || lines[at - 1] !== LOCAL_SETTINGS_EXCLUDE_MARKER) return false;
|
|
45148
|
-
lines.splice(at - 1, 2);
|
|
45149
|
-
writeFileSync2(exclude, lines.join("\n"));
|
|
45150
|
-
return true;
|
|
45151
|
-
}
|
|
45152
|
-
async function syncClaudeCodeHeavyCommandHook(projectDir, mode) {
|
|
45153
|
-
const result = await syncJsonHeavyCommandHook(
|
|
45154
|
-
join6(projectDir, CLAUDE_LOCAL_SETTINGS),
|
|
45155
|
-
"claude-code",
|
|
45156
|
-
mode
|
|
45157
|
-
);
|
|
45158
|
-
if (mode === "off") unexcludeLocalSettingsFromGit(projectDir);
|
|
45159
|
-
else excludeLocalSettingsFromGit(projectDir);
|
|
45160
|
-
await syncJsonHeavyCommandHook(
|
|
45161
|
-
join6(projectDir, ".claude", "settings.json"),
|
|
45162
|
-
"claude-code",
|
|
45163
|
-
"off"
|
|
45164
|
-
);
|
|
45165
|
-
return result;
|
|
45166
|
-
}
|
|
45167
|
-
function opencodeHeavyCommandPluginSource() {
|
|
45168
|
-
return [
|
|
45169
|
-
"// CLEO heavy-command plugin for OpenCode (generated by @cleocode/adapters, T12983).",
|
|
45170
|
-
"// Routes heavy shell commands (tests, builds, typechecks, installs) through",
|
|
45171
|
-
"// `cleo run`, the machine-wide resource budget. Opt out with",
|
|
45172
|
-
'// CLEO_HEAVY_COMMAND_HOOK=off, or set resources.heavyCommandHook to "off" and',
|
|
45173
|
-
"// run `cleo upgrade` (which deletes this file). Fails open: on any error the",
|
|
45174
|
-
"// command runs unchanged.",
|
|
45175
|
-
"",
|
|
45176
|
-
"import { execFile } from 'node:child_process';",
|
|
45177
|
-
"",
|
|
45178
|
-
`const HEAVY = /(?:^|[^A-Za-z0-9_.@+-])(?:${HEAVY_TOOL_WORDS.join("|")})(?=$|[^A-Za-z0-9_.@+-])/;`,
|
|
45179
|
-
"const contexts = new Map();",
|
|
45180
|
-
"",
|
|
45181
|
-
"function ask(payload) {",
|
|
45182
|
-
" return new Promise((done) => {",
|
|
45183
|
-
" const child = execFile(",
|
|
45184
|
-
" 'cleo',",
|
|
45185
|
-
" ['hook', 'heavy-command', '--provider', 'opencode'],",
|
|
45186
|
-
` { timeout: ${HEAVY_COMMAND_HOOK_TIMEOUT_SEC * 1e3} },`,
|
|
45187
|
-
" (err, stdout) => done(err ? '' : stdout),",
|
|
45188
|
-
" );",
|
|
45189
|
-
" child.on('error', () => done(''));",
|
|
45190
|
-
" child.stdin?.end(JSON.stringify(payload));",
|
|
45191
|
-
" });",
|
|
45192
|
-
"}",
|
|
45193
|
-
"",
|
|
45194
|
-
"export const CleoHeavyCommand = async ({ directory }) => ({",
|
|
45195
|
-
" 'tool.execute.before': async (input, output) => {",
|
|
45196
|
-
" if (input?.tool !== 'bash' || typeof output?.args?.command !== 'string') return;",
|
|
45197
|
-
" if (process.env.CLEO_HEAVY_COMMAND_HOOK === 'off') return;",
|
|
45198
|
-
" if (!HEAVY.test(output.args.command)) return;",
|
|
45199
|
-
" try {",
|
|
45200
|
-
" const text = await ask({ tool_name: 'bash', tool_input: output.args, cwd: directory });",
|
|
45201
|
-
" const answer = JSON.parse(text || '{}');",
|
|
45202
|
-
" if (typeof answer.command === 'string') output.args.command = answer.command;",
|
|
45203
|
-
" if (typeof answer.timeout === 'number') output.args.timeout = answer.timeout;",
|
|
45204
|
-
" if (typeof answer.context === 'string' && input.callID) contexts.set(input.callID, answer.context);",
|
|
45205
|
-
" } catch {",
|
|
45206
|
-
" // Fail open.",
|
|
45207
|
-
" }",
|
|
45208
|
-
" },",
|
|
45209
|
-
" 'tool.execute.after': async (input, output) => {",
|
|
45210
|
-
" const context = input?.callID ? contexts.get(input.callID) : undefined;",
|
|
45211
|
-
" if (context === undefined) return;",
|
|
45212
|
-
" contexts.delete(input.callID);",
|
|
45213
|
-
" if (typeof output?.output === 'string') output.output += '\\n\\n' + context;",
|
|
45214
|
-
" },",
|
|
45215
|
-
"});",
|
|
45216
|
-
""
|
|
45217
|
-
].join("\n");
|
|
45218
|
-
}
|
|
45219
|
-
function syncOpencodeHeavyCommandPlugin(projectDir, mode) {
|
|
45220
|
-
const pluginPath = join6(projectDir, ".opencode", "plugins", OPENCODE_HEAVY_COMMAND_PLUGIN);
|
|
45221
|
-
const exists = existsSync5(pluginPath);
|
|
45222
|
-
if (mode === "off") {
|
|
45223
|
-
if (!exists) return "unchanged";
|
|
45224
|
-
rmSync(pluginPath, { force: true });
|
|
45225
|
-
return "removed";
|
|
45226
|
-
}
|
|
45227
|
-
const source = opencodeHeavyCommandPluginSource();
|
|
45228
|
-
if (exists && readFileSync4(pluginPath, "utf-8") === source) return "unchanged";
|
|
45229
|
-
mkdirSync(dirname2(pluginPath), { recursive: true });
|
|
45230
|
-
writeFileSync2(pluginPath, source, "utf-8");
|
|
45231
|
-
return exists ? "updated" : "installed";
|
|
45232
|
-
}
|
|
45233
|
-
var HEAVY_COMMAND_HOOK_ID, HEAVY_COMMAND_HOOK_TIMEOUT_SEC, OPENCODE_HEAVY_COMMAND_PLUGIN, HEAVY_TOOL_WORDS, OLDER_CLEO_HOOK_ANSWER, OLDER_CLEO_MARKER_PREFIX, CLAUDE_LOCAL_SETTINGS, LOCAL_SETTINGS_EXCLUDE_MARKER;
|
|
45234
|
-
var init_heavy_command_hook_install = __esm({
|
|
45235
|
-
"packages/adapters/src/providers/shared/heavy-command-hook-install.ts"() {
|
|
45236
|
-
"use strict";
|
|
45237
|
-
init_hook_config();
|
|
45238
|
-
HEAVY_COMMAND_HOOK_ID = "cleo hook heavy-command";
|
|
45239
|
-
HEAVY_COMMAND_HOOK_TIMEOUT_SEC = 20;
|
|
45240
|
-
OPENCODE_HEAVY_COMMAND_PLUGIN = "cleo-heavy-command.js";
|
|
45241
|
-
HEAVY_TOOL_WORDS = Object.freeze([
|
|
45242
|
-
"vitest",
|
|
45243
|
-
"jest",
|
|
45244
|
-
"mocha",
|
|
45245
|
-
"ava",
|
|
45246
|
-
"tap",
|
|
45247
|
-
"playwright",
|
|
45248
|
-
"pytest",
|
|
45249
|
-
"rspec",
|
|
45250
|
-
"phpunit",
|
|
45251
|
-
"tsc",
|
|
45252
|
-
"tsup",
|
|
45253
|
-
"turbo",
|
|
45254
|
-
"vite",
|
|
45255
|
-
"esbuild",
|
|
45256
|
-
"webpack",
|
|
45257
|
-
"rollup",
|
|
45258
|
-
"next",
|
|
45259
|
-
"nx",
|
|
45260
|
-
"biome",
|
|
45261
|
-
"eslint",
|
|
45262
|
-
"svelte-check",
|
|
45263
|
-
"npm",
|
|
45264
|
-
"pnpm",
|
|
45265
|
-
"yarn",
|
|
45266
|
-
"bun",
|
|
45267
|
-
"npx",
|
|
45268
|
-
"pnpx",
|
|
45269
|
-
"bunx",
|
|
45270
|
-
"cargo",
|
|
45271
|
-
"go"
|
|
45272
|
-
]);
|
|
45273
|
-
OLDER_CLEO_HOOK_ANSWER = JSON.stringify({
|
|
45274
|
-
hookSpecificOutput: {
|
|
45275
|
-
hookEventName: "PreToolUse",
|
|
45276
|
-
additionalContext: "[cleo] This may be a heavy command, but the cleo on PATH predates cleo hook and cleo run, so it runs outside the machine-wide resource budget. Upgrade CLEO to govern it."
|
|
45277
|
-
}
|
|
45278
|
-
});
|
|
45279
|
-
OLDER_CLEO_MARKER_PREFIX = "cleo-hook-unsupported-";
|
|
45280
|
-
CLAUDE_LOCAL_SETTINGS = ".claude/settings.local.json";
|
|
45281
|
-
LOCAL_SETTINGS_EXCLUDE_MARKER = "# cleo-hook: keep the per-machine heavy-command hook settings out of git (T12983)";
|
|
45282
|
-
}
|
|
45283
|
-
});
|
|
45284
|
-
|
|
45285
45634
|
// packages/adapters/src/providers/shared/hook-template-installer.ts
|
|
45286
|
-
import { copyFileSync, existsSync as existsSync6, mkdirSync as mkdirSync2, statSync } from "node:fs";
|
|
45287
|
-
import { dirname as
|
|
45635
|
+
import { copyFileSync, existsSync as existsSync6, mkdirSync as mkdirSync2, statSync as statSync2 } from "node:fs";
|
|
45636
|
+
import { dirname as dirname4, join as join7 } from "node:path";
|
|
45288
45637
|
import { fileURLToPath } from "node:url";
|
|
45289
45638
|
function resolveProviderCandidates() {
|
|
45290
|
-
const thisDir =
|
|
45291
|
-
const here =
|
|
45639
|
+
const thisDir = dirname4(fileURLToPath(import.meta.url));
|
|
45640
|
+
const here = dirname4(thisDir);
|
|
45292
45641
|
const fromDist = join7(here, "..", "..", "src", "providers");
|
|
45293
45642
|
return [here, fromDist];
|
|
45294
45643
|
}
|
|
@@ -45311,13 +45660,13 @@ function copyTemplate(src, dest, force) {
|
|
|
45311
45660
|
throw new Error(`CLEO hook template missing at source: ${src}`);
|
|
45312
45661
|
}
|
|
45313
45662
|
if (!force && existsSync6(dest)) {
|
|
45314
|
-
const srcStat =
|
|
45315
|
-
const destStat =
|
|
45663
|
+
const srcStat = statSync2(src);
|
|
45664
|
+
const destStat = statSync2(dest);
|
|
45316
45665
|
if (srcStat.size === destStat.size && srcStat.mtimeMs <= destStat.mtimeMs) {
|
|
45317
45666
|
return { wrote: false };
|
|
45318
45667
|
}
|
|
45319
45668
|
}
|
|
45320
|
-
mkdirSync2(
|
|
45669
|
+
mkdirSync2(dirname4(dest), { recursive: true });
|
|
45321
45670
|
copyFileSync(src, dest);
|
|
45322
45671
|
return { wrote: true };
|
|
45323
45672
|
}
|
|
@@ -45363,25 +45712,28 @@ var init_hook_template_installer = __esm({
|
|
|
45363
45712
|
|
|
45364
45713
|
// packages/adapters/src/providers/claude-code/install.ts
|
|
45365
45714
|
import { copyFileSync as copyFileSync2, existsSync as existsSync7, mkdirSync as mkdirSync3, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
|
|
45366
|
-
import {
|
|
45367
|
-
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";
|
|
45368
45716
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
45369
45717
|
import { ensureProviderInstructionFile, updateJsonConfigFile as updateJsonConfigFile3 } from "@cleocode/caamp";
|
|
45370
|
-
function getClaudeConfigDir() {
|
|
45371
|
-
return process.env["CLAUDE_HOME"] ?? join8(homedir5(), ".claude");
|
|
45372
|
-
}
|
|
45373
45718
|
function getAdapterCommandsDir() {
|
|
45374
|
-
const thisDir =
|
|
45719
|
+
const thisDir = dirname5(fileURLToPath2(import.meta.url));
|
|
45375
45720
|
return join8(thisDir, "commands");
|
|
45376
45721
|
}
|
|
45377
|
-
var ClaudeCodeInstallProvider;
|
|
45722
|
+
var CLEO_PLUGIN_KEY, PROJECT_HOOK_FILES, ClaudeCodeInstallProvider;
|
|
45378
45723
|
var init_install = __esm({
|
|
45379
45724
|
"packages/adapters/src/providers/claude-code/install.ts"() {
|
|
45380
45725
|
"use strict";
|
|
45381
45726
|
init_heavy_command_hook_install();
|
|
45382
45727
|
init_hook_template_installer();
|
|
45383
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
|
+
];
|
|
45384
45734
|
ClaudeCodeInstallProvider = class {
|
|
45735
|
+
/** The project the last {@link install} ran for; {@link isInstalled} reads its settings. */
|
|
45736
|
+
projectDir = null;
|
|
45385
45737
|
/**
|
|
45386
45738
|
* Install CLEO into a Claude Code project.
|
|
45387
45739
|
*
|
|
@@ -45390,38 +45742,52 @@ var init_install = __esm({
|
|
|
45390
45742
|
*/
|
|
45391
45743
|
async install(options) {
|
|
45392
45744
|
const { projectDir } = options;
|
|
45745
|
+
this.projectDir = projectDir;
|
|
45393
45746
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
45394
45747
|
let instructionFileUpdated = false;
|
|
45395
45748
|
const details = {};
|
|
45396
|
-
|
|
45397
|
-
|
|
45398
|
-
|
|
45399
|
-
|
|
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";
|
|
45400
45759
|
}
|
|
45401
|
-
|
|
45402
|
-
|
|
45403
|
-
|
|
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";
|
|
45404
45768
|
}
|
|
45405
45769
|
const settingsErrors = [];
|
|
45406
45770
|
try {
|
|
45407
|
-
const pluginResult = await this.registerPlugin();
|
|
45771
|
+
const pluginResult = await this.registerPlugin(projectDir);
|
|
45408
45772
|
if (pluginResult) {
|
|
45409
45773
|
details.plugin = pluginResult;
|
|
45410
45774
|
}
|
|
45411
45775
|
} catch (err) {
|
|
45412
|
-
|
|
45776
|
+
if (err instanceof UserGlobalClaudeConfigError) details.plugin = "skipped";
|
|
45777
|
+
else settingsErrors.push(err instanceof Error ? err.message : String(err));
|
|
45413
45778
|
}
|
|
45414
45779
|
try {
|
|
45415
|
-
const hookResult = await this.installHookTemplates();
|
|
45780
|
+
const hookResult = await this.installHookTemplates(projectDir);
|
|
45416
45781
|
if (hookResult) {
|
|
45417
45782
|
details.hookTemplates = hookResult;
|
|
45418
45783
|
}
|
|
45419
45784
|
} catch (err) {
|
|
45420
|
-
|
|
45785
|
+
if (err instanceof UserGlobalClaudeConfigError) details.hookTemplates = "skipped";
|
|
45786
|
+
else settingsErrors.push(err instanceof Error ? err.message : String(err));
|
|
45421
45787
|
}
|
|
45422
45788
|
if (options.heavyCommandHook !== void 0) {
|
|
45423
45789
|
const projectSettings = join8(projectDir, ".claude", "settings.json");
|
|
45424
|
-
if (isUserHomeDir(projectDir) ||
|
|
45790
|
+
if (isUserHomeDir(projectDir) || resolve4(projectSettings) === resolve4(claudeSettingsPath())) {
|
|
45425
45791
|
details.heavyCommandHook = "skipped";
|
|
45426
45792
|
} else {
|
|
45427
45793
|
try {
|
|
@@ -45454,16 +45820,25 @@ var init_install = __esm({
|
|
|
45454
45820
|
/**
|
|
45455
45821
|
* Check whether CLEO is installed in the current environment.
|
|
45456
45822
|
*
|
|
45457
|
-
* Checks for plugin enabled in
|
|
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).
|
|
45458
45826
|
*/
|
|
45459
45827
|
async isInstalled() {
|
|
45460
|
-
|
|
45828
|
+
let settingsPath;
|
|
45829
|
+
try {
|
|
45830
|
+
settingsPath = projectClaudeSettingsPath(this.projectDir ?? process.cwd());
|
|
45831
|
+
} catch {
|
|
45832
|
+
return false;
|
|
45833
|
+
}
|
|
45461
45834
|
if (existsSync7(settingsPath)) {
|
|
45462
45835
|
try {
|
|
45463
45836
|
const settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
45464
|
-
|
|
45465
|
-
|
|
45466
|
-
|
|
45837
|
+
if (isPlainObject2(settings)) {
|
|
45838
|
+
const plugins = settings.enabledPlugins;
|
|
45839
|
+
if (isPlainObject2(plugins) && plugins[CLEO_PLUGIN_KEY] === true) {
|
|
45840
|
+
return true;
|
|
45841
|
+
}
|
|
45467
45842
|
}
|
|
45468
45843
|
} catch {
|
|
45469
45844
|
}
|
|
@@ -45477,8 +45852,11 @@ var init_install = __esm({
|
|
|
45477
45852
|
* and default references from the provider registry (T1919).
|
|
45478
45853
|
*
|
|
45479
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.
|
|
45480
45857
|
*/
|
|
45481
45858
|
async ensureInstructionReferences(projectDir) {
|
|
45859
|
+
assertProjectInstructionScope(projectDir);
|
|
45482
45860
|
await ensureProviderInstructionFile("claude-code", projectDir, {});
|
|
45483
45861
|
}
|
|
45484
45862
|
/**
|
|
@@ -45489,13 +45867,14 @@ var init_install = __esm({
|
|
|
45489
45867
|
*
|
|
45490
45868
|
* @param projectDir - Project root directory
|
|
45491
45869
|
* @returns Array of installed command filenames
|
|
45870
|
+
* @throws {@link UserGlobalClaudeConfigError} when the target is user-global
|
|
45492
45871
|
*/
|
|
45493
45872
|
installCommands(projectDir) {
|
|
45494
45873
|
const adapterCommandsDir = getAdapterCommandsDir();
|
|
45495
45874
|
if (!existsSync7(adapterCommandsDir)) {
|
|
45496
45875
|
return [];
|
|
45497
45876
|
}
|
|
45498
|
-
const targetDir =
|
|
45877
|
+
const targetDir = projectClaudeCommandsDir(projectDir);
|
|
45499
45878
|
mkdirSync3(targetDir, { recursive: true });
|
|
45500
45879
|
const installed = [];
|
|
45501
45880
|
const files = readdirSync3(adapterCommandsDir).filter((f) => f.endsWith(".md"));
|
|
@@ -45508,13 +45887,17 @@ var init_install = __esm({
|
|
|
45508
45887
|
return installed;
|
|
45509
45888
|
}
|
|
45510
45889
|
/**
|
|
45511
|
-
* Register the CLEO brain plugin in
|
|
45890
|
+
* Register the CLEO brain plugin in the project's
|
|
45891
|
+
* `.claude/settings.local.json` (T13227: never the user-global settings).
|
|
45512
45892
|
*
|
|
45893
|
+
* @param projectDir - Project root directory
|
|
45513
45894
|
* @returns Description of what was registered, or null if no change needed
|
|
45895
|
+
* @throws {@link UserGlobalClaudeConfigError} when the target is user-global
|
|
45514
45896
|
*/
|
|
45515
|
-
async registerPlugin() {
|
|
45516
|
-
const pluginKey =
|
|
45517
|
-
const
|
|
45897
|
+
async registerPlugin(projectDir) {
|
|
45898
|
+
const pluginKey = CLEO_PLUGIN_KEY;
|
|
45899
|
+
const settingsPath = projectClaudeSettingsPath(projectDir);
|
|
45900
|
+
const wrote = await updateJsonConfigFile3(settingsPath, (settings) => {
|
|
45518
45901
|
const enabledPlugins = settings.enabledPlugins ?? {};
|
|
45519
45902
|
if (!isPlainObject2(enabledPlugins)) {
|
|
45520
45903
|
throw new Error('settings.json "enabledPlugins" is not an object; not modifying it');
|
|
@@ -45529,31 +45912,38 @@ var init_install = __esm({
|
|
|
45529
45912
|
settings.enabledPlugins = enabledPlugins;
|
|
45530
45913
|
return true;
|
|
45531
45914
|
});
|
|
45532
|
-
|
|
45915
|
+
if (!wrote) return null;
|
|
45916
|
+
excludeLocalSettingsFromGit(projectDir);
|
|
45917
|
+
return `Enabled ${pluginKey} in ${settingsPath}`;
|
|
45533
45918
|
}
|
|
45534
45919
|
/**
|
|
45535
45920
|
* Install the CLEO PreCompact hook templates for Claude Code (T1013).
|
|
45536
45921
|
*
|
|
45537
|
-
* Writes two files to
|
|
45922
|
+
* Writes two files to the project's `.claude/hooks/`:
|
|
45538
45923
|
* 1. `cleo-precompact-core.sh` — universal CLEO safestop helper (shared
|
|
45539
45924
|
* across all providers; sourced by the provider-specific shim).
|
|
45540
45925
|
* 2. `precompact-safestop.sh` — Claude-Code-flavoured wrapper that invokes
|
|
45541
45926
|
* `cleo memory precompact-flush` and `cleo safestop`.
|
|
45542
45927
|
*
|
|
45543
|
-
* Also registers a `PreCompact` entry in
|
|
45544
|
-
* Code runs the hook when
|
|
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).
|
|
45545
45933
|
*
|
|
45546
45934
|
* Idempotent: subsequent installs skip unchanged files and do not duplicate
|
|
45547
|
-
* the settings
|
|
45935
|
+
* the settings hook entry.
|
|
45548
45936
|
*
|
|
45937
|
+
* @param projectDir - Project root directory
|
|
45549
45938
|
* @returns Install summary (paths written + config change description), or
|
|
45550
45939
|
* `null` when no change was required.
|
|
45940
|
+
* @throws {@link UserGlobalClaudeConfigError} when the target is user-global
|
|
45551
45941
|
*
|
|
45552
|
-
* @task T1013
|
|
45942
|
+
* @task T1013 @task T13227
|
|
45553
45943
|
*/
|
|
45554
|
-
async installHookTemplates() {
|
|
45555
|
-
const
|
|
45556
|
-
const
|
|
45944
|
+
async installHookTemplates(projectDir) {
|
|
45945
|
+
const hooksDir = projectClaudeHooksDir(projectDir);
|
|
45946
|
+
const settingsPath = projectClaudeSettingsPath(projectDir);
|
|
45557
45947
|
let templates;
|
|
45558
45948
|
try {
|
|
45559
45949
|
templates = installProviderHookTemplates({
|
|
@@ -45563,30 +45953,35 @@ var init_install = __esm({
|
|
|
45563
45953
|
} catch {
|
|
45564
45954
|
return null;
|
|
45565
45955
|
}
|
|
45956
|
+
for (const file2 of PROJECT_HOOK_FILES) excludeHookFileFromGit(projectDir, file2);
|
|
45566
45957
|
const settingsEntryAdded = await this.registerPreCompactHook(
|
|
45958
|
+
settingsPath,
|
|
45567
45959
|
join8(hooksDir, "precompact-safestop.sh")
|
|
45568
45960
|
);
|
|
45961
|
+
if (settingsEntryAdded) excludeLocalSettingsFromGit(projectDir);
|
|
45569
45962
|
if (templates.installedFiles.length === 0 && !settingsEntryAdded) {
|
|
45570
45963
|
return null;
|
|
45571
45964
|
}
|
|
45572
45965
|
return { templates, settingsEntryAdded };
|
|
45573
45966
|
}
|
|
45574
45967
|
/**
|
|
45575
|
-
* Register the PreCompact hook command in
|
|
45968
|
+
* Register the PreCompact hook command in the project's
|
|
45969
|
+
* `.claude/settings.local.json`.
|
|
45576
45970
|
*
|
|
45577
45971
|
* The Claude Code native event name for the canonical `PreCompact` event is
|
|
45578
45972
|
* `PreCompact` (identity mapping — see `hook-mappings.json`). The entry is
|
|
45579
45973
|
* tagged with `# cleo-hook` so the uninstall flow can identify and remove
|
|
45580
45974
|
* our additions without touching user-authored hooks.
|
|
45581
45975
|
*
|
|
45976
|
+
* @param settingsPath - The project settings file (already scope-checked).
|
|
45582
45977
|
* @param shimPath - Absolute path to the installed `precompact-safestop.sh`.
|
|
45583
45978
|
* @returns `true` when a new hook entry was written, `false` when an
|
|
45584
45979
|
* equivalent entry was already present.
|
|
45585
45980
|
*
|
|
45586
45981
|
* @task T1013
|
|
45587
45982
|
*/
|
|
45588
|
-
async registerPreCompactHook(shimPath) {
|
|
45589
|
-
return updateJsonConfigFile3(
|
|
45983
|
+
async registerPreCompactHook(settingsPath, shimPath) {
|
|
45984
|
+
return updateJsonConfigFile3(settingsPath, (settings) => {
|
|
45590
45985
|
const hooks = hookMap(settings);
|
|
45591
45986
|
if (hasCleoHook(hooks.PreCompact, "precompact-safestop.sh")) {
|
|
45592
45987
|
return false;
|
|
@@ -45709,7 +46104,7 @@ var init_agent_spawn_wrapper = __esm({
|
|
|
45709
46104
|
// packages/adapters/src/providers/shared/prompt-file.ts
|
|
45710
46105
|
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
45711
46106
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
45712
|
-
import { dirname as
|
|
46107
|
+
import { dirname as dirname6, join as join9 } from "node:path";
|
|
45713
46108
|
async function writeSpawnPromptFile(prefix, prompt) {
|
|
45714
46109
|
const dir = await mkdtemp(join9(tmpdir2(), `cleo-${prefix}-`));
|
|
45715
46110
|
const file2 = join9(dir, "prompt.txt");
|
|
@@ -45717,7 +46112,7 @@ async function writeSpawnPromptFile(prefix, prompt) {
|
|
|
45717
46112
|
return file2;
|
|
45718
46113
|
}
|
|
45719
46114
|
async function removeSpawnPromptFile(file2) {
|
|
45720
|
-
await rm(
|
|
46115
|
+
await rm(dirname6(file2), { recursive: true, force: true }).catch(() => void 0);
|
|
45721
46116
|
}
|
|
45722
46117
|
var init_prompt_file = __esm({
|
|
45723
46118
|
"packages/adapters/src/providers/shared/prompt-file.ts"() {
|
|
@@ -45809,7 +46204,7 @@ function isEsrch(err) {
|
|
|
45809
46204
|
return false;
|
|
45810
46205
|
}
|
|
45811
46206
|
function sleep(ms) {
|
|
45812
|
-
return new Promise((
|
|
46207
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
45813
46208
|
}
|
|
45814
46209
|
var SIGTERM_GRACE_MS;
|
|
45815
46210
|
var init_suite_reaper = __esm({
|
|
@@ -46103,7 +46498,7 @@ var init_transport = __esm({
|
|
|
46103
46498
|
|
|
46104
46499
|
// packages/adapters/src/providers/claude-code/adapter.ts
|
|
46105
46500
|
import { existsSync as existsSync8 } from "node:fs";
|
|
46106
|
-
import { homedir as
|
|
46501
|
+
import { homedir as homedir5 } from "node:os";
|
|
46107
46502
|
import { join as join11 } from "node:path";
|
|
46108
46503
|
import { findOnPath as findOnPath2 } from "@cleocode/paths";
|
|
46109
46504
|
var ClaudeCodeAdapter;
|
|
@@ -46257,7 +46652,7 @@ var init_adapter = __esm({
|
|
|
46257
46652
|
cliAvailable = resolvedCli !== null;
|
|
46258
46653
|
if (resolvedCli) details.cliPath = resolvedCli;
|
|
46259
46654
|
else details.cliAvailable = false;
|
|
46260
|
-
const claudeConfigDir = join11(
|
|
46655
|
+
const claudeConfigDir = join11(homedir5(), ".claude");
|
|
46261
46656
|
const configExists = existsSync8(claudeConfigDir);
|
|
46262
46657
|
details.configDirExists = configExists;
|
|
46263
46658
|
const entrypointSet = process.env.CLAUDE_CODE_ENTRYPOINT !== void 0;
|
|
@@ -46288,10 +46683,10 @@ var init_adapter = __esm({
|
|
|
46288
46683
|
|
|
46289
46684
|
// packages/adapters/src/providers/claude-code/statusline.ts
|
|
46290
46685
|
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
46291
|
-
import { homedir as
|
|
46686
|
+
import { homedir as homedir6 } from "node:os";
|
|
46292
46687
|
import { join as join12 } from "node:path";
|
|
46293
46688
|
function getClaudeSettingsPath() {
|
|
46294
|
-
return process.env["CLAUDE_SETTINGS"] ?? join12(process.env["CLAUDE_HOME"] ?? join12(
|
|
46689
|
+
return process.env["CLAUDE_SETTINGS"] ?? join12(process.env["CLAUDE_HOME"] ?? join12(homedir6(), ".claude"), "settings.json");
|
|
46295
46690
|
}
|
|
46296
46691
|
function checkStatuslineIntegration() {
|
|
46297
46692
|
const settingsPath = getClaudeSettingsPath();
|
|
@@ -46305,7 +46700,7 @@ function checkStatuslineIntegration() {
|
|
|
46305
46700
|
if (cmd.includes("context-monitor.sh") || cmd.includes("cleo-statusline") || cmd.includes(".context-state.json") || cmd.includes("context-states")) {
|
|
46306
46701
|
return "configured";
|
|
46307
46702
|
}
|
|
46308
|
-
const scriptPath = cmd.startsWith("~") ? cmd.replace("~",
|
|
46703
|
+
const scriptPath = cmd.startsWith("~") ? cmd.replace("~", homedir6()) : cmd;
|
|
46309
46704
|
if (existsSync9(scriptPath)) {
|
|
46310
46705
|
try {
|
|
46311
46706
|
const content = readFileSync7(scriptPath, "utf-8");
|
|
@@ -46387,6 +46782,25 @@ var init_paths2 = __esm({
|
|
|
46387
46782
|
}
|
|
46388
46783
|
});
|
|
46389
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
|
+
|
|
46390
46804
|
// packages/adapters/src/providers/shared/cli-spawn.ts
|
|
46391
46805
|
import { spawn } from "node:child_process";
|
|
46392
46806
|
import { resolveSpawnInvocation as resolveSpawnInvocation2 } from "@cleocode/paths";
|
|
@@ -46561,7 +46975,7 @@ var init_hooks2 = __esm({
|
|
|
46561
46975
|
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
|
|
46562
46976
|
import { join as join18 } from "node:path";
|
|
46563
46977
|
import {
|
|
46564
|
-
ensureProviderInstructionFile as
|
|
46978
|
+
ensureProviderInstructionFile as ensureProviderInstructionFile4,
|
|
46565
46979
|
ensureProviderRuleFile,
|
|
46566
46980
|
updateJsonConfigFile as updateJsonConfigFile4
|
|
46567
46981
|
} from "@cleocode/caamp";
|
|
@@ -46572,8 +46986,10 @@ var CLEO_MDC_FRONTMATTER, CursorInstallProvider;
|
|
|
46572
46986
|
var init_install2 = __esm({
|
|
46573
46987
|
"packages/adapters/src/providers/cursor/install.ts"() {
|
|
46574
46988
|
"use strict";
|
|
46989
|
+
init_heavy_command_hook_install();
|
|
46575
46990
|
init_hook_template_installer();
|
|
46576
46991
|
init_paths2();
|
|
46992
|
+
init_project_instruction_file();
|
|
46577
46993
|
CLEO_MDC_FRONTMATTER = [
|
|
46578
46994
|
"---",
|
|
46579
46995
|
"description: CLEO task management protocol references",
|
|
@@ -46594,21 +47010,29 @@ var init_install2 = __esm({
|
|
|
46594
47010
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
46595
47011
|
let instructionFileUpdated = false;
|
|
46596
47012
|
const details = {};
|
|
46597
|
-
const instructionResult = await
|
|
46598
|
-
|
|
46599
|
-
|
|
46600
|
-
|
|
46601
|
-
|
|
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
|
+
}
|
|
46602
47022
|
}
|
|
46603
47023
|
let hooksError = null;
|
|
46604
|
-
|
|
46605
|
-
|
|
46606
|
-
|
|
46607
|
-
|
|
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;
|
|
46608
47035
|
}
|
|
46609
|
-
} catch (err) {
|
|
46610
|
-
hooksError = err instanceof Error ? err.message : String(err);
|
|
46611
|
-
details.hooksError = hooksError;
|
|
46612
47036
|
}
|
|
46613
47037
|
return {
|
|
46614
47038
|
success: hooksError === null,
|
|
@@ -46656,7 +47080,7 @@ var init_install2 = __esm({
|
|
|
46656
47080
|
* @param projectDir - Project root directory
|
|
46657
47081
|
*/
|
|
46658
47082
|
async ensureInstructionReferences(projectDir) {
|
|
46659
|
-
await
|
|
47083
|
+
await ensureProviderInstructionFile4("cursor", projectDir, {});
|
|
46660
47084
|
await this.updateInstructionFiles(projectDir);
|
|
46661
47085
|
}
|
|
46662
47086
|
/**
|
|
@@ -47088,7 +47512,7 @@ var init_hooks3 = __esm({
|
|
|
47088
47512
|
// packages/adapters/src/providers/opencode/install.ts
|
|
47089
47513
|
import { existsSync as existsSync18, mkdirSync as mkdirSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "node:fs";
|
|
47090
47514
|
import { join as join25 } from "node:path";
|
|
47091
|
-
import { ensureProviderInstructionFile as
|
|
47515
|
+
import { ensureProviderInstructionFile as ensureProviderInstructionFile7 } from "@cleocode/caamp";
|
|
47092
47516
|
var OpenCodeInstallProvider;
|
|
47093
47517
|
var init_install3 = __esm({
|
|
47094
47518
|
"packages/adapters/src/providers/opencode/install.ts"() {
|
|
@@ -47096,6 +47520,7 @@ var init_install3 = __esm({
|
|
|
47096
47520
|
init_heavy_command_hook_install();
|
|
47097
47521
|
init_hook_template_installer();
|
|
47098
47522
|
init_paths2();
|
|
47523
|
+
init_project_instruction_file();
|
|
47099
47524
|
OpenCodeInstallProvider = class {
|
|
47100
47525
|
/**
|
|
47101
47526
|
* Install CLEO into an OpenCode project.
|
|
@@ -47107,14 +47532,15 @@ var init_install3 = __esm({
|
|
|
47107
47532
|
const { projectDir } = options;
|
|
47108
47533
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47109
47534
|
const details = {};
|
|
47110
|
-
const instructResult = await
|
|
47535
|
+
const instructResult = await ensureProjectInstructionFile("opencode", projectDir, {
|
|
47111
47536
|
scope: "project",
|
|
47112
47537
|
references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"]
|
|
47113
47538
|
});
|
|
47114
|
-
const instructionFileUpdated = instructResult.action !== "intact";
|
|
47539
|
+
const instructionFileUpdated = instructResult !== null && instructResult.action !== "intact";
|
|
47115
47540
|
if (instructionFileUpdated) {
|
|
47116
47541
|
details.instructionFile = join25(projectDir, instructResult.instructFile);
|
|
47117
47542
|
}
|
|
47543
|
+
if (instructResult === null) details.instructionFile = "skipped";
|
|
47118
47544
|
const hookResult = this.installHookTemplates(projectDir);
|
|
47119
47545
|
if (hookResult) {
|
|
47120
47546
|
details.hookTemplates = hookResult;
|
|
@@ -47154,7 +47580,7 @@ var init_install3 = __esm({
|
|
|
47154
47580
|
*/
|
|
47155
47581
|
async isInstalled() {
|
|
47156
47582
|
try {
|
|
47157
|
-
const result = await
|
|
47583
|
+
const result = await ensureProviderInstructionFile7("opencode", process.cwd(), {
|
|
47158
47584
|
scope: "project",
|
|
47159
47585
|
references: [
|
|
47160
47586
|
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
@@ -47174,7 +47600,7 @@ var init_install3 = __esm({
|
|
|
47174
47600
|
* @param projectDir - Project root directory
|
|
47175
47601
|
*/
|
|
47176
47602
|
async ensureInstructionReferences(projectDir) {
|
|
47177
|
-
await
|
|
47603
|
+
await ensureProviderInstructionFile7("opencode", projectDir, {
|
|
47178
47604
|
scope: "project",
|
|
47179
47605
|
references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"]
|
|
47180
47606
|
});
|
|
@@ -47781,8 +48207,8 @@ var init_hooks4 = __esm({
|
|
|
47781
48207
|
});
|
|
47782
48208
|
|
|
47783
48209
|
// packages/adapters/src/providers/pi/install.ts
|
|
47784
|
-
import { join as
|
|
47785
|
-
import { ensureProviderInstructionFile as
|
|
48210
|
+
import { join as join29 } from "node:path";
|
|
48211
|
+
import { ensureProviderInstructionFile as ensureProviderInstructionFile8 } from "@cleocode/caamp";
|
|
47786
48212
|
function getCleoReferences() {
|
|
47787
48213
|
return [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"];
|
|
47788
48214
|
}
|
|
@@ -47791,6 +48217,7 @@ var init_install4 = __esm({
|
|
|
47791
48217
|
"packages/adapters/src/providers/pi/install.ts"() {
|
|
47792
48218
|
"use strict";
|
|
47793
48219
|
init_paths2();
|
|
48220
|
+
init_project_instruction_file();
|
|
47794
48221
|
PiInstallProvider = class {
|
|
47795
48222
|
/**
|
|
47796
48223
|
* Install CLEO into a Pi coding agent project.
|
|
@@ -47802,17 +48229,18 @@ var init_install4 = __esm({
|
|
|
47802
48229
|
const { projectDir } = options;
|
|
47803
48230
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47804
48231
|
const details = {};
|
|
47805
|
-
const projectResult = await
|
|
48232
|
+
const projectResult = await ensureProjectInstructionFile("pi", projectDir, {
|
|
47806
48233
|
scope: "project",
|
|
47807
48234
|
references: getCleoReferences()
|
|
47808
48235
|
});
|
|
47809
|
-
const projectUpdated = projectResult.action !== "intact";
|
|
48236
|
+
const projectUpdated = projectResult !== null && projectResult.action !== "intact";
|
|
47810
48237
|
if (projectUpdated) {
|
|
47811
|
-
details.instructionFile =
|
|
48238
|
+
details.instructionFile = join29(projectDir, projectResult.instructFile);
|
|
47812
48239
|
}
|
|
48240
|
+
if (projectResult === null) details.instructionFile = "skipped";
|
|
47813
48241
|
let globalUpdated = false;
|
|
47814
48242
|
try {
|
|
47815
|
-
const globalResult = await
|
|
48243
|
+
const globalResult = await ensureProviderInstructionFile8("pi", projectDir, {
|
|
47816
48244
|
scope: "global",
|
|
47817
48245
|
references: getCleoReferences()
|
|
47818
48246
|
});
|
|
@@ -47844,7 +48272,7 @@ var init_install4 = __esm({
|
|
|
47844
48272
|
*/
|
|
47845
48273
|
async isInstalled() {
|
|
47846
48274
|
try {
|
|
47847
|
-
const result = await
|
|
48275
|
+
const result = await ensureProviderInstructionFile8("pi", process.cwd(), {
|
|
47848
48276
|
scope: "project",
|
|
47849
48277
|
references: getCleoReferences()
|
|
47850
48278
|
});
|
|
@@ -47852,7 +48280,7 @@ var init_install4 = __esm({
|
|
|
47852
48280
|
} catch {
|
|
47853
48281
|
}
|
|
47854
48282
|
try {
|
|
47855
|
-
const result = await
|
|
48283
|
+
const result = await ensureProviderInstructionFile8("pi", process.cwd(), {
|
|
47856
48284
|
scope: "global",
|
|
47857
48285
|
references: getCleoReferences()
|
|
47858
48286
|
});
|
|
@@ -47869,7 +48297,7 @@ var init_install4 = __esm({
|
|
|
47869
48297
|
* @param projectDir - Project root directory
|
|
47870
48298
|
*/
|
|
47871
48299
|
async ensureInstructionReferences(projectDir) {
|
|
47872
|
-
await
|
|
48300
|
+
await ensureProviderInstructionFile8("pi", projectDir, {
|
|
47873
48301
|
scope: "project",
|
|
47874
48302
|
references: getCleoReferences()
|
|
47875
48303
|
});
|
|
@@ -47879,7 +48307,7 @@ var init_install4 = __esm({
|
|
|
47879
48307
|
});
|
|
47880
48308
|
|
|
47881
48309
|
// packages/adapters/src/providers/pi/spawn.ts
|
|
47882
|
-
import { findOnPath as
|
|
48310
|
+
import { findOnPath as findOnPath12 } from "@cleocode/paths";
|
|
47883
48311
|
function getPiCliPath() {
|
|
47884
48312
|
return process.env["PI_CLI_PATH"] ?? "pi";
|
|
47885
48313
|
}
|
|
@@ -47902,7 +48330,7 @@ var init_spawn4 = __esm({
|
|
|
47902
48330
|
*/
|
|
47903
48331
|
async canSpawn() {
|
|
47904
48332
|
const cliPath = getPiCliPath();
|
|
47905
|
-
return
|
|
48333
|
+
return findOnPath12(cliPath) !== null;
|
|
47906
48334
|
}
|
|
47907
48335
|
/**
|
|
47908
48336
|
* Spawn a subagent via Pi CLI.
|
|
@@ -48013,22 +48441,22 @@ var init_spawn4 = __esm({
|
|
|
48013
48441
|
});
|
|
48014
48442
|
|
|
48015
48443
|
// packages/adapters/src/providers/pi/adapter.ts
|
|
48016
|
-
import { existsSync as
|
|
48444
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
48017
48445
|
import { homedir as homedir13 } from "node:os";
|
|
48018
|
-
import { join as
|
|
48019
|
-
import { findOnPath as
|
|
48446
|
+
import { join as join30 } from "node:path";
|
|
48447
|
+
import { findOnPath as findOnPath13 } from "@cleocode/paths";
|
|
48020
48448
|
function getPiAgentDir() {
|
|
48021
48449
|
const env = process.env["PI_CODING_AGENT_DIR"];
|
|
48022
48450
|
if (env !== void 0 && env.length > 0) {
|
|
48023
48451
|
if (env === "~") return homedir13();
|
|
48024
|
-
if (env.startsWith("~/")) return
|
|
48452
|
+
if (env.startsWith("~/")) return join30(homedir13(), env.slice(2));
|
|
48025
48453
|
return env;
|
|
48026
48454
|
}
|
|
48027
48455
|
const piHome = process.env["PI_HOME"];
|
|
48028
48456
|
if (piHome !== void 0 && piHome.length > 0) {
|
|
48029
|
-
return
|
|
48457
|
+
return join30(piHome, "agent");
|
|
48030
48458
|
}
|
|
48031
|
-
return
|
|
48459
|
+
return join30(homedir13(), ".pi", "agent");
|
|
48032
48460
|
}
|
|
48033
48461
|
var PiAdapter;
|
|
48034
48462
|
var init_adapter4 = __esm({
|
|
@@ -48131,17 +48559,17 @@ var init_adapter4 = __esm({
|
|
|
48131
48559
|
}
|
|
48132
48560
|
let cliAvailable = false;
|
|
48133
48561
|
const cliPath = process.env["PI_CLI_PATH"] ?? "pi";
|
|
48134
|
-
const resolvedCli =
|
|
48562
|
+
const resolvedCli = findOnPath13(cliPath);
|
|
48135
48563
|
cliAvailable = resolvedCli !== null;
|
|
48136
48564
|
if (resolvedCli) details.cliPath = cliPath === "pi" ? resolvedCli : cliPath;
|
|
48137
48565
|
else details.cliAvailable = false;
|
|
48138
48566
|
const agentDir = getPiAgentDir();
|
|
48139
|
-
const agentDirExists =
|
|
48567
|
+
const agentDirExists = existsSync21(agentDir);
|
|
48140
48568
|
details.agentDirExists = agentDirExists;
|
|
48141
48569
|
details.agentDir = agentDir;
|
|
48142
48570
|
if (this.projectDir) {
|
|
48143
|
-
const projectPiDir =
|
|
48144
|
-
details.projectPiDirExists =
|
|
48571
|
+
const projectPiDir = join30(this.projectDir, ".pi");
|
|
48572
|
+
details.projectPiDirExists = existsSync21(projectPiDir);
|
|
48145
48573
|
}
|
|
48146
48574
|
details.piCodingAgentDirSet = process.env["PI_CODING_AGENT_DIR"] !== void 0;
|
|
48147
48575
|
details.piHomeSet = process.env["PI_HOME"] !== void 0;
|
|
@@ -48353,12 +48781,12 @@ function createAdapter2() {
|
|
|
48353
48781
|
|
|
48354
48782
|
// packages/adapters/src/providers/codex/adapter.ts
|
|
48355
48783
|
import { existsSync as existsSync11 } from "node:fs";
|
|
48356
|
-
import { homedir as
|
|
48784
|
+
import { homedir as homedir8 } from "node:os";
|
|
48357
48785
|
import { join as join17 } from "node:path";
|
|
48358
48786
|
import { findOnPath as findOnPath3 } from "@cleocode/paths";
|
|
48359
48787
|
|
|
48360
48788
|
// packages/adapters/src/providers/codex/hooks.ts
|
|
48361
|
-
import { homedir as
|
|
48789
|
+
import { homedir as homedir7 } from "node:os";
|
|
48362
48790
|
import { join as join15 } from "node:path";
|
|
48363
48791
|
|
|
48364
48792
|
// packages/adapters/src/providers/shared/transcript-reader.ts
|
|
@@ -48478,15 +48906,16 @@ var CodexHookProvider = class {
|
|
|
48478
48906
|
* @task T162 @epic T134
|
|
48479
48907
|
*/
|
|
48480
48908
|
async getTranscript(_sessionId, _projectDir) {
|
|
48481
|
-
return readLatestTranscript(join15(
|
|
48909
|
+
return readLatestTranscript(join15(homedir7(), ".codex"));
|
|
48482
48910
|
}
|
|
48483
48911
|
};
|
|
48484
48912
|
|
|
48485
48913
|
// packages/adapters/src/providers/codex/install.ts
|
|
48486
48914
|
init_heavy_command_hook_install();
|
|
48487
48915
|
init_paths2();
|
|
48916
|
+
init_project_instruction_file();
|
|
48488
48917
|
import { join as join16 } from "node:path";
|
|
48489
|
-
import { ensureProviderInstructionFile as
|
|
48918
|
+
import { ensureProviderInstructionFile as ensureProviderInstructionFile3 } from "@cleocode/caamp";
|
|
48490
48919
|
var CodexInstallProvider = class {
|
|
48491
48920
|
/**
|
|
48492
48921
|
* Install CLEO into a Codex CLI environment.
|
|
@@ -48499,22 +48928,22 @@ var CodexInstallProvider = class {
|
|
|
48499
48928
|
const { projectDir } = options;
|
|
48500
48929
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48501
48930
|
const details = {};
|
|
48502
|
-
const result = await
|
|
48931
|
+
const result = await ensureProjectInstructionFile("codex", projectDir, {
|
|
48503
48932
|
scope: "project",
|
|
48504
48933
|
references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"]
|
|
48505
48934
|
});
|
|
48506
|
-
const instructionFileUpdated = result.action !== "intact";
|
|
48935
|
+
const instructionFileUpdated = result !== null && result.action !== "intact";
|
|
48507
48936
|
if (instructionFileUpdated) {
|
|
48508
48937
|
details.instructionFile = join16(projectDir, result.instructFile);
|
|
48509
48938
|
}
|
|
48939
|
+
if (result === null) details.instructionFile = "skipped";
|
|
48510
48940
|
let success2 = true;
|
|
48511
48941
|
if (options.heavyCommandHook !== void 0 && isUserHomeDir(projectDir)) {
|
|
48512
48942
|
details.heavyCommandHook = "skipped";
|
|
48513
48943
|
} else if (options.heavyCommandHook !== void 0) {
|
|
48514
48944
|
try {
|
|
48515
|
-
details.heavyCommandHook = await
|
|
48516
|
-
|
|
48517
|
-
"codex",
|
|
48945
|
+
details.heavyCommandHook = await syncCodexHeavyCommandHook(
|
|
48946
|
+
projectDir,
|
|
48518
48947
|
options.heavyCommandHook
|
|
48519
48948
|
);
|
|
48520
48949
|
} catch (err) {
|
|
@@ -48545,7 +48974,7 @@ var CodexInstallProvider = class {
|
|
|
48545
48974
|
*/
|
|
48546
48975
|
async isInstalled() {
|
|
48547
48976
|
try {
|
|
48548
|
-
const result = await
|
|
48977
|
+
const result = await ensureProviderInstructionFile3("codex", process.cwd(), {
|
|
48549
48978
|
scope: "project",
|
|
48550
48979
|
references: [
|
|
48551
48980
|
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
@@ -48566,7 +48995,7 @@ var CodexInstallProvider = class {
|
|
|
48566
48995
|
* @task T162
|
|
48567
48996
|
*/
|
|
48568
48997
|
async ensureInstructionReferences(projectDir) {
|
|
48569
|
-
await
|
|
48998
|
+
await ensureProviderInstructionFile3("codex", projectDir, {
|
|
48570
48999
|
scope: "project",
|
|
48571
49000
|
references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"]
|
|
48572
49001
|
});
|
|
@@ -48654,7 +49083,7 @@ var CodexAdapter = class {
|
|
|
48654
49083
|
cliAvailable = resolvedCli !== null;
|
|
48655
49084
|
if (resolvedCli) details.cliPath = resolvedCli;
|
|
48656
49085
|
else details.cliAvailable = false;
|
|
48657
|
-
const codexConfigDir = join17(
|
|
49086
|
+
const codexConfigDir = join17(homedir8(), ".codex");
|
|
48658
49087
|
const configExists = existsSync11(codexConfigDir);
|
|
48659
49088
|
details.configDirExists = configExists;
|
|
48660
49089
|
const healthy = cliAvailable;
|
|
@@ -48697,12 +49126,12 @@ init_cursor();
|
|
|
48697
49126
|
|
|
48698
49127
|
// packages/adapters/src/providers/gemini-cli/adapter.ts
|
|
48699
49128
|
import { existsSync as existsSync15 } from "node:fs";
|
|
48700
|
-
import { homedir as
|
|
49129
|
+
import { homedir as homedir10 } from "node:os";
|
|
48701
49130
|
import { join as join22 } from "node:path";
|
|
48702
49131
|
import { findOnPath as findOnPath5 } from "@cleocode/paths";
|
|
48703
49132
|
|
|
48704
49133
|
// packages/adapters/src/providers/gemini-cli/hooks.ts
|
|
48705
|
-
import { homedir as
|
|
49134
|
+
import { homedir as homedir9 } from "node:os";
|
|
48706
49135
|
import { join as join20 } from "node:path";
|
|
48707
49136
|
var GEMINI_CLI_EVENT_MAP = {
|
|
48708
49137
|
SessionStart: "SessionStart",
|
|
@@ -48781,15 +49210,16 @@ var GeminiCliHookProvider = class {
|
|
|
48781
49210
|
* @task T161 @epic T134
|
|
48782
49211
|
*/
|
|
48783
49212
|
async getTranscript(_sessionId, _projectDir) {
|
|
48784
|
-
return readLatestTranscript(join20(
|
|
49213
|
+
return readLatestTranscript(join20(homedir9(), ".gemini"));
|
|
48785
49214
|
}
|
|
48786
49215
|
};
|
|
48787
49216
|
|
|
48788
49217
|
// packages/adapters/src/providers/gemini-cli/install.ts
|
|
48789
49218
|
init_paths2();
|
|
49219
|
+
init_project_instruction_file();
|
|
48790
49220
|
import { existsSync as existsSync14, readFileSync as readFileSync9 } from "node:fs";
|
|
48791
49221
|
import { join as join21 } from "node:path";
|
|
48792
|
-
import { ensureProviderInstructionFile as
|
|
49222
|
+
import { ensureProviderInstructionFile as ensureProviderInstructionFile5 } from "@cleocode/caamp";
|
|
48793
49223
|
var GeminiCliInstallProvider = class {
|
|
48794
49224
|
/**
|
|
48795
49225
|
* Install CLEO into a Gemini CLI environment.
|
|
@@ -48802,14 +49232,15 @@ var GeminiCliInstallProvider = class {
|
|
|
48802
49232
|
const { projectDir } = options;
|
|
48803
49233
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48804
49234
|
const details = {};
|
|
48805
|
-
const result = await
|
|
49235
|
+
const result = await ensureProjectInstructionFile("gemini-cli", projectDir, {
|
|
48806
49236
|
references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"],
|
|
48807
49237
|
scope: "project"
|
|
48808
49238
|
});
|
|
48809
|
-
const instructionFileUpdated = result.action !== "intact";
|
|
49239
|
+
const instructionFileUpdated = result !== null && result.action !== "intact";
|
|
48810
49240
|
if (instructionFileUpdated) {
|
|
48811
49241
|
details.instructionFile = result.filePath;
|
|
48812
49242
|
}
|
|
49243
|
+
if (result === null) details.instructionFile = "skipped";
|
|
48813
49244
|
return {
|
|
48814
49245
|
success: true,
|
|
48815
49246
|
installedAt,
|
|
@@ -48854,7 +49285,7 @@ var GeminiCliInstallProvider = class {
|
|
|
48854
49285
|
* @task T161
|
|
48855
49286
|
*/
|
|
48856
49287
|
async ensureInstructionReferences(projectDir) {
|
|
48857
|
-
await
|
|
49288
|
+
await ensureProviderInstructionFile5("gemini-cli", projectDir, {
|
|
48858
49289
|
references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"],
|
|
48859
49290
|
scope: "project"
|
|
48860
49291
|
});
|
|
@@ -48953,7 +49384,7 @@ var GeminiCliAdapter = class {
|
|
|
48953
49384
|
cliAvailable = resolvedCli !== null;
|
|
48954
49385
|
if (resolvedCli) details.cliPath = resolvedCli;
|
|
48955
49386
|
else details.cliAvailable = false;
|
|
48956
|
-
const geminiConfigDir = join22(
|
|
49387
|
+
const geminiConfigDir = join22(homedir10(), ".gemini");
|
|
48957
49388
|
const configExists = existsSync15(geminiConfigDir);
|
|
48958
49389
|
details.configDirExists = configExists;
|
|
48959
49390
|
const healthy = cliAvailable;
|
|
@@ -48992,7 +49423,7 @@ function createAdapter5() {
|
|
|
48992
49423
|
|
|
48993
49424
|
// packages/adapters/src/providers/kimi/adapter.ts
|
|
48994
49425
|
import { existsSync as existsSync17 } from "node:fs";
|
|
48995
|
-
import { homedir as
|
|
49426
|
+
import { homedir as homedir11 } from "node:os";
|
|
48996
49427
|
import { join as join24 } from "node:path";
|
|
48997
49428
|
import { findOnPath as findOnPath7 } from "@cleocode/paths";
|
|
48998
49429
|
|
|
@@ -49053,9 +49484,10 @@ var KimiHookProvider = class {
|
|
|
49053
49484
|
|
|
49054
49485
|
// packages/adapters/src/providers/kimi/install.ts
|
|
49055
49486
|
init_paths2();
|
|
49487
|
+
init_project_instruction_file();
|
|
49056
49488
|
import { existsSync as existsSync16, readFileSync as readFileSync10 } from "node:fs";
|
|
49057
49489
|
import { join as join23 } from "node:path";
|
|
49058
|
-
import { ensureProviderInstructionFile as
|
|
49490
|
+
import { ensureProviderInstructionFile as ensureProviderInstructionFile6 } from "@cleocode/caamp";
|
|
49059
49491
|
var KimiInstallProvider = class {
|
|
49060
49492
|
/**
|
|
49061
49493
|
* Install CLEO into a Kimi environment.
|
|
@@ -49068,14 +49500,15 @@ var KimiInstallProvider = class {
|
|
|
49068
49500
|
const { projectDir } = options;
|
|
49069
49501
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
49070
49502
|
const details = {};
|
|
49071
|
-
const result = await
|
|
49503
|
+
const result = await ensureProjectInstructionFile("kimi", projectDir, {
|
|
49072
49504
|
references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"],
|
|
49073
49505
|
scope: "project"
|
|
49074
49506
|
});
|
|
49075
|
-
const instructionFileUpdated = result.action !== "intact";
|
|
49507
|
+
const instructionFileUpdated = result !== null && result.action !== "intact";
|
|
49076
49508
|
if (instructionFileUpdated) {
|
|
49077
49509
|
details.instructionFile = result.filePath;
|
|
49078
49510
|
}
|
|
49511
|
+
if (result === null) details.instructionFile = "skipped";
|
|
49079
49512
|
return {
|
|
49080
49513
|
success: true,
|
|
49081
49514
|
installedAt,
|
|
@@ -49120,7 +49553,7 @@ var KimiInstallProvider = class {
|
|
|
49120
49553
|
* @task T163
|
|
49121
49554
|
*/
|
|
49122
49555
|
async ensureInstructionReferences(projectDir) {
|
|
49123
|
-
await
|
|
49556
|
+
await ensureProviderInstructionFile6("kimi", projectDir, {
|
|
49124
49557
|
references: [`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`, "@.cleo/memory-bridge.md"],
|
|
49125
49558
|
scope: "project"
|
|
49126
49559
|
});
|
|
@@ -49206,7 +49639,7 @@ var KimiAdapter = class {
|
|
|
49206
49639
|
cliAvailable = resolvedCli !== null;
|
|
49207
49640
|
if (resolvedCli) details.cliPath = resolvedCli;
|
|
49208
49641
|
else details.cliAvailable = false;
|
|
49209
|
-
const kimiConfigDir = join24(
|
|
49642
|
+
const kimiConfigDir = join24(homedir11(), ".kimi");
|
|
49210
49643
|
const configExists = existsSync17(kimiConfigDir);
|
|
49211
49644
|
details.configDirExists = configExists;
|
|
49212
49645
|
const healthy = cliAvailable;
|
|
@@ -49244,20 +49677,405 @@ function createAdapter6() {
|
|
|
49244
49677
|
|
|
49245
49678
|
// packages/adapters/src/index.ts
|
|
49246
49679
|
init_opencode();
|
|
49680
|
+
|
|
49681
|
+
// packages/adapters/src/providers/shared/heavy-command-hook-delivery.ts
|
|
49682
|
+
init_heavy_command_hook_install();
|
|
49683
|
+
init_hook_config();
|
|
49684
|
+
import { execFileSync as execFileSync2, spawnSync as spawnSync3 } from "node:child_process";
|
|
49685
|
+
import { existsSync as existsSync20, lstatSync, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
|
|
49686
|
+
import { homedir as homedir12 } from "node:os";
|
|
49687
|
+
import { dirname as dirname7, join as join28 } from "node:path";
|
|
49688
|
+
import { JsonConfigParseError } from "@cleocode/caamp";
|
|
49689
|
+
import { findOnPath as findOnPath11 } from "@cleocode/paths";
|
|
49690
|
+
var HEAVY_HOOK_DELIVERY_PROVIDERS = Object.freeze([
|
|
49691
|
+
"claude-code",
|
|
49692
|
+
"codex",
|
|
49693
|
+
"opencode",
|
|
49694
|
+
"kimi"
|
|
49695
|
+
]);
|
|
49696
|
+
var HEAVY_HOOK_FIX_COMMAND = "cleo doctor heavy-command-hook --fix";
|
|
49697
|
+
var CODEX_SHARED_REMEDY = "if the team wants Codex governed here, add CLEO's PreToolUse entry (the snippet) to .codex/hooks.json yourself and commit it deliberately; CLEO never writes or hides a project's own hook config";
|
|
49698
|
+
var KIMI_REASON = "Kimi reads hooks only from its global ~/.kimi/config.toml, and CLEO never writes user-global configs";
|
|
49699
|
+
var KIMI_REMEDY = "add a [[hooks]] entry for PreToolUse that runs `cleo hook heavy-command --provider kimi` to ~/.kimi/config.toml yourself";
|
|
49700
|
+
function homeOf(env) {
|
|
49701
|
+
return env.HOME || homedir12();
|
|
49702
|
+
}
|
|
49703
|
+
function heavyHookTarget(provider, projectDir, env = process.env) {
|
|
49704
|
+
switch (provider) {
|
|
49705
|
+
case "claude-code":
|
|
49706
|
+
return join28(projectDir, CLAUDE_LOCAL_SETTINGS);
|
|
49707
|
+
case "codex":
|
|
49708
|
+
return join28(projectDir, CODEX_HOOKS_FILE);
|
|
49709
|
+
case "opencode":
|
|
49710
|
+
return join28(projectDir, OPENCODE_PLUGIN_FILE);
|
|
49711
|
+
case "kimi":
|
|
49712
|
+
return join28(homeOf(env), ".kimi", "config.toml");
|
|
49713
|
+
}
|
|
49714
|
+
}
|
|
49715
|
+
function detectHeavyHookProvider(provider, projectDir, env = process.env) {
|
|
49716
|
+
const home = homeOf(env);
|
|
49717
|
+
const signals = provider === "claude-code" ? [
|
|
49718
|
+
[
|
|
49719
|
+
env.CLAUDECODE === "1" || Boolean(env.CLAUDE_CODE_ENTRYPOINT),
|
|
49720
|
+
"running inside Claude Code"
|
|
49721
|
+
],
|
|
49722
|
+
[() => existsSync20(join28(projectDir, ".claude")), "the project has .claude/"],
|
|
49723
|
+
[() => findOnPath11("claude", { env }) !== null, "`claude` is on PATH"],
|
|
49724
|
+
[() => existsSync20(env.CLAUDE_CONFIG_DIR || join28(home, ".claude")), "~/.claude exists"]
|
|
49725
|
+
] : provider === "codex" ? [
|
|
49726
|
+
[() => existsSync20(join28(projectDir, ".codex")), "the project has .codex"],
|
|
49727
|
+
[() => findOnPath11("codex", { env }) !== null, "`codex` is on PATH"],
|
|
49728
|
+
[() => existsSync20(env.CODEX_HOME || join28(home, ".codex")), "~/.codex exists"]
|
|
49729
|
+
] : provider === "opencode" ? [
|
|
49730
|
+
[() => existsSync20(join28(projectDir, ".opencode")), "the project has .opencode/"],
|
|
49731
|
+
[
|
|
49732
|
+
() => existsSync20(join28(projectDir, "opencode.json")) || existsSync20(join28(projectDir, "opencode.jsonc")),
|
|
49733
|
+
"the project has opencode.json"
|
|
49734
|
+
],
|
|
49735
|
+
[() => findOnPath11("opencode", { env }) !== null, "`opencode` is on PATH"],
|
|
49736
|
+
[
|
|
49737
|
+
() => existsSync20(join28(env.XDG_CONFIG_HOME || join28(home, ".config"), "opencode")),
|
|
49738
|
+
"~/.config/opencode exists"
|
|
49739
|
+
]
|
|
49740
|
+
] : [
|
|
49741
|
+
[() => findOnPath11("kimi", { env }) !== null, "`kimi` is on PATH"],
|
|
49742
|
+
[() => existsSync20(join28(home, ".kimi")), "~/.kimi exists"]
|
|
49743
|
+
];
|
|
49744
|
+
for (const [test, why] of signals) {
|
|
49745
|
+
if (typeof test === "boolean" ? test : test()) return { detected: true, why };
|
|
49746
|
+
}
|
|
49747
|
+
if (provider !== "kimi" && existsSync20(heavyHookTarget(provider, projectDir, env))) {
|
|
49748
|
+
return { detected: true, why: "its hook config exists" };
|
|
49749
|
+
}
|
|
49750
|
+
return {
|
|
49751
|
+
detected: false,
|
|
49752
|
+
why: `${provider} is not in use here (no config directory or CLI found)`
|
|
49753
|
+
};
|
|
49754
|
+
}
|
|
49755
|
+
function errorText(err) {
|
|
49756
|
+
return err instanceof Error ? err.message : String(err);
|
|
49757
|
+
}
|
|
49758
|
+
async function syncProvider(provider, projectDir, mode, env) {
|
|
49759
|
+
const target = heavyHookTarget(provider, projectDir, env);
|
|
49760
|
+
if (provider === "kimi") {
|
|
49761
|
+
return mode === "off" ? { provider, status: "unchanged", target } : { provider, status: "unsupported", target, reason: KIMI_REASON, remedy: KIMI_REMEDY };
|
|
49762
|
+
}
|
|
49763
|
+
try {
|
|
49764
|
+
const result = provider === "claude-code" ? await syncClaudeCodeHeavyCommandHook(projectDir, mode) : provider === "codex" ? await syncCodexHeavyCommandHook(projectDir, mode) : syncOpencodeHeavyCommandPlugin(projectDir, mode);
|
|
49765
|
+
return { provider, status: result, target };
|
|
49766
|
+
} catch (err) {
|
|
49767
|
+
if (err instanceof HeavyHookSharedConfigError) {
|
|
49768
|
+
return {
|
|
49769
|
+
provider,
|
|
49770
|
+
status: "needs-consent",
|
|
49771
|
+
target,
|
|
49772
|
+
reason: err.message,
|
|
49773
|
+
...mode === "off" ? {
|
|
49774
|
+
remedy: "the team committed CLEO's hook in .codex/hooks.json; remove it there in a team change if the team agrees"
|
|
49775
|
+
} : { remedy: CODEX_SHARED_REMEDY, snippet: codexHookSnippet() }
|
|
49776
|
+
};
|
|
49777
|
+
}
|
|
49778
|
+
if (err instanceof HeavyHookPathBlockedError) {
|
|
49779
|
+
return {
|
|
49780
|
+
provider,
|
|
49781
|
+
status: "blocked",
|
|
49782
|
+
target,
|
|
49783
|
+
reason: err.message,
|
|
49784
|
+
remedy: `remove or rename ${err.path} (it is not a directory), then run: ${HEAVY_HOOK_FIX_COMMAND}`
|
|
49785
|
+
};
|
|
49786
|
+
}
|
|
49787
|
+
return {
|
|
49788
|
+
provider,
|
|
49789
|
+
status: "failed",
|
|
49790
|
+
target,
|
|
49791
|
+
reason: errorText(err),
|
|
49792
|
+
remedy: err instanceof JsonConfigParseError ? `fix the JSON in ${err.filePath} (it was left untouched), then run: ${HEAVY_HOOK_FIX_COMMAND}` : `run: ${HEAVY_HOOK_FIX_COMMAND}`
|
|
49793
|
+
};
|
|
49794
|
+
}
|
|
49795
|
+
}
|
|
49796
|
+
async function syncProjectHeavyCommandHooks(projectDir, mode, options = {}) {
|
|
49797
|
+
const env = options.env ?? process.env;
|
|
49798
|
+
const providers = options.providers ?? HEAVY_HOOK_DELIVERY_PROVIDERS;
|
|
49799
|
+
const home = isUserHomeDir(projectDir, homeOf(env));
|
|
49800
|
+
const outcomes = [];
|
|
49801
|
+
for (const provider of providers) {
|
|
49802
|
+
const target = heavyHookTarget(provider, projectDir, env);
|
|
49803
|
+
if (home) {
|
|
49804
|
+
outcomes.push({
|
|
49805
|
+
provider,
|
|
49806
|
+
status: "skipped",
|
|
49807
|
+
target,
|
|
49808
|
+
reason: "the project is your home directory, whose provider configs are user-global"
|
|
49809
|
+
});
|
|
49810
|
+
continue;
|
|
49811
|
+
}
|
|
49812
|
+
const detection = detectHeavyHookProvider(provider, projectDir, env);
|
|
49813
|
+
if (mode !== "off" && !detection.detected) {
|
|
49814
|
+
outcomes.push({ provider, status: "skipped", target, reason: detection.why });
|
|
49815
|
+
continue;
|
|
49816
|
+
}
|
|
49817
|
+
outcomes.push(await syncProvider(provider, projectDir, mode, env));
|
|
49818
|
+
}
|
|
49819
|
+
return outcomes;
|
|
49820
|
+
}
|
|
49821
|
+
function jsonHookPresence(file2, provider) {
|
|
49822
|
+
let raw;
|
|
49823
|
+
try {
|
|
49824
|
+
raw = readFileSync12(file2, "utf-8");
|
|
49825
|
+
} catch (err) {
|
|
49826
|
+
const code = err.code;
|
|
49827
|
+
return code === "ENOENT" || code === "ENOTDIR" ? { kind: "absent" } : { kind: "unreadable", error: errorText(err) };
|
|
49828
|
+
}
|
|
49829
|
+
if (raw.trim() === "") return { kind: "absent" };
|
|
49830
|
+
let config2;
|
|
49831
|
+
try {
|
|
49832
|
+
config2 = JSON.parse(raw);
|
|
49833
|
+
} catch (err) {
|
|
49834
|
+
return { kind: "unreadable", error: errorText(err) };
|
|
49835
|
+
}
|
|
49836
|
+
if (!isPlainObject2(config2))
|
|
49837
|
+
return { kind: "unreadable", error: "top-level value is not an object" };
|
|
49838
|
+
const hooks = config2.hooks;
|
|
49839
|
+
const groups = isPlainObject2(hooks) ? hooks.PreToolUse : void 0;
|
|
49840
|
+
if (!Array.isArray(groups)) return { kind: "absent" };
|
|
49841
|
+
const expected = JSON.stringify(heavyCommandHookObject(provider));
|
|
49842
|
+
let found = { kind: "absent" };
|
|
49843
|
+
for (const group of groups) {
|
|
49844
|
+
if (!isPlainObject2(group) || !Array.isArray(group.hooks)) continue;
|
|
49845
|
+
for (const hook of group.hooks) {
|
|
49846
|
+
if (!isHeavyHookObject(hook)) continue;
|
|
49847
|
+
if (JSON.stringify(hook) === expected) return { kind: "present", current: true };
|
|
49848
|
+
found = { kind: "present", current: false };
|
|
49849
|
+
}
|
|
49850
|
+
}
|
|
49851
|
+
return found;
|
|
49852
|
+
}
|
|
49853
|
+
function presenceOf(provider, projectDir, target) {
|
|
49854
|
+
if (provider !== "opencode") {
|
|
49855
|
+
const local = jsonHookPresence(target, provider);
|
|
49856
|
+
if (provider !== "claude-code" || local.kind !== "absent") return local;
|
|
49857
|
+
const legacy = jsonHookPresence(join28(projectDir, ".claude", "settings.json"), provider);
|
|
49858
|
+
return legacy.kind === "present" ? { kind: "present", current: false } : { kind: "absent" };
|
|
49859
|
+
}
|
|
49860
|
+
if (!existsSync20(target)) return { kind: "absent" };
|
|
49861
|
+
try {
|
|
49862
|
+
return {
|
|
49863
|
+
kind: "present",
|
|
49864
|
+
current: readFileSync12(target, "utf-8") === opencodeHeavyCommandPluginSource()
|
|
49865
|
+
};
|
|
49866
|
+
} catch (err) {
|
|
49867
|
+
return { kind: "unreadable", error: errorText(err) };
|
|
49868
|
+
}
|
|
49869
|
+
}
|
|
49870
|
+
var HOOK_FILES = {
|
|
49871
|
+
"claude-code": CLAUDE_LOCAL_SETTINGS,
|
|
49872
|
+
codex: CODEX_HOOKS_FILE,
|
|
49873
|
+
opencode: OPENCODE_PLUGIN_FILE
|
|
49874
|
+
};
|
|
49875
|
+
function inspectProvider(provider, projectDir, mode, env, gitChecks) {
|
|
49876
|
+
const target = heavyHookTarget(provider, projectDir, env);
|
|
49877
|
+
const { detected, why } = detectHeavyHookProvider(provider, projectDir, env);
|
|
49878
|
+
const base = { provider, detected, target };
|
|
49879
|
+
if (provider === "kimi") {
|
|
49880
|
+
if (!detected || mode === "off") return { ...base, state: "not-detected", detail: why };
|
|
49881
|
+
let manual = false;
|
|
49882
|
+
try {
|
|
49883
|
+
manual = readFileSync12(target, "utf-8").includes(HEAVY_COMMAND_HOOK_ID);
|
|
49884
|
+
} catch {
|
|
49885
|
+
}
|
|
49886
|
+
return manual ? { ...base, state: "installed", detail: `a manual entry in ${target} runs the hook` } : { ...base, state: "unsupported", detail: `${why}; ${KIMI_REASON}`, remedy: KIMI_REMEDY };
|
|
49887
|
+
}
|
|
49888
|
+
const presence = presenceOf(provider, projectDir, target);
|
|
49889
|
+
if (presence.kind === "unreadable") {
|
|
49890
|
+
return {
|
|
49891
|
+
...base,
|
|
49892
|
+
state: "unreadable",
|
|
49893
|
+
detail: `${target} cannot be read or parsed (${presence.error})`,
|
|
49894
|
+
remedy: `fix ${target}, then run: ${HEAVY_HOOK_FIX_COMMAND}`
|
|
49895
|
+
};
|
|
49896
|
+
}
|
|
49897
|
+
if (mode === "off") {
|
|
49898
|
+
return presence.kind === "present" ? {
|
|
49899
|
+
...base,
|
|
49900
|
+
state: "outdated",
|
|
49901
|
+
detail: "resources.heavyCommandHook is off, but the hook is still installed",
|
|
49902
|
+
remedy: `run: ${HEAVY_HOOK_FIX_COMMAND} (removes it)`
|
|
49903
|
+
} : { ...base, state: "disabled", detail: "resources.heavyCommandHook is off" };
|
|
49904
|
+
}
|
|
49905
|
+
if (presence.kind === "present") {
|
|
49906
|
+
if (!presence.current) {
|
|
49907
|
+
return {
|
|
49908
|
+
...base,
|
|
49909
|
+
state: "outdated",
|
|
49910
|
+
detail: `the hook in ${target} (or a legacy location) was written by another CLEO build`,
|
|
49911
|
+
remedy: `run: ${HEAVY_HOOK_FIX_COMMAND}`
|
|
49912
|
+
};
|
|
49913
|
+
}
|
|
49914
|
+
if (!gitChecks) return { ...base, state: "installed", detail: `installed in ${target}` };
|
|
49915
|
+
const shared2 = provider === "codex" ? codexHooksSharedReason(projectDir, true) : null;
|
|
49916
|
+
if (shared2 !== null && excludedByCleo(projectDir, CODEX_HOOKS_FILE)) {
|
|
49917
|
+
return {
|
|
49918
|
+
...base,
|
|
49919
|
+
state: "outdated",
|
|
49920
|
+
detail: `CLEO's info/exclude line hides ${target}, which ${shared2}`,
|
|
49921
|
+
remedy: `run: ${HEAVY_HOOK_FIX_COMMAND} (removes CLEO's exclude line)`
|
|
49922
|
+
};
|
|
49923
|
+
}
|
|
49924
|
+
if (shared2 !== null) {
|
|
49925
|
+
const modified = trackedFileModified(projectDir, CODEX_HOOKS_FILE);
|
|
49926
|
+
if (modified || hookFileVisibleToGit(projectDir, CODEX_HOOKS_FILE)) {
|
|
49927
|
+
return {
|
|
49928
|
+
...base,
|
|
49929
|
+
state: "outdated",
|
|
49930
|
+
detail: `CLEO's per-machine hook sits in ${target}, which ${shared2}, as ${modified ? "an uncommitted change" : "an untracked file"}: one \`git commit -a\` ships it to the team, and it widens evidence scope`,
|
|
49931
|
+
remedy: "remove CLEO's entry from .codex/hooks.json, or commit it deliberately if the team wants Codex governed"
|
|
49932
|
+
};
|
|
49933
|
+
}
|
|
49934
|
+
return { ...base, state: "installed", detail: `installed in ${target}, which ${shared2}` };
|
|
49935
|
+
}
|
|
49936
|
+
if (hookFileVisibleToGit(projectDir, HOOK_FILES[provider])) {
|
|
49937
|
+
return {
|
|
49938
|
+
...base,
|
|
49939
|
+
state: "outdated",
|
|
49940
|
+
detail: `${target} is installed but git sees it as an untracked file (it widens evidence scope)`,
|
|
49941
|
+
remedy: `run: ${HEAVY_HOOK_FIX_COMMAND} (adds it to the repository's info/exclude)`
|
|
49942
|
+
};
|
|
49943
|
+
}
|
|
49944
|
+
return { ...base, state: "installed", detail: `installed in ${target}` };
|
|
49945
|
+
}
|
|
49946
|
+
if (!detected) return { ...base, state: "not-detected", detail: why };
|
|
49947
|
+
const shared = provider === "codex" ? codexHooksSharedReason(projectDir, gitChecks) : null;
|
|
49948
|
+
if (shared !== null && gitChecks && excludedByCleo(projectDir, CODEX_HOOKS_FILE)) {
|
|
49949
|
+
return {
|
|
49950
|
+
...base,
|
|
49951
|
+
state: "outdated",
|
|
49952
|
+
detail: `CLEO's info/exclude line hides ${target}, which ${shared}`,
|
|
49953
|
+
remedy: `run: ${HEAVY_HOOK_FIX_COMMAND} (removes CLEO's exclude line)`
|
|
49954
|
+
};
|
|
49955
|
+
}
|
|
49956
|
+
if (shared !== null) {
|
|
49957
|
+
return {
|
|
49958
|
+
...base,
|
|
49959
|
+
state: "needs-consent",
|
|
49960
|
+
detail: `${target} ${shared}, so CLEO does not write or hide it; Codex runs ungoverned here until the team adds the entry (${why})`,
|
|
49961
|
+
remedy: CODEX_SHARED_REMEDY,
|
|
49962
|
+
snippet: codexHookSnippet()
|
|
49963
|
+
};
|
|
49964
|
+
}
|
|
49965
|
+
const blocked = nonDirectoryAncestor(dirname7(target));
|
|
49966
|
+
if (blocked !== null) {
|
|
49967
|
+
return {
|
|
49968
|
+
...base,
|
|
49969
|
+
state: "blocked",
|
|
49970
|
+
detail: `${blocked} exists but is not a directory, so the hook cannot be installed (${why})`,
|
|
49971
|
+
remedy: `remove or rename ${blocked}, then run: ${HEAVY_HOOK_FIX_COMMAND}`
|
|
49972
|
+
};
|
|
49973
|
+
}
|
|
49974
|
+
return {
|
|
49975
|
+
...base,
|
|
49976
|
+
state: "missing",
|
|
49977
|
+
detail: `${why}, but ${target} has no heavy-command hook: agent-run tests and builds bypass the machine-wide budget`,
|
|
49978
|
+
remedy: `run: ${HEAVY_HOOK_FIX_COMMAND}`
|
|
49979
|
+
};
|
|
49980
|
+
}
|
|
49981
|
+
function inspectProjectHeavyCommandHooks(projectDir, mode, options = {}) {
|
|
49982
|
+
const env = options.env ?? process.env;
|
|
49983
|
+
const providers = options.providers ?? HEAVY_HOOK_DELIVERY_PROVIDERS;
|
|
49984
|
+
if (isUserHomeDir(projectDir, homeOf(env))) {
|
|
49985
|
+
return providers.map((provider) => ({
|
|
49986
|
+
provider,
|
|
49987
|
+
detected: false,
|
|
49988
|
+
state: "not-detected",
|
|
49989
|
+
target: heavyHookTarget(provider, projectDir, env),
|
|
49990
|
+
detail: "the project is your home directory; CLEO installs this hook per project only"
|
|
49991
|
+
}));
|
|
49992
|
+
}
|
|
49993
|
+
const gitChecks = options.gitChecks ?? true;
|
|
49994
|
+
return providers.map((provider) => inspectProvider(provider, projectDir, mode, env, gitChecks));
|
|
49995
|
+
}
|
|
49996
|
+
var OLDER_CLEO_MARKER_TTL_MS = 60 * 60 * 1e3;
|
|
49997
|
+
function olderCleoMarkerPath(cleoPath, dir, env) {
|
|
49998
|
+
try {
|
|
49999
|
+
const key = execFileSync2(
|
|
50000
|
+
"/bin/sh",
|
|
50001
|
+
["-c", `printf '%s|%s' "$1" "$2" | cksum | tr -c '0-9' '-'`, "sh", cleoPath, dir],
|
|
50002
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }
|
|
50003
|
+
);
|
|
50004
|
+
const base = env.XDG_RUNTIME_DIR || env.TMPDIR || "/tmp";
|
|
50005
|
+
return join28(base, `${OLDER_CLEO_MARKER_PREFIX}${key}`);
|
|
50006
|
+
} catch {
|
|
50007
|
+
return null;
|
|
50008
|
+
}
|
|
50009
|
+
}
|
|
50010
|
+
function hasOlderCleoMarker(cleoPath, dir, env) {
|
|
50011
|
+
const marker16 = olderCleoMarkerPath(cleoPath, dir, env);
|
|
50012
|
+
if (marker16 === null) return false;
|
|
50013
|
+
try {
|
|
50014
|
+
const st = lstatSync(marker16);
|
|
50015
|
+
if (!st.isFile()) return false;
|
|
50016
|
+
if (Date.now() - st.mtimeMs > OLDER_CLEO_MARKER_TTL_MS) return false;
|
|
50017
|
+
return statSync3(cleoPath).mtimeMs <= st.mtimeMs;
|
|
50018
|
+
} catch {
|
|
50019
|
+
return false;
|
|
50020
|
+
}
|
|
50021
|
+
}
|
|
50022
|
+
function probeHeavyHookCli(projectDir, options = {}) {
|
|
50023
|
+
const env = options.env ?? process.env;
|
|
50024
|
+
const path = findOnPath11("cleo", { env });
|
|
50025
|
+
if (path === null) {
|
|
50026
|
+
return {
|
|
50027
|
+
state: "missing",
|
|
50028
|
+
path: null,
|
|
50029
|
+
detail: "no `cleo` on PATH, so the hook lets every heavy command run ungoverned",
|
|
50030
|
+
remedy: "install CLEO so `cleo` is on PATH: npm i -g @cleocode/cleo"
|
|
50031
|
+
};
|
|
50032
|
+
}
|
|
50033
|
+
const older = {
|
|
50034
|
+
state: "older",
|
|
50035
|
+
path,
|
|
50036
|
+
detail: `${path} predates \`cleo hook\` and \`cleo run\`, so the hook lets every heavy command run ungoverned`,
|
|
50037
|
+
remedy: `upgrade the cleo at ${path} (npm i -g @cleocode/cleo, or your version manager), then run: ${HEAVY_HOOK_FIX_COMMAND}`
|
|
50038
|
+
};
|
|
50039
|
+
if (hasOlderCleoMarker(path, projectDir, env)) return older;
|
|
50040
|
+
const probe = spawnSync3(path, ["hook", "heavy-command", "--provider", "claude-code"], {
|
|
50041
|
+
cwd: projectDir,
|
|
50042
|
+
env: { ...env },
|
|
50043
|
+
input: "{}",
|
|
50044
|
+
encoding: "utf-8",
|
|
50045
|
+
timeout: 2e4
|
|
50046
|
+
});
|
|
50047
|
+
if (probe.status === 0) {
|
|
50048
|
+
return { state: "current", path, detail: `${path} answers \`cleo hook heavy-command\`` };
|
|
50049
|
+
}
|
|
50050
|
+
if (probe.status === 127 && /Unknown command/.test(probe.stderr ?? "")) return older;
|
|
50051
|
+
return {
|
|
50052
|
+
state: "unknown",
|
|
50053
|
+
path,
|
|
50054
|
+
detail: `${path} did not answer \`cleo hook heavy-command\` (${probe.error?.message ?? `exit ${probe.status ?? "none"}`}); the hook fails open, so heavy commands run ungoverned while it does not`,
|
|
50055
|
+
remedy: `run \`${path} hook heavy-command < /dev/null\` in ${projectDir} to see why it fails (a broken version-manager shim, say)`
|
|
50056
|
+
};
|
|
50057
|
+
}
|
|
50058
|
+
var heavyHookDeliveryApi = Object.freeze({
|
|
50059
|
+
syncProjectHeavyCommandHooks,
|
|
50060
|
+
inspectProjectHeavyCommandHooks,
|
|
50061
|
+
probeHeavyHookCli
|
|
50062
|
+
});
|
|
50063
|
+
|
|
50064
|
+
// packages/adapters/src/index.ts
|
|
49247
50065
|
init_hook_template_installer();
|
|
49248
50066
|
|
|
49249
50067
|
// packages/adapters/src/registry.ts
|
|
49250
|
-
import { readFileSync as
|
|
49251
|
-
import { dirname as
|
|
50068
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
50069
|
+
import { dirname as dirname8, join as join31, resolve as resolve5 } from "node:path";
|
|
49252
50070
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
49253
50071
|
var PROVIDER_IDS = ["claude-code", "opencode", "cursor", "pi"];
|
|
49254
50072
|
function getProviderManifests() {
|
|
49255
50073
|
const manifests = [];
|
|
49256
|
-
const baseDir =
|
|
50074
|
+
const baseDir = resolve5(dirname8(fileURLToPath3(import.meta.url)), "providers");
|
|
49257
50075
|
for (const providerId of PROVIDER_IDS) {
|
|
49258
50076
|
try {
|
|
49259
|
-
const manifestPath =
|
|
49260
|
-
const raw =
|
|
50077
|
+
const manifestPath = join31(baseDir, providerId, "manifest.json");
|
|
50078
|
+
const raw = readFileSync13(manifestPath, "utf-8");
|
|
49261
50079
|
manifests.push(JSON.parse(raw));
|
|
49262
50080
|
} catch {
|
|
49263
50081
|
}
|
|
@@ -49305,6 +50123,8 @@ export {
|
|
|
49305
50123
|
GeminiCliAdapter,
|
|
49306
50124
|
GeminiCliHookProvider,
|
|
49307
50125
|
GeminiCliInstallProvider,
|
|
50126
|
+
HEAVY_HOOK_DELIVERY_PROVIDERS,
|
|
50127
|
+
HEAVY_HOOK_FIX_COMMAND,
|
|
49308
50128
|
KimiAdapter,
|
|
49309
50129
|
KimiHookProvider,
|
|
49310
50130
|
KimiInstallProvider,
|
|
@@ -49325,6 +50145,7 @@ export {
|
|
|
49325
50145
|
createAdapter5 as createGeminiCliAdapter,
|
|
49326
50146
|
createAdapter6 as createKimiAdapter,
|
|
49327
50147
|
createAdapter7 as createOpenCodeAdapter,
|
|
50148
|
+
detectHeavyHookProvider,
|
|
49328
50149
|
discoverProviders,
|
|
49329
50150
|
extractSymbolsFromText,
|
|
49330
50151
|
getProviderHookTemplatePath,
|
|
@@ -49333,8 +50154,13 @@ export {
|
|
|
49333
50154
|
getSetupInstructions,
|
|
49334
50155
|
getSharedHookCorePath,
|
|
49335
50156
|
getStatuslineConfig,
|
|
50157
|
+
heavyHookDeliveryApi,
|
|
50158
|
+
heavyHookTarget,
|
|
50159
|
+
inspectProjectHeavyCommandHooks,
|
|
49336
50160
|
installProviderHookTemplates,
|
|
50161
|
+
probeHeavyHookCli,
|
|
49337
50162
|
resolveTools,
|
|
49338
|
-
runNexusPostModificationCheck
|
|
50163
|
+
runNexusPostModificationCheck,
|
|
50164
|
+
syncProjectHeavyCommandHooks
|
|
49339
50165
|
};
|
|
49340
50166
|
//# sourceMappingURL=index.js.map
|