grepmax 0.26.53 → 0.26.55
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/.claude-plugin/marketplace.json +1 -1
- package/README.md +9 -7
- package/dist/commands/add.js +2 -0
- package/dist/commands/doctor.js +9 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/remove.js +2 -0
- package/dist/commands/repair.js +2 -0
- package/dist/commands/watch.js +12 -0
- package/dist/lib/daemon/daemon.js +90 -34
- package/dist/lib/output/mcp-results.js +3 -0
- package/dist/lib/store/maintenance-policy.js +172 -0
- package/dist/lib/store/meta-cache.js +34 -1
- package/dist/lib/store/vector-db.js +166 -33
- package/dist/lib/utils/autostart.js +34 -7
- package/dist/lib/utils/daemon-launcher.js +6 -0
- package/dist/lib/utils/doctor-optimize.js +6 -0
- package/dist/lib/utils/kernel-zone.js +10 -5
- package/dist/lib/utils/safety-latch.js +121 -0
- package/package.json +1 -1
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
- package/plugins/grepmax/hooks/watch-lease.js +13 -5
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SAFETY_LATCH_NAME = void 0;
|
|
37
|
+
exports.safetyStopReason = safetyStopReason;
|
|
38
|
+
exports.latchSafetyStop = latchSafetyStop;
|
|
39
|
+
exports.assertNoSafetyStop = assertNoSafetyStop;
|
|
40
|
+
const node_crypto_1 = require("node:crypto");
|
|
41
|
+
const fs = __importStar(require("node:fs"));
|
|
42
|
+
const path = __importStar(require("node:path"));
|
|
43
|
+
const config_1 = require("../../config");
|
|
44
|
+
/** Machine-wide stop: changing stores or installing a version cannot clear it. */
|
|
45
|
+
exports.SAFETY_LATCH_NAME = "safety-stop.json";
|
|
46
|
+
function safetyRoot() {
|
|
47
|
+
var _a;
|
|
48
|
+
return (_a = config_1.PATHS.sharedRoot) !== null && _a !== void 0 ? _a : path.dirname(config_1.PATHS.autostartDisabledFile);
|
|
49
|
+
}
|
|
50
|
+
/** Absence is distinct from an unreadable/corrupt stop, which stays stopped. */
|
|
51
|
+
function safetyStopReason(root = safetyRoot()) {
|
|
52
|
+
const file = path.join(root, exports.SAFETY_LATCH_NAME);
|
|
53
|
+
try {
|
|
54
|
+
const stat = fs.lstatSync(file);
|
|
55
|
+
if (!stat.isFile() || stat.size > 8192)
|
|
56
|
+
return "unverified safety stop";
|
|
57
|
+
const value = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
58
|
+
if (value.schemaVersion !== 1 ||
|
|
59
|
+
!Number.isFinite(value.at) ||
|
|
60
|
+
typeof value.reason !== "string" ||
|
|
61
|
+
!value.reason.trim())
|
|
62
|
+
return "unverified safety stop";
|
|
63
|
+
return value.reason.replace(/[\r\n\t]/g, " ").slice(0, 512);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return error.code === "ENOENT"
|
|
67
|
+
? null
|
|
68
|
+
: "unreadable safety stop";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Atomic durable latch; intentionally no automatic expiry or clear operation. */
|
|
72
|
+
function latchSafetyStop(reason, root = safetyRoot()) {
|
|
73
|
+
if (safetyStopReason(root) !== null)
|
|
74
|
+
return;
|
|
75
|
+
fs.mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
76
|
+
fs.chmodSync(root, 0o700);
|
|
77
|
+
const file = path.join(root, exports.SAFETY_LATCH_NAME);
|
|
78
|
+
const temporary = path.join(root, `.safety-stop-${(0, node_crypto_1.randomUUID)()}.tmp`);
|
|
79
|
+
let fd;
|
|
80
|
+
try {
|
|
81
|
+
fd = fs.openSync(temporary, "wx", 0o600);
|
|
82
|
+
const record = {
|
|
83
|
+
schemaVersion: 1,
|
|
84
|
+
at: Date.now(),
|
|
85
|
+
reason: reason.replace(/[\r\n\t]/g, " ").slice(0, 512) || "host safety stop",
|
|
86
|
+
};
|
|
87
|
+
fs.writeFileSync(fd, `${JSON.stringify(record)}\n`);
|
|
88
|
+
fs.fsyncSync(fd);
|
|
89
|
+
fs.closeSync(fd);
|
|
90
|
+
fd = undefined;
|
|
91
|
+
// Publish without replacing another concurrent stop's original cause.
|
|
92
|
+
try {
|
|
93
|
+
fs.linkSync(temporary, file);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (error.code !== "EEXIST")
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
// Persist the directory entry, not only the payload, before stopping.
|
|
100
|
+
const dir = fs.openSync(root, "r");
|
|
101
|
+
try {
|
|
102
|
+
fs.fsyncSync(dir);
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
fs.closeSync(dir);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
if (fd !== undefined)
|
|
110
|
+
fs.closeSync(fd);
|
|
111
|
+
try {
|
|
112
|
+
fs.unlinkSync(temporary);
|
|
113
|
+
}
|
|
114
|
+
catch (_a) { }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function assertNoSafetyStop() {
|
|
118
|
+
const reason = safetyStopReason();
|
|
119
|
+
if (reason !== null)
|
|
120
|
+
throw new Error(`gmax safety stop: ${reason}; containment must be reviewed before resuming`);
|
|
121
|
+
}
|
package/package.json
CHANGED
|
@@ -15,15 +15,23 @@ const SOCKET = path.join(GMAX_DIR, "daemon.sock");
|
|
|
15
15
|
// Activity refreshes this TTL; idle sessions do not watch forever.
|
|
16
16
|
const SESSION_LEASE_TTL_MS = 4 * 60 * 60 * 1000;
|
|
17
17
|
|
|
18
|
-
function
|
|
19
|
-
if (process.env.GMAX_NO_AUTOSTART === "1") return true;
|
|
18
|
+
function markerPresentOrUnknown(file) {
|
|
20
19
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
fs.lstatSync(file);
|
|
21
|
+
return true;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
return error.code !== "ENOENT";
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function isAutostartDisabled() {
|
|
28
|
+
if (process.env.GMAX_NO_AUTOSTART === "1") return true;
|
|
29
|
+
return (
|
|
30
|
+
markerPresentOrUnknown(path.join(GMAX_DIR, "autostart-disabled")) ||
|
|
31
|
+
markerPresentOrUnknown(path.join(GMAX_DIR, "safety-stop.json"))
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
function readHookInput(timeoutMs = 1000) {
|
|
28
36
|
return new Promise((resolve) => {
|
|
29
37
|
let data = "";
|