tim-hooks 0.1.0-beta.0
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 +31 -0
- package/dist/cadence-runner.d.ts +11 -0
- package/dist/cadence-runner.d.ts.map +1 -0
- package/dist/cadence-runner.js +30 -0
- package/dist/cadence-runner.js.map +1 -0
- package/dist/cadence.d.ts +10 -0
- package/dist/cadence.d.ts.map +1 -0
- package/dist/cadence.js +36 -0
- package/dist/cadence.js.map +1 -0
- package/dist/checkpoint.d.ts +56 -0
- package/dist/checkpoint.d.ts.map +1 -0
- package/dist/checkpoint.js +232 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/claude-stop.d.ts +32 -0
- package/dist/claude-stop.d.ts.map +1 -0
- package/dist/claude-stop.js +213 -0
- package/dist/claude-stop.js.map +1 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/delta.d.ts +7 -0
- package/dist/delta.d.ts.map +1 -0
- package/dist/delta.js +53 -0
- package/dist/delta.js.map +1 -0
- package/dist/hooks.d.ts +39 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +136 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/dist/marker.d.ts +179 -0
- package/dist/marker.d.ts.map +1 -0
- package/dist/marker.js +590 -0
- package/dist/marker.js.map +1 -0
- package/dist/phantom-recovery.d.ts +13 -0
- package/dist/phantom-recovery.d.ts.map +1 -0
- package/dist/phantom-recovery.js +113 -0
- package/dist/phantom-recovery.js.map +1 -0
- package/dist/project-creation.d.ts +48 -0
- package/dist/project-creation.d.ts.map +1 -0
- package/dist/project-creation.js +265 -0
- package/dist/project-creation.js.map +1 -0
- package/dist/prompt-submit.d.ts +16 -0
- package/dist/prompt-submit.d.ts.map +1 -0
- package/dist/prompt-submit.js +69 -0
- package/dist/prompt-submit.js.map +1 -0
- package/dist/rebalance.d.ts +17 -0
- package/dist/rebalance.d.ts.map +1 -0
- package/dist/rebalance.js +91 -0
- package/dist/rebalance.js.map +1 -0
- package/dist/session-hooks.d.ts +53 -0
- package/dist/session-hooks.d.ts.map +1 -0
- package/dist/session-hooks.js +167 -0
- package/dist/session-hooks.js.map +1 -0
- package/dist/update-check.d.ts +5 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +66 -0
- package/dist/update-check.js.map +1 -0
- package/package.json +24 -0
- package/scripts/README-hermes-statusline.md +47 -0
- package/scripts/hermes-cli-tim-statusline.patch +75 -0
- package/scripts/lib/resolve-tim-cli.sh +30 -0
- package/scripts/post-commit.sh +30 -0
- package/scripts/tim-claude-session-start.sh +26 -0
- package/scripts/tim-cursor-inject.sh +17 -0
- package/scripts/tim-hermes-session-cache.sh +32 -0
- package/scripts/tim-hermes-statusline.sh +28 -0
- package/scripts/tim-post-commit.sh +14 -0
- package/scripts/tim-session-start.sh +104 -0
- package/scripts/tim-statusline.sh +16 -0
package/dist/marker.js
ADDED
|
@@ -0,0 +1,590 @@
|
|
|
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.CWD_ONLY_MARKER_DISCOVERY_POLICY = exports.DEFAULT_MARKER_DISCOVERY_POLICY = exports.LOCK_TTL_MS = exports.ExclusiveMarkerConflictError = exports.INBOX_LABEL = exports.MARKER_VERSION = exports.CANONICAL_PROJECT_FILENAME = exports.MARKER_LOCK = exports.MARKER_FILENAME = void 0;
|
|
37
|
+
exports.markerPath = markerPath;
|
|
38
|
+
exports.canonicalProjectPath = canonicalProjectPath;
|
|
39
|
+
exports.validateProjectLabel = validateProjectLabel;
|
|
40
|
+
exports.readMarker = readMarker;
|
|
41
|
+
exports.validateMarkerAgainstStore = validateMarkerAgainstStore;
|
|
42
|
+
exports.isUnsafeMarkerDir = isUnsafeMarkerDir;
|
|
43
|
+
exports.writeMarkerAtomic = writeMarkerAtomic;
|
|
44
|
+
exports.writeMarkerExclusive = writeMarkerExclusive;
|
|
45
|
+
exports.writeMarker = writeMarker;
|
|
46
|
+
exports.rotateMarkerSession = rotateMarkerSession;
|
|
47
|
+
exports.syncNearestProjectMarker = syncNearestProjectMarker;
|
|
48
|
+
exports.detectProject = detectProject;
|
|
49
|
+
exports.reconcileMarker = reconcileMarker;
|
|
50
|
+
exports.acquireLock = acquireLock;
|
|
51
|
+
exports.isSessionLocked = isSessionLocked;
|
|
52
|
+
exports.releaseLock = releaseLock;
|
|
53
|
+
exports.findMarkerOptionsFromEnv = findMarkerOptionsFromEnv;
|
|
54
|
+
exports.discoverMarker = discoverMarker;
|
|
55
|
+
exports.findMarker = findMarker;
|
|
56
|
+
exports.buildLoadDirective = buildLoadDirective;
|
|
57
|
+
exports.buildSessionDirective = buildSessionDirective;
|
|
58
|
+
const fs = __importStar(require("fs"));
|
|
59
|
+
const os = __importStar(require("os"));
|
|
60
|
+
const path = __importStar(require("path"));
|
|
61
|
+
const crypto = __importStar(require("node:crypto"));
|
|
62
|
+
const constants_js_1 = require("./constants.js");
|
|
63
|
+
const tim_store_1 = require("tim-store");
|
|
64
|
+
exports.MARKER_FILENAME = '.tim-project';
|
|
65
|
+
exports.MARKER_LOCK = '.tim-project.lock';
|
|
66
|
+
/**
|
|
67
|
+
* Committed default project label for repos that gitignore `.tim-project`.
|
|
68
|
+
* Contains only the stable `project` field; runtime counters live in the
|
|
69
|
+
* local `.tim-project` file created on session start. Override per-machine
|
|
70
|
+
* by creating `.tim-project` in the repo root (it wins over tim.json).
|
|
71
|
+
*/
|
|
72
|
+
exports.CANONICAL_PROJECT_FILENAME = 'tim.json';
|
|
73
|
+
/**
|
|
74
|
+
* Current marker schema version. Bump this when the on-disk shape changes;
|
|
75
|
+
* readers detect older files by the missing/unknown `version` field and
|
|
76
|
+
* normalize to the current shape.
|
|
77
|
+
*/
|
|
78
|
+
exports.MARKER_VERSION = 2;
|
|
79
|
+
function markerPath(cwd) {
|
|
80
|
+
return path.join(cwd, exports.MARKER_FILENAME);
|
|
81
|
+
}
|
|
82
|
+
function canonicalProjectPath(cwd) {
|
|
83
|
+
return path.join(cwd, exports.CANONICAL_PROJECT_FILENAME);
|
|
84
|
+
}
|
|
85
|
+
/** Valid project labels: P/L/E/N + 4 digits (P0062, L0042, …). */
|
|
86
|
+
const PROJECT_LABEL_PATTERN = /^[PLEN]\d{4}$/;
|
|
87
|
+
/**
|
|
88
|
+
* Shape-valid label that must never be written to `.tim-project`.
|
|
89
|
+
* Used as a vitest fixture / corruption sentinel (see P9999 bug); DB
|
|
90
|
+
* validation also rejects it when the project does not exist.
|
|
91
|
+
*/
|
|
92
|
+
const DENIED_MARKER_LABELS = new Set(['P9999']);
|
|
93
|
+
function validateProjectLabel(label) {
|
|
94
|
+
if (DENIED_MARKER_LABELS.has(label))
|
|
95
|
+
return false;
|
|
96
|
+
return PROJECT_LABEL_PATTERN.test(label);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Sentinel label for the Inbox project (P0000). Always treated as
|
|
100
|
+
* valid even when not present in the DB — the Inbox is a system
|
|
101
|
+
* project that tim-store.ensureInboxProject() materializes lazily.
|
|
102
|
+
*/
|
|
103
|
+
exports.INBOX_LABEL = 'P0000';
|
|
104
|
+
/**
|
|
105
|
+
* Read a marker and normalize it to the current schema version.
|
|
106
|
+
*
|
|
107
|
+
* - Missing file → null
|
|
108
|
+
* - Corrupt JSON → null
|
|
109
|
+
* - v1 file (no `version` field) → strips `route_exchanges_to` + `sessions`
|
|
110
|
+
* map, sets `version: 2`, returns the upgraded object. The file itself
|
|
111
|
+
* is NOT rewritten here — the next `writeMarker` call upgrades it.
|
|
112
|
+
* - v2 file → returned as-is.
|
|
113
|
+
*
|
|
114
|
+
* Callers always see a v2-conformant `ProjectMarker` regardless of what's
|
|
115
|
+
* on disk. This is the only safe way to evolve the schema without forcing
|
|
116
|
+
* a one-shot migration.
|
|
117
|
+
*
|
|
118
|
+
* When no `.tim-project` exists, falls back to `tim.json` (committed
|
|
119
|
+
* canonical default). A real `.tim-project` always wins — even when
|
|
120
|
+
* corrupt (returns null rather than silently using tim.json).
|
|
121
|
+
*/
|
|
122
|
+
function readMarker(cwd) {
|
|
123
|
+
const p = markerPath(cwd);
|
|
124
|
+
if (fs.existsSync(p)) {
|
|
125
|
+
let raw;
|
|
126
|
+
try {
|
|
127
|
+
raw = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return normalizeMarker(raw);
|
|
133
|
+
}
|
|
134
|
+
return readCanonicalProject(cwd);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Read the committed default project from tim.json. Runtime fields use
|
|
138
|
+
* neutral defaults — session start overwrites them into `.tim-project`.
|
|
139
|
+
*/
|
|
140
|
+
function readCanonicalProject(cwd) {
|
|
141
|
+
const p = canonicalProjectPath(cwd);
|
|
142
|
+
if (!fs.existsSync(p))
|
|
143
|
+
return null;
|
|
144
|
+
let raw;
|
|
145
|
+
try {
|
|
146
|
+
raw = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
if (!raw || typeof raw !== 'object')
|
|
152
|
+
return null;
|
|
153
|
+
const obj = raw;
|
|
154
|
+
if (typeof obj.project !== 'string' || !PROJECT_LABEL_PATTERN.test(obj.project)) {
|
|
155
|
+
console.warn(`[tim-hooks] ${exports.CANONICAL_PROJECT_FILENAME} has malformed project label ` +
|
|
156
|
+
`"${String(obj.project)}" — expected ^[PLEN]\\d{4}$. Ignoring.`);
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
version: exports.MARKER_VERSION,
|
|
161
|
+
project: obj.project,
|
|
162
|
+
session: '',
|
|
163
|
+
exchanges: 0,
|
|
164
|
+
batch_size: 5,
|
|
165
|
+
batches_summarized: 0,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Coerce an unknown JSON value into a v2 ProjectMarker. Strips legacy
|
|
170
|
+
* fields. Returns null if the value isn't a usable marker (missing
|
|
171
|
+
* project/session, wrong types, or malformed project label).
|
|
172
|
+
*
|
|
173
|
+
* NOTE: This is the pure-FS reader. The DB-existence check
|
|
174
|
+
* (project label must resolve to a real entry in the TIM DB) lives
|
|
175
|
+
* in `validateMarkerAgainstStore` — called from the two write-side
|
|
176
|
+
* paths (runSessionStart, syncNearestProjectMarker) before they
|
|
177
|
+
* persist anything. We deliberately keep the disk reader free of
|
|
178
|
+
* DB dependencies so hooks under a tight timeout can still parse
|
|
179
|
+
* the marker without paying for an SQLite roundtrip.
|
|
180
|
+
*/
|
|
181
|
+
function normalizeMarker(raw) {
|
|
182
|
+
if (!raw || typeof raw !== 'object')
|
|
183
|
+
return null;
|
|
184
|
+
const obj = raw;
|
|
185
|
+
if (typeof obj.project !== 'string' || obj.project.length === 0)
|
|
186
|
+
return null;
|
|
187
|
+
if (!PROJECT_LABEL_PATTERN.test(obj.project)) {
|
|
188
|
+
console.warn(`[tim-hooks] .tim-project has malformed project label "${obj.project}" — ` +
|
|
189
|
+
`expected ^[PLEN]\\d{4}$ (P0062, L0042, …). Ignoring marker.`);
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
if (typeof obj.session !== 'string')
|
|
193
|
+
return null;
|
|
194
|
+
if (typeof obj.exchanges !== 'number' || !Number.isFinite(obj.exchanges))
|
|
195
|
+
return null;
|
|
196
|
+
if (typeof obj.batch_size !== 'number' || !Number.isFinite(obj.batch_size))
|
|
197
|
+
return null;
|
|
198
|
+
if (typeof obj.batches_summarized !== 'number' || !Number.isFinite(obj.batches_summarized)) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
version: exports.MARKER_VERSION,
|
|
203
|
+
project: obj.project,
|
|
204
|
+
session: obj.session,
|
|
205
|
+
exchanges: obj.exchanges,
|
|
206
|
+
batch_size: obj.batch_size,
|
|
207
|
+
batches_summarized: obj.batches_summarized,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Defense-in-depth check: a project label that matches the
|
|
212
|
+
* pattern but is semantically bogus (e.g. `P9999` — a label that
|
|
213
|
+
* was never issued by TIM, often the residue of a hand-edit or a
|
|
214
|
+
* botched commit) must NOT be persisted into `.tim-project`. The
|
|
215
|
+
* original P9999 bug bound the statusline to a non-existent
|
|
216
|
+
* project because the file was trusted blindly.
|
|
217
|
+
*
|
|
218
|
+
* Resolution: pattern-match (already enforced by normalizeMarker)
|
|
219
|
+
* AND the project must exist as a `kind=project` entry in the DB.
|
|
220
|
+
* The Inbox (P0000) is exempt — it's a system project that
|
|
221
|
+
* tim-store creates on first use via `ensureInboxProject`.
|
|
222
|
+
*
|
|
223
|
+
* Returns the marker on success, null on rejection. On DB error
|
|
224
|
+
* (store unavailable, DB locked, etc.) we FAIL OPEN: a corrupted
|
|
225
|
+
* DB is not a license to corrupt the marker, but a transient
|
|
226
|
+
* read failure shouldn't brick the session-start hook. The
|
|
227
|
+
* pattern check in normalizeMarker still ran, so we never accept
|
|
228
|
+
* malformed labels — we just skip the existence confirmation.
|
|
229
|
+
*/
|
|
230
|
+
async function validateMarkerAgainstStore(marker, store) {
|
|
231
|
+
if (marker.project === exports.INBOX_LABEL)
|
|
232
|
+
return marker;
|
|
233
|
+
let resolved;
|
|
234
|
+
try {
|
|
235
|
+
resolved = await store.resolveProjectLabel(marker.project);
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
console.warn(`[tim-hooks] .tim-project validation: DB lookup for "${marker.project}" ` +
|
|
239
|
+
`failed (${err.message ?? err}) — accepting on pattern match only.`);
|
|
240
|
+
return marker;
|
|
241
|
+
}
|
|
242
|
+
if (resolved.status === 'found') {
|
|
243
|
+
return { ...marker, project: resolved.label };
|
|
244
|
+
}
|
|
245
|
+
console.warn(`[tim-hooks] .tim-project has pattern-valid project label "${marker.project}" ` +
|
|
246
|
+
`but no matching entry exists in the DB. Treating as corrupt.`);
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Shared/system directories where a `.tim-project` must never live: every
|
|
251
|
+
* process can have them as cwd, so a marker there leaks into unrelated
|
|
252
|
+
* sessions via walk-up (observed: a cron with cwd=/tmp wrote /tmp/.tim-project
|
|
253
|
+
* and every process under /tmp inherited it). v1 unsafe set — deliberately
|
|
254
|
+
* minimal and explicit: os.tmpdir() itself and the filesystem root.
|
|
255
|
+
* Subdirectories of tmpdir (mkdtemp scratch dirs) are private and stay legal.
|
|
256
|
+
*/
|
|
257
|
+
function isUnsafeMarkerDir(dir) {
|
|
258
|
+
let resolved = path.resolve(dir);
|
|
259
|
+
try {
|
|
260
|
+
resolved = fs.realpathSync(resolved);
|
|
261
|
+
}
|
|
262
|
+
catch { /* nonexistent — compare as-is */ }
|
|
263
|
+
let tmp = path.resolve(os.tmpdir());
|
|
264
|
+
try {
|
|
265
|
+
tmp = fs.realpathSync(tmp);
|
|
266
|
+
}
|
|
267
|
+
catch { /* keep resolved */ }
|
|
268
|
+
return resolved === tmp || resolved === path.parse(resolved).root;
|
|
269
|
+
}
|
|
270
|
+
/** Atomically write JSON to `filePath` (tmp + rename — no torn reads on POSIX). */
|
|
271
|
+
function writeMarkerAtomic(filePath, content) {
|
|
272
|
+
const tmp = `${filePath}.tmp.${process.pid}`;
|
|
273
|
+
fs.writeFileSync(tmp, content);
|
|
274
|
+
fs.renameSync(tmp, filePath);
|
|
275
|
+
}
|
|
276
|
+
class ExclusiveMarkerConflictError extends Error {
|
|
277
|
+
filePath;
|
|
278
|
+
constructor(filePath) {
|
|
279
|
+
super(`Local marker already exists: ${filePath}`);
|
|
280
|
+
this.filePath = filePath;
|
|
281
|
+
this.name = 'ExclusiveMarkerConflictError';
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
exports.ExclusiveMarkerConflictError = ExclusiveMarkerConflictError;
|
|
285
|
+
/** Publish a marker only when no local marker exists already. */
|
|
286
|
+
function writeMarkerExclusive(cwd, marker) {
|
|
287
|
+
if (!validateProjectLabel(marker.project)) {
|
|
288
|
+
throw new Error(`[tim-hooks] writeMarkerExclusive: refusing to write invalid project label "${marker.project}" — ` +
|
|
289
|
+
`expected ^[PLEN]\\d{4}$ (P0062, L0042, …). Marker not written.`);
|
|
290
|
+
}
|
|
291
|
+
const filePath = markerPath(cwd);
|
|
292
|
+
const tmp = `${filePath}.tmp.${process.pid}.${crypto.randomUUID()}`;
|
|
293
|
+
const complete = { ...marker, version: exports.MARKER_VERSION };
|
|
294
|
+
let ownsTemp = false;
|
|
295
|
+
try {
|
|
296
|
+
fs.writeFileSync(tmp, JSON.stringify(complete, null, 2), { flag: 'wx' });
|
|
297
|
+
ownsTemp = true;
|
|
298
|
+
try {
|
|
299
|
+
fs.linkSync(tmp, filePath);
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
if (err.code === 'EEXIST') {
|
|
303
|
+
throw new ExclusiveMarkerConflictError(filePath);
|
|
304
|
+
}
|
|
305
|
+
throw err;
|
|
306
|
+
}
|
|
307
|
+
return complete;
|
|
308
|
+
}
|
|
309
|
+
finally {
|
|
310
|
+
if (ownsTemp) {
|
|
311
|
+
try {
|
|
312
|
+
fs.rmSync(tmp, { force: true });
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
// Publication success or failure is authoritative; cleanup is best-effort.
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/** Write a project marker file. Always emits the current schema version:
|
|
321
|
+
* the on-disk file becomes v2 on first write, regardless of the caller's
|
|
322
|
+
* input. This is the auto-upgrade path for v1 files. */
|
|
323
|
+
function writeMarker(cwd, marker) {
|
|
324
|
+
if (isUnsafeMarkerDir(cwd)) {
|
|
325
|
+
console.warn(`[tim-hooks] writeMarker: refusing to write ${exports.MARKER_FILENAME} in shared directory ` +
|
|
326
|
+
`"${cwd}" (tmpdir / filesystem root). Marker not written — running markerless.`);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (!validateProjectLabel(marker.project)) {
|
|
330
|
+
console.warn(`[tim-hooks] writeMarker: refusing to write invalid project label "${marker.project}" — ` +
|
|
331
|
+
`expected ^[PLEN]\\d{4}$ (P0062, L0042, …). Marker not written.`);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const p = markerPath(cwd);
|
|
335
|
+
const upgraded = { ...marker, version: exports.MARKER_VERSION };
|
|
336
|
+
writeMarkerAtomic(p, JSON.stringify(upgraded, null, 2));
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Rotate the session id in cwd's `.tim-project` when the harness supplies a new one.
|
|
340
|
+
* Used by tim-session-start.sh — must not interpolate paths into JS source.
|
|
341
|
+
*/
|
|
342
|
+
function rotateMarkerSession(cwd, sessionId) {
|
|
343
|
+
if (isUnsafeMarkerDir(cwd)) {
|
|
344
|
+
console.warn(`[tim-hooks] rotateMarkerSession: refusing to touch ${exports.MARKER_FILENAME} in shared ` +
|
|
345
|
+
`directory "${cwd}" (tmpdir / filesystem root). Running markerless.`);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const p = markerPath(cwd);
|
|
349
|
+
if (!fs.existsSync(p))
|
|
350
|
+
return;
|
|
351
|
+
try {
|
|
352
|
+
const raw = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
353
|
+
if (raw.session === sessionId)
|
|
354
|
+
return;
|
|
355
|
+
raw.session = sessionId;
|
|
356
|
+
writeMarkerAtomic(p, JSON.stringify(raw, null, 2));
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
/* corrupt marker — leave untouched */
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Update the nearest `.tim-project` (walk-up from cwd) after tim_load_project.
|
|
364
|
+
* Statusline and hooks read this marker — must match the loaded project label.
|
|
365
|
+
*/
|
|
366
|
+
function syncNearestProjectMarker(startCwd, projectLabel, options) {
|
|
367
|
+
if (!validateProjectLabel(projectLabel)) {
|
|
368
|
+
console.warn(`[tim-hooks] syncNearestProjectMarker: refusing to sync invalid project label ` +
|
|
369
|
+
`"${projectLabel}" — expected ^[PLEN]\\d{4}$. Returning false.`);
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
const located = discoverMarker(startCwd, {
|
|
373
|
+
...exports.DEFAULT_MARKER_DISCOVERY_POLICY,
|
|
374
|
+
...options?.findOptions,
|
|
375
|
+
});
|
|
376
|
+
if (!located)
|
|
377
|
+
return false;
|
|
378
|
+
const sessionId = options?.sessionId?.trim();
|
|
379
|
+
const { version: _v, ...rest } = located.marker;
|
|
380
|
+
writeMarker(located.dir, {
|
|
381
|
+
...rest,
|
|
382
|
+
project: projectLabel,
|
|
383
|
+
...(sessionId ? { session: sessionId } : {}),
|
|
384
|
+
});
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
/** Project detection — cwd-only marker (no walk-up). */
|
|
388
|
+
function detectProject(cwd) {
|
|
389
|
+
return discoverMarker(cwd, exports.CWD_ONLY_MARKER_DISCOVERY_POLICY)?.marker ?? null;
|
|
390
|
+
}
|
|
391
|
+
/** Re-derive counters from the DB and persist them into the marker. */
|
|
392
|
+
async function reconcileMarker(store, cwd) {
|
|
393
|
+
const marker = readMarker(cwd);
|
|
394
|
+
if (!marker)
|
|
395
|
+
throw new Error(`No ${exports.MARKER_FILENAME} in ${cwd}`);
|
|
396
|
+
const { exchangeCount, batchesSummarized } = await (0, tim_store_1.deriveCounters)(store, marker.session);
|
|
397
|
+
const reconciled = {
|
|
398
|
+
...marker,
|
|
399
|
+
exchanges: exchangeCount,
|
|
400
|
+
batches_summarized: batchesSummarized,
|
|
401
|
+
};
|
|
402
|
+
writeMarker(cwd, reconciled);
|
|
403
|
+
// Read back to return the canonical v2 shape (writeMarker upgraded the file).
|
|
404
|
+
return readMarker(cwd) ?? reconciled;
|
|
405
|
+
}
|
|
406
|
+
var constants_js_2 = require("./constants.js");
|
|
407
|
+
Object.defineProperty(exports, "LOCK_TTL_MS", { enumerable: true, get: function () { return constants_js_2.LOCK_TTL_MS; } });
|
|
408
|
+
function acquireLock(cwd) {
|
|
409
|
+
const lock = path.join(cwd, exports.MARKER_LOCK);
|
|
410
|
+
try {
|
|
411
|
+
fs.writeFileSync(lock, JSON.stringify({ pid: process.pid, ts: Date.now() }), { flag: 'wx' });
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
catch {
|
|
415
|
+
try {
|
|
416
|
+
const raw = JSON.parse(fs.readFileSync(lock, 'utf8'));
|
|
417
|
+
if (Date.now() - raw.ts > constants_js_1.LOCK_TTL_MS) {
|
|
418
|
+
fs.writeFileSync(lock, JSON.stringify({ pid: process.pid, ts: Date.now() }));
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
catch {
|
|
423
|
+
/* unreadable lock → treat as held */
|
|
424
|
+
}
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
/** True when an active (non-stale) summarizer/session lock is held. */
|
|
429
|
+
function isSessionLocked(cwd) {
|
|
430
|
+
const lock = path.join(cwd, exports.MARKER_LOCK);
|
|
431
|
+
if (!fs.existsSync(lock))
|
|
432
|
+
return false;
|
|
433
|
+
try {
|
|
434
|
+
const raw = JSON.parse(fs.readFileSync(lock, 'utf8'));
|
|
435
|
+
return Date.now() - raw.ts <= constants_js_1.LOCK_TTL_MS;
|
|
436
|
+
}
|
|
437
|
+
catch {
|
|
438
|
+
return true;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function releaseLock(cwd) {
|
|
442
|
+
try {
|
|
443
|
+
fs.rmSync(path.join(cwd, exports.MARKER_LOCK), { force: true });
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
/* ignore */
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
/** Production default: walk-up from cwd, home ancestors allowed (statusline / sync paths). */
|
|
450
|
+
exports.DEFAULT_MARKER_DISCOVERY_POLICY = {
|
|
451
|
+
walkUp: true,
|
|
452
|
+
allowHome: true,
|
|
453
|
+
};
|
|
454
|
+
/** Cwd-only binding (session-start hook, checkpoint auto-load). */
|
|
455
|
+
exports.CWD_ONLY_MARKER_DISCOVERY_POLICY = {
|
|
456
|
+
walkUp: false,
|
|
457
|
+
allowHome: false,
|
|
458
|
+
};
|
|
459
|
+
function isInsideRoot(dir, root) {
|
|
460
|
+
const d = path.resolve(dir);
|
|
461
|
+
const r = path.resolve(root);
|
|
462
|
+
return d === r || d.startsWith(r + path.sep);
|
|
463
|
+
}
|
|
464
|
+
/** Test helper: env vars override findMarker scope for spawned CLI. */
|
|
465
|
+
function findMarkerOptionsFromEnv() {
|
|
466
|
+
const maxRoot = process.env.TIM_MARKER_MAX_ROOT?.trim();
|
|
467
|
+
const walkUp = process.env.TIM_MARKER_WALK_UP === '1';
|
|
468
|
+
const allowHome = process.env.TIM_MARKER_ALLOW_HOME === '1';
|
|
469
|
+
if (!maxRoot && !walkUp && !allowHome)
|
|
470
|
+
return undefined;
|
|
471
|
+
return {
|
|
472
|
+
...(maxRoot ? { maxRoot } : {}),
|
|
473
|
+
...(walkUp ? { walkUp: true } : {}),
|
|
474
|
+
...(allowHome ? { allowHome: true } : {}),
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
function isHomePath(dir) {
|
|
478
|
+
return path.resolve(dir) === path.resolve(os.homedir());
|
|
479
|
+
}
|
|
480
|
+
function pickMarkerLocation(candidates) {
|
|
481
|
+
return candidates.reduce((best, cur) => path.resolve(cur.dir).length > path.resolve(best.dir).length ? cur : best);
|
|
482
|
+
}
|
|
483
|
+
function scanDirForMarker(dir) {
|
|
484
|
+
// Markers in shared directories (tmpdir, /) are never trusted — treat the
|
|
485
|
+
// dir as marker-free and keep walking, same as any dir without a marker.
|
|
486
|
+
if (isUnsafeMarkerDir(dir))
|
|
487
|
+
return null;
|
|
488
|
+
if (fs.existsSync(markerPath(dir))) {
|
|
489
|
+
const marker = readMarker(dir);
|
|
490
|
+
if (!marker)
|
|
491
|
+
return 'corrupt';
|
|
492
|
+
return { marker, dir };
|
|
493
|
+
}
|
|
494
|
+
const canonical = readCanonicalProject(dir);
|
|
495
|
+
if (canonical)
|
|
496
|
+
return { marker: canonical, dir };
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Find a project marker from `startCwd` — the single discovery implementation.
|
|
501
|
+
*
|
|
502
|
+
* Policy defaults (when fields omitted): walkUp=true, allowHome=true.
|
|
503
|
+
* Pass `CWD_ONLY_MARKER_DISCOVERY_POLICY` for harness cwd binding.
|
|
504
|
+
*/
|
|
505
|
+
function discoverMarker(startCwd, policy = exports.DEFAULT_MARKER_DISCOVERY_POLICY) {
|
|
506
|
+
const walkUp = policy.walkUp ?? true;
|
|
507
|
+
const allowHome = policy.allowHome ?? true;
|
|
508
|
+
const startResolved = path.resolve(startCwd);
|
|
509
|
+
if (!walkUp) {
|
|
510
|
+
const result = scanDirForMarker(startResolved);
|
|
511
|
+
if (result === 'corrupt')
|
|
512
|
+
return null;
|
|
513
|
+
return result;
|
|
514
|
+
}
|
|
515
|
+
const maxRoot = policy.maxRoot ? path.resolve(policy.maxRoot) : null;
|
|
516
|
+
let dir = startResolved;
|
|
517
|
+
const found = [];
|
|
518
|
+
for (let i = 0; i < 256; i++) {
|
|
519
|
+
const result = scanDirForMarker(dir);
|
|
520
|
+
if (result === 'corrupt')
|
|
521
|
+
return null;
|
|
522
|
+
if (result)
|
|
523
|
+
found.push(result);
|
|
524
|
+
const parent = path.dirname(dir);
|
|
525
|
+
if (parent === dir)
|
|
526
|
+
break;
|
|
527
|
+
if (maxRoot && isInsideRoot(dir, maxRoot) && !isInsideRoot(parent, maxRoot))
|
|
528
|
+
break;
|
|
529
|
+
dir = parent;
|
|
530
|
+
}
|
|
531
|
+
if (found.length === 0)
|
|
532
|
+
return null;
|
|
533
|
+
const filtered = found.filter((loc) => {
|
|
534
|
+
if (allowHome)
|
|
535
|
+
return true;
|
|
536
|
+
if (!isHomePath(loc.dir))
|
|
537
|
+
return true;
|
|
538
|
+
return path.resolve(loc.dir) === startResolved;
|
|
539
|
+
});
|
|
540
|
+
if (filtered.length === 0)
|
|
541
|
+
return null;
|
|
542
|
+
return pickMarkerLocation(filtered);
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Back-compat wrapper: when `options` is omitted, cwd-only (historical default).
|
|
546
|
+
* Prefer `discoverMarker` with an explicit policy for new code.
|
|
547
|
+
*/
|
|
548
|
+
function findMarker(startCwd, options) {
|
|
549
|
+
if (!options) {
|
|
550
|
+
return discoverMarker(startCwd, exports.CWD_ONLY_MARKER_DISCOVERY_POLICY);
|
|
551
|
+
}
|
|
552
|
+
return discoverMarker(startCwd, {
|
|
553
|
+
walkUp: options.walkUp ?? false,
|
|
554
|
+
allowHome: options.allowHome ?? false,
|
|
555
|
+
...(options.maxRoot ? { maxRoot: options.maxRoot } : {}),
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Shared, harness-agnostic directive text. Every start hook (Hermes,
|
|
560
|
+
* Claude Code, Cursor) emits exactly this so wording stays DRY. The TIM
|
|
561
|
+
* marker is authoritative for project binding this turn (see plan §end-state).
|
|
562
|
+
*/
|
|
563
|
+
function buildLoadDirective(projectLabel, markerDir, bindingLabel) {
|
|
564
|
+
const display = bindingLabel?.trim() || projectLabel;
|
|
565
|
+
return [
|
|
566
|
+
`📍 TIM project marker detected (.tim-project in ${markerDir}).`,
|
|
567
|
+
`This session is bound to TIM project ${display}.`,
|
|
568
|
+
``,
|
|
569
|
+
`ACTION: call tim_load_project(label="${projectLabel}") now to load the project ` +
|
|
570
|
+
`brief from the TIM store, then run the tim-session-start skill. STEP 1 ` +
|
|
571
|
+
`(project binding) is already decided by this marker — do NOT ask which ` +
|
|
572
|
+
`project, and do NOT run any hmem/active-project cwd→project resolution. ` +
|
|
573
|
+
`The TIM marker is authoritative for this turn.`,
|
|
574
|
+
].join('\n');
|
|
575
|
+
}
|
|
576
|
+
/** Directive when project comes from TIM session metadata (no local .tim-project). */
|
|
577
|
+
function buildSessionDirective(projectLabel, cwd, bindingLabel) {
|
|
578
|
+
const display = bindingLabel?.trim() || projectLabel;
|
|
579
|
+
return [
|
|
580
|
+
`📍 TIM session bound to project ${display} (TIM store, cwd ${cwd}).`,
|
|
581
|
+
`This session is bound to TIM project ${display}.`,
|
|
582
|
+
``,
|
|
583
|
+
`ACTION: call tim_load_project(label="${projectLabel}") now to load the project ` +
|
|
584
|
+
`brief from the TIM store, then run the tim-session-start skill. STEP 1 ` +
|
|
585
|
+
`is already decided by this TIM session — do NOT ask which project, and do NOT ` +
|
|
586
|
+
`run any hmem/active-project cwd→project resolution. The TIM binding is authoritative ` +
|
|
587
|
+
`for this turn.`,
|
|
588
|
+
].join('\n');
|
|
589
|
+
}
|
|
590
|
+
//# sourceMappingURL=marker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker.js","sourceRoot":"","sources":["../src/marker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TimStore } from 'tim-store';
|
|
2
|
+
import { type ProjectMarker } from './marker.js';
|
|
3
|
+
/**
|
|
4
|
+
* Attempt to recover a real project label when `.tim-project` points at a
|
|
5
|
+
* phantom (pattern-valid label missing from the DB).
|
|
6
|
+
*/
|
|
7
|
+
export declare function repairPhantomProjectBinding(store: TimStore, dir: string): Promise<string | null>;
|
|
8
|
+
/** Strip trailing `?` from statusline unbound display labels. */
|
|
9
|
+
export declare function stripUnboundProjectSuffix(label: string): string;
|
|
10
|
+
export declare function formatUnboundProjectLabel(label: string): string;
|
|
11
|
+
export declare function isUnboundProjectLabel(label: string): boolean;
|
|
12
|
+
export declare function markerWithRepairedProject(marker: ProjectMarker, recoveredLabel: string): ProjectMarker;
|
|
13
|
+
//# sourceMappingURL=phantom-recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phantom-recovery.d.ts","sourceRoot":"","sources":["../src/phantom-recovery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAgCrB;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA8BxB;AAED,iEAAiE;AACjE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,MAAM,GACrB,aAAa,CAEf"}
|