@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
|
@@ -53,8 +53,8 @@ var require_ucs2length = __commonJS({
|
|
|
53
53
|
|
|
54
54
|
// src/hooks/prim-hook.ts
|
|
55
55
|
import { spawn } from "child_process";
|
|
56
|
-
import { readFileSync as
|
|
57
|
-
import { dirname as
|
|
56
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
57
|
+
import { dirname as dirname11, join as join16 } from "path";
|
|
58
58
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
59
59
|
|
|
60
60
|
// src/binding.ts
|
|
@@ -613,14 +613,14 @@ function throwIfAborted(signal) {
|
|
|
613
613
|
}
|
|
614
614
|
async function defaultSleep(ms, signal) {
|
|
615
615
|
if (!signal) {
|
|
616
|
-
await new Promise((
|
|
616
|
+
await new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
617
617
|
return;
|
|
618
618
|
}
|
|
619
619
|
throwIfAborted(signal);
|
|
620
|
-
await new Promise((
|
|
620
|
+
await new Promise((resolve6, reject) => {
|
|
621
621
|
const timer = setTimeout(() => {
|
|
622
622
|
signal.removeEventListener("abort", onAbort);
|
|
623
|
-
|
|
623
|
+
resolve6();
|
|
624
624
|
}, ms);
|
|
625
625
|
const onAbort = () => {
|
|
626
626
|
clearTimeout(timer);
|
|
@@ -1591,7 +1591,7 @@ var PRIM_REPO_SYNC_REPOSITORY_KEY = "prim.repoSyncRepository";
|
|
|
1591
1591
|
var PRIM_REPO_BINDING_STATE_KEY = "prim.repoBindingState";
|
|
1592
1592
|
var GIT_TIMEOUT_MS2 = 1e3;
|
|
1593
1593
|
var REPO_SYNC_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
1594
|
-
var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json"];
|
|
1594
|
+
var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json", ".cursor/hooks.json"];
|
|
1595
1595
|
var PRIM_HOOK_BINS = ["prim-hook", "prim-pre-tool-use", "prim-post-tool-use"];
|
|
1596
1596
|
function repoActiveFlag(cwd) {
|
|
1597
1597
|
try {
|
|
@@ -2486,7 +2486,7 @@ function validate23(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
2486
2486
|
return errors === 0;
|
|
2487
2487
|
}
|
|
2488
2488
|
validate23.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
2489
|
-
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": {} };
|
|
2489
|
+
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": {} };
|
|
2490
2490
|
function validate24(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
2491
2491
|
;
|
|
2492
2492
|
let vErrors = null;
|
|
@@ -3037,7 +3037,7 @@ function validate24(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
3037
3037
|
}
|
|
3038
3038
|
errors++;
|
|
3039
3039
|
}
|
|
3040
|
-
if (!(data18 === "claude_code" || data18 === "codex" || data18 === "hermes")) {
|
|
3040
|
+
if (!(data18 === "claude_code" || data18 === "codex" || data18 === "cursor" || data18 === "hermes")) {
|
|
3041
3041
|
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" };
|
|
3042
3042
|
if (vErrors === null) {
|
|
3043
3043
|
vErrors = [err34];
|
|
@@ -3806,7 +3806,7 @@ function validate26(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
3806
3806
|
return errors === 0;
|
|
3807
3807
|
}
|
|
3808
3808
|
validate26.evaluated = { "dynamicProps": true, "dynamicItems": false };
|
|
3809
|
-
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"] };
|
|
3809
|
+
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"] };
|
|
3810
3810
|
function validate27(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
3811
3811
|
;
|
|
3812
3812
|
let vErrors = null;
|
|
@@ -4510,7 +4510,7 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
4510
4510
|
}
|
|
4511
4511
|
errors++;
|
|
4512
4512
|
}
|
|
4513
|
-
if (!(data34 === "claude_code" || data34 === "codex" || data34 === "hermes")) {
|
|
4513
|
+
if (!(data34 === "claude_code" || data34 === "codex" || data34 === "cursor" || data34 === "hermes")) {
|
|
4514
4514
|
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" };
|
|
4515
4515
|
if (vErrors === null) {
|
|
4516
4516
|
vErrors = [err19];
|
|
@@ -4738,7 +4738,7 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
4738
4738
|
return errors === 0;
|
|
4739
4739
|
}
|
|
4740
4740
|
validate27.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
4741
|
-
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": {} };
|
|
4741
|
+
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": {} };
|
|
4742
4742
|
function validate28(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
4743
4743
|
;
|
|
4744
4744
|
let vErrors = null;
|
|
@@ -5274,7 +5274,7 @@ function validate28(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
5274
5274
|
}
|
|
5275
5275
|
errors++;
|
|
5276
5276
|
}
|
|
5277
|
-
if (!(data22 === "claude_code" || data22 === "codex" || data22 === "hermes")) {
|
|
5277
|
+
if (!(data22 === "claude_code" || data22 === "codex" || data22 === "cursor" || data22 === "hermes")) {
|
|
5278
5278
|
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" };
|
|
5279
5279
|
if (vErrors === null) {
|
|
5280
5280
|
vErrors = [err19];
|
|
@@ -5506,7 +5506,7 @@ function validate28(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
5506
5506
|
return errors === 0;
|
|
5507
5507
|
}
|
|
5508
5508
|
validate28.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
5509
|
-
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": {} };
|
|
5509
|
+
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": {} };
|
|
5510
5510
|
function validate29(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
5511
5511
|
;
|
|
5512
5512
|
let vErrors = null;
|
|
@@ -6800,7 +6800,7 @@ function validate29(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
6800
6800
|
}
|
|
6801
6801
|
errors++;
|
|
6802
6802
|
}
|
|
6803
|
-
if (!(data70 === "claude_code" || data70 === "codex" || data70 === "hermes")) {
|
|
6803
|
+
if (!(data70 === "claude_code" || data70 === "codex" || data70 === "cursor" || data70 === "hermes")) {
|
|
6804
6804
|
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" };
|
|
6805
6805
|
if (vErrors === null) {
|
|
6806
6806
|
vErrors = [err24];
|
|
@@ -7361,7 +7361,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
7361
7361
|
return errors === 0;
|
|
7362
7362
|
}
|
|
7363
7363
|
validate33.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
7364
|
-
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": {} };
|
|
7364
|
+
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": {} };
|
|
7365
7365
|
function validate34(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
7366
7366
|
;
|
|
7367
7367
|
let vErrors = null;
|
|
@@ -8002,7 +8002,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
8002
8002
|
}
|
|
8003
8003
|
errors++;
|
|
8004
8004
|
}
|
|
8005
|
-
if (!(data19 === "claude_code" || data19 === "codex" || data19 === "hermes")) {
|
|
8005
|
+
if (!(data19 === "claude_code" || data19 === "codex" || data19 === "cursor" || data19 === "hermes")) {
|
|
8006
8006
|
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" };
|
|
8007
8007
|
if (vErrors === null) {
|
|
8008
8008
|
vErrors = [err38];
|
|
@@ -8230,7 +8230,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
8230
8230
|
return errors === 0;
|
|
8231
8231
|
}
|
|
8232
8232
|
validate34.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
8233
|
-
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": {} }] };
|
|
8233
|
+
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": {} }] };
|
|
8234
8234
|
function validate35(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
8235
8235
|
;
|
|
8236
8236
|
let vErrors = null;
|
|
@@ -8868,7 +8868,7 @@ function validate35(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
8868
8868
|
}
|
|
8869
8869
|
errors++;
|
|
8870
8870
|
}
|
|
8871
|
-
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "hermes")) {
|
|
8871
|
+
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "cursor" || data21 === "hermes")) {
|
|
8872
8872
|
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" };
|
|
8873
8873
|
if (vErrors === null) {
|
|
8874
8874
|
vErrors = [err41];
|
|
@@ -9792,7 +9792,7 @@ function validate35(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
9792
9792
|
}
|
|
9793
9793
|
errors++;
|
|
9794
9794
|
}
|
|
9795
|
-
if (!(data49 === "claude_code" || data49 === "codex" || data49 === "hermes")) {
|
|
9795
|
+
if (!(data49 === "claude_code" || data49 === "codex" || data49 === "cursor" || data49 === "hermes")) {
|
|
9796
9796
|
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" };
|
|
9797
9797
|
if (vErrors === null) {
|
|
9798
9798
|
vErrors = [err100];
|
|
@@ -15438,7 +15438,7 @@ function validate50(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
15438
15438
|
return errors === 0;
|
|
15439
15439
|
}
|
|
15440
15440
|
validate50.evaluated = { "dynamicProps": true, "dynamicItems": false };
|
|
15441
|
-
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": {} };
|
|
15441
|
+
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": {} };
|
|
15442
15442
|
var pattern8 = new RegExp("^[A-Za-z0-9_-]+$", "u");
|
|
15443
15443
|
function validate51(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
15444
15444
|
;
|
|
@@ -15692,7 +15692,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
15692
15692
|
}
|
|
15693
15693
|
errors++;
|
|
15694
15694
|
}
|
|
15695
|
-
if (!(data10 === "claude_code" || data10 === "codex" || data10 === "hermes")) {
|
|
15695
|
+
if (!(data10 === "claude_code" || data10 === "codex" || data10 === "cursor" || data10 === "hermes")) {
|
|
15696
15696
|
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" };
|
|
15697
15697
|
if (vErrors === null) {
|
|
15698
15698
|
vErrors = [err16];
|
|
@@ -16004,7 +16004,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
16004
16004
|
}
|
|
16005
16005
|
errors++;
|
|
16006
16006
|
}
|
|
16007
|
-
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "hermes")) {
|
|
16007
|
+
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "cursor" || data21 === "hermes")) {
|
|
16008
16008
|
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" };
|
|
16009
16009
|
if (vErrors === null) {
|
|
16010
16010
|
vErrors = [err38];
|
|
@@ -16141,7 +16141,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
16141
16141
|
return errors === 0;
|
|
16142
16142
|
}
|
|
16143
16143
|
validate51.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
16144
|
-
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"] };
|
|
16144
|
+
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"] };
|
|
16145
16145
|
var pattern10 = new RegExp("^[A-Za-z0-9._:-]{1,128}$", "u");
|
|
16146
16146
|
var pattern12 = new RegExp("^[A-Za-z0-9]{1,64}$", "u");
|
|
16147
16147
|
var pattern13 = new RegExp("^(?!@?$)(?!\\/)(?!.*\\/$)(?!.*\\/\\/)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)[^/]*\\.lock(?:\\/|$))(?!.*\\.\\.)(?!.*@\\{)(?!.*[~^:?*\\\\]).+$", "u");
|
|
@@ -16197,7 +16197,7 @@ function validate52(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
16197
16197
|
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" }];
|
|
16198
16198
|
return false;
|
|
16199
16199
|
}
|
|
16200
|
-
if (!(data1 === "claude_code" || data1 === "codex" || data1 === "hermes")) {
|
|
16200
|
+
if (!(data1 === "claude_code" || data1 === "codex" || data1 === "cursor" || data1 === "hermes")) {
|
|
16201
16201
|
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" }];
|
|
16202
16202
|
return false;
|
|
16203
16203
|
}
|
|
@@ -19572,7 +19572,7 @@ function optionalUserScopeMembers(record) {
|
|
|
19572
19572
|
members.push({ kind: "role", role: candidate.role });
|
|
19573
19573
|
continue;
|
|
19574
19574
|
}
|
|
19575
|
-
if (candidate.kind === "agent" && (candidate.agent === "claude_code" || candidate.agent === "codex" || candidate.agent === "hermes")) {
|
|
19575
|
+
if (candidate.kind === "agent" && (candidate.agent === "claude_code" || candidate.agent === "codex" || candidate.agent === "cursor" || candidate.agent === "hermes")) {
|
|
19576
19576
|
members.push({ kind: "agent", agent: candidate.agent });
|
|
19577
19577
|
continue;
|
|
19578
19578
|
}
|
|
@@ -19945,7 +19945,7 @@ function errorCode(error) {
|
|
|
19945
19945
|
function parseAgent(argv) {
|
|
19946
19946
|
const i = argv.indexOf("--agent");
|
|
19947
19947
|
const value = i !== -1 ? argv[i + 1] : void 0;
|
|
19948
|
-
if (value === "codex" || value === "hermes") {
|
|
19948
|
+
if (value === "codex" || value === "cursor" || value === "hermes") {
|
|
19949
19949
|
return value;
|
|
19950
19950
|
}
|
|
19951
19951
|
return "claude_code";
|
|
@@ -20032,7 +20032,7 @@ function daemonRequest(method, params = {}, opts = {}) {
|
|
|
20032
20032
|
...caller ? { caller } : {}
|
|
20033
20033
|
};
|
|
20034
20034
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
20035
|
-
return new Promise((
|
|
20035
|
+
return new Promise((resolve6) => {
|
|
20036
20036
|
let settled = false;
|
|
20037
20037
|
let socket;
|
|
20038
20038
|
let buffer = Buffer.alloc(0);
|
|
@@ -20047,7 +20047,7 @@ function daemonRequest(method, params = {}, opts = {}) {
|
|
|
20047
20047
|
} catch {
|
|
20048
20048
|
}
|
|
20049
20049
|
}
|
|
20050
|
-
|
|
20050
|
+
resolve6(value);
|
|
20051
20051
|
};
|
|
20052
20052
|
const timer = setTimeout(() => settle(null), timeoutMs);
|
|
20053
20053
|
timer.unref();
|
|
@@ -20125,6 +20125,7 @@ import { dirname as dirname8, isAbsolute as isAbsolute4, join as join10 } from "
|
|
|
20125
20125
|
import { fileURLToPath } from "url";
|
|
20126
20126
|
var PKG_NAME = "@primitive.ai/prim";
|
|
20127
20127
|
var ROOT_WALK_LIMIT = 6;
|
|
20128
|
+
var STABLE_HOOK_LAUNCHER_NAME = "prim-hook-launcher-v1";
|
|
20128
20129
|
var resolvedRoot;
|
|
20129
20130
|
function locateRoot() {
|
|
20130
20131
|
if (resolvedRoot !== void 0) {
|
|
@@ -20155,6 +20156,34 @@ function locateRoot() {
|
|
|
20155
20156
|
function packageVersion() {
|
|
20156
20157
|
return locateRoot()?.version ?? null;
|
|
20157
20158
|
}
|
|
20159
|
+
function shellQuote(value) {
|
|
20160
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
20161
|
+
}
|
|
20162
|
+
var STABLE_HOOK_ARGUMENTS_RE = /^[-A-Za-z0-9_ ]*$/u;
|
|
20163
|
+
var STABLE_HOOK_BIN_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/u;
|
|
20164
|
+
function stableHookCommand(bin, args = "") {
|
|
20165
|
+
if (!STABLE_HOOK_BIN_RE.test(bin) || !STABLE_HOOK_ARGUMENTS_RE.test(args)) {
|
|
20166
|
+
throw new Error("invalid stable hook command");
|
|
20167
|
+
}
|
|
20168
|
+
const resolver = [
|
|
20169
|
+
// #242 and earlier identify managed commands by this package marker. Keep
|
|
20170
|
+
// it as inert data during the rolling window so an older uninstall or
|
|
20171
|
+
// reinstall can remove the stable entry without invoking npm or PATH.
|
|
20172
|
+
`prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
|
|
20173
|
+
'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
|
|
20174
|
+
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
20175
|
+
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
20176
|
+
'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; ',
|
|
20177
|
+
"fi; fi; ",
|
|
20178
|
+
`case "$prim_config" in /) prim_launcher=/${STABLE_HOOK_LAUNCHER_NAME} ;; *) prim_launcher="$prim_config/${STABLE_HOOK_LAUNCHER_NAME}" ;; esac; `,
|
|
20179
|
+
'exec "$prim_launcher" "$@"'
|
|
20180
|
+
].join("");
|
|
20181
|
+
const suffix = args ? ` ${args}` : "";
|
|
20182
|
+
return `/bin/sh -c ${shellQuote(resolver)} ${STABLE_HOOK_LAUNCHER_NAME} ${bin}${suffix}`;
|
|
20183
|
+
}
|
|
20184
|
+
function detachedHookShimCommand(bin, args = "") {
|
|
20185
|
+
return `payload=$(cat); { trap '' HUP; printf '%s' "$payload" | { ${stableHookCommand(bin, args)}; }; } </dev/null >/dev/null 2>&1 &`;
|
|
20186
|
+
}
|
|
20158
20187
|
|
|
20159
20188
|
// src/lib/presence.ts
|
|
20160
20189
|
var DECISION_ORIGIN = "https://app.getprimitive.ai";
|
|
@@ -20269,15 +20298,13 @@ var CODEX_DRAFT_DIGEST_MAX_SEEN_IDS = 4096;
|
|
|
20269
20298
|
var CODEX_DIGEST_STATE_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
20270
20299
|
var CODEX_DIGEST_STATE_MAX_FILES = 256;
|
|
20271
20300
|
var STATE_VERSION = 1;
|
|
20272
|
-
var STATE_DIRECTORY = ["codex", "decision-digests"];
|
|
20273
20301
|
var DRAFT_STATE_VERSION = 2;
|
|
20274
|
-
var DRAFT_STATE_DIRECTORY = ["codex", "decision-draft-deliveries"];
|
|
20275
20302
|
var NO_CURSOR = -1;
|
|
20276
|
-
function stateRoot() {
|
|
20277
|
-
return join11(primConfigDirectory(),
|
|
20303
|
+
function stateRoot(namespace) {
|
|
20304
|
+
return join11(primConfigDirectory(), namespace, "decision-digests");
|
|
20278
20305
|
}
|
|
20279
|
-
function draftStateRoot() {
|
|
20280
|
-
return join11(primConfigDirectory(),
|
|
20306
|
+
function draftStateRoot(namespace) {
|
|
20307
|
+
return join11(primConfigDirectory(), namespace, "decision-draft-deliveries");
|
|
20281
20308
|
}
|
|
20282
20309
|
function workspaceFor(cwd) {
|
|
20283
20310
|
try {
|
|
@@ -20289,12 +20316,12 @@ function workspaceFor(cwd) {
|
|
|
20289
20316
|
function statePath(args) {
|
|
20290
20317
|
const identity = `${args.siteUrl}\0${workspaceFor(args.cwd)}\0${args.sessionId}`;
|
|
20291
20318
|
const key = createHash5("sha256").update(identity).digest("hex");
|
|
20292
|
-
return join11(stateRoot(), `${key}.json`);
|
|
20319
|
+
return join11(stateRoot(args.namespace), `${key}.json`);
|
|
20293
20320
|
}
|
|
20294
20321
|
function draftStatePath(args) {
|
|
20295
20322
|
const identity = `${args.siteUrl}\0${workspaceFor(args.cwd)}\0${args.sessionId}\0${args.principalId}\0${args.organizationId}\0${args.credentialFingerprint}`;
|
|
20296
20323
|
const key = createHash5("sha256").update(identity).digest("hex");
|
|
20297
|
-
return join11(draftStateRoot(), `${key}.json`);
|
|
20324
|
+
return join11(draftStateRoot(args.namespace), `${key}.json`);
|
|
20298
20325
|
}
|
|
20299
20326
|
function parseState(value) {
|
|
20300
20327
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
@@ -20485,14 +20512,14 @@ function mergeState(latest, args) {
|
|
|
20485
20512
|
updatedAt: args.now
|
|
20486
20513
|
};
|
|
20487
20514
|
}
|
|
20488
|
-
async function commitState(path, args) {
|
|
20515
|
+
async function commitState(path, args, namespace) {
|
|
20489
20516
|
try {
|
|
20490
20517
|
await withFileLock(
|
|
20491
20518
|
`${path}.lock`,
|
|
20492
20519
|
() => {
|
|
20493
20520
|
const latest = readState(path);
|
|
20494
|
-
writeStateFile(path, stateRoot(), mergeState(latest, args));
|
|
20495
|
-
cleanupStateFiles(stateRoot(), args.now);
|
|
20521
|
+
writeStateFile(path, stateRoot(namespace), mergeState(latest, args));
|
|
20522
|
+
cleanupStateFiles(stateRoot(namespace), args.now);
|
|
20496
20523
|
},
|
|
20497
20524
|
{ timeoutMs: 50, pollMs: 10 }
|
|
20498
20525
|
);
|
|
@@ -20514,7 +20541,7 @@ function mergeDraftState(latest, args) {
|
|
|
20514
20541
|
updatedAt: args.now
|
|
20515
20542
|
};
|
|
20516
20543
|
}
|
|
20517
|
-
async function commitDraftState(path, args) {
|
|
20544
|
+
async function commitDraftState(path, args, namespace) {
|
|
20518
20545
|
try {
|
|
20519
20546
|
let next;
|
|
20520
20547
|
await withFileLock(
|
|
@@ -20522,8 +20549,8 @@ async function commitDraftState(path, args) {
|
|
|
20522
20549
|
() => {
|
|
20523
20550
|
const latest = readDraftState(path);
|
|
20524
20551
|
next = mergeDraftState(latest, args);
|
|
20525
|
-
writeStateFile(path, draftStateRoot(), next);
|
|
20526
|
-
cleanupStateFiles(draftStateRoot(), args.now);
|
|
20552
|
+
writeStateFile(path, draftStateRoot(namespace), next);
|
|
20553
|
+
cleanupStateFiles(draftStateRoot(namespace), args.now);
|
|
20527
20554
|
},
|
|
20528
20555
|
{ timeoutMs: 50, pollMs: 10 }
|
|
20529
20556
|
);
|
|
@@ -20533,9 +20560,10 @@ async function commitDraftState(path, args) {
|
|
|
20533
20560
|
}
|
|
20534
20561
|
}
|
|
20535
20562
|
async function prepareCodexContext(options) {
|
|
20563
|
+
const namespace = options.namespace ?? "codex";
|
|
20536
20564
|
const siteUrl = getSiteUrl();
|
|
20537
20565
|
const workspace = workspaceFor(options.cwd);
|
|
20538
|
-
const path = statePath({ cwd: options.cwd, sessionId: options.sessionId, siteUrl });
|
|
20566
|
+
const path = statePath({ cwd: options.cwd, sessionId: options.sessionId, siteUrl, namespace });
|
|
20539
20567
|
const previous = readState(path);
|
|
20540
20568
|
const principal = resolveDaemonPrincipal();
|
|
20541
20569
|
const privatePath = principal ? draftStatePath({
|
|
@@ -20544,7 +20572,8 @@ async function prepareCodexContext(options) {
|
|
|
20544
20572
|
siteUrl,
|
|
20545
20573
|
principalId: principal.principalId,
|
|
20546
20574
|
organizationId: principal.organizationId,
|
|
20547
|
-
credentialFingerprint: principal.credentialFingerprint
|
|
20575
|
+
credentialFingerprint: principal.credentialFingerprint,
|
|
20576
|
+
namespace
|
|
20548
20577
|
}) : void 0;
|
|
20549
20578
|
const previousDraft = privatePath ? readDraftState(privatePath) : void 0;
|
|
20550
20579
|
const startup = options.startup === true;
|
|
@@ -20634,32 +20663,40 @@ async function prepareCodexContext(options) {
|
|
|
20634
20663
|
acknowledge: async (handedOff) => {
|
|
20635
20664
|
if (!handedOff || acknowledged) return;
|
|
20636
20665
|
acknowledged = true;
|
|
20637
|
-
await commitState(
|
|
20638
|
-
|
|
20639
|
-
|
|
20640
|
-
|
|
20641
|
-
|
|
20642
|
-
|
|
20643
|
-
|
|
20644
|
-
|
|
20645
|
-
|
|
20646
|
-
|
|
20647
|
-
|
|
20666
|
+
await commitState(
|
|
20667
|
+
path,
|
|
20668
|
+
{
|
|
20669
|
+
sessionId: options.sessionId,
|
|
20670
|
+
siteUrl,
|
|
20671
|
+
workspace,
|
|
20672
|
+
startedAt,
|
|
20673
|
+
watermarkMs: pageWatermark,
|
|
20674
|
+
seenIds: freshRows.map((row) => row.id),
|
|
20675
|
+
report,
|
|
20676
|
+
feedAvailable,
|
|
20677
|
+
now: Date.now()
|
|
20678
|
+
},
|
|
20679
|
+
namespace
|
|
20680
|
+
);
|
|
20648
20681
|
if (privatePath === void 0 || principal === void 0 || draftPageToken === void 0) {
|
|
20649
20682
|
return;
|
|
20650
20683
|
}
|
|
20651
20684
|
let persistedDraft = previousDraft;
|
|
20652
20685
|
if (draftDigest?.deliveredIds.length) {
|
|
20653
|
-
persistedDraft = await commitDraftState(
|
|
20654
|
-
|
|
20655
|
-
|
|
20656
|
-
|
|
20657
|
-
|
|
20658
|
-
|
|
20659
|
-
|
|
20660
|
-
|
|
20661
|
-
|
|
20662
|
-
|
|
20686
|
+
persistedDraft = await commitDraftState(
|
|
20687
|
+
privatePath,
|
|
20688
|
+
{
|
|
20689
|
+
sessionId: options.sessionId,
|
|
20690
|
+
siteUrl,
|
|
20691
|
+
workspace,
|
|
20692
|
+
principalId: principal.principalId,
|
|
20693
|
+
organizationId: principal.organizationId,
|
|
20694
|
+
credentialFingerprint: principal.credentialFingerprint,
|
|
20695
|
+
deliveredIds: draftDigest.deliveredIds,
|
|
20696
|
+
now: Date.now()
|
|
20697
|
+
},
|
|
20698
|
+
namespace
|
|
20699
|
+
);
|
|
20663
20700
|
}
|
|
20664
20701
|
const seenDrafts = new Set(persistedDraft?.seenDraftIds ?? []);
|
|
20665
20702
|
const deliveredOnThisPage = draftPageActionableIds.filter((id) => seenDrafts.has(id));
|
|
@@ -20709,6 +20746,290 @@ async function processCodexMessageContext(envelope, deps = defaultDeps) {
|
|
|
20709
20746
|
};
|
|
20710
20747
|
}
|
|
20711
20748
|
|
|
20749
|
+
// src/commands/cursor-install.ts
|
|
20750
|
+
import { existsSync as existsSync10, readFileSync as readFileSync12 } from "fs";
|
|
20751
|
+
import { homedir as homedir4 } from "os";
|
|
20752
|
+
import { isAbsolute as isAbsolute6, join as join14 } from "path";
|
|
20753
|
+
|
|
20754
|
+
// src/lib/hook-runtime.ts
|
|
20755
|
+
import { createHash as createHash6, randomBytes as randomBytes4 } from "crypto";
|
|
20756
|
+
import {
|
|
20757
|
+
constants as constants3,
|
|
20758
|
+
accessSync,
|
|
20759
|
+
chmodSync as chmodSync4,
|
|
20760
|
+
copyFileSync,
|
|
20761
|
+
existsSync as existsSync8,
|
|
20762
|
+
lstatSync as lstatSync3,
|
|
20763
|
+
mkdirSync as mkdirSync7,
|
|
20764
|
+
mkdtempSync,
|
|
20765
|
+
readFileSync as readFileSync10,
|
|
20766
|
+
readdirSync as readdirSync3,
|
|
20767
|
+
realpathSync as realpathSync2,
|
|
20768
|
+
renameSync as renameSync3,
|
|
20769
|
+
rmSync as rmSync5,
|
|
20770
|
+
statSync as statSync4,
|
|
20771
|
+
utimesSync,
|
|
20772
|
+
writeFileSync as writeFileSync5
|
|
20773
|
+
} from "fs";
|
|
20774
|
+
import { delimiter, dirname as dirname9, isAbsolute as isAbsolute5, join as join12, resolve as resolve4 } from "path";
|
|
20775
|
+
var RELEASE_PREFIX = "release-";
|
|
20776
|
+
var MAX_MANIFEST_BYTES = 64 * 1024;
|
|
20777
|
+
var RELEASE_GRACE_MS = 10 * 60 * 1e3;
|
|
20778
|
+
var HOOK_RUNTIME_ENTRIES = {
|
|
20779
|
+
// SessionStart self-healing resolves this exact CLI entry to run
|
|
20780
|
+
// `daemon ensure`; it must travel with the immutable hook release.
|
|
20781
|
+
prim: "dist/index.js",
|
|
20782
|
+
"prim-hook": "dist/hooks/prim-hook.js",
|
|
20783
|
+
"prim-pre-commit": "dist/hooks/pre-commit.js",
|
|
20784
|
+
"prim-post-commit": "dist/hooks/post-commit.js",
|
|
20785
|
+
"prim-post-rewrite": "dist/hooks/post-rewrite.js",
|
|
20786
|
+
"prim-pre-tool-use": "dist/hooks/pre-tool-use.js",
|
|
20787
|
+
"prim-post-tool-use": "dist/hooks/post-tool-use.js",
|
|
20788
|
+
"prim-session-start": "dist/hooks/session-start.js",
|
|
20789
|
+
"prim-session-end": "dist/hooks/session-end.js",
|
|
20790
|
+
"prim-daemon-server": "dist/daemon/server.js",
|
|
20791
|
+
"prim-statusline": "dist/statusline-main.js"
|
|
20792
|
+
};
|
|
20793
|
+
var SOURCE_ENTRIES = Object.fromEntries(
|
|
20794
|
+
Object.entries(HOOK_RUNTIME_ENTRIES).map(([bin, target]) => [
|
|
20795
|
+
bin,
|
|
20796
|
+
target.replace(/^dist\//u, "")
|
|
20797
|
+
])
|
|
20798
|
+
);
|
|
20799
|
+
var STABLE_HOOK_LAUNCHER_CONTENT = `#!/bin/sh
|
|
20800
|
+
set -eu
|
|
20801
|
+
case "$0" in */*) prim_launcher_dir=\${0%/*} ;; *) exit 78 ;; esac
|
|
20802
|
+
IFS= read -r prim_release_name < "$prim_launcher_dir/hook-runtime/current" || exit 69
|
|
20803
|
+
case "$prim_release_name" in ${RELEASE_PREFIX}*) ;; *) exit 69 ;; esac
|
|
20804
|
+
prim_release_id=\${prim_release_name#${RELEASE_PREFIX}}
|
|
20805
|
+
case "$prim_release_id" in *[!0-9a-f]*|"") exit 69 ;; esac
|
|
20806
|
+
[ "\${#prim_release_id}" -eq 64 ] || exit 69
|
|
20807
|
+
prim_release="$prim_launcher_dir/hook-runtime/releases/$prim_release_name"
|
|
20808
|
+
case "\${1-}" in
|
|
20809
|
+
${Object.entries(HOOK_RUNTIME_ENTRIES).map(([bin, entry]) => ` ${bin}) prim_entry="$prim_release/${entry}" ;;`).join("\n")}
|
|
20810
|
+
*) exit 64 ;;
|
|
20811
|
+
esac
|
|
20812
|
+
shift
|
|
20813
|
+
IFS= read -r prim_node < "$prim_release/node" || exit 69
|
|
20814
|
+
case "$prim_node" in /*) ;; *) exit 69 ;; esac
|
|
20815
|
+
[ -x "$prim_node" ] && [ -f "$prim_entry" ] || exit 69
|
|
20816
|
+
exec "$prim_node" "$prim_entry" "$@"
|
|
20817
|
+
`;
|
|
20818
|
+
|
|
20819
|
+
// src/commands/claude-install.ts
|
|
20820
|
+
import { existsSync as existsSync9, readFileSync as readFileSync11 } from "fs";
|
|
20821
|
+
import { homedir as homedir3 } from "os";
|
|
20822
|
+
import { join as join13 } from "path";
|
|
20823
|
+
var CAPTURE_BIN = "prim-hook";
|
|
20824
|
+
var GATE_BIN = "prim-pre-tool-use";
|
|
20825
|
+
var POST_TOOL_USE_BIN = "prim-post-tool-use";
|
|
20826
|
+
var SESSION_START_BIN = "prim-session-start";
|
|
20827
|
+
var SESSION_END_BIN = "prim-session-end";
|
|
20828
|
+
var STATUSLINE_BIN = "prim-statusline";
|
|
20829
|
+
var STATUSLINE_ARGS = "";
|
|
20830
|
+
var STATUSLINE_COMMAND = stableHookCommand(STATUSLINE_BIN, STATUSLINE_ARGS);
|
|
20831
|
+
var USER_SCOPE_PATH = join13(homedir3(), ".claude", "settings.json");
|
|
20832
|
+
function projectRoot() {
|
|
20833
|
+
return gitToplevel() ?? process.cwd();
|
|
20834
|
+
}
|
|
20835
|
+
var CAPTURE_EVENTS = [
|
|
20836
|
+
"SessionStart",
|
|
20837
|
+
"UserPromptSubmit",
|
|
20838
|
+
"PreToolUse",
|
|
20839
|
+
"PostToolUse",
|
|
20840
|
+
"PostToolUseFailure",
|
|
20841
|
+
"Stop",
|
|
20842
|
+
"SessionEnd",
|
|
20843
|
+
"SubagentStop"
|
|
20844
|
+
];
|
|
20845
|
+
function makeRegistration(event, matcher, bin, args = "") {
|
|
20846
|
+
return {
|
|
20847
|
+
event,
|
|
20848
|
+
matcher,
|
|
20849
|
+
bin,
|
|
20850
|
+
command: stableHookCommand(bin, args)
|
|
20851
|
+
};
|
|
20852
|
+
}
|
|
20853
|
+
function makeDetachedRegistration(event, matcher, bin, args = "") {
|
|
20854
|
+
return { event, matcher, bin, command: detachedHookShimCommand(bin, args) };
|
|
20855
|
+
}
|
|
20856
|
+
var REGISTRATIONS = [
|
|
20857
|
+
...CAPTURE_EVENTS.map(
|
|
20858
|
+
(event) => event === "SessionEnd" ? makeDetachedRegistration(event, "*", CAPTURE_BIN) : makeRegistration(event, "*", CAPTURE_BIN)
|
|
20859
|
+
),
|
|
20860
|
+
makeRegistration("PreToolUse", "Edit|Write|MultiEdit|NotebookEdit|Bash", GATE_BIN),
|
|
20861
|
+
makeRegistration("PostToolUse", "Edit|Write|MultiEdit|NotebookEdit|Bash", POST_TOOL_USE_BIN),
|
|
20862
|
+
makeRegistration(
|
|
20863
|
+
"PostToolUseFailure",
|
|
20864
|
+
"Edit|Write|MultiEdit|NotebookEdit|Bash",
|
|
20865
|
+
POST_TOOL_USE_BIN
|
|
20866
|
+
),
|
|
20867
|
+
makeRegistration("SessionStart", "*", SESSION_START_BIN),
|
|
20868
|
+
makeDetachedRegistration("SessionEnd", "*", SESSION_END_BIN)
|
|
20869
|
+
];
|
|
20870
|
+
var PRIM_PERMISSION_RULE = "Bash(npx --yes @primitive.ai/prim*)";
|
|
20871
|
+
var LEGACY_PRIM_PERMISSION_RULES = [
|
|
20872
|
+
"Bash(npx --yes @primitive.ai/prim@latest:*)",
|
|
20873
|
+
"Bash(npx --yes @primitive.ai/prim:*)"
|
|
20874
|
+
];
|
|
20875
|
+
var ALL_PRIM_PERMISSION_RULES = /* @__PURE__ */ new Set([
|
|
20876
|
+
PRIM_PERMISSION_RULE,
|
|
20877
|
+
...LEGACY_PRIM_PERMISSION_RULES
|
|
20878
|
+
]);
|
|
20879
|
+
|
|
20880
|
+
// src/commands/cursor-install.ts
|
|
20881
|
+
var CAPTURE_BIN2 = "prim-hook";
|
|
20882
|
+
var GATE_BIN2 = "prim-pre-tool-use";
|
|
20883
|
+
var POST_TOOL_BIN = "prim-post-tool-use";
|
|
20884
|
+
var SESSION_START_BIN2 = "prim-session-start";
|
|
20885
|
+
var SESSION_END_BIN2 = "prim-session-end";
|
|
20886
|
+
var STATUSLINE_BIN2 = "prim-statusline";
|
|
20887
|
+
var CURSOR_EVENTS = [
|
|
20888
|
+
"sessionStart",
|
|
20889
|
+
"beforeSubmitPrompt",
|
|
20890
|
+
"preToolUse",
|
|
20891
|
+
"postToolUse",
|
|
20892
|
+
"postToolUseFailure",
|
|
20893
|
+
"afterAgentResponse",
|
|
20894
|
+
"subagentStop",
|
|
20895
|
+
"stop",
|
|
20896
|
+
"sessionEnd"
|
|
20897
|
+
];
|
|
20898
|
+
var REGISTRATIONS2 = [
|
|
20899
|
+
...CURSOR_EVENTS.map((event) => ({ event, bin: CAPTURE_BIN2 })),
|
|
20900
|
+
{ event: "preToolUse", bin: GATE_BIN2, matcher: "Write|Delete|Shell", timeout: 10 },
|
|
20901
|
+
{ event: "postToolUse", bin: POST_TOOL_BIN },
|
|
20902
|
+
{ event: "postToolUseFailure", bin: POST_TOOL_BIN },
|
|
20903
|
+
{ event: "sessionStart", bin: SESSION_START_BIN2 },
|
|
20904
|
+
{ event: "sessionEnd", bin: SESSION_END_BIN2 }
|
|
20905
|
+
];
|
|
20906
|
+
function cursorConfigDirectory(env = process.env, home = homedir4(), platform2 = process.platform) {
|
|
20907
|
+
const explicit = env.CURSOR_CONFIG_DIR?.trim();
|
|
20908
|
+
if (explicit && isAbsolute6(explicit)) return explicit;
|
|
20909
|
+
const xdg = env.XDG_CONFIG_HOME?.trim();
|
|
20910
|
+
if (platform2 !== "darwin" && xdg && isAbsolute6(xdg)) return join14(xdg, "cursor");
|
|
20911
|
+
return join14(home, ".cursor");
|
|
20912
|
+
}
|
|
20913
|
+
function cursorHooksPath(scope, root = projectRoot()) {
|
|
20914
|
+
return scope === "user" ? join14(cursorConfigDirectory(), "hooks.json") : join14(root, ".cursor", "hooks.json");
|
|
20915
|
+
}
|
|
20916
|
+
function plainObject(value) {
|
|
20917
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20918
|
+
}
|
|
20919
|
+
function readCursorHooks(path) {
|
|
20920
|
+
if (!existsSync10(path)) return {};
|
|
20921
|
+
let parsed;
|
|
20922
|
+
try {
|
|
20923
|
+
parsed = JSON.parse(readFileSync12(path, "utf8"));
|
|
20924
|
+
} catch {
|
|
20925
|
+
throw new Error(`invalid Cursor hooks JSON at ${path}`);
|
|
20926
|
+
}
|
|
20927
|
+
if (!plainObject(parsed)) throw new Error(`Cursor hooks config must be an object: ${path}`);
|
|
20928
|
+
if (parsed.version !== void 0 && parsed.version !== 1) {
|
|
20929
|
+
throw new Error(`unsupported Cursor hooks version at ${path} (expected version 1)`);
|
|
20930
|
+
}
|
|
20931
|
+
if (parsed.hooks !== void 0) {
|
|
20932
|
+
if (!plainObject(parsed.hooks)) throw new Error(`Cursor hooks must be an object: ${path}`);
|
|
20933
|
+
for (const [event, entries] of Object.entries(parsed.hooks)) {
|
|
20934
|
+
if (!Array.isArray(entries) || !entries.every(plainObject)) {
|
|
20935
|
+
throw new Error(`Cursor hook list must contain objects: ${event} in ${path}`);
|
|
20936
|
+
}
|
|
20937
|
+
}
|
|
20938
|
+
}
|
|
20939
|
+
return parsed;
|
|
20940
|
+
}
|
|
20941
|
+
function commandFor(registration, scope) {
|
|
20942
|
+
return stableHookCommand(
|
|
20943
|
+
registration.bin,
|
|
20944
|
+
`--agent cursor --event ${registration.event} --scope ${scope}`
|
|
20945
|
+
);
|
|
20946
|
+
}
|
|
20947
|
+
var OWNED_COMMANDS = new Set(
|
|
20948
|
+
["project", "user"].flatMap(
|
|
20949
|
+
(scope) => REGISTRATIONS2.map((registration) => commandFor(registration, scope))
|
|
20950
|
+
)
|
|
20951
|
+
);
|
|
20952
|
+
function jsoncUnsafeCommand(command) {
|
|
20953
|
+
return command.replace('case "$1" in [/]* ', 'case "$1" in /*').replace("*[/][/]*", "*//*").replace("*[/].[/]*", "*/./*").replace("*[/]..[/]*", "*/../*").replace("*[/].", "*/.").replace("*[/]..", "*/..").replace("?*[/]", "?*/");
|
|
20954
|
+
}
|
|
20955
|
+
var JSONC_UNSAFE_OWNED_COMMANDS = new Set([...OWNED_COMMANDS].map(jsoncUnsafeCommand));
|
|
20956
|
+
function hookFor(registration, scope) {
|
|
20957
|
+
return {
|
|
20958
|
+
command: commandFor(registration, scope),
|
|
20959
|
+
...registration.matcher ? { matcher: registration.matcher } : {},
|
|
20960
|
+
...registration.timeout ? { timeout: registration.timeout } : {}
|
|
20961
|
+
};
|
|
20962
|
+
}
|
|
20963
|
+
function exactHook(entry, registration, scope) {
|
|
20964
|
+
return JSON.stringify(entry) === JSON.stringify(hookFor(registration, scope));
|
|
20965
|
+
}
|
|
20966
|
+
function hasExactCursorHandler(settings, event, bin, scope) {
|
|
20967
|
+
const registration = REGISTRATIONS2.find(
|
|
20968
|
+
(candidate) => candidate.event === event && candidate.bin === bin
|
|
20969
|
+
);
|
|
20970
|
+
return registration ? (settings.hooks?.[event] ?? []).some((entry) => exactHook(entry, registration, scope)) : false;
|
|
20971
|
+
}
|
|
20972
|
+
var FOOTER = {
|
|
20973
|
+
type: "command",
|
|
20974
|
+
command: stableHookCommand(STATUSLINE_BIN2),
|
|
20975
|
+
updateIntervalMs: 1e3,
|
|
20976
|
+
timeoutMs: 2e3
|
|
20977
|
+
};
|
|
20978
|
+
var JSONC_UNSAFE_FOOTER = {
|
|
20979
|
+
...FOOTER,
|
|
20980
|
+
command: jsoncUnsafeCommand(FOOTER.command)
|
|
20981
|
+
};
|
|
20982
|
+
|
|
20983
|
+
// src/hooks/cursor-coexistence.ts
|
|
20984
|
+
var CURSOR_EVENTS2 = /* @__PURE__ */ new Set([
|
|
20985
|
+
"sessionStart",
|
|
20986
|
+
"beforeSubmitPrompt",
|
|
20987
|
+
"preToolUse",
|
|
20988
|
+
"postToolUse",
|
|
20989
|
+
"postToolUseFailure",
|
|
20990
|
+
"afterAgentResponse",
|
|
20991
|
+
"subagentStop",
|
|
20992
|
+
"stop",
|
|
20993
|
+
"sessionEnd"
|
|
20994
|
+
]);
|
|
20995
|
+
function cursorEvidence(parsed) {
|
|
20996
|
+
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);
|
|
20997
|
+
}
|
|
20998
|
+
function uniqueProjectRoot(parsed) {
|
|
20999
|
+
if (!Array.isArray(parsed.workspace_roots)) return;
|
|
21000
|
+
const roots = new Set(
|
|
21001
|
+
parsed.workspace_roots.filter((value) => typeof value === "string" && value.length > 0).map((value) => resolveRepositoryContext(value)?.repoRoot).filter((value) => !!value)
|
|
21002
|
+
);
|
|
21003
|
+
return roots.size === 1 ? [...roots][0] : void 0;
|
|
21004
|
+
}
|
|
21005
|
+
function shouldSuppressImportedCursorHandler(parsed, bin) {
|
|
21006
|
+
if (!cursorEvidence(parsed)) return false;
|
|
21007
|
+
const project = uniqueProjectRoot(parsed);
|
|
21008
|
+
if (project) {
|
|
21009
|
+
try {
|
|
21010
|
+
if (hasExactCursorHandler(
|
|
21011
|
+
readCursorHooks(cursorHooksPath("project", project)),
|
|
21012
|
+
parsed.hook_event_name,
|
|
21013
|
+
bin,
|
|
21014
|
+
"project"
|
|
21015
|
+
)) {
|
|
21016
|
+
return true;
|
|
21017
|
+
}
|
|
21018
|
+
} catch {
|
|
21019
|
+
}
|
|
21020
|
+
}
|
|
21021
|
+
try {
|
|
21022
|
+
return hasExactCursorHandler(
|
|
21023
|
+
readCursorHooks(cursorHooksPath("user")),
|
|
21024
|
+
parsed.hook_event_name,
|
|
21025
|
+
bin,
|
|
21026
|
+
"user"
|
|
21027
|
+
);
|
|
21028
|
+
} catch {
|
|
21029
|
+
return false;
|
|
21030
|
+
}
|
|
21031
|
+
}
|
|
21032
|
+
|
|
20712
21033
|
// src/hooks/decision-feedback-core.ts
|
|
20713
21034
|
function buildHookOutput(options) {
|
|
20714
21035
|
const output = {};
|
|
@@ -20722,13 +21043,13 @@ function buildHookOutput(options) {
|
|
|
20722
21043
|
return output;
|
|
20723
21044
|
}
|
|
20724
21045
|
function writeHookOutput(output, stream = process.stdout) {
|
|
20725
|
-
return new Promise((
|
|
21046
|
+
return new Promise((resolve6) => {
|
|
20726
21047
|
let settled = false;
|
|
20727
21048
|
const finish = (ok, retainErrorListener = false) => {
|
|
20728
21049
|
if (settled) return;
|
|
20729
21050
|
settled = true;
|
|
20730
21051
|
if (!retainErrorListener) stream.off("error", onError);
|
|
20731
|
-
|
|
21052
|
+
resolve6(ok);
|
|
20732
21053
|
};
|
|
20733
21054
|
const onError = () => {
|
|
20734
21055
|
if (settled) {
|
|
@@ -20761,7 +21082,7 @@ async function handoffHookOutput(output, acknowledge, stream = process.stdout) {
|
|
|
20761
21082
|
}
|
|
20762
21083
|
|
|
20763
21084
|
// src/hooks/pre-tool-use-scoring.ts
|
|
20764
|
-
import { isAbsolute as
|
|
21085
|
+
import { isAbsolute as isAbsolute7, relative as relative2, sep as sep2 } from "path";
|
|
20765
21086
|
var SUPPORTED_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
20766
21087
|
var APPLY_PATCH_FILE_RE = /^\*\*\* (?:Update|Add|Delete) File: (?<path>.+)$/;
|
|
20767
21088
|
var MOVE_FILE_RE = /^\*\*\* Move File:\s*(?<src>.+?)\s*->\s*(?<dst>.+?)\s*$/;
|
|
@@ -20832,10 +21153,25 @@ function extractHermesFileTargets(toolName, toolInput) {
|
|
|
20832
21153
|
const mode = input.mode;
|
|
20833
21154
|
return { paths, complete: paths.length > 0 && (mode === void 0 || mode === "replace") };
|
|
20834
21155
|
}
|
|
21156
|
+
function extractCursorFileTargets(toolName, toolInput) {
|
|
21157
|
+
if (toolName !== "Write" && toolName !== "Delete") return null;
|
|
21158
|
+
if (!toolInput || typeof toolInput !== "object" || Array.isArray(toolInput)) {
|
|
21159
|
+
return { paths: [], complete: false };
|
|
21160
|
+
}
|
|
21161
|
+
const input = toolInput;
|
|
21162
|
+
const candidates = [input.file_path, input.path].filter(
|
|
21163
|
+
(value) => typeof value === "string" && value.length > 0
|
|
21164
|
+
);
|
|
21165
|
+
const paths = [...new Set(candidates)];
|
|
21166
|
+
return { paths, complete: paths.length === 1 };
|
|
21167
|
+
}
|
|
20835
21168
|
function extractFileTargets(toolName, toolInput, agent = "claude_code") {
|
|
20836
21169
|
if (agent === "codex") {
|
|
20837
21170
|
return extractCodexFileTargets(toolName, toolInput);
|
|
20838
21171
|
}
|
|
21172
|
+
if (agent === "cursor") {
|
|
21173
|
+
return extractCursorFileTargets(toolName, toolInput);
|
|
21174
|
+
}
|
|
20839
21175
|
if (agent === "hermes") {
|
|
20840
21176
|
return extractHermesFileTargets(toolName, toolInput);
|
|
20841
21177
|
}
|
|
@@ -22129,16 +22465,16 @@ var Lexer = class {
|
|
|
22129
22465
|
readHereDocDelimiter() {
|
|
22130
22466
|
const src = this.src;
|
|
22131
22467
|
const len = this.srcEnd;
|
|
22132
|
-
let
|
|
22468
|
+
let delimiter2 = "";
|
|
22133
22469
|
if (this.pos < len && src.charCodeAt(this.pos) === CH_SQUOTE) {
|
|
22134
22470
|
this.pos++;
|
|
22135
22471
|
const start = this.pos;
|
|
22136
22472
|
while (this.pos < len && src.charCodeAt(this.pos) !== CH_SQUOTE)
|
|
22137
22473
|
this.pos++;
|
|
22138
|
-
|
|
22474
|
+
delimiter2 = src.slice(start, this.pos);
|
|
22139
22475
|
if (this.pos < len)
|
|
22140
22476
|
this.pos++;
|
|
22141
|
-
this._hereDelim =
|
|
22477
|
+
this._hereDelim = delimiter2;
|
|
22142
22478
|
this._hereQuoted = true;
|
|
22143
22479
|
return;
|
|
22144
22480
|
} else if (this.pos < len && src.charCodeAt(this.pos) === CH_DQUOTE) {
|
|
@@ -22146,12 +22482,12 @@ var Lexer = class {
|
|
|
22146
22482
|
while (this.pos < len && src.charCodeAt(this.pos) !== CH_DQUOTE) {
|
|
22147
22483
|
if (src.charCodeAt(this.pos) === CH_BACKSLASH)
|
|
22148
22484
|
this.pos++;
|
|
22149
|
-
|
|
22485
|
+
delimiter2 += src[this.pos];
|
|
22150
22486
|
this.pos++;
|
|
22151
22487
|
}
|
|
22152
22488
|
if (this.pos < len)
|
|
22153
22489
|
this.pos++;
|
|
22154
|
-
this._hereDelim =
|
|
22490
|
+
this._hereDelim = delimiter2;
|
|
22155
22491
|
this._hereQuoted = true;
|
|
22156
22492
|
return;
|
|
22157
22493
|
} else if (this.pos < len && src.charCodeAt(this.pos) === CH_BACKSLASH) {
|
|
@@ -22162,11 +22498,11 @@ var Lexer = class {
|
|
|
22162
22498
|
if (c === CH_BACKSLASH)
|
|
22163
22499
|
this.pos++;
|
|
22164
22500
|
if (this.pos < len) {
|
|
22165
|
-
|
|
22501
|
+
delimiter2 += src[this.pos];
|
|
22166
22502
|
this.pos++;
|
|
22167
22503
|
}
|
|
22168
22504
|
}
|
|
22169
|
-
this._hereDelim =
|
|
22505
|
+
this._hereDelim = delimiter2;
|
|
22170
22506
|
this._hereQuoted = true;
|
|
22171
22507
|
return;
|
|
22172
22508
|
} else {
|
|
@@ -22198,9 +22534,9 @@ var Lexer = class {
|
|
|
22198
22534
|
}
|
|
22199
22535
|
this.pendingHereDocs.length = 0;
|
|
22200
22536
|
}
|
|
22201
|
-
readHereDocBody(
|
|
22537
|
+
readHereDocBody(delimiter2, strip) {
|
|
22202
22538
|
const bodyStart = this.pos;
|
|
22203
|
-
const bodyEnd = this.skipHereDocBody(
|
|
22539
|
+
const bodyEnd = this.skipHereDocBody(delimiter2, strip);
|
|
22204
22540
|
return this.src.slice(bodyStart, bodyEnd);
|
|
22205
22541
|
}
|
|
22206
22542
|
// Advance past the heredoc body and its delimiter line; return the body end
|
|
@@ -22208,10 +22544,10 @@ var Lexer = class {
|
|
|
22208
22544
|
// With parenEnds (inside $(...)), a line starting with the delimiter directly
|
|
22209
22545
|
// followed by ")" also terminates the body, resuming at the ")" — bash treats
|
|
22210
22546
|
// the substitution's closing paren as end-of-file for its heredocs.
|
|
22211
|
-
skipHereDocBody(
|
|
22547
|
+
skipHereDocBody(delimiter2, strip, parenEnds = false) {
|
|
22212
22548
|
const src = this.src;
|
|
22213
22549
|
const len = this.srcEnd;
|
|
22214
|
-
const dLen =
|
|
22550
|
+
const dLen = delimiter2.length;
|
|
22215
22551
|
while (this.pos < len) {
|
|
22216
22552
|
let lineStart = this.pos;
|
|
22217
22553
|
let lineEnd = src.indexOf("\n", this.pos);
|
|
@@ -22221,12 +22557,12 @@ var Lexer = class {
|
|
|
22221
22557
|
while (lineStart < lineEnd && src.charCodeAt(lineStart) === CH_TAB)
|
|
22222
22558
|
lineStart++;
|
|
22223
22559
|
}
|
|
22224
|
-
if (lineEnd - lineStart === dLen && src.startsWith(
|
|
22560
|
+
if (lineEnd - lineStart === dLen && src.startsWith(delimiter2, lineStart)) {
|
|
22225
22561
|
const bodyEnd = this.pos;
|
|
22226
22562
|
this.pos = lineEnd < len ? lineEnd + 1 : lineEnd;
|
|
22227
22563
|
return bodyEnd;
|
|
22228
22564
|
}
|
|
22229
|
-
if (parenEnds && lineEnd - lineStart > dLen && src.charCodeAt(lineStart + dLen) === CH_RPAREN && src.startsWith(
|
|
22565
|
+
if (parenEnds && lineEnd - lineStart > dLen && src.charCodeAt(lineStart + dLen) === CH_RPAREN && src.startsWith(delimiter2, lineStart)) {
|
|
22230
22566
|
const bodyEnd = this.pos;
|
|
22231
22567
|
this.pos = lineStart + dLen;
|
|
22232
22568
|
return bodyEnd;
|
|
@@ -24938,7 +25274,7 @@ function safeSedProgram(program) {
|
|
|
24938
25274
|
return true;
|
|
24939
25275
|
const match = /^(?:(?:\d+|\$)(?:,(?:\d+|\$))?)?s(.)(.*)$/s.exec(program);
|
|
24940
25276
|
if (!match || /[\\\nA-Za-z0-9]/.test(match[1])) return false;
|
|
24941
|
-
const
|
|
25277
|
+
const delimiter2 = match[1];
|
|
24942
25278
|
const tail = match[2];
|
|
24943
25279
|
let offset = 0;
|
|
24944
25280
|
for (let section = 0; section < 2; section += 1) {
|
|
@@ -24946,7 +25282,7 @@ function safeSedProgram(program) {
|
|
|
24946
25282
|
while (offset < tail.length) {
|
|
24947
25283
|
if (tail[offset] === "\\") {
|
|
24948
25284
|
offset += 2;
|
|
24949
|
-
} else if (tail[offset] ===
|
|
25285
|
+
} else if (tail[offset] === delimiter2) {
|
|
24950
25286
|
offset += 1;
|
|
24951
25287
|
closed = true;
|
|
24952
25288
|
break;
|
|
@@ -25302,7 +25638,8 @@ function preserveHookFileMetadata(payload, resolution) {
|
|
|
25302
25638
|
return { ...payload, primitive };
|
|
25303
25639
|
}
|
|
25304
25640
|
function resolveHookFileRefs(args) {
|
|
25305
|
-
const
|
|
25641
|
+
const isShellTool = (args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash" || args.agent === "cursor" && args.toolName === "Shell";
|
|
25642
|
+
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;
|
|
25306
25643
|
const shell = command === void 0 ? void 0 : analyzeShellTargets(command);
|
|
25307
25644
|
const shellMutation = shell?.mutation === "none" ? "none" : shell?.coverage === "complete" ? "resolved" : shell ? "unresolved" : void 0;
|
|
25308
25645
|
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;
|
|
@@ -25347,8 +25684,41 @@ function enrichHookPayloadWithFileRefs(args) {
|
|
|
25347
25684
|
};
|
|
25348
25685
|
}
|
|
25349
25686
|
|
|
25687
|
+
// src/hooks/hook-stdin.ts
|
|
25688
|
+
var DEFAULT_MAX_BYTES = 1024 * 1024;
|
|
25689
|
+
function readHookStdin(timeoutMs = 1e3, maxBytes = DEFAULT_MAX_BYTES) {
|
|
25690
|
+
return new Promise((resolve6, reject) => {
|
|
25691
|
+
const chunks = [];
|
|
25692
|
+
let bytes = 0;
|
|
25693
|
+
let settled = false;
|
|
25694
|
+
const finish = (error) => {
|
|
25695
|
+
if (settled) return;
|
|
25696
|
+
settled = true;
|
|
25697
|
+
clearTimeout(timer);
|
|
25698
|
+
process.stdin.removeAllListeners("data");
|
|
25699
|
+
process.stdin.removeAllListeners("end");
|
|
25700
|
+
process.stdin.removeAllListeners("error");
|
|
25701
|
+
if (error) reject(error);
|
|
25702
|
+
else resolve6(Buffer.concat(chunks, bytes).toString("utf-8"));
|
|
25703
|
+
};
|
|
25704
|
+
const timer = setTimeout(() => finish(new Error("stdin read timeout")), timeoutMs);
|
|
25705
|
+
process.stdin.on("data", (chunk) => {
|
|
25706
|
+
bytes += chunk.length;
|
|
25707
|
+
if (bytes > maxBytes) {
|
|
25708
|
+
finish(new Error("stdin envelope exceeds size limit"));
|
|
25709
|
+
return;
|
|
25710
|
+
}
|
|
25711
|
+
chunks.push(chunk);
|
|
25712
|
+
});
|
|
25713
|
+
process.stdin.on("end", () => finish());
|
|
25714
|
+
process.stdin.on("error", (error) => finish(error));
|
|
25715
|
+
});
|
|
25716
|
+
}
|
|
25717
|
+
|
|
25350
25718
|
// src/hooks/normalize.ts
|
|
25351
|
-
import { createHash as
|
|
25719
|
+
import { createHash as createHash7 } from "crypto";
|
|
25720
|
+
import { realpathSync as realpathSync3 } from "fs";
|
|
25721
|
+
import { isAbsolute as isAbsolute8, resolve as resolve5 } from "path";
|
|
25352
25722
|
var HERMES_EVENT_MAP = {
|
|
25353
25723
|
on_session_start: "SessionStart",
|
|
25354
25724
|
on_session_end: "SessionEnd",
|
|
@@ -25358,7 +25728,125 @@ var HERMES_EVENT_MAP = {
|
|
|
25358
25728
|
post_tool_call: "PostToolUse",
|
|
25359
25729
|
subagent_stop: "SubagentStop"
|
|
25360
25730
|
};
|
|
25731
|
+
var CURSOR_EVENT_MAP = {
|
|
25732
|
+
sessionStart: "SessionStart",
|
|
25733
|
+
beforeSubmitPrompt: "UserPromptSubmit",
|
|
25734
|
+
preToolUse: "PreToolUse",
|
|
25735
|
+
postToolUse: "PostToolUse",
|
|
25736
|
+
postToolUseFailure: "PostToolUseFailure",
|
|
25737
|
+
afterAgentResponse: "AssistantResponse",
|
|
25738
|
+
subagentStop: "SubagentStop",
|
|
25739
|
+
stop: "Stop",
|
|
25740
|
+
sessionEnd: "SessionEnd"
|
|
25741
|
+
};
|
|
25742
|
+
var CURSOR_TOOL_EVENTS = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse", "PostToolUseFailure"]);
|
|
25743
|
+
var SAFE_CORRELATION_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/u;
|
|
25744
|
+
var CURSOR_LOCAL_ONLY_FIELDS = /* @__PURE__ */ new Set([
|
|
25745
|
+
"conversation_id",
|
|
25746
|
+
"generation_id",
|
|
25747
|
+
"user_email",
|
|
25748
|
+
"account_email",
|
|
25749
|
+
"transcript_path",
|
|
25750
|
+
"transcript",
|
|
25751
|
+
"thought",
|
|
25752
|
+
"thoughts",
|
|
25753
|
+
"thinking",
|
|
25754
|
+
"tool_output"
|
|
25755
|
+
]);
|
|
25756
|
+
function requiredId(value, field) {
|
|
25757
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
25758
|
+
throw new TypeError(`Cursor hook envelope is missing ${field}`);
|
|
25759
|
+
}
|
|
25760
|
+
return value;
|
|
25761
|
+
}
|
|
25762
|
+
function cursorToolUseId(value) {
|
|
25763
|
+
if (SAFE_CORRELATION_ID_RE.test(value)) return value;
|
|
25764
|
+
return `cursor:tool:v1:${createHash7("sha256").update(value).digest("hex")}`;
|
|
25765
|
+
}
|
|
25766
|
+
function workspaceCandidates(value) {
|
|
25767
|
+
if (!Array.isArray(value)) return [];
|
|
25768
|
+
const roots = value.filter((item) => typeof item === "string" && item.length > 0);
|
|
25769
|
+
if (roots.some((root) => !isAbsolute8(root))) {
|
|
25770
|
+
throw new TypeError("Cursor workspace roots must be absolute");
|
|
25771
|
+
}
|
|
25772
|
+
return roots;
|
|
25773
|
+
}
|
|
25774
|
+
function pathIdentity(path) {
|
|
25775
|
+
try {
|
|
25776
|
+
return realpathSync3.native(path);
|
|
25777
|
+
} catch {
|
|
25778
|
+
return resolve5(path);
|
|
25779
|
+
}
|
|
25780
|
+
}
|
|
25781
|
+
function resolveCursorCwd(parsed) {
|
|
25782
|
+
const roots = workspaceCandidates(parsed.workspace_roots).map(pathIdentity);
|
|
25783
|
+
const rootRepositories = roots.map((root) => resolveRepositoryContext(root)?.repoRoot);
|
|
25784
|
+
const repositoryRoots = new Set(rootRepositories.filter((root) => !!root));
|
|
25785
|
+
if (repositoryRoots.size > 1) {
|
|
25786
|
+
throw new TypeError("Cursor hook envelope spans multiple repositories");
|
|
25787
|
+
}
|
|
25788
|
+
if (roots.length > 1 && rootRepositories.some((root) => root === void 0)) {
|
|
25789
|
+
throw new TypeError("Cursor hook envelope has ambiguous workspace roots");
|
|
25790
|
+
}
|
|
25791
|
+
const expectedRepo = [...repositoryRoots][0];
|
|
25792
|
+
const rawCwd = typeof parsed.cwd === "string" && parsed.cwd.length > 0 ? parsed.cwd : void 0;
|
|
25793
|
+
if (rawCwd && !isAbsolute8(rawCwd)) {
|
|
25794
|
+
throw new TypeError("Cursor hook cwd must be absolute");
|
|
25795
|
+
}
|
|
25796
|
+
const envelopeCwd = rawCwd ? pathIdentity(rawCwd) : void 0;
|
|
25797
|
+
const input = typeof parsed.tool_input === "object" && parsed.tool_input !== null && !Array.isArray(parsed.tool_input) ? parsed.tool_input : void 0;
|
|
25798
|
+
const rawToolCwd = parsed.tool_name === "Shell" && typeof input?.working_directory === "string" ? input.working_directory : void 0;
|
|
25799
|
+
const base = envelopeCwd ?? (roots.length === 1 ? roots[0] : expectedRepo);
|
|
25800
|
+
if (rawToolCwd && !isAbsolute8(rawToolCwd) && !base) {
|
|
25801
|
+
throw new TypeError("relative Cursor tool cwd has no workspace base");
|
|
25802
|
+
}
|
|
25803
|
+
const toolCwd = rawToolCwd ? pathIdentity(isAbsolute8(rawToolCwd) ? rawToolCwd : resolve5(base, rawToolCwd)) : void 0;
|
|
25804
|
+
const selected = toolCwd ?? envelopeCwd ?? (roots.length === 1 ? roots[0] : expectedRepo);
|
|
25805
|
+
if (!selected) {
|
|
25806
|
+
throw new TypeError("Cursor hook envelope has no unambiguous workspace");
|
|
25807
|
+
}
|
|
25808
|
+
const selectedRepo = resolveRepositoryContext(selected)?.repoRoot;
|
|
25809
|
+
if (expectedRepo && selectedRepo !== expectedRepo) {
|
|
25810
|
+
throw new TypeError("Cursor hook cwd conflicts with workspace repository");
|
|
25811
|
+
}
|
|
25812
|
+
return selected;
|
|
25813
|
+
}
|
|
25814
|
+
function normalizeCursorEnvelope(parsed) {
|
|
25815
|
+
const rawEvent = requiredId(parsed.hook_event_name, "hook_event_name");
|
|
25816
|
+
const event = CURSOR_EVENT_MAP[rawEvent];
|
|
25817
|
+
if (!event) throw new TypeError(`unsupported Cursor hook event: ${rawEvent}`);
|
|
25818
|
+
const sessionId = requiredId(parsed.conversation_id, "conversation_id");
|
|
25819
|
+
const turnId = requiredId(parsed.generation_id, "generation_id");
|
|
25820
|
+
if (parsed.session_id !== void 0 && parsed.session_id !== sessionId) {
|
|
25821
|
+
throw new TypeError("Cursor conversation_id conflicts with session_id");
|
|
25822
|
+
}
|
|
25823
|
+
if (parsed.turn_id !== void 0 && parsed.turn_id !== turnId) {
|
|
25824
|
+
throw new TypeError("Cursor generation_id conflicts with turn_id");
|
|
25825
|
+
}
|
|
25826
|
+
const rawToolUseId = CURSOR_TOOL_EVENTS.has(event) ? requiredId(parsed.tool_use_id, "tool_use_id") : void 0;
|
|
25827
|
+
const normalized = {
|
|
25828
|
+
...Object.fromEntries(
|
|
25829
|
+
Object.entries(parsed).filter(([key]) => !CURSOR_LOCAL_ONLY_FIELDS.has(key))
|
|
25830
|
+
),
|
|
25831
|
+
hook_event_name: event,
|
|
25832
|
+
session_id: sessionId,
|
|
25833
|
+
turn_id: turnId,
|
|
25834
|
+
cwd: resolveCursorCwd(parsed),
|
|
25835
|
+
...rawToolUseId === void 0 ? {} : { tool_use_id: cursorToolUseId(rawToolUseId) }
|
|
25836
|
+
};
|
|
25837
|
+
if (typeof parsed.tool_output === "string") {
|
|
25838
|
+
try {
|
|
25839
|
+
normalized.tool_response = JSON.parse(parsed.tool_output);
|
|
25840
|
+
} catch {
|
|
25841
|
+
normalized.tool_response = parsed.tool_output;
|
|
25842
|
+
}
|
|
25843
|
+
}
|
|
25844
|
+
return normalized;
|
|
25845
|
+
}
|
|
25361
25846
|
function normalizeEnvelope(parsed, agent) {
|
|
25847
|
+
if (agent === "cursor") {
|
|
25848
|
+
return normalizeCursorEnvelope(parsed);
|
|
25849
|
+
}
|
|
25362
25850
|
if (agent === "codex") {
|
|
25363
25851
|
const event = parsed.hook_event_name;
|
|
25364
25852
|
if ((event === "PreToolUse" || event === "PostToolUse") && (typeof parsed.tool_use_id !== "string" || parsed.tool_use_id.length === 0)) {
|
|
@@ -25370,7 +25858,7 @@ function normalizeEnvelope(parsed, agent) {
|
|
|
25370
25858
|
]);
|
|
25371
25859
|
return {
|
|
25372
25860
|
...parsed,
|
|
25373
|
-
tool_use_id: `codex:fallback:v1:${
|
|
25861
|
+
tool_use_id: `codex:fallback:v1:${createHash7("sha256").update(stableToolIdentity).digest("hex")}`
|
|
25374
25862
|
};
|
|
25375
25863
|
}
|
|
25376
25864
|
return parsed;
|
|
@@ -25386,15 +25874,15 @@ function normalizeEnvelope(parsed, agent) {
|
|
|
25386
25874
|
}
|
|
25387
25875
|
|
|
25388
25876
|
// src/hooks/prim-hook-core.ts
|
|
25389
|
-
import { createHash as
|
|
25877
|
+
import { createHash as createHash8, randomUUID as randomUUID3 } from "crypto";
|
|
25390
25878
|
import { platform } from "os";
|
|
25391
25879
|
|
|
25392
25880
|
// src/protocol/move.ts
|
|
25393
25881
|
var AGENT_ENVELOPE_VERSION = 3;
|
|
25394
25882
|
|
|
25395
25883
|
// src/hooks/redact.ts
|
|
25396
|
-
import { existsSync as
|
|
25397
|
-
import { join as
|
|
25884
|
+
import { existsSync as existsSync11, readFileSync as readFileSync13, statSync as statSync5 } from "fs";
|
|
25885
|
+
import { join as join15 } from "path";
|
|
25398
25886
|
import { Worker } from "worker_threads";
|
|
25399
25887
|
|
|
25400
25888
|
// src/lib/ansi.ts
|
|
@@ -25481,15 +25969,15 @@ function normalizedWorkspaceFlags(value) {
|
|
|
25481
25969
|
return [...new Set(`g${requested}`)].sort().join("");
|
|
25482
25970
|
}
|
|
25483
25971
|
function loadWorkspaceRules(cwd) {
|
|
25484
|
-
const path =
|
|
25485
|
-
if (!
|
|
25972
|
+
const path = join15(cwd, WORKSPACE_FILE2);
|
|
25973
|
+
if (!existsSync11(path)) return [];
|
|
25486
25974
|
let cfg;
|
|
25487
25975
|
try {
|
|
25488
|
-
if (
|
|
25976
|
+
if (statSync5(path).size > MAX_WORKSPACE_CONFIG_BYTES) {
|
|
25489
25977
|
debugRedaction(`ignoring oversized ${WORKSPACE_FILE2}`);
|
|
25490
25978
|
return [];
|
|
25491
25979
|
}
|
|
25492
|
-
cfg = JSON.parse(
|
|
25980
|
+
cfg = JSON.parse(readFileSync13(path, "utf-8"));
|
|
25493
25981
|
} catch {
|
|
25494
25982
|
debugRedaction(`ignoring unparseable ${WORKSPACE_FILE2}`);
|
|
25495
25983
|
return [];
|
|
@@ -25608,7 +26096,7 @@ function applyWorkspaceRules(value, rules) {
|
|
|
25608
26096
|
flags: pattern.flags,
|
|
25609
26097
|
reason
|
|
25610
26098
|
}));
|
|
25611
|
-
return new Promise((
|
|
26099
|
+
return new Promise((resolve6) => {
|
|
25612
26100
|
let worker;
|
|
25613
26101
|
try {
|
|
25614
26102
|
worker = new Worker(WORKSPACE_REDACTION_WORKER, {
|
|
@@ -25616,7 +26104,7 @@ function applyWorkspaceRules(value, rules) {
|
|
|
25616
26104
|
workerData: { value, rules: serialized }
|
|
25617
26105
|
});
|
|
25618
26106
|
} catch {
|
|
25619
|
-
|
|
26107
|
+
resolve6(redactEveryString(value, "workspace-rule-failed"));
|
|
25620
26108
|
return;
|
|
25621
26109
|
}
|
|
25622
26110
|
let settled = false;
|
|
@@ -25625,7 +26113,7 @@ function applyWorkspaceRules(value, rules) {
|
|
|
25625
26113
|
settled = true;
|
|
25626
26114
|
clearTimeout(timer);
|
|
25627
26115
|
void worker.terminate();
|
|
25628
|
-
|
|
26116
|
+
resolve6(result);
|
|
25629
26117
|
};
|
|
25630
26118
|
const failClosed = () => finish(redactEveryString(value, "workspace-rule-failed"));
|
|
25631
26119
|
const timer = setTimeout(failClosed, WORKSPACE_RULE_TIMEOUT_MS);
|
|
@@ -25679,6 +26167,17 @@ function toolOutcomeFor(parsed, agent) {
|
|
|
25679
26167
|
if (agent === "codex") {
|
|
25680
26168
|
return event === "PostToolUse" ? "returned" : void 0;
|
|
25681
26169
|
}
|
|
26170
|
+
if (agent === "cursor") {
|
|
26171
|
+
if (event === "PostToolUse") return "succeeded";
|
|
26172
|
+
if (event === "PostToolUseFailure") {
|
|
26173
|
+
if (parsed.is_interrupt === true) return "interrupted";
|
|
26174
|
+
const failureType = lowerString(parsed.failure_type);
|
|
26175
|
+
if (failureType === "permission_denied") return "prevented";
|
|
26176
|
+
if (failureType === "error" || failureType === "timeout") return "failed";
|
|
26177
|
+
return "unknown";
|
|
26178
|
+
}
|
|
26179
|
+
return void 0;
|
|
26180
|
+
}
|
|
25682
26181
|
const extra = parsed.extra;
|
|
25683
26182
|
if (event === "post_approval_response") {
|
|
25684
26183
|
const choice = lowerString(extra?.choice);
|
|
@@ -25708,9 +26207,9 @@ function toMove(parsed, cliVersion, agent = "claude_code", workspaceId, reposito
|
|
|
25708
26207
|
const toolOutcome = toolOutcomeFor(parsed, agent);
|
|
25709
26208
|
let moveId;
|
|
25710
26209
|
if (CORRELATED_TOOL_EVENTS.has(eventType) && sessionId && invocationId) {
|
|
25711
|
-
moveId = `posttool:v1:${
|
|
25712
|
-
} else if (CORRELATED_TOOL_EVENTS.has(eventType) && sessionId) {
|
|
25713
|
-
moveId = `posttool:fallback:v1:${
|
|
26210
|
+
moveId = `posttool:v1:${createHash8("sha256").update(JSON.stringify([agent, sessionId, eventType, invocationId])).digest("hex")}`;
|
|
26211
|
+
} else if (CORRELATED_TOOL_EVENTS.has(eventType) && sessionId && agent !== "cursor") {
|
|
26212
|
+
moveId = `posttool:fallback:v1:${createHash8("sha256").update(
|
|
25714
26213
|
JSON.stringify([
|
|
25715
26214
|
agent,
|
|
25716
26215
|
sessionId,
|
|
@@ -25748,12 +26247,12 @@ function toMove(parsed, cliVersion, agent = "claude_code", workspaceId, reposito
|
|
|
25748
26247
|
...toolOutcome ? { toolOutcome } : {}
|
|
25749
26248
|
};
|
|
25750
26249
|
}
|
|
25751
|
-
function shouldFlushAfter(eventType) {
|
|
25752
|
-
return eventType === "SessionEnd";
|
|
26250
|
+
function shouldFlushAfter(eventType, agent = "claude_code") {
|
|
26251
|
+
return eventType === "SessionEnd" || agent === "cursor" && eventType === "Stop";
|
|
25753
26252
|
}
|
|
25754
26253
|
|
|
25755
26254
|
// src/hooks/prim-hook.ts
|
|
25756
|
-
var here =
|
|
26255
|
+
var here = dirname11(fileURLToPath2(import.meta.url));
|
|
25757
26256
|
var outputAttempted = false;
|
|
25758
26257
|
function emitOutput(output, acknowledge) {
|
|
25759
26258
|
outputAttempted = true;
|
|
@@ -25761,14 +26260,14 @@ function emitOutput(output, acknowledge) {
|
|
|
25761
26260
|
}
|
|
25762
26261
|
function resolveCliVersion() {
|
|
25763
26262
|
try {
|
|
25764
|
-
const pkg = JSON.parse(
|
|
26263
|
+
const pkg = JSON.parse(readFileSync14(join16(here, "..", "..", "package.json"), "utf-8"));
|
|
25765
26264
|
return pkg.version ?? "unknown";
|
|
25766
26265
|
} catch {
|
|
25767
26266
|
return "unknown";
|
|
25768
26267
|
}
|
|
25769
26268
|
}
|
|
25770
26269
|
function spawnBackgroundFlush() {
|
|
25771
|
-
const entry =
|
|
26270
|
+
const entry = join16(here, "..", "index.js");
|
|
25772
26271
|
spawn(process.execPath, [entry, "moves", "flush"], {
|
|
25773
26272
|
detached: true,
|
|
25774
26273
|
stdio: "ignore"
|
|
@@ -25780,18 +26279,22 @@ async function main() {
|
|
|
25780
26279
|
let raw;
|
|
25781
26280
|
let parsed;
|
|
25782
26281
|
try {
|
|
25783
|
-
raw =
|
|
25784
|
-
|
|
26282
|
+
raw = await readHookStdin();
|
|
26283
|
+
const incoming = JSON.parse(raw);
|
|
26284
|
+
if (agent !== "cursor" && shouldSuppressImportedCursorHandler(incoming, "prim-hook")) return;
|
|
26285
|
+
parsed = normalizeEnvelope(incoming, agent);
|
|
25785
26286
|
} catch (error) {
|
|
25786
26287
|
writeHookDebug("capture failed", error);
|
|
25787
|
-
await emitOutput(
|
|
26288
|
+
await emitOutput(cursorPassiveOutput());
|
|
25788
26289
|
return;
|
|
25789
26290
|
}
|
|
25790
26291
|
const cwd = parsed.cwd ?? process.cwd();
|
|
25791
26292
|
const isClaudeStop = agent === "claude_code" && parsed.hook_event_name === "Stop";
|
|
25792
26293
|
const isCodexContextEvent = agent === "codex" && (parsed.hook_event_name === "UserPromptSubmit" || parsed.hook_event_name === "Stop");
|
|
25793
26294
|
if (!isRepoActiveForCapture(cwd)) {
|
|
25794
|
-
if (isClaudeStop || isCodexContextEvent)
|
|
26295
|
+
if (isClaudeStop || isCodexContextEvent || agent === "cursor") {
|
|
26296
|
+
await emitOutput(cursorPassiveOutput());
|
|
26297
|
+
}
|
|
25795
26298
|
return;
|
|
25796
26299
|
}
|
|
25797
26300
|
const identity = getOrCreateWorkspaceId(cwd);
|
|
@@ -25803,7 +26306,8 @@ async function main() {
|
|
|
25803
26306
|
const resolution = enrichment?.resolution;
|
|
25804
26307
|
const hasPathEvidence = resolution !== void 0 && (resolution.fileRefs.length > 0 || resolution.rejected.length > 0 || resolution.targetsIncomplete || resolution.targetsTruncated || resolution.shellMutation === "unresolved");
|
|
25805
26308
|
const pathsComplete = resolution !== void 0 && !resolution.targetsIncomplete && !resolution.targetsTruncated && resolution.rejected.length === 0 && resolution.shellMutation !== "unresolved";
|
|
25806
|
-
|
|
26309
|
+
const cursorAmbiguousTargets = agent === "cursor" && resolution !== void 0 && (resolution.rejected.length > 0 || resolution.targetsIncomplete || resolution.targetsTruncated || resolution.shellMutation === "unresolved");
|
|
26310
|
+
if (!cursorAmbiguousTargets && cachedCollectScopeAdmits(cwd, {
|
|
25807
26311
|
repository: resolvedRepository?.repoFullName,
|
|
25808
26312
|
branch: currentBranch(cwd),
|
|
25809
26313
|
agent,
|
|
@@ -25826,7 +26330,7 @@ async function main() {
|
|
|
25826
26330
|
};
|
|
25827
26331
|
const { orgId } = resolveOrg({ sessionId: move.sessionId, cwd });
|
|
25828
26332
|
appendMove(move, orgId);
|
|
25829
|
-
if (shouldFlushAfter(move.eventType)) {
|
|
26333
|
+
if (shouldFlushAfter(move.eventType, agent)) {
|
|
25830
26334
|
spawnBackgroundFlush();
|
|
25831
26335
|
}
|
|
25832
26336
|
}
|
|
@@ -25838,6 +26342,10 @@ async function main() {
|
|
|
25838
26342
|
await emitOutput(result.output, result.acknowledge);
|
|
25839
26343
|
return;
|
|
25840
26344
|
}
|
|
26345
|
+
if (agent === "cursor") {
|
|
26346
|
+
await emitOutput(cursorPassiveOutput());
|
|
26347
|
+
return;
|
|
26348
|
+
}
|
|
25841
26349
|
if (!isClaudeStop) return;
|
|
25842
26350
|
const sessionId = typeof parsed.session_id === "string" ? parsed.session_id : "";
|
|
25843
26351
|
if (!workspaceId || !sessionId) {
|
|
@@ -25866,5 +26374,13 @@ async function main() {
|
|
|
25866
26374
|
}
|
|
25867
26375
|
void main().catch(async (error) => {
|
|
25868
26376
|
writeHookDebug("capture failed", error);
|
|
25869
|
-
if (!outputAttempted) await emitOutput(
|
|
26377
|
+
if (!outputAttempted) await emitOutput(cursorPassiveOutput());
|
|
25870
26378
|
});
|
|
26379
|
+
function cursorPassiveOutput() {
|
|
26380
|
+
if (parseAgent(process.argv) !== "cursor") return buildHookOutput({});
|
|
26381
|
+
const index = process.argv.indexOf("--event");
|
|
26382
|
+
const event = index === -1 ? void 0 : process.argv[index + 1];
|
|
26383
|
+
if (event === "beforeSubmitPrompt") return { continue: true };
|
|
26384
|
+
if (event === "preToolUse") return { permission: "allow" };
|
|
26385
|
+
return {};
|
|
26386
|
+
}
|