@tyroneross/bookmark 0.1.0 → 0.3.2
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 +29 -12
- package/.claude-plugin/plugin.json +12 -8
- package/.codex-plugin/plugin.json +31 -0
- package/.mcp.json +8 -0
- package/CLAUDE.md +83 -49
- package/LICENSE +202 -21
- package/README.md +150 -57
- package/agents/snapshot-analyst.md +1 -1
- package/commands/bookmark.md +29 -0
- package/commands/feedback.md +37 -0
- package/commands/restore.md +14 -4
- package/commands/snapshot.md +19 -7
- package/commands/status.md +1 -1
- package/dist/cli/index.js +627 -87
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/snapshot-resolution.d.ts +15 -0
- package/dist/cli/snapshot-resolution.d.ts.map +1 -0
- package/dist/cli/snapshot-resolution.js +21 -0
- package/dist/cli/snapshot-resolution.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +149 -23
- package/dist/config.js.map +1 -1
- package/dist/context/freshness.d.ts +3 -0
- package/dist/context/freshness.d.ts.map +1 -0
- package/dist/context/freshness.js +29 -0
- package/dist/context/freshness.js.map +1 -0
- package/dist/context/handoff-prompt.d.ts +12 -0
- package/dist/context/handoff-prompt.d.ts.map +1 -0
- package/dist/context/handoff-prompt.js +29 -0
- package/dist/context/handoff-prompt.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +85 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +97 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +304 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/registry.d.ts +40 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +134 -0
- package/dist/registry.js.map +1 -0
- package/dist/restore/index.d.ts +13 -1
- package/dist/restore/index.d.ts.map +1 -1
- package/dist/restore/index.js +163 -43
- package/dist/restore/index.js.map +1 -1
- package/dist/setup/auto-setup.d.ts +8 -2
- package/dist/setup/auto-setup.d.ts.map +1 -1
- package/dist/setup/auto-setup.js +287 -67
- package/dist/setup/auto-setup.js.map +1 -1
- package/dist/setup/configure-hooks.d.ts +14 -3
- package/dist/setup/configure-hooks.d.ts.map +1 -1
- package/dist/setup/configure-hooks.js +156 -24
- package/dist/setup/configure-hooks.js.map +1 -1
- package/dist/snapshot/capture.d.ts +13 -9
- package/dist/snapshot/capture.d.ts.map +1 -1
- package/dist/snapshot/capture.js +42 -105
- package/dist/snapshot/capture.js.map +1 -1
- package/dist/snapshot/compress.d.ts +3 -3
- package/dist/snapshot/compress.d.ts.map +1 -1
- package/dist/snapshot/compress.js +35 -67
- package/dist/snapshot/compress.js.map +1 -1
- package/dist/snapshot/storage.d.ts +7 -0
- package/dist/snapshot/storage.d.ts.map +1 -1
- package/dist/snapshot/storage.js +31 -6
- package/dist/snapshot/storage.js.map +1 -1
- package/dist/threshold/state.d.ts +5 -0
- package/dist/threshold/state.d.ts.map +1 -1
- package/dist/threshold/state.js +28 -2
- package/dist/threshold/state.js.map +1 -1
- package/dist/threshold/token-usage.d.ts +29 -0
- package/dist/threshold/token-usage.d.ts.map +1 -0
- package/dist/threshold/token-usage.js +128 -0
- package/dist/threshold/token-usage.js.map +1 -0
- package/dist/trails/identity.d.ts +76 -0
- package/dist/trails/identity.d.ts.map +1 -0
- package/dist/trails/identity.js +117 -0
- package/dist/trails/identity.js.map +1 -0
- package/dist/trails/reader.d.ts +7 -0
- package/dist/trails/reader.d.ts.map +1 -0
- package/dist/trails/reader.js +22 -0
- package/dist/trails/reader.js.map +1 -0
- package/dist/trails/writer.d.ts +9 -0
- package/dist/trails/writer.d.ts.map +1 -0
- package/dist/trails/writer.js +110 -0
- package/dist/trails/writer.js.map +1 -0
- package/dist/transcript/extractor.d.ts +17 -4
- package/dist/transcript/extractor.d.ts.map +1 -1
- package/dist/transcript/extractor.js +141 -174
- package/dist/transcript/extractor.js.map +1 -1
- package/dist/transcript/parser.d.ts.map +1 -1
- package/dist/transcript/parser.js +69 -7
- package/dist/transcript/parser.js.map +1 -1
- package/dist/types.d.ts +37 -38
- package/dist/types.d.ts.map +1 -1
- package/hooks/hooks.json +12 -14
- package/package.json +13 -10
- package/scripts/install-plugin.sh +48 -0
- package/skills/context-continuity/SKILL.md +43 -24
- package/commands/activate.md +0 -20
- package/dist/transcript/estimator.d.ts +0 -20
- package/dist/transcript/estimator.d.ts.map +0 -1
- package/dist/transcript/estimator.js +0 -95
- package/dist/transcript/estimator.js.map +0 -1
package/dist/registry.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { basename, dirname, join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
const REGISTRY_VERSION = '1.0.0';
|
|
5
|
+
const MAX_ENTRIES = 500;
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a human-readable project name from a directory path.
|
|
8
|
+
*
|
|
9
|
+
* Resolution order:
|
|
10
|
+
* 1. package.json "name" field in cwd
|
|
11
|
+
* 2. basename of git repo root (walk up until .git is found)
|
|
12
|
+
* 3. basename of cwd — unless it's the home directory
|
|
13
|
+
* 4. Fallback: basename(cwd) regardless
|
|
14
|
+
*/
|
|
15
|
+
export function resolveProjectName(cwd) {
|
|
16
|
+
const home = homedir();
|
|
17
|
+
// 1. package.json name
|
|
18
|
+
const pkgPath = join(cwd, 'package.json');
|
|
19
|
+
if (existsSync(pkgPath)) {
|
|
20
|
+
try {
|
|
21
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
22
|
+
if (pkg.name && pkg.name.trim()) {
|
|
23
|
+
// Strip scoped package prefix (@scope/name → name)
|
|
24
|
+
return pkg.name.replace(/^@[^/]+\//, '').trim();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Fall through
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// 2. Walk up looking for .git directory
|
|
32
|
+
let dir = cwd;
|
|
33
|
+
const root = dirname(home); // Stop before going above home's parent
|
|
34
|
+
while (dir && dir !== root && dir !== dirname(dir)) {
|
|
35
|
+
if (existsSync(join(dir, '.git'))) {
|
|
36
|
+
return basename(dir);
|
|
37
|
+
}
|
|
38
|
+
dir = dirname(dir);
|
|
39
|
+
}
|
|
40
|
+
// 3. Avoid returning home dir basename as the name
|
|
41
|
+
const cwdBase = basename(cwd);
|
|
42
|
+
if (cwd === home || cwdBase === basename(home)) {
|
|
43
|
+
return 'home';
|
|
44
|
+
}
|
|
45
|
+
return cwdBase;
|
|
46
|
+
}
|
|
47
|
+
export function getRegistryPath() {
|
|
48
|
+
return join(homedir(), '.bookmark', 'registry.json');
|
|
49
|
+
}
|
|
50
|
+
function ensureRegistryDir() {
|
|
51
|
+
const dir = join(homedir(), '.bookmark');
|
|
52
|
+
if (!existsSync(dir))
|
|
53
|
+
mkdirSync(dir, { recursive: true });
|
|
54
|
+
}
|
|
55
|
+
export function loadRegistry() {
|
|
56
|
+
const path = getRegistryPath();
|
|
57
|
+
if (!existsSync(path)) {
|
|
58
|
+
return { version: REGISTRY_VERSION, last_updated: 0, snapshots: [] };
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(readFileSync(path, 'utf-8'));
|
|
62
|
+
if (!parsed.snapshots)
|
|
63
|
+
parsed.snapshots = [];
|
|
64
|
+
return parsed;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return { version: REGISTRY_VERSION, last_updated: 0, snapshots: [] };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function saveRegistry(registry) {
|
|
71
|
+
ensureRegistryDir();
|
|
72
|
+
registry.last_updated = Date.now();
|
|
73
|
+
writeFileSync(getRegistryPath(), JSON.stringify(registry, null, 2), 'utf-8');
|
|
74
|
+
}
|
|
75
|
+
export function appendToRegistry(snapshot, canonicalFile) {
|
|
76
|
+
try {
|
|
77
|
+
const registry = loadRegistry();
|
|
78
|
+
const entry = {
|
|
79
|
+
id: snapshot.snapshot_id,
|
|
80
|
+
timestamp: snapshot.timestamp,
|
|
81
|
+
trigger: snapshot.trigger,
|
|
82
|
+
project_path: snapshot.project_path,
|
|
83
|
+
project_name: resolveProjectName(snapshot.project_path),
|
|
84
|
+
canonical_file: canonicalFile,
|
|
85
|
+
files_changed_count: snapshot.files_changed.length,
|
|
86
|
+
};
|
|
87
|
+
// Dedupe by id, newest wins
|
|
88
|
+
registry.snapshots = [entry, ...registry.snapshots.filter(e => e.id !== entry.id)];
|
|
89
|
+
if (registry.snapshots.length > MAX_ENTRIES) {
|
|
90
|
+
registry.snapshots.length = MAX_ENTRIES;
|
|
91
|
+
}
|
|
92
|
+
registry.last_project = {
|
|
93
|
+
path: snapshot.project_path,
|
|
94
|
+
name: entry.project_name,
|
|
95
|
+
last_activity_at: snapshot.timestamp,
|
|
96
|
+
};
|
|
97
|
+
saveRegistry(registry);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Never break capture for registry bookkeeping
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export function touchLastProject(projectPath) {
|
|
104
|
+
try {
|
|
105
|
+
const registry = loadRegistry();
|
|
106
|
+
registry.last_project = {
|
|
107
|
+
path: projectPath,
|
|
108
|
+
name: resolveProjectName(projectPath),
|
|
109
|
+
last_activity_at: Date.now(),
|
|
110
|
+
};
|
|
111
|
+
saveRegistry(registry);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// Silent — never break restore for bookkeeping
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export function findById(id) {
|
|
118
|
+
const registry = loadRegistry();
|
|
119
|
+
return registry.snapshots.find(e => e.id === id) ?? null;
|
|
120
|
+
}
|
|
121
|
+
export function getLastProject() {
|
|
122
|
+
return loadRegistry().last_project ?? null;
|
|
123
|
+
}
|
|
124
|
+
/** Prune entries whose canonical_file is missing. Lazy cleanup on read paths. */
|
|
125
|
+
export function pruneStale() {
|
|
126
|
+
const registry = loadRegistry();
|
|
127
|
+
const live = registry.snapshots.filter(e => existsSync(e.canonical_file));
|
|
128
|
+
if (live.length !== registry.snapshots.length) {
|
|
129
|
+
registry.snapshots = live;
|
|
130
|
+
saveRegistry(registry);
|
|
131
|
+
}
|
|
132
|
+
return registry;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/restore/index.d.ts
CHANGED
|
@@ -7,7 +7,19 @@ export interface RestoreOptions {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Generate restoration context for a SessionStart hook.
|
|
10
|
-
*
|
|
10
|
+
*
|
|
11
|
+
* v0.4 adds:
|
|
12
|
+
* 1. BOOKMARK_IDENTITY parsing + repo_path validation
|
|
13
|
+
* 2. Home-scope pointer delegation to a canonical repo bookmark
|
|
14
|
+
* 3. Hard staleness block at 72h (instead of soft warning only)
|
|
15
|
+
*
|
|
16
|
+
* Cascade:
|
|
17
|
+
* 1. bookmark.context.md — if present and useful
|
|
18
|
+
* 1a. If identity scope=home + points_to_canonical, follow the pointer
|
|
19
|
+
* 1b. If identity scope=repo and path mismatch, prefix a warning
|
|
20
|
+
* 1c. If age >= STALENESS_HARD_BLOCK_HOURS, return staleness block
|
|
21
|
+
* 2. LATEST.md — file tracking fallback
|
|
22
|
+
* 3. Empty
|
|
11
23
|
*/
|
|
12
24
|
export declare function restoreContext(options: RestoreOptions): HookOutput;
|
|
13
25
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/restore/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/restore/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,aAAa,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,gBAAgB,GAAG,MAAM,GAAG,UAAU,CAAC;CACjD;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU,CAqFlE"}
|
package/dist/restore/index.js
CHANGED
|
@@ -1,67 +1,190 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, statSync, unlinkSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { readLatestMd, getSnapshotCount } from '../snapshot/storage.js';
|
|
4
|
+
import { readContextMd } from '../trails/reader.js';
|
|
5
|
+
import { parseIdentity, validateRepoIdentity, followPointer, } from '../trails/identity.js';
|
|
3
6
|
import { loadState, saveState, resetForNewSession, incrementCompaction } from '../threshold/state.js';
|
|
4
7
|
import { loadConfig, getStoragePath } from '../config.js';
|
|
8
|
+
import { touchLastProject } from '../registry.js';
|
|
9
|
+
/**
|
|
10
|
+
* Hours after which a bookmark is considered too stale to auto-restore.
|
|
11
|
+
* Below this threshold: restore with a soft warning.
|
|
12
|
+
* At or above: hard-block — return an empty context with guidance instead
|
|
13
|
+
* of risking a confident wrong start from stale content.
|
|
14
|
+
*/
|
|
15
|
+
const STALENESS_HARD_BLOCK_HOURS = 72;
|
|
16
|
+
const STALENESS_SOFT_WARN_HOURS = 24;
|
|
5
17
|
/**
|
|
6
18
|
* Generate restoration context for a SessionStart hook.
|
|
7
|
-
*
|
|
19
|
+
*
|
|
20
|
+
* v0.4 adds:
|
|
21
|
+
* 1. BOOKMARK_IDENTITY parsing + repo_path validation
|
|
22
|
+
* 2. Home-scope pointer delegation to a canonical repo bookmark
|
|
23
|
+
* 3. Hard staleness block at 72h (instead of soft warning only)
|
|
24
|
+
*
|
|
25
|
+
* Cascade:
|
|
26
|
+
* 1. bookmark.context.md — if present and useful
|
|
27
|
+
* 1a. If identity scope=home + points_to_canonical, follow the pointer
|
|
28
|
+
* 1b. If identity scope=repo and path mismatch, prefix a warning
|
|
29
|
+
* 1c. If age >= STALENESS_HARD_BLOCK_HOURS, return staleness block
|
|
30
|
+
* 2. LATEST.md — file tracking fallback
|
|
31
|
+
* 3. Empty
|
|
8
32
|
*/
|
|
9
33
|
export function restoreContext(options) {
|
|
10
34
|
const config = loadConfig(options.cwd);
|
|
11
35
|
const storagePath = getStoragePath(options.cwd, config);
|
|
12
36
|
const state = loadState(storagePath);
|
|
13
|
-
// Handle session state transitions
|
|
14
37
|
handleSessionTransition(storagePath, state, options, config.thresholds);
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
|
|
38
|
+
const stopRequestedPath = join(storagePath, '.stop-requested');
|
|
39
|
+
if (existsSync(stopRequestedPath)) {
|
|
40
|
+
try {
|
|
41
|
+
unlinkSync(stopRequestedPath);
|
|
42
|
+
}
|
|
43
|
+
catch { /* ignore */ }
|
|
18
44
|
}
|
|
19
|
-
|
|
20
|
-
if (options.source === 'resume') {
|
|
45
|
+
if (!config.restoreOnSessionStart)
|
|
21
46
|
return {};
|
|
47
|
+
if (options.source === 'resume')
|
|
48
|
+
return {};
|
|
49
|
+
// Primary: bookmark.context.md with identity-aware handling
|
|
50
|
+
const rawContextMd = readContextMd(storagePath);
|
|
51
|
+
if (rawContextMd && isContextMdUseful(rawContextMd)) {
|
|
52
|
+
const contextPath = join(storagePath, 'bookmark.context.md');
|
|
53
|
+
const { identity, bodyWithoutIdentity } = parseIdentity(rawContextMd);
|
|
54
|
+
// 1a. Home-scope pointer? Follow it to the canonical repo bookmark.
|
|
55
|
+
if (identity?.scope === 'home') {
|
|
56
|
+
const target = followPointer(identity);
|
|
57
|
+
if (target) {
|
|
58
|
+
const targetAge = target.staleness_hours ?? 0;
|
|
59
|
+
if (targetAge >= STALENESS_HARD_BLOCK_HOURS) {
|
|
60
|
+
trackRestore(storagePath, 0);
|
|
61
|
+
return { systemMessage: buildHardStalenessMessage(target.canonical_path, targetAge) };
|
|
62
|
+
}
|
|
63
|
+
// Strip identity block from target content for cleaner display
|
|
64
|
+
const { bodyWithoutIdentity: targetBody } = parseIdentity(target.content);
|
|
65
|
+
const header = buildPointerFollowHeader(identity, target.canonical_path, targetAge);
|
|
66
|
+
const message = `${header}\n\n${targetBody}`;
|
|
67
|
+
trackRestore(storagePath, message.length);
|
|
68
|
+
if (identity.points_to_canonical) {
|
|
69
|
+
touchLastProject(derivProjectFromCanonical(identity.points_to_canonical));
|
|
70
|
+
}
|
|
71
|
+
return { systemMessage: message };
|
|
72
|
+
}
|
|
73
|
+
// Pointer target missing — fall through to present the pointer body itself
|
|
74
|
+
}
|
|
75
|
+
// 1c. Hard staleness block
|
|
76
|
+
const ageHours = getAgeHours(contextPath);
|
|
77
|
+
if (ageHours !== null && ageHours >= STALENESS_HARD_BLOCK_HOURS) {
|
|
78
|
+
trackRestore(storagePath, 0);
|
|
79
|
+
return { systemMessage: buildHardStalenessMessage(contextPath, ageHours) };
|
|
80
|
+
}
|
|
81
|
+
// 1b. Path-mismatch warning for repo-scoped identities
|
|
82
|
+
const mismatchWarning = identity ? validateRepoIdentity(identity, options.cwd) : null;
|
|
83
|
+
// Soft staleness warning
|
|
84
|
+
const softWarning = ageHours !== null && ageHours >= STALENESS_SOFT_WARN_HOURS
|
|
85
|
+
? `[Note: This bookmark context is ${ageHours}h old and may be outdated.]`
|
|
86
|
+
: null;
|
|
87
|
+
const prefixes = [mismatchWarning, softWarning].filter(Boolean).join('\n\n');
|
|
88
|
+
const message = prefixes ? `${prefixes}\n\n${bodyWithoutIdentity}` : bodyWithoutIdentity;
|
|
89
|
+
trackRestore(storagePath, message.length);
|
|
90
|
+
touchLastProject(options.cwd);
|
|
91
|
+
return { systemMessage: message };
|
|
22
92
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (snapshotCount === 0) {
|
|
26
|
-
// First run — tell Claude that bookmark is active
|
|
27
|
-
return {
|
|
28
|
-
systemMessage: '[Bookmark: Active — no snapshots yet. Snapshots will be captured automatically ' +
|
|
29
|
-
'before compaction, on 20-minute intervals, and at session end.]\n\n' +
|
|
30
|
-
'Briefly let the user know that Bookmark is active and will start capturing context snapshots automatically.',
|
|
31
|
-
};
|
|
93
|
+
if (rawContextMd) {
|
|
94
|
+
trackBoilerplateCaught(storagePath);
|
|
32
95
|
}
|
|
33
|
-
//
|
|
96
|
+
// Fallback: LATEST.md
|
|
97
|
+
const snapshotCount = getSnapshotCount(storagePath);
|
|
34
98
|
const latestMd = readLatestMd(storagePath);
|
|
35
|
-
if (
|
|
36
|
-
|
|
99
|
+
if (latestMd) {
|
|
100
|
+
const message = buildFallbackRestoration(latestMd, snapshotCount);
|
|
101
|
+
trackRestore(storagePath, message.length);
|
|
102
|
+
touchLastProject(options.cwd);
|
|
103
|
+
return { systemMessage: message };
|
|
104
|
+
}
|
|
105
|
+
// No local bookmark and no LATEST.md — stay silent rather than inject
|
|
106
|
+
// another repo's context. The home-scope pointer at ~/.bookmark/bookmark.context.md
|
|
107
|
+
// is the supported way to redirect from an empty CWD to a canonical project.
|
|
108
|
+
return {};
|
|
109
|
+
}
|
|
110
|
+
/** Derive the project path from a canonical bookmark.context.md path. */
|
|
111
|
+
function derivProjectFromCanonical(canonicalPath) {
|
|
112
|
+
// .../<project>/.bookmark/bookmark.context.md → <project>
|
|
113
|
+
const marker = `/.bookmark/`;
|
|
114
|
+
const idx = canonicalPath.lastIndexOf(marker);
|
|
115
|
+
return idx > 0 ? canonicalPath.slice(0, idx) : canonicalPath;
|
|
116
|
+
}
|
|
117
|
+
/** Record a successful restore — chars injected / 4 ≈ tokens */
|
|
118
|
+
function trackRestore(storagePath, charCount) {
|
|
119
|
+
try {
|
|
120
|
+
const state = loadState(storagePath);
|
|
121
|
+
state.restores_performed = (state.restores_performed ?? 0) + 1;
|
|
122
|
+
state.tokens_injected = (state.tokens_injected ?? 0) + Math.round(charCount / 4);
|
|
123
|
+
saveState(storagePath, state);
|
|
124
|
+
}
|
|
125
|
+
catch { /* never break restore for tracking */ }
|
|
126
|
+
}
|
|
127
|
+
function trackBoilerplateCaught(storagePath) {
|
|
128
|
+
try {
|
|
129
|
+
const state = loadState(storagePath);
|
|
130
|
+
state.boilerplate_caught = (state.boilerplate_caught ?? 0) + 1;
|
|
131
|
+
saveState(storagePath, state);
|
|
37
132
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
133
|
+
catch { /* never break restore for tracking */ }
|
|
134
|
+
}
|
|
135
|
+
function isContextMdUseful(content) {
|
|
136
|
+
if (content.length < 200)
|
|
137
|
+
return false;
|
|
138
|
+
if (content.startsWith('[Bookmark Context') && !content.includes('## '))
|
|
139
|
+
return false;
|
|
140
|
+
const markers = ['## ', '**Task', '**Status', '**Progress', 'done', 'remaining', '- '];
|
|
141
|
+
return markers.some(m => content.includes(m));
|
|
142
|
+
}
|
|
143
|
+
function getAgeHours(path) {
|
|
144
|
+
try {
|
|
145
|
+
const mtime = statSync(path).mtimeMs;
|
|
146
|
+
return Math.round((Date.now() - mtime) / (1000 * 60 * 60));
|
|
43
147
|
}
|
|
44
|
-
|
|
45
|
-
return
|
|
46
|
-
systemMessage: latestMd,
|
|
47
|
-
};
|
|
148
|
+
catch {
|
|
149
|
+
return null;
|
|
48
150
|
}
|
|
49
|
-
// Default: system_message format
|
|
50
|
-
const systemMessage = buildRestorationMessage(latestMd, snapshotCount);
|
|
51
|
-
return { systemMessage };
|
|
52
151
|
}
|
|
53
|
-
function
|
|
152
|
+
function buildHardStalenessMessage(path, ageHours) {
|
|
153
|
+
return [
|
|
154
|
+
`[Bookmark: auto-restore BLOCKED — source is ${ageHours}h stale (threshold ${STALENESS_HARD_BLOCK_HOURS}h).]`,
|
|
155
|
+
'',
|
|
156
|
+
`The bookmark file at ${path} is too old to treat as current context.`,
|
|
157
|
+
'Stale auto-restore creates confident wrong starts — worse than no restore at all.',
|
|
158
|
+
'',
|
|
159
|
+
'To proceed, either:',
|
|
160
|
+
'- Run `/bookmark:list` and pick a specific snapshot explicitly',
|
|
161
|
+
'- Read the stale file manually if you still want its content: ' +
|
|
162
|
+
`\`cat "${path}"\``,
|
|
163
|
+
'- Ask the user what they were working on most recently',
|
|
164
|
+
].join('\n');
|
|
165
|
+
}
|
|
166
|
+
function buildPointerFollowHeader(pointer, canonicalPath, ageHours) {
|
|
167
|
+
const lines = [
|
|
168
|
+
`[Bookmark: followed home-scope pointer → repo-scope bookmark]`,
|
|
169
|
+
'',
|
|
170
|
+
`Canonical file: ${canonicalPath}`,
|
|
171
|
+
];
|
|
172
|
+
if (pointer.points_to_project) {
|
|
173
|
+
lines.push(`Project: ${pointer.points_to_project}`);
|
|
174
|
+
}
|
|
175
|
+
if (ageHours >= STALENESS_SOFT_WARN_HOURS) {
|
|
176
|
+
lines.push(`Age: ${ageHours}h (approaching staleness threshold of ${STALENESS_HARD_BLOCK_HOURS}h)`);
|
|
177
|
+
}
|
|
178
|
+
return lines.join('\n');
|
|
179
|
+
}
|
|
180
|
+
function buildFallbackRestoration(latestMd, snapshotCount) {
|
|
54
181
|
const lines = [];
|
|
55
182
|
lines.push('[Bookmark: Context recovered from previous session]');
|
|
56
183
|
lines.push('');
|
|
57
|
-
lines.push('Briefly notify the user that their prior session context has been recovered by Bookmark.');
|
|
58
|
-
lines.push('');
|
|
59
|
-
lines.push('## Prior Session Context (Bookmark)');
|
|
60
|
-
lines.push('');
|
|
61
184
|
lines.push(latestMd);
|
|
62
|
-
lines.push('');
|
|
63
185
|
if (snapshotCount > 1) {
|
|
64
|
-
lines.push(
|
|
186
|
+
lines.push('');
|
|
187
|
+
lines.push(`> ${snapshotCount} snapshots available. \`/bookmark:list\` for history.`);
|
|
65
188
|
}
|
|
66
189
|
return lines.join('\n');
|
|
67
190
|
}
|
|
@@ -72,16 +195,13 @@ function handleSessionTransition(storagePath, state, options, thresholds) {
|
|
|
72
195
|
switch (source) {
|
|
73
196
|
case 'startup':
|
|
74
197
|
case 'clear':
|
|
75
|
-
// New session — reset compaction count
|
|
76
198
|
updatedState = resetForNewSession(state, sessionId, thresholds);
|
|
77
199
|
break;
|
|
78
200
|
case 'compact':
|
|
79
|
-
// After compaction — increment compaction count
|
|
80
201
|
updatedState = incrementCompaction(state, thresholds);
|
|
81
202
|
updatedState.session_id = sessionId;
|
|
82
203
|
break;
|
|
83
204
|
case 'resume':
|
|
84
|
-
// Resuming — keep state, just update session ID if different
|
|
85
205
|
updatedState = { ...state, session_id: sessionId, last_event_time: Date.now() };
|
|
86
206
|
break;
|
|
87
207
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/restore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/restore/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register bookmark in Claude Code's installed_plugins.json.
|
|
3
|
+
* This is required for skill/command discovery — the symlink alone isn't enough.
|
|
4
|
+
*/
|
|
5
|
+
export declare function registerPlugin(): boolean;
|
|
1
6
|
/**
|
|
2
7
|
* Check if bookmark hooks are already configured in a project.
|
|
3
8
|
*/
|
|
@@ -9,8 +14,9 @@ export declare function isProjectConfigured(cwd: string): boolean;
|
|
|
9
14
|
*/
|
|
10
15
|
export declare function setupProject(cwd: string): string[];
|
|
11
16
|
/**
|
|
12
|
-
* Auto-bootstrap: silently configure
|
|
13
|
-
* Called at the top of CLI commands.
|
|
17
|
+
* Auto-bootstrap: silently configure storage if bookmark CLI runs in an unconfigured project.
|
|
18
|
+
* Called at the top of CLI commands. Creates .bookmark/ if needed.
|
|
19
|
+
* Works in any directory — not just npm projects.
|
|
14
20
|
*/
|
|
15
21
|
export declare function ensureProjectBootstrapped(cwd: string): void;
|
|
16
22
|
//# sourceMappingURL=auto-setup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-setup.d.ts","sourceRoot":"","sources":["../../src/setup/auto-setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auto-setup.d.ts","sourceRoot":"","sources":["../../src/setup/auto-setup.ts"],"names":[],"mappings":"AA4BA;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAqDxC;AA+CD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CASxD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CA2ClD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAgB3D"}
|