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.
Files changed (73) hide show
  1. package/README.md +31 -0
  2. package/dist/cadence-runner.d.ts +11 -0
  3. package/dist/cadence-runner.d.ts.map +1 -0
  4. package/dist/cadence-runner.js +30 -0
  5. package/dist/cadence-runner.js.map +1 -0
  6. package/dist/cadence.d.ts +10 -0
  7. package/dist/cadence.d.ts.map +1 -0
  8. package/dist/cadence.js +36 -0
  9. package/dist/cadence.js.map +1 -0
  10. package/dist/checkpoint.d.ts +56 -0
  11. package/dist/checkpoint.d.ts.map +1 -0
  12. package/dist/checkpoint.js +232 -0
  13. package/dist/checkpoint.js.map +1 -0
  14. package/dist/claude-stop.d.ts +32 -0
  15. package/dist/claude-stop.d.ts.map +1 -0
  16. package/dist/claude-stop.js +213 -0
  17. package/dist/claude-stop.js.map +1 -0
  18. package/dist/constants.d.ts +5 -0
  19. package/dist/constants.d.ts.map +1 -0
  20. package/dist/constants.js +8 -0
  21. package/dist/constants.js.map +1 -0
  22. package/dist/delta.d.ts +7 -0
  23. package/dist/delta.d.ts.map +1 -0
  24. package/dist/delta.js +53 -0
  25. package/dist/delta.js.map +1 -0
  26. package/dist/hooks.d.ts +39 -0
  27. package/dist/hooks.d.ts.map +1 -0
  28. package/dist/hooks.js +136 -0
  29. package/dist/hooks.js.map +1 -0
  30. package/dist/index.d.ts +13 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +88 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/marker.d.ts +179 -0
  35. package/dist/marker.d.ts.map +1 -0
  36. package/dist/marker.js +590 -0
  37. package/dist/marker.js.map +1 -0
  38. package/dist/phantom-recovery.d.ts +13 -0
  39. package/dist/phantom-recovery.d.ts.map +1 -0
  40. package/dist/phantom-recovery.js +113 -0
  41. package/dist/phantom-recovery.js.map +1 -0
  42. package/dist/project-creation.d.ts +48 -0
  43. package/dist/project-creation.d.ts.map +1 -0
  44. package/dist/project-creation.js +265 -0
  45. package/dist/project-creation.js.map +1 -0
  46. package/dist/prompt-submit.d.ts +16 -0
  47. package/dist/prompt-submit.d.ts.map +1 -0
  48. package/dist/prompt-submit.js +69 -0
  49. package/dist/prompt-submit.js.map +1 -0
  50. package/dist/rebalance.d.ts +17 -0
  51. package/dist/rebalance.d.ts.map +1 -0
  52. package/dist/rebalance.js +91 -0
  53. package/dist/rebalance.js.map +1 -0
  54. package/dist/session-hooks.d.ts +53 -0
  55. package/dist/session-hooks.d.ts.map +1 -0
  56. package/dist/session-hooks.js +167 -0
  57. package/dist/session-hooks.js.map +1 -0
  58. package/dist/update-check.d.ts +5 -0
  59. package/dist/update-check.d.ts.map +1 -0
  60. package/dist/update-check.js +66 -0
  61. package/dist/update-check.js.map +1 -0
  62. package/package.json +24 -0
  63. package/scripts/README-hermes-statusline.md +47 -0
  64. package/scripts/hermes-cli-tim-statusline.patch +75 -0
  65. package/scripts/lib/resolve-tim-cli.sh +30 -0
  66. package/scripts/post-commit.sh +30 -0
  67. package/scripts/tim-claude-session-start.sh +26 -0
  68. package/scripts/tim-cursor-inject.sh +17 -0
  69. package/scripts/tim-hermes-session-cache.sh +32 -0
  70. package/scripts/tim-hermes-statusline.sh +28 -0
  71. package/scripts/tim-post-commit.sh +14 -0
  72. package/scripts/tim-session-start.sh +104 -0
  73. package/scripts/tim-statusline.sh +16 -0
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # tim-hooks
2
+
3
+ Session hooks, checkpoint logic, and `.tim-project` marker handling for TIM.
4
+
5
+ ## Project binding: `.tim-project` vs `tim.json`
6
+
7
+ **`.tim-project` is runtime state, not source.** It holds per-session fields (`session`, `exchanges`, `batch_size`, `batches_summarized`) that change every session. Do not commit it — it is listed in the repo `.gitignore`.
8
+
9
+ **`tim.json` is the committed canonical default.** It contains only the stable project label, e.g. `{"project": "P0063"}`. Workers and fresh clones rely on this when no local `.tim-project` exists yet.
10
+
11
+ ### Resolution order
12
+
13
+ 1. **Nearest `.tim-project`** (walk up from cwd) — wins when present. Corrupt files are rejected (no silent fallback to `tim.json` at the same directory).
14
+ 2. **`tim.json`** (walk up) — used when no `.tim-project` exists on that chain.
15
+ 3. **`~/.tim/active-project`** or Inbox (`P0000`) — see `checkpoint.ts`.
16
+
17
+ ### Per-developer override
18
+
19
+ Create `.tim-project` in the repo root (or any ancestor of your cwd). Session start will refresh it. To change the team default for new clones, edit committed `tim.json` instead.
20
+
21
+ `validateMarkerAgainstStore` still rejects pattern-valid labels that do not exist in the TIM DB (defense against bogus labels like `P9999`).
22
+
23
+ ## Hook CLI resolution
24
+
25
+ Hook entrypoints are relocatable. They resolve the TIM CLI in this order:
26
+
27
+ 1. `TIM_CLI` override.
28
+ 2. A `tim` executable on `PATH`.
29
+ 3. The sibling installed package at `tim-cli/dist/cli.js`.
30
+
31
+ For example, run `bash packages/tim-hooks/scripts/tim-statusline.sh` from a source checkout, or copy/symlink the packaged scripts from any installation prefix. No repository-specific absolute path is required.
@@ -0,0 +1,11 @@
1
+ import type { TimStore } from 'tim-store';
2
+ export interface CadenceResult {
3
+ exchangeCount: number;
4
+ autoCheckpoint?: boolean;
5
+ checkpointEntryId?: string;
6
+ }
7
+ /**
8
+ * After logging exchanges: bump marker counter, optionally auto-checkpoint.
9
+ */
10
+ export declare function afterExchangeLogged(store: TimStore, sessionId: string, cwd: string): Promise<CadenceResult>;
11
+ //# sourceMappingURL=cadence-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cadence-runner.d.ts","sourceRoot":"","sources":["../src/cadence-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAM1C,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,CAAC,CAqBxB"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.afterExchangeLogged = afterExchangeLogged;
4
+ const tim_store_1 = require("tim-store");
5
+ const tim_core_1 = require("tim-core");
6
+ const marker_js_1 = require("./marker.js");
7
+ const cadence_js_1 = require("./cadence.js");
8
+ /**
9
+ * After logging exchanges: bump marker counter, optionally auto-checkpoint.
10
+ */
11
+ async function afterExchangeLogged(store, sessionId, cwd) {
12
+ const marker = (0, marker_js_1.readMarker)(cwd);
13
+ if (!marker) {
14
+ const { exchangeCount } = await (0, tim_store_1.deriveCounters)(store, sessionId);
15
+ return { exchangeCount };
16
+ }
17
+ const reconciled = await (0, marker_js_1.reconcileMarker)(store, cwd);
18
+ const everyN = (0, cadence_js_1.getCheckpointEveryN)((0, tim_core_1.loadConfig)());
19
+ const result = { exchangeCount: reconciled.exchanges };
20
+ if ((0, cadence_js_1.shouldAutoCheckpoint)(reconciled.exchanges, everyN)) {
21
+ const sessions = new tim_store_1.SessionManager(store);
22
+ const entry = await sessions.checkpoint(sessionId);
23
+ result.autoCheckpoint = true;
24
+ result.checkpointEntryId = entry.id;
25
+ const after = await (0, marker_js_1.reconcileMarker)(store, cwd);
26
+ (0, marker_js_1.writeMarker)(cwd, after);
27
+ }
28
+ return result;
29
+ }
30
+ //# sourceMappingURL=cadence-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cadence-runner.js","sourceRoot":"","sources":["../src/cadence-runner.ts"],"names":[],"mappings":";;AAeA,kDAyBC;AAvCD,yCAA2D;AAC3D,uCAAsC;AACtC,2CAAuE;AACvE,6CAAyE;AAQzE;;GAEG;AACI,KAAK,UAAU,mBAAmB,CACvC,KAAe,EACf,SAAiB,EACjB,GAAW;IAEX,MAAM,MAAM,GAAG,IAAA,sBAAU,EAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,IAAA,0BAAc,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACjE,OAAO,EAAE,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,IAAA,2BAAe,EAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,IAAA,gCAAmB,EAAC,IAAA,qBAAU,GAAE,CAAC,CAAC;IACjD,MAAM,MAAM,GAAkB,EAAE,aAAa,EAAE,UAAU,CAAC,SAAS,EAAE,CAAC;IAEtE,IAAI,IAAA,iCAAoB,EAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,IAAI,0BAAc,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACnD,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,MAAM,CAAC,iBAAiB,GAAG,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,IAAA,2BAAe,EAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAChD,IAAA,uBAAW,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { TimConfigFile } from 'tim-core';
2
+ export declare const DEFAULT_CHECKPOINT_EVERY_N = 20;
3
+ export declare const DEFAULT_BRIEFING_MAX_TOKENS = 9000;
4
+ export declare function getCheckpointEveryN(config: TimConfigFile): number;
5
+ export declare function getBriefingMaxTokens(config: TimConfigFile): number;
6
+ /** True when an auto-checkpoint should fire after this exchange count. */
7
+ export declare function shouldAutoCheckpoint(exchangeCount: number, everyN: number): boolean;
8
+ /** Reminder line when approaching checkpoint cadence (last 3 before N). */
9
+ export declare function checkpointCadenceReminder(exchangeCount: number, everyN: number): string | null;
10
+ //# sourceMappingURL=cadence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cadence.d.ts","sourceRoot":"","sources":["../src/cadence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAC7C,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAIjE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAIlE;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED,2EAA2E;AAC3E,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAOf"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_BRIEFING_MAX_TOKENS = exports.DEFAULT_CHECKPOINT_EVERY_N = void 0;
4
+ exports.getCheckpointEveryN = getCheckpointEveryN;
5
+ exports.getBriefingMaxTokens = getBriefingMaxTokens;
6
+ exports.shouldAutoCheckpoint = shouldAutoCheckpoint;
7
+ exports.checkpointCadenceReminder = checkpointCadenceReminder;
8
+ exports.DEFAULT_CHECKPOINT_EVERY_N = 20;
9
+ exports.DEFAULT_BRIEFING_MAX_TOKENS = 9000;
10
+ function getCheckpointEveryN(config) {
11
+ const n = config.checkpoint?.everyN;
12
+ if (typeof n === 'number' && n > 0)
13
+ return n;
14
+ return exports.DEFAULT_CHECKPOINT_EVERY_N;
15
+ }
16
+ function getBriefingMaxTokens(config) {
17
+ const n = config.briefing?.maxTokens;
18
+ if (typeof n === 'number' && n > 0)
19
+ return n;
20
+ return exports.DEFAULT_BRIEFING_MAX_TOKENS;
21
+ }
22
+ /** True when an auto-checkpoint should fire after this exchange count. */
23
+ function shouldAutoCheckpoint(exchangeCount, everyN) {
24
+ return exchangeCount > 0 && exchangeCount % everyN === 0;
25
+ }
26
+ /** Reminder line when approaching checkpoint cadence (last 3 before N). */
27
+ function checkpointCadenceReminder(exchangeCount, everyN) {
28
+ if (everyN <= 0)
29
+ return null;
30
+ const remaining = everyN - (exchangeCount % everyN);
31
+ if (remaining > 0 && remaining <= 3 && exchangeCount > 0) {
32
+ return `TIM: checkpoint in ${remaining} exchange(s) (every ${everyN})`;
33
+ }
34
+ return null;
35
+ }
36
+ //# sourceMappingURL=cadence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cadence.js","sourceRoot":"","sources":["../src/cadence.ts"],"names":[],"mappings":";;;AAKA,kDAIC;AAED,oDAIC;AAGD,oDAEC;AAGD,8DAUC;AA/BY,QAAA,0BAA0B,GAAG,EAAE,CAAC;AAChC,QAAA,2BAA2B,GAAG,IAAI,CAAC;AAEhD,SAAgB,mBAAmB,CAAC,MAAqB;IACvD,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC;IACpC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7C,OAAO,kCAA0B,CAAC;AACpC,CAAC;AAED,SAAgB,oBAAoB,CAAC,MAAqB;IACxD,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC;IACrC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7C,OAAO,mCAA2B,CAAC;AACrC,CAAC;AAED,0EAA0E;AAC1E,SAAgB,oBAAoB,CAAC,aAAqB,EAAE,MAAc;IACxE,OAAO,aAAa,GAAG,CAAC,IAAI,aAAa,GAAG,MAAM,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,2EAA2E;AAC3E,SAAgB,yBAAyB,CACvC,aAAqB,EACrB,MAAc;IAEd,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,CAAC;IACpD,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,IAAI,CAAC,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACzD,OAAO,sBAAsB,SAAS,uBAAuB,MAAM,GAAG,CAAC;IACzE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { Entry } from 'tim-core';
2
+ import type { HooksConfig } from 'tim-core';
3
+ import { type Summarizer, type TimStore } from 'tim-store';
4
+ import { type HookEnv } from './hooks.js';
5
+ export interface SessionEndOptions {
6
+ summarize?: Summarizer;
7
+ hooksConfig?: HooksConfig;
8
+ env?: HookEnv;
9
+ }
10
+ export interface SessionStartResult {
11
+ session: Entry;
12
+ project: Entry | null;
13
+ /** Optional briefing supplement (delta, update check, …). */
14
+ briefing?: string;
15
+ }
16
+ /** Resolve active project label from TIM_PROJECT env or ~/.tim/active-project. */
17
+ export declare function getActiveProjectLabel(): string | null;
18
+ /**
19
+ * Resolve the active project from a .tim-project marker in cwd ONLY.
20
+ *
21
+ * No walk-up. No parent traversal. This is the Auto-Load Hook contract:
22
+ * a session binds to a project only if the marker is in the directory the
23
+ * user explicitly invoked the harness from. Walking up to a parent has
24
+ * caused repeated cross-project binding bugs (Worker A→B→C in 2 days);
25
+ * cwd-only is the same pattern Hermes statusline uses after the 133c5abd
26
+ * fix in its-over-9k, kept consistent here.
27
+ *
28
+ * Falls back to:
29
+ * - readMarker(cwd) which checks .tim-project and then tim.json
30
+ * - validateMarkerAgainstStore which gates the project label against the DB
31
+ *
32
+ * Returns the project label, or null when no cwd marker exists, the marker
33
+ * is corrupt, or the project does not exist in the DB.
34
+ */
35
+ export declare function resolveActiveProjectFromCwd(cwd: string, store: TimStore): Promise<string | null>;
36
+ /** Load project entry by hmem-style label (e.g. P0062) when configured. */
37
+ export declare function loadProjectContext(store: TimStore): Promise<Entry | null>;
38
+ export declare function runCheckpoint(store: TimStore, sessionId: string, opts?: {
39
+ summarize?: Summarizer;
40
+ runDecay?: boolean;
41
+ handoffNote?: string;
42
+ }): Promise<Entry>;
43
+ export declare function runSessionStart(store: TimStore, params: {
44
+ sessionId: string;
45
+ agentName: string;
46
+ cwd: string;
47
+ harness: string;
48
+ hooksConfig?: HooksConfig;
49
+ projectId?: string;
50
+ batchSize?: number;
51
+ tool?: string;
52
+ model?: string;
53
+ taskSummary?: string;
54
+ }): Promise<SessionStartResult>;
55
+ export declare function runSessionEnd(store: TimStore, sessionId: string, opts?: SessionEndOptions): Promise<Entry>;
56
+ //# sourceMappingURL=checkpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../src/checkpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAS5C,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,QAAQ,EACd,MAAM,WAAW,CAAC;AACnB,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAc9D,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,IAAI,CASrD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKxB;AAED,2EAA2E;AAC3E,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAI/E;AAyED,wBAAsB,aAAa,CACjC,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9E,OAAO,CAAC,KAAK,CAAC,CAGhB;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE;IACN,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,OAAO,CAAC,kBAAkB,CAAC,CAyD7B;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,KAAK,CAAC,CA2BhB"}
@@ -0,0 +1,232 @@
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.getActiveProjectLabel = getActiveProjectLabel;
37
+ exports.resolveActiveProjectFromCwd = resolveActiveProjectFromCwd;
38
+ exports.loadProjectContext = loadProjectContext;
39
+ exports.runCheckpoint = runCheckpoint;
40
+ exports.runSessionStart = runSessionStart;
41
+ exports.runSessionEnd = runSessionEnd;
42
+ const tim_core_1 = require("tim-core");
43
+ const cadence_js_1 = require("./cadence.js");
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const tim_store_1 = require("tim-store");
47
+ const hooks_js_1 = require("./hooks.js");
48
+ const delta_js_1 = require("./delta.js");
49
+ const update_check_js_1 = require("./update-check.js");
50
+ const marker_js_1 = require("./marker.js");
51
+ const phantom_recovery_js_1 = require("./phantom-recovery.js");
52
+ const session_hooks_js_1 = require("./session-hooks.js");
53
+ /** Resolve active project label from TIM_PROJECT env or ~/.tim/active-project. */
54
+ function getActiveProjectLabel() {
55
+ const fromEnv = process.env.TIM_PROJECT?.trim();
56
+ if (fromEnv)
57
+ return fromEnv;
58
+ const activeFile = path.join((0, tim_core_1.getTimDir)(), 'active-project');
59
+ if (!fs.existsSync(activeFile))
60
+ return null;
61
+ const label = fs.readFileSync(activeFile, 'utf8').trim();
62
+ return label || null;
63
+ }
64
+ /**
65
+ * Resolve the active project from a .tim-project marker in cwd ONLY.
66
+ *
67
+ * No walk-up. No parent traversal. This is the Auto-Load Hook contract:
68
+ * a session binds to a project only if the marker is in the directory the
69
+ * user explicitly invoked the harness from. Walking up to a parent has
70
+ * caused repeated cross-project binding bugs (Worker A→B→C in 2 days);
71
+ * cwd-only is the same pattern Hermes statusline uses after the 133c5abd
72
+ * fix in its-over-9k, kept consistent here.
73
+ *
74
+ * Falls back to:
75
+ * - readMarker(cwd) which checks .tim-project and then tim.json
76
+ * - validateMarkerAgainstStore which gates the project label against the DB
77
+ *
78
+ * Returns the project label, or null when no cwd marker exists, the marker
79
+ * is corrupt, or the project does not exist in the DB.
80
+ */
81
+ async function resolveActiveProjectFromCwd(cwd, store) {
82
+ const located = (0, marker_js_1.discoverMarker)(cwd, marker_js_1.CWD_ONLY_MARKER_DISCOVERY_POLICY);
83
+ if (!located)
84
+ return null;
85
+ const validated = await (0, marker_js_1.validateMarkerAgainstStore)(located.marker, store);
86
+ return validated?.project ?? null;
87
+ }
88
+ /** Load project entry by hmem-style label (e.g. P0062) when configured. */
89
+ async function loadProjectContext(store) {
90
+ const label = getActiveProjectLabel();
91
+ if (!label)
92
+ return null;
93
+ return store.read(label);
94
+ }
95
+ async function resolveSessionProjectId(store, cwd, explicitProjectId) {
96
+ if (explicitProjectId) {
97
+ // Validate explicit project ids against the DB so a hand-edited
98
+ // `--project=P9999` (or a botched upstream commit) can't smuggle
99
+ // a bogus label into the marker. The Inbox (P0000) is exempt —
100
+ // it's a system project that tim-store.ensureInboxProject()
101
+ // materializes on first use. This closes the second half of the
102
+ // P9999 bug: even if the on-disk marker was repaired, an
103
+ // explicit override could re-poison the file.
104
+ if (explicitProjectId !== 'P0000') {
105
+ const resolved = await store.resolveProjectLabel(explicitProjectId);
106
+ if (resolved.status === 'found')
107
+ return resolved.label;
108
+ if (resolved.status === 'not_found') {
109
+ throw new Error(`Project not found: ${explicitProjectId}. Use tim_load_project to pick a real project.`);
110
+ }
111
+ throw new Error(`Ambiguous project label: ${explicitProjectId} matches ${resolved.labels.join(', ')}.`);
112
+ }
113
+ return explicitProjectId;
114
+ }
115
+ const located = (0, marker_js_1.discoverMarker)(cwd, marker_js_1.CWD_ONLY_MARKER_DISCOVERY_POLICY);
116
+ if (located) {
117
+ const validated = await (0, marker_js_1.validateMarkerAgainstStore)(located.marker, store);
118
+ if (validated)
119
+ return validated.project;
120
+ const recovered = await (0, phantom_recovery_js_1.repairPhantomProjectBinding)(store, located.dir);
121
+ if (recovered) {
122
+ if (store.getDatabasePath() !== ':memory:') {
123
+ (0, marker_js_1.writeMarker)(located.dir, (0, phantom_recovery_js_1.markerWithRepairedProject)(located.marker, recovered));
124
+ }
125
+ return recovered;
126
+ }
127
+ await (0, tim_store_1.ensureInboxProject)(store);
128
+ return tim_store_1.INBOX_PROJECT_LABEL;
129
+ }
130
+ const active = getActiveProjectLabel();
131
+ if (active) {
132
+ const validated = await (0, marker_js_1.validateMarkerAgainstStore)({
133
+ version: 2,
134
+ project: active,
135
+ session: '',
136
+ exchanges: 0,
137
+ batch_size: 5,
138
+ batches_summarized: 0,
139
+ }, store);
140
+ if (validated)
141
+ return validated.project;
142
+ }
143
+ const auto = await (0, tim_store_1.ensureProjectForPath)(store, cwd);
144
+ if (auto)
145
+ return auto.label;
146
+ await (0, tim_store_1.ensureInboxProject)(store);
147
+ return tim_store_1.INBOX_PROJECT_LABEL;
148
+ }
149
+ async function runCheckpoint(store, sessionId, opts = {}) {
150
+ const sessions = new tim_store_1.SessionManager(store);
151
+ return sessions.checkpoint(sessionId, opts);
152
+ }
153
+ async function runSessionStart(store, params) {
154
+ const sessions = new tim_store_1.SessionManager(store);
155
+ const projectId = await resolveSessionProjectId(store, params.cwd, params.projectId);
156
+ const session = await sessions.startProjectSession({
157
+ sessionId: params.sessionId,
158
+ projectId,
159
+ agentName: params.agentName,
160
+ cwd: params.cwd,
161
+ harness: params.harness,
162
+ batchSize: params.batchSize,
163
+ });
164
+ if (store.getDatabasePath() !== ':memory:') {
165
+ (0, marker_js_1.writeMarker)(params.cwd, {
166
+ project: projectId,
167
+ session: params.sessionId,
168
+ exchanges: 0,
169
+ batch_size: typeof session.metadata.batch_size === 'number'
170
+ ? session.metadata.batch_size
171
+ : 5,
172
+ batches_summarized: 0,
173
+ version: 2,
174
+ });
175
+ }
176
+ await (0, hooks_js_1.runConfiguredHooks)('sessionStart', params.hooksConfig, {
177
+ TIM_SESSION_ID: params.sessionId,
178
+ TIM_CWD: params.cwd,
179
+ TIM_AGENT: params.agentName,
180
+ TIM_HARNESS: params.harness,
181
+ TIM_PROJECT: projectId,
182
+ });
183
+ const project = await store.read(projectId);
184
+ let briefing;
185
+ const briefingParts = [];
186
+ if (projectId !== tim_store_1.INBOX_PROJECT_LABEL) {
187
+ const delta = await (0, delta_js_1.getDeltaBriefing)(store, projectId, {
188
+ sessionId: params.sessionId,
189
+ });
190
+ if (delta)
191
+ briefingParts.push(delta);
192
+ }
193
+ const updateLine = await (0, update_check_js_1.getUpdateCheckLineBriefing)();
194
+ if (updateLine)
195
+ briefingParts.push(updateLine);
196
+ const marker = (0, marker_js_1.readMarker)(params.cwd);
197
+ if (marker && marker.exchanges > 0) {
198
+ const everyN = (0, cadence_js_1.getCheckpointEveryN)((0, tim_core_1.loadConfig)());
199
+ const reminder = (0, cadence_js_1.checkpointCadenceReminder)(marker.exchanges, everyN);
200
+ if (reminder)
201
+ briefingParts.push(reminder);
202
+ }
203
+ if (briefingParts.length > 0)
204
+ briefing = briefingParts.join('\n');
205
+ return { session, project, briefing };
206
+ }
207
+ async function runSessionEnd(store, sessionId, opts = {}) {
208
+ const cwd = opts.env?.TIM_CWD ?? process.cwd();
209
+ const env = {
210
+ TIM_SESSION_ID: sessionId,
211
+ TIM_CWD: cwd,
212
+ ...opts.env,
213
+ };
214
+ await (0, hooks_js_1.runConfiguredHooks)('sessionEnd', opts.hooksConfig, env);
215
+ await (0, session_hooks_js_1.onSessionStop)(store, cwd);
216
+ // Periodically regenerate the project-level summary (every Nth session).
217
+ // Fire-and-forget — must never block or fail the session-end hook.
218
+ try {
219
+ const config = (0, tim_core_1.loadConfig)();
220
+ const threshold = config.projectSummary?.sessions_threshold ?? session_hooks_js_1.DEFAULT_PROJECT_SUMMARY_THRESHOLD;
221
+ const cwdLabel = await resolveActiveProjectFromCwd(cwd, store);
222
+ const label = cwdLabel ?? getActiveProjectLabel();
223
+ await (0, session_hooks_js_1.maybeSpawnProjectSummary)(store, cwd, label, { threshold });
224
+ }
225
+ catch {
226
+ /* non-critical */
227
+ }
228
+ return runCheckpoint(store, sessionId, {
229
+ summarize: opts.summarize,
230
+ });
231
+ }
232
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../src/checkpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { TimStore } from 'tim-store';
2
+ import { type CadenceResult } from './cadence-runner.js';
3
+ export declare const MAX_TRANSCRIPT_BYTES: number;
4
+ export declare const MAX_EXCHANGE_CHARS: number;
5
+ export interface ClaudeStopPayload {
6
+ session_id: string;
7
+ transcript_path: string;
8
+ cwd?: string;
9
+ stop_hook_active?: boolean;
10
+ [key: string]: unknown;
11
+ }
12
+ export interface ClaudeStopResult extends Partial<CadenceResult> {
13
+ logged: boolean;
14
+ duplicate?: boolean;
15
+ }
16
+ interface TranscriptTurn {
17
+ user: string;
18
+ assistant: string;
19
+ identity: string;
20
+ }
21
+ /**
22
+ * Read a Claude Code transcript JSONL and return the last genuine user/assistant turn.
23
+ * Skips isMeta, tool-only assistants, malformed lines, and files over the byte bound.
24
+ */
25
+ export declare function readLastExchange(transcriptPath: string, maxBytes?: number): TranscriptTurn | null;
26
+ export declare function runClaudeStop(store: TimStore, payload: ClaudeStopPayload, options: {
27
+ cwd: string;
28
+ }): Promise<ClaudeStopResult>;
29
+ /** Test helper: expose counters after stop logging. */
30
+ export declare function stopExchangeCount(store: TimStore, sessionId: string): Promise<number>;
31
+ export {};
32
+ //# sourceMappingURL=claude-stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-stop.d.ts","sourceRoot":"","sources":["../src/claude-stop.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAG9E,eAAO,MAAM,oBAAoB,QAAc,CAAC;AAChD,eAAO,MAAM,kBAAkB,QAAY,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAiB,SAAQ,OAAO,CAAC,aAAa,CAAC;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAoDD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,MAAM,EACtB,QAAQ,SAAuB,GAC9B,cAAc,GAAG,IAAI,CAwDvB;AA4BD,wBAAsB,aAAa,CACjC,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA6B3B;AAED,uDAAuD;AACvD,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3F"}