sessionlog 0.0.1
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/LICENSE +21 -0
- package/README.md +388 -0
- package/dist/agent/agents/claude-code.d.ts +76 -0
- package/dist/agent/agents/claude-code.d.ts.map +1 -0
- package/dist/agent/agents/claude-code.js +769 -0
- package/dist/agent/agents/claude-code.js.map +1 -0
- package/dist/agent/agents/cursor.d.ts +35 -0
- package/dist/agent/agents/cursor.d.ts.map +1 -0
- package/dist/agent/agents/cursor.js +294 -0
- package/dist/agent/agents/cursor.js.map +1 -0
- package/dist/agent/agents/gemini-cli.d.ts +62 -0
- package/dist/agent/agents/gemini-cli.d.ts.map +1 -0
- package/dist/agent/agents/gemini-cli.js +474 -0
- package/dist/agent/agents/gemini-cli.js.map +1 -0
- package/dist/agent/agents/opencode.d.ts +100 -0
- package/dist/agent/agents/opencode.d.ts.map +1 -0
- package/dist/agent/agents/opencode.js +423 -0
- package/dist/agent/agents/opencode.js.map +1 -0
- package/dist/agent/registry.d.ts +54 -0
- package/dist/agent/registry.d.ts.map +1 -0
- package/dist/agent/registry.js +123 -0
- package/dist/agent/registry.js.map +1 -0
- package/dist/agent/session-types.d.ts +45 -0
- package/dist/agent/session-types.d.ts.map +1 -0
- package/dist/agent/session-types.js +48 -0
- package/dist/agent/session-types.js.map +1 -0
- package/dist/agent/types.d.ts +126 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +40 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +425 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/clean.d.ts +30 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +98 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/disable.d.ts +23 -0
- package/dist/commands/disable.d.ts.map +1 -0
- package/dist/commands/disable.js +57 -0
- package/dist/commands/disable.js.map +1 -0
- package/dist/commands/doctor.d.ts +43 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +97 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/enable.d.ts +37 -0
- package/dist/commands/enable.d.ts.map +1 -0
- package/dist/commands/enable.js +133 -0
- package/dist/commands/enable.js.map +1 -0
- package/dist/commands/explain.d.ts +68 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +182 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/reset.d.ts +23 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +68 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/resume.d.ts +42 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +133 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/rewind.d.ts +34 -0
- package/dist/commands/rewind.d.ts.map +1 -0
- package/dist/commands/rewind.js +155 -0
- package/dist/commands/rewind.js.map +1 -0
- package/dist/commands/status.d.ts +51 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +112 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config.d.ts +40 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +127 -0
- package/dist/config.js.map +1 -0
- package/dist/git-operations.d.ts +191 -0
- package/dist/git-operations.d.ts.map +1 -0
- package/dist/git-operations.js +462 -0
- package/dist/git-operations.js.map +1 -0
- package/dist/hooks/git-hooks.d.ts +22 -0
- package/dist/hooks/git-hooks.d.ts.map +1 -0
- package/dist/hooks/git-hooks.js +139 -0
- package/dist/hooks/git-hooks.js.map +1 -0
- package/dist/hooks/lifecycle.d.ts +21 -0
- package/dist/hooks/lifecycle.d.ts.map +1 -0
- package/dist/hooks/lifecycle.js +179 -0
- package/dist/hooks/lifecycle.js.map +1 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/security/redaction.d.ts +35 -0
- package/dist/security/redaction.d.ts.map +1 -0
- package/dist/security/redaction.js +239 -0
- package/dist/security/redaction.js.map +1 -0
- package/dist/session/state-machine.d.ts +90 -0
- package/dist/session/state-machine.d.ts.map +1 -0
- package/dist/session/state-machine.js +345 -0
- package/dist/session/state-machine.js.map +1 -0
- package/dist/store/checkpoint-store.d.ts +59 -0
- package/dist/store/checkpoint-store.d.ts.map +1 -0
- package/dist/store/checkpoint-store.js +321 -0
- package/dist/store/checkpoint-store.js.map +1 -0
- package/dist/store/native-store.d.ts +14 -0
- package/dist/store/native-store.d.ts.map +1 -0
- package/dist/store/native-store.js +159 -0
- package/dist/store/native-store.js.map +1 -0
- package/dist/store/provider-types.d.ts +78 -0
- package/dist/store/provider-types.d.ts.map +1 -0
- package/dist/store/provider-types.js +12 -0
- package/dist/store/provider-types.js.map +1 -0
- package/dist/store/session-store.d.ts +36 -0
- package/dist/store/session-store.d.ts.map +1 -0
- package/dist/store/session-store.js +193 -0
- package/dist/store/session-store.js.map +1 -0
- package/dist/strategy/attribution.d.ts +39 -0
- package/dist/strategy/attribution.d.ts.map +1 -0
- package/dist/strategy/attribution.js +225 -0
- package/dist/strategy/attribution.js.map +1 -0
- package/dist/strategy/common.d.ts +57 -0
- package/dist/strategy/common.d.ts.map +1 -0
- package/dist/strategy/common.js +156 -0
- package/dist/strategy/common.js.map +1 -0
- package/dist/strategy/content-overlap.d.ts +33 -0
- package/dist/strategy/content-overlap.d.ts.map +1 -0
- package/dist/strategy/content-overlap.js +176 -0
- package/dist/strategy/content-overlap.js.map +1 -0
- package/dist/strategy/manual-commit.d.ts +36 -0
- package/dist/strategy/manual-commit.d.ts.map +1 -0
- package/dist/strategy/manual-commit.js +717 -0
- package/dist/strategy/manual-commit.js.map +1 -0
- package/dist/strategy/types.d.ts +163 -0
- package/dist/strategy/types.d.ts.map +1 -0
- package/dist/strategy/types.js +48 -0
- package/dist/strategy/types.js.map +1 -0
- package/dist/summarize/claude-generator.d.ts +25 -0
- package/dist/summarize/claude-generator.d.ts.map +1 -0
- package/dist/summarize/claude-generator.js +87 -0
- package/dist/summarize/claude-generator.js.map +1 -0
- package/dist/summarize/summarize.d.ts +52 -0
- package/dist/summarize/summarize.d.ts.map +1 -0
- package/dist/summarize/summarize.js +335 -0
- package/dist/summarize/summarize.js.map +1 -0
- package/dist/types.d.ts +293 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +94 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/chunk-files.d.ts +25 -0
- package/dist/utils/chunk-files.d.ts.map +1 -0
- package/dist/utils/chunk-files.js +47 -0
- package/dist/utils/chunk-files.js.map +1 -0
- package/dist/utils/commit-message.d.ts +11 -0
- package/dist/utils/commit-message.d.ts.map +1 -0
- package/dist/utils/commit-message.js +54 -0
- package/dist/utils/commit-message.js.map +1 -0
- package/dist/utils/detect-agent.d.ts +19 -0
- package/dist/utils/detect-agent.d.ts.map +1 -0
- package/dist/utils/detect-agent.js +34 -0
- package/dist/utils/detect-agent.js.map +1 -0
- package/dist/utils/hook-managers.d.ts +24 -0
- package/dist/utils/hook-managers.d.ts.map +1 -0
- package/dist/utils/hook-managers.js +96 -0
- package/dist/utils/hook-managers.js.map +1 -0
- package/dist/utils/ide-tags.d.ts +12 -0
- package/dist/utils/ide-tags.d.ts.map +1 -0
- package/dist/utils/ide-tags.js +30 -0
- package/dist/utils/ide-tags.js.map +1 -0
- package/dist/utils/paths.d.ts +32 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +55 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/preview-rewind.d.ts +23 -0
- package/dist/utils/preview-rewind.d.ts.map +1 -0
- package/dist/utils/preview-rewind.js +63 -0
- package/dist/utils/preview-rewind.js.map +1 -0
- package/dist/utils/rewind-conflict.d.ts +52 -0
- package/dist/utils/rewind-conflict.d.ts.map +1 -0
- package/dist/utils/rewind-conflict.js +79 -0
- package/dist/utils/rewind-conflict.js.map +1 -0
- package/dist/utils/shadow-branch.d.ts +44 -0
- package/dist/utils/shadow-branch.d.ts.map +1 -0
- package/dist/utils/shadow-branch.js +93 -0
- package/dist/utils/shadow-branch.js.map +1 -0
- package/dist/utils/string-utils.d.ts +24 -0
- package/dist/utils/string-utils.d.ts.map +1 -0
- package/dist/utils/string-utils.js +47 -0
- package/dist/utils/string-utils.js.map +1 -0
- package/dist/utils/todo-extract.d.ts +52 -0
- package/dist/utils/todo-extract.d.ts.map +1 -0
- package/dist/utils/todo-extract.js +167 -0
- package/dist/utils/todo-extract.js.map +1 -0
- package/dist/utils/trailers.d.ts +36 -0
- package/dist/utils/trailers.d.ts.map +1 -0
- package/dist/utils/trailers.js +148 -0
- package/dist/utils/trailers.js.map +1 -0
- package/dist/utils/transcript-parse.d.ts +57 -0
- package/dist/utils/transcript-parse.d.ts.map +1 -0
- package/dist/utils/transcript-parse.js +126 -0
- package/dist/utils/transcript-parse.js.map +1 -0
- package/dist/utils/transcript-timestamp.d.ts +22 -0
- package/dist/utils/transcript-timestamp.d.ts.map +1 -0
- package/dist/utils/transcript-timestamp.js +56 -0
- package/dist/utils/transcript-timestamp.js.map +1 -0
- package/dist/utils/tree-ops.d.ts +47 -0
- package/dist/utils/tree-ops.d.ts.map +1 -0
- package/dist/utils/tree-ops.js +145 -0
- package/dist/utils/tree-ops.js.map +1 -0
- package/dist/utils/tty.d.ts +25 -0
- package/dist/utils/tty.d.ts.map +1 -0
- package/dist/utils/tty.js +70 -0
- package/dist/utils/tty.js.map +1 -0
- package/dist/utils/validation.d.ts +31 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +59 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/worktree.d.ts +16 -0
- package/dist/utils/worktree.d.ts.map +1 -0
- package/dist/utils/worktree.js +50 -0
- package/dist/utils/worktree.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalized Agent Session Type
|
|
3
|
+
*
|
|
4
|
+
* A shared, agent-agnostic representation of a coding session with typed
|
|
5
|
+
* entries. This provides a uniform interface for cross-agent operations.
|
|
6
|
+
*
|
|
7
|
+
* Ported from Go: agent/session.go
|
|
8
|
+
*/
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Implementation
|
|
11
|
+
// ============================================================================
|
|
12
|
+
export function createAgentSession(agentType, sessionID, entries) {
|
|
13
|
+
return {
|
|
14
|
+
agentType,
|
|
15
|
+
sessionID,
|
|
16
|
+
entries,
|
|
17
|
+
getLastUserPrompt() {
|
|
18
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
19
|
+
if (entries[i].type === "user" /* EntryType.User */ && entries[i].text) {
|
|
20
|
+
return entries[i].text;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return '';
|
|
24
|
+
},
|
|
25
|
+
getUserPrompts() {
|
|
26
|
+
return entries.filter((e) => e.type === "user" /* EntryType.User */ && e.text).map((e) => e.text);
|
|
27
|
+
},
|
|
28
|
+
length() {
|
|
29
|
+
return entries.length;
|
|
30
|
+
},
|
|
31
|
+
truncateAtUUID(uuid) {
|
|
32
|
+
const idx = entries.findIndex((e) => e.uuid === uuid);
|
|
33
|
+
if (idx === -1)
|
|
34
|
+
return createAgentSession(agentType, sessionID, entries);
|
|
35
|
+
return createAgentSession(agentType, sessionID, entries.slice(0, idx + 1));
|
|
36
|
+
},
|
|
37
|
+
findToolResultByUUID(uuid) {
|
|
38
|
+
return entries.find((e) => e.type === "tool" /* EntryType.Tool */ && e.uuid === uuid);
|
|
39
|
+
},
|
|
40
|
+
getEntriesByType(type) {
|
|
41
|
+
return entries.filter((e) => e.type === type);
|
|
42
|
+
},
|
|
43
|
+
slice(fromOffset) {
|
|
44
|
+
return entries.slice(fromOffset);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=session-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-types.js","sourceRoot":"","sources":["../../src/agent/session-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAwDH,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,UAAU,kBAAkB,CAChC,SAAoB,EACpB,SAAiB,EACjB,OAAuB;IAEvB,OAAO;QACL,SAAS;QACT,SAAS;QACT,OAAO;QAEP,iBAAiB;YACf,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,gCAAmB,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC1D,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,IAAK,CAAC;gBAC1B,CAAC;YACH,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,cAAc;YACZ,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,gCAAmB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC;QACxF,CAAC;QAED,MAAM;YACJ,OAAO,OAAO,CAAC,MAAM,CAAC;QACxB,CAAC;QAED,cAAc,CAAC,IAAY;YACzB,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YACtD,IAAI,GAAG,KAAK,CAAC,CAAC;gBAAE,OAAO,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;YACzE,OAAO,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QAED,oBAAoB,CAAC,IAAY;YAC/B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,gCAAmB,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC3E,CAAC;QAED,gBAAgB,CAAC,IAAe;YAC9B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAChD,CAAC;QAED,KAAK,CAAC,UAAkB;YACtB,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Types
|
|
3
|
+
*
|
|
4
|
+
* Interfaces for AI agent integrations. Each supported agent
|
|
5
|
+
* (Claude Code, Cursor, Gemini CLI, OpenCode) implements these
|
|
6
|
+
* interfaces to participate in the Entire session tracking lifecycle.
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentName, AgentType, HookInput, Event, TokenUsage } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Agent represents a supported AI coding agent
|
|
11
|
+
*/
|
|
12
|
+
export interface Agent {
|
|
13
|
+
/** Registry key (e.g., 'claude-code') */
|
|
14
|
+
readonly name: AgentName;
|
|
15
|
+
/** Human-readable type (e.g., 'Claude Code') */
|
|
16
|
+
readonly type: AgentType;
|
|
17
|
+
/** Description of the agent */
|
|
18
|
+
readonly description: string;
|
|
19
|
+
/** Whether this agent integration is in preview */
|
|
20
|
+
readonly isPreview: boolean;
|
|
21
|
+
/** Directories that should never be modified/deleted by Entire */
|
|
22
|
+
readonly protectedDirs: string[];
|
|
23
|
+
/** Check if this agent is present in the current environment */
|
|
24
|
+
detectPresence(cwd?: string): Promise<boolean>;
|
|
25
|
+
/** Get the session directory for this agent */
|
|
26
|
+
getSessionDir(repoPath: string): Promise<string>;
|
|
27
|
+
/** Get session ID from hook input */
|
|
28
|
+
getSessionID(input: HookInput): string;
|
|
29
|
+
/** Resolve transcript file path */
|
|
30
|
+
resolveSessionFile(sessionDir: string, agentSessionID: string): string;
|
|
31
|
+
/** Read the raw transcript for a session */
|
|
32
|
+
readTranscript(sessionRef: string): Promise<Buffer>;
|
|
33
|
+
/** Format a resume command for the user */
|
|
34
|
+
formatResumeCommand(sessionID: string): string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Agent supports lifecycle hooks
|
|
38
|
+
*/
|
|
39
|
+
export interface HookSupport {
|
|
40
|
+
/** Hook names this agent supports */
|
|
41
|
+
hookNames(): string[];
|
|
42
|
+
/** Parse a hook event from stdin */
|
|
43
|
+
parseHookEvent(hookName: string, stdin: string): Event | null;
|
|
44
|
+
/** Install hooks for this agent in a repo */
|
|
45
|
+
installHooks(repoPath: string, force?: boolean): Promise<number>;
|
|
46
|
+
/** Remove hooks for this agent from a repo */
|
|
47
|
+
uninstallHooks(repoPath: string): Promise<void>;
|
|
48
|
+
/** Check if hooks are installed */
|
|
49
|
+
areHooksInstalled(repoPath: string): Promise<boolean>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Agent supports file watching for session changes
|
|
53
|
+
*/
|
|
54
|
+
export interface FileWatcher {
|
|
55
|
+
/** Get paths to watch for changes */
|
|
56
|
+
getWatchPaths(repoPath: string): Promise<string[]>;
|
|
57
|
+
/** Handle a file change event */
|
|
58
|
+
onFileChange(filePath: string): Promise<SessionChangeEvent | null>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Agent supports transcript analysis
|
|
62
|
+
*/
|
|
63
|
+
export interface TranscriptAnalyzer {
|
|
64
|
+
/** Get current position in the transcript */
|
|
65
|
+
getTranscriptPosition(transcriptPath: string): Promise<number>;
|
|
66
|
+
/** Extract modified files from a transcript segment */
|
|
67
|
+
extractModifiedFilesFromOffset(transcriptPath: string, startOffset: number): Promise<{
|
|
68
|
+
files: string[];
|
|
69
|
+
currentPosition: number;
|
|
70
|
+
}>;
|
|
71
|
+
/** Extract user prompts from a transcript segment */
|
|
72
|
+
extractPrompts(sessionRef: string, fromOffset: number): Promise<string[]>;
|
|
73
|
+
/** Extract a summary from the transcript */
|
|
74
|
+
extractSummary(sessionRef: string): Promise<string>;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Agent supports token usage calculation
|
|
78
|
+
*/
|
|
79
|
+
export interface TokenCalculator {
|
|
80
|
+
/** Calculate token usage from a transcript segment */
|
|
81
|
+
calculateTokenUsage(transcriptData: Buffer, fromOffset: number): Promise<TokenUsage>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Agent supports transcript preparation (e.g., waiting for async flush).
|
|
85
|
+
*
|
|
86
|
+
* Some agents write transcripts asynchronously. Before reading the transcript
|
|
87
|
+
* for checkpoint creation, the agent can wait for a flush sentinel to ensure
|
|
88
|
+
* the transcript is complete.
|
|
89
|
+
*/
|
|
90
|
+
export interface TranscriptPreparer {
|
|
91
|
+
/** Wait for the transcript to be fully flushed before reading */
|
|
92
|
+
prepareTranscript(sessionRef: string): Promise<void>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Agent supports subagent-aware extraction (e.g., Claude Code's Task tool).
|
|
96
|
+
* Aggregates files and tokens from both the main session and spawned subagents.
|
|
97
|
+
*/
|
|
98
|
+
export interface SubagentAwareExtractor {
|
|
99
|
+
/** Extract files modified by both the main agent and any spawned subagents */
|
|
100
|
+
extractAllModifiedFiles(transcriptData: Buffer, fromOffset: number, subagentsDir: string): Promise<string[]>;
|
|
101
|
+
/** Calculate token usage including all spawned subagents */
|
|
102
|
+
calculateTotalTokenUsage(transcriptData: Buffer, fromOffset: number, subagentsDir: string): Promise<TokenUsage>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Agent supports transcript chunking for storage
|
|
106
|
+
*/
|
|
107
|
+
export interface TranscriptChunker {
|
|
108
|
+
/** Split a transcript into storage-safe chunks */
|
|
109
|
+
chunkTranscript(content: Buffer, maxSize: number): Promise<Buffer[]>;
|
|
110
|
+
/** Reassemble chunked transcripts */
|
|
111
|
+
reassembleTranscript(chunks: Buffer[]): Promise<Buffer>;
|
|
112
|
+
}
|
|
113
|
+
export interface SessionChangeEvent {
|
|
114
|
+
sessionID: string;
|
|
115
|
+
sessionRef: string;
|
|
116
|
+
eventType: string;
|
|
117
|
+
timestamp: Date;
|
|
118
|
+
}
|
|
119
|
+
export declare function hasHookSupport(agent: Agent): agent is Agent & HookSupport;
|
|
120
|
+
export declare function hasFileWatcher(agent: Agent): agent is Agent & FileWatcher;
|
|
121
|
+
export declare function hasTranscriptAnalyzer(agent: Agent): agent is Agent & TranscriptAnalyzer;
|
|
122
|
+
export declare function hasTokenCalculator(agent: Agent): agent is Agent & TokenCalculator;
|
|
123
|
+
export declare function hasTranscriptPreparer(agent: Agent): agent is Agent & TranscriptPreparer;
|
|
124
|
+
export declare function hasSubagentAwareExtractor(agent: Agent): agent is Agent & SubagentAwareExtractor;
|
|
125
|
+
export declare function hasTranscriptChunker(agent: Agent): agent is Agent & TranscriptChunker;
|
|
126
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Types
|
|
3
|
+
*
|
|
4
|
+
* Interfaces for AI agent integrations. Each supported agent
|
|
5
|
+
* (Claude Code, Cursor, Gemini CLI, OpenCode) implements these
|
|
6
|
+
* interfaces to participate in the Entire session tracking lifecycle.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Type Guards
|
|
10
|
+
// ============================================================================
|
|
11
|
+
export function hasHookSupport(agent) {
|
|
12
|
+
return 'hookNames' in agent && typeof agent.hookNames === 'function';
|
|
13
|
+
}
|
|
14
|
+
export function hasFileWatcher(agent) {
|
|
15
|
+
return ('getWatchPaths' in agent &&
|
|
16
|
+
typeof agent.getWatchPaths === 'function');
|
|
17
|
+
}
|
|
18
|
+
export function hasTranscriptAnalyzer(agent) {
|
|
19
|
+
return ('getTranscriptPosition' in agent &&
|
|
20
|
+
typeof agent.getTranscriptPosition === 'function');
|
|
21
|
+
}
|
|
22
|
+
export function hasTokenCalculator(agent) {
|
|
23
|
+
return ('calculateTokenUsage' in agent &&
|
|
24
|
+
typeof agent.calculateTokenUsage === 'function');
|
|
25
|
+
}
|
|
26
|
+
export function hasTranscriptPreparer(agent) {
|
|
27
|
+
return ('prepareTranscript' in agent &&
|
|
28
|
+
typeof agent.prepareTranscript === 'function');
|
|
29
|
+
}
|
|
30
|
+
export function hasSubagentAwareExtractor(agent) {
|
|
31
|
+
return ('extractAllModifiedFiles' in agent &&
|
|
32
|
+
typeof agent.extractAllModifiedFiles === 'function' &&
|
|
33
|
+
'calculateTotalTokenUsage' in agent &&
|
|
34
|
+
typeof agent.calculateTotalTokenUsage === 'function');
|
|
35
|
+
}
|
|
36
|
+
export function hasTranscriptChunker(agent) {
|
|
37
|
+
return ('chunkTranscript' in agent &&
|
|
38
|
+
typeof agent.chunkTranscript === 'function');
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmKH,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,MAAM,UAAU,cAAc,CAAC,KAAY;IACzC,OAAO,WAAW,IAAI,KAAK,IAAI,OAAQ,KAAgC,CAAC,SAAS,KAAK,UAAU,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAY;IACzC,OAAO,CACL,eAAe,IAAI,KAAK;QACxB,OAAQ,KAAgC,CAAC,aAAa,KAAK,UAAU,CACtE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAY;IAChD,OAAO,CACL,uBAAuB,IAAI,KAAK;QAChC,OAAQ,KAAuC,CAAC,qBAAqB,KAAK,UAAU,CACrF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAY;IAC7C,OAAO,CACL,qBAAqB,IAAI,KAAK;QAC9B,OAAQ,KAAoC,CAAC,mBAAmB,KAAK,UAAU,CAChF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAY;IAChD,OAAO,CACL,mBAAmB,IAAI,KAAK;QAC5B,OAAQ,KAAuC,CAAC,iBAAiB,KAAK,UAAU,CACjF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,KAAY;IACpD,OAAO,CACL,yBAAyB,IAAI,KAAK;QAClC,OAAQ,KAA2C,CAAC,uBAAuB,KAAK,UAAU;QAC1F,0BAA0B,IAAI,KAAK;QACnC,OAAQ,KAA2C,CAAC,wBAAwB,KAAK,UAAU,CAC5F,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAY;IAC/C,OAAO,CACL,iBAAiB,IAAI,KAAK;QAC1B,OAAQ,KAAsC,CAAC,eAAe,KAAK,UAAU,CAC9E,CAAC;AACJ,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Entire CLI Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Minimal CLI wrapper over the library functions.
|
|
6
|
+
* Parses arguments and dispatches to the appropriate command.
|
|
7
|
+
*/
|
|
8
|
+
import './agent/agents/claude-code.js';
|
|
9
|
+
import './agent/agents/cursor.js';
|
|
10
|
+
import './agent/agents/gemini-cli.js';
|
|
11
|
+
import './agent/agents/opencode.js';
|
|
12
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAKH,OAAO,+BAA+B,CAAC;AACvC,OAAO,0BAA0B,CAAC;AAClC,OAAO,8BAA8B,CAAC;AACtC,OAAO,4BAA4B,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Entire CLI Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Minimal CLI wrapper over the library functions.
|
|
6
|
+
* Parses arguments and dispatches to the appropriate command.
|
|
7
|
+
*/
|
|
8
|
+
import * as process from 'node:process';
|
|
9
|
+
// Ensure agent implementations are registered
|
|
10
|
+
import './agent/agents/claude-code.js';
|
|
11
|
+
import './agent/agents/cursor.js';
|
|
12
|
+
import './agent/agents/gemini-cli.js';
|
|
13
|
+
import './agent/agents/opencode.js';
|
|
14
|
+
import { enable } from './commands/enable.js';
|
|
15
|
+
import { disable } from './commands/disable.js';
|
|
16
|
+
import { status, formatStatusJSON, formatTokens } from './commands/status.js';
|
|
17
|
+
import { listRewindPoints, rewindTo, listRewindPointsJSON } from './commands/rewind.js';
|
|
18
|
+
import { doctor, diagnose } from './commands/doctor.js';
|
|
19
|
+
import { clean } from './commands/clean.js';
|
|
20
|
+
import { reset } from './commands/reset.js';
|
|
21
|
+
import { explainCommit, getCheckpointDetail } from './commands/explain.js';
|
|
22
|
+
import { discoverResumeInfo, listResumableBranches } from './commands/resume.js';
|
|
23
|
+
import { isEnabled, loadSettings } from './config.js';
|
|
24
|
+
import { createSessionStore } from './store/session-store.js';
|
|
25
|
+
import { createCheckpointStore } from './store/checkpoint-store.js';
|
|
26
|
+
import { createManualCommitStrategy } from './strategy/manual-commit.js';
|
|
27
|
+
import { getVersion } from './index.js';
|
|
28
|
+
import { getWorktreeRoot, initSessionRepo, resolveSessionRepoPath, getProjectID, } from './git-operations.js';
|
|
29
|
+
import { CHECKPOINTS_BRANCH, SESSION_DIR_NAME } from './types.js';
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Argument Parsing Helpers
|
|
32
|
+
// ============================================================================
|
|
33
|
+
function hasFlag(args, ...flags) {
|
|
34
|
+
return flags.some((f) => args.includes(f));
|
|
35
|
+
}
|
|
36
|
+
function getFlagValue(args, ...flags) {
|
|
37
|
+
for (const flag of flags) {
|
|
38
|
+
const idx = args.indexOf(flag);
|
|
39
|
+
if (idx !== -1 && idx + 1 < args.length) {
|
|
40
|
+
return args[idx + 1];
|
|
41
|
+
}
|
|
42
|
+
// Handle --flag=value
|
|
43
|
+
const prefix = flag + '=';
|
|
44
|
+
const match = args.find((a) => a.startsWith(prefix));
|
|
45
|
+
if (match)
|
|
46
|
+
return match.slice(prefix.length);
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
function getPositionalArg(args, flagPrefixes) {
|
|
51
|
+
for (const arg of args) {
|
|
52
|
+
if (arg.startsWith('-'))
|
|
53
|
+
continue;
|
|
54
|
+
if (flagPrefixes.some((p) => args.includes(p) && args[args.indexOf(p) + 1] === arg))
|
|
55
|
+
continue;
|
|
56
|
+
return arg;
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Command Handlers
|
|
62
|
+
// ============================================================================
|
|
63
|
+
async function cmdEnable(args) {
|
|
64
|
+
const result = await enable({
|
|
65
|
+
agent: getFlagValue(args, '--agent'),
|
|
66
|
+
force: hasFlag(args, '--force', '-f'),
|
|
67
|
+
local: hasFlag(args, '--local'),
|
|
68
|
+
project: hasFlag(args, '--project'),
|
|
69
|
+
skipPushSessions: hasFlag(args, '--skip-push-sessions') ? true : undefined,
|
|
70
|
+
telemetry: getFlagValue(args, '--telemetry') === 'false' ? false : undefined,
|
|
71
|
+
sessionRepoPath: getFlagValue(args, '--session-repo'),
|
|
72
|
+
});
|
|
73
|
+
if (!result.enabled) {
|
|
74
|
+
console.error('Failed to enable Entire:');
|
|
75
|
+
for (const err of result.errors)
|
|
76
|
+
console.error(` ${err}`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
console.log('Entire enabled.');
|
|
80
|
+
if (result.agent)
|
|
81
|
+
console.log(` Agent: ${result.agent}`);
|
|
82
|
+
console.log(` Git hooks installed: ${result.gitHooksInstalled}`);
|
|
83
|
+
console.log(` Agent hooks installed: ${result.agentHooksInstalled}`);
|
|
84
|
+
if (result.errors.length > 0) {
|
|
85
|
+
console.warn('Warnings:');
|
|
86
|
+
for (const err of result.errors)
|
|
87
|
+
console.warn(` ${err}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function cmdDisable(args) {
|
|
91
|
+
const result = await disable({
|
|
92
|
+
uninstall: hasFlag(args, '--uninstall'),
|
|
93
|
+
local: hasFlag(args, '--local'),
|
|
94
|
+
});
|
|
95
|
+
if (!result.disabled) {
|
|
96
|
+
console.error('Failed to disable Entire:');
|
|
97
|
+
for (const err of result.errors)
|
|
98
|
+
console.error(` ${err}`);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
console.log('Entire disabled.');
|
|
102
|
+
if (result.uninstalled)
|
|
103
|
+
console.log(' Hooks uninstalled.');
|
|
104
|
+
}
|
|
105
|
+
async function cmdStatus(args) {
|
|
106
|
+
const result = await status();
|
|
107
|
+
if (hasFlag(args, '--json')) {
|
|
108
|
+
console.log(formatStatusJSON(result));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
console.log(`Enabled: ${result.enabled}`);
|
|
112
|
+
console.log(`Strategy: ${result.strategy}`);
|
|
113
|
+
console.log(`Branch: ${result.branch ?? '(detached)'}`);
|
|
114
|
+
console.log(`Checkpoints branch: ${result.hasCheckpointsBranch ? 'exists' : 'not created'}`);
|
|
115
|
+
console.log(`Git hooks: ${result.gitHooksInstalled ? 'installed' : 'not installed'}`);
|
|
116
|
+
console.log(`Agents: ${result.agents.length > 0 ? result.agents.join(', ') : 'none'}`);
|
|
117
|
+
if (result.settings.sessionRepoPath) {
|
|
118
|
+
console.log(`Session repo: ${result.settings.sessionRepoPath}`);
|
|
119
|
+
}
|
|
120
|
+
if (result.sessions.length > 0) {
|
|
121
|
+
console.log(`\nActive sessions (${result.sessions.length}):`);
|
|
122
|
+
for (const s of result.sessions) {
|
|
123
|
+
console.log(` ${s.sessionID} (${s.agentType}) - ${s.phase}`);
|
|
124
|
+
if (s.firstPrompt)
|
|
125
|
+
console.log(` Prompt: ${s.firstPrompt.slice(0, 80)}...`);
|
|
126
|
+
if (s.filesTouched.length > 0)
|
|
127
|
+
console.log(` Files: ${s.filesTouched.length}`);
|
|
128
|
+
if (s.tokenUsage) {
|
|
129
|
+
console.log(` Tokens: ${formatTokens(s.tokenUsage.input)} in / ${formatTokens(s.tokenUsage.output)} out`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function cmdRewind(args) {
|
|
135
|
+
const toID = getFlagValue(args, '--to');
|
|
136
|
+
if (hasFlag(args, '--list')) {
|
|
137
|
+
console.log(await listRewindPointsJSON());
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (toID) {
|
|
141
|
+
const result = await rewindTo(toID, {
|
|
142
|
+
logsOnly: hasFlag(args, '--logs-only'),
|
|
143
|
+
reset: hasFlag(args, '--reset'),
|
|
144
|
+
});
|
|
145
|
+
if (!result.success) {
|
|
146
|
+
console.error(result.message);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
console.log(result.message);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// Default: list rewind points
|
|
153
|
+
const points = await listRewindPoints({ limit: 20 });
|
|
154
|
+
if (points.length === 0) {
|
|
155
|
+
console.log('No rewind points found. Work with your agent and commit changes.');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
for (const p of points) {
|
|
159
|
+
const prefix = p.isLogsOnly ? '[logs]' : '[code]';
|
|
160
|
+
const agent = p.agent ? ` (${p.agent})` : '';
|
|
161
|
+
console.log(` ${prefix} ${p.id.slice(0, 8)} - ${p.message}${agent} - ${p.date}`);
|
|
162
|
+
}
|
|
163
|
+
console.log(`\nUse --to <id> to rewind to a specific point.`);
|
|
164
|
+
}
|
|
165
|
+
async function cmdDoctor(args) {
|
|
166
|
+
if (hasFlag(args, '--force')) {
|
|
167
|
+
const result = await doctor({ force: true });
|
|
168
|
+
console.log(`Fixed: ${result.fixedCount}, Discarded: ${result.discardedCount}`);
|
|
169
|
+
for (const err of result.errors)
|
|
170
|
+
console.error(` Error: ${err}`);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const stuck = await diagnose();
|
|
174
|
+
if (stuck.length === 0) {
|
|
175
|
+
console.log('No stuck sessions found.');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
console.log(`Found ${stuck.length} stuck session(s):`);
|
|
179
|
+
for (const s of stuck) {
|
|
180
|
+
console.log(` ${s.sessionID} - ${s.reason}`);
|
|
181
|
+
}
|
|
182
|
+
console.log('\nUse --force to auto-fix.');
|
|
183
|
+
}
|
|
184
|
+
async function cmdClean(args) {
|
|
185
|
+
const result = await clean({ force: hasFlag(args, '--force') });
|
|
186
|
+
if (result.items.length === 0) {
|
|
187
|
+
console.log('Nothing to clean.');
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
for (const item of result.items) {
|
|
191
|
+
const status = result.deletedCount > 0 ? 'deleted' : 'would delete';
|
|
192
|
+
console.log(` [${item.type}] ${item.path} - ${item.reason} (${status})`);
|
|
193
|
+
}
|
|
194
|
+
if (!hasFlag(args, '--force')) {
|
|
195
|
+
console.log(`\nFound ${result.items.length} item(s). Use --force to delete.`);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
console.log(`\nDeleted ${result.deletedCount} item(s).`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async function cmdReset(args) {
|
|
202
|
+
const result = await reset({
|
|
203
|
+
sessionID: getFlagValue(args, '--session'),
|
|
204
|
+
force: hasFlag(args, '--force'),
|
|
205
|
+
});
|
|
206
|
+
if (result.errors.length > 0) {
|
|
207
|
+
for (const err of result.errors)
|
|
208
|
+
console.error(` ${err}`);
|
|
209
|
+
if (result.sessionsReset.length === 0)
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
console.log(`Sessions reset: ${result.sessionsReset.length}`);
|
|
213
|
+
console.log(`Branches deleted: ${result.branchesDeleted.length}`);
|
|
214
|
+
}
|
|
215
|
+
async function cmdExplain(args) {
|
|
216
|
+
const commitRef = getFlagValue(args, '--commit') ?? getPositionalArg(args, ['--commit', '--checkpoint']);
|
|
217
|
+
const checkpointID = getFlagValue(args, '--checkpoint', '-c');
|
|
218
|
+
if (checkpointID) {
|
|
219
|
+
const detail = await getCheckpointDetail(checkpointID);
|
|
220
|
+
if (!detail) {
|
|
221
|
+
console.error(`Checkpoint not found: ${checkpointID}`);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
console.log(JSON.stringify(detail, null, 2));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const ref = commitRef ?? 'HEAD';
|
|
228
|
+
const result = await explainCommit(ref);
|
|
229
|
+
if (!result) {
|
|
230
|
+
console.error(`Could not explain commit: ${ref}`);
|
|
231
|
+
process.exit(1);
|
|
232
|
+
}
|
|
233
|
+
console.log(`Commit: ${result.commitSHA.slice(0, 8)}`);
|
|
234
|
+
console.log(`Message: ${result.commitMessage}`);
|
|
235
|
+
if (result.checkpointID) {
|
|
236
|
+
console.log(`Checkpoint: ${result.checkpointID}`);
|
|
237
|
+
}
|
|
238
|
+
if (result.detail) {
|
|
239
|
+
console.log(`Agent: ${result.detail.agent}`);
|
|
240
|
+
console.log(`Files: ${result.detail.filesTouched.join(', ')}`);
|
|
241
|
+
if (result.detail.summary) {
|
|
242
|
+
console.log(`\nIntent: ${result.detail.summary.intent}`);
|
|
243
|
+
console.log(`Outcome: ${result.detail.summary.outcome}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async function cmdResume(args) {
|
|
248
|
+
const branch = getPositionalArg(args, []);
|
|
249
|
+
if (!branch) {
|
|
250
|
+
// List resumable branches
|
|
251
|
+
const branches = await listResumableBranches();
|
|
252
|
+
if (branches.length === 0) {
|
|
253
|
+
console.log('No resumable branches found.');
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
console.log('Resumable branches:');
|
|
257
|
+
for (const b of branches) {
|
|
258
|
+
console.log(` ${b.branch} - session ${b.sessionID} (${b.lastCommit})`);
|
|
259
|
+
}
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const result = await discoverResumeInfo(branch);
|
|
263
|
+
if (!result.success || !result.info) {
|
|
264
|
+
console.error(result.error ?? 'Failed to discover resume info');
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
console.log(`Branch: ${result.info.branchName}`);
|
|
268
|
+
console.log(`Session: ${result.info.sessionID}`);
|
|
269
|
+
console.log(`Checkpoint: ${result.info.checkpointID}`);
|
|
270
|
+
console.log(`Commit: ${result.info.commitSHA.slice(0, 8)} - ${result.info.commitMessage}`);
|
|
271
|
+
if (result.info.needsReset) {
|
|
272
|
+
console.log(`\nNote: branch has advanced past checkpoint. Reset target: ${result.info.resetTargetSHA?.slice(0, 8)}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// ============================================================================
|
|
276
|
+
// Git Hook Dispatch
|
|
277
|
+
// ============================================================================
|
|
278
|
+
/**
|
|
279
|
+
* Handle `entire hooks git <hook-name> [args...]`
|
|
280
|
+
*
|
|
281
|
+
* This is invoked by the git hooks installed via `entire enable`.
|
|
282
|
+
* Each hook delegates to the corresponding strategy method.
|
|
283
|
+
* All hooks are designed to fail silently (the shell scripts use `|| true`
|
|
284
|
+
* except commit-msg which uses `|| exit 1`).
|
|
285
|
+
*/
|
|
286
|
+
async function cmdHooksGit(args) {
|
|
287
|
+
const hookName = args[0];
|
|
288
|
+
const hookArgs = args.slice(1);
|
|
289
|
+
// Bail silently if Entire is not enabled
|
|
290
|
+
if (!(await isEnabled()))
|
|
291
|
+
return;
|
|
292
|
+
// Resolve session repo if configured
|
|
293
|
+
const settings = await loadSettings();
|
|
294
|
+
let sessionRepoCwd;
|
|
295
|
+
let sessionsDir;
|
|
296
|
+
let checkpointsBranch;
|
|
297
|
+
if (settings.sessionRepoPath) {
|
|
298
|
+
const root = await getWorktreeRoot();
|
|
299
|
+
const projectID = getProjectID(root);
|
|
300
|
+
const resolved = resolveSessionRepoPath(settings.sessionRepoPath, root);
|
|
301
|
+
sessionRepoCwd = await initSessionRepo(resolved);
|
|
302
|
+
// Namespace by project so multiple repos can share one session repo
|
|
303
|
+
sessionsDir = `${sessionRepoCwd}/${SESSION_DIR_NAME}/${projectID}`;
|
|
304
|
+
checkpointsBranch = `${CHECKPOINTS_BRANCH}/${projectID}`;
|
|
305
|
+
}
|
|
306
|
+
const strategy = createManualCommitStrategy({
|
|
307
|
+
sessionStore: createSessionStore(undefined, sessionsDir),
|
|
308
|
+
checkpointStore: createCheckpointStore(undefined, sessionRepoCwd, checkpointsBranch),
|
|
309
|
+
sessionRepoCwd,
|
|
310
|
+
checkpointsBranch,
|
|
311
|
+
});
|
|
312
|
+
switch (hookName) {
|
|
313
|
+
case 'prepare-commit-msg': {
|
|
314
|
+
// Args: <commit-msg-file> [<source>] [<sha>]
|
|
315
|
+
const commitMsgFile = hookArgs[0];
|
|
316
|
+
const source = hookArgs[1] ?? '';
|
|
317
|
+
const sha = hookArgs[2] ?? '';
|
|
318
|
+
if (!commitMsgFile)
|
|
319
|
+
return;
|
|
320
|
+
await strategy.prepareCommitMsg(commitMsgFile, source, sha);
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
case 'commit-msg': {
|
|
324
|
+
// Args: <commit-msg-file>
|
|
325
|
+
const commitMsgFile = hookArgs[0];
|
|
326
|
+
if (!commitMsgFile)
|
|
327
|
+
return;
|
|
328
|
+
await strategy.commitMsg(commitMsgFile);
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
case 'post-commit': {
|
|
332
|
+
await strategy.postCommit();
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
case 'pre-push': {
|
|
336
|
+
// Args: <remote> <url>
|
|
337
|
+
const remote = hookArgs[0] ?? 'origin';
|
|
338
|
+
await strategy.prePush(remote);
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
default:
|
|
342
|
+
// Unknown hook — ignore silently (hooks must not break git)
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
async function cmdVersion() {
|
|
347
|
+
console.log(`entire-cli ${getVersion()}`);
|
|
348
|
+
}
|
|
349
|
+
function printHelp() {
|
|
350
|
+
console.log(`entire-cli ${getVersion()}
|
|
351
|
+
|
|
352
|
+
Usage: entire <command> [options]
|
|
353
|
+
|
|
354
|
+
Commands:
|
|
355
|
+
enable Activate Entire in a repository
|
|
356
|
+
disable Deactivate Entire hooks
|
|
357
|
+
status Show current session information
|
|
358
|
+
rewind Browse and restore checkpoints
|
|
359
|
+
doctor Diagnose and fix stuck sessions
|
|
360
|
+
clean Remove orphaned data artifacts
|
|
361
|
+
reset Clear shadow branch and session state
|
|
362
|
+
explain Show session or commit details
|
|
363
|
+
resume Switch branches and restore sessions
|
|
364
|
+
version Show version
|
|
365
|
+
|
|
366
|
+
Options:
|
|
367
|
+
enable --session-repo <path> Store sessions in a separate repository
|
|
368
|
+
|
|
369
|
+
Run 'entire <command> --help' for more information on a command.`);
|
|
370
|
+
}
|
|
371
|
+
// ============================================================================
|
|
372
|
+
// Main Dispatch
|
|
373
|
+
// ============================================================================
|
|
374
|
+
async function main() {
|
|
375
|
+
const args = process.argv.slice(2);
|
|
376
|
+
const command = args[0];
|
|
377
|
+
const commandArgs = args.slice(1);
|
|
378
|
+
if (!command || hasFlag(args, '--help', '-h')) {
|
|
379
|
+
printHelp();
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
switch (command) {
|
|
383
|
+
case 'enable':
|
|
384
|
+
return cmdEnable(commandArgs);
|
|
385
|
+
case 'disable':
|
|
386
|
+
return cmdDisable(commandArgs);
|
|
387
|
+
case 'status':
|
|
388
|
+
return cmdStatus(commandArgs);
|
|
389
|
+
case 'rewind':
|
|
390
|
+
return cmdRewind(commandArgs);
|
|
391
|
+
case 'doctor':
|
|
392
|
+
return cmdDoctor(commandArgs);
|
|
393
|
+
case 'clean':
|
|
394
|
+
return cmdClean(commandArgs);
|
|
395
|
+
case 'reset':
|
|
396
|
+
return cmdReset(commandArgs);
|
|
397
|
+
case 'explain':
|
|
398
|
+
return cmdExplain(commandArgs);
|
|
399
|
+
case 'resume':
|
|
400
|
+
return cmdResume(commandArgs);
|
|
401
|
+
case 'hooks': {
|
|
402
|
+
// `entire hooks git <hook-name> [args...]`
|
|
403
|
+
const subcommand = commandArgs[0];
|
|
404
|
+
if (subcommand === 'git') {
|
|
405
|
+
return cmdHooksGit(commandArgs.slice(1));
|
|
406
|
+
}
|
|
407
|
+
console.error(`Unknown hooks subcommand: ${subcommand}`);
|
|
408
|
+
process.exit(1);
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
case 'version':
|
|
412
|
+
case '--version':
|
|
413
|
+
case '-v':
|
|
414
|
+
return cmdVersion();
|
|
415
|
+
default:
|
|
416
|
+
console.error(`Unknown command: ${command}`);
|
|
417
|
+
printHelp();
|
|
418
|
+
process.exit(1);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
main().catch((err) => {
|
|
422
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
423
|
+
process.exit(1);
|
|
424
|
+
});
|
|
425
|
+
//# sourceMappingURL=cli.js.map
|