@primitive.ai/prim 0.1.0-alpha.90 → 0.1.0-alpha.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -12
- package/SKILL.md +6 -6
- package/dist/chunk-26P57LAR.js +1491 -0
- package/dist/{chunk-LMRYZL3D.js → chunk-5AFRMOPX.js} +1 -1
- package/dist/{chunk-RO3F6JYV.js → chunk-5GYQ4J3D.js} +2 -2
- package/dist/chunk-5HRR4AOR.js +264 -0
- package/dist/{chunk-3EEFL6NJ.js → chunk-67VNLLBN.js} +261 -1
- package/dist/{chunk-UZPBB7V4.js → chunk-ADUTW66W.js} +60 -48
- package/dist/{chunk-LEMX3IOG.js → chunk-BTNNEH2W.js} +1 -1
- package/dist/{chunk-YWO7O6QG.js → chunk-FBAYCS3X.js} +2 -2
- package/dist/{chunk-R26A7TWY.js → chunk-FKXFUUWJ.js} +1 -1
- package/dist/chunk-H4UNYFUC.js +196 -0
- package/dist/{chunk-CUE2LKLR.js → chunk-KFXF2V5G.js} +1 -1
- package/dist/{chunk-6IWNH776.js → chunk-LFFLHSQO.js} +4 -3
- package/dist/{chunk-C7T7B45R.js → chunk-LGGMJYY4.js} +150 -21
- package/dist/{chunk-MAZWKJGL.js → chunk-M6RIJVRE.js} +42 -232
- package/dist/{chunk-2JRX7ZR4.js → chunk-NAHHFSLH.js} +16 -5
- package/dist/{chunk-FI3LIRCB.js → chunk-OAAP2MY6.js} +2 -2
- package/dist/{chunk-Z7YPFWAZ.js → chunk-PCVGBE5B.js} +10 -268
- package/dist/chunk-WX52U7Z2.js +112 -0
- package/dist/{chunk-PPQYQEIR.js → chunk-ZB4F75SZ.js} +28 -0
- package/dist/daemon/server.js +30 -21
- package/dist/hook-runtime/daemon/server.js +30 -21
- package/dist/hook-runtime/hooks/post-commit.js +20 -20
- package/dist/hook-runtime/hooks/post-rewrite.js +20 -20
- package/dist/hook-runtime/hooks/post-tool-use.js +666 -147
- package/dist/hook-runtime/hooks/pre-tool-use.js +659 -111
- package/dist/hook-runtime/hooks/prim-hook.js +627 -111
- package/dist/hook-runtime/hooks/session-end.js +610 -27
- package/dist/hook-runtime/hooks/session-start.js +1132 -533
- package/dist/hook-runtime/index.js +764 -267
- package/dist/hook-runtime/statusline-main.js +48 -4
- package/dist/hooks/post-commit.js +11 -9
- package/dist/hooks/post-rewrite.js +11 -9
- package/dist/hooks/post-tool-use.js +73 -48
- package/dist/hooks/pre-commit.js +4 -4
- package/dist/hooks/pre-tool-use.js +46 -44
- package/dist/hooks/prim-hook.js +47 -25
- package/dist/hooks/session-end.js +15 -26
- package/dist/hooks/session-start.js +59 -32
- package/dist/index.js +561 -1430
- package/dist/statusline-main.js +48 -4
- package/package.json +1 -1
- package/dist/chunk-PMRDE2DA.js +0 -310
- package/dist/chunk-WB7AUZ4C.js +0 -52
|
@@ -52,8 +52,8 @@ var require_ucs2length = __commonJS({
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
// src/hooks/post-tool-use.ts
|
|
55
|
-
import { readFileSync as
|
|
56
|
-
import { dirname as
|
|
55
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
56
|
+
import { dirname as dirname11, join as join16 } from "path";
|
|
57
57
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
58
58
|
|
|
59
59
|
// src/binding.ts
|
|
@@ -636,7 +636,7 @@ var PRIM_REPO_SYNC_REPOSITORY_KEY = "prim.repoSyncRepository";
|
|
|
636
636
|
var PRIM_REPO_BINDING_STATE_KEY = "prim.repoBindingState";
|
|
637
637
|
var GIT_TIMEOUT_MS2 = 1e3;
|
|
638
638
|
var REPO_SYNC_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
639
|
-
var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json"];
|
|
639
|
+
var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json", ".cursor/hooks.json"];
|
|
640
640
|
var PRIM_HOOK_BINS = ["prim-hook", "prim-pre-tool-use", "prim-post-tool-use"];
|
|
641
641
|
function repoActiveFlag(cwd) {
|
|
642
642
|
try {
|
|
@@ -893,14 +893,14 @@ function throwIfAborted(signal) {
|
|
|
893
893
|
}
|
|
894
894
|
async function defaultSleep(ms, signal) {
|
|
895
895
|
if (!signal) {
|
|
896
|
-
await new Promise((
|
|
896
|
+
await new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
897
897
|
return;
|
|
898
898
|
}
|
|
899
899
|
throwIfAborted(signal);
|
|
900
|
-
await new Promise((
|
|
900
|
+
await new Promise((resolve6, reject) => {
|
|
901
901
|
const timer = setTimeout(() => {
|
|
902
902
|
signal.removeEventListener("abort", onAbort);
|
|
903
|
-
|
|
903
|
+
resolve6();
|
|
904
904
|
}, ms);
|
|
905
905
|
const onAbort = () => {
|
|
906
906
|
clearTimeout(timer);
|
|
@@ -2257,7 +2257,7 @@ function validate23(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
2257
2257
|
}
|
|
2258
2258
|
validate23.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
2259
2259
|
var isDecisionCollectScopeResponse = validate24;
|
|
2260
|
-
var schema39 = { "type": "object", "properties": { "policy": { "anyOf": [{ "type": "object", "properties": { "repositories": { "type": "array", "items": { "type": "string" } }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } }, "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } }, "updatedAt": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": ["updatedAt"], "additionalProperties": {} }, { "type": "null" }] }, "collectScopeVersion": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "callerIncluded": { "type": "boolean" } }, "required": ["policy", "collectScopeVersion", "callerIncluded"], "additionalProperties": {} };
|
|
2260
|
+
var schema39 = { "type": "object", "properties": { "policy": { "anyOf": [{ "type": "object", "properties": { "repositories": { "type": "array", "items": { "type": "string" } }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } }, "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } }, "updatedAt": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": ["updatedAt"], "additionalProperties": {} }, { "type": "null" }] }, "collectScopeVersion": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "callerIncluded": { "type": "boolean" } }, "required": ["policy", "collectScopeVersion", "callerIncluded"], "additionalProperties": {} };
|
|
2261
2261
|
function validate24(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
2262
2262
|
;
|
|
2263
2263
|
let vErrors = null;
|
|
@@ -2808,7 +2808,7 @@ function validate24(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
2808
2808
|
}
|
|
2809
2809
|
errors++;
|
|
2810
2810
|
}
|
|
2811
|
-
if (!(data18 === "claude_code" || data18 === "codex" || data18 === "hermes")) {
|
|
2811
|
+
if (!(data18 === "claude_code" || data18 === "codex" || data18 === "cursor" || data18 === "hermes")) {
|
|
2812
2812
|
const err34 = { instancePath: instancePath + "/policy/users/" + i4 + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/DecisionCollectScopeResponse/properties/policy/anyOf/0/properties/users/items/oneOf/2/properties/agent/enum", keyword: "enum", params: { allowedValues: schema39.properties.policy.anyOf[0].properties.users.items.oneOf[2].properties.agent.enum }, message: "must be equal to one of the allowed values" };
|
|
2813
2813
|
if (vErrors === null) {
|
|
2814
2814
|
vErrors = [err34];
|
|
@@ -3577,7 +3577,7 @@ function validate26(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
3577
3577
|
return errors === 0;
|
|
3578
3578
|
}
|
|
3579
3579
|
validate26.evaluated = { "dynamicProps": true, "dynamicItems": false };
|
|
3580
|
-
var schema45 = { "type": "object", "properties": { "intent": { "type": "string", "minLength": 1, "maxLength": 500 }, "attribution": { "type": "string", "enum": ["user", "agent", "unknown"] }, "kind": { "type": "string", "enum": ["change", "exploration", "task_execution", "unclear"] }, "rationale": { "type": "string" }, "area": { "type": "string" }, "decided": { "type": "array", "items": { "type": "string" } }, "alternatives": { "type": "array", "items": { "type": "string" } }, "confidence": { "type": "string", "enum": ["high", "medium", "low"] }, "reversibility": { "type": "string", "enum": ["high", "low"] }, "files": { "type": "array", "items": { "type": "string" } }, "protocolVersion": { "type": "number", "const": 3 }, "repoSyncId": { "type": "string" }, "scope": { "default": {}, "type": "object", "properties": { "location": { "default": {}, "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "additionalProperties": {} }, "time": { "default": {}, "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "additionalProperties": {} }, "stageOverride": { "type": "string", "enum": ["candidate", "draft", "adopted"] } }, "required": ["intent"], "additionalProperties": {}, "x-primitive-runtime-refinements": ["degrade_invalid_rollout_fields", "degrade_invalid_location_scope", "degrade_invalid_time_scope"] };
|
|
3580
|
+
var schema45 = { "type": "object", "properties": { "intent": { "type": "string", "minLength": 1, "maxLength": 500 }, "attribution": { "type": "string", "enum": ["user", "agent", "unknown"] }, "kind": { "type": "string", "enum": ["change", "exploration", "task_execution", "unclear"] }, "rationale": { "type": "string" }, "area": { "type": "string" }, "decided": { "type": "array", "items": { "type": "string" } }, "alternatives": { "type": "array", "items": { "type": "string" } }, "confidence": { "type": "string", "enum": ["high", "medium", "low"] }, "reversibility": { "type": "string", "enum": ["high", "low"] }, "files": { "type": "array", "items": { "type": "string" } }, "protocolVersion": { "type": "number", "const": 3 }, "repoSyncId": { "type": "string" }, "scope": { "default": {}, "type": "object", "properties": { "location": { "default": {}, "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "additionalProperties": {} }, "time": { "default": {}, "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "additionalProperties": {} }, "stageOverride": { "type": "string", "enum": ["candidate", "draft", "adopted"] } }, "required": ["intent"], "additionalProperties": {}, "x-primitive-runtime-refinements": ["degrade_invalid_rollout_fields", "degrade_invalid_location_scope", "degrade_invalid_time_scope"] };
|
|
3581
3581
|
function validate27(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
3582
3582
|
;
|
|
3583
3583
|
let vErrors = null;
|
|
@@ -4281,7 +4281,7 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
4281
4281
|
}
|
|
4282
4282
|
errors++;
|
|
4283
4283
|
}
|
|
4284
|
-
if (!(data34 === "claude_code" || data34 === "codex" || data34 === "hermes")) {
|
|
4284
|
+
if (!(data34 === "claude_code" || data34 === "codex" || data34 === "cursor" || data34 === "hermes")) {
|
|
4285
4285
|
const err19 = { instancePath: instancePath + "/scope/users/" + i6 + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/DecisionCreateRequest/properties/scope/properties/users/items/oneOf/2/properties/agent/enum", keyword: "enum", params: { allowedValues: schema45.properties.scope.properties.users.items.oneOf[2].properties.agent.enum }, message: "must be equal to one of the allowed values" };
|
|
4286
4286
|
if (vErrors === null) {
|
|
4287
4287
|
vErrors = [err19];
|
|
@@ -4509,7 +4509,7 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
4509
4509
|
return errors === 0;
|
|
4510
4510
|
}
|
|
4511
4511
|
validate27.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
4512
|
-
var schema47 = { "type": "object", "properties": { "decisionId": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "createdAt": { "type": "number" }, "scope": { "type": "object", "properties": { "location": { "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "required": ["repository", "directories", "globs", "branches"], "additionalProperties": {} }, "time": { "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "required": ["location", "time", "users"], "additionalProperties": {} }, "scopeWarnings": { "type": "array", "items": { "type": "string" } } }, "required": ["decisionId", "shortId", "createdAt"], "additionalProperties": {} };
|
|
4512
|
+
var schema47 = { "type": "object", "properties": { "decisionId": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "createdAt": { "type": "number" }, "scope": { "type": "object", "properties": { "location": { "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "required": ["repository", "directories", "globs", "branches"], "additionalProperties": {} }, "time": { "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "required": ["location", "time", "users"], "additionalProperties": {} }, "scopeWarnings": { "type": "array", "items": { "type": "string" } } }, "required": ["decisionId", "shortId", "createdAt"], "additionalProperties": {} };
|
|
4513
4513
|
function validate28(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
4514
4514
|
;
|
|
4515
4515
|
let vErrors = null;
|
|
@@ -5045,7 +5045,7 @@ function validate28(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
5045
5045
|
}
|
|
5046
5046
|
errors++;
|
|
5047
5047
|
}
|
|
5048
|
-
if (!(data22 === "claude_code" || data22 === "codex" || data22 === "hermes")) {
|
|
5048
|
+
if (!(data22 === "claude_code" || data22 === "codex" || data22 === "cursor" || data22 === "hermes")) {
|
|
5049
5049
|
const err19 = { instancePath: instancePath + "/scope/users/" + i3 + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/DecisionCreateResponse/properties/scope/properties/users/items/oneOf/2/properties/agent/enum", keyword: "enum", params: { allowedValues: schema47.properties.scope.properties.users.items.oneOf[2].properties.agent.enum }, message: "must be equal to one of the allowed values" };
|
|
5050
5050
|
if (vErrors === null) {
|
|
5051
5051
|
vErrors = [err19];
|
|
@@ -5277,7 +5277,7 @@ function validate28(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
5277
5277
|
return errors === 0;
|
|
5278
5278
|
}
|
|
5279
5279
|
validate28.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
5280
|
-
var schema49 = { "type": "object", "properties": { "decision": { "type": "object", "properties": { "id": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "intent": { "type": "string" }, "intentKind": { "type": "string", "enum": ["change", "exploration", "task_execution", "unclear"] }, "rationale": { "type": "string" }, "decided": { "type": "array", "items": { "type": "string" } }, "alternatives": { "type": "array", "items": { "type": "string" } }, "area": { "type": "string" }, "producerKind": { "type": "string" }, "stage": { "type": "string", "enum": ["draft", "provisional", "adopted", "superseded", "abandoned"] }, "status": { "type": "string", "enum": ["active", "superseded", "under_review"] }, "supersededBy": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] }, "confidence": { "type": "string", "enum": ["high", "medium", "low"] }, "reversibility": { "type": "string", "enum": ["high", "low"] }, "confirmed": { "type": "boolean" }, "respondedAt": { "type": "number" }, "fanOut": { "type": "number" }, "classifiedAt": { "type": "number" }, "authorName": { "type": "string" } }, "required": ["id", "intent", "intentKind", "alternatives", "stage", "status", "supersededBy", "confidence", "classifiedAt", "authorName"], "additionalProperties": {} }, "files": { "type": "array", "items": { "type": "string" } }, "flags": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string", "enum": ["file_edit", "supersession", "invalidation", "confirmation_request"] }, "file": { "type": "string" }, "flaggedAt": { "type": "number" }, "acknowledgedAt": { "type": "number" }, "gateVerdict": { "type": "string" }, "reason": { "type": "string" } }, "required": ["type", "flaggedAt"], "additionalProperties": {} } }, "dependsOn": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "intent": { "type": "string" }, "area": { "type": "string" }, "authorName": { "type": "string" }, "classifiedAt": { "type": "number" }, "status": { "type": "string", "enum": ["active", "superseded", "under_review"] } }, "required": ["id", "intent", "authorName", "classifiedAt", "status"], "additionalProperties": {} } }, "dependents": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "intent": { "type": "string" }, "area": { "type": "string" }, "authorName": { "type": "string" }, "classifiedAt": { "type": "number" }, "status": { "type": "string", "enum": ["active", "superseded", "under_review"] } }, "required": ["id", "intent", "authorName", "classifiedAt", "status"], "additionalProperties": {} } }, "scope": { "type": "object", "properties": { "location": { "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "required": ["repository", "directories", "globs", "branches"], "additionalProperties": {} }, "time": { "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 }, "displayName": { "type": "string" } }, "required": ["kind", "userId", "displayName"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "required": ["location", "time", "users"], "additionalProperties": {} }, "truncated": { "type": "boolean" } }, "required": ["decision", "files", "flags", "dependsOn", "dependents", "scope", "truncated"], "additionalProperties": {} };
|
|
5280
|
+
var schema49 = { "type": "object", "properties": { "decision": { "type": "object", "properties": { "id": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "intent": { "type": "string" }, "intentKind": { "type": "string", "enum": ["change", "exploration", "task_execution", "unclear"] }, "rationale": { "type": "string" }, "decided": { "type": "array", "items": { "type": "string" } }, "alternatives": { "type": "array", "items": { "type": "string" } }, "area": { "type": "string" }, "producerKind": { "type": "string" }, "stage": { "type": "string", "enum": ["draft", "provisional", "adopted", "superseded", "abandoned"] }, "status": { "type": "string", "enum": ["active", "superseded", "under_review"] }, "supersededBy": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] }, "confidence": { "type": "string", "enum": ["high", "medium", "low"] }, "reversibility": { "type": "string", "enum": ["high", "low"] }, "confirmed": { "type": "boolean" }, "respondedAt": { "type": "number" }, "fanOut": { "type": "number" }, "classifiedAt": { "type": "number" }, "authorName": { "type": "string" } }, "required": ["id", "intent", "intentKind", "alternatives", "stage", "status", "supersededBy", "confidence", "classifiedAt", "authorName"], "additionalProperties": {} }, "files": { "type": "array", "items": { "type": "string" } }, "flags": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string", "enum": ["file_edit", "supersession", "invalidation", "confirmation_request"] }, "file": { "type": "string" }, "flaggedAt": { "type": "number" }, "acknowledgedAt": { "type": "number" }, "gateVerdict": { "type": "string" }, "reason": { "type": "string" } }, "required": ["type", "flaggedAt"], "additionalProperties": {} } }, "dependsOn": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "intent": { "type": "string" }, "area": { "type": "string" }, "authorName": { "type": "string" }, "classifiedAt": { "type": "number" }, "status": { "type": "string", "enum": ["active", "superseded", "under_review"] } }, "required": ["id", "intent", "authorName", "classifiedAt", "status"], "additionalProperties": {} } }, "dependents": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "intent": { "type": "string" }, "area": { "type": "string" }, "authorName": { "type": "string" }, "classifiedAt": { "type": "number" }, "status": { "type": "string", "enum": ["active", "superseded", "under_review"] } }, "required": ["id", "intent", "authorName", "classifiedAt", "status"], "additionalProperties": {} } }, "scope": { "type": "object", "properties": { "location": { "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "required": ["repository", "directories", "globs", "branches"], "additionalProperties": {} }, "time": { "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 }, "displayName": { "type": "string" } }, "required": ["kind", "userId", "displayName"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "required": ["location", "time", "users"], "additionalProperties": {} }, "truncated": { "type": "boolean" } }, "required": ["decision", "files", "flags", "dependsOn", "dependents", "scope", "truncated"], "additionalProperties": {} };
|
|
5281
5281
|
function validate29(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
5282
5282
|
;
|
|
5283
5283
|
let vErrors = null;
|
|
@@ -6571,7 +6571,7 @@ function validate29(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
6571
6571
|
}
|
|
6572
6572
|
errors++;
|
|
6573
6573
|
}
|
|
6574
|
-
if (!(data70 === "claude_code" || data70 === "codex" || data70 === "hermes")) {
|
|
6574
|
+
if (!(data70 === "claude_code" || data70 === "codex" || data70 === "cursor" || data70 === "hermes")) {
|
|
6575
6575
|
const err24 = { instancePath: instancePath + "/scope/users/" + i9 + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/DecisionDetailResponse/properties/scope/properties/users/items/oneOf/2/properties/agent/enum", keyword: "enum", params: { allowedValues: schema49.properties.scope.properties.users.items.oneOf[2].properties.agent.enum }, message: "must be equal to one of the allowed values" };
|
|
6576
6576
|
if (vErrors === null) {
|
|
6577
6577
|
vErrors = [err24];
|
|
@@ -7132,7 +7132,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
7132
7132
|
return errors === 0;
|
|
7133
7133
|
}
|
|
7134
7134
|
validate33.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
7135
|
-
var schema59 = { "type": "object", "properties": { "id": { "type": "string" }, "location": { "anyOf": [{ "default": {}, "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "additionalProperties": {} }, { "type": "null" }] }, "time": { "anyOf": [{ "default": {}, "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, { "type": "null" }] }, "users": { "anyOf": [{ "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } }, { "type": "null" }] } }, "required": ["id"], "additionalProperties": {} };
|
|
7135
|
+
var schema59 = { "type": "object", "properties": { "id": { "type": "string" }, "location": { "anyOf": [{ "default": {}, "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "additionalProperties": {} }, { "type": "null" }] }, "time": { "anyOf": [{ "default": {}, "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, { "type": "null" }] }, "users": { "anyOf": [{ "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } }, { "type": "null" }] } }, "required": ["id"], "additionalProperties": {} };
|
|
7136
7136
|
function validate34(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
7137
7137
|
;
|
|
7138
7138
|
let vErrors = null;
|
|
@@ -7773,7 +7773,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
7773
7773
|
}
|
|
7774
7774
|
errors++;
|
|
7775
7775
|
}
|
|
7776
|
-
if (!(data19 === "claude_code" || data19 === "codex" || data19 === "hermes")) {
|
|
7776
|
+
if (!(data19 === "claude_code" || data19 === "codex" || data19 === "cursor" || data19 === "hermes")) {
|
|
7777
7777
|
const err38 = { instancePath: instancePath + "/users/" + i3 + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/DecisionRescopeRequest/properties/users/anyOf/0/items/oneOf/2/properties/agent/enum", keyword: "enum", params: { allowedValues: schema59.properties.users.anyOf[0].items.oneOf[2].properties.agent.enum }, message: "must be equal to one of the allowed values" };
|
|
7778
7778
|
if (vErrors === null) {
|
|
7779
7779
|
vErrors = [err38];
|
|
@@ -8001,7 +8001,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
8001
8001
|
return errors === 0;
|
|
8002
8002
|
}
|
|
8003
8003
|
validate34.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
8004
|
-
var schema61 = { "anyOf": [{ "type": "object", "properties": { "outcome": { "type": "string", "const": "no_op" }, "stage": { "type": "string", "enum": ["draft", "provisional", "adopted", "superseded", "abandoned"] }, "scope": { "type": "object", "properties": { "location": { "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "required": ["repository", "directories", "globs", "branches"], "additionalProperties": {} }, "time": { "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "required": ["location", "time", "users"], "additionalProperties": {} }, "scopeWarnings": { "type": "array", "items": { "type": "string" } } }, "required": ["outcome", "stage", "scope"], "additionalProperties": {} }, { "type": "object", "properties": { "outcome": { "type": "string", "const": "ok" }, "decisionId": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "stage": { "type": "string", "enum": ["draft", "provisional", "adopted", "superseded", "abandoned"] }, "scope": { "type": "object", "properties": { "location": { "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "required": ["repository", "directories", "globs", "branches"], "additionalProperties": {} }, "time": { "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "required": ["location", "time", "users"], "additionalProperties": {} }, "scopeWarnings": { "type": "array", "items": { "type": "string" } } }, "required": ["outcome", "decisionId", "stage", "scope"], "additionalProperties": {} }] };
|
|
8004
|
+
var schema61 = { "anyOf": [{ "type": "object", "properties": { "outcome": { "type": "string", "const": "no_op" }, "stage": { "type": "string", "enum": ["draft", "provisional", "adopted", "superseded", "abandoned"] }, "scope": { "type": "object", "properties": { "location": { "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "required": ["repository", "directories", "globs", "branches"], "additionalProperties": {} }, "time": { "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "required": ["location", "time", "users"], "additionalProperties": {} }, "scopeWarnings": { "type": "array", "items": { "type": "string" } } }, "required": ["outcome", "stage", "scope"], "additionalProperties": {} }, { "type": "object", "properties": { "outcome": { "type": "string", "const": "ok" }, "decisionId": { "type": "string", "minLength": 1 }, "shortId": { "type": "string" }, "stage": { "type": "string", "enum": ["draft", "provisional", "adopted", "superseded", "abandoned"] }, "scope": { "type": "object", "properties": { "location": { "type": "object", "properties": { "repository": { "type": "boolean" }, "directories": { "type": "array", "items": { "type": "string" } }, "globs": { "type": "array", "items": { "type": "string" } }, "branches": { "type": "array", "items": { "type": "string" } } }, "required": ["repository", "directories", "globs", "branches"], "additionalProperties": {} }, "time": { "type": "object", "properties": { "effectiveFrom": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "effectiveUntil": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 } }, "additionalProperties": {} }, "users": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "type": "string", "const": "user" }, "userId": { "type": "string", "minLength": 1 } }, "required": ["kind", "userId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "role" }, "role": { "type": "string", "enum": ["owner", "admin", "member"] } }, "required": ["kind", "role"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "agent" }, "agent": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] } }, "required": ["kind", "agent"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "type": "string", "const": "credential" }, "credential": { "type": "string", "enum": ["workos_jwt", "workos_api_key", "service_token"] } }, "required": ["kind", "credential"], "additionalProperties": false }] } } }, "required": ["location", "time", "users"], "additionalProperties": {} }, "scopeWarnings": { "type": "array", "items": { "type": "string" } } }, "required": ["outcome", "decisionId", "stage", "scope"], "additionalProperties": {} }] };
|
|
8005
8005
|
function validate35(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
8006
8006
|
;
|
|
8007
8007
|
let vErrors = null;
|
|
@@ -8639,7 +8639,7 @@ function validate35(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
8639
8639
|
}
|
|
8640
8640
|
errors++;
|
|
8641
8641
|
}
|
|
8642
|
-
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "hermes")) {
|
|
8642
|
+
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "cursor" || data21 === "hermes")) {
|
|
8643
8643
|
const err41 = { instancePath: instancePath + "/scope/users/" + i3 + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/DecisionRescopeResponse/anyOf/0/properties/scope/properties/users/items/oneOf/2/properties/agent/enum", keyword: "enum", params: { allowedValues: schema61.anyOf[0].properties.scope.properties.users.items.oneOf[2].properties.agent.enum }, message: "must be equal to one of the allowed values" };
|
|
8644
8644
|
if (vErrors === null) {
|
|
8645
8645
|
vErrors = [err41];
|
|
@@ -9563,7 +9563,7 @@ function validate35(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
9563
9563
|
}
|
|
9564
9564
|
errors++;
|
|
9565
9565
|
}
|
|
9566
|
-
if (!(data49 === "claude_code" || data49 === "codex" || data49 === "hermes")) {
|
|
9566
|
+
if (!(data49 === "claude_code" || data49 === "codex" || data49 === "cursor" || data49 === "hermes")) {
|
|
9567
9567
|
const err100 = { instancePath: instancePath + "/scope/users/" + i8 + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/DecisionRescopeResponse/anyOf/1/properties/scope/properties/users/items/oneOf/2/properties/agent/enum", keyword: "enum", params: { allowedValues: schema61.anyOf[1].properties.scope.properties.users.items.oneOf[2].properties.agent.enum }, message: "must be equal to one of the allowed values" };
|
|
9568
9568
|
if (vErrors === null) {
|
|
9569
9569
|
vErrors = [err100];
|
|
@@ -15209,7 +15209,7 @@ function validate50(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
15209
15209
|
return errors === 0;
|
|
15210
15210
|
}
|
|
15211
15211
|
validate50.evaluated = { "dynamicProps": true, "dynamicItems": false };
|
|
15212
|
-
var schema93 = { "type": "object", "properties": { "batch": { "type": "array", "items": { "anyOf": [{ "type": "object", "properties": { "moveId": { "type": "string" }, "capturedAt": { "type": "number" }, "sessionId": { "type": "string" }, "invocationId": { "type": "string" }, "eventType": { "type": "string" }, "payload": {}, "env": {}, "capturedOrganizationId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9_-]+$" }, "captureAuthorityKind": { "type": "string", "enum": ["workos", "service_token"] }, "decisionLifecycleProtocolVersion": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "producer": { "type": "string", "enum": ["claude_code", "codex", "hermes"] }, "toolOutcome": { "type": "string", "enum": ["succeeded", "returned", "failed", "interrupted", "prevented", "unknown"] }, "envelopeVersion": { "type": "number", "const": 4 } }, "required": ["moveId", "capturedAt", "sessionId", "eventType", "capturedOrganizationId", "captureAuthorityKind", "decisionLifecycleProtocolVersion", "envelopeVersion"], "additionalProperties": {} }, { "type": "object", "properties": { "moveId": { "type": "string" }, "capturedAt": { "type": "number" }, "sessionId": { "type": "string" }, "invocationId": { "type": "string" }, "eventType": { "type": "string" }, "payload": {}, "env": {}, "capturedOrganizationId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9_-]+$" }, "captureAuthorityKind": { "type": "string", "enum": ["workos", "service_token"] }, "decisionLifecycleProtocolVersion": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "producer": { "type": "string", "enum": ["claude_code", "codex", "hermes"] }, "toolOutcome": { "type": "string", "enum": ["succeeded", "returned", "failed", "interrupted", "prevented", "unknown"] }, "envelopeVersion": { "type": "number", "exclusiveMaximum": 4 } }, "required": ["moveId", "capturedAt", "sessionId", "eventType"], "additionalProperties": {} }] } } }, "required": ["batch"], "additionalProperties": {} };
|
|
15212
|
+
var schema93 = { "type": "object", "properties": { "batch": { "type": "array", "items": { "anyOf": [{ "type": "object", "properties": { "moveId": { "type": "string" }, "capturedAt": { "type": "number" }, "sessionId": { "type": "string" }, "invocationId": { "type": "string" }, "eventType": { "type": "string" }, "payload": {}, "env": {}, "capturedOrganizationId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9_-]+$" }, "captureAuthorityKind": { "type": "string", "enum": ["workos", "service_token"] }, "decisionLifecycleProtocolVersion": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "producer": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] }, "toolOutcome": { "type": "string", "enum": ["succeeded", "returned", "failed", "interrupted", "prevented", "unknown"] }, "envelopeVersion": { "type": "number", "const": 4 } }, "required": ["moveId", "capturedAt", "sessionId", "eventType", "capturedOrganizationId", "captureAuthorityKind", "decisionLifecycleProtocolVersion", "envelopeVersion"], "additionalProperties": {} }, { "type": "object", "properties": { "moveId": { "type": "string" }, "capturedAt": { "type": "number" }, "sessionId": { "type": "string" }, "invocationId": { "type": "string" }, "eventType": { "type": "string" }, "payload": {}, "env": {}, "capturedOrganizationId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[A-Za-z0-9_-]+$" }, "captureAuthorityKind": { "type": "string", "enum": ["workos", "service_token"] }, "decisionLifecycleProtocolVersion": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "producer": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] }, "toolOutcome": { "type": "string", "enum": ["succeeded", "returned", "failed", "interrupted", "prevented", "unknown"] }, "envelopeVersion": { "type": "number", "exclusiveMaximum": 4 } }, "required": ["moveId", "capturedAt", "sessionId", "eventType"], "additionalProperties": {} }] } } }, "required": ["batch"], "additionalProperties": {} };
|
|
15213
15213
|
var pattern8 = new RegExp("^[A-Za-z0-9_-]+$", "u");
|
|
15214
15214
|
function validate51(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
15215
15215
|
;
|
|
@@ -15463,7 +15463,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
15463
15463
|
}
|
|
15464
15464
|
errors++;
|
|
15465
15465
|
}
|
|
15466
|
-
if (!(data10 === "claude_code" || data10 === "codex" || data10 === "hermes")) {
|
|
15466
|
+
if (!(data10 === "claude_code" || data10 === "codex" || data10 === "cursor" || data10 === "hermes")) {
|
|
15467
15467
|
const err16 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/0/properties/producer/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[0].properties.producer.enum }, message: "must be equal to one of the allowed values" };
|
|
15468
15468
|
if (vErrors === null) {
|
|
15469
15469
|
vErrors = [err16];
|
|
@@ -15775,7 +15775,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
15775
15775
|
}
|
|
15776
15776
|
errors++;
|
|
15777
15777
|
}
|
|
15778
|
-
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "hermes")) {
|
|
15778
|
+
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "cursor" || data21 === "hermes")) {
|
|
15779
15779
|
const err38 = { instancePath: instancePath + "/batch/" + i0 + "/producer", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/MoveIngestRequest/properties/batch/items/anyOf/1/properties/producer/enum", keyword: "enum", params: { allowedValues: schema93.properties.batch.items.anyOf[1].properties.producer.enum }, message: "must be equal to one of the allowed values" };
|
|
15780
15780
|
if (vErrors === null) {
|
|
15781
15781
|
vErrors = [err38];
|
|
@@ -15912,7 +15912,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
15912
15912
|
return errors === 0;
|
|
15913
15913
|
}
|
|
15914
15914
|
validate51.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
15915
|
-
var schema95 = { "type": "object", "properties": { "protocolVersion": { "type": "number", "const": 3 }, "agent": { "type": "string", "enum": ["claude_code", "codex", "hermes"] }, "sessionId": { "type": "string", "pattern": "^[A-Za-z0-9._:-]{1,128}$" }, "invocationId": { "type": "string", "pattern": "^[A-Za-z0-9._:-]{1,128}$" }, "repoSyncId": { "type": "string", "pattern": "^[A-Za-z0-9]{1,64}$" }, "paths": { "maxItems": 32, "type": "array", "items": { "type": "string" } }, "coverage": { "type": "string", "enum": ["complete", "unverified"] }, "branch": { "type": "string", "maxLength": 255, "pattern": "^(?!@?$)(?!\\/)(?!.*\\/$)(?!.*\\/\\/)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)[^/]*\\.lock(?:\\/|$))(?!.*\\.\\.)(?!.*@\\{)(?!.*[~^:?*\\\\]).+$" }, "clientMode": { "type": "string", "enum": ["block", "warn"] }, "clientVersion": { "type": "string", "maxLength": 32, "pattern": "^[A-Za-z0-9][A-Za-z0-9._+-]*$" }, "proposal": { "type": "string" } }, "required": ["protocolVersion", "agent", "sessionId", "invocationId", "repoSyncId", "paths", "coverage", "proposal"], "additionalProperties": false, "x-primitive-runtime-refinements": ["canonical_repository_paths", "unique_repository_paths", "complete_coverage_requires_path", "proposal_utf8_max_6144", "degrade_invalid_rollout_fields", "degrade_invalid_branch"] };
|
|
15915
|
+
var schema95 = { "type": "object", "properties": { "protocolVersion": { "type": "number", "const": 3 }, "agent": { "type": "string", "enum": ["claude_code", "codex", "cursor", "hermes"] }, "sessionId": { "type": "string", "pattern": "^[A-Za-z0-9._:-]{1,128}$" }, "invocationId": { "type": "string", "pattern": "^[A-Za-z0-9._:-]{1,128}$" }, "repoSyncId": { "type": "string", "pattern": "^[A-Za-z0-9]{1,64}$" }, "paths": { "maxItems": 32, "type": "array", "items": { "type": "string" } }, "coverage": { "type": "string", "enum": ["complete", "unverified"] }, "branch": { "type": "string", "maxLength": 255, "pattern": "^(?!@?$)(?!\\/)(?!.*\\/$)(?!.*\\/\\/)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)[^/]*\\.lock(?:\\/|$))(?!.*\\.\\.)(?!.*@\\{)(?!.*[~^:?*\\\\]).+$" }, "clientMode": { "type": "string", "enum": ["block", "warn"] }, "clientVersion": { "type": "string", "maxLength": 32, "pattern": "^[A-Za-z0-9][A-Za-z0-9._+-]*$" }, "proposal": { "type": "string" } }, "required": ["protocolVersion", "agent", "sessionId", "invocationId", "repoSyncId", "paths", "coverage", "proposal"], "additionalProperties": false, "x-primitive-runtime-refinements": ["canonical_repository_paths", "unique_repository_paths", "complete_coverage_requires_path", "proposal_utf8_max_6144", "degrade_invalid_rollout_fields", "degrade_invalid_branch"] };
|
|
15916
15916
|
var pattern10 = new RegExp("^[A-Za-z0-9._:-]{1,128}$", "u");
|
|
15917
15917
|
var pattern12 = new RegExp("^[A-Za-z0-9]{1,64}$", "u");
|
|
15918
15918
|
var pattern13 = new RegExp("^(?!@?$)(?!\\/)(?!.*\\/$)(?!.*\\/\\/)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)[^/]*\\.lock(?:\\/|$))(?!.*\\.\\.)(?!.*@\\{)(?!.*[~^:?*\\\\]).+$", "u");
|
|
@@ -15968,7 +15968,7 @@ function validate52(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
15968
15968
|
validate52.errors = [{ instancePath: instancePath + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/PreflightRequestV3/properties/agent/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
|
|
15969
15969
|
return false;
|
|
15970
15970
|
}
|
|
15971
|
-
if (!(data1 === "claude_code" || data1 === "codex" || data1 === "hermes")) {
|
|
15971
|
+
if (!(data1 === "claude_code" || data1 === "codex" || data1 === "cursor" || data1 === "hermes")) {
|
|
15972
15972
|
validate52.errors = [{ instancePath: instancePath + "/agent", schemaPath: "https://api.getprimitive.ai/contracts/cli-http-v1.schema.json#/$defs/PreflightRequestV3/properties/agent/enum", keyword: "enum", params: { allowedValues: schema95.properties.agent.enum }, message: "must be equal to one of the allowed values" }];
|
|
15973
15973
|
return false;
|
|
15974
15974
|
}
|
|
@@ -19350,7 +19350,7 @@ function optionalUserScopeMembers(record) {
|
|
|
19350
19350
|
members.push({ kind: "role", role: candidate.role });
|
|
19351
19351
|
continue;
|
|
19352
19352
|
}
|
|
19353
|
-
if (candidate.kind === "agent" && (candidate.agent === "claude_code" || candidate.agent === "codex" || candidate.agent === "hermes")) {
|
|
19353
|
+
if (candidate.kind === "agent" && (candidate.agent === "claude_code" || candidate.agent === "codex" || candidate.agent === "cursor" || candidate.agent === "hermes")) {
|
|
19354
19354
|
members.push({ kind: "agent", agent: candidate.agent });
|
|
19355
19355
|
continue;
|
|
19356
19356
|
}
|
|
@@ -19782,7 +19782,7 @@ function errorCode(error) {
|
|
|
19782
19782
|
function parseAgent(argv) {
|
|
19783
19783
|
const i = argv.indexOf("--agent");
|
|
19784
19784
|
const value = i !== -1 ? argv[i + 1] : void 0;
|
|
19785
|
-
if (value === "codex" || value === "hermes") {
|
|
19785
|
+
if (value === "codex" || value === "cursor" || value === "hermes") {
|
|
19786
19786
|
return value;
|
|
19787
19787
|
}
|
|
19788
19788
|
return "claude_code";
|
|
@@ -19869,7 +19869,7 @@ function daemonRequest(method, params = {}, opts = {}) {
|
|
|
19869
19869
|
...caller ? { caller } : {}
|
|
19870
19870
|
};
|
|
19871
19871
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
19872
|
-
return new Promise((
|
|
19872
|
+
return new Promise((resolve6) => {
|
|
19873
19873
|
let settled = false;
|
|
19874
19874
|
let socket;
|
|
19875
19875
|
let buffer = Buffer.alloc(0);
|
|
@@ -19884,7 +19884,7 @@ function daemonRequest(method, params = {}, opts = {}) {
|
|
|
19884
19884
|
} catch {
|
|
19885
19885
|
}
|
|
19886
19886
|
}
|
|
19887
|
-
|
|
19887
|
+
resolve6(value);
|
|
19888
19888
|
};
|
|
19889
19889
|
const timer = setTimeout(() => settle(null), timeoutMs);
|
|
19890
19890
|
timer.unref();
|
|
@@ -19962,6 +19962,7 @@ import { dirname as dirname7, isAbsolute as isAbsolute4, join as join9 } from "p
|
|
|
19962
19962
|
import { fileURLToPath } from "url";
|
|
19963
19963
|
var PKG_NAME = "@primitive.ai/prim";
|
|
19964
19964
|
var ROOT_WALK_LIMIT = 6;
|
|
19965
|
+
var STABLE_HOOK_LAUNCHER_NAME = "prim-hook-launcher-v1";
|
|
19965
19966
|
var resolvedRoot;
|
|
19966
19967
|
function locateRoot() {
|
|
19967
19968
|
if (resolvedRoot !== void 0) {
|
|
@@ -19992,6 +19993,34 @@ function locateRoot() {
|
|
|
19992
19993
|
function packageVersion() {
|
|
19993
19994
|
return locateRoot()?.version ?? null;
|
|
19994
19995
|
}
|
|
19996
|
+
function shellQuote(value) {
|
|
19997
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
19998
|
+
}
|
|
19999
|
+
var STABLE_HOOK_ARGUMENTS_RE = /^[-A-Za-z0-9_ ]*$/u;
|
|
20000
|
+
var STABLE_HOOK_BIN_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/u;
|
|
20001
|
+
function stableHookCommand(bin, args = "") {
|
|
20002
|
+
if (!STABLE_HOOK_BIN_RE.test(bin) || !STABLE_HOOK_ARGUMENTS_RE.test(args)) {
|
|
20003
|
+
throw new Error("invalid stable hook command");
|
|
20004
|
+
}
|
|
20005
|
+
const resolver = [
|
|
20006
|
+
// #242 and earlier identify managed commands by this package marker. Keep
|
|
20007
|
+
// it as inert data during the rolling window so an older uninstall or
|
|
20008
|
+
// reinstall can remove the stable entry without invoking npm or PATH.
|
|
20009
|
+
`prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
|
|
20010
|
+
'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
|
|
20011
|
+
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
20012
|
+
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
20013
|
+
'else prim_home=${HOME:-}; prim_absolute "$prim_home" || exit 78; case "$prim_home" in /) prim_config=/.config/prim ;; *) prim_config="$prim_home/.config/prim" ;; esac; ',
|
|
20014
|
+
"fi; fi; ",
|
|
20015
|
+
`case "$prim_config" in /) prim_launcher=/${STABLE_HOOK_LAUNCHER_NAME} ;; *) prim_launcher="$prim_config/${STABLE_HOOK_LAUNCHER_NAME}" ;; esac; `,
|
|
20016
|
+
'exec "$prim_launcher" "$@"'
|
|
20017
|
+
].join("");
|
|
20018
|
+
const suffix = args ? ` ${args}` : "";
|
|
20019
|
+
return `/bin/sh -c ${shellQuote(resolver)} ${STABLE_HOOK_LAUNCHER_NAME} ${bin}${suffix}`;
|
|
20020
|
+
}
|
|
20021
|
+
function detachedHookShimCommand(bin, args = "") {
|
|
20022
|
+
return `payload=$(cat); { trap '' HUP; printf '%s' "$payload" | { ${stableHookCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
|
|
20023
|
+
}
|
|
19995
20024
|
|
|
19996
20025
|
// src/lib/presence.ts
|
|
19997
20026
|
var DECISION_ORIGIN = "https://app.getprimitive.ai";
|
|
@@ -20106,9 +20135,7 @@ var CODEX_DRAFT_DIGEST_MAX_SEEN_IDS = 4096;
|
|
|
20106
20135
|
var CODEX_DIGEST_STATE_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
20107
20136
|
var CODEX_DIGEST_STATE_MAX_FILES = 256;
|
|
20108
20137
|
var STATE_VERSION = 1;
|
|
20109
|
-
var STATE_DIRECTORY = ["codex", "decision-digests"];
|
|
20110
20138
|
var DRAFT_STATE_VERSION = 2;
|
|
20111
|
-
var DRAFT_STATE_DIRECTORY = ["codex", "decision-draft-deliveries"];
|
|
20112
20139
|
var NO_CURSOR = -1;
|
|
20113
20140
|
function appendContext(existing, context) {
|
|
20114
20141
|
return existing ? `${existing}
|
|
@@ -20133,11 +20160,11 @@ function appendCodexContext(output, context) {
|
|
|
20133
20160
|
}
|
|
20134
20161
|
return next;
|
|
20135
20162
|
}
|
|
20136
|
-
function stateRoot() {
|
|
20137
|
-
return join10(primConfigDirectory(),
|
|
20163
|
+
function stateRoot(namespace) {
|
|
20164
|
+
return join10(primConfigDirectory(), namespace, "decision-digests");
|
|
20138
20165
|
}
|
|
20139
|
-
function draftStateRoot() {
|
|
20140
|
-
return join10(primConfigDirectory(),
|
|
20166
|
+
function draftStateRoot(namespace) {
|
|
20167
|
+
return join10(primConfigDirectory(), namespace, "decision-draft-deliveries");
|
|
20141
20168
|
}
|
|
20142
20169
|
function workspaceFor(cwd) {
|
|
20143
20170
|
try {
|
|
@@ -20149,12 +20176,12 @@ function workspaceFor(cwd) {
|
|
|
20149
20176
|
function statePath(args) {
|
|
20150
20177
|
const identity = `${args.siteUrl}\0${workspaceFor(args.cwd)}\0${args.sessionId}`;
|
|
20151
20178
|
const key = createHash5("sha256").update(identity).digest("hex");
|
|
20152
|
-
return join10(stateRoot(), `${key}.json`);
|
|
20179
|
+
return join10(stateRoot(args.namespace), `${key}.json`);
|
|
20153
20180
|
}
|
|
20154
20181
|
function draftStatePath(args) {
|
|
20155
20182
|
const identity = `${args.siteUrl}\0${workspaceFor(args.cwd)}\0${args.sessionId}\0${args.principalId}\0${args.organizationId}\0${args.credentialFingerprint}`;
|
|
20156
20183
|
const key = createHash5("sha256").update(identity).digest("hex");
|
|
20157
|
-
return join10(draftStateRoot(), `${key}.json`);
|
|
20184
|
+
return join10(draftStateRoot(args.namespace), `${key}.json`);
|
|
20158
20185
|
}
|
|
20159
20186
|
function parseState(value) {
|
|
20160
20187
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
@@ -20345,14 +20372,14 @@ function mergeState(latest, args) {
|
|
|
20345
20372
|
updatedAt: args.now
|
|
20346
20373
|
};
|
|
20347
20374
|
}
|
|
20348
|
-
async function commitState(path, args) {
|
|
20375
|
+
async function commitState(path, args, namespace) {
|
|
20349
20376
|
try {
|
|
20350
20377
|
await withFileLock(
|
|
20351
20378
|
`${path}.lock`,
|
|
20352
20379
|
() => {
|
|
20353
20380
|
const latest = readState(path);
|
|
20354
|
-
writeStateFile(path, stateRoot(), mergeState(latest, args));
|
|
20355
|
-
cleanupStateFiles(stateRoot(), args.now);
|
|
20381
|
+
writeStateFile(path, stateRoot(namespace), mergeState(latest, args));
|
|
20382
|
+
cleanupStateFiles(stateRoot(namespace), args.now);
|
|
20356
20383
|
},
|
|
20357
20384
|
{ timeoutMs: 50, pollMs: 10 }
|
|
20358
20385
|
);
|
|
@@ -20374,7 +20401,7 @@ function mergeDraftState(latest, args) {
|
|
|
20374
20401
|
updatedAt: args.now
|
|
20375
20402
|
};
|
|
20376
20403
|
}
|
|
20377
|
-
async function commitDraftState(path, args) {
|
|
20404
|
+
async function commitDraftState(path, args, namespace) {
|
|
20378
20405
|
try {
|
|
20379
20406
|
let next;
|
|
20380
20407
|
await withFileLock(
|
|
@@ -20382,8 +20409,8 @@ async function commitDraftState(path, args) {
|
|
|
20382
20409
|
() => {
|
|
20383
20410
|
const latest = readDraftState(path);
|
|
20384
20411
|
next = mergeDraftState(latest, args);
|
|
20385
|
-
writeStateFile(path, draftStateRoot(), next);
|
|
20386
|
-
cleanupStateFiles(draftStateRoot(), args.now);
|
|
20412
|
+
writeStateFile(path, draftStateRoot(namespace), next);
|
|
20413
|
+
cleanupStateFiles(draftStateRoot(namespace), args.now);
|
|
20387
20414
|
},
|
|
20388
20415
|
{ timeoutMs: 50, pollMs: 10 }
|
|
20389
20416
|
);
|
|
@@ -20393,9 +20420,10 @@ async function commitDraftState(path, args) {
|
|
|
20393
20420
|
}
|
|
20394
20421
|
}
|
|
20395
20422
|
async function prepareCodexContext(options) {
|
|
20423
|
+
const namespace = options.namespace ?? "codex";
|
|
20396
20424
|
const siteUrl = getSiteUrl();
|
|
20397
20425
|
const workspace = workspaceFor(options.cwd);
|
|
20398
|
-
const path = statePath({ cwd: options.cwd, sessionId: options.sessionId, siteUrl });
|
|
20426
|
+
const path = statePath({ cwd: options.cwd, sessionId: options.sessionId, siteUrl, namespace });
|
|
20399
20427
|
const previous = readState(path);
|
|
20400
20428
|
const principal = resolveDaemonPrincipal();
|
|
20401
20429
|
const privatePath = principal ? draftStatePath({
|
|
@@ -20404,7 +20432,8 @@ async function prepareCodexContext(options) {
|
|
|
20404
20432
|
siteUrl,
|
|
20405
20433
|
principalId: principal.principalId,
|
|
20406
20434
|
organizationId: principal.organizationId,
|
|
20407
|
-
credentialFingerprint: principal.credentialFingerprint
|
|
20435
|
+
credentialFingerprint: principal.credentialFingerprint,
|
|
20436
|
+
namespace
|
|
20408
20437
|
}) : void 0;
|
|
20409
20438
|
const previousDraft = privatePath ? readDraftState(privatePath) : void 0;
|
|
20410
20439
|
const startup = options.startup === true;
|
|
@@ -20494,32 +20523,40 @@ async function prepareCodexContext(options) {
|
|
|
20494
20523
|
acknowledge: async (handedOff) => {
|
|
20495
20524
|
if (!handedOff || acknowledged) return;
|
|
20496
20525
|
acknowledged = true;
|
|
20497
|
-
await commitState(
|
|
20498
|
-
|
|
20499
|
-
|
|
20500
|
-
|
|
20501
|
-
|
|
20502
|
-
|
|
20503
|
-
|
|
20504
|
-
|
|
20505
|
-
|
|
20506
|
-
|
|
20507
|
-
|
|
20526
|
+
await commitState(
|
|
20527
|
+
path,
|
|
20528
|
+
{
|
|
20529
|
+
sessionId: options.sessionId,
|
|
20530
|
+
siteUrl,
|
|
20531
|
+
workspace,
|
|
20532
|
+
startedAt,
|
|
20533
|
+
watermarkMs: pageWatermark,
|
|
20534
|
+
seenIds: freshRows.map((row) => row.id),
|
|
20535
|
+
report,
|
|
20536
|
+
feedAvailable,
|
|
20537
|
+
now: Date.now()
|
|
20538
|
+
},
|
|
20539
|
+
namespace
|
|
20540
|
+
);
|
|
20508
20541
|
if (privatePath === void 0 || principal === void 0 || draftPageToken === void 0) {
|
|
20509
20542
|
return;
|
|
20510
20543
|
}
|
|
20511
20544
|
let persistedDraft = previousDraft;
|
|
20512
20545
|
if (draftDigest?.deliveredIds.length) {
|
|
20513
|
-
persistedDraft = await commitDraftState(
|
|
20514
|
-
|
|
20515
|
-
|
|
20516
|
-
|
|
20517
|
-
|
|
20518
|
-
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20546
|
+
persistedDraft = await commitDraftState(
|
|
20547
|
+
privatePath,
|
|
20548
|
+
{
|
|
20549
|
+
sessionId: options.sessionId,
|
|
20550
|
+
siteUrl,
|
|
20551
|
+
workspace,
|
|
20552
|
+
principalId: principal.principalId,
|
|
20553
|
+
organizationId: principal.organizationId,
|
|
20554
|
+
credentialFingerprint: principal.credentialFingerprint,
|
|
20555
|
+
deliveredIds: draftDigest.deliveredIds,
|
|
20556
|
+
now: Date.now()
|
|
20557
|
+
},
|
|
20558
|
+
namespace
|
|
20559
|
+
);
|
|
20523
20560
|
}
|
|
20524
20561
|
const seenDrafts = new Set(persistedDraft?.seenDraftIds ?? []);
|
|
20525
20562
|
const deliveredOnThisPage = draftPageActionableIds.filter((id) => seenDrafts.has(id));
|
|
@@ -20536,8 +20573,292 @@ async function prepareCodexContext(options) {
|
|
|
20536
20573
|
};
|
|
20537
20574
|
}
|
|
20538
20575
|
|
|
20576
|
+
// src/commands/cursor-install.ts
|
|
20577
|
+
import { existsSync as existsSync9, readFileSync as readFileSync11 } from "fs";
|
|
20578
|
+
import { homedir as homedir4 } from "os";
|
|
20579
|
+
import { isAbsolute as isAbsolute6, join as join13 } from "path";
|
|
20580
|
+
|
|
20581
|
+
// src/lib/hook-runtime.ts
|
|
20582
|
+
import { createHash as createHash6, randomBytes as randomBytes4 } from "crypto";
|
|
20583
|
+
import {
|
|
20584
|
+
constants as constants3,
|
|
20585
|
+
accessSync,
|
|
20586
|
+
chmodSync as chmodSync4,
|
|
20587
|
+
copyFileSync,
|
|
20588
|
+
existsSync as existsSync7,
|
|
20589
|
+
lstatSync as lstatSync3,
|
|
20590
|
+
mkdirSync as mkdirSync6,
|
|
20591
|
+
mkdtempSync,
|
|
20592
|
+
readFileSync as readFileSync9,
|
|
20593
|
+
readdirSync as readdirSync2,
|
|
20594
|
+
realpathSync as realpathSync2,
|
|
20595
|
+
renameSync as renameSync3,
|
|
20596
|
+
rmSync as rmSync5,
|
|
20597
|
+
statSync as statSync4,
|
|
20598
|
+
utimesSync,
|
|
20599
|
+
writeFileSync as writeFileSync5
|
|
20600
|
+
} from "fs";
|
|
20601
|
+
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute5, join as join11, resolve as resolve4 } from "path";
|
|
20602
|
+
var RELEASE_PREFIX = "release-";
|
|
20603
|
+
var MAX_MANIFEST_BYTES = 64 * 1024;
|
|
20604
|
+
var RELEASE_GRACE_MS = 10 * 60 * 1e3;
|
|
20605
|
+
var HOOK_RUNTIME_ENTRIES = {
|
|
20606
|
+
// SessionStart self-healing resolves this exact CLI entry to run
|
|
20607
|
+
// `daemon ensure`; it must travel with the immutable hook release.
|
|
20608
|
+
prim: "dist/index.js",
|
|
20609
|
+
"prim-hook": "dist/hooks/prim-hook.js",
|
|
20610
|
+
"prim-pre-commit": "dist/hooks/pre-commit.js",
|
|
20611
|
+
"prim-post-commit": "dist/hooks/post-commit.js",
|
|
20612
|
+
"prim-post-rewrite": "dist/hooks/post-rewrite.js",
|
|
20613
|
+
"prim-pre-tool-use": "dist/hooks/pre-tool-use.js",
|
|
20614
|
+
"prim-post-tool-use": "dist/hooks/post-tool-use.js",
|
|
20615
|
+
"prim-session-start": "dist/hooks/session-start.js",
|
|
20616
|
+
"prim-session-end": "dist/hooks/session-end.js",
|
|
20617
|
+
"prim-daemon-server": "dist/daemon/server.js",
|
|
20618
|
+
"prim-statusline": "dist/statusline-main.js"
|
|
20619
|
+
};
|
|
20620
|
+
var SOURCE_ENTRIES = Object.fromEntries(
|
|
20621
|
+
Object.entries(HOOK_RUNTIME_ENTRIES).map(([bin, target]) => [
|
|
20622
|
+
bin,
|
|
20623
|
+
target.replace(/^dist\//u, "")
|
|
20624
|
+
])
|
|
20625
|
+
);
|
|
20626
|
+
var STABLE_HOOK_LAUNCHER_CONTENT = `#!/bin/sh
|
|
20627
|
+
set -eu
|
|
20628
|
+
case "$0" in */*) prim_launcher_dir=\${0%/*} ;; *) exit 78 ;; esac
|
|
20629
|
+
IFS= read -r prim_release_name < "$prim_launcher_dir/hook-runtime/current" || exit 69
|
|
20630
|
+
case "$prim_release_name" in ${RELEASE_PREFIX}*) ;; *) exit 69 ;; esac
|
|
20631
|
+
prim_release_id=\${prim_release_name#${RELEASE_PREFIX}}
|
|
20632
|
+
case "$prim_release_id" in *[!0-9a-f]*|"") exit 69 ;; esac
|
|
20633
|
+
[ "\${#prim_release_id}" -eq 64 ] || exit 69
|
|
20634
|
+
prim_release="$prim_launcher_dir/hook-runtime/releases/$prim_release_name"
|
|
20635
|
+
case "\${1-}" in
|
|
20636
|
+
${Object.entries(HOOK_RUNTIME_ENTRIES).map(([bin, entry]) => ` ${bin}) prim_entry="$prim_release/${entry}" ;;`).join("\n")}
|
|
20637
|
+
*) exit 64 ;;
|
|
20638
|
+
esac
|
|
20639
|
+
shift
|
|
20640
|
+
IFS= read -r prim_node < "$prim_release/node" || exit 69
|
|
20641
|
+
case "$prim_node" in /*) ;; *) exit 69 ;; esac
|
|
20642
|
+
[ -x "$prim_node" ] && [ -f "$prim_entry" ] || exit 69
|
|
20643
|
+
exec "$prim_node" "$prim_entry" "$@"
|
|
20644
|
+
`;
|
|
20645
|
+
|
|
20646
|
+
// src/commands/claude-install.ts
|
|
20647
|
+
import { existsSync as existsSync8, readFileSync as readFileSync10 } from "fs";
|
|
20648
|
+
import { homedir as homedir3 } from "os";
|
|
20649
|
+
import { join as join12 } from "path";
|
|
20650
|
+
var CAPTURE_BIN = "prim-hook";
|
|
20651
|
+
var GATE_BIN = "prim-pre-tool-use";
|
|
20652
|
+
var POST_TOOL_USE_BIN = "prim-post-tool-use";
|
|
20653
|
+
var SESSION_START_BIN = "prim-session-start";
|
|
20654
|
+
var SESSION_END_BIN = "prim-session-end";
|
|
20655
|
+
var STATUSLINE_BIN = "prim-statusline";
|
|
20656
|
+
var STATUSLINE_ARGS = "";
|
|
20657
|
+
var STATUSLINE_COMMAND = stableHookCommand(STATUSLINE_BIN, STATUSLINE_ARGS);
|
|
20658
|
+
var USER_SCOPE_PATH = join12(homedir3(), ".claude", "settings.json");
|
|
20659
|
+
function projectRoot() {
|
|
20660
|
+
return gitToplevel() ?? process.cwd();
|
|
20661
|
+
}
|
|
20662
|
+
var CAPTURE_EVENTS = [
|
|
20663
|
+
"SessionStart",
|
|
20664
|
+
"UserPromptSubmit",
|
|
20665
|
+
"PreToolUse",
|
|
20666
|
+
"PostToolUse",
|
|
20667
|
+
"PostToolUseFailure",
|
|
20668
|
+
"Stop",
|
|
20669
|
+
"SessionEnd",
|
|
20670
|
+
"SubagentStop"
|
|
20671
|
+
];
|
|
20672
|
+
function makeRegistration(event, matcher, bin, args = "") {
|
|
20673
|
+
return {
|
|
20674
|
+
event,
|
|
20675
|
+
matcher,
|
|
20676
|
+
bin,
|
|
20677
|
+
command: stableHookCommand(bin, args)
|
|
20678
|
+
};
|
|
20679
|
+
}
|
|
20680
|
+
function makeDetachedRegistration(event, matcher, bin, args = "") {
|
|
20681
|
+
return { event, matcher, bin, command: detachedHookShimCommand(bin, args) };
|
|
20682
|
+
}
|
|
20683
|
+
var REGISTRATIONS = [
|
|
20684
|
+
...CAPTURE_EVENTS.map(
|
|
20685
|
+
(event) => event === "SessionEnd" ? makeDetachedRegistration(event, "*", CAPTURE_BIN) : makeRegistration(event, "*", CAPTURE_BIN)
|
|
20686
|
+
),
|
|
20687
|
+
makeRegistration("PreToolUse", "Edit|Write|MultiEdit|NotebookEdit|Bash", GATE_BIN),
|
|
20688
|
+
makeRegistration("PostToolUse", "Edit|Write|MultiEdit|NotebookEdit|Bash", POST_TOOL_USE_BIN),
|
|
20689
|
+
makeRegistration(
|
|
20690
|
+
"PostToolUseFailure",
|
|
20691
|
+
"Edit|Write|MultiEdit|NotebookEdit|Bash",
|
|
20692
|
+
POST_TOOL_USE_BIN
|
|
20693
|
+
),
|
|
20694
|
+
makeRegistration("SessionStart", "*", SESSION_START_BIN),
|
|
20695
|
+
makeDetachedRegistration("SessionEnd", "*", SESSION_END_BIN)
|
|
20696
|
+
];
|
|
20697
|
+
var PRIM_PERMISSION_RULE = "Bash(npx --yes @primitive.ai/prim*)";
|
|
20698
|
+
var LEGACY_PRIM_PERMISSION_RULES = [
|
|
20699
|
+
"Bash(npx --yes @primitive.ai/prim@latest:*)",
|
|
20700
|
+
"Bash(npx --yes @primitive.ai/prim:*)"
|
|
20701
|
+
];
|
|
20702
|
+
var ALL_PRIM_PERMISSION_RULES = /* @__PURE__ */ new Set([
|
|
20703
|
+
PRIM_PERMISSION_RULE,
|
|
20704
|
+
...LEGACY_PRIM_PERMISSION_RULES
|
|
20705
|
+
]);
|
|
20706
|
+
|
|
20707
|
+
// src/commands/cursor-install.ts
|
|
20708
|
+
var CAPTURE_BIN2 = "prim-hook";
|
|
20709
|
+
var GATE_BIN2 = "prim-pre-tool-use";
|
|
20710
|
+
var POST_TOOL_BIN = "prim-post-tool-use";
|
|
20711
|
+
var SESSION_START_BIN2 = "prim-session-start";
|
|
20712
|
+
var SESSION_END_BIN2 = "prim-session-end";
|
|
20713
|
+
var STATUSLINE_BIN2 = "prim-statusline";
|
|
20714
|
+
var CURSOR_EVENTS = [
|
|
20715
|
+
"sessionStart",
|
|
20716
|
+
"beforeSubmitPrompt",
|
|
20717
|
+
"preToolUse",
|
|
20718
|
+
"postToolUse",
|
|
20719
|
+
"postToolUseFailure",
|
|
20720
|
+
"afterAgentResponse",
|
|
20721
|
+
"subagentStop",
|
|
20722
|
+
"stop",
|
|
20723
|
+
"sessionEnd"
|
|
20724
|
+
];
|
|
20725
|
+
var REGISTRATIONS2 = [
|
|
20726
|
+
...CURSOR_EVENTS.map((event) => ({ event, bin: CAPTURE_BIN2 })),
|
|
20727
|
+
{ event: "preToolUse", bin: GATE_BIN2, matcher: "Write|Delete|Shell", timeout: 10 },
|
|
20728
|
+
{ event: "postToolUse", bin: POST_TOOL_BIN },
|
|
20729
|
+
{ event: "postToolUseFailure", bin: POST_TOOL_BIN },
|
|
20730
|
+
{ event: "sessionStart", bin: SESSION_START_BIN2 },
|
|
20731
|
+
{ event: "sessionEnd", bin: SESSION_END_BIN2 }
|
|
20732
|
+
];
|
|
20733
|
+
function cursorConfigDirectory(env = process.env, home = homedir4(), platform2 = process.platform) {
|
|
20734
|
+
const explicit = env.CURSOR_CONFIG_DIR?.trim();
|
|
20735
|
+
if (explicit && isAbsolute6(explicit)) return explicit;
|
|
20736
|
+
const xdg = env.XDG_CONFIG_HOME?.trim();
|
|
20737
|
+
if (platform2 !== "darwin" && xdg && isAbsolute6(xdg)) return join13(xdg, "cursor");
|
|
20738
|
+
return join13(home, ".cursor");
|
|
20739
|
+
}
|
|
20740
|
+
function cursorHooksPath(scope, root = projectRoot()) {
|
|
20741
|
+
return scope === "user" ? join13(cursorConfigDirectory(), "hooks.json") : join13(root, ".cursor", "hooks.json");
|
|
20742
|
+
}
|
|
20743
|
+
function plainObject(value) {
|
|
20744
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20745
|
+
}
|
|
20746
|
+
function readCursorHooks(path) {
|
|
20747
|
+
if (!existsSync9(path)) return {};
|
|
20748
|
+
let parsed;
|
|
20749
|
+
try {
|
|
20750
|
+
parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
20751
|
+
} catch {
|
|
20752
|
+
throw new Error(`invalid Cursor hooks JSON at ${path}`);
|
|
20753
|
+
}
|
|
20754
|
+
if (!plainObject(parsed)) throw new Error(`Cursor hooks config must be an object: ${path}`);
|
|
20755
|
+
if (parsed.version !== void 0 && parsed.version !== 1) {
|
|
20756
|
+
throw new Error(`unsupported Cursor hooks version at ${path} (expected version 1)`);
|
|
20757
|
+
}
|
|
20758
|
+
if (parsed.hooks !== void 0) {
|
|
20759
|
+
if (!plainObject(parsed.hooks)) throw new Error(`Cursor hooks must be an object: ${path}`);
|
|
20760
|
+
for (const [event, entries] of Object.entries(parsed.hooks)) {
|
|
20761
|
+
if (!Array.isArray(entries) || !entries.every(plainObject)) {
|
|
20762
|
+
throw new Error(`Cursor hook list must contain objects: ${event} in ${path}`);
|
|
20763
|
+
}
|
|
20764
|
+
}
|
|
20765
|
+
}
|
|
20766
|
+
return parsed;
|
|
20767
|
+
}
|
|
20768
|
+
function commandFor(registration, scope) {
|
|
20769
|
+
return stableHookCommand(
|
|
20770
|
+
registration.bin,
|
|
20771
|
+
`--agent cursor --event ${registration.event} --scope ${scope}`
|
|
20772
|
+
);
|
|
20773
|
+
}
|
|
20774
|
+
var OWNED_COMMANDS = new Set(
|
|
20775
|
+
["project", "user"].flatMap(
|
|
20776
|
+
(scope) => REGISTRATIONS2.map((registration) => commandFor(registration, scope))
|
|
20777
|
+
)
|
|
20778
|
+
);
|
|
20779
|
+
function jsoncUnsafeCommand(command) {
|
|
20780
|
+
return command.replace('case "$1" in [/]* ', 'case "$1" in /*').replace("*[/][/]*", "*//*").replace("*[/].[/]*", "*/./*").replace("*[/]..[/]*", "*/../*").replace("*[/].", "*/.").replace("*[/]..", "*/..").replace("?*[/]", "?*/");
|
|
20781
|
+
}
|
|
20782
|
+
var JSONC_UNSAFE_OWNED_COMMANDS = new Set([...OWNED_COMMANDS].map(jsoncUnsafeCommand));
|
|
20783
|
+
function hookFor(registration, scope) {
|
|
20784
|
+
return {
|
|
20785
|
+
command: commandFor(registration, scope),
|
|
20786
|
+
...registration.matcher ? { matcher: registration.matcher } : {},
|
|
20787
|
+
...registration.timeout ? { timeout: registration.timeout } : {}
|
|
20788
|
+
};
|
|
20789
|
+
}
|
|
20790
|
+
function exactHook(entry, registration, scope) {
|
|
20791
|
+
return JSON.stringify(entry) === JSON.stringify(hookFor(registration, scope));
|
|
20792
|
+
}
|
|
20793
|
+
function hasExactCursorHandler(settings, event, bin, scope) {
|
|
20794
|
+
const registration = REGISTRATIONS2.find(
|
|
20795
|
+
(candidate) => candidate.event === event && candidate.bin === bin
|
|
20796
|
+
);
|
|
20797
|
+
return registration ? (settings.hooks?.[event] ?? []).some((entry) => exactHook(entry, registration, scope)) : false;
|
|
20798
|
+
}
|
|
20799
|
+
var FOOTER = {
|
|
20800
|
+
type: "command",
|
|
20801
|
+
command: stableHookCommand(STATUSLINE_BIN2),
|
|
20802
|
+
updateIntervalMs: 1e3,
|
|
20803
|
+
timeoutMs: 2e3
|
|
20804
|
+
};
|
|
20805
|
+
var JSONC_UNSAFE_FOOTER = {
|
|
20806
|
+
...FOOTER,
|
|
20807
|
+
command: jsoncUnsafeCommand(FOOTER.command)
|
|
20808
|
+
};
|
|
20809
|
+
|
|
20810
|
+
// src/hooks/cursor-coexistence.ts
|
|
20811
|
+
var CURSOR_EVENTS2 = /* @__PURE__ */ new Set([
|
|
20812
|
+
"sessionStart",
|
|
20813
|
+
"beforeSubmitPrompt",
|
|
20814
|
+
"preToolUse",
|
|
20815
|
+
"postToolUse",
|
|
20816
|
+
"postToolUseFailure",
|
|
20817
|
+
"afterAgentResponse",
|
|
20818
|
+
"subagentStop",
|
|
20819
|
+
"stop",
|
|
20820
|
+
"sessionEnd"
|
|
20821
|
+
]);
|
|
20822
|
+
function cursorEvidence(parsed) {
|
|
20823
|
+
return typeof parsed.cursor_version === "string" && parsed.cursor_version.length > 0 && typeof parsed.conversation_id === "string" && parsed.conversation_id.length > 0 && typeof parsed.generation_id === "string" && parsed.generation_id.length > 0 && Array.isArray(parsed.workspace_roots) && typeof parsed.hook_event_name === "string" && CURSOR_EVENTS2.has(parsed.hook_event_name);
|
|
20824
|
+
}
|
|
20825
|
+
function uniqueProjectRoot(parsed) {
|
|
20826
|
+
if (!Array.isArray(parsed.workspace_roots)) return;
|
|
20827
|
+
const roots = new Set(
|
|
20828
|
+
parsed.workspace_roots.filter((value) => typeof value === "string" && value.length > 0).map((value) => resolveRepositoryContext(value)?.repoRoot).filter((value) => !!value)
|
|
20829
|
+
);
|
|
20830
|
+
return roots.size === 1 ? [...roots][0] : void 0;
|
|
20831
|
+
}
|
|
20832
|
+
function shouldSuppressImportedCursorHandler(parsed, bin) {
|
|
20833
|
+
if (!cursorEvidence(parsed)) return false;
|
|
20834
|
+
const project = uniqueProjectRoot(parsed);
|
|
20835
|
+
if (project) {
|
|
20836
|
+
try {
|
|
20837
|
+
if (hasExactCursorHandler(
|
|
20838
|
+
readCursorHooks(cursorHooksPath("project", project)),
|
|
20839
|
+
parsed.hook_event_name,
|
|
20840
|
+
bin,
|
|
20841
|
+
"project"
|
|
20842
|
+
)) {
|
|
20843
|
+
return true;
|
|
20844
|
+
}
|
|
20845
|
+
} catch {
|
|
20846
|
+
}
|
|
20847
|
+
}
|
|
20848
|
+
try {
|
|
20849
|
+
return hasExactCursorHandler(
|
|
20850
|
+
readCursorHooks(cursorHooksPath("user")),
|
|
20851
|
+
parsed.hook_event_name,
|
|
20852
|
+
bin,
|
|
20853
|
+
"user"
|
|
20854
|
+
);
|
|
20855
|
+
} catch {
|
|
20856
|
+
return false;
|
|
20857
|
+
}
|
|
20858
|
+
}
|
|
20859
|
+
|
|
20539
20860
|
// src/hooks/pre-tool-use-scoring.ts
|
|
20540
|
-
import { isAbsolute as
|
|
20861
|
+
import { isAbsolute as isAbsolute7, relative as relative2, sep as sep2 } from "path";
|
|
20541
20862
|
var SUPPORTED_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
20542
20863
|
var APPLY_PATCH_FILE_RE = /^\*\*\* (?:Update|Add|Delete) File: (?<path>.+)$/;
|
|
20543
20864
|
var MOVE_FILE_RE = /^\*\*\* Move File:\s*(?<src>.+?)\s*->\s*(?<dst>.+?)\s*$/;
|
|
@@ -20608,10 +20929,25 @@ function extractHermesFileTargets(toolName, toolInput) {
|
|
|
20608
20929
|
const mode = input.mode;
|
|
20609
20930
|
return { paths, complete: paths.length > 0 && (mode === void 0 || mode === "replace") };
|
|
20610
20931
|
}
|
|
20932
|
+
function extractCursorFileTargets(toolName, toolInput) {
|
|
20933
|
+
if (toolName !== "Write" && toolName !== "Delete") return null;
|
|
20934
|
+
if (!toolInput || typeof toolInput !== "object" || Array.isArray(toolInput)) {
|
|
20935
|
+
return { paths: [], complete: false };
|
|
20936
|
+
}
|
|
20937
|
+
const input = toolInput;
|
|
20938
|
+
const candidates = [input.file_path, input.path].filter(
|
|
20939
|
+
(value) => typeof value === "string" && value.length > 0
|
|
20940
|
+
);
|
|
20941
|
+
const paths = [...new Set(candidates)];
|
|
20942
|
+
return { paths, complete: paths.length === 1 };
|
|
20943
|
+
}
|
|
20611
20944
|
function extractFileTargets(toolName, toolInput, agent = "claude_code") {
|
|
20612
20945
|
if (agent === "codex") {
|
|
20613
20946
|
return extractCodexFileTargets(toolName, toolInput);
|
|
20614
20947
|
}
|
|
20948
|
+
if (agent === "cursor") {
|
|
20949
|
+
return extractCursorFileTargets(toolName, toolInput);
|
|
20950
|
+
}
|
|
20615
20951
|
if (agent === "hermes") {
|
|
20616
20952
|
return extractHermesFileTargets(toolName, toolInput);
|
|
20617
20953
|
}
|
|
@@ -21905,16 +22241,16 @@ var Lexer = class {
|
|
|
21905
22241
|
readHereDocDelimiter() {
|
|
21906
22242
|
const src = this.src;
|
|
21907
22243
|
const len = this.srcEnd;
|
|
21908
|
-
let
|
|
22244
|
+
let delimiter2 = "";
|
|
21909
22245
|
if (this.pos < len && src.charCodeAt(this.pos) === CH_SQUOTE) {
|
|
21910
22246
|
this.pos++;
|
|
21911
22247
|
const start = this.pos;
|
|
21912
22248
|
while (this.pos < len && src.charCodeAt(this.pos) !== CH_SQUOTE)
|
|
21913
22249
|
this.pos++;
|
|
21914
|
-
|
|
22250
|
+
delimiter2 = src.slice(start, this.pos);
|
|
21915
22251
|
if (this.pos < len)
|
|
21916
22252
|
this.pos++;
|
|
21917
|
-
this._hereDelim =
|
|
22253
|
+
this._hereDelim = delimiter2;
|
|
21918
22254
|
this._hereQuoted = true;
|
|
21919
22255
|
return;
|
|
21920
22256
|
} else if (this.pos < len && src.charCodeAt(this.pos) === CH_DQUOTE) {
|
|
@@ -21922,12 +22258,12 @@ var Lexer = class {
|
|
|
21922
22258
|
while (this.pos < len && src.charCodeAt(this.pos) !== CH_DQUOTE) {
|
|
21923
22259
|
if (src.charCodeAt(this.pos) === CH_BACKSLASH)
|
|
21924
22260
|
this.pos++;
|
|
21925
|
-
|
|
22261
|
+
delimiter2 += src[this.pos];
|
|
21926
22262
|
this.pos++;
|
|
21927
22263
|
}
|
|
21928
22264
|
if (this.pos < len)
|
|
21929
22265
|
this.pos++;
|
|
21930
|
-
this._hereDelim =
|
|
22266
|
+
this._hereDelim = delimiter2;
|
|
21931
22267
|
this._hereQuoted = true;
|
|
21932
22268
|
return;
|
|
21933
22269
|
} else if (this.pos < len && src.charCodeAt(this.pos) === CH_BACKSLASH) {
|
|
@@ -21938,11 +22274,11 @@ var Lexer = class {
|
|
|
21938
22274
|
if (c === CH_BACKSLASH)
|
|
21939
22275
|
this.pos++;
|
|
21940
22276
|
if (this.pos < len) {
|
|
21941
|
-
|
|
22277
|
+
delimiter2 += src[this.pos];
|
|
21942
22278
|
this.pos++;
|
|
21943
22279
|
}
|
|
21944
22280
|
}
|
|
21945
|
-
this._hereDelim =
|
|
22281
|
+
this._hereDelim = delimiter2;
|
|
21946
22282
|
this._hereQuoted = true;
|
|
21947
22283
|
return;
|
|
21948
22284
|
} else {
|
|
@@ -21974,9 +22310,9 @@ var Lexer = class {
|
|
|
21974
22310
|
}
|
|
21975
22311
|
this.pendingHereDocs.length = 0;
|
|
21976
22312
|
}
|
|
21977
|
-
readHereDocBody(
|
|
22313
|
+
readHereDocBody(delimiter2, strip) {
|
|
21978
22314
|
const bodyStart = this.pos;
|
|
21979
|
-
const bodyEnd = this.skipHereDocBody(
|
|
22315
|
+
const bodyEnd = this.skipHereDocBody(delimiter2, strip);
|
|
21980
22316
|
return this.src.slice(bodyStart, bodyEnd);
|
|
21981
22317
|
}
|
|
21982
22318
|
// Advance past the heredoc body and its delimiter line; return the body end
|
|
@@ -21984,10 +22320,10 @@ var Lexer = class {
|
|
|
21984
22320
|
// With parenEnds (inside $(...)), a line starting with the delimiter directly
|
|
21985
22321
|
// followed by ")" also terminates the body, resuming at the ")" — bash treats
|
|
21986
22322
|
// the substitution's closing paren as end-of-file for its heredocs.
|
|
21987
|
-
skipHereDocBody(
|
|
22323
|
+
skipHereDocBody(delimiter2, strip, parenEnds = false) {
|
|
21988
22324
|
const src = this.src;
|
|
21989
22325
|
const len = this.srcEnd;
|
|
21990
|
-
const dLen =
|
|
22326
|
+
const dLen = delimiter2.length;
|
|
21991
22327
|
while (this.pos < len) {
|
|
21992
22328
|
let lineStart = this.pos;
|
|
21993
22329
|
let lineEnd = src.indexOf("\n", this.pos);
|
|
@@ -21997,12 +22333,12 @@ var Lexer = class {
|
|
|
21997
22333
|
while (lineStart < lineEnd && src.charCodeAt(lineStart) === CH_TAB)
|
|
21998
22334
|
lineStart++;
|
|
21999
22335
|
}
|
|
22000
|
-
if (lineEnd - lineStart === dLen && src.startsWith(
|
|
22336
|
+
if (lineEnd - lineStart === dLen && src.startsWith(delimiter2, lineStart)) {
|
|
22001
22337
|
const bodyEnd = this.pos;
|
|
22002
22338
|
this.pos = lineEnd < len ? lineEnd + 1 : lineEnd;
|
|
22003
22339
|
return bodyEnd;
|
|
22004
22340
|
}
|
|
22005
|
-
if (parenEnds && lineEnd - lineStart > dLen && src.charCodeAt(lineStart + dLen) === CH_RPAREN && src.startsWith(
|
|
22341
|
+
if (parenEnds && lineEnd - lineStart > dLen && src.charCodeAt(lineStart + dLen) === CH_RPAREN && src.startsWith(delimiter2, lineStart)) {
|
|
22006
22342
|
const bodyEnd = this.pos;
|
|
22007
22343
|
this.pos = lineStart + dLen;
|
|
22008
22344
|
return bodyEnd;
|
|
@@ -24714,7 +25050,7 @@ function safeSedProgram(program) {
|
|
|
24714
25050
|
return true;
|
|
24715
25051
|
const match = /^(?:(?:\d+|\$)(?:,(?:\d+|\$))?)?s(.)(.*)$/s.exec(program);
|
|
24716
25052
|
if (!match || /[\\\nA-Za-z0-9]/.test(match[1])) return false;
|
|
24717
|
-
const
|
|
25053
|
+
const delimiter2 = match[1];
|
|
24718
25054
|
const tail = match[2];
|
|
24719
25055
|
let offset = 0;
|
|
24720
25056
|
for (let section = 0; section < 2; section += 1) {
|
|
@@ -24722,7 +25058,7 @@ function safeSedProgram(program) {
|
|
|
24722
25058
|
while (offset < tail.length) {
|
|
24723
25059
|
if (tail[offset] === "\\") {
|
|
24724
25060
|
offset += 2;
|
|
24725
|
-
} else if (tail[offset] ===
|
|
25061
|
+
} else if (tail[offset] === delimiter2) {
|
|
24726
25062
|
offset += 1;
|
|
24727
25063
|
closed = true;
|
|
24728
25064
|
break;
|
|
@@ -25078,7 +25414,8 @@ function preserveHookFileMetadata(payload, resolution) {
|
|
|
25078
25414
|
return { ...payload, primitive };
|
|
25079
25415
|
}
|
|
25080
25416
|
function resolveHookFileRefs(args) {
|
|
25081
|
-
const
|
|
25417
|
+
const isShellTool = (args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash" || args.agent === "cursor" && args.toolName === "Shell";
|
|
25418
|
+
const command = isShellTool ? typeof args.toolInput === "string" ? args.toolInput : args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.command === "string" ? args.toolInput.command : void 0 : void 0;
|
|
25082
25419
|
const shell = command === void 0 ? void 0 : analyzeShellTargets(command);
|
|
25083
25420
|
const shellMutation = shell?.mutation === "none" ? "none" : shell?.coverage === "complete" ? "resolved" : shell ? "unresolved" : void 0;
|
|
25084
25421
|
const readPath = args.agent === "claude_code" && args.toolName === "Read" && args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.file_path === "string" ? [args.toolInput.file_path] : void 0;
|
|
@@ -25123,8 +25460,41 @@ function enrichHookPayloadWithFileRefs(args) {
|
|
|
25123
25460
|
};
|
|
25124
25461
|
}
|
|
25125
25462
|
|
|
25463
|
+
// src/hooks/hook-stdin.ts
|
|
25464
|
+
var DEFAULT_MAX_BYTES = 1024 * 1024;
|
|
25465
|
+
function readHookStdin(timeoutMs = 1e3, maxBytes = DEFAULT_MAX_BYTES) {
|
|
25466
|
+
return new Promise((resolve6, reject) => {
|
|
25467
|
+
const chunks = [];
|
|
25468
|
+
let bytes = 0;
|
|
25469
|
+
let settled = false;
|
|
25470
|
+
const finish2 = (error) => {
|
|
25471
|
+
if (settled) return;
|
|
25472
|
+
settled = true;
|
|
25473
|
+
clearTimeout(timer);
|
|
25474
|
+
process.stdin.removeAllListeners("data");
|
|
25475
|
+
process.stdin.removeAllListeners("end");
|
|
25476
|
+
process.stdin.removeAllListeners("error");
|
|
25477
|
+
if (error) reject(error);
|
|
25478
|
+
else resolve6(Buffer.concat(chunks, bytes).toString("utf-8"));
|
|
25479
|
+
};
|
|
25480
|
+
const timer = setTimeout(() => finish2(new Error("stdin read timeout")), timeoutMs);
|
|
25481
|
+
process.stdin.on("data", (chunk) => {
|
|
25482
|
+
bytes += chunk.length;
|
|
25483
|
+
if (bytes > maxBytes) {
|
|
25484
|
+
finish2(new Error("stdin envelope exceeds size limit"));
|
|
25485
|
+
return;
|
|
25486
|
+
}
|
|
25487
|
+
chunks.push(chunk);
|
|
25488
|
+
});
|
|
25489
|
+
process.stdin.on("end", () => finish2());
|
|
25490
|
+
process.stdin.on("error", (error) => finish2(error));
|
|
25491
|
+
});
|
|
25492
|
+
}
|
|
25493
|
+
|
|
25126
25494
|
// src/hooks/normalize.ts
|
|
25127
|
-
import { createHash as
|
|
25495
|
+
import { createHash as createHash7 } from "crypto";
|
|
25496
|
+
import { realpathSync as realpathSync3 } from "fs";
|
|
25497
|
+
import { isAbsolute as isAbsolute8, resolve as resolve5 } from "path";
|
|
25128
25498
|
var HERMES_EVENT_MAP = {
|
|
25129
25499
|
on_session_start: "SessionStart",
|
|
25130
25500
|
on_session_end: "SessionEnd",
|
|
@@ -25134,7 +25504,125 @@ var HERMES_EVENT_MAP = {
|
|
|
25134
25504
|
post_tool_call: "PostToolUse",
|
|
25135
25505
|
subagent_stop: "SubagentStop"
|
|
25136
25506
|
};
|
|
25507
|
+
var CURSOR_EVENT_MAP = {
|
|
25508
|
+
sessionStart: "SessionStart",
|
|
25509
|
+
beforeSubmitPrompt: "UserPromptSubmit",
|
|
25510
|
+
preToolUse: "PreToolUse",
|
|
25511
|
+
postToolUse: "PostToolUse",
|
|
25512
|
+
postToolUseFailure: "PostToolUseFailure",
|
|
25513
|
+
afterAgentResponse: "AssistantResponse",
|
|
25514
|
+
subagentStop: "SubagentStop",
|
|
25515
|
+
stop: "Stop",
|
|
25516
|
+
sessionEnd: "SessionEnd"
|
|
25517
|
+
};
|
|
25518
|
+
var CURSOR_TOOL_EVENTS = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse", "PostToolUseFailure"]);
|
|
25519
|
+
var SAFE_CORRELATION_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/u;
|
|
25520
|
+
var CURSOR_LOCAL_ONLY_FIELDS = /* @__PURE__ */ new Set([
|
|
25521
|
+
"conversation_id",
|
|
25522
|
+
"generation_id",
|
|
25523
|
+
"user_email",
|
|
25524
|
+
"account_email",
|
|
25525
|
+
"transcript_path",
|
|
25526
|
+
"transcript",
|
|
25527
|
+
"thought",
|
|
25528
|
+
"thoughts",
|
|
25529
|
+
"thinking",
|
|
25530
|
+
"tool_output"
|
|
25531
|
+
]);
|
|
25532
|
+
function requiredId(value, field) {
|
|
25533
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
25534
|
+
throw new TypeError(`Cursor hook envelope is missing ${field}`);
|
|
25535
|
+
}
|
|
25536
|
+
return value;
|
|
25537
|
+
}
|
|
25538
|
+
function cursorToolUseId(value) {
|
|
25539
|
+
if (SAFE_CORRELATION_ID_RE.test(value)) return value;
|
|
25540
|
+
return `cursor:tool:v1:${createHash7("sha256").update(value).digest("hex")}`;
|
|
25541
|
+
}
|
|
25542
|
+
function workspaceCandidates(value) {
|
|
25543
|
+
if (!Array.isArray(value)) return [];
|
|
25544
|
+
const roots = value.filter((item) => typeof item === "string" && item.length > 0);
|
|
25545
|
+
if (roots.some((root) => !isAbsolute8(root))) {
|
|
25546
|
+
throw new TypeError("Cursor workspace roots must be absolute");
|
|
25547
|
+
}
|
|
25548
|
+
return roots;
|
|
25549
|
+
}
|
|
25550
|
+
function pathIdentity(path) {
|
|
25551
|
+
try {
|
|
25552
|
+
return realpathSync3.native(path);
|
|
25553
|
+
} catch {
|
|
25554
|
+
return resolve5(path);
|
|
25555
|
+
}
|
|
25556
|
+
}
|
|
25557
|
+
function resolveCursorCwd(parsed) {
|
|
25558
|
+
const roots = workspaceCandidates(parsed.workspace_roots).map(pathIdentity);
|
|
25559
|
+
const rootRepositories = roots.map((root) => resolveRepositoryContext(root)?.repoRoot);
|
|
25560
|
+
const repositoryRoots = new Set(rootRepositories.filter((root) => !!root));
|
|
25561
|
+
if (repositoryRoots.size > 1) {
|
|
25562
|
+
throw new TypeError("Cursor hook envelope spans multiple repositories");
|
|
25563
|
+
}
|
|
25564
|
+
if (roots.length > 1 && rootRepositories.some((root) => root === void 0)) {
|
|
25565
|
+
throw new TypeError("Cursor hook envelope has ambiguous workspace roots");
|
|
25566
|
+
}
|
|
25567
|
+
const expectedRepo = [...repositoryRoots][0];
|
|
25568
|
+
const rawCwd = typeof parsed.cwd === "string" && parsed.cwd.length > 0 ? parsed.cwd : void 0;
|
|
25569
|
+
if (rawCwd && !isAbsolute8(rawCwd)) {
|
|
25570
|
+
throw new TypeError("Cursor hook cwd must be absolute");
|
|
25571
|
+
}
|
|
25572
|
+
const envelopeCwd = rawCwd ? pathIdentity(rawCwd) : void 0;
|
|
25573
|
+
const input = typeof parsed.tool_input === "object" && parsed.tool_input !== null && !Array.isArray(parsed.tool_input) ? parsed.tool_input : void 0;
|
|
25574
|
+
const rawToolCwd = parsed.tool_name === "Shell" && typeof input?.working_directory === "string" ? input.working_directory : void 0;
|
|
25575
|
+
const base = envelopeCwd ?? (roots.length === 1 ? roots[0] : expectedRepo);
|
|
25576
|
+
if (rawToolCwd && !isAbsolute8(rawToolCwd) && !base) {
|
|
25577
|
+
throw new TypeError("relative Cursor tool cwd has no workspace base");
|
|
25578
|
+
}
|
|
25579
|
+
const toolCwd = rawToolCwd ? pathIdentity(isAbsolute8(rawToolCwd) ? rawToolCwd : resolve5(base, rawToolCwd)) : void 0;
|
|
25580
|
+
const selected = toolCwd ?? envelopeCwd ?? (roots.length === 1 ? roots[0] : expectedRepo);
|
|
25581
|
+
if (!selected) {
|
|
25582
|
+
throw new TypeError("Cursor hook envelope has no unambiguous workspace");
|
|
25583
|
+
}
|
|
25584
|
+
const selectedRepo = resolveRepositoryContext(selected)?.repoRoot;
|
|
25585
|
+
if (expectedRepo && selectedRepo !== expectedRepo) {
|
|
25586
|
+
throw new TypeError("Cursor hook cwd conflicts with workspace repository");
|
|
25587
|
+
}
|
|
25588
|
+
return selected;
|
|
25589
|
+
}
|
|
25590
|
+
function normalizeCursorEnvelope(parsed) {
|
|
25591
|
+
const rawEvent = requiredId(parsed.hook_event_name, "hook_event_name");
|
|
25592
|
+
const event = CURSOR_EVENT_MAP[rawEvent];
|
|
25593
|
+
if (!event) throw new TypeError(`unsupported Cursor hook event: ${rawEvent}`);
|
|
25594
|
+
const sessionId = requiredId(parsed.conversation_id, "conversation_id");
|
|
25595
|
+
const turnId = requiredId(parsed.generation_id, "generation_id");
|
|
25596
|
+
if (parsed.session_id !== void 0 && parsed.session_id !== sessionId) {
|
|
25597
|
+
throw new TypeError("Cursor conversation_id conflicts with session_id");
|
|
25598
|
+
}
|
|
25599
|
+
if (parsed.turn_id !== void 0 && parsed.turn_id !== turnId) {
|
|
25600
|
+
throw new TypeError("Cursor generation_id conflicts with turn_id");
|
|
25601
|
+
}
|
|
25602
|
+
const rawToolUseId = CURSOR_TOOL_EVENTS.has(event) ? requiredId(parsed.tool_use_id, "tool_use_id") : void 0;
|
|
25603
|
+
const normalized = {
|
|
25604
|
+
...Object.fromEntries(
|
|
25605
|
+
Object.entries(parsed).filter(([key]) => !CURSOR_LOCAL_ONLY_FIELDS.has(key))
|
|
25606
|
+
),
|
|
25607
|
+
hook_event_name: event,
|
|
25608
|
+
session_id: sessionId,
|
|
25609
|
+
turn_id: turnId,
|
|
25610
|
+
cwd: resolveCursorCwd(parsed),
|
|
25611
|
+
...rawToolUseId === void 0 ? {} : { tool_use_id: cursorToolUseId(rawToolUseId) }
|
|
25612
|
+
};
|
|
25613
|
+
if (typeof parsed.tool_output === "string") {
|
|
25614
|
+
try {
|
|
25615
|
+
normalized.tool_response = JSON.parse(parsed.tool_output);
|
|
25616
|
+
} catch {
|
|
25617
|
+
normalized.tool_response = parsed.tool_output;
|
|
25618
|
+
}
|
|
25619
|
+
}
|
|
25620
|
+
return normalized;
|
|
25621
|
+
}
|
|
25137
25622
|
function normalizeEnvelope(parsed, agent) {
|
|
25623
|
+
if (agent === "cursor") {
|
|
25624
|
+
return normalizeCursorEnvelope(parsed);
|
|
25625
|
+
}
|
|
25138
25626
|
if (agent === "codex") {
|
|
25139
25627
|
const event = parsed.hook_event_name;
|
|
25140
25628
|
if ((event === "PreToolUse" || event === "PostToolUse") && (typeof parsed.tool_use_id !== "string" || parsed.tool_use_id.length === 0)) {
|
|
@@ -25146,7 +25634,7 @@ function normalizeEnvelope(parsed, agent) {
|
|
|
25146
25634
|
]);
|
|
25147
25635
|
return {
|
|
25148
25636
|
...parsed,
|
|
25149
|
-
tool_use_id: `codex:fallback:v1:${
|
|
25637
|
+
tool_use_id: `codex:fallback:v1:${createHash7("sha256").update(stableToolIdentity).digest("hex")}`
|
|
25150
25638
|
};
|
|
25151
25639
|
}
|
|
25152
25640
|
return parsed;
|
|
@@ -25194,17 +25682,17 @@ function requireDurableIngestAcknowledgement(value, expected, cwd = process.cwd(
|
|
|
25194
25682
|
import {
|
|
25195
25683
|
appendFileSync,
|
|
25196
25684
|
closeSync as closeSync3,
|
|
25197
|
-
existsSync as
|
|
25685
|
+
existsSync as existsSync10,
|
|
25198
25686
|
fstatSync,
|
|
25199
|
-
mkdirSync as
|
|
25687
|
+
mkdirSync as mkdirSync7,
|
|
25200
25688
|
openSync as openSync3,
|
|
25201
25689
|
opendirSync,
|
|
25202
|
-
readFileSync as
|
|
25690
|
+
readFileSync as readFileSync12,
|
|
25203
25691
|
readSync,
|
|
25204
|
-
readdirSync as
|
|
25692
|
+
readdirSync as readdirSync3
|
|
25205
25693
|
} from "fs";
|
|
25206
|
-
import { dirname as
|
|
25207
|
-
var JOURNAL_DIR =
|
|
25694
|
+
import { dirname as dirname10, join as join14 } from "path";
|
|
25695
|
+
var JOURNAL_DIR = join14(primConfigDirectory(), "moves");
|
|
25208
25696
|
var UNBOUND_BUCKET = "_unbound";
|
|
25209
25697
|
var JOURNAL_BASENAME = "journal.ndjson";
|
|
25210
25698
|
var JOURNAL_STATS_SAMPLE_BYTES = 64 * 1024;
|
|
@@ -25216,26 +25704,26 @@ function envSlug(apiUrl) {
|
|
|
25216
25704
|
return slug;
|
|
25217
25705
|
}
|
|
25218
25706
|
function currentEnvDir() {
|
|
25219
|
-
return
|
|
25707
|
+
return join14(JOURNAL_DIR, envSlug(getSiteUrl()));
|
|
25220
25708
|
}
|
|
25221
25709
|
var DIR_MODE = 448;
|
|
25222
25710
|
var FILE_MODE2 = 384;
|
|
25223
25711
|
var SAFE_BUCKET = /^[A-Za-z0-9_-]+$/;
|
|
25224
25712
|
var RESERVED_BUCKETS = /* @__PURE__ */ new Set([UNBOUND_BUCKET, "_legacy"]);
|
|
25225
25713
|
function appendMoveToPath(path, move) {
|
|
25226
|
-
const dir =
|
|
25227
|
-
if (!
|
|
25228
|
-
|
|
25714
|
+
const dir = dirname10(path);
|
|
25715
|
+
if (!existsSync10(dir)) {
|
|
25716
|
+
mkdirSync7(dir, { recursive: true, mode: DIR_MODE });
|
|
25229
25717
|
}
|
|
25230
25718
|
appendFileSync(path, `${JSON.stringify(move)}
|
|
25231
25719
|
`, { mode: FILE_MODE2 });
|
|
25232
25720
|
}
|
|
25233
25721
|
function bucketDir(orgId) {
|
|
25234
25722
|
const safe = orgId !== void 0 && SAFE_BUCKET.test(orgId) && !RESERVED_BUCKETS.has(orgId);
|
|
25235
|
-
return
|
|
25723
|
+
return join14(currentEnvDir(), safe ? orgId : UNBOUND_BUCKET);
|
|
25236
25724
|
}
|
|
25237
25725
|
function journalPath(orgId) {
|
|
25238
|
-
return
|
|
25726
|
+
return join14(bucketDir(orgId), JOURNAL_BASENAME);
|
|
25239
25727
|
}
|
|
25240
25728
|
function appendMove(move, orgId) {
|
|
25241
25729
|
appendMoveToPath(journalPath(orgId), move);
|
|
@@ -25255,15 +25743,15 @@ async function deliverPostToolMove(move, orgId) {
|
|
|
25255
25743
|
}
|
|
25256
25744
|
|
|
25257
25745
|
// src/hooks/prim-hook-core.ts
|
|
25258
|
-
import { createHash as
|
|
25746
|
+
import { createHash as createHash8, randomUUID as randomUUID3 } from "crypto";
|
|
25259
25747
|
import { platform } from "os";
|
|
25260
25748
|
|
|
25261
25749
|
// src/protocol/move.ts
|
|
25262
25750
|
var AGENT_ENVELOPE_VERSION = 3;
|
|
25263
25751
|
|
|
25264
25752
|
// src/hooks/redact.ts
|
|
25265
|
-
import { existsSync as
|
|
25266
|
-
import { join as
|
|
25753
|
+
import { existsSync as existsSync11, readFileSync as readFileSync13, statSync as statSync5 } from "fs";
|
|
25754
|
+
import { join as join15 } from "path";
|
|
25267
25755
|
import { Worker } from "worker_threads";
|
|
25268
25756
|
|
|
25269
25757
|
// src/lib/ansi.ts
|
|
@@ -25381,15 +25869,15 @@ function normalizedWorkspaceFlags(value) {
|
|
|
25381
25869
|
return [...new Set(`g${requested}`)].sort().join("");
|
|
25382
25870
|
}
|
|
25383
25871
|
function loadWorkspaceRules(cwd) {
|
|
25384
|
-
const path =
|
|
25385
|
-
if (!
|
|
25872
|
+
const path = join15(cwd, WORKSPACE_FILE2);
|
|
25873
|
+
if (!existsSync11(path)) return [];
|
|
25386
25874
|
let cfg;
|
|
25387
25875
|
try {
|
|
25388
|
-
if (
|
|
25876
|
+
if (statSync5(path).size > MAX_WORKSPACE_CONFIG_BYTES) {
|
|
25389
25877
|
debugRedaction(`ignoring oversized ${WORKSPACE_FILE2}`);
|
|
25390
25878
|
return [];
|
|
25391
25879
|
}
|
|
25392
|
-
cfg = JSON.parse(
|
|
25880
|
+
cfg = JSON.parse(readFileSync13(path, "utf-8"));
|
|
25393
25881
|
} catch {
|
|
25394
25882
|
debugRedaction(`ignoring unparseable ${WORKSPACE_FILE2}`);
|
|
25395
25883
|
return [];
|
|
@@ -25508,7 +25996,7 @@ function applyWorkspaceRules(value, rules) {
|
|
|
25508
25996
|
flags: pattern.flags,
|
|
25509
25997
|
reason
|
|
25510
25998
|
}));
|
|
25511
|
-
return new Promise((
|
|
25999
|
+
return new Promise((resolve6) => {
|
|
25512
26000
|
let worker;
|
|
25513
26001
|
try {
|
|
25514
26002
|
worker = new Worker(WORKSPACE_REDACTION_WORKER, {
|
|
@@ -25516,20 +26004,20 @@ function applyWorkspaceRules(value, rules) {
|
|
|
25516
26004
|
workerData: { value, rules: serialized }
|
|
25517
26005
|
});
|
|
25518
26006
|
} catch {
|
|
25519
|
-
|
|
26007
|
+
resolve6(redactEveryString(value, "workspace-rule-failed"));
|
|
25520
26008
|
return;
|
|
25521
26009
|
}
|
|
25522
26010
|
let settled = false;
|
|
25523
|
-
const
|
|
26011
|
+
const finish2 = (result) => {
|
|
25524
26012
|
if (settled) return;
|
|
25525
26013
|
settled = true;
|
|
25526
26014
|
clearTimeout(timer);
|
|
25527
26015
|
void worker.terminate();
|
|
25528
|
-
|
|
26016
|
+
resolve6(result);
|
|
25529
26017
|
};
|
|
25530
|
-
const failClosed = () =>
|
|
26018
|
+
const failClosed = () => finish2(redactEveryString(value, "workspace-rule-failed"));
|
|
25531
26019
|
const timer = setTimeout(failClosed, WORKSPACE_RULE_TIMEOUT_MS);
|
|
25532
|
-
worker.once("message",
|
|
26020
|
+
worker.once("message", finish2);
|
|
25533
26021
|
worker.once("error", failClosed);
|
|
25534
26022
|
worker.once("exit", (code) => {
|
|
25535
26023
|
if (code !== 0) failClosed();
|
|
@@ -25579,6 +26067,17 @@ function toolOutcomeFor(parsed, agent) {
|
|
|
25579
26067
|
if (agent === "codex") {
|
|
25580
26068
|
return event === "PostToolUse" ? "returned" : void 0;
|
|
25581
26069
|
}
|
|
26070
|
+
if (agent === "cursor") {
|
|
26071
|
+
if (event === "PostToolUse") return "succeeded";
|
|
26072
|
+
if (event === "PostToolUseFailure") {
|
|
26073
|
+
if (parsed.is_interrupt === true) return "interrupted";
|
|
26074
|
+
const failureType = lowerString(parsed.failure_type);
|
|
26075
|
+
if (failureType === "permission_denied") return "prevented";
|
|
26076
|
+
if (failureType === "error" || failureType === "timeout") return "failed";
|
|
26077
|
+
return "unknown";
|
|
26078
|
+
}
|
|
26079
|
+
return void 0;
|
|
26080
|
+
}
|
|
25582
26081
|
const extra = parsed.extra;
|
|
25583
26082
|
if (event === "post_approval_response") {
|
|
25584
26083
|
const choice = lowerString(extra?.choice);
|
|
@@ -25608,9 +26107,9 @@ function toMove(parsed, cliVersion, agent = "claude_code", workspaceId, reposito
|
|
|
25608
26107
|
const toolOutcome = toolOutcomeFor(parsed, agent);
|
|
25609
26108
|
let moveId;
|
|
25610
26109
|
if (CORRELATED_TOOL_EVENTS.has(eventType) && sessionId && invocationId) {
|
|
25611
|
-
moveId = `posttool:v1:${
|
|
25612
|
-
} else if (CORRELATED_TOOL_EVENTS.has(eventType) && sessionId) {
|
|
25613
|
-
moveId = `posttool:fallback:v1:${
|
|
26110
|
+
moveId = `posttool:v1:${createHash8("sha256").update(JSON.stringify([agent, sessionId, eventType, invocationId])).digest("hex")}`;
|
|
26111
|
+
} else if (CORRELATED_TOOL_EVENTS.has(eventType) && sessionId && agent !== "cursor") {
|
|
26112
|
+
moveId = `posttool:fallback:v1:${createHash8("sha256").update(
|
|
25614
26113
|
JSON.stringify([
|
|
25615
26114
|
agent,
|
|
25616
26115
|
sessionId,
|
|
@@ -25670,6 +26169,7 @@ var STDIN_TIMEOUT_MS = 1e3;
|
|
|
25670
26169
|
var EDITING_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit", "Bash"]);
|
|
25671
26170
|
var CODEX_EDITING_TOOLS = /* @__PURE__ */ new Set(["apply_patch", "Bash"]);
|
|
25672
26171
|
var HERMES_EDITING_TOOLS2 = /* @__PURE__ */ new Set(["write_file", "patch"]);
|
|
26172
|
+
var CURSOR_EDITING_TOOLS = /* @__PURE__ */ new Set(["Write", "Delete", "Shell"]);
|
|
25673
26173
|
function editingToolsFor(agent) {
|
|
25674
26174
|
if (agent === "codex") {
|
|
25675
26175
|
return CODEX_EDITING_TOOLS;
|
|
@@ -25677,41 +26177,27 @@ function editingToolsFor(agent) {
|
|
|
25677
26177
|
if (agent === "hermes") {
|
|
25678
26178
|
return HERMES_EDITING_TOOLS2;
|
|
25679
26179
|
}
|
|
26180
|
+
if (agent === "cursor") {
|
|
26181
|
+
return CURSOR_EDITING_TOOLS;
|
|
26182
|
+
}
|
|
25680
26183
|
return EDITING_TOOLS;
|
|
25681
26184
|
}
|
|
25682
|
-
var here =
|
|
26185
|
+
var here = dirname11(fileURLToPath2(import.meta.url));
|
|
25683
26186
|
function resolveCliVersion() {
|
|
25684
26187
|
try {
|
|
25685
|
-
const pkg = JSON.parse(
|
|
26188
|
+
const pkg = JSON.parse(readFileSync14(join16(here, "..", "..", "package.json"), "utf-8"));
|
|
25686
26189
|
return pkg.version ?? "unknown";
|
|
25687
26190
|
} catch {
|
|
25688
26191
|
return "unknown";
|
|
25689
26192
|
}
|
|
25690
26193
|
}
|
|
25691
|
-
function readStdin() {
|
|
25692
|
-
return new Promise((resolve4, reject) => {
|
|
25693
|
-
const chunks = [];
|
|
25694
|
-
const timer = setTimeout(() => {
|
|
25695
|
-
reject(new Error("stdin read timeout"));
|
|
25696
|
-
}, STDIN_TIMEOUT_MS);
|
|
25697
|
-
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
25698
|
-
process.stdin.on("end", () => {
|
|
25699
|
-
clearTimeout(timer);
|
|
25700
|
-
resolve4(Buffer.concat(chunks).toString("utf-8"));
|
|
25701
|
-
});
|
|
25702
|
-
process.stdin.on("error", (err) => {
|
|
25703
|
-
clearTimeout(timer);
|
|
25704
|
-
reject(err);
|
|
25705
|
-
});
|
|
25706
|
-
});
|
|
25707
|
-
}
|
|
25708
26194
|
async function emit(output = {}) {
|
|
25709
|
-
return await new Promise((
|
|
26195
|
+
return await new Promise((resolve6) => {
|
|
25710
26196
|
try {
|
|
25711
26197
|
process.stdout.write(`${JSON.stringify(output)}
|
|
25712
|
-
`, (error) =>
|
|
26198
|
+
`, (error) => resolve6(!error));
|
|
25713
26199
|
} catch {
|
|
25714
|
-
|
|
26200
|
+
resolve6(false);
|
|
25715
26201
|
}
|
|
25716
26202
|
});
|
|
25717
26203
|
}
|
|
@@ -25719,6 +26205,30 @@ async function emitWithAcknowledgment(output, acknowledge) {
|
|
|
25719
26205
|
const handedOff = await emit(output);
|
|
25720
26206
|
await acknowledge?.(handedOff);
|
|
25721
26207
|
}
|
|
26208
|
+
async function emitCursorContext(envelope) {
|
|
26209
|
+
if (typeof envelope.session_id !== "string" || envelope.session_id.length === 0 || typeof envelope.cwd !== "string" || envelope.cwd.length === 0) {
|
|
26210
|
+
await emit();
|
|
26211
|
+
return;
|
|
26212
|
+
}
|
|
26213
|
+
try {
|
|
26214
|
+
const context = await prepareCodexContext({
|
|
26215
|
+
cwd: envelope.cwd,
|
|
26216
|
+
sessionId: envelope.session_id,
|
|
26217
|
+
includeDigest: true,
|
|
26218
|
+
namespace: "cursor"
|
|
26219
|
+
});
|
|
26220
|
+
await emitWithAcknowledgment(
|
|
26221
|
+
context.context ? { additional_context: context.context } : {},
|
|
26222
|
+
context.acknowledge
|
|
26223
|
+
);
|
|
26224
|
+
} catch {
|
|
26225
|
+
await emit();
|
|
26226
|
+
}
|
|
26227
|
+
}
|
|
26228
|
+
async function finish(agent, envelope) {
|
|
26229
|
+
if (agent === "cursor" && envelope) await emitCursorContext(envelope);
|
|
26230
|
+
else await emit();
|
|
26231
|
+
}
|
|
25722
26232
|
function debug(msg) {
|
|
25723
26233
|
if (process.env.PRIM_HOOK_VERBOSE === "1") {
|
|
25724
26234
|
process.stderr.write(`[prim-post-tool-use] ${msg}
|
|
@@ -25729,33 +26239,38 @@ async function main() {
|
|
|
25729
26239
|
const agent = parseAgent(process.argv);
|
|
25730
26240
|
let raw;
|
|
25731
26241
|
try {
|
|
25732
|
-
raw = await
|
|
26242
|
+
raw = await readHookStdin(STDIN_TIMEOUT_MS);
|
|
25733
26243
|
} catch {
|
|
25734
26244
|
await emit();
|
|
25735
26245
|
return;
|
|
25736
26246
|
}
|
|
25737
26247
|
let parsed;
|
|
25738
26248
|
try {
|
|
25739
|
-
|
|
26249
|
+
const incoming = JSON.parse(raw);
|
|
26250
|
+
if (agent !== "cursor" && shouldSuppressImportedCursorHandler(incoming, "prim-post-tool-use")) {
|
|
26251
|
+
await emit();
|
|
26252
|
+
return;
|
|
26253
|
+
}
|
|
26254
|
+
parsed = normalizeEnvelope(incoming, agent);
|
|
25740
26255
|
} catch {
|
|
25741
26256
|
await emit();
|
|
25742
26257
|
return;
|
|
25743
26258
|
}
|
|
25744
26259
|
let envelope = parsed;
|
|
25745
|
-
const isToolResult = envelope.hook_event_name === "PostToolUse" || agent === "claude_code" && envelope.hook_event_name === "PostToolUseFailure";
|
|
26260
|
+
const isToolResult = envelope.hook_event_name === "PostToolUse" || (agent === "claude_code" || agent === "cursor") && envelope.hook_event_name === "PostToolUseFailure";
|
|
25746
26261
|
const isHermesDenial = agent === "hermes" && envelope.hook_event_name === "post_approval_response" && toolOutcomeFor(parsed, agent) === "prevented";
|
|
25747
26262
|
if (!isToolResult && !isHermesDenial) {
|
|
25748
|
-
await
|
|
26263
|
+
await finish(agent, envelope);
|
|
25749
26264
|
return;
|
|
25750
26265
|
}
|
|
25751
26266
|
const invocationId = postToolInvocationId(parsed, agent);
|
|
25752
26267
|
if (isHermesDenial && !invocationId) {
|
|
25753
|
-
await
|
|
26268
|
+
await finish(agent, envelope);
|
|
25754
26269
|
return;
|
|
25755
26270
|
}
|
|
25756
26271
|
const toolName = typeof envelope.tool_name === "string" ? envelope.tool_name : "";
|
|
25757
26272
|
if (!isHermesDenial && !editingToolsFor(agent).has(toolName)) {
|
|
25758
|
-
await
|
|
26273
|
+
await finish(agent, envelope);
|
|
25759
26274
|
return;
|
|
25760
26275
|
}
|
|
25761
26276
|
if (isHermesDenial && (typeof envelope.session_id !== "string" || envelope.session_id.length === 0) && typeof envelope.extra?.session_key === "string" && envelope.extra.session_key.length > 0) {
|
|
@@ -25763,17 +26278,17 @@ async function main() {
|
|
|
25763
26278
|
envelope = parsed;
|
|
25764
26279
|
}
|
|
25765
26280
|
if (typeof envelope.session_id !== "string" || envelope.session_id.length === 0) {
|
|
25766
|
-
await
|
|
26281
|
+
await finish(agent, envelope);
|
|
25767
26282
|
return;
|
|
25768
26283
|
}
|
|
25769
26284
|
const cwd = parsed.cwd ?? process.cwd();
|
|
25770
26285
|
if (!isRepoActiveForCapture(cwd)) {
|
|
25771
|
-
await
|
|
26286
|
+
await finish(agent, envelope);
|
|
25772
26287
|
return;
|
|
25773
26288
|
}
|
|
25774
26289
|
const resolvedRepository = resolveRepositoryContext(cwd);
|
|
25775
26290
|
if (!resolvedRepository) {
|
|
25776
|
-
await
|
|
26291
|
+
await finish(agent, envelope);
|
|
25777
26292
|
return;
|
|
25778
26293
|
}
|
|
25779
26294
|
const repository = { ...resolvedRepository, repoSyncId: repoSyncId(cwd) };
|
|
@@ -25786,23 +26301,27 @@ async function main() {
|
|
|
25786
26301
|
const { resolution } = enrichment;
|
|
25787
26302
|
if (!isHermesDenial) {
|
|
25788
26303
|
if (resolution.shellMutation === "none") {
|
|
25789
|
-
await
|
|
26304
|
+
await finish(agent, envelope);
|
|
25790
26305
|
return;
|
|
25791
26306
|
}
|
|
25792
26307
|
if (resolution.shellMutation === void 0 && resolution.fileRefs.length === 0) {
|
|
25793
|
-
await
|
|
26308
|
+
await finish(agent, envelope);
|
|
25794
26309
|
return;
|
|
25795
26310
|
}
|
|
25796
26311
|
}
|
|
25797
26312
|
const pathsComplete = !resolution.targetsIncomplete && !resolution.targetsTruncated && resolution.rejected.length === 0 && resolution.shellMutation !== "unresolved";
|
|
25798
26313
|
const hasPathEvidence = resolution.fileRefs.length > 0 || resolution.rejected.length > 0 || resolution.targetsIncomplete || resolution.targetsTruncated || resolution.shellMutation === "unresolved";
|
|
26314
|
+
if (agent === "cursor" && (resolution.rejected.length > 0 || resolution.targetsIncomplete || resolution.targetsTruncated || resolution.shellMutation === "unresolved")) {
|
|
26315
|
+
await finish(agent, envelope);
|
|
26316
|
+
return;
|
|
26317
|
+
}
|
|
25799
26318
|
if (!cachedCollectScopeAdmits(cwd, {
|
|
25800
26319
|
repository: resolvedRepository.repoFullName,
|
|
25801
26320
|
branch: currentBranch(cwd),
|
|
25802
26321
|
agent,
|
|
25803
26322
|
...isHermesDenial || !hasPathEvidence ? {} : { paths: resolution.fileRefs, pathsComplete }
|
|
25804
26323
|
})) {
|
|
25805
|
-
await
|
|
26324
|
+
await finish(agent, envelope);
|
|
25806
26325
|
return;
|
|
25807
26326
|
}
|
|
25808
26327
|
const enriched = enrichment.parsed;
|
|
@@ -25839,7 +26358,7 @@ async function main() {
|
|
|
25839
26358
|
} catch {
|
|
25840
26359
|
}
|
|
25841
26360
|
}
|
|
25842
|
-
await
|
|
26361
|
+
await finish(agent, envelope);
|
|
25843
26362
|
}
|
|
25844
26363
|
main().catch(async () => {
|
|
25845
26364
|
await emit();
|