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
@@ -0,0 +1,179 @@
1
+ import type { TimStore } from 'tim-store';
2
+ export declare const MARKER_FILENAME = ".tim-project";
3
+ export declare const MARKER_LOCK = ".tim-project.lock";
4
+ /**
5
+ * Committed default project label for repos that gitignore `.tim-project`.
6
+ * Contains only the stable `project` field; runtime counters live in the
7
+ * local `.tim-project` file created on session start. Override per-machine
8
+ * by creating `.tim-project` in the repo root (it wins over tim.json).
9
+ */
10
+ export declare const CANONICAL_PROJECT_FILENAME = "tim.json";
11
+ /**
12
+ * Current marker schema version. Bump this when the on-disk shape changes;
13
+ * readers detect older files by the missing/unknown `version` field and
14
+ * normalize to the current shape.
15
+ */
16
+ export declare const MARKER_VERSION = 2;
17
+ /**
18
+ * .tim-project — v2 schema.
19
+ *
20
+ * v2 removed the legacy `route_exchanges_to` and `sessions` map fields
21
+ * (hmem-era cruft: written by the MCP server, read by nothing). See
22
+ * `references/sql-to-mcp-mapping.md` and the schema evaluation journal
23
+ * for the field-by-field rationale.
24
+ *
25
+ * `version` is required on disk; the read path fills it in automatically
26
+ * for v1 files so existing installations keep working without an explicit
27
+ * migration step. The next write upgrades the file to v2.
28
+ */
29
+ export interface ProjectMarker {
30
+ version: 2;
31
+ project: string;
32
+ session: string;
33
+ exchanges: number;
34
+ batch_size: number;
35
+ batches_summarized: number;
36
+ }
37
+ /**
38
+ * Input shape for writeMarker. Callers MAY omit `version` — the writer
39
+ * always stamps the current version on disk. All other fields are required.
40
+ * Kept as a separate alias so the read API can return the strict v2 type
41
+ * while the write API stays convenient for callers that don't care about
42
+ * the version field.
43
+ */
44
+ export type ProjectMarkerInput = Omit<ProjectMarker, 'version'> & {
45
+ version?: 2;
46
+ };
47
+ export declare function markerPath(cwd: string): string;
48
+ export declare function canonicalProjectPath(cwd: string): string;
49
+ export declare function validateProjectLabel(label: string): boolean;
50
+ /**
51
+ * Sentinel label for the Inbox project (P0000). Always treated as
52
+ * valid even when not present in the DB — the Inbox is a system
53
+ * project that tim-store.ensureInboxProject() materializes lazily.
54
+ */
55
+ export declare const INBOX_LABEL = "P0000";
56
+ /**
57
+ * Read a marker and normalize it to the current schema version.
58
+ *
59
+ * - Missing file → null
60
+ * - Corrupt JSON → null
61
+ * - v1 file (no `version` field) → strips `route_exchanges_to` + `sessions`
62
+ * map, sets `version: 2`, returns the upgraded object. The file itself
63
+ * is NOT rewritten here — the next `writeMarker` call upgrades it.
64
+ * - v2 file → returned as-is.
65
+ *
66
+ * Callers always see a v2-conformant `ProjectMarker` regardless of what's
67
+ * on disk. This is the only safe way to evolve the schema without forcing
68
+ * a one-shot migration.
69
+ *
70
+ * When no `.tim-project` exists, falls back to `tim.json` (committed
71
+ * canonical default). A real `.tim-project` always wins — even when
72
+ * corrupt (returns null rather than silently using tim.json).
73
+ */
74
+ export declare function readMarker(cwd: string): ProjectMarker | null;
75
+ /**
76
+ * Defense-in-depth check: a project label that matches the
77
+ * pattern but is semantically bogus (e.g. `P9999` — a label that
78
+ * was never issued by TIM, often the residue of a hand-edit or a
79
+ * botched commit) must NOT be persisted into `.tim-project`. The
80
+ * original P9999 bug bound the statusline to a non-existent
81
+ * project because the file was trusted blindly.
82
+ *
83
+ * Resolution: pattern-match (already enforced by normalizeMarker)
84
+ * AND the project must exist as a `kind=project` entry in the DB.
85
+ * The Inbox (P0000) is exempt — it's a system project that
86
+ * tim-store creates on first use via `ensureInboxProject`.
87
+ *
88
+ * Returns the marker on success, null on rejection. On DB error
89
+ * (store unavailable, DB locked, etc.) we FAIL OPEN: a corrupted
90
+ * DB is not a license to corrupt the marker, but a transient
91
+ * read failure shouldn't brick the session-start hook. The
92
+ * pattern check in normalizeMarker still ran, so we never accept
93
+ * malformed labels — we just skip the existence confirmation.
94
+ */
95
+ export declare function validateMarkerAgainstStore(marker: ProjectMarker, store: Pick<TimStore, 'resolveProjectLabel'>): Promise<ProjectMarker | null>;
96
+ /**
97
+ * Shared/system directories where a `.tim-project` must never live: every
98
+ * process can have them as cwd, so a marker there leaks into unrelated
99
+ * sessions via walk-up (observed: a cron with cwd=/tmp wrote /tmp/.tim-project
100
+ * and every process under /tmp inherited it). v1 unsafe set — deliberately
101
+ * minimal and explicit: os.tmpdir() itself and the filesystem root.
102
+ * Subdirectories of tmpdir (mkdtemp scratch dirs) are private and stay legal.
103
+ */
104
+ export declare function isUnsafeMarkerDir(dir: string): boolean;
105
+ /** Atomically write JSON to `filePath` (tmp + rename — no torn reads on POSIX). */
106
+ export declare function writeMarkerAtomic(filePath: string, content: string): void;
107
+ export declare class ExclusiveMarkerConflictError extends Error {
108
+ readonly filePath: string;
109
+ constructor(filePath: string);
110
+ }
111
+ /** Publish a marker only when no local marker exists already. */
112
+ export declare function writeMarkerExclusive(cwd: string, marker: ProjectMarkerInput): ProjectMarker;
113
+ /** Write a project marker file. Always emits the current schema version:
114
+ * the on-disk file becomes v2 on first write, regardless of the caller's
115
+ * input. This is the auto-upgrade path for v1 files. */
116
+ export declare function writeMarker(cwd: string, marker: ProjectMarkerInput): void;
117
+ /**
118
+ * Rotate the session id in cwd's `.tim-project` when the harness supplies a new one.
119
+ * Used by tim-session-start.sh — must not interpolate paths into JS source.
120
+ */
121
+ export declare function rotateMarkerSession(cwd: string, sessionId: string): void;
122
+ /**
123
+ * Update the nearest `.tim-project` (walk-up from cwd) after tim_load_project.
124
+ * Statusline and hooks read this marker — must match the loaded project label.
125
+ */
126
+ export declare function syncNearestProjectMarker(startCwd: string, projectLabel: string, options?: {
127
+ sessionId?: string;
128
+ findOptions?: FindMarkerOptions;
129
+ }): boolean;
130
+ /** Project detection — cwd-only marker (no walk-up). */
131
+ export declare function detectProject(cwd: string): ProjectMarker | null;
132
+ /** Re-derive counters from the DB and persist them into the marker. */
133
+ export declare function reconcileMarker(store: TimStore, cwd: string): Promise<ProjectMarker>;
134
+ export { LOCK_TTL_MS } from './constants.js';
135
+ export declare function acquireLock(cwd: string): boolean;
136
+ /** True when an active (non-stale) summarizer/session lock is held. */
137
+ export declare function isSessionLocked(cwd: string): boolean;
138
+ export declare function releaseLock(cwd: string): void;
139
+ export interface MarkerLocation {
140
+ marker: ProjectMarker;
141
+ dir: string;
142
+ }
143
+ /** Discovery policy for `discoverMarker` — single knob for walk-up scope. */
144
+ export type MarkerDiscoveryPolicy = FindMarkerOptions;
145
+ export interface FindMarkerOptions {
146
+ /** Do not walk above this directory (isolates tests; ignores e.g. /tmp/.tim-project). */
147
+ maxRoot?: string;
148
+ /** Walk parent directories for a marker. */
149
+ walkUp?: boolean;
150
+ /** When walkUp is true, include ancestor markers at $HOME. Default false. */
151
+ allowHome?: boolean;
152
+ }
153
+ /** Production default: walk-up from cwd, home ancestors allowed (statusline / sync paths). */
154
+ export declare const DEFAULT_MARKER_DISCOVERY_POLICY: MarkerDiscoveryPolicy;
155
+ /** Cwd-only binding (session-start hook, checkpoint auto-load). */
156
+ export declare const CWD_ONLY_MARKER_DISCOVERY_POLICY: MarkerDiscoveryPolicy;
157
+ /** Test helper: env vars override findMarker scope for spawned CLI. */
158
+ export declare function findMarkerOptionsFromEnv(): FindMarkerOptions | undefined;
159
+ /**
160
+ * Find a project marker from `startCwd` — the single discovery implementation.
161
+ *
162
+ * Policy defaults (when fields omitted): walkUp=true, allowHome=true.
163
+ * Pass `CWD_ONLY_MARKER_DISCOVERY_POLICY` for harness cwd binding.
164
+ */
165
+ export declare function discoverMarker(startCwd: string, policy?: MarkerDiscoveryPolicy): MarkerLocation | null;
166
+ /**
167
+ * Back-compat wrapper: when `options` is omitted, cwd-only (historical default).
168
+ * Prefer `discoverMarker` with an explicit policy for new code.
169
+ */
170
+ export declare function findMarker(startCwd: string, options?: FindMarkerOptions): MarkerLocation | null;
171
+ /**
172
+ * Shared, harness-agnostic directive text. Every start hook (Hermes,
173
+ * Claude Code, Cursor) emits exactly this so wording stays DRY. The TIM
174
+ * marker is authoritative for project binding this turn (see plan §end-state).
175
+ */
176
+ export declare function buildLoadDirective(projectLabel: string, markerDir: string, bindingLabel?: string): string;
177
+ /** Directive when project comes from TIM session metadata (no local .tim-project). */
178
+ export declare function buildSessionDirective(projectLabel: string, cwd: string, bindingLabel?: string): string;
179
+ //# sourceMappingURL=marker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../src/marker.ts"],"names":[],"mappings":"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"}