sealkeep 0.5.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/ARCHITECTURE.md +201 -0
- package/CHANGELOG.md +218 -0
- package/CONTROL_PLANE.md +86 -0
- package/LICENSE +34 -0
- package/README.md +249 -0
- package/THIRD_PARTY.md +22 -0
- package/THREAT_MODEL.md +107 -0
- package/dist/packages/vaultline-crypto/src/aead.d.ts +12 -0
- package/dist/packages/vaultline-crypto/src/aead.js +24 -0
- package/dist/packages/vaultline-crypto/src/chunk-access.d.ts +39 -0
- package/dist/packages/vaultline-crypto/src/chunk-access.js +93 -0
- package/dist/packages/vaultline-crypto/src/envelope.d.ts +71 -0
- package/dist/packages/vaultline-crypto/src/envelope.js +188 -0
- package/dist/packages/vaultline-crypto/src/format.d.ts +106 -0
- package/dist/packages/vaultline-crypto/src/format.js +43 -0
- package/dist/packages/vaultline-crypto/src/index.d.ts +5 -0
- package/dist/packages/vaultline-crypto/src/index.js +5 -0
- package/dist/packages/vaultline-crypto/src/recipients.d.ts +42 -0
- package/dist/packages/vaultline-crypto/src/recipients.js +129 -0
- package/dist/packages/vaultline-crypto/src/sha256-stream.d.ts +41 -0
- package/dist/packages/vaultline-crypto/src/sha256-stream.js +206 -0
- package/dist/packages/vaultline-crypto/src/stream.d.ts +139 -0
- package/dist/packages/vaultline-crypto/src/stream.js +477 -0
- package/dist/site/index.html +1542 -0
- package/dist/site.zip +0 -0
- package/dist/src/activity.d.ts +22 -0
- package/dist/src/activity.js +52 -0
- package/dist/src/adapters.d.ts +212 -0
- package/dist/src/adapters.js +533 -0
- package/dist/src/audit.d.ts +24 -0
- package/dist/src/audit.js +41 -0
- package/dist/src/autopilot.d.ts +77 -0
- package/dist/src/autopilot.js +148 -0
- package/dist/src/bip39-wordlist.d.ts +15 -0
- package/dist/src/bip39-wordlist.js +272 -0
- package/dist/src/branding.d.ts +31 -0
- package/dist/src/branding.js +31 -0
- package/dist/src/chunk-store.d.ts +142 -0
- package/dist/src/chunk-store.js +502 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +2035 -0
- package/dist/src/cloud.d.ts +434 -0
- package/dist/src/cloud.js +851 -0
- package/dist/src/control-plane/auth.d.ts +62 -0
- package/dist/src/control-plane/auth.js +123 -0
- package/dist/src/control-plane/server.d.ts +31 -0
- package/dist/src/control-plane/server.js +263 -0
- package/dist/src/control-plane/store.d.ts +101 -0
- package/dist/src/control-plane/store.js +82 -0
- package/dist/src/control-plane-cli.d.ts +2 -0
- package/dist/src/control-plane-cli.js +37 -0
- package/dist/src/control-plane-server.d.ts +10 -0
- package/dist/src/control-plane-server.js +11 -0
- package/dist/src/control-plane.d.ts +78 -0
- package/dist/src/control-plane.js +61 -0
- package/dist/src/crypto.d.ts +56 -0
- package/dist/src/crypto.js +132 -0
- package/dist/src/daemon.d.ts +52 -0
- package/dist/src/daemon.js +142 -0
- package/dist/src/dashboard-cli.d.ts +2 -0
- package/dist/src/dashboard-cli.js +20 -0
- package/dist/src/disk.d.ts +110 -0
- package/dist/src/disk.js +169 -0
- package/dist/src/doctor.d.ts +11 -0
- package/dist/src/doctor.js +198 -0
- package/dist/src/enroll.d.ts +27 -0
- package/dist/src/enroll.js +136 -0
- package/dist/src/errors.d.ts +26 -0
- package/dist/src/errors.js +23 -0
- package/dist/src/heartbeat.d.ts +89 -0
- package/dist/src/heartbeat.js +120 -0
- package/dist/src/index-sync.d.ts +53 -0
- package/dist/src/index-sync.js +147 -0
- package/dist/src/leakscan.d.ts +48 -0
- package/dist/src/leakscan.js +222 -0
- package/dist/src/local-api.d.ts +132 -0
- package/dist/src/local-api.js +1757 -0
- package/dist/src/managed-chunks.d.ts +55 -0
- package/dist/src/managed-chunks.js +108 -0
- package/dist/src/mcp-install.d.ts +52 -0
- package/dist/src/mcp-install.js +140 -0
- package/dist/src/mcp.d.ts +1 -0
- package/dist/src/mcp.js +59 -0
- package/dist/src/migrate.d.ts +35 -0
- package/dist/src/migrate.js +88 -0
- package/dist/src/mnemonic.d.ts +60 -0
- package/dist/src/mnemonic.js +134 -0
- package/dist/src/net.d.ts +2 -0
- package/dist/src/net.js +16 -0
- package/dist/src/notify.d.ts +46 -0
- package/dist/src/notify.js +84 -0
- package/dist/src/offload.d.ts +117 -0
- package/dist/src/offload.js +331 -0
- package/dist/src/onboarding.d.ts +10 -0
- package/dist/src/onboarding.js +44 -0
- package/dist/src/packages.d.ts +126 -0
- package/dist/src/packages.js +114 -0
- package/dist/src/passkey.d.ts +26 -0
- package/dist/src/passkey.js +54 -0
- package/dist/src/password-lock.d.ts +19 -0
- package/dist/src/password-lock.js +156 -0
- package/dist/src/paths.d.ts +9 -0
- package/dist/src/paths.js +24 -0
- package/dist/src/providers/gcs.d.ts +133 -0
- package/dist/src/providers/gcs.js +235 -0
- package/dist/src/providers/gdrive.d.ts +156 -0
- package/dist/src/providers/gdrive.js +335 -0
- package/dist/src/providers/index.d.ts +45 -0
- package/dist/src/providers/index.js +74 -0
- package/dist/src/providers/s3.d.ts +174 -0
- package/dist/src/providers/s3.js +345 -0
- package/dist/src/providers/sigv4.d.ts +78 -0
- package/dist/src/providers/sigv4.js +112 -0
- package/dist/src/queue.d.ts +185 -0
- package/dist/src/queue.js +286 -0
- package/dist/src/recovery.d.ts +40 -0
- package/dist/src/recovery.js +132 -0
- package/dist/src/rehydrate.d.ts +43 -0
- package/dist/src/rehydrate.js +66 -0
- package/dist/src/restore.d.ts +34 -0
- package/dist/src/restore.js +80 -0
- package/dist/src/retention.d.ts +251 -0
- package/dist/src/retention.js +446 -0
- package/dist/src/rotate.d.ts +47 -0
- package/dist/src/rotate.js +95 -0
- package/dist/src/search.d.ts +147 -0
- package/dist/src/search.js +677 -0
- package/dist/src/secrets.d.ts +86 -0
- package/dist/src/secrets.js +220 -0
- package/dist/src/service.d.ts +73 -0
- package/dist/src/service.js +197 -0
- package/dist/src/share.d.ts +34 -0
- package/dist/src/share.js +68 -0
- package/dist/src/spool.d.ts +97 -0
- package/dist/src/spool.js +213 -0
- package/dist/src/start-tui.d.ts +17 -0
- package/dist/src/start-tui.js +113 -0
- package/dist/src/start.d.ts +75 -0
- package/dist/src/start.js +101 -0
- package/dist/src/storage-setup.d.ts +49 -0
- package/dist/src/storage-setup.js +222 -0
- package/dist/src/storage-targets.d.ts +40 -0
- package/dist/src/storage-targets.js +147 -0
- package/dist/src/stream-to-cloud.d.ts +76 -0
- package/dist/src/stream-to-cloud.js +820 -0
- package/dist/src/sync-rules.d.ts +85 -0
- package/dist/src/sync-rules.js +125 -0
- package/dist/src/trash.d.ts +15 -0
- package/dist/src/trash.js +63 -0
- package/dist/src/tui.d.ts +18 -0
- package/dist/src/tui.js +179 -0
- package/dist/src/types.d.ts +191 -0
- package/dist/src/types.js +3 -0
- package/dist/src/ui-server.d.ts +187 -0
- package/dist/src/ui-server.js +293 -0
- package/dist/src/ui.d.ts +41 -0
- package/dist/src/ui.js +102 -0
- package/dist/src/update.d.ts +30 -0
- package/dist/src/update.js +56 -0
- package/dist/src/upload.d.ts +46 -0
- package/dist/src/upload.js +80 -0
- package/dist/src/vault.d.ts +208 -0
- package/dist/src/vault.js +812 -0
- package/dist/src/watcher.d.ts +34 -0
- package/dist/src/watcher.js +121 -0
- package/dist/src/worker.d.ts +52 -0
- package/dist/src/worker.js +190 -0
- package/package.json +65 -0
- package/web/app.js +1372 -0
- package/web/index.html +476 -0
- package/web/rail.js +308 -0
- package/web/retention.html +17 -0
- package/web/rules-view.js +249 -0
- package/web/sessions-view.js +448 -0
- package/web/sessions.html +17 -0
- package/web/setup-api.js +181 -0
- package/web/setup-logic.js +394 -0
- package/web/setup.html +419 -0
- package/web/setup.js +697 -0
- package/web/style.css +990 -0
package/dist/site.zip
ADDED
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type ActivityVerdict = {
|
|
2
|
+
active: boolean;
|
|
3
|
+
reason: string;
|
|
4
|
+
};
|
|
5
|
+
export type ActivityOptions = {
|
|
6
|
+
/** A file touched within this window is treated as in use. */
|
|
7
|
+
quietMs?: number;
|
|
8
|
+
now?: number;
|
|
9
|
+
/** Injected for tests; defaults to a real `lsof` probe where available. */
|
|
10
|
+
openHandles?: (path: string) => Promise<boolean | null>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Reports whether any process currently holds the file open.
|
|
14
|
+
* Returns `null` when it cannot tell, which callers must treat as "assume active".
|
|
15
|
+
*/
|
|
16
|
+
export declare function probeOpenHandles(path: string): Promise<boolean | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Conservative activity check. Anything uncertain counts as active, because the
|
|
19
|
+
* cost of a false "idle" is deleting a session a user is still working in, while
|
|
20
|
+
* the cost of a false "active" is only a delayed reclamation.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isSourceActive(path: string, options?: ActivityOptions): Promise<ActivityVerdict>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { platform } from "node:os";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
const run = promisify(execFile);
|
|
6
|
+
/**
|
|
7
|
+
* Reports whether any process currently holds the file open.
|
|
8
|
+
* Returns `null` when it cannot tell, which callers must treat as "assume active".
|
|
9
|
+
*/
|
|
10
|
+
export async function probeOpenHandles(path) {
|
|
11
|
+
if (platform() === "win32")
|
|
12
|
+
return null;
|
|
13
|
+
try {
|
|
14
|
+
const { stdout } = await run("lsof", ["-t", "--", path], { timeout: 3000 });
|
|
15
|
+
return stdout.trim().length > 0;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
// lsof exits non-zero with no output when nothing holds the file open.
|
|
19
|
+
const failure = error;
|
|
20
|
+
if (failure.code === 1 && (failure.stdout ?? "").trim() === "")
|
|
21
|
+
return false;
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Conservative activity check. Anything uncertain counts as active, because the
|
|
27
|
+
* cost of a false "idle" is deleting a session a user is still working in, while
|
|
28
|
+
* the cost of a false "active" is only a delayed reclamation.
|
|
29
|
+
*/
|
|
30
|
+
export async function isSourceActive(path, options = {}) {
|
|
31
|
+
const quietMs = options.quietMs ?? 15 * 60_000;
|
|
32
|
+
const now = options.now ?? Date.now();
|
|
33
|
+
let info;
|
|
34
|
+
try {
|
|
35
|
+
info = await stat(path);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return { active: true, reason: "source is unreadable, so its state cannot be confirmed" };
|
|
39
|
+
}
|
|
40
|
+
if (!info.isFile())
|
|
41
|
+
return { active: true, reason: "source is not a regular file" };
|
|
42
|
+
const age = now - info.mtimeMs;
|
|
43
|
+
if (age < quietMs)
|
|
44
|
+
return { active: true, reason: `modified ${Math.round(age / 1000)}s ago, inside the ${Math.round(quietMs / 1000)}s quiet window` };
|
|
45
|
+
const probe = options.openHandles ?? probeOpenHandles;
|
|
46
|
+
const open = await probe(path);
|
|
47
|
+
if (open === null)
|
|
48
|
+
return { active: true, reason: "could not determine whether a process holds the file open" };
|
|
49
|
+
if (open)
|
|
50
|
+
return { active: true, reason: "a process currently holds the file open" };
|
|
51
|
+
return { active: false, reason: `idle for ${Math.round(age / 60_000)} minutes with no open handle` };
|
|
52
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agents whose sessions Sealkeep archives.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately narrower than `SetupAgentId`: every id here needs a transcript
|
|
5
|
+
* root the watcher can follow *and* a native restore root (`NATIVE_ROOTS` in
|
|
6
|
+
* restore.ts), and an id with neither would produce an agent the watcher
|
|
7
|
+
* queues and the restorer cannot put back.
|
|
8
|
+
*/
|
|
9
|
+
export type AgentId = "codex" | "claude";
|
|
10
|
+
/**
|
|
11
|
+
* Every agent first-run setup can find on this machine.
|
|
12
|
+
*
|
|
13
|
+
* A superset of `AgentId`, because finding an agent and reporting where its
|
|
14
|
+
* hooks live costs nothing but a `stat`, while archiving it needs an adapter
|
|
15
|
+
* that knows its session store. Reporting the difference is the point — see
|
|
16
|
+
* `archivable` below.
|
|
17
|
+
*/
|
|
18
|
+
export type SetupAgentId = AgentId | "cursor" | "gemini" | "windsurf" | "antigravity";
|
|
19
|
+
export type AgentInstall = {
|
|
20
|
+
agent: AgentId;
|
|
21
|
+
root: string;
|
|
22
|
+
transcriptRoots: string[];
|
|
23
|
+
detected: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** Every id `detectSetupAgents` reports on, in the order a setup page should show them. */
|
|
26
|
+
export declare const SETUP_AGENT_IDS: SetupAgentId[];
|
|
27
|
+
/** The subset with a session adapter. Mirrors `AgentId` at runtime for schema use. */
|
|
28
|
+
export declare const ARCHIVING_AGENT_IDS: readonly ["codex", "claude"];
|
|
29
|
+
/** Narrows a setup id to an archiving one, so callers prove the subset rather than casting to it. */
|
|
30
|
+
export declare function isArchivingAgent(agent: SetupAgentId): agent is AgentId;
|
|
31
|
+
/** Detect only well-known local roots; it never reads transcript contents. */
|
|
32
|
+
export declare function detectAgents(home?: string): Promise<AgentInstall[]>;
|
|
33
|
+
export type TranscriptCandidate = {
|
|
34
|
+
agent: AgentId;
|
|
35
|
+
path: string;
|
|
36
|
+
bytes: number;
|
|
37
|
+
modifiedAt: string;
|
|
38
|
+
/**
|
|
39
|
+
* The project this session ran in, when its metadata says — null when
|
|
40
|
+
* nothing does. Optional because a candidate is valid before resolution
|
|
41
|
+
* (`walkJsonl` and `measureSessions` never need it); everything
|
|
42
|
+
* `findTranscripts` returns has both fields resolved.
|
|
43
|
+
*/
|
|
44
|
+
project?: string | null;
|
|
45
|
+
/** The working directory behind `project`, best-effort. See the decode caveat on `claudeProjectFromPath`. */
|
|
46
|
+
projectPath?: string | null;
|
|
47
|
+
};
|
|
48
|
+
export type ProjectIdentity = {
|
|
49
|
+
project: string | null;
|
|
50
|
+
projectPath: string | null;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Claude Code names each transcript directory after the session's cwd with the
|
|
54
|
+
* separators flattened to dashes ("/Users/x/repo" → "-Users-x-repo"). The
|
|
55
|
+
* decode is lossy by construction — a dash that was part of a directory name
|
|
56
|
+
* is indistinguishable from one that was a separator — so `project` is the
|
|
57
|
+
* final segment, which is the part a person recognises, and `projectPath` is
|
|
58
|
+
* the naive re-expansion, kept because "which /Users/… did this come from" is
|
|
59
|
+
* still worth answering approximately.
|
|
60
|
+
*/
|
|
61
|
+
export declare function claudeProjectFromPath(path: string): ProjectIdentity;
|
|
62
|
+
export declare function codexProjectFromRollout(path: string, modifiedAt: string): Promise<ProjectIdentity>;
|
|
63
|
+
/**
|
|
64
|
+
* Lists metadata for recent transcripts, never their conversations. The one
|
|
65
|
+
* read into a file is the codex rollout's first line, which is the session's
|
|
66
|
+
* own metadata record — what was said in the session stays unread.
|
|
67
|
+
*/
|
|
68
|
+
export declare function findTranscripts(agent: AgentId, home?: string, limit?: number): Promise<TranscriptCandidate[]>;
|
|
69
|
+
/**
|
|
70
|
+
* The one command a Sealkeep hook ever runs, built in one place.
|
|
71
|
+
*
|
|
72
|
+
* Detection matches installed hooks on the `hook enqueue --agent <id>` part of
|
|
73
|
+
* it, so the command and the thing that recognises it can never disagree about
|
|
74
|
+
* what a Sealkeep hook looks like.
|
|
75
|
+
*/
|
|
76
|
+
export declare function hookCommand(agent: SetupAgentId, executable?: string, dataDir?: string): string;
|
|
77
|
+
/** The substring that identifies a Sealkeep hook for one agent, wherever it is written. */
|
|
78
|
+
export declare function hookMarker(agent: SetupAgentId): string;
|
|
79
|
+
/**
|
|
80
|
+
* Returns a reviewable config fragment. It is intentionally not installed into
|
|
81
|
+
* an agent's settings: users must review and merge it themselves. The hook only
|
|
82
|
+
* enqueues local work, so it needs no recovery phrase and no network access.
|
|
83
|
+
*/
|
|
84
|
+
export declare function hookConfig(agent: AgentId, executable?: string, dataDir?: string): {
|
|
85
|
+
description: string;
|
|
86
|
+
hooks: {
|
|
87
|
+
SessionEnd: {
|
|
88
|
+
hooks: {
|
|
89
|
+
type: string;
|
|
90
|
+
command: string;
|
|
91
|
+
timeout: number;
|
|
92
|
+
statusMessage: string;
|
|
93
|
+
}[];
|
|
94
|
+
}[];
|
|
95
|
+
PostCompact: {
|
|
96
|
+
hooks: {
|
|
97
|
+
type: string;
|
|
98
|
+
command: string;
|
|
99
|
+
timeout: number;
|
|
100
|
+
}[];
|
|
101
|
+
}[];
|
|
102
|
+
SessionStart: {
|
|
103
|
+
matcher: string;
|
|
104
|
+
hooks: {
|
|
105
|
+
type: "command";
|
|
106
|
+
command: string;
|
|
107
|
+
timeout: number;
|
|
108
|
+
}[];
|
|
109
|
+
}[];
|
|
110
|
+
};
|
|
111
|
+
_vaultlineNote: string;
|
|
112
|
+
} | {
|
|
113
|
+
hooks: {
|
|
114
|
+
SessionEnd: {
|
|
115
|
+
hooks: {
|
|
116
|
+
type: string;
|
|
117
|
+
command: string;
|
|
118
|
+
timeout: number;
|
|
119
|
+
}[];
|
|
120
|
+
}[];
|
|
121
|
+
SessionStart: {
|
|
122
|
+
matcher: string;
|
|
123
|
+
hooks: {
|
|
124
|
+
type: "command";
|
|
125
|
+
command: string;
|
|
126
|
+
timeout: number;
|
|
127
|
+
}[];
|
|
128
|
+
}[];
|
|
129
|
+
PostCompact?: undefined;
|
|
130
|
+
};
|
|
131
|
+
_vaultlineNote: string;
|
|
132
|
+
description?: undefined;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* What first-run setup knows about one agent.
|
|
136
|
+
*
|
|
137
|
+
* `status` is the single field a page should branch on; the rest is the
|
|
138
|
+
* evidence behind it, so nothing has to be re-derived by a second reader.
|
|
139
|
+
*/
|
|
140
|
+
export type AgentHookStatus =
|
|
141
|
+
/** No root directory: this agent is not on the machine. */
|
|
142
|
+
"not-installed"
|
|
143
|
+
/** Sealkeep's hook is already in this agent's config. */
|
|
144
|
+
| "hooked"
|
|
145
|
+
/** Found, but its hook file can neither be written nor created. */
|
|
146
|
+
| "found-but-unwritable"
|
|
147
|
+
/** Found and writable, but this build cannot process a hook from it. */
|
|
148
|
+
| "found-but-unsupported"
|
|
149
|
+
/** Found and writable, but its config is a format this build cannot merge into. */
|
|
150
|
+
| "manual-merge-required"
|
|
151
|
+
/** Found, writable, and hookable right now. */
|
|
152
|
+
| "ready";
|
|
153
|
+
export type AgentDetection = {
|
|
154
|
+
agent: SetupAgentId;
|
|
155
|
+
label: string;
|
|
156
|
+
detected: boolean;
|
|
157
|
+
root: string;
|
|
158
|
+
hookFile: string;
|
|
159
|
+
hookFileFormat: "json" | "toml";
|
|
160
|
+
hookFileExists: boolean;
|
|
161
|
+
hookFileWritable: boolean;
|
|
162
|
+
hooksInstalled: boolean;
|
|
163
|
+
/** True when Sealkeep can archive this agent's sessions, not merely find it. */
|
|
164
|
+
archivable: boolean;
|
|
165
|
+
/** Disk this agent's transcripts occupy right now. Zero for anything not archivable. */
|
|
166
|
+
sessionBytes: number;
|
|
167
|
+
sessionCount: number;
|
|
168
|
+
status: AgentHookStatus;
|
|
169
|
+
/** Why the status is what it is, whenever it is not simply "ready". */
|
|
170
|
+
note: string | null;
|
|
171
|
+
};
|
|
172
|
+
export declare function detectSetupAgents(home?: string): Promise<AgentDetection[]>;
|
|
173
|
+
export type HookInstallOutcome = {
|
|
174
|
+
agent: SetupAgentId;
|
|
175
|
+
/** True only when the agent's own config now carries the hook. */
|
|
176
|
+
installed: boolean;
|
|
177
|
+
hookFile: string;
|
|
178
|
+
/** True when the hook was already there and nothing was written. */
|
|
179
|
+
alreadyInstalled: boolean;
|
|
180
|
+
/** The copy taken before the agent's config was edited, when one was needed. */
|
|
181
|
+
backupPath: string | null;
|
|
182
|
+
/** A reviewable document under the vault, for a config this build will not edit. */
|
|
183
|
+
fragmentPath: string | null;
|
|
184
|
+
/** Why `installed` is false. Null when it is true. */
|
|
185
|
+
reason: string | null;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Installs Sealkeep's hook into the agents it can, and says why for the rest.
|
|
189
|
+
*
|
|
190
|
+
* Idempotent by construction: a second call finds its own marker and writes
|
|
191
|
+
* nothing. Nothing here reports `installed: true` unless the agent's own config
|
|
192
|
+
* now contains the command — a fragment written for manual review is reported
|
|
193
|
+
* as what it is.
|
|
194
|
+
*/
|
|
195
|
+
export declare function installAgentHooks(agents: readonly SetupAgentId[], options: {
|
|
196
|
+
dataDir: string;
|
|
197
|
+
home?: string;
|
|
198
|
+
executable?: string;
|
|
199
|
+
}): Promise<HookInstallOutcome[]>;
|
|
200
|
+
/** A normalized archive intent. Sealkeep reads lifecycle metadata only, never transcript bodies. */
|
|
201
|
+
export type HookEvent = {
|
|
202
|
+
agent: AgentId;
|
|
203
|
+
event: string;
|
|
204
|
+
sourcePath: string;
|
|
205
|
+
sessionId?: string;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Accepts Codex `SessionEnd`/`PostCompact` and Claude `SessionEnd` payloads. Unknown
|
|
209
|
+
* vendor fields are ignored rather than parsed, so a schema change cannot break preservation.
|
|
210
|
+
*/
|
|
211
|
+
export declare function hookEventFromStdin(agent: AgentId, stdin: string): Promise<HookEvent>;
|
|
212
|
+
export declare function transcriptPathFromHook(stdin: string, agent?: AgentId): Promise<string>;
|