@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
|
@@ -4963,7 +4963,7 @@ var require_rc = __commonJS({
|
|
|
4963
4963
|
"node_modules/.pnpm/rc@1.2.8/node_modules/rc/index.js"(exports, module) {
|
|
4964
4964
|
"use strict";
|
|
4965
4965
|
var cc = require_utils();
|
|
4966
|
-
var
|
|
4966
|
+
var join28 = __require("path").join;
|
|
4967
4967
|
var deepExtend = require_deep_extend();
|
|
4968
4968
|
var etc = "/etc";
|
|
4969
4969
|
var win = process.platform === "win32";
|
|
@@ -4988,15 +4988,15 @@ var require_rc = __commonJS({
|
|
|
4988
4988
|
}
|
|
4989
4989
|
if (!win)
|
|
4990
4990
|
[
|
|
4991
|
-
|
|
4992
|
-
|
|
4991
|
+
join28(etc, name, "config"),
|
|
4992
|
+
join28(etc, name + "rc")
|
|
4993
4993
|
].forEach(addConfigFile);
|
|
4994
4994
|
if (home)
|
|
4995
4995
|
[
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
4996
|
+
join28(home, ".config", name, "config"),
|
|
4997
|
+
join28(home, ".config", name),
|
|
4998
|
+
join28(home, "." + name, "config"),
|
|
4999
|
+
join28(home, "." + name + "rc")
|
|
5000
5000
|
].forEach(addConfigFile);
|
|
5001
5001
|
addConfigFile(cc.find("." + name + "rc"));
|
|
5002
5002
|
if (env4.config) addConfigFile(env4.config);
|
|
@@ -8896,7 +8896,7 @@ var require_ucs2length = __commonJS({
|
|
|
8896
8896
|
});
|
|
8897
8897
|
|
|
8898
8898
|
// src/index.ts
|
|
8899
|
-
import { readFileSync as
|
|
8899
|
+
import { readFileSync as readFileSync22 } from "fs";
|
|
8900
8900
|
import { dirname as dirname18, resolve as resolve10 } from "path";
|
|
8901
8901
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
8902
8902
|
|
|
@@ -13041,7 +13041,7 @@ var PRIM_REPO_SYNC_REPOSITORY_KEY = "prim.repoSyncRepository";
|
|
|
13041
13041
|
var PRIM_REPO_BINDING_STATE_KEY = "prim.repoBindingState";
|
|
13042
13042
|
var GIT_TIMEOUT_MS2 = 1e3;
|
|
13043
13043
|
var REPO_SYNC_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
13044
|
-
var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json"];
|
|
13044
|
+
var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json", ".cursor/hooks.json"];
|
|
13045
13045
|
var PRIM_HOOK_BINS = ["prim-hook", "prim-pre-tool-use", "prim-post-tool-use"];
|
|
13046
13046
|
function repoActiveFlag(cwd) {
|
|
13047
13047
|
try {
|
|
@@ -14850,7 +14850,7 @@ function validate23(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
14850
14850
|
}
|
|
14851
14851
|
validate23.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
14852
14852
|
var isDecisionCollectScopeResponse = validate24;
|
|
14853
|
-
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": {} };
|
|
14853
|
+
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": {} };
|
|
14854
14854
|
function validate24(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
14855
14855
|
;
|
|
14856
14856
|
let vErrors = null;
|
|
@@ -15401,7 +15401,7 @@ function validate24(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
15401
15401
|
}
|
|
15402
15402
|
errors++;
|
|
15403
15403
|
}
|
|
15404
|
-
if (!(data18 === "claude_code" || data18 === "codex" || data18 === "hermes")) {
|
|
15404
|
+
if (!(data18 === "claude_code" || data18 === "codex" || data18 === "cursor" || data18 === "hermes")) {
|
|
15405
15405
|
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" };
|
|
15406
15406
|
if (vErrors === null) {
|
|
15407
15407
|
vErrors = [err34];
|
|
@@ -16170,7 +16170,7 @@ function validate26(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
16170
16170
|
return errors === 0;
|
|
16171
16171
|
}
|
|
16172
16172
|
validate26.evaluated = { "dynamicProps": true, "dynamicItems": false };
|
|
16173
|
-
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"] };
|
|
16173
|
+
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"] };
|
|
16174
16174
|
function validate27(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
16175
16175
|
;
|
|
16176
16176
|
let vErrors = null;
|
|
@@ -16874,7 +16874,7 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
16874
16874
|
}
|
|
16875
16875
|
errors++;
|
|
16876
16876
|
}
|
|
16877
|
-
if (!(data34 === "claude_code" || data34 === "codex" || data34 === "hermes")) {
|
|
16877
|
+
if (!(data34 === "claude_code" || data34 === "codex" || data34 === "cursor" || data34 === "hermes")) {
|
|
16878
16878
|
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" };
|
|
16879
16879
|
if (vErrors === null) {
|
|
16880
16880
|
vErrors = [err19];
|
|
@@ -17102,7 +17102,7 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
17102
17102
|
return errors === 0;
|
|
17103
17103
|
}
|
|
17104
17104
|
validate27.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
17105
|
-
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": {} };
|
|
17105
|
+
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": {} };
|
|
17106
17106
|
function validate28(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
17107
17107
|
;
|
|
17108
17108
|
let vErrors = null;
|
|
@@ -17638,7 +17638,7 @@ function validate28(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
17638
17638
|
}
|
|
17639
17639
|
errors++;
|
|
17640
17640
|
}
|
|
17641
|
-
if (!(data22 === "claude_code" || data22 === "codex" || data22 === "hermes")) {
|
|
17641
|
+
if (!(data22 === "claude_code" || data22 === "codex" || data22 === "cursor" || data22 === "hermes")) {
|
|
17642
17642
|
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" };
|
|
17643
17643
|
if (vErrors === null) {
|
|
17644
17644
|
vErrors = [err19];
|
|
@@ -17870,7 +17870,7 @@ function validate28(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
17870
17870
|
return errors === 0;
|
|
17871
17871
|
}
|
|
17872
17872
|
validate28.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
17873
|
-
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": {} };
|
|
17873
|
+
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": {} };
|
|
17874
17874
|
function validate29(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
17875
17875
|
;
|
|
17876
17876
|
let vErrors = null;
|
|
@@ -19164,7 +19164,7 @@ function validate29(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
19164
19164
|
}
|
|
19165
19165
|
errors++;
|
|
19166
19166
|
}
|
|
19167
|
-
if (!(data70 === "claude_code" || data70 === "codex" || data70 === "hermes")) {
|
|
19167
|
+
if (!(data70 === "claude_code" || data70 === "codex" || data70 === "cursor" || data70 === "hermes")) {
|
|
19168
19168
|
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" };
|
|
19169
19169
|
if (vErrors === null) {
|
|
19170
19170
|
vErrors = [err24];
|
|
@@ -19727,7 +19727,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
19727
19727
|
}
|
|
19728
19728
|
validate33.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
19729
19729
|
var isDecisionRescopeRequest = validate34;
|
|
19730
|
-
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": {} };
|
|
19730
|
+
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": {} };
|
|
19731
19731
|
function validate34(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
19732
19732
|
;
|
|
19733
19733
|
let vErrors = null;
|
|
@@ -20368,7 +20368,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
20368
20368
|
}
|
|
20369
20369
|
errors++;
|
|
20370
20370
|
}
|
|
20371
|
-
if (!(data19 === "claude_code" || data19 === "codex" || data19 === "hermes")) {
|
|
20371
|
+
if (!(data19 === "claude_code" || data19 === "codex" || data19 === "cursor" || data19 === "hermes")) {
|
|
20372
20372
|
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" };
|
|
20373
20373
|
if (vErrors === null) {
|
|
20374
20374
|
vErrors = [err38];
|
|
@@ -20597,7 +20597,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
20597
20597
|
}
|
|
20598
20598
|
validate34.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
20599
20599
|
var isDecisionRescopeResponse = validate35;
|
|
20600
|
-
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": {} }] };
|
|
20600
|
+
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": {} }] };
|
|
20601
20601
|
function validate35(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
20602
20602
|
;
|
|
20603
20603
|
let vErrors = null;
|
|
@@ -21235,7 +21235,7 @@ function validate35(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
21235
21235
|
}
|
|
21236
21236
|
errors++;
|
|
21237
21237
|
}
|
|
21238
|
-
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "hermes")) {
|
|
21238
|
+
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "cursor" || data21 === "hermes")) {
|
|
21239
21239
|
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" };
|
|
21240
21240
|
if (vErrors === null) {
|
|
21241
21241
|
vErrors = [err41];
|
|
@@ -22159,7 +22159,7 @@ function validate35(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
22159
22159
|
}
|
|
22160
22160
|
errors++;
|
|
22161
22161
|
}
|
|
22162
|
-
if (!(data49 === "claude_code" || data49 === "codex" || data49 === "hermes")) {
|
|
22162
|
+
if (!(data49 === "claude_code" || data49 === "codex" || data49 === "cursor" || data49 === "hermes")) {
|
|
22163
22163
|
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" };
|
|
22164
22164
|
if (vErrors === null) {
|
|
22165
22165
|
vErrors = [err100];
|
|
@@ -27811,7 +27811,7 @@ function validate50(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
27811
27811
|
}
|
|
27812
27812
|
validate50.evaluated = { "dynamicProps": true, "dynamicItems": false };
|
|
27813
27813
|
var isMoveIngestRequest = validate51;
|
|
27814
|
-
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": {} };
|
|
27814
|
+
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": {} };
|
|
27815
27815
|
var pattern8 = new RegExp("^[A-Za-z0-9_-]+$", "u");
|
|
27816
27816
|
function validate51(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
27817
27817
|
;
|
|
@@ -28065,7 +28065,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
28065
28065
|
}
|
|
28066
28066
|
errors++;
|
|
28067
28067
|
}
|
|
28068
|
-
if (!(data10 === "claude_code" || data10 === "codex" || data10 === "hermes")) {
|
|
28068
|
+
if (!(data10 === "claude_code" || data10 === "codex" || data10 === "cursor" || data10 === "hermes")) {
|
|
28069
28069
|
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" };
|
|
28070
28070
|
if (vErrors === null) {
|
|
28071
28071
|
vErrors = [err16];
|
|
@@ -28377,7 +28377,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
28377
28377
|
}
|
|
28378
28378
|
errors++;
|
|
28379
28379
|
}
|
|
28380
|
-
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "hermes")) {
|
|
28380
|
+
if (!(data21 === "claude_code" || data21 === "codex" || data21 === "cursor" || data21 === "hermes")) {
|
|
28381
28381
|
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" };
|
|
28382
28382
|
if (vErrors === null) {
|
|
28383
28383
|
vErrors = [err38];
|
|
@@ -28514,7 +28514,7 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
28514
28514
|
return errors === 0;
|
|
28515
28515
|
}
|
|
28516
28516
|
validate51.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
28517
|
-
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"] };
|
|
28517
|
+
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"] };
|
|
28518
28518
|
var pattern10 = new RegExp("^[A-Za-z0-9._:-]{1,128}$", "u");
|
|
28519
28519
|
var pattern12 = new RegExp("^[A-Za-z0-9]{1,64}$", "u");
|
|
28520
28520
|
var pattern13 = new RegExp("^(?!@?$)(?!\\/)(?!.*\\/$)(?!.*\\/\\/)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)[^/]*\\.lock(?:\\/|$))(?!.*\\.\\.)(?!.*@\\{)(?!.*[~^:?*\\\\]).+$", "u");
|
|
@@ -28570,7 +28570,7 @@ function validate52(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
28570
28570
|
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" }];
|
|
28571
28571
|
return false;
|
|
28572
28572
|
}
|
|
28573
|
-
if (!(data1 === "claude_code" || data1 === "codex" || data1 === "hermes")) {
|
|
28573
|
+
if (!(data1 === "claude_code" || data1 === "codex" || data1 === "cursor" || data1 === "hermes")) {
|
|
28574
28574
|
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" }];
|
|
28575
28575
|
return false;
|
|
28576
28576
|
}
|
|
@@ -31883,7 +31883,7 @@ function optionalUserScopeMembers(record2) {
|
|
|
31883
31883
|
members.push({ kind: "role", role: candidate.role });
|
|
31884
31884
|
continue;
|
|
31885
31885
|
}
|
|
31886
|
-
if (candidate.kind === "agent" && (candidate.agent === "claude_code" || candidate.agent === "codex" || candidate.agent === "hermes")) {
|
|
31886
|
+
if (candidate.kind === "agent" && (candidate.agent === "claude_code" || candidate.agent === "codex" || candidate.agent === "cursor" || candidate.agent === "hermes")) {
|
|
31887
31887
|
members.push({ kind: "agent", agent: candidate.agent });
|
|
31888
31888
|
continue;
|
|
31889
31889
|
}
|
|
@@ -32187,7 +32187,7 @@ function stableHookCommand(bin, args = "") {
|
|
|
32187
32187
|
// it as inert data during the rolling window so an older uninstall or
|
|
32188
32188
|
// reinstall can remove the stable entry without invoking npm or PATH.
|
|
32189
32189
|
`prim_legacy_reader='-p ${PKG_NAME}@stable prim-shim.sh ${bin} '; `,
|
|
32190
|
-
'prim_absolute() { case "$1" in
|
|
32190
|
+
'prim_absolute() { case "$1" in [/]* ) ;; *) return 1 ;; esac; case "$1" in [[:space:]]*|*[[:space:]]|*[/][/]*|*[/].[/]*|*[/]..[/]*|*[/].|*[/]..|?*[/]) return 1 ;; esac; }; ',
|
|
32191
32191
|
'prim_config=${PRIM_CONFIG_DIR:-}; if ! prim_absolute "$prim_config"; then prim_config=${XDG_CONFIG_HOME:-}; if prim_absolute "$prim_config"; then ',
|
|
32192
32192
|
'case "$prim_config" in /) prim_config=/prim ;; *) prim_config="$prim_config/prim" ;; esac; ',
|
|
32193
32193
|
'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; ',
|
|
@@ -34963,7 +34963,7 @@ import {
|
|
|
34963
34963
|
utimesSync,
|
|
34964
34964
|
writeFileSync as writeFileSync6
|
|
34965
34965
|
} from "fs";
|
|
34966
|
-
import { dirname as dirname8, isAbsolute as isAbsolute5, join as join10, resolve as resolve5 } from "path";
|
|
34966
|
+
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute5, join as join10, resolve as resolve5 } from "path";
|
|
34967
34967
|
var HOOK_RUNTIME_SCHEMA_VERSION = 1;
|
|
34968
34968
|
var DIRECTORY_MODE2 = 448;
|
|
34969
34969
|
var DATA_FILE_MODE = 384;
|
|
@@ -35313,11 +35313,28 @@ function writeRelease(sourceDir, releaseDir, manifest, releasesDir) {
|
|
|
35313
35313
|
rmSync4(stagingDir, { recursive: true, force: true });
|
|
35314
35314
|
}
|
|
35315
35315
|
}
|
|
35316
|
+
function stableNodePath(execPath = process.execPath, searchPath = process.env.PATH ?? "") {
|
|
35317
|
+
let target;
|
|
35318
|
+
try {
|
|
35319
|
+
target = realpathSync2(execPath);
|
|
35320
|
+
} catch {
|
|
35321
|
+
return execPath;
|
|
35322
|
+
}
|
|
35323
|
+
for (const directory of searchPath.split(delimiter)) {
|
|
35324
|
+
if (!isAbsolute5(directory)) continue;
|
|
35325
|
+
const candidate = join10(directory, "node");
|
|
35326
|
+
try {
|
|
35327
|
+
if (realpathSync2(candidate) === target) return candidate;
|
|
35328
|
+
} catch {
|
|
35329
|
+
}
|
|
35330
|
+
}
|
|
35331
|
+
return execPath;
|
|
35332
|
+
}
|
|
35316
35333
|
function stageHookRuntime(options = {}) {
|
|
35317
35334
|
const root = packageRoot();
|
|
35318
35335
|
const sourceDir = options.sourceDir ?? (root ? join10(root, "dist", "hook-runtime") : null);
|
|
35319
35336
|
const version = options.version ?? packageVersion();
|
|
35320
|
-
const nodePath = resolve5(options.nodePath ??
|
|
35337
|
+
const nodePath = resolve5(options.nodePath ?? stableNodePath());
|
|
35321
35338
|
if (!sourceDir || !version || compareSemver(version, version) !== 0 || !isAbsolute5(nodePath) || /[\r\n]/u.test(nodePath)) {
|
|
35322
35339
|
throw new Error("cannot stage hook runtime: package identity is unavailable");
|
|
35323
35340
|
}
|
|
@@ -35805,7 +35822,7 @@ function performPermissionInstall(scope) {
|
|
|
35805
35822
|
};
|
|
35806
35823
|
}
|
|
35807
35824
|
function performStatus() {
|
|
35808
|
-
const
|
|
35825
|
+
const statusFor2 = (path9) => {
|
|
35809
35826
|
const settings = readSettings(path9);
|
|
35810
35827
|
return {
|
|
35811
35828
|
path: path9,
|
|
@@ -35818,7 +35835,7 @@ function performStatus() {
|
|
|
35818
35835
|
statuslineState: statuslineState(settings)
|
|
35819
35836
|
};
|
|
35820
35837
|
};
|
|
35821
|
-
return { user:
|
|
35838
|
+
return { user: statusFor2(USER_SCOPE_PATH), project: statusFor2(projectScopePath()) };
|
|
35822
35839
|
}
|
|
35823
35840
|
function resolveScope(input) {
|
|
35824
35841
|
if (input === void 0 || input === "project") {
|
|
@@ -36017,7 +36034,7 @@ function performUninstall2(scope) {
|
|
|
36017
36034
|
return resultFor(scope, path9, after, changed);
|
|
36018
36035
|
}
|
|
36019
36036
|
function performStatus2() {
|
|
36020
|
-
const
|
|
36037
|
+
const statusFor2 = (path9) => {
|
|
36021
36038
|
const settings = readSettings(path9);
|
|
36022
36039
|
return {
|
|
36023
36040
|
path: path9,
|
|
@@ -36027,7 +36044,7 @@ function performStatus2() {
|
|
|
36027
36044
|
complete: hasCompleteHookRegistration2(settings)
|
|
36028
36045
|
};
|
|
36029
36046
|
};
|
|
36030
|
-
return { user:
|
|
36047
|
+
return { user: statusFor2(USER_SCOPE_PATH2), project: statusFor2(projectScopePath2()) };
|
|
36031
36048
|
}
|
|
36032
36049
|
function resolveScope2(input) {
|
|
36033
36050
|
if (input === void 0 || input === "project") {
|
|
@@ -36079,14 +36096,302 @@ ${line("project", result.project)}`);
|
|
|
36079
36096
|
});
|
|
36080
36097
|
}
|
|
36081
36098
|
|
|
36099
|
+
// src/commands/cursor-install.ts
|
|
36100
|
+
import { existsSync as existsSync10, readFileSync as readFileSync11 } from "fs";
|
|
36101
|
+
import { homedir as homedir7 } from "os";
|
|
36102
|
+
import { isAbsolute as isAbsolute6, join as join13 } from "path";
|
|
36103
|
+
var CAPTURE_BIN3 = "prim-hook";
|
|
36104
|
+
var GATE_BIN3 = "prim-pre-tool-use";
|
|
36105
|
+
var POST_TOOL_BIN = "prim-post-tool-use";
|
|
36106
|
+
var SESSION_START_BIN3 = "prim-session-start";
|
|
36107
|
+
var SESSION_END_BIN2 = "prim-session-end";
|
|
36108
|
+
var STATUSLINE_BIN2 = "prim-statusline";
|
|
36109
|
+
var PRIM_BINS3 = [CAPTURE_BIN3, GATE_BIN3, POST_TOOL_BIN, SESSION_START_BIN3, SESSION_END_BIN2];
|
|
36110
|
+
var CURSOR_EVENTS = [
|
|
36111
|
+
"sessionStart",
|
|
36112
|
+
"beforeSubmitPrompt",
|
|
36113
|
+
"preToolUse",
|
|
36114
|
+
"postToolUse",
|
|
36115
|
+
"postToolUseFailure",
|
|
36116
|
+
"afterAgentResponse",
|
|
36117
|
+
"subagentStop",
|
|
36118
|
+
"stop",
|
|
36119
|
+
"sessionEnd"
|
|
36120
|
+
];
|
|
36121
|
+
var REGISTRATIONS2 = [
|
|
36122
|
+
...CURSOR_EVENTS.map((event) => ({ event, bin: CAPTURE_BIN3 })),
|
|
36123
|
+
{ event: "preToolUse", bin: GATE_BIN3, matcher: "Write|Delete|Shell", timeout: 10 },
|
|
36124
|
+
{ event: "postToolUse", bin: POST_TOOL_BIN },
|
|
36125
|
+
{ event: "postToolUseFailure", bin: POST_TOOL_BIN },
|
|
36126
|
+
{ event: "sessionStart", bin: SESSION_START_BIN3 },
|
|
36127
|
+
{ event: "sessionEnd", bin: SESSION_END_BIN2 }
|
|
36128
|
+
];
|
|
36129
|
+
function cursorConfigDirectory(env4 = process.env, home = homedir7(), platform2 = process.platform) {
|
|
36130
|
+
const explicit = env4.CURSOR_CONFIG_DIR?.trim();
|
|
36131
|
+
if (explicit && isAbsolute6(explicit)) return explicit;
|
|
36132
|
+
const xdg = env4.XDG_CONFIG_HOME?.trim();
|
|
36133
|
+
if (platform2 !== "darwin" && xdg && isAbsolute6(xdg)) return join13(xdg, "cursor");
|
|
36134
|
+
return join13(home, ".cursor");
|
|
36135
|
+
}
|
|
36136
|
+
function cursorHooksPath(scope, root = projectRoot()) {
|
|
36137
|
+
return scope === "user" ? join13(cursorConfigDirectory(), "hooks.json") : join13(root, ".cursor", "hooks.json");
|
|
36138
|
+
}
|
|
36139
|
+
function cursorCliConfigPath() {
|
|
36140
|
+
return join13(cursorConfigDirectory(), "cli-config.json");
|
|
36141
|
+
}
|
|
36142
|
+
function plainObject(value) {
|
|
36143
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36144
|
+
}
|
|
36145
|
+
function readCursorHooks(path9) {
|
|
36146
|
+
if (!existsSync10(path9)) return {};
|
|
36147
|
+
let parsed;
|
|
36148
|
+
try {
|
|
36149
|
+
parsed = JSON.parse(readFileSync11(path9, "utf8"));
|
|
36150
|
+
} catch {
|
|
36151
|
+
throw new Error(`invalid Cursor hooks JSON at ${path9}`);
|
|
36152
|
+
}
|
|
36153
|
+
if (!plainObject(parsed)) throw new Error(`Cursor hooks config must be an object: ${path9}`);
|
|
36154
|
+
if (parsed.version !== void 0 && parsed.version !== 1) {
|
|
36155
|
+
throw new Error(`unsupported Cursor hooks version at ${path9} (expected version 1)`);
|
|
36156
|
+
}
|
|
36157
|
+
if (parsed.hooks !== void 0) {
|
|
36158
|
+
if (!plainObject(parsed.hooks)) throw new Error(`Cursor hooks must be an object: ${path9}`);
|
|
36159
|
+
for (const [event, entries] of Object.entries(parsed.hooks)) {
|
|
36160
|
+
if (!Array.isArray(entries) || !entries.every(plainObject)) {
|
|
36161
|
+
throw new Error(`Cursor hook list must contain objects: ${event} in ${path9}`);
|
|
36162
|
+
}
|
|
36163
|
+
}
|
|
36164
|
+
}
|
|
36165
|
+
return parsed;
|
|
36166
|
+
}
|
|
36167
|
+
function readObject(path9) {
|
|
36168
|
+
if (!existsSync10(path9)) return {};
|
|
36169
|
+
let parsed;
|
|
36170
|
+
try {
|
|
36171
|
+
parsed = JSON.parse(readFileSync11(path9, "utf8"));
|
|
36172
|
+
} catch {
|
|
36173
|
+
throw new Error(`invalid Cursor CLI config JSON at ${path9}`);
|
|
36174
|
+
}
|
|
36175
|
+
if (!plainObject(parsed)) throw new Error(`Cursor CLI config must be an object: ${path9}`);
|
|
36176
|
+
return parsed;
|
|
36177
|
+
}
|
|
36178
|
+
function writeJson(path9, value) {
|
|
36179
|
+
atomicWriteFile(path9, `${JSON.stringify(value, null, 2)}
|
|
36180
|
+
`, { ensureParent: true });
|
|
36181
|
+
}
|
|
36182
|
+
function commandFor(registration, scope) {
|
|
36183
|
+
return stableHookCommand(
|
|
36184
|
+
registration.bin,
|
|
36185
|
+
`--agent cursor --event ${registration.event} --scope ${scope}`
|
|
36186
|
+
);
|
|
36187
|
+
}
|
|
36188
|
+
var OWNED_COMMANDS = new Set(
|
|
36189
|
+
["project", "user"].flatMap(
|
|
36190
|
+
(scope) => REGISTRATIONS2.map((registration) => commandFor(registration, scope))
|
|
36191
|
+
)
|
|
36192
|
+
);
|
|
36193
|
+
function jsoncUnsafeCommand(command) {
|
|
36194
|
+
return command.replace('case "$1" in [/]* ', 'case "$1" in /*').replace("*[/][/]*", "*//*").replace("*[/].[/]*", "*/./*").replace("*[/]..[/]*", "*/../*").replace("*[/].", "*/.").replace("*[/]..", "*/..").replace("?*[/]", "?*/");
|
|
36195
|
+
}
|
|
36196
|
+
var JSONC_UNSAFE_OWNED_COMMANDS = new Set([...OWNED_COMMANDS].map(jsoncUnsafeCommand));
|
|
36197
|
+
function isOwnedCursorHookCommand(command) {
|
|
36198
|
+
return typeof command === "string" && (OWNED_COMMANDS.has(command) || JSONC_UNSAFE_OWNED_COMMANDS.has(command));
|
|
36199
|
+
}
|
|
36200
|
+
function hookFor(registration, scope) {
|
|
36201
|
+
return {
|
|
36202
|
+
command: commandFor(registration, scope),
|
|
36203
|
+
...registration.matcher ? { matcher: registration.matcher } : {},
|
|
36204
|
+
...registration.timeout ? { timeout: registration.timeout } : {}
|
|
36205
|
+
};
|
|
36206
|
+
}
|
|
36207
|
+
function exactHook(entry, registration, scope) {
|
|
36208
|
+
return JSON.stringify(entry) === JSON.stringify(hookFor(registration, scope));
|
|
36209
|
+
}
|
|
36210
|
+
function applyCursorInstall(settings, scope) {
|
|
36211
|
+
const hooks = {};
|
|
36212
|
+
for (const [event, entries] of Object.entries(settings.hooks ?? {})) {
|
|
36213
|
+
hooks[event] = entries.filter((entry) => !isOwnedCursorHookCommand(entry.command));
|
|
36214
|
+
}
|
|
36215
|
+
for (const registration of REGISTRATIONS2) {
|
|
36216
|
+
const entries = hooks[registration.event] ?? [];
|
|
36217
|
+
entries.push(hookFor(registration, scope));
|
|
36218
|
+
hooks[registration.event] = entries;
|
|
36219
|
+
}
|
|
36220
|
+
return { ...settings, version: 1, hooks };
|
|
36221
|
+
}
|
|
36222
|
+
function applyCursorUninstall(settings) {
|
|
36223
|
+
const hooks = {};
|
|
36224
|
+
for (const [event, entries] of Object.entries(settings.hooks ?? {})) {
|
|
36225
|
+
const retained = entries.filter((entry) => !isOwnedCursorHookCommand(entry.command));
|
|
36226
|
+
if (retained.length > 0) hooks[event] = retained;
|
|
36227
|
+
}
|
|
36228
|
+
return { ...settings, hooks };
|
|
36229
|
+
}
|
|
36230
|
+
function ownedEntries(settings) {
|
|
36231
|
+
return Object.entries(settings.hooks ?? {}).flatMap(
|
|
36232
|
+
([event, entries]) => entries.filter((entry) => isOwnedCursorHookCommand(entry.command)).map((entry) => ({ event, entry }))
|
|
36233
|
+
);
|
|
36234
|
+
}
|
|
36235
|
+
function hasExactCursorHandler(settings, event, bin, scope) {
|
|
36236
|
+
const registration = REGISTRATIONS2.find(
|
|
36237
|
+
(candidate) => candidate.event === event && candidate.bin === bin
|
|
36238
|
+
);
|
|
36239
|
+
return registration ? (settings.hooks?.[event] ?? []).some((entry) => exactHook(entry, registration, scope)) : false;
|
|
36240
|
+
}
|
|
36241
|
+
function complete(settings, scope) {
|
|
36242
|
+
const owned = ownedEntries(settings);
|
|
36243
|
+
return owned.length === REGISTRATIONS2.length && REGISTRATIONS2.every(
|
|
36244
|
+
(registration) => owned.filter(
|
|
36245
|
+
({ event, entry }) => event === registration.event && exactHook(entry, registration, scope)
|
|
36246
|
+
).length === 1
|
|
36247
|
+
);
|
|
36248
|
+
}
|
|
36249
|
+
function captureInstalled3(settings, scope) {
|
|
36250
|
+
return CURSOR_EVENTS.every((event) => hasExactCursorHandler(settings, event, CAPTURE_BIN3, scope));
|
|
36251
|
+
}
|
|
36252
|
+
function gateInstalled(settings, scope) {
|
|
36253
|
+
return hasExactCursorHandler(settings, "preToolUse", GATE_BIN3, scope);
|
|
36254
|
+
}
|
|
36255
|
+
var FOOTER = {
|
|
36256
|
+
type: "command",
|
|
36257
|
+
command: stableHookCommand(STATUSLINE_BIN2),
|
|
36258
|
+
updateIntervalMs: 1e3,
|
|
36259
|
+
timeoutMs: 2e3
|
|
36260
|
+
};
|
|
36261
|
+
var JSONC_UNSAFE_FOOTER = {
|
|
36262
|
+
...FOOTER,
|
|
36263
|
+
command: jsoncUnsafeCommand(FOOTER.command)
|
|
36264
|
+
};
|
|
36265
|
+
function exactFooter(value) {
|
|
36266
|
+
return plainObject(value) && JSON.stringify(value) === JSON.stringify(FOOTER);
|
|
36267
|
+
}
|
|
36268
|
+
function jsoncUnsafeFooter(value) {
|
|
36269
|
+
return plainObject(value) && JSON.stringify(value) === JSON.stringify(JSONC_UNSAFE_FOOTER);
|
|
36270
|
+
}
|
|
36271
|
+
function applyCursorFooterInstall(config) {
|
|
36272
|
+
if (config.statusLine === void 0)
|
|
36273
|
+
return { config: { ...config, statusLine: FOOTER }, installed: true, preservedCustom: false };
|
|
36274
|
+
if (exactFooter(config.statusLine)) return { config, installed: true, preservedCustom: false };
|
|
36275
|
+
if (jsoncUnsafeFooter(config.statusLine)) {
|
|
36276
|
+
return { config: { ...config, statusLine: FOOTER }, installed: true, preservedCustom: false };
|
|
36277
|
+
}
|
|
36278
|
+
return { config, installed: false, preservedCustom: true };
|
|
36279
|
+
}
|
|
36280
|
+
function applyCursorFooterUninstall(config) {
|
|
36281
|
+
if (!exactFooter(config.statusLine) && !jsoncUnsafeFooter(config.statusLine)) {
|
|
36282
|
+
return { config, removed: false };
|
|
36283
|
+
}
|
|
36284
|
+
return {
|
|
36285
|
+
config: Object.fromEntries(Object.entries(config).filter(([key]) => key !== "statusLine")),
|
|
36286
|
+
removed: true
|
|
36287
|
+
};
|
|
36288
|
+
}
|
|
36289
|
+
function statusFor(scope, path9 = cursorHooksPath(scope)) {
|
|
36290
|
+
const settings = readCursorHooks(path9);
|
|
36291
|
+
const base = {
|
|
36292
|
+
path: path9,
|
|
36293
|
+
present: ownedEntries(settings).length > 0,
|
|
36294
|
+
gate: gateInstalled(settings, scope),
|
|
36295
|
+
capture: captureInstalled3(settings, scope),
|
|
36296
|
+
complete: complete(settings, scope)
|
|
36297
|
+
};
|
|
36298
|
+
if (scope === "user") {
|
|
36299
|
+
const cliConfig = readObject(cursorCliConfigPath());
|
|
36300
|
+
base.footer = exactFooter(cliConfig.statusLine);
|
|
36301
|
+
base.footerPreservedCustom = cliConfig.statusLine !== void 0 && !base.footer;
|
|
36302
|
+
}
|
|
36303
|
+
return base;
|
|
36304
|
+
}
|
|
36305
|
+
function performInstall3(scope, _force = false) {
|
|
36306
|
+
stageHookRuntime();
|
|
36307
|
+
const path9 = cursorHooksPath(scope);
|
|
36308
|
+
const before = readCursorHooks(path9);
|
|
36309
|
+
const after = applyCursorInstall(before, scope);
|
|
36310
|
+
let changed = JSON.stringify(before) !== JSON.stringify(after);
|
|
36311
|
+
if (changed) writeJson(path9, after);
|
|
36312
|
+
let restartRequired = false;
|
|
36313
|
+
if (scope === "user") {
|
|
36314
|
+
const cliPath = cursorCliConfigPath();
|
|
36315
|
+
const cliBefore = readObject(cliPath);
|
|
36316
|
+
const footer = applyCursorFooterInstall(cliBefore);
|
|
36317
|
+
if (JSON.stringify(cliBefore) !== JSON.stringify(footer.config)) {
|
|
36318
|
+
writeJson(cliPath, footer.config);
|
|
36319
|
+
changed = true;
|
|
36320
|
+
restartRequired = true;
|
|
36321
|
+
}
|
|
36322
|
+
}
|
|
36323
|
+
return { scope, ...statusFor(scope, path9), changed, restartRequired };
|
|
36324
|
+
}
|
|
36325
|
+
function performUninstall3(scope) {
|
|
36326
|
+
const path9 = cursorHooksPath(scope);
|
|
36327
|
+
const before = readCursorHooks(path9);
|
|
36328
|
+
const after = applyCursorUninstall(before);
|
|
36329
|
+
let changed = JSON.stringify(before) !== JSON.stringify(after);
|
|
36330
|
+
if (changed) writeJson(path9, after);
|
|
36331
|
+
let restartRequired = false;
|
|
36332
|
+
if (scope === "user") {
|
|
36333
|
+
const cliPath = cursorCliConfigPath();
|
|
36334
|
+
const cliBefore = readObject(cliPath);
|
|
36335
|
+
const footer = applyCursorFooterUninstall(cliBefore);
|
|
36336
|
+
if (footer.removed) {
|
|
36337
|
+
writeJson(cliPath, footer.config);
|
|
36338
|
+
changed = true;
|
|
36339
|
+
restartRequired = true;
|
|
36340
|
+
}
|
|
36341
|
+
}
|
|
36342
|
+
return { scope, ...statusFor(scope, path9), changed, restartRequired };
|
|
36343
|
+
}
|
|
36344
|
+
function performStatus3() {
|
|
36345
|
+
return { user: statusFor("user"), project: statusFor("project") };
|
|
36346
|
+
}
|
|
36347
|
+
function inspectHookRuntimeResolutions3() {
|
|
36348
|
+
const commands = ["user", "project"].flatMap(
|
|
36349
|
+
(scope) => ownedEntries(readCursorHooks(cursorHooksPath(scope))).map(({ entry }) => entry.command)
|
|
36350
|
+
);
|
|
36351
|
+
return hookCommandResolutions(commands, PRIM_BINS3);
|
|
36352
|
+
}
|
|
36353
|
+
function resolveScope3(input) {
|
|
36354
|
+
if (input === void 0 || input === "project") return "project";
|
|
36355
|
+
if (input === "user") return "user";
|
|
36356
|
+
throw new Error(`unknown --scope "${input}" (expected: user or project)`);
|
|
36357
|
+
}
|
|
36358
|
+
function registerCursorCommands(program3) {
|
|
36359
|
+
const cursor = program3.command("cursor").description("Manage the native Cursor integration (capture, gate, ingest, presence)");
|
|
36360
|
+
cursor.command("install").description("Register Primitive in Cursor's native hooks.json").option("--scope <scope>", "project (default) or user").option("--force", "Repair drifted Primitive entries; custom Cursor fields remain untouched").action((opts) => {
|
|
36361
|
+
const result = performInstall3(resolveScope3(opts.scope), opts.force);
|
|
36362
|
+
console.error(
|
|
36363
|
+
result.changed ? `[prim] Cursor integration installed (${result.scope} scope) at ${result.path}` : `[prim] Cursor integration already present at ${result.path}`
|
|
36364
|
+
);
|
|
36365
|
+
if (result.restartRequired) console.error("[prim] restart Cursor CLI to load the footer");
|
|
36366
|
+
console.log(JSON.stringify(result, null, 2));
|
|
36367
|
+
});
|
|
36368
|
+
cursor.command("uninstall").description("Remove only Primitive-owned Cursor hooks and footer").option("--scope <scope>", "project (default) or user").action((opts) => {
|
|
36369
|
+
const result = performUninstall3(resolveScope3(opts.scope));
|
|
36370
|
+
console.error(
|
|
36371
|
+
result.changed ? `[prim] Cursor integration removed (${result.scope} scope)` : `[prim] no Primitive-owned Cursor integration found (${result.scope} scope)`
|
|
36372
|
+
);
|
|
36373
|
+
if (result.restartRequired) console.error("[prim] restart Cursor CLI to remove the footer");
|
|
36374
|
+
console.log(JSON.stringify(result, null, 2));
|
|
36375
|
+
});
|
|
36376
|
+
cursor.command("status").description("Report native Cursor hook and footer status").action(() => {
|
|
36377
|
+
const result = performStatus3();
|
|
36378
|
+
const mark = (value) => value ? "\u2713" : "\u2717";
|
|
36379
|
+
console.error(
|
|
36380
|
+
`[prim] user: gate ${mark(result.user.gate)} \xB7 capture ${mark(result.user.capture)} \xB7 footer ${mark(result.user.footer)} (${result.user.path})
|
|
36381
|
+
[prim] project: gate ${mark(result.project.gate)} \xB7 capture ${mark(result.project.capture)} (${result.project.path})`
|
|
36382
|
+
);
|
|
36383
|
+
console.log(JSON.stringify(result, null, 2));
|
|
36384
|
+
});
|
|
36385
|
+
}
|
|
36386
|
+
|
|
36082
36387
|
// src/commands/daemon.ts
|
|
36083
36388
|
import { spawn as spawn3 } from "child_process";
|
|
36084
|
-
import { closeSync as closeSync3, existsSync as
|
|
36085
|
-
import { join as
|
|
36389
|
+
import { closeSync as closeSync3, existsSync as existsSync12, mkdirSync as mkdirSync9, openSync as openSync3, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "fs";
|
|
36390
|
+
import { join as join16 } from "path";
|
|
36086
36391
|
|
|
36087
36392
|
// src/daemon/latest-bootstrap.ts
|
|
36088
36393
|
import { spawn as spawn2 } from "child_process";
|
|
36089
|
-
import { join as
|
|
36394
|
+
import { join as join14 } from "path";
|
|
36090
36395
|
var LATEST_BOOTSTRAP_TIMEOUT_MS = 45e3;
|
|
36091
36396
|
var LATEST_BOOTSTRAP_LOCK_NAME = "daemon-latest.lock";
|
|
36092
36397
|
async function runPinnedEnsure(options) {
|
|
@@ -36127,7 +36432,7 @@ async function runPinnedEnsure(options) {
|
|
|
36127
36432
|
});
|
|
36128
36433
|
}
|
|
36129
36434
|
async function runLatestDaemonBootstrap(ensureCurrent, options = {}) {
|
|
36130
|
-
const lockPath = options.lockPath ??
|
|
36435
|
+
const lockPath = options.lockPath ?? join14(
|
|
36131
36436
|
primConfigDirectory({ env: options.env, homeDir: options.homeDir }),
|
|
36132
36437
|
LATEST_BOOTSTRAP_LOCK_NAME
|
|
36133
36438
|
);
|
|
@@ -36157,11 +36462,11 @@ import {
|
|
|
36157
36462
|
accessSync as accessSync2,
|
|
36158
36463
|
chmodSync as chmodSync4,
|
|
36159
36464
|
copyFileSync as copyFileSync2,
|
|
36160
|
-
existsSync as
|
|
36465
|
+
existsSync as existsSync11,
|
|
36161
36466
|
lstatSync as lstatSync5,
|
|
36162
36467
|
mkdirSync as mkdirSync8,
|
|
36163
36468
|
mkdtempSync as mkdtempSync2,
|
|
36164
|
-
readFileSync as
|
|
36469
|
+
readFileSync as readFileSync12,
|
|
36165
36470
|
readdirSync as readdirSync3,
|
|
36166
36471
|
readlinkSync,
|
|
36167
36472
|
realpathSync as realpathSync3,
|
|
@@ -36170,8 +36475,8 @@ import {
|
|
|
36170
36475
|
symlinkSync,
|
|
36171
36476
|
writeFileSync as writeFileSync7
|
|
36172
36477
|
} from "fs";
|
|
36173
|
-
import { homedir as
|
|
36174
|
-
import { basename as basename3, dirname as dirname10, isAbsolute as
|
|
36478
|
+
import { homedir as homedir8 } from "os";
|
|
36479
|
+
import { basename as basename3, dirname as dirname10, isAbsolute as isAbsolute7, join as join15, resolve as resolve6 } from "path";
|
|
36175
36480
|
|
|
36176
36481
|
// src/daemon/env-binding.ts
|
|
36177
36482
|
function normalizeApiUrl(url) {
|
|
@@ -36210,31 +36515,31 @@ var LaunchctlError = class extends Error {
|
|
|
36210
36515
|
}
|
|
36211
36516
|
};
|
|
36212
36517
|
function xdgDataHome(options) {
|
|
36213
|
-
const home = options.homeDir ??
|
|
36518
|
+
const home = options.homeDir ?? homedir8();
|
|
36214
36519
|
const configured = (options.env ?? process.env).XDG_DATA_HOME;
|
|
36215
|
-
return configured &&
|
|
36520
|
+
return configured && isAbsolute7(configured) ? configured : join15(home, ".local", "share");
|
|
36216
36521
|
}
|
|
36217
36522
|
function runtimePaths(options = {}) {
|
|
36218
|
-
const dataDir =
|
|
36219
|
-
const runtimeDir =
|
|
36220
|
-
const currentLink =
|
|
36523
|
+
const dataDir = join15(xdgDataHome(options), "prim");
|
|
36524
|
+
const runtimeDir = join15(dataDir, "runtime");
|
|
36525
|
+
const currentLink = join15(runtimeDir, "current");
|
|
36221
36526
|
return {
|
|
36222
36527
|
dataDir,
|
|
36223
36528
|
runtimeDir,
|
|
36224
|
-
releasesDir:
|
|
36529
|
+
releasesDir: join15(runtimeDir, "releases"),
|
|
36225
36530
|
currentLink,
|
|
36226
|
-
statuslineLauncher:
|
|
36227
|
-
disabledMarker:
|
|
36228
|
-
lifecycleLockDir:
|
|
36531
|
+
statuslineLauncher: join15(runtimeDir, "prim-statusline"),
|
|
36532
|
+
disabledMarker: join15(dataDir, "daemon.disabled"),
|
|
36533
|
+
lifecycleLockDir: join15(dataDir, "daemon.lifecycle.lock")
|
|
36229
36534
|
};
|
|
36230
36535
|
}
|
|
36231
36536
|
function daemonControlPaths(options = {}) {
|
|
36232
36537
|
const configDir = primConfigDirectory(options);
|
|
36233
36538
|
const legacy = runtimePaths(options);
|
|
36234
36539
|
return {
|
|
36235
|
-
launcher:
|
|
36236
|
-
disabledMarker:
|
|
36237
|
-
lifecycleLockDir:
|
|
36540
|
+
launcher: join15(configDir, `prim-daemon-launcher-v${LAUNCHER_SCHEMA_VERSION}`),
|
|
36541
|
+
disabledMarker: join15(configDir, "daemon.disabled"),
|
|
36542
|
+
lifecycleLockDir: join15(configDir, "daemon.lifecycle.lock"),
|
|
36238
36543
|
legacyDisabledMarker: legacy.disabledMarker,
|
|
36239
36544
|
legacyLifecycleLockDir: legacy.lifecycleLockDir
|
|
36240
36545
|
};
|
|
@@ -36242,10 +36547,10 @@ function daemonControlPaths(options = {}) {
|
|
|
36242
36547
|
function findPackageVersion(entryFile) {
|
|
36243
36548
|
let dir = dirname10(resolve6(entryFile));
|
|
36244
36549
|
for (let depth = 0; depth < 6; depth++) {
|
|
36245
|
-
const packagePath =
|
|
36246
|
-
if (
|
|
36550
|
+
const packagePath = join15(dir, "package.json");
|
|
36551
|
+
if (existsSync11(packagePath)) {
|
|
36247
36552
|
try {
|
|
36248
|
-
const manifest = JSON.parse(
|
|
36553
|
+
const manifest = JSON.parse(readFileSync12(packagePath, "utf8"));
|
|
36249
36554
|
if (manifest.name === "@primitive.ai/prim" && manifest.version) {
|
|
36250
36555
|
return manifest.version;
|
|
36251
36556
|
}
|
|
@@ -36260,7 +36565,7 @@ function findPackageVersion(entryFile) {
|
|
|
36260
36565
|
}
|
|
36261
36566
|
function readRuntimeManifest(path9) {
|
|
36262
36567
|
try {
|
|
36263
|
-
const parsed = JSON.parse(
|
|
36568
|
+
const parsed = JSON.parse(readFileSync12(path9, "utf8"));
|
|
36264
36569
|
if (parsed.schemaVersion !== RUNTIME_SCHEMA_VERSION || typeof parsed.version !== "string" || typeof parsed.nodePath !== "string" || parsed.daemonFile !== "prim-daemon-server" || typeof parsed.daemonSha256 !== "string" || !/^[a-f0-9]{64}$/u.test(parsed.daemonSha256)) {
|
|
36265
36570
|
return null;
|
|
36266
36571
|
}
|
|
@@ -36276,10 +36581,10 @@ function exactKeys2(value, expected) {
|
|
|
36276
36581
|
return actual.length === wanted.length && actual.every((key, index) => key === wanted[index]);
|
|
36277
36582
|
}
|
|
36278
36583
|
function readOwnedRuntimeManifest(releaseDir) {
|
|
36279
|
-
const manifestPath =
|
|
36280
|
-
const daemonPath =
|
|
36584
|
+
const manifestPath = join15(releaseDir, "manifest.json");
|
|
36585
|
+
const daemonPath = join15(releaseDir, "prim-daemon-server");
|
|
36281
36586
|
try {
|
|
36282
|
-
const raw =
|
|
36587
|
+
const raw = readFileSync12(manifestPath, "utf8");
|
|
36283
36588
|
const parsed = JSON.parse(raw);
|
|
36284
36589
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
36285
36590
|
if (!exactKeys2(parsed, [
|
|
@@ -36293,7 +36598,7 @@ function readOwnedRuntimeManifest(releaseDir) {
|
|
|
36293
36598
|
return null;
|
|
36294
36599
|
}
|
|
36295
36600
|
const manifest = parsed;
|
|
36296
|
-
if (manifest.schemaVersion !== RUNTIME_SCHEMA_VERSION || compareSemver(manifest.version, manifest.version) !== 0 || !
|
|
36601
|
+
if (manifest.schemaVersion !== RUNTIME_SCHEMA_VERSION || compareSemver(manifest.version, manifest.version) !== 0 || !isAbsolute7(manifest.nodePath) || /[\r\n]/u.test(manifest.nodePath) || manifest.daemonFile !== "prim-daemon-server" || !/^[0-9a-f]{64}$/u.test(manifest.daemonSha256) || new Date(manifest.stagedAt).toISOString() !== manifest.stagedAt || raw !== `${JSON.stringify(manifest, null, 2)}
|
|
36297
36602
|
` || !lstatSync5(daemonPath).isFile() || sha256File(daemonPath) !== manifest.daemonSha256) {
|
|
36298
36603
|
return null;
|
|
36299
36604
|
}
|
|
@@ -36314,7 +36619,7 @@ function sameRuntime(current, desired, daemonPath) {
|
|
|
36314
36619
|
}
|
|
36315
36620
|
}
|
|
36316
36621
|
function sha256File(path9) {
|
|
36317
|
-
return createHash8("sha256").update(
|
|
36622
|
+
return createHash8("sha256").update(readFileSync12(path9)).digest("hex");
|
|
36318
36623
|
}
|
|
36319
36624
|
function atomicSymlink(target, linkPath) {
|
|
36320
36625
|
const tempLink = `${linkPath}.tmp-${process.pid}-${createHash8("sha256").update(`${target}\0${Date.now()}\0${Math.random()}`).digest("hex").slice(0, 12)}`;
|
|
@@ -36329,7 +36634,7 @@ function atomicSymlink(target, linkPath) {
|
|
|
36329
36634
|
function stageRuntime(options = {}) {
|
|
36330
36635
|
const paths = runtimePaths(options);
|
|
36331
36636
|
const daemonSource = options.daemonSource ?? binFile("prim-daemon-server");
|
|
36332
|
-
if (!daemonSource || !
|
|
36637
|
+
if (!daemonSource || !existsSync11(daemonSource)) {
|
|
36333
36638
|
throw new Error("cannot stage runtime: prim-daemon-server bundle is unavailable");
|
|
36334
36639
|
}
|
|
36335
36640
|
const nodePath = resolve6(options.nodePath ?? process.execPath);
|
|
@@ -36347,8 +36652,8 @@ function stageRuntime(options = {}) {
|
|
|
36347
36652
|
currentRelease = realpathSync3(paths.currentLink);
|
|
36348
36653
|
} catch {
|
|
36349
36654
|
}
|
|
36350
|
-
const current = currentRelease ? readRuntimeManifest(
|
|
36351
|
-
const currentDaemon = currentRelease ?
|
|
36655
|
+
const current = currentRelease ? readRuntimeManifest(join15(currentRelease, "manifest.json")) : null;
|
|
36656
|
+
const currentDaemon = currentRelease ? join15(currentRelease, desired.daemonFile) : "";
|
|
36352
36657
|
if (currentRelease && sameRuntime(current, desired, currentDaemon)) {
|
|
36353
36658
|
const manifest = current;
|
|
36354
36659
|
atomicWrite3(
|
|
@@ -36366,17 +36671,17 @@ function stageRuntime(options = {}) {
|
|
|
36366
36671
|
mkdirSync8(paths.releasesDir, { recursive: true, mode: RUNTIME_DIR_MODE });
|
|
36367
36672
|
chmodSync4(paths.runtimeDir, RUNTIME_DIR_MODE);
|
|
36368
36673
|
chmodSync4(paths.releasesDir, RUNTIME_DIR_MODE);
|
|
36369
|
-
const stagingDir = mkdtempSync2(
|
|
36674
|
+
const stagingDir = mkdtempSync2(join15(paths.releasesDir, ".stage-"));
|
|
36370
36675
|
chmodSync4(stagingDir, RUNTIME_DIR_MODE);
|
|
36371
36676
|
let releaseDir;
|
|
36372
36677
|
try {
|
|
36373
|
-
const daemonTarget =
|
|
36678
|
+
const daemonTarget = join15(stagingDir, desired.daemonFile);
|
|
36374
36679
|
copyFileSync2(daemonSource, daemonTarget);
|
|
36375
36680
|
chmodSync4(daemonTarget, RUNTIME_FILE_MODE);
|
|
36376
36681
|
if (sha256File(daemonTarget) !== desired.daemonSha256) {
|
|
36377
36682
|
throw new Error("cannot stage runtime: daemon bundle changed while it was copied");
|
|
36378
36683
|
}
|
|
36379
|
-
const manifestTarget =
|
|
36684
|
+
const manifestTarget = join15(stagingDir, "manifest.json");
|
|
36380
36685
|
writeFileSync7(manifestTarget, `${JSON.stringify(desired, null, 2)}
|
|
36381
36686
|
`, {
|
|
36382
36687
|
encoding: "utf8",
|
|
@@ -36384,10 +36689,10 @@ function stageRuntime(options = {}) {
|
|
|
36384
36689
|
flag: "wx"
|
|
36385
36690
|
});
|
|
36386
36691
|
const releaseName = `release-${createHash8("sha256").update(`${version}\0${nodePath}\0${desired.stagedAt}\0${process.pid}\0${Math.random()}`).digest("hex").slice(0, 16)}`;
|
|
36387
|
-
releaseDir =
|
|
36692
|
+
releaseDir = join15(paths.releasesDir, releaseName);
|
|
36388
36693
|
renameSync4(stagingDir, releaseDir);
|
|
36389
36694
|
releaseDir = realpathSync3(releaseDir);
|
|
36390
|
-
atomicSymlink(
|
|
36695
|
+
atomicSymlink(join15("releases", releaseName), paths.currentLink);
|
|
36391
36696
|
atomicWrite3(
|
|
36392
36697
|
paths.statuslineLauncher,
|
|
36393
36698
|
statuslineLauncherContent(desired.version, options),
|
|
@@ -36401,14 +36706,14 @@ function stageRuntime(options = {}) {
|
|
|
36401
36706
|
changed: true,
|
|
36402
36707
|
manifest: desired,
|
|
36403
36708
|
paths,
|
|
36404
|
-
daemonPath:
|
|
36709
|
+
daemonPath: join15(releaseDir, desired.daemonFile)
|
|
36405
36710
|
};
|
|
36406
36711
|
}
|
|
36407
36712
|
function shellQuote2(value) {
|
|
36408
36713
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
36409
36714
|
}
|
|
36410
36715
|
function statuslineLauncherContent(version, options = {}) {
|
|
36411
|
-
const socketPath =
|
|
36716
|
+
const socketPath = join15(primConfigDirectory(options), "sock");
|
|
36412
36717
|
const fallback = `primitive ${version} (daemon: down)`;
|
|
36413
36718
|
return `#!/bin/sh
|
|
36414
36719
|
response=$(
|
|
@@ -36441,7 +36746,7 @@ function lstatIfPresent3(path9) {
|
|
|
36441
36746
|
function assertExactFile(path9, expected, label) {
|
|
36442
36747
|
if (!lstatIfPresent3(path9)) return;
|
|
36443
36748
|
assertRegularFile(path9, label);
|
|
36444
|
-
if (
|
|
36749
|
+
if (readFileSync12(path9, "utf8") !== expected) {
|
|
36445
36750
|
throw new Error(`refusing to remove unrecognized ${label} at ${path9}`);
|
|
36446
36751
|
}
|
|
36447
36752
|
}
|
|
@@ -36450,12 +36755,12 @@ function assertOwnedDaemonRuntime(options) {
|
|
|
36450
36755
|
const control = daemonControlPaths(options);
|
|
36451
36756
|
const configDir = primConfigDirectory(options);
|
|
36452
36757
|
const service = process.platform === "darwin" ? launchdPaths(options) : void 0;
|
|
36453
|
-
const logPath = service?.logPath ??
|
|
36758
|
+
const logPath = service?.logPath ?? join15(configDir, "daemon.log");
|
|
36454
36759
|
for (const activeArtifact of [
|
|
36455
|
-
|
|
36456
|
-
|
|
36457
|
-
|
|
36458
|
-
|
|
36760
|
+
join15(configDir, "daemon.pid"),
|
|
36761
|
+
join15(configDir, "sock"),
|
|
36762
|
+
join15(configDir, "daemon.lock"),
|
|
36763
|
+
join15(configDir, "client-instance.lock")
|
|
36459
36764
|
]) {
|
|
36460
36765
|
if (lstatIfPresent3(activeArtifact)) {
|
|
36461
36766
|
throw new Error(`refusing runtime removal while daemon state remains at ${activeArtifact}`);
|
|
@@ -36476,17 +36781,17 @@ function assertOwnedDaemonRuntime(options) {
|
|
|
36476
36781
|
);
|
|
36477
36782
|
}
|
|
36478
36783
|
assertRegularFile(logPath, "daemon log");
|
|
36479
|
-
assertRegularFile(
|
|
36480
|
-
assertRegularFile(
|
|
36784
|
+
assertRegularFile(join15(configDir, "daemon-health.json"), "daemon health snapshot");
|
|
36785
|
+
assertRegularFile(join15(configDir, "client_instance_id"), "daemon client instance id");
|
|
36481
36786
|
if (service && lstatIfPresent3(service.plistPath)) {
|
|
36482
36787
|
assertRegularFile(service.plistPath, "launchd property list");
|
|
36483
36788
|
const expected = generateLaunchAgentPlist({
|
|
36484
36789
|
launcherPath: control.launcher,
|
|
36485
36790
|
logPath,
|
|
36486
|
-
workingDirectory: options.homeDir ??
|
|
36791
|
+
workingDirectory: options.homeDir ?? homedir8(),
|
|
36487
36792
|
label: options.label
|
|
36488
36793
|
});
|
|
36489
|
-
if (
|
|
36794
|
+
if (readFileSync12(service.plistPath, "utf8") !== expected) {
|
|
36490
36795
|
throw new Error(
|
|
36491
36796
|
`refusing to remove unrecognized launchd property list at ${service.plistPath}`
|
|
36492
36797
|
);
|
|
@@ -36511,7 +36816,7 @@ function assertOwnedDaemonRuntime(options) {
|
|
|
36511
36816
|
throw new Error(`refusing to remove non-directory daemon releases at ${runtime.releasesDir}`);
|
|
36512
36817
|
}
|
|
36513
36818
|
for (const entry of readdirSync3(runtime.releasesDir, { withFileTypes: true })) {
|
|
36514
|
-
const releaseDir =
|
|
36819
|
+
const releaseDir = join15(runtime.releasesDir, entry.name);
|
|
36515
36820
|
const manifest = entry.isDirectory() && RUNTIME_RELEASE_RE.test(entry.name) ? readOwnedRuntimeManifest(releaseDir) : null;
|
|
36516
36821
|
if (!manifest) {
|
|
36517
36822
|
throw new Error(`refusing to remove unrecognized daemon release ${releaseDir}`);
|
|
@@ -36529,7 +36834,7 @@ function assertOwnedDaemonRuntime(options) {
|
|
|
36529
36834
|
}
|
|
36530
36835
|
const target = readlinkSync(runtime.currentLink);
|
|
36531
36836
|
const releaseName = basename3(target);
|
|
36532
|
-
if (target !==
|
|
36837
|
+
if (target !== join15("releases", releaseName) || !RUNTIME_RELEASE_RE.test(releaseName)) {
|
|
36533
36838
|
throw new Error(
|
|
36534
36839
|
`refusing to remove malformed daemon runtime selector ${runtime.currentLink}`
|
|
36535
36840
|
);
|
|
@@ -36557,7 +36862,7 @@ async function removeDaemonRuntime(options = {}) {
|
|
|
36557
36862
|
const control = daemonControlPaths(options);
|
|
36558
36863
|
const configDir = primConfigDirectory(options);
|
|
36559
36864
|
const service = process.platform === "darwin" ? launchdPaths(options) : void 0;
|
|
36560
|
-
const logPath = service?.logPath ??
|
|
36865
|
+
const logPath = service?.logPath ?? join15(configDir, "daemon.log");
|
|
36561
36866
|
const ownedArtifacts = [
|
|
36562
36867
|
runtime.runtimeDir,
|
|
36563
36868
|
control.launcher,
|
|
@@ -36565,8 +36870,8 @@ async function removeDaemonRuntime(options = {}) {
|
|
|
36565
36870
|
control.legacyDisabledMarker,
|
|
36566
36871
|
...service ? [service.plistPath] : [],
|
|
36567
36872
|
logPath,
|
|
36568
|
-
|
|
36569
|
-
|
|
36873
|
+
join15(configDir, "daemon-health.json"),
|
|
36874
|
+
join15(configDir, "client_instance_id")
|
|
36570
36875
|
];
|
|
36571
36876
|
if (!ownedArtifacts.some((path9) => lstatIfPresent3(path9))) {
|
|
36572
36877
|
return { changed: false, runtimePaths: runtime };
|
|
@@ -36610,11 +36915,11 @@ ${config.configDir ? `export PRIM_CONFIG_DIR=${shellQuote2(config.configDir)}
|
|
|
36610
36915
|
}
|
|
36611
36916
|
function readDaemonLauncher(path9) {
|
|
36612
36917
|
try {
|
|
36613
|
-
const content =
|
|
36918
|
+
const content = readFileSync12(path9, "utf8");
|
|
36614
36919
|
const encoded = /^# prim-daemon-launcher: ([A-Za-z0-9_-]+)$/mu.exec(content)?.[1];
|
|
36615
36920
|
if (!encoded) return null;
|
|
36616
36921
|
const value = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
36617
|
-
if (value.schemaVersion !== LAUNCHER_SCHEMA_VERSION || typeof value.nodePath !== "string" || typeof value.daemonPath !== "string" || typeof value.runtimeVersion !== "string" || value.apiUrl !== null && typeof value.apiUrl !== "string" || value.configDir !== void 0 && (typeof value.configDir !== "string" || !
|
|
36922
|
+
if (value.schemaVersion !== LAUNCHER_SCHEMA_VERSION || typeof value.nodePath !== "string" || typeof value.daemonPath !== "string" || typeof value.runtimeVersion !== "string" || value.apiUrl !== null && typeof value.apiUrl !== "string" || value.configDir !== void 0 && (typeof value.configDir !== "string" || !isAbsolute7(value.configDir)) || typeof value.revision !== "string") {
|
|
36618
36923
|
return null;
|
|
36619
36924
|
}
|
|
36620
36925
|
const config = {
|
|
@@ -36633,7 +36938,7 @@ function readDaemonLauncher(path9) {
|
|
|
36633
36938
|
function readUsableDaemonConfig(path9) {
|
|
36634
36939
|
const config = readDaemonLauncher(path9);
|
|
36635
36940
|
if (!config) return null;
|
|
36636
|
-
const manifest = readRuntimeManifest(
|
|
36941
|
+
const manifest = readRuntimeManifest(join15(dirname10(config.daemonPath), "manifest.json"));
|
|
36637
36942
|
try {
|
|
36638
36943
|
accessSync2(config.nodePath, constants4.X_OK);
|
|
36639
36944
|
return manifest?.version === config.runtimeVersion && manifest.nodePath === config.nodePath && manifest.daemonSha256 === sha256File(config.daemonPath) ? config : null;
|
|
@@ -36678,7 +36983,7 @@ function generateLaunchAgentPlist(config) {
|
|
|
36678
36983
|
`;
|
|
36679
36984
|
}
|
|
36680
36985
|
function launchdPaths(options = {}) {
|
|
36681
|
-
const home = options.homeDir ??
|
|
36986
|
+
const home = options.homeDir ?? homedir8();
|
|
36682
36987
|
const configDir = primConfigDirectory(options);
|
|
36683
36988
|
const uid = options.uid ?? process.getuid?.();
|
|
36684
36989
|
const label = options.label ?? LAUNCHD_LABEL;
|
|
@@ -36686,8 +36991,8 @@ function launchdPaths(options = {}) {
|
|
|
36686
36991
|
return {
|
|
36687
36992
|
domainTarget: `gui/${uid}`,
|
|
36688
36993
|
serviceTarget: `gui/${uid}/${label}`,
|
|
36689
|
-
plistPath:
|
|
36690
|
-
logPath:
|
|
36994
|
+
plistPath: join15(home, "Library", "LaunchAgents", `${label}.plist`),
|
|
36995
|
+
logPath: join15(configDir, "daemon.log")
|
|
36691
36996
|
};
|
|
36692
36997
|
}
|
|
36693
36998
|
var runLaunchctl = (args, timeoutMs2 = COMMAND_TIMEOUT_MS) => {
|
|
@@ -36720,7 +37025,7 @@ function getLaunchdService(options = {}) {
|
|
|
36720
37025
|
}
|
|
36721
37026
|
function atomicWrite3(path9, content, mode, validate3) {
|
|
36722
37027
|
try {
|
|
36723
|
-
if (
|
|
37028
|
+
if (readFileSync12(path9, "utf8") === content) {
|
|
36724
37029
|
chmodSync4(path9, mode);
|
|
36725
37030
|
validate3?.(path9, COMMAND_TIMEOUT_MS);
|
|
36726
37031
|
return false;
|
|
@@ -36762,14 +37067,14 @@ async function inspectDaemon(timeoutMs2) {
|
|
|
36762
37067
|
function canonicalProspectivePath(path9) {
|
|
36763
37068
|
const suffix = [];
|
|
36764
37069
|
let ancestor = resolve6(path9);
|
|
36765
|
-
while (!
|
|
37070
|
+
while (!existsSync11(ancestor)) {
|
|
36766
37071
|
const parent = dirname10(ancestor);
|
|
36767
37072
|
if (parent === ancestor) return resolve6(path9);
|
|
36768
37073
|
suffix.unshift(basename3(ancestor));
|
|
36769
37074
|
ancestor = parent;
|
|
36770
37075
|
}
|
|
36771
37076
|
try {
|
|
36772
|
-
return
|
|
37077
|
+
return join15(realpathSync3(ancestor), ...suffix);
|
|
36773
37078
|
} catch {
|
|
36774
37079
|
return resolve6(path9);
|
|
36775
37080
|
}
|
|
@@ -36784,10 +37089,10 @@ async function withDaemonLifecycleLock(operation, options = {}) {
|
|
|
36784
37089
|
);
|
|
36785
37090
|
}
|
|
36786
37091
|
async function stopVerifiedLegacyDaemon(options, deadlineMs, nowMs, sleep2) {
|
|
36787
|
-
const pidPath =
|
|
37092
|
+
const pidPath = join15(primConfigDirectory(options), "daemon.pid");
|
|
36788
37093
|
let pid;
|
|
36789
37094
|
try {
|
|
36790
|
-
pid = Number(
|
|
37095
|
+
pid = Number(readFileSync12(pidPath, "utf8").trim());
|
|
36791
37096
|
} catch {
|
|
36792
37097
|
throw new Error("an unsupervised daemon answered, but it has no verifiable pidfile");
|
|
36793
37098
|
}
|
|
@@ -36964,7 +37269,7 @@ async function waitForAbsence(context) {
|
|
|
36964
37269
|
}
|
|
36965
37270
|
function daemonExplicitlyDisabled(options = {}) {
|
|
36966
37271
|
const paths = daemonControlPaths(options);
|
|
36967
|
-
return
|
|
37272
|
+
return existsSync11(paths.disabledMarker) || existsSync11(paths.legacyDisabledMarker);
|
|
36968
37273
|
}
|
|
36969
37274
|
function setDaemonExplicitlyDisabled(disabled, options = {}) {
|
|
36970
37275
|
const paths = daemonControlPaths(options);
|
|
@@ -36987,7 +37292,7 @@ async function ensureMacDaemonLocked(options) {
|
|
|
36987
37292
|
let service = getLaunchdService({ ...options, runner });
|
|
36988
37293
|
if (!options.explicitlyStarted && daemonExplicitlyDisabled(options)) {
|
|
36989
37294
|
const control2 = daemonControlPaths(options);
|
|
36990
|
-
if (!
|
|
37295
|
+
if (!existsSync11(control2.disabledMarker)) {
|
|
36991
37296
|
atomicWrite3(control2.disabledMarker, "disabled by `prim daemon stop`\n", RUNTIME_FILE_MODE);
|
|
36992
37297
|
}
|
|
36993
37298
|
return {
|
|
@@ -37014,7 +37319,7 @@ async function ensureMacDaemonLocked(options) {
|
|
|
37014
37319
|
const configuredApiUrl = (options.env ?? process.env).PRIM_API_URL;
|
|
37015
37320
|
const apiUrl = configuredApiUrl ? normalizeApiUrl(configuredApiUrl) || void 0 : void 0;
|
|
37016
37321
|
const configDir = primConfigDirectory(options);
|
|
37017
|
-
const legacyDefaultConfigDir =
|
|
37322
|
+
const legacyDefaultConfigDir = join15(options.homeDir ?? homedir8(), ".config", "prim");
|
|
37018
37323
|
const launcherConfigDir = configDir === legacyDefaultConfigDir ? void 0 : configDir;
|
|
37019
37324
|
if (retainSelected && selected) {
|
|
37020
37325
|
const usable = readUsableDaemonConfig(control.launcher);
|
|
@@ -37049,7 +37354,7 @@ async function ensureMacDaemonLocked(options) {
|
|
|
37049
37354
|
const plist = generateLaunchAgentPlist({
|
|
37050
37355
|
launcherPath: control.launcher,
|
|
37051
37356
|
logPath: servicePaths.logPath,
|
|
37052
|
-
workingDirectory: options.homeDir ??
|
|
37357
|
+
workingDirectory: options.homeDir ?? homedir8(),
|
|
37053
37358
|
label: options.label
|
|
37054
37359
|
});
|
|
37055
37360
|
const plistChanged = atomicWrite3(
|
|
@@ -37272,9 +37577,9 @@ function formatStatusline(version, snapshot, resolveIngestionStatus, options = {
|
|
|
37272
37577
|
// src/commands/daemon.ts
|
|
37273
37578
|
var DAEMON_BIN = "prim-daemon-server";
|
|
37274
37579
|
var CONFIG_DIR = primConfigDirectory();
|
|
37275
|
-
var PID_PATH =
|
|
37276
|
-
var SOCK_PATH2 =
|
|
37277
|
-
var LOG_PATH =
|
|
37580
|
+
var PID_PATH = join16(CONFIG_DIR, "daemon.pid");
|
|
37581
|
+
var SOCK_PATH2 = join16(CONFIG_DIR, "sock");
|
|
37582
|
+
var LOG_PATH = join16(CONFIG_DIR, "daemon.log");
|
|
37278
37583
|
var CONFIG_DIR_MODE2 = 448;
|
|
37279
37584
|
var LOG_FILE_MODE = 384;
|
|
37280
37585
|
var STOP_TIMEOUT_MS = 5e3;
|
|
@@ -37312,10 +37617,10 @@ function daemonDegradedReason(snapshot) {
|
|
|
37312
37617
|
return "health checks have not recovered";
|
|
37313
37618
|
}
|
|
37314
37619
|
function readPidfile() {
|
|
37315
|
-
if (!
|
|
37620
|
+
if (!existsSync12(PID_PATH)) {
|
|
37316
37621
|
return null;
|
|
37317
37622
|
}
|
|
37318
|
-
const raw =
|
|
37623
|
+
const raw = readFileSync13(PID_PATH, "utf-8").trim();
|
|
37319
37624
|
const pid = Number(raw);
|
|
37320
37625
|
if (!Number.isInteger(pid) || pid <= 0) {
|
|
37321
37626
|
return null;
|
|
@@ -37340,10 +37645,10 @@ function spawnDaemon(options) {
|
|
|
37340
37645
|
return file ? spawn3(process.execPath, [file], options) : spawn3(DAEMON_BIN, [], options);
|
|
37341
37646
|
}
|
|
37342
37647
|
function openDaemonLog(configDir = CONFIG_DIR) {
|
|
37343
|
-
if (!
|
|
37648
|
+
if (!existsSync12(configDir)) {
|
|
37344
37649
|
mkdirSync9(configDir, { recursive: true, mode: CONFIG_DIR_MODE2 });
|
|
37345
37650
|
}
|
|
37346
|
-
return openSync3(
|
|
37651
|
+
return openSync3(join16(configDir, "daemon.log"), "a", LOG_FILE_MODE);
|
|
37347
37652
|
}
|
|
37348
37653
|
async function waitForReady() {
|
|
37349
37654
|
const deadline = Date.now() + READY_TIMEOUT_MS;
|
|
@@ -37477,7 +37782,7 @@ async function detachedDaemonStop() {
|
|
|
37477
37782
|
{},
|
|
37478
37783
|
{ timeoutMs: STATUS_PROBE_TIMEOUT_MS }
|
|
37479
37784
|
);
|
|
37480
|
-
if (
|
|
37785
|
+
if (existsSync12(PID_PATH) || existsSync12(SOCK_PATH2) || socketOwner) {
|
|
37481
37786
|
process.stderr.write(
|
|
37482
37787
|
`[prim] refusing to verify daemon absence: ${socketOwner ? `socket is owned by pid=${socketOwner.pid}` : "daemon artifacts remain"}
|
|
37483
37788
|
`
|
|
@@ -37509,7 +37814,7 @@ async function detachedDaemonStop() {
|
|
|
37509
37814
|
{},
|
|
37510
37815
|
{ timeoutMs: STATUS_PROBE_TIMEOUT_MS }
|
|
37511
37816
|
);
|
|
37512
|
-
if (socketOwner ||
|
|
37817
|
+
if (socketOwner || existsSync12(SOCK_PATH2)) {
|
|
37513
37818
|
process.stderr.write(
|
|
37514
37819
|
`[prim] refusing to clear stale pidfile: ${socketOwner ? `socket is owned by pid=${socketOwner.pid}` : "socket artifact remains"}
|
|
37515
37820
|
`
|
|
@@ -38298,6 +38603,8 @@ function authorLabel(row) {
|
|
|
38298
38603
|
return "Your Claude Code";
|
|
38299
38604
|
case "codex":
|
|
38300
38605
|
return "Your Codex";
|
|
38606
|
+
case "cursor":
|
|
38607
|
+
return "Your Cursor";
|
|
38301
38608
|
case "hermes":
|
|
38302
38609
|
return "Your Hermes";
|
|
38303
38610
|
case "chat":
|
|
@@ -39730,6 +40037,7 @@ function describeAudienceMember(member) {
|
|
|
39730
40037
|
return {
|
|
39731
40038
|
claude_code: "Claude Code agent",
|
|
39732
40039
|
codex: "Codex agent",
|
|
40040
|
+
cursor: "Cursor agent",
|
|
39733
40041
|
hermes: "Hermes agent"
|
|
39734
40042
|
}[member.agent] ?? terminalSafeLine(member.agent);
|
|
39735
40043
|
case "credential":
|
|
@@ -39941,7 +40249,7 @@ var UserScopeInputError = class extends Error {
|
|
|
39941
40249
|
}
|
|
39942
40250
|
};
|
|
39943
40251
|
var USER_SCOPE_ROLES = /* @__PURE__ */ new Set(["owner", "admin", "member"]);
|
|
39944
|
-
var USER_SCOPE_AGENTS = /* @__PURE__ */ new Set(["claude_code", "codex", "hermes"]);
|
|
40252
|
+
var USER_SCOPE_AGENTS = /* @__PURE__ */ new Set(["claude_code", "codex", "cursor", "hermes"]);
|
|
39945
40253
|
var USER_SCOPE_CREDENTIALS = /* @__PURE__ */ new Set(["workos_jwt", "workos_api_key", "service_token"]);
|
|
39946
40254
|
function requiredScopeValue(flag, value) {
|
|
39947
40255
|
const trimmed = value.trim();
|
|
@@ -39969,9 +40277,12 @@ function userScopeFromOptions(opts) {
|
|
|
39969
40277
|
for (const value of agents) {
|
|
39970
40278
|
const agent = requiredScopeValue("--for-agent", value);
|
|
39971
40279
|
if (!USER_SCOPE_AGENTS.has(agent)) {
|
|
39972
|
-
throw new UserScopeInputError("--for-agent must be claude_code, codex, or hermes");
|
|
40280
|
+
throw new UserScopeInputError("--for-agent must be claude_code, codex, cursor, or hermes");
|
|
39973
40281
|
}
|
|
39974
|
-
members.push({
|
|
40282
|
+
members.push({
|
|
40283
|
+
kind: "agent",
|
|
40284
|
+
agent
|
|
40285
|
+
});
|
|
39975
40286
|
}
|
|
39976
40287
|
for (const value of credentials) {
|
|
39977
40288
|
const credential = requiredScopeValue("--for-credential", value);
|
|
@@ -40178,7 +40489,7 @@ function registerDecisionsCommands(program3) {
|
|
|
40178
40489
|
[]
|
|
40179
40490
|
).option(
|
|
40180
40491
|
"--for-agent <agent>",
|
|
40181
|
-
"Include one agent: claude_code | codex | hermes (repeatable)",
|
|
40492
|
+
"Include one agent: claude_code | codex | cursor | hermes (repeatable)",
|
|
40182
40493
|
collectItem,
|
|
40183
40494
|
[]
|
|
40184
40495
|
).option(
|
|
@@ -40334,7 +40645,7 @@ function registerDecisionsCommands(program3) {
|
|
|
40334
40645
|
[]
|
|
40335
40646
|
).option(
|
|
40336
40647
|
"--for-agent <agent>",
|
|
40337
|
-
"Set one agent: claude_code | codex | hermes (repeatable)",
|
|
40648
|
+
"Set one agent: claude_code | codex | cursor | hermes (repeatable)",
|
|
40338
40649
|
collectItem,
|
|
40339
40650
|
[]
|
|
40340
40651
|
).option(
|
|
@@ -40414,7 +40725,7 @@ function registerDecisionsCommands(program3) {
|
|
|
40414
40725
|
}
|
|
40415
40726
|
|
|
40416
40727
|
// src/commands/doctor.ts
|
|
40417
|
-
import { existsSync as
|
|
40728
|
+
import { existsSync as existsSync15 } from "fs";
|
|
40418
40729
|
|
|
40419
40730
|
// src/decisions/feedback.ts
|
|
40420
40731
|
var FEEDBACK_PROTOCOL_VERSION = 2;
|
|
@@ -40559,17 +40870,17 @@ async function inspectJournalDelivery(buckets, options = {}) {
|
|
|
40559
40870
|
import {
|
|
40560
40871
|
appendFileSync,
|
|
40561
40872
|
closeSync as closeSync4,
|
|
40562
|
-
existsSync as
|
|
40873
|
+
existsSync as existsSync13,
|
|
40563
40874
|
fstatSync,
|
|
40564
40875
|
mkdirSync as mkdirSync10,
|
|
40565
40876
|
openSync as openSync4,
|
|
40566
40877
|
opendirSync,
|
|
40567
|
-
readFileSync as
|
|
40878
|
+
readFileSync as readFileSync14,
|
|
40568
40879
|
readSync,
|
|
40569
40880
|
readdirSync as readdirSync4
|
|
40570
40881
|
} from "fs";
|
|
40571
|
-
import { dirname as dirname11, join as
|
|
40572
|
-
var JOURNAL_DIR =
|
|
40882
|
+
import { dirname as dirname11, join as join17 } from "path";
|
|
40883
|
+
var JOURNAL_DIR = join17(primConfigDirectory(), "moves");
|
|
40573
40884
|
var JOURNAL_BASENAME = "journal.ndjson";
|
|
40574
40885
|
var JOURNAL_STATS_SAMPLE_BYTES = 64 * 1024;
|
|
40575
40886
|
var PENDING_STATS_MAX_FILES = 128;
|
|
@@ -40581,7 +40892,7 @@ function envSlug(apiUrl) {
|
|
|
40581
40892
|
return slug;
|
|
40582
40893
|
}
|
|
40583
40894
|
function currentEnvDir() {
|
|
40584
|
-
return
|
|
40895
|
+
return join17(JOURNAL_DIR, envSlug(getSiteUrl()));
|
|
40585
40896
|
}
|
|
40586
40897
|
function parseMoves(content) {
|
|
40587
40898
|
const moves = [];
|
|
@@ -40597,23 +40908,23 @@ function parseMoves(content) {
|
|
|
40597
40908
|
return moves;
|
|
40598
40909
|
}
|
|
40599
40910
|
function readMovesFromPath(path9) {
|
|
40600
|
-
if (!
|
|
40911
|
+
if (!existsSync13(path9)) {
|
|
40601
40912
|
return [];
|
|
40602
40913
|
}
|
|
40603
|
-
return parseMoves(
|
|
40914
|
+
return parseMoves(readFileSync14(path9, "utf-8"));
|
|
40604
40915
|
}
|
|
40605
40916
|
function listBuckets() {
|
|
40606
40917
|
const out = [];
|
|
40607
40918
|
const envDir = currentEnvDir();
|
|
40608
|
-
if (!
|
|
40919
|
+
if (!existsSync13(envDir)) {
|
|
40609
40920
|
return out;
|
|
40610
40921
|
}
|
|
40611
40922
|
for (const entry of readdirSync4(envDir, { withFileTypes: true })) {
|
|
40612
40923
|
if (!entry.isDirectory()) {
|
|
40613
40924
|
continue;
|
|
40614
40925
|
}
|
|
40615
|
-
const path9 =
|
|
40616
|
-
if (
|
|
40926
|
+
const path9 = join17(envDir, entry.name, JOURNAL_BASENAME);
|
|
40927
|
+
if (existsSync13(path9)) {
|
|
40617
40928
|
out.push({ bucket: entry.name, path: path9 });
|
|
40618
40929
|
}
|
|
40619
40930
|
}
|
|
@@ -40673,7 +40984,7 @@ function parseFlushingPid(name) {
|
|
|
40673
40984
|
return Number.isSafeInteger(pid) && pid > 0 ? pid : void 0;
|
|
40674
40985
|
}
|
|
40675
40986
|
function listFlushingInDir(dir, bucket, options = {}) {
|
|
40676
|
-
if (!
|
|
40987
|
+
if (!existsSync13(dir)) {
|
|
40677
40988
|
return [];
|
|
40678
40989
|
}
|
|
40679
40990
|
const out = [];
|
|
@@ -40687,7 +40998,7 @@ function listFlushingInDir(dir, bucket, options = {}) {
|
|
|
40687
40998
|
entry = entries.readSync();
|
|
40688
40999
|
continue;
|
|
40689
41000
|
}
|
|
40690
|
-
const path9 =
|
|
41001
|
+
const path9 = join17(dir, entry.name);
|
|
40691
41002
|
let sample;
|
|
40692
41003
|
try {
|
|
40693
41004
|
sample = sampleJournalFile(path9, remainingBytes);
|
|
@@ -40714,7 +41025,7 @@ function listFlushingInDir(dir, bucket, options = {}) {
|
|
|
40714
41025
|
}
|
|
40715
41026
|
function listFlushing(options = {}) {
|
|
40716
41027
|
const envDir = currentEnvDir();
|
|
40717
|
-
if (!
|
|
41028
|
+
if (!existsSync13(envDir)) {
|
|
40718
41029
|
return [];
|
|
40719
41030
|
}
|
|
40720
41031
|
const out = [];
|
|
@@ -40725,7 +41036,7 @@ function listFlushing(options = {}) {
|
|
|
40725
41036
|
break;
|
|
40726
41037
|
}
|
|
40727
41038
|
if (entry.isDirectory()) {
|
|
40728
|
-
const found = listFlushingInDir(
|
|
41039
|
+
const found = listFlushingInDir(join17(envDir, entry.name), entry.name, {
|
|
40729
41040
|
sampleBytes: remainingBytes,
|
|
40730
41041
|
maxFiles: maxFiles - out.length
|
|
40731
41042
|
});
|
|
@@ -40783,9 +41094,9 @@ function pendingJournalStats() {
|
|
|
40783
41094
|
}
|
|
40784
41095
|
|
|
40785
41096
|
// src/commands/hermes-install.ts
|
|
40786
|
-
import { existsSync as
|
|
40787
|
-
import { homedir as
|
|
40788
|
-
import { join as
|
|
41097
|
+
import { existsSync as existsSync14, readFileSync as readFileSync15, rmSync as rmSync6, statSync as statSync3 } from "fs";
|
|
41098
|
+
import { homedir as homedir9 } from "os";
|
|
41099
|
+
import { join as join18 } from "path";
|
|
40789
41100
|
|
|
40790
41101
|
// node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/nodes/identity.js
|
|
40791
41102
|
var ALIAS = /* @__PURE__ */ Symbol.for("yaml.alias");
|
|
@@ -47053,33 +47364,33 @@ function stringify3(value, replacer, options) {
|
|
|
47053
47364
|
}
|
|
47054
47365
|
|
|
47055
47366
|
// src/commands/hermes-install.ts
|
|
47056
|
-
var
|
|
47057
|
-
var
|
|
47367
|
+
var CAPTURE_BIN4 = "prim-hook";
|
|
47368
|
+
var GATE_BIN4 = "prim-pre-tool-use";
|
|
47058
47369
|
var POST_TOOL_USE_BIN3 = "prim-post-tool-use";
|
|
47059
|
-
var
|
|
47060
|
-
var
|
|
47370
|
+
var SESSION_START_BIN4 = "prim-session-start";
|
|
47371
|
+
var SESSION_END_BIN3 = "prim-session-end";
|
|
47061
47372
|
var HERMES_ARGS = "--agent hermes";
|
|
47062
47373
|
var EDIT_MATCHER = "write_file|patch";
|
|
47063
47374
|
var JSON_INDENT3 = 2;
|
|
47064
47375
|
var CONFIG_MODE = 384;
|
|
47065
|
-
var
|
|
47376
|
+
var PRIM_BINS4 = [CAPTURE_BIN4, GATE_BIN4, POST_TOOL_USE_BIN3, SESSION_START_BIN4, SESSION_END_BIN3];
|
|
47066
47377
|
function hermesHome() {
|
|
47067
|
-
return process.env.HERMES_HOME ??
|
|
47378
|
+
return process.env.HERMES_HOME ?? join18(homedir9(), ".hermes");
|
|
47068
47379
|
}
|
|
47069
47380
|
function configPath() {
|
|
47070
|
-
return
|
|
47381
|
+
return join18(hermesHome(), "config.yaml");
|
|
47071
47382
|
}
|
|
47072
47383
|
function legacyShimPath() {
|
|
47073
|
-
return
|
|
47384
|
+
return join18(hermesHome(), "agent-hooks", "prim-shim.sh");
|
|
47074
47385
|
}
|
|
47075
|
-
function
|
|
47386
|
+
function commandFor2(bin) {
|
|
47076
47387
|
return stableHookCommand(bin, HERMES_ARGS);
|
|
47077
47388
|
}
|
|
47078
47389
|
function legacyCommandFor(bin) {
|
|
47079
47390
|
return `"${legacyShimPath()}" ${bin} ${HERMES_ARGS}`;
|
|
47080
47391
|
}
|
|
47081
47392
|
function commandUsesBin(command, bin) {
|
|
47082
|
-
return command ===
|
|
47393
|
+
return command === commandFor2(bin) || command === legacyCommandFor(bin);
|
|
47083
47394
|
}
|
|
47084
47395
|
var CAPTURE_EVENTS2 = [
|
|
47085
47396
|
"on_session_start",
|
|
@@ -47091,13 +47402,13 @@ var CAPTURE_EVENTS2 = [
|
|
|
47091
47402
|
"subagent_stop"
|
|
47092
47403
|
];
|
|
47093
47404
|
var GATE_TIMEOUT_SECONDS = 10;
|
|
47094
|
-
var
|
|
47095
|
-
...CAPTURE_EVENTS2.map((event) => ({ event, bin:
|
|
47096
|
-
{ event: "pre_tool_call", matcher: EDIT_MATCHER, bin:
|
|
47405
|
+
var REGISTRATIONS3 = [
|
|
47406
|
+
...CAPTURE_EVENTS2.map((event) => ({ event, bin: CAPTURE_BIN4 })),
|
|
47407
|
+
{ event: "pre_tool_call", matcher: EDIT_MATCHER, bin: GATE_BIN4, timeout: GATE_TIMEOUT_SECONDS },
|
|
47097
47408
|
{ event: "post_tool_call", matcher: EDIT_MATCHER, bin: POST_TOOL_USE_BIN3 },
|
|
47098
47409
|
{ event: "post_approval_response", bin: POST_TOOL_USE_BIN3 },
|
|
47099
|
-
{ event: "on_session_start", bin:
|
|
47100
|
-
{ event: "on_session_end", bin:
|
|
47410
|
+
{ event: "on_session_start", bin: SESSION_START_BIN4 },
|
|
47411
|
+
{ event: "on_session_end", bin: SESSION_END_BIN3 }
|
|
47101
47412
|
];
|
|
47102
47413
|
function yamlValue(node) {
|
|
47103
47414
|
return typeof node?.toJSON === "function" ? node.toJSON?.() : node;
|
|
@@ -47107,7 +47418,7 @@ function hookEntry(node) {
|
|
|
47107
47418
|
return typeof value === "object" && value !== null && typeof value.command === "string" ? value : null;
|
|
47108
47419
|
}
|
|
47109
47420
|
function entryFor(reg) {
|
|
47110
|
-
const command =
|
|
47421
|
+
const command = commandFor2(reg.bin);
|
|
47111
47422
|
const entry = reg.matcher ? { matcher: reg.matcher, command } : { command };
|
|
47112
47423
|
if (reg.timeout !== void 0) {
|
|
47113
47424
|
entry.timeout = reg.timeout;
|
|
@@ -47129,7 +47440,7 @@ function ensureReg(list, reg, force) {
|
|
|
47129
47440
|
}
|
|
47130
47441
|
function applyInstall3(hooks, force) {
|
|
47131
47442
|
const next = { ...hooks };
|
|
47132
|
-
for (const reg of
|
|
47443
|
+
for (const reg of REGISTRATIONS3) {
|
|
47133
47444
|
next[reg.event] = ensureReg(next[reg.event] ?? [], reg, force);
|
|
47134
47445
|
}
|
|
47135
47446
|
return next;
|
|
@@ -47138,7 +47449,7 @@ function applyUninstall3(hooks) {
|
|
|
47138
47449
|
const next = {};
|
|
47139
47450
|
for (const [event, list] of Object.entries(hooks)) {
|
|
47140
47451
|
let kept = list;
|
|
47141
|
-
for (const bin of
|
|
47452
|
+
for (const bin of PRIM_BINS4) {
|
|
47142
47453
|
kept = stripBin(kept, bin);
|
|
47143
47454
|
}
|
|
47144
47455
|
if (kept.length > 0) {
|
|
@@ -47148,15 +47459,15 @@ function applyUninstall3(hooks) {
|
|
|
47148
47459
|
return next;
|
|
47149
47460
|
}
|
|
47150
47461
|
function isGateInstalled3(hooks) {
|
|
47151
|
-
return (hooks.pre_tool_call ?? []).some((e) => commandUsesBin(e.command,
|
|
47462
|
+
return (hooks.pre_tool_call ?? []).some((e) => commandUsesBin(e.command, GATE_BIN4));
|
|
47152
47463
|
}
|
|
47153
47464
|
function isCaptureInstalled(hooks) {
|
|
47154
47465
|
return CAPTURE_EVENTS2.some(
|
|
47155
|
-
(event) => (hooks[event] ?? []).some((e) => commandUsesBin(e.command,
|
|
47466
|
+
(event) => (hooks[event] ?? []).some((e) => commandUsesBin(e.command, CAPTURE_BIN4))
|
|
47156
47467
|
);
|
|
47157
47468
|
}
|
|
47158
47469
|
function entryUsesOwnedBin(entry) {
|
|
47159
|
-
return
|
|
47470
|
+
return PRIM_BINS4.some(
|
|
47160
47471
|
(bin) => commandUsesBin(entry.command, bin) || commandMatchesBin(entry.command, bin)
|
|
47161
47472
|
);
|
|
47162
47473
|
}
|
|
@@ -47171,21 +47482,21 @@ function hasAnyHookRegistration3(hooks) {
|
|
|
47171
47482
|
function hookRuntimeResolutions3(hooks) {
|
|
47172
47483
|
const resolutions = hookCommandResolutions(
|
|
47173
47484
|
Object.values(hooks).flatMap((entries) => entries.map((entry) => entry.command)),
|
|
47174
|
-
|
|
47485
|
+
PRIM_BINS4
|
|
47175
47486
|
);
|
|
47176
47487
|
for (const entries of Object.values(hooks)) {
|
|
47177
47488
|
for (const entry of entries) {
|
|
47178
|
-
for (const bin of
|
|
47489
|
+
for (const bin of PRIM_BINS4) {
|
|
47179
47490
|
if (entry.command === legacyCommandFor(bin)) resolutions.push({ kind: "legacy_path" });
|
|
47180
47491
|
}
|
|
47181
47492
|
}
|
|
47182
47493
|
}
|
|
47183
47494
|
return resolutions;
|
|
47184
47495
|
}
|
|
47185
|
-
function
|
|
47496
|
+
function inspectHookRuntimeResolutions4() {
|
|
47186
47497
|
const path9 = configPath();
|
|
47187
|
-
if (!
|
|
47188
|
-
return hookRuntimeResolutions3(readHooks(parseHermesDocument(
|
|
47498
|
+
if (!existsSync14(path9)) return [];
|
|
47499
|
+
return hookRuntimeResolutions3(readHooks(parseHermesDocument(readFileSync15(path9, "utf8"))));
|
|
47189
47500
|
}
|
|
47190
47501
|
function entryMatchesRegistration3(owned, registration) {
|
|
47191
47502
|
const expected = entryFor(registration);
|
|
@@ -47193,7 +47504,7 @@ function entryMatchesRegistration3(owned, registration) {
|
|
|
47193
47504
|
}
|
|
47194
47505
|
function hasCompleteHookRegistration3(hooks) {
|
|
47195
47506
|
const owned = ownedRegistrationEntries3(hooks);
|
|
47196
|
-
return owned.length ===
|
|
47507
|
+
return owned.length === REGISTRATIONS3.length && REGISTRATIONS3.every(
|
|
47197
47508
|
(registration) => owned.filter((entry) => entryMatchesRegistration3(entry, registration)).length === 1
|
|
47198
47509
|
);
|
|
47199
47510
|
}
|
|
@@ -47269,7 +47580,7 @@ function serializeHooks(hooks) {
|
|
|
47269
47580
|
return stringify3({ hooks }, { lineWidth: 0 });
|
|
47270
47581
|
}
|
|
47271
47582
|
function isPrimEntry(entry) {
|
|
47272
|
-
return
|
|
47583
|
+
return PRIM_BINS4.some((bin) => commandUsesBin(entry.command, bin));
|
|
47273
47584
|
}
|
|
47274
47585
|
function entryKey(entry) {
|
|
47275
47586
|
return JSON.stringify(entry);
|
|
@@ -47454,11 +47765,11 @@ function assertMergeValid(before, after, expectedHooks) {
|
|
|
47454
47765
|
}
|
|
47455
47766
|
}
|
|
47456
47767
|
function readConfigSnapshot(path9) {
|
|
47457
|
-
if (!
|
|
47768
|
+
if (!existsSync14(path9)) return { exists: false, mode: CONFIG_MODE, raw: "" };
|
|
47458
47769
|
return {
|
|
47459
47770
|
exists: true,
|
|
47460
47771
|
mode: statSync3(path9).mode & 511,
|
|
47461
|
-
raw:
|
|
47772
|
+
raw: readFileSync15(path9, "utf8")
|
|
47462
47773
|
};
|
|
47463
47774
|
}
|
|
47464
47775
|
var CONCURRENT_CONFIG_MESSAGE = "Hermes config changed during update; concurrent changes were preserved, retry the command";
|
|
@@ -47467,7 +47778,7 @@ function writeHermesConfigSnapshot(path9, before, after, expectedHooks) {
|
|
|
47467
47778
|
ensureParent: true,
|
|
47468
47779
|
mode: before.mode,
|
|
47469
47780
|
validate(temporaryPath) {
|
|
47470
|
-
const flushed =
|
|
47781
|
+
const flushed = readFileSync15(temporaryPath, "utf8");
|
|
47471
47782
|
if (!mergePreservesHermesSemantics(before.raw, flushed, expectedHooks)) {
|
|
47472
47783
|
throw new Error(INVALID_MERGE_MESSAGE);
|
|
47473
47784
|
}
|
|
@@ -47490,7 +47801,7 @@ function autoAcceptOf(raw) {
|
|
|
47490
47801
|
function readHooksFromRaw(raw) {
|
|
47491
47802
|
return readHooks(parseHermesDocument(raw));
|
|
47492
47803
|
}
|
|
47493
|
-
function
|
|
47804
|
+
function performInstall4(opts) {
|
|
47494
47805
|
(opts.stageRuntime ?? stageHookRuntime)();
|
|
47495
47806
|
const path9 = configPath();
|
|
47496
47807
|
const snapshot = readConfigSnapshot(path9);
|
|
@@ -47518,9 +47829,9 @@ function performInstall3(opts) {
|
|
|
47518
47829
|
changed
|
|
47519
47830
|
};
|
|
47520
47831
|
}
|
|
47521
|
-
function
|
|
47832
|
+
function performUninstall4() {
|
|
47522
47833
|
const path9 = configPath();
|
|
47523
|
-
if (!
|
|
47834
|
+
if (!existsSync14(path9)) {
|
|
47524
47835
|
removeLegacyShim();
|
|
47525
47836
|
return { path: path9, gate: false, capture: false, autoAccept: false, changed: false };
|
|
47526
47837
|
}
|
|
@@ -47543,9 +47854,9 @@ function performUninstall3() {
|
|
|
47543
47854
|
changed
|
|
47544
47855
|
};
|
|
47545
47856
|
}
|
|
47546
|
-
function
|
|
47857
|
+
function performStatus4() {
|
|
47547
47858
|
const path9 = configPath();
|
|
47548
|
-
const raw =
|
|
47859
|
+
const raw = existsSync14(path9) ? readFileSync15(path9, "utf8") : "";
|
|
47549
47860
|
const hooks = raw ? readHooks(parseHermesDocument(raw)) : {};
|
|
47550
47861
|
return {
|
|
47551
47862
|
path: path9,
|
|
@@ -47569,7 +47880,7 @@ function registerHermesCommands(program3) {
|
|
|
47569
47880
|
const hermes = program3.command("hermes").description("Manage the prim Hermes Agent integration (capture, gate, ingest, presence)");
|
|
47570
47881
|
hermes.command("install").description("Register the prim hooks in Hermes's ~/.hermes/config.yaml").option("--scope <scope>", "user (default; Hermes config is global-only)").option("--force", "Replace any drifted prim hook entries").option("--auto-accept", "Also set hooks_auto_accept: true so the hooks need no TTY consent").action((opts) => {
|
|
47571
47882
|
rejectProjectScope(opts.scope);
|
|
47572
|
-
const result =
|
|
47883
|
+
const result = performInstall4({
|
|
47573
47884
|
force: opts.force ?? false,
|
|
47574
47885
|
autoAccept: opts.autoAccept ?? false
|
|
47575
47886
|
});
|
|
@@ -47580,14 +47891,14 @@ function registerHermesCommands(program3) {
|
|
|
47580
47891
|
console.log(JSON.stringify(result, null, JSON_INDENT3));
|
|
47581
47892
|
});
|
|
47582
47893
|
hermes.command("uninstall").description("Remove all prim hooks from Hermes's ~/.hermes/config.yaml").action(() => {
|
|
47583
|
-
const result =
|
|
47894
|
+
const result = performUninstall4();
|
|
47584
47895
|
console.error(
|
|
47585
47896
|
result.changed ? `[prim] prim hooks removed from ${result.path}` : `[prim] no prim hooks to remove at ${result.path} (nothing changed)`
|
|
47586
47897
|
);
|
|
47587
47898
|
console.log(JSON.stringify(result, null, JSON_INDENT3));
|
|
47588
47899
|
});
|
|
47589
47900
|
hermes.command("status").description("Report whether each prim surface (gate, capture) is installed").action(() => {
|
|
47590
|
-
const result =
|
|
47901
|
+
const result = performStatus4();
|
|
47591
47902
|
const mark = (b) => b ? "\u2713" : "\u2717";
|
|
47592
47903
|
console.error(
|
|
47593
47904
|
`[prim] hermes: gate ${mark(result.gate)} \xB7 capture ${mark(result.capture)} (${result.path})`
|
|
@@ -47635,7 +47946,7 @@ function checkAuth() {
|
|
|
47635
47946
|
return classifyAuthCredential(
|
|
47636
47947
|
credential,
|
|
47637
47948
|
storedCredential ? getTokenExpiresAt() : void 0,
|
|
47638
|
-
storedCredential &&
|
|
47949
|
+
storedCredential && existsSync15(REFRESH_TOKEN_PATH)
|
|
47639
47950
|
);
|
|
47640
47951
|
}
|
|
47641
47952
|
function classifyDaemonHealth(snapshot, options = {}) {
|
|
@@ -47979,6 +48290,34 @@ function classifyCodexHooks(statuses) {
|
|
|
47979
48290
|
detail: "installed; Codex trust is not machine-readable \u2014 verify with `/hooks`"
|
|
47980
48291
|
};
|
|
47981
48292
|
}
|
|
48293
|
+
function classifyCursorHooks(statuses) {
|
|
48294
|
+
const installed = statuses.filter((status) => status.present);
|
|
48295
|
+
if (installed.length === 0)
|
|
48296
|
+
return { name: "cursor-hooks", status: "ok", detail: "not installed" };
|
|
48297
|
+
if (installed.some((status) => !status.complete)) {
|
|
48298
|
+
return {
|
|
48299
|
+
name: "cursor-hooks",
|
|
48300
|
+
status: "fail",
|
|
48301
|
+
detail: "incomplete or drifted native lifecycle \u2014 run `prim cursor install --force`"
|
|
48302
|
+
};
|
|
48303
|
+
}
|
|
48304
|
+
const user = statuses.find((status) => status.footer !== void 0);
|
|
48305
|
+
if (user?.present && user.footer === false && !user.footerPreservedCustom) {
|
|
48306
|
+
return {
|
|
48307
|
+
name: "cursor-hooks",
|
|
48308
|
+
status: "fail",
|
|
48309
|
+
detail: "native lifecycle ready but Cursor CLI footer is missing \u2014 run `prim cursor install --scope user --force`"
|
|
48310
|
+
};
|
|
48311
|
+
}
|
|
48312
|
+
if (statuses.some((status) => status.footerPreservedCustom)) {
|
|
48313
|
+
return {
|
|
48314
|
+
name: "cursor-hooks",
|
|
48315
|
+
status: "warn",
|
|
48316
|
+
detail: "native lifecycle ready; custom Cursor CLI footer preserved"
|
|
48317
|
+
};
|
|
48318
|
+
}
|
|
48319
|
+
return { name: "cursor-hooks", status: "ok", detail: "complete native lifecycle ready" };
|
|
48320
|
+
}
|
|
47982
48321
|
function classifyHermesHooks(status) {
|
|
47983
48322
|
if (!status.present) {
|
|
47984
48323
|
return { name: "hermes-hooks", status: "ok", detail: "not installed" };
|
|
@@ -48010,7 +48349,18 @@ function checkAgentHooks() {
|
|
|
48010
48349
|
});
|
|
48011
48350
|
}
|
|
48012
48351
|
try {
|
|
48013
|
-
|
|
48352
|
+
const status = performStatus3();
|
|
48353
|
+
checks.push(classifyCursorHooks([status.project, status.user]));
|
|
48354
|
+
} catch (error) {
|
|
48355
|
+
const detail = boundedHealthError(error instanceof Error ? error.message : String(error));
|
|
48356
|
+
checks.push({
|
|
48357
|
+
name: "cursor-hooks",
|
|
48358
|
+
status: "fail",
|
|
48359
|
+
detail: detail ?? "hook configuration is unreadable"
|
|
48360
|
+
});
|
|
48361
|
+
}
|
|
48362
|
+
try {
|
|
48363
|
+
checks.push(classifyHermesHooks(performStatus4()));
|
|
48014
48364
|
} catch (error) {
|
|
48015
48365
|
const detail = boundedHealthError(error instanceof Error ? error.message : String(error));
|
|
48016
48366
|
checks.push({
|
|
@@ -48120,7 +48470,8 @@ function checkHookRuntime() {
|
|
|
48120
48470
|
[
|
|
48121
48471
|
...inspectHookRuntimeResolutions(),
|
|
48122
48472
|
...inspectHookRuntimeResolutions2(),
|
|
48123
|
-
...inspectHookRuntimeResolutions3()
|
|
48473
|
+
...inspectHookRuntimeResolutions3(),
|
|
48474
|
+
...inspectHookRuntimeResolutions4()
|
|
48124
48475
|
],
|
|
48125
48476
|
inspectHookRuntime,
|
|
48126
48477
|
packageVersion
|
|
@@ -48255,12 +48606,12 @@ function registerDoctorCommands(program3) {
|
|
|
48255
48606
|
}
|
|
48256
48607
|
|
|
48257
48608
|
// src/commands/moves.ts
|
|
48258
|
-
import { existsSync as
|
|
48259
|
-
import { join as
|
|
48609
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync12, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
|
|
48610
|
+
import { join as join21 } from "path";
|
|
48260
48611
|
|
|
48261
48612
|
// src/flusher.ts
|
|
48262
48613
|
import { createReadStream, renameSync as renameSync6, unlinkSync as unlinkSync4 } from "fs";
|
|
48263
|
-
import { dirname as dirname13, join as
|
|
48614
|
+
import { dirname as dirname13, join as join20 } from "path";
|
|
48264
48615
|
|
|
48265
48616
|
// src/dead-letter.ts
|
|
48266
48617
|
import { createHash as createHash9, randomBytes as randomBytes6 } from "crypto";
|
|
@@ -48268,7 +48619,7 @@ import {
|
|
|
48268
48619
|
constants as constants5,
|
|
48269
48620
|
chmodSync as chmodSync5,
|
|
48270
48621
|
closeSync as closeSync5,
|
|
48271
|
-
existsSync as
|
|
48622
|
+
existsSync as existsSync16,
|
|
48272
48623
|
fchmodSync as fchmodSync3,
|
|
48273
48624
|
fsyncSync as fsyncSync3,
|
|
48274
48625
|
mkdirSync as mkdirSync11,
|
|
@@ -48277,16 +48628,16 @@ import {
|
|
|
48277
48628
|
rmSync as rmSync7,
|
|
48278
48629
|
writeFileSync as writeFileSync8
|
|
48279
48630
|
} from "fs";
|
|
48280
|
-
import { dirname as dirname12, join as
|
|
48631
|
+
import { dirname as dirname12, join as join19 } from "path";
|
|
48281
48632
|
var DIRECTORY_MODE3 = 448;
|
|
48282
48633
|
var FILE_MODE2 = 384;
|
|
48283
48634
|
var DEAD_LETTER_DIRNAME = "dead-letter";
|
|
48284
48635
|
function deadLetterDirectoryForRotation(flushingPath) {
|
|
48285
|
-
return
|
|
48636
|
+
return join19(dirname12(flushingPath), DEAD_LETTER_DIRNAME);
|
|
48286
48637
|
}
|
|
48287
48638
|
function deadLetterPathForRawLine(flushingPath, rawLine) {
|
|
48288
48639
|
const quarantineId = createHash9("sha256").update(rawLine).digest("hex");
|
|
48289
|
-
return
|
|
48640
|
+
return join19(deadLetterDirectoryForRotation(flushingPath), `raw-${quarantineId}.json`);
|
|
48290
48641
|
}
|
|
48291
48642
|
function ensureDeadLetterDirectory(flushingPath, persistDirectory) {
|
|
48292
48643
|
const directory = deadLetterDirectoryForRotation(flushingPath);
|
|
@@ -48296,11 +48647,11 @@ function ensureDeadLetterDirectory(flushingPath, persistDirectory) {
|
|
|
48296
48647
|
return directory;
|
|
48297
48648
|
}
|
|
48298
48649
|
function persistDeadLetter(directory, path9, quarantineId, record2, persistDirectory) {
|
|
48299
|
-
if (
|
|
48650
|
+
if (existsSync16(path9)) {
|
|
48300
48651
|
persistDirectory(directory);
|
|
48301
48652
|
return;
|
|
48302
48653
|
}
|
|
48303
|
-
const temporaryPath =
|
|
48654
|
+
const temporaryPath = join19(
|
|
48304
48655
|
directory,
|
|
48305
48656
|
`.${quarantineId}.${String(process.pid)}.${randomBytes6(8).toString("hex")}.tmp`
|
|
48306
48657
|
);
|
|
@@ -48332,7 +48683,7 @@ function quarantineMove(flushingPath, move, reason, now = Date.now, options = {}
|
|
|
48332
48683
|
reason,
|
|
48333
48684
|
move
|
|
48334
48685
|
};
|
|
48335
|
-
const path9 =
|
|
48686
|
+
const path9 = join19(directory, `${record2.quarantineId}.json`);
|
|
48336
48687
|
persistDeadLetter(directory, path9, record2.quarantineId, record2, persistDirectory);
|
|
48337
48688
|
return record2;
|
|
48338
48689
|
}
|
|
@@ -48437,6 +48788,12 @@ function deadLetterReason(error) {
|
|
|
48437
48788
|
}
|
|
48438
48789
|
return void 0;
|
|
48439
48790
|
}
|
|
48791
|
+
function mayBeBatchSizeFailure(error) {
|
|
48792
|
+
if (error instanceof HttpError) {
|
|
48793
|
+
return error.status >= 500 && error.status !== 503;
|
|
48794
|
+
}
|
|
48795
|
+
return error instanceof Error && error.name === "TimeoutError";
|
|
48796
|
+
}
|
|
48440
48797
|
async function* rawJournalLines(input) {
|
|
48441
48798
|
let pending = [];
|
|
48442
48799
|
let pendingBytes = 0;
|
|
@@ -48478,7 +48835,7 @@ async function drainFlushingPath(flushingPath, client, binding, options = {}) {
|
|
|
48478
48835
|
return { flushed: batch2.length, quarantined: 0 };
|
|
48479
48836
|
} catch (error) {
|
|
48480
48837
|
const reason = deadLetterReason(error);
|
|
48481
|
-
if (!reason) {
|
|
48838
|
+
if (!(reason || mayBeBatchSizeFailure(error))) {
|
|
48482
48839
|
throw error;
|
|
48483
48840
|
}
|
|
48484
48841
|
if (batch2.length > 1) {
|
|
@@ -48487,6 +48844,9 @@ async function drainFlushingPath(flushingPath, client, binding, options = {}) {
|
|
|
48487
48844
|
const right = await postBatch(batch2.slice(midpoint));
|
|
48488
48845
|
return addDrainCounts(left, right);
|
|
48489
48846
|
}
|
|
48847
|
+
if (!reason) {
|
|
48848
|
+
throw error;
|
|
48849
|
+
}
|
|
48490
48850
|
const [move] = batch2;
|
|
48491
48851
|
const quarantined = quarantineMove(
|
|
48492
48852
|
flushingPath,
|
|
@@ -48644,7 +49004,7 @@ async function flushOnce() {
|
|
|
48644
49004
|
return inspection.retainedBuckets.length > 0 ? { flushed: total, quarantined, retained: inspection.retainedBuckets } : { flushed: total, quarantined };
|
|
48645
49005
|
}
|
|
48646
49006
|
var flushInFlight;
|
|
48647
|
-
var FLUSH_LOCK_PATH =
|
|
49007
|
+
var FLUSH_LOCK_PATH = join20(dirname13(JOURNAL_DIR), ".flush.lock");
|
|
48648
49008
|
var FLUSH_LOCK_TIMEOUT_MS = 250;
|
|
48649
49009
|
function isFlushLockContended(error) {
|
|
48650
49010
|
return error instanceof Error && error.message.startsWith("timed out waiting for file lock");
|
|
@@ -48778,19 +49138,19 @@ function registerMovesCommands(program3) {
|
|
|
48778
49138
|
}
|
|
48779
49139
|
});
|
|
48780
49140
|
moves.command("bind").description("Pin the current directory to an org via .prim/workspace.json").requiredOption("--orgId <orgId>", "Convex organization id").action((opts) => {
|
|
48781
|
-
const dir =
|
|
48782
|
-
if (!
|
|
49141
|
+
const dir = join21(process.cwd(), ".prim");
|
|
49142
|
+
if (!existsSync17(dir)) {
|
|
48783
49143
|
mkdirSync12(dir, { recursive: true, mode: DIR_MODE });
|
|
48784
49144
|
}
|
|
48785
|
-
const file =
|
|
49145
|
+
const file = join21(process.cwd(), WORKSPACE_FILE);
|
|
48786
49146
|
writeFileSync9(file, JSON.stringify({ orgId: opts.orgId, boundAt: Date.now() }, null, 2), {
|
|
48787
49147
|
mode: FILE_MODE3
|
|
48788
49148
|
});
|
|
48789
49149
|
console.log(`[prim] bound ${process.cwd()} to org ${opts.orgId}`);
|
|
48790
49150
|
});
|
|
48791
49151
|
moves.command("drop").description("Remove the .prim/workspace.json binding from the cwd").action(() => {
|
|
48792
|
-
const file =
|
|
48793
|
-
if (!
|
|
49152
|
+
const file = join21(process.cwd(), WORKSPACE_FILE);
|
|
49153
|
+
if (!existsSync17(file)) {
|
|
48794
49154
|
console.log("[prim] no workspace binding in cwd");
|
|
48795
49155
|
return;
|
|
48796
49156
|
}
|
|
@@ -48881,31 +49241,31 @@ function registerReconcileCommands(program3) {
|
|
|
48881
49241
|
|
|
48882
49242
|
// src/commands/session.ts
|
|
48883
49243
|
import {
|
|
48884
|
-
existsSync as
|
|
49244
|
+
existsSync as existsSync19,
|
|
48885
49245
|
mkdirSync as mkdirSync13,
|
|
48886
|
-
readFileSync as
|
|
49246
|
+
readFileSync as readFileSync17,
|
|
48887
49247
|
readdirSync as readdirSync5,
|
|
48888
49248
|
unlinkSync as unlinkSync6,
|
|
48889
49249
|
writeFileSync as writeFileSync10
|
|
48890
49250
|
} from "fs";
|
|
48891
|
-
import { join as
|
|
49251
|
+
import { join as join23 } from "path";
|
|
48892
49252
|
|
|
48893
49253
|
// src/binding.ts
|
|
48894
|
-
import { existsSync as
|
|
48895
|
-
import { dirname as dirname14, join as
|
|
49254
|
+
import { existsSync as existsSync18, readFileSync as readFileSync16 } from "fs";
|
|
49255
|
+
import { dirname as dirname14, join as join22 } from "path";
|
|
48896
49256
|
var PRIM_CONFIG_DIR = primConfigDirectory();
|
|
48897
|
-
var SESSIONS_DIR =
|
|
49257
|
+
var SESSIONS_DIR = join22(PRIM_CONFIG_DIR, "sessions");
|
|
48898
49258
|
|
|
48899
49259
|
// src/commands/session.ts
|
|
48900
49260
|
var DIR_MODE2 = 448;
|
|
48901
49261
|
var FILE_MODE4 = 384;
|
|
48902
49262
|
function ensureDir() {
|
|
48903
|
-
if (!
|
|
49263
|
+
if (!existsSync19(SESSIONS_DIR)) {
|
|
48904
49264
|
mkdirSync13(SESSIONS_DIR, { recursive: true, mode: DIR_MODE2 });
|
|
48905
49265
|
}
|
|
48906
49266
|
}
|
|
48907
49267
|
function markerPath(sessionId) {
|
|
48908
|
-
return
|
|
49268
|
+
return join23(SESSIONS_DIR, `${sessionId}.json`);
|
|
48909
49269
|
}
|
|
48910
49270
|
function registerSessionCommands(program3) {
|
|
48911
49271
|
const session = program3.command("session").description("Decision Event Pipeline \u2014 session binding markers");
|
|
@@ -48921,7 +49281,7 @@ function registerSessionCommands(program3) {
|
|
|
48921
49281
|
console.log(`[prim] session ${sessionId} bound to org ${opts.orgId}`);
|
|
48922
49282
|
});
|
|
48923
49283
|
session.command("list").description("List active session markers").action(() => {
|
|
48924
|
-
if (!
|
|
49284
|
+
if (!existsSync19(SESSIONS_DIR)) {
|
|
48925
49285
|
console.log("[prim] no session markers");
|
|
48926
49286
|
return;
|
|
48927
49287
|
}
|
|
@@ -48933,7 +49293,7 @@ function registerSessionCommands(program3) {
|
|
|
48933
49293
|
for (const f of files) {
|
|
48934
49294
|
const sessionId = f.replace(/\.json$/, "");
|
|
48935
49295
|
try {
|
|
48936
|
-
const m = JSON.parse(
|
|
49296
|
+
const m = JSON.parse(readFileSync17(join23(SESSIONS_DIR, f), "utf-8"));
|
|
48937
49297
|
console.log(`${sessionId} org=${m.orgId}`);
|
|
48938
49298
|
} catch {
|
|
48939
49299
|
}
|
|
@@ -48941,7 +49301,7 @@ function registerSessionCommands(program3) {
|
|
|
48941
49301
|
});
|
|
48942
49302
|
session.command("drop <sessionId>").description("Remove a session marker").action((sessionId) => {
|
|
48943
49303
|
const p = markerPath(sessionId);
|
|
48944
|
-
if (!
|
|
49304
|
+
if (!existsSync19(p)) {
|
|
48945
49305
|
console.log(`[prim] no marker for session ${sessionId}`);
|
|
48946
49306
|
return;
|
|
48947
49307
|
}
|
|
@@ -48952,13 +49312,14 @@ function registerSessionCommands(program3) {
|
|
|
48952
49312
|
|
|
48953
49313
|
// src/commands/setup.ts
|
|
48954
49314
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
48955
|
-
import { existsSync as
|
|
48956
|
-
import { join as
|
|
49315
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
|
|
49316
|
+
import { join as join24 } from "path";
|
|
48957
49317
|
var EXIT_INCOMPLETE = 1;
|
|
48958
49318
|
var EXIT_USAGE3 = 2;
|
|
48959
49319
|
var SESSION_LABELS = {
|
|
48960
49320
|
claude: "Claude Code integration",
|
|
48961
49321
|
codex: "Codex integration",
|
|
49322
|
+
cursor: "Cursor integration",
|
|
48962
49323
|
hermes: "Hermes integration"
|
|
48963
49324
|
};
|
|
48964
49325
|
function planSetupSteps(opts) {
|
|
@@ -49034,8 +49395,8 @@ function detectProjectConflicts(agent, run) {
|
|
|
49034
49395
|
}
|
|
49035
49396
|
try {
|
|
49036
49397
|
const root = gitToplevel();
|
|
49037
|
-
const preCommit = root &&
|
|
49038
|
-
if (preCommit &&
|
|
49398
|
+
const preCommit = root && join24(root, ".git", "hooks", "pre-commit");
|
|
49399
|
+
if (preCommit && existsSync20(preCommit) && readFileSync18(preCommit, "utf-8").includes("prim-pre-commit")) {
|
|
49039
49400
|
conflicts.push(CONFLICT_HOOKS);
|
|
49040
49401
|
}
|
|
49041
49402
|
} catch {
|
|
@@ -49053,6 +49414,9 @@ function detectAgent(env4) {
|
|
|
49053
49414
|
if (env4.HERMES_INTERACTIVE) {
|
|
49054
49415
|
return "hermes";
|
|
49055
49416
|
}
|
|
49417
|
+
if (env4.CURSOR_AGENT) {
|
|
49418
|
+
return "cursor";
|
|
49419
|
+
}
|
|
49056
49420
|
return "claude";
|
|
49057
49421
|
}
|
|
49058
49422
|
function resolveAgent(agentFlag, env4) {
|
|
@@ -49074,7 +49438,7 @@ function parseSetupAuthStatus(result) {
|
|
|
49074
49438
|
function registerSetupCommand(program3, dependencies = {}) {
|
|
49075
49439
|
program3.command("setup").description(
|
|
49076
49440
|
"Install everything in one shot (auth, session + git hooks, daemon, skill, welcome)"
|
|
49077
|
-
).option("--agent <agent>", "claude, codex, or hermes (auto-detected when omitted)").option(
|
|
49441
|
+
).option("--agent <agent>", "claude, codex, cursor, or hermes (auto-detected when omitted)").option(
|
|
49078
49442
|
"--scope <scope>",
|
|
49079
49443
|
"user (default \u2014 install once for every repo) or project (this repo only)",
|
|
49080
49444
|
"user"
|
|
@@ -49083,9 +49447,9 @@ function registerSetupCommand(program3, dependencies = {}) {
|
|
|
49083
49447
|
"with the default user scope, remove any project-scoped prim config in this repo (else just warn)"
|
|
49084
49448
|
).option("--no-daemon", "stop and disable the companion daemon").action((opts) => {
|
|
49085
49449
|
const { agent: agentInput, detected } = resolveAgent(opts.agent, process.env);
|
|
49086
|
-
if (agentInput !== "claude" && agentInput !== "codex" && agentInput !== "hermes") {
|
|
49450
|
+
if (agentInput !== "claude" && agentInput !== "codex" && agentInput !== "cursor" && agentInput !== "hermes") {
|
|
49087
49451
|
process.stderr.write(
|
|
49088
|
-
`[prim] unknown --agent "${agentInput}" (expected claude, codex, or hermes)
|
|
49452
|
+
`[prim] unknown --agent "${agentInput}" (expected claude, codex, cursor, or hermes)
|
|
49089
49453
|
`
|
|
49090
49454
|
);
|
|
49091
49455
|
(dependencies.exit ?? process.exit)(EXIT_USAGE3);
|
|
@@ -49196,18 +49560,22 @@ function registerSetupCommand(program3, dependencies = {}) {
|
|
|
49196
49560
|
}
|
|
49197
49561
|
|
|
49198
49562
|
// src/commands/skill.ts
|
|
49563
|
+
import { createHash as createHash11 } from "crypto";
|
|
49199
49564
|
import {
|
|
49200
49565
|
constants as constants7,
|
|
49201
49566
|
closeSync as closeSync7,
|
|
49202
|
-
existsSync as
|
|
49567
|
+
existsSync as existsSync22,
|
|
49203
49568
|
fstatSync as fstatSync3,
|
|
49204
49569
|
lstatSync as lstatSync7,
|
|
49205
49570
|
openSync as openSync7,
|
|
49206
|
-
readFileSync as
|
|
49207
|
-
readSync as readSync3
|
|
49571
|
+
readFileSync as readFileSync20,
|
|
49572
|
+
readSync as readSync3,
|
|
49573
|
+
readdirSync as readdirSync7,
|
|
49574
|
+
rmdirSync as rmdirSync2,
|
|
49575
|
+
unlinkSync as unlinkSync7
|
|
49208
49576
|
} from "fs";
|
|
49209
|
-
import { homedir as
|
|
49210
|
-
import { dirname as dirname16, join as
|
|
49577
|
+
import { homedir as homedir11 } from "os";
|
|
49578
|
+
import { dirname as dirname16, join as join27, resolve as resolve8 } from "path";
|
|
49211
49579
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
49212
49580
|
|
|
49213
49581
|
// node_modules/.pnpm/diff@5.2.2/node_modules/diff/lib/index.mjs
|
|
@@ -49377,7 +49745,7 @@ Diff.prototype = {
|
|
|
49377
49745
|
tokenize: function tokenize(value) {
|
|
49378
49746
|
return value.split("");
|
|
49379
49747
|
},
|
|
49380
|
-
join: function
|
|
49748
|
+
join: function join25(chars) {
|
|
49381
49749
|
return chars.join("");
|
|
49382
49750
|
}
|
|
49383
49751
|
};
|
|
@@ -49717,28 +50085,28 @@ import { createHash as createHash10 } from "crypto";
|
|
|
49717
50085
|
import {
|
|
49718
50086
|
constants as constants6,
|
|
49719
50087
|
closeSync as closeSync6,
|
|
49720
|
-
existsSync as
|
|
50088
|
+
existsSync as existsSync21,
|
|
49721
50089
|
fstatSync as fstatSync2,
|
|
49722
50090
|
lstatSync as lstatSync6,
|
|
49723
50091
|
mkdirSync as mkdirSync14,
|
|
49724
50092
|
openSync as openSync6,
|
|
49725
|
-
readFileSync as
|
|
50093
|
+
readFileSync as readFileSync19,
|
|
49726
50094
|
readSync as readSync2,
|
|
49727
50095
|
readdirSync as readdirSync6,
|
|
49728
50096
|
realpathSync as realpathSync4,
|
|
49729
50097
|
rmSync as rmSync8,
|
|
49730
50098
|
rmdirSync
|
|
49731
50099
|
} from "fs";
|
|
49732
|
-
import { homedir as
|
|
49733
|
-
import { dirname as dirname15, isAbsolute as
|
|
50100
|
+
import { homedir as homedir10 } from "os";
|
|
50101
|
+
import { dirname as dirname15, isAbsolute as isAbsolute8, join as join26, relative as relative2, resolve as resolve7, sep as sep2 } from "path";
|
|
49734
50102
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
49735
50103
|
var __dirname4 = dirname15(fileURLToPath4(import.meta.url));
|
|
49736
50104
|
var PLUGIN_DESCRIPTION = "Primitive decision-graph guidance for the prim CLI \u2014 a model-invoked skill installed by prim skill install.";
|
|
49737
50105
|
var MAX_MANIFEST_BYTES2 = 64 * 1024;
|
|
49738
50106
|
var MAX_SKILL_BYTES = 1024 * 1024;
|
|
49739
50107
|
function pluginDirFor(cwd, scope) {
|
|
49740
|
-
const base = scope === "user" ?
|
|
49741
|
-
return
|
|
50108
|
+
const base = scope === "user" ? join26(homedir10(), ".claude") : join26(gitToplevel(cwd) ?? cwd, ".claude");
|
|
50109
|
+
return join26(base, "skills", "prim");
|
|
49742
50110
|
}
|
|
49743
50111
|
function resolvePluginDir(cwd, scope) {
|
|
49744
50112
|
if (scope && scope !== "user" && scope !== "project") {
|
|
@@ -49751,7 +50119,7 @@ function packageVersion2() {
|
|
|
49751
50119
|
let dir = __dirname4;
|
|
49752
50120
|
while (dir !== dirname15(dir)) {
|
|
49753
50121
|
const p = resolve7(dir, "package.json");
|
|
49754
|
-
if (
|
|
50122
|
+
if (existsSync21(p)) return JSON.parse(readFileSync19(p, "utf-8")).version;
|
|
49755
50123
|
dir = dirname15(dir);
|
|
49756
50124
|
}
|
|
49757
50125
|
return "0.0.0";
|
|
@@ -49766,12 +50134,12 @@ function renderClaudePlugin() {
|
|
|
49766
50134
|
return { manifest: pluginManifest(version), skill: loadSkill(), version };
|
|
49767
50135
|
}
|
|
49768
50136
|
function removeDirIfEmpty(dir) {
|
|
49769
|
-
if (
|
|
50137
|
+
if (existsSync21(dir) && readdirSync6(dir).length === 0) rmdirSync(dir);
|
|
49770
50138
|
}
|
|
49771
50139
|
function pluginPaths(dir) {
|
|
49772
50140
|
return {
|
|
49773
|
-
manifestPath:
|
|
49774
|
-
skillPath:
|
|
50141
|
+
manifestPath: join26(dir, ".claude-plugin", "plugin.json"),
|
|
50142
|
+
skillPath: join26(dir, "SKILL.md")
|
|
49775
50143
|
};
|
|
49776
50144
|
}
|
|
49777
50145
|
function installClaudePlugin(cwd, opts) {
|
|
@@ -49779,8 +50147,8 @@ function installClaudePlugin(cwd, opts) {
|
|
|
49779
50147
|
if (dir === null) return 1;
|
|
49780
50148
|
const { manifestPath, skillPath } = pluginPaths(dir);
|
|
49781
50149
|
const { manifest, skill } = renderClaudePlugin();
|
|
49782
|
-
const manifestCurrent =
|
|
49783
|
-
const skillCurrent =
|
|
50150
|
+
const manifestCurrent = existsSync21(manifestPath) ? readFileSync19(manifestPath, "utf-8") : null;
|
|
50151
|
+
const skillCurrent = existsSync21(skillPath) ? readFileSync19(skillPath, "utf-8") : null;
|
|
49784
50152
|
if (manifestCurrent === manifest && skillCurrent === skill) {
|
|
49785
50153
|
console.log("No changes \u2014 prim skill plugin already up to date.");
|
|
49786
50154
|
return 0;
|
|
@@ -49789,7 +50157,7 @@ function installClaudePlugin(cwd, opts) {
|
|
|
49789
50157
|
console.log(`Would write plugin to ${dir} (.claude-plugin/plugin.json + SKILL.md)`);
|
|
49790
50158
|
return 0;
|
|
49791
50159
|
}
|
|
49792
|
-
mkdirSync14(
|
|
50160
|
+
mkdirSync14(join26(dir, ".claude-plugin"), { recursive: true });
|
|
49793
50161
|
atomicWrite4(manifestPath, manifest);
|
|
49794
50162
|
atomicWrite4(skillPath, skill);
|
|
49795
50163
|
console.log(`Installed prim skill plugin at ${dir}`);
|
|
@@ -49803,13 +50171,13 @@ function uninstallClaudePlugin(cwd, opts) {
|
|
|
49803
50171
|
const dir = resolvePluginDir(cwd, opts.scope);
|
|
49804
50172
|
if (dir === null) return 1;
|
|
49805
50173
|
const { manifestPath, skillPath } = pluginPaths(dir);
|
|
49806
|
-
if (!
|
|
50174
|
+
if (!existsSync21(manifestPath) && !existsSync21(skillPath)) {
|
|
49807
50175
|
console.log(`prim skill plugin not present at ${dir}`);
|
|
49808
50176
|
return 0;
|
|
49809
50177
|
}
|
|
49810
50178
|
rmSync8(manifestPath, { force: true });
|
|
49811
50179
|
rmSync8(skillPath, { force: true });
|
|
49812
|
-
removeDirIfEmpty(
|
|
50180
|
+
removeDirIfEmpty(join26(dir, ".claude-plugin"));
|
|
49813
50181
|
removeDirIfEmpty(dir);
|
|
49814
50182
|
console.log(`Removed prim skill plugin from ${dir}`);
|
|
49815
50183
|
return 0;
|
|
@@ -49818,7 +50186,7 @@ function statusClaudePlugin(cwd, opts) {
|
|
|
49818
50186
|
const dir = resolvePluginDir(cwd, opts.scope);
|
|
49819
50187
|
if (dir === null) return 1;
|
|
49820
50188
|
const { skillPath } = pluginPaths(dir);
|
|
49821
|
-
const installed =
|
|
50189
|
+
const installed = existsSync21(skillPath);
|
|
49822
50190
|
if (opts.json) {
|
|
49823
50191
|
printJson({ installed, target: dir });
|
|
49824
50192
|
return installed ? 0 : 1;
|
|
@@ -49853,11 +50221,109 @@ var AGENT_TARGET = {
|
|
|
49853
50221
|
codex: "AGENTS.md",
|
|
49854
50222
|
hermes: ".hermes.md"
|
|
49855
50223
|
};
|
|
50224
|
+
var CURSOR_SKILL_OWNER = "@primitive.ai/prim";
|
|
50225
|
+
var CURSOR_SKILL_MANIFEST = ".prim-owned.json";
|
|
50226
|
+
function sha2563(content) {
|
|
50227
|
+
return createHash11("sha256").update(content).digest("hex");
|
|
50228
|
+
}
|
|
50229
|
+
function cursorSkillDirectory(cwd, scope) {
|
|
50230
|
+
const base = scope === "user" ? cursorConfigDirectory() : gitToplevel(cwd) ?? cwd;
|
|
50231
|
+
return join27(base, scope === "user" ? "skills" : ".cursor/skills", "prim");
|
|
50232
|
+
}
|
|
50233
|
+
function cursorSkillPaths(cwd, scope) {
|
|
50234
|
+
const directory = cursorSkillDirectory(cwd, scope);
|
|
50235
|
+
return {
|
|
50236
|
+
directory,
|
|
50237
|
+
skill: join27(directory, "SKILL.md"),
|
|
50238
|
+
manifest: join27(directory, CURSOR_SKILL_MANIFEST)
|
|
50239
|
+
};
|
|
50240
|
+
}
|
|
50241
|
+
function readCursorSkillManifest(path9) {
|
|
50242
|
+
try {
|
|
50243
|
+
const value = JSON.parse(readFileSync20(path9, "utf8"));
|
|
50244
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
50245
|
+
const record2 = value;
|
|
50246
|
+
if (record2.version !== 1 || record2.owner !== CURSOR_SKILL_OWNER || typeof record2.contentSha256 !== "string" || !/^[0-9a-f]{64}$/u.test(record2.contentSha256)) {
|
|
50247
|
+
return;
|
|
50248
|
+
}
|
|
50249
|
+
return record2;
|
|
50250
|
+
} catch {
|
|
50251
|
+
return;
|
|
50252
|
+
}
|
|
50253
|
+
}
|
|
50254
|
+
function cursorSkillStatus(cwd, scope) {
|
|
50255
|
+
const paths = cursorSkillPaths(cwd, scope);
|
|
50256
|
+
const manifest = readCursorSkillManifest(paths.manifest);
|
|
50257
|
+
const content = existsSync22(paths.skill) ? readFileSync20(paths.skill, "utf8") : void 0;
|
|
50258
|
+
const owned = manifest !== void 0;
|
|
50259
|
+
const installed = owned && content !== void 0 && sha2563(content) === manifest.contentSha256;
|
|
50260
|
+
return {
|
|
50261
|
+
installed,
|
|
50262
|
+
owned,
|
|
50263
|
+
edited: owned && content !== void 0 && !installed,
|
|
50264
|
+
target: paths.skill
|
|
50265
|
+
};
|
|
50266
|
+
}
|
|
50267
|
+
function validCursorSkillScope(scope) {
|
|
50268
|
+
if (scope === void 0 || scope === "project" || scope === "user") return true;
|
|
50269
|
+
console.error(`Unknown --scope "${scope}" (expected user or project)`);
|
|
50270
|
+
return false;
|
|
50271
|
+
}
|
|
50272
|
+
function installCursorSkill(cwd, opts) {
|
|
50273
|
+
const paths = cursorSkillPaths(cwd, opts.scope);
|
|
50274
|
+
const status = cursorSkillStatus(cwd, opts.scope);
|
|
50275
|
+
const manifestExists = existsSync22(paths.manifest);
|
|
50276
|
+
const skillExists = existsSync22(paths.skill);
|
|
50277
|
+
if (manifestExists && !status.owned || !manifestExists && skillExists || status.edited) {
|
|
50278
|
+
console.error(`Refusing to overwrite a foreign or edited Cursor skill at ${paths.skill}`);
|
|
50279
|
+
return 1;
|
|
50280
|
+
}
|
|
50281
|
+
const content = loadSkill();
|
|
50282
|
+
const manifest = {
|
|
50283
|
+
version: 1,
|
|
50284
|
+
owner: CURSOR_SKILL_OWNER,
|
|
50285
|
+
contentSha256: sha2563(content)
|
|
50286
|
+
};
|
|
50287
|
+
if (status.installed && readFileSync20(paths.skill, "utf8") === content) {
|
|
50288
|
+
console.log(`No changes \u2014 Cursor skill already up to date at ${paths.skill}`);
|
|
50289
|
+
return 0;
|
|
50290
|
+
}
|
|
50291
|
+
if (opts.dryRun) {
|
|
50292
|
+
const existing = skillExists ? readFileSync20(paths.skill, "utf8") : "";
|
|
50293
|
+
process.stdout.write(createPatch(paths.skill, existing, content, "current", "proposed"));
|
|
50294
|
+
return 0;
|
|
50295
|
+
}
|
|
50296
|
+
atomicWriteFile(paths.skill, content, { ensureParent: true });
|
|
50297
|
+
atomicWriteFile(paths.manifest, `${JSON.stringify(manifest, null, 2)}
|
|
50298
|
+
`, { ensureParent: true });
|
|
50299
|
+
console.log(`Installed Cursor skill at ${paths.skill}`);
|
|
50300
|
+
return 0;
|
|
50301
|
+
}
|
|
50302
|
+
function uninstallCursorSkill(cwd, scope) {
|
|
50303
|
+
const paths = cursorSkillPaths(cwd, scope);
|
|
50304
|
+
const status = cursorSkillStatus(cwd, scope);
|
|
50305
|
+
if (!status.owned) {
|
|
50306
|
+
console.log(`No Primitive-owned Cursor skill at ${paths.skill}`);
|
|
50307
|
+
return 0;
|
|
50308
|
+
}
|
|
50309
|
+
if (status.edited) {
|
|
50310
|
+
console.error(`Refusing to remove an edited Cursor skill at ${paths.skill}`);
|
|
50311
|
+
return 1;
|
|
50312
|
+
}
|
|
50313
|
+
if (existsSync22(paths.skill)) unlinkSync7(paths.skill);
|
|
50314
|
+
if (existsSync22(paths.manifest)) unlinkSync7(paths.manifest);
|
|
50315
|
+
try {
|
|
50316
|
+
if (readdirSync7(paths.directory).length === 0) rmdirSync2(paths.directory);
|
|
50317
|
+
} catch {
|
|
50318
|
+
}
|
|
50319
|
+
console.log(`Removed Primitive-owned Cursor skill from ${paths.skill}`);
|
|
50320
|
+
return 0;
|
|
50321
|
+
}
|
|
49856
50322
|
function userTargetFor(agent) {
|
|
49857
|
-
if (agent === "claude") return
|
|
49858
|
-
if (agent === "codex") return
|
|
50323
|
+
if (agent === "claude") return join27(homedir11(), ".claude", "CLAUDE.md");
|
|
50324
|
+
if (agent === "codex") return join27(homedir11(), ".codex", "AGENTS.md");
|
|
49859
50325
|
if (agent === "hermes") {
|
|
49860
|
-
return
|
|
50326
|
+
return join27(process.env.HERMES_HOME ?? join27(homedir11(), ".hermes"), ".hermes.md");
|
|
49861
50327
|
}
|
|
49862
50328
|
return null;
|
|
49863
50329
|
}
|
|
@@ -49865,13 +50331,13 @@ function loadSkill() {
|
|
|
49865
50331
|
let dir = __dirname5;
|
|
49866
50332
|
while (dir !== dirname16(dir)) {
|
|
49867
50333
|
const p = resolve8(dir, "SKILL.md");
|
|
49868
|
-
if (
|
|
50334
|
+
if (existsSync22(p)) return readFileSync20(p, "utf-8");
|
|
49869
50335
|
dir = dirname16(dir);
|
|
49870
50336
|
}
|
|
49871
50337
|
throw new Error("SKILL.md not found in package");
|
|
49872
50338
|
}
|
|
49873
50339
|
function detectTargets(cwd) {
|
|
49874
|
-
return TARGET_CANDIDATES.filter((p) =>
|
|
50340
|
+
return TARGET_CANDIDATES.filter((p) => existsSync22(resolve8(cwd, p)));
|
|
49875
50341
|
}
|
|
49876
50342
|
function detectNewline(content) {
|
|
49877
50343
|
return content.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -49908,18 +50374,18 @@ function resolveTarget(cwd, opts) {
|
|
|
49908
50374
|
if (opts.target) return resolve8(cwd, opts.target);
|
|
49909
50375
|
if (opts.scope === "user") {
|
|
49910
50376
|
if (!opts.agent) {
|
|
49911
|
-
console.error("--scope user requires --agent (claude, codex, or hermes)");
|
|
50377
|
+
console.error("--scope user requires --agent (claude, codex, cursor, or hermes)");
|
|
49912
50378
|
return null;
|
|
49913
50379
|
}
|
|
49914
50380
|
const userTarget = userTargetFor(opts.agent);
|
|
49915
50381
|
if (userTarget) return userTarget;
|
|
49916
|
-
console.error(`Unknown --agent "${opts.agent}" (expected claude, codex, or hermes)`);
|
|
50382
|
+
console.error(`Unknown --agent "${opts.agent}" (expected claude, codex, cursor, or hermes)`);
|
|
49917
50383
|
return null;
|
|
49918
50384
|
}
|
|
49919
50385
|
if (opts.agent) {
|
|
49920
50386
|
const mapped = AGENT_TARGET[opts.agent];
|
|
49921
50387
|
if (typeof mapped === "string") return resolve8(cwd, mapped);
|
|
49922
|
-
console.error(`Unknown --agent "${opts.agent}" (expected claude, codex, or hermes)`);
|
|
50388
|
+
console.error(`Unknown --agent "${opts.agent}" (expected claude, codex, cursor, or hermes)`);
|
|
49923
50389
|
return null;
|
|
49924
50390
|
}
|
|
49925
50391
|
const matches = detectTargets(cwd);
|
|
@@ -49931,9 +50397,13 @@ function resolveTarget(cwd, opts) {
|
|
|
49931
50397
|
}
|
|
49932
50398
|
function runInstall(cwd, opts) {
|
|
49933
50399
|
if (opts.agent === "claude" && !opts.target) return installClaudePlugin(cwd, opts);
|
|
50400
|
+
if (opts.agent === "cursor" && !opts.target) {
|
|
50401
|
+
if (!validCursorSkillScope(opts.scope)) return 1;
|
|
50402
|
+
return installCursorSkill(cwd, opts);
|
|
50403
|
+
}
|
|
49934
50404
|
const target = resolveTarget(cwd, opts);
|
|
49935
50405
|
if (target === null) return 1;
|
|
49936
|
-
const existing =
|
|
50406
|
+
const existing = existsSync22(target) ? readFileSync20(target, "utf-8") : "";
|
|
49937
50407
|
const eol = existing ? detectNewline(existing) : "\n";
|
|
49938
50408
|
const block = composeBlock(loadSkill(), eol);
|
|
49939
50409
|
const next = applyBlock(existing, block, eol);
|
|
@@ -49951,13 +50421,17 @@ function runInstall(cwd, opts) {
|
|
|
49951
50421
|
}
|
|
49952
50422
|
function runUninstall(cwd, opts) {
|
|
49953
50423
|
if (opts.agent === "claude" && !opts.target) return uninstallClaudePlugin(cwd, opts);
|
|
50424
|
+
if (opts.agent === "cursor" && !opts.target) {
|
|
50425
|
+
if (!validCursorSkillScope(opts.scope)) return 1;
|
|
50426
|
+
return uninstallCursorSkill(cwd, opts.scope);
|
|
50427
|
+
}
|
|
49954
50428
|
const target = resolveTarget(cwd, opts);
|
|
49955
50429
|
if (target === null) return 1;
|
|
49956
|
-
if (!
|
|
50430
|
+
if (!existsSync22(target)) {
|
|
49957
50431
|
console.log(`Skill block not present at ${target}`);
|
|
49958
50432
|
return 0;
|
|
49959
50433
|
}
|
|
49960
|
-
const existing =
|
|
50434
|
+
const existing = readFileSync20(target, "utf-8");
|
|
49961
50435
|
const next = removeBlock(existing);
|
|
49962
50436
|
if (next === null) {
|
|
49963
50437
|
console.log(`Skill block not present at ${target}`);
|
|
@@ -49969,12 +50443,22 @@ function runUninstall(cwd, opts) {
|
|
|
49969
50443
|
}
|
|
49970
50444
|
function runStatus(cwd, opts) {
|
|
49971
50445
|
if (opts.agent === "claude" && !opts.target) return statusClaudePlugin(cwd, opts);
|
|
50446
|
+
if (opts.agent === "cursor" && !opts.target) {
|
|
50447
|
+
if (!validCursorSkillScope(opts.scope)) return 1;
|
|
50448
|
+
const status = cursorSkillStatus(cwd, opts.scope);
|
|
50449
|
+
if (opts.json) printJson(status);
|
|
50450
|
+
else
|
|
50451
|
+
console.log(
|
|
50452
|
+
status.installed ? `Primitive Cursor skill installed at ${status.target}` : `No intact Primitive-owned Cursor skill at ${status.target}`
|
|
50453
|
+
);
|
|
50454
|
+
return status.installed ? 0 : 1;
|
|
50455
|
+
}
|
|
49972
50456
|
const target = resolveTarget(cwd, opts);
|
|
49973
50457
|
if (target === null) return 1;
|
|
49974
|
-
const fileExists =
|
|
50458
|
+
const fileExists = existsSync22(target);
|
|
49975
50459
|
let installed = false;
|
|
49976
50460
|
if (fileExists) {
|
|
49977
|
-
const content =
|
|
50461
|
+
const content = readFileSync20(target, "utf-8");
|
|
49978
50462
|
installed = content.includes(SKILL_BEGIN) && content.includes(SKILL_END);
|
|
49979
50463
|
}
|
|
49980
50464
|
if (opts.json) {
|
|
@@ -49994,7 +50478,7 @@ function runStatus(cwd, opts) {
|
|
|
49994
50478
|
}
|
|
49995
50479
|
function registerSkillCommands(program3) {
|
|
49996
50480
|
const skill = program3.command("skill").description("Manage the prim skill in your project rules file");
|
|
49997
|
-
skill.command("install").description("Install the prim skill block into your project rules file").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, or hermes
|
|
50481
|
+
skill.command("install").description("Install the prim skill block into your project rules file").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, cursor, or hermes").option("--scope <scope>", "project (default, this repo) or user (machine-global \u2014 every repo)").option("--dry-run", "Print a unified diff without writing").action((opts) => {
|
|
49998
50482
|
try {
|
|
49999
50483
|
process.exit(runInstall(process.cwd(), opts));
|
|
50000
50484
|
} catch (err) {
|
|
@@ -50002,16 +50486,16 @@ function registerSkillCommands(program3) {
|
|
|
50002
50486
|
process.exit(2);
|
|
50003
50487
|
}
|
|
50004
50488
|
});
|
|
50005
|
-
skill.command("uninstall").description("Remove the prim skill block from your project rules file").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, or hermes
|
|
50489
|
+
skill.command("uninstall").description("Remove the prim skill block from your project rules file").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, cursor, or hermes").option("--scope <scope>", "project (default, this repo) or user (machine-global \u2014 every repo)").action((opts) => {
|
|
50006
50490
|
process.exit(runUninstall(process.cwd(), opts));
|
|
50007
50491
|
});
|
|
50008
|
-
skill.command("status").description("Report whether the prim skill block is installed").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, or hermes
|
|
50492
|
+
skill.command("status").description("Report whether the prim skill block is installed").option("--target <path>", "Path to the rules file (overrides auto-detection)").option("--agent <agent>", "claude, codex, cursor, or hermes").option("--scope <scope>", "project (default, this repo) or user (machine-global \u2014 every repo)").option("--json", "Output as JSON").action((opts) => {
|
|
50009
50493
|
process.exit(runStatus(process.cwd(), opts));
|
|
50010
50494
|
});
|
|
50011
50495
|
}
|
|
50012
50496
|
|
|
50013
50497
|
// src/commands/statusline.ts
|
|
50014
|
-
import { readFileSync as
|
|
50498
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
50015
50499
|
import { dirname as dirname17, resolve as resolve9 } from "path";
|
|
50016
50500
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
50017
50501
|
var STATUSLINE_TIMEOUT_MS = 200;
|
|
@@ -50027,7 +50511,7 @@ function readPackageVersion() {
|
|
|
50027
50511
|
];
|
|
50028
50512
|
for (const path9 of candidates) {
|
|
50029
50513
|
try {
|
|
50030
|
-
const pkg2 = JSON.parse(
|
|
50514
|
+
const pkg2 = JSON.parse(readFileSync21(path9, "utf-8"));
|
|
50031
50515
|
if (pkg2.version) {
|
|
50032
50516
|
return pkg2.version;
|
|
50033
50517
|
}
|
|
@@ -50044,9 +50528,8 @@ function debug(msg) {
|
|
|
50044
50528
|
`);
|
|
50045
50529
|
}
|
|
50046
50530
|
}
|
|
50047
|
-
async function renderStatusline() {
|
|
50531
|
+
async function renderStatusline(cwd = process.cwd()) {
|
|
50048
50532
|
const version = readPackageVersion();
|
|
50049
|
-
const cwd = process.cwd();
|
|
50050
50533
|
let ingestion;
|
|
50051
50534
|
const resolveIngestion = () => {
|
|
50052
50535
|
ingestion ??= decisionIngestionStatus(cwd);
|
|
@@ -50094,6 +50577,11 @@ function planUninstallSteps(inRepository) {
|
|
|
50094
50577
|
label: "Codex project integration",
|
|
50095
50578
|
args: ["codex", "uninstall", "--scope", "project"]
|
|
50096
50579
|
},
|
|
50580
|
+
{
|
|
50581
|
+
key: "cursor-project",
|
|
50582
|
+
label: "Cursor project integration",
|
|
50583
|
+
args: ["cursor", "uninstall", "--scope", "project"]
|
|
50584
|
+
},
|
|
50097
50585
|
{
|
|
50098
50586
|
key: "hooks-project",
|
|
50099
50587
|
label: "project Git hooks",
|
|
@@ -50113,6 +50601,11 @@ function planUninstallSteps(inRepository) {
|
|
|
50113
50601
|
label: "Codex user integration",
|
|
50114
50602
|
args: ["codex", "uninstall", "--scope", "user"]
|
|
50115
50603
|
},
|
|
50604
|
+
{
|
|
50605
|
+
key: "cursor-user",
|
|
50606
|
+
label: "Cursor user integration",
|
|
50607
|
+
args: ["cursor", "uninstall", "--scope", "user"]
|
|
50608
|
+
},
|
|
50116
50609
|
{ key: "hermes-user", label: "Hermes integration", args: ["hermes", "uninstall"] },
|
|
50117
50610
|
{
|
|
50118
50611
|
key: "hooks-user",
|
|
@@ -50131,7 +50624,7 @@ function uninstallStepSucceeded(step, result) {
|
|
|
50131
50624
|
return false;
|
|
50132
50625
|
}
|
|
50133
50626
|
}
|
|
50134
|
-
if (!step.key.startsWith("claude-") && !step.key.startsWith("codex-") && step.key !== "hermes-user") {
|
|
50627
|
+
if (!step.key.startsWith("claude-") && !step.key.startsWith("codex-") && !step.key.startsWith("cursor-") && step.key !== "hermes-user") {
|
|
50135
50628
|
return true;
|
|
50136
50629
|
}
|
|
50137
50630
|
try {
|
|
@@ -50139,7 +50632,7 @@ function uninstallStepSucceeded(step, result) {
|
|
|
50139
50632
|
if (step.key.startsWith("claude-")) {
|
|
50140
50633
|
return parsed.gate === false && parsed.capture === false && parsed.feedback === false && parsed.statusline === false;
|
|
50141
50634
|
}
|
|
50142
|
-
return parsed.gate === false && parsed.capture === false;
|
|
50635
|
+
return parsed.gate === false && parsed.capture === false && (!step.key.startsWith("cursor-user") || parsed.footer === false);
|
|
50143
50636
|
} catch {
|
|
50144
50637
|
return false;
|
|
50145
50638
|
}
|
|
@@ -50254,9 +50747,9 @@ function registerUninstallCommand(program3, dependencies = {}) {
|
|
|
50254
50747
|
note(`uninstall \xB7 runtime removal incomplete (unknown state): ${detail}`);
|
|
50255
50748
|
}
|
|
50256
50749
|
}
|
|
50257
|
-
const
|
|
50750
|
+
const complete2 = failed.length === 0;
|
|
50258
50751
|
const result = {
|
|
50259
|
-
uninstalled:
|
|
50752
|
+
uninstalled: complete2,
|
|
50260
50753
|
projectScopeChecked: inRepository,
|
|
50261
50754
|
steps: results,
|
|
50262
50755
|
runtime,
|
|
@@ -50270,16 +50763,16 @@ function registerUninstallCommand(program3, dependencies = {}) {
|
|
|
50270
50763
|
write(`${JSON.stringify(result, null, 2)}
|
|
50271
50764
|
`);
|
|
50272
50765
|
note(
|
|
50273
|
-
|
|
50766
|
+
complete2 ? "uninstall complete \xB7 credentials and pending journals preserved" : `uninstall incomplete \xB7 failed: ${failed.join(", ")}`
|
|
50274
50767
|
);
|
|
50275
|
-
exit(
|
|
50768
|
+
exit(complete2 ? 0 : EXIT_INCOMPLETE2);
|
|
50276
50769
|
});
|
|
50277
50770
|
}
|
|
50278
50771
|
|
|
50279
50772
|
// src/commands/welcome.ts
|
|
50280
50773
|
var CMD_GUTTER = 38;
|
|
50281
50774
|
var RECENT_LIMIT = 5;
|
|
50282
|
-
var WELCOME_AGENTS = ["claude", "codex", "hermes"];
|
|
50775
|
+
var WELCOME_AGENTS = ["claude", "codex", "cursor", "hermes"];
|
|
50283
50776
|
function resolveWelcomeAgent(agentFlag, env4) {
|
|
50284
50777
|
if (agentFlag !== void 0 && WELCOME_AGENTS.includes(agentFlag)) {
|
|
50285
50778
|
return agentFlag;
|
|
@@ -50287,6 +50780,9 @@ function resolveWelcomeAgent(agentFlag, env4) {
|
|
|
50287
50780
|
if (agentFlag === void 0 && env4.HERMES_INTERACTIVE) {
|
|
50288
50781
|
return "hermes";
|
|
50289
50782
|
}
|
|
50783
|
+
if (agentFlag === void 0 && env4.CURSOR_AGENT) {
|
|
50784
|
+
return "cursor";
|
|
50785
|
+
}
|
|
50290
50786
|
return void 0;
|
|
50291
50787
|
}
|
|
50292
50788
|
var CAPTURE_LINES = {
|
|
@@ -50295,6 +50791,7 @@ var CAPTURE_LINES = {
|
|
|
50295
50791
|
"Capture starts once you trust the prim hooks \u2014 run /hooks in Codex;",
|
|
50296
50792
|
"until then nothing is recorded."
|
|
50297
50793
|
],
|
|
50794
|
+
cursor: ["Capture is automatic in trusted Cursor workspaces; restart Cursor CLI for the footer."],
|
|
50298
50795
|
hermes: [
|
|
50299
50796
|
"Capture starts once you approve the prim hooks when Hermes prompts;",
|
|
50300
50797
|
"until then nothing is recorded."
|
|
@@ -50310,6 +50807,7 @@ var PASSIVE_LINES = {
|
|
|
50310
50807
|
"Once you trust the prim hooks (/hooks in Codex), Primitive captures",
|
|
50311
50808
|
"decisions passively while you work."
|
|
50312
50809
|
],
|
|
50810
|
+
cursor: ["In trusted Cursor workspaces, Primitive captures decisions passively while you work."],
|
|
50313
50811
|
hermes: [
|
|
50314
50812
|
"Once you approve the prim hooks, Primitive captures decisions",
|
|
50315
50813
|
"passively while you work."
|
|
@@ -50322,6 +50820,7 @@ var PASSIVE_LINES = {
|
|
|
50322
50820
|
var GUIDANCE_PASSIVE = {
|
|
50323
50821
|
claude: "Otherwise, Primitive passively captures decisions in the background while you work.",
|
|
50324
50822
|
codex: "Otherwise, once you trust the prim hooks (run /hooks in Codex), Primitive passively captures decisions in the background while you work.",
|
|
50823
|
+
cursor: "Otherwise, Primitive passively captures decisions in trusted Cursor workspaces while you work.",
|
|
50325
50824
|
hermes: "Otherwise, once you approve the prim hooks when Hermes prompts, Primitive passively captures decisions in the background while you work.",
|
|
50326
50825
|
generic: "Otherwise, once your agent's prim hooks are active, Primitive passively captures decisions in the background while you work."
|
|
50327
50826
|
};
|
|
@@ -50416,10 +50915,7 @@ function welcomeJson(state, agent) {
|
|
|
50416
50915
|
return { welcomed: true, org: "unknown" };
|
|
50417
50916
|
}
|
|
50418
50917
|
function registerWelcomeCommand(program3, deps = { getClient }) {
|
|
50419
|
-
program3.command("welcome").description("Print a brief orientation to Primitive's decision graph").option(
|
|
50420
|
-
"--agent <agent>",
|
|
50421
|
-
"claude, codex, or hermes \u2014 tailors the capture guidance (Hermes auto-detected)"
|
|
50422
|
-
).action(async (options) => {
|
|
50918
|
+
program3.command("welcome").description("Print a brief orientation to Primitive's decision graph").option("--agent <agent>", "claude, codex, cursor, or hermes \u2014 tailors the capture guidance").action(async (options) => {
|
|
50423
50919
|
const agent = resolveWelcomeAgent(options.agent, process.env);
|
|
50424
50920
|
const result = await fetchRecent({ limit: RECENT_LIMIT }, deps);
|
|
50425
50921
|
const state = welcomeStateFromRecent(result);
|
|
@@ -50447,7 +50943,7 @@ function runStartupBackgroundWork(argv, env4, work) {
|
|
|
50447
50943
|
|
|
50448
50944
|
// src/index.ts
|
|
50449
50945
|
var __dirname6 = dirname18(fileURLToPath7(import.meta.url));
|
|
50450
|
-
var pkg = JSON.parse(
|
|
50946
|
+
var pkg = JSON.parse(readFileSync22(resolve10(__dirname6, "../package.json"), "utf-8"));
|
|
50451
50947
|
runStartupBackgroundWork(process.argv.slice(2), process.env, {
|
|
50452
50948
|
notify: () => updateNotifier({ pkg }).notify(),
|
|
50453
50949
|
flush: () => flushIfNeeded()
|
|
@@ -50466,6 +50962,7 @@ registerSessionCommands(program2);
|
|
|
50466
50962
|
registerDecisionsCommands(program2);
|
|
50467
50963
|
registerClaudeCommands(program2);
|
|
50468
50964
|
registerCodexCommands(program2);
|
|
50965
|
+
registerCursorCommands(program2);
|
|
50469
50966
|
registerHermesCommands(program2);
|
|
50470
50967
|
registerDaemonCommands(program2);
|
|
50471
50968
|
registerGithubCommands(program2);
|