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,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strategy Common Infrastructure
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities used by strategy implementations for metadata branch
|
|
5
|
+
* operations, repository validation, and setup.
|
|
6
|
+
*
|
|
7
|
+
* Ported from Go: strategy/common.go
|
|
8
|
+
*/
|
|
9
|
+
import { git, gitSafe, refExists, isGitRepository, getWorktreeRoot, getHead, showFile, commitTree, mktree, getGitAuthor, } from '../git-operations.js';
|
|
10
|
+
import { CHECKPOINTS_BRANCH, checkpointIDPath, } from '../types.js';
|
|
11
|
+
import { ensureGitignore } from '../config.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Repository Validation
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Validates that the repository is suitable for the manual-commit strategy.
|
|
17
|
+
* Throws if the repository is bare, has no commits, or is not a git repo.
|
|
18
|
+
*/
|
|
19
|
+
export async function validateRepository(cwd) {
|
|
20
|
+
const isRepo = await isGitRepository(cwd);
|
|
21
|
+
if (!isRepo) {
|
|
22
|
+
throw new Error('Not a git repository');
|
|
23
|
+
}
|
|
24
|
+
// Check that it's not a bare repository
|
|
25
|
+
const isBare = await gitSafe(['rev-parse', '--is-bare-repository'], { cwd });
|
|
26
|
+
if (isBare?.trim() === 'true') {
|
|
27
|
+
throw new Error('Cannot operate on a bare repository');
|
|
28
|
+
}
|
|
29
|
+
// Check that we can access the worktree
|
|
30
|
+
try {
|
|
31
|
+
await getWorktreeRoot(cwd);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
throw new Error('Failed to access worktree');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if the repository has any commits.
|
|
39
|
+
*/
|
|
40
|
+
export async function isEmptyRepository(cwd) {
|
|
41
|
+
try {
|
|
42
|
+
await getHead(cwd);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if commit `ancestor` is an ancestor of commit `descendant`.
|
|
51
|
+
* Uses a bounded traversal to prevent runaway history walks.
|
|
52
|
+
*/
|
|
53
|
+
export async function isAncestorOf(ancestor, descendant, _maxDepth = 1000, cwd) {
|
|
54
|
+
const result = await gitSafe(['merge-base', '--is-ancestor', ancestor, descendant], { cwd });
|
|
55
|
+
// git merge-base --is-ancestor exits 0 if true, 1 if not
|
|
56
|
+
return result !== null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if we're inside a git worktree (not the main repo).
|
|
60
|
+
*/
|
|
61
|
+
export async function isInsideWorktree(cwd) {
|
|
62
|
+
const result = await gitSafe(['rev-parse', '--git-common-dir'], { cwd });
|
|
63
|
+
const gitDir = await gitSafe(['rev-parse', '--git-dir'], { cwd });
|
|
64
|
+
if (!result || !gitDir)
|
|
65
|
+
return false;
|
|
66
|
+
return result.trim() !== gitDir.trim();
|
|
67
|
+
}
|
|
68
|
+
// ============================================================================
|
|
69
|
+
// Metadata Branch Operations
|
|
70
|
+
// ============================================================================
|
|
71
|
+
/**
|
|
72
|
+
* Ensure the metadata branch (entire/checkpoints/v1) exists.
|
|
73
|
+
* Creates it with an initial empty-tree commit if it doesn't exist.
|
|
74
|
+
*/
|
|
75
|
+
export async function ensureMetadataBranch(cwd) {
|
|
76
|
+
const branchRef = `refs/heads/${CHECKPOINTS_BRANCH}`;
|
|
77
|
+
const exists = await refExists(branchRef, cwd);
|
|
78
|
+
if (exists)
|
|
79
|
+
return;
|
|
80
|
+
// Create an empty tree
|
|
81
|
+
const emptyTree = await mktree([], cwd);
|
|
82
|
+
const author = await getGitAuthor(cwd);
|
|
83
|
+
const commitHash = await commitTree(emptyTree, null, 'Initialize Entire checkpoints branch', author, cwd);
|
|
84
|
+
// Create the branch pointing to this commit
|
|
85
|
+
await git(['branch', CHECKPOINTS_BRANCH, commitHash], { cwd });
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Read checkpoint metadata from the metadata branch.
|
|
89
|
+
*/
|
|
90
|
+
export async function readCheckpointMetadata(checkpointID, cwd) {
|
|
91
|
+
const checkpointPath = checkpointIDPath(checkpointID);
|
|
92
|
+
try {
|
|
93
|
+
const content = await showFile(CHECKPOINTS_BRANCH, `${checkpointPath}/metadata.json`, cwd);
|
|
94
|
+
return JSON.parse(content);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Read a session prompt from the metadata branch tree.
|
|
102
|
+
*/
|
|
103
|
+
export async function readSessionPromptFromTree(checkpointID, sessionIndex, cwd) {
|
|
104
|
+
const checkpointPath = checkpointIDPath(checkpointID);
|
|
105
|
+
try {
|
|
106
|
+
return await showFile(CHECKPOINTS_BRANCH, `${checkpointPath}/${sessionIndex}/prompt.txt`, cwd);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return '';
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Read the agent type from checkpoint metadata.
|
|
114
|
+
*/
|
|
115
|
+
export async function readAgentTypeFromTree(checkpointID, cwd) {
|
|
116
|
+
const metadata = await readCheckpointMetadata(checkpointID, cwd);
|
|
117
|
+
return metadata?.agent ?? '';
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Extract the first user prompt from a transcript or prompt file.
|
|
121
|
+
*/
|
|
122
|
+
export function extractFirstPrompt(prompts) {
|
|
123
|
+
if (!prompts)
|
|
124
|
+
return '';
|
|
125
|
+
// Split on the prompt separator
|
|
126
|
+
const parts = prompts.split('\n---\n');
|
|
127
|
+
const first = parts[0]?.trim() ?? '';
|
|
128
|
+
// Truncate to 200 chars
|
|
129
|
+
return first.length > 200 ? first.slice(0, 200) + '...' : first;
|
|
130
|
+
}
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Setup
|
|
133
|
+
// ============================================================================
|
|
134
|
+
/**
|
|
135
|
+
* Full strategy setup: create metadata branch, ensure .gitignore, etc.
|
|
136
|
+
*/
|
|
137
|
+
export async function ensureSetup(cwd) {
|
|
138
|
+
await validateRepository(cwd);
|
|
139
|
+
await ensureMetadataBranch(cwd);
|
|
140
|
+
await ensureGitignore(cwd);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the root directory of the main repository (not a worktree).
|
|
144
|
+
*/
|
|
145
|
+
export async function getMainRepoRoot(cwd) {
|
|
146
|
+
const commonDir = await gitSafe(['rev-parse', '--git-common-dir'], { cwd });
|
|
147
|
+
if (!commonDir) {
|
|
148
|
+
throw new Error('Not inside a git repository');
|
|
149
|
+
}
|
|
150
|
+
const { resolve, dirname } = await import('node:path');
|
|
151
|
+
// Common dir is typically <repo>/.git or <repo>/.git/worktrees/<name>
|
|
152
|
+
// For the main repo, --git-common-dir returns .git
|
|
153
|
+
const absCommon = resolve(cwd ?? process.cwd(), commonDir.trim());
|
|
154
|
+
return dirname(absCommon);
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/strategy/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Overlap Detection
|
|
3
|
+
*
|
|
4
|
+
* Determines whether a commit contains session-related work by comparing
|
|
5
|
+
* file content (not just filenames) against the shadow branch. This enables
|
|
6
|
+
* accurate detection of the "reverted and replaced" scenario.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Check if any file in filesTouched overlaps with the committed content.
|
|
10
|
+
* Uses content-aware comparison to detect the "reverted and replaced" scenario.
|
|
11
|
+
*
|
|
12
|
+
* For modified files (exist in parent), always counts as overlap.
|
|
13
|
+
* For new files, requires content match against shadow branch.
|
|
14
|
+
*/
|
|
15
|
+
export declare function filesOverlapWithContent(shadowBranchName: string, headCommitHash: string, parentCommitHash: string | null, filesTouched: string[], cwd?: string): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Check if any staged file overlaps with filesTouched using content comparison.
|
|
18
|
+
*/
|
|
19
|
+
export declare function stagedFilesOverlapWithContent(shadowBranchName: string, stagedFiles: string[], filesTouched: string[], cwd?: string): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Return files from filesTouched that still have uncommitted agent changes.
|
|
22
|
+
*/
|
|
23
|
+
export declare function filesWithRemainingAgentChanges(shadowBranchName: string, headCommitHash: string, filesTouched: string[], committedFiles: Set<string>, cwd?: string): Promise<string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Check if two file contents share significant lines.
|
|
26
|
+
* Distinguishes partial staging from "reverted and replaced".
|
|
27
|
+
*/
|
|
28
|
+
export declare function hasSignificantContentOverlap(stagedContent: string, shadowContent: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Simple filename-based overlap check (fallback).
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasOverlappingFiles(stagedFiles: string[], filesTouched: string[]): boolean;
|
|
33
|
+
//# sourceMappingURL=content-overlap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-overlap.d.ts","sourceRoot":"","sources":["../../src/strategy/content-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,EAC/B,YAAY,EAAE,MAAM,EAAE,EACtB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAmDlB;AAED;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,gBAAgB,EAAE,MAAM,EACxB,WAAW,EAAE,MAAM,EAAE,EACrB,YAAY,EAAE,MAAM,EAAE,EACtB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAwClB;AAED;;GAEG;AACH,wBAAsB,8BAA8B,CAClD,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EAAE,EACtB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,EAC3B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BnB;AAMD;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,GACpB,OAAO,CAkBT;AAiBD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAG1F"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Overlap Detection
|
|
3
|
+
*
|
|
4
|
+
* Determines whether a commit contains session-related work by comparing
|
|
5
|
+
* file content (not just filenames) against the shadow branch. This enables
|
|
6
|
+
* accurate detection of the "reverted and replaced" scenario.
|
|
7
|
+
*/
|
|
8
|
+
import { gitSafe } from '../git-operations.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Content Overlap
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Check if any file in filesTouched overlaps with the committed content.
|
|
14
|
+
* Uses content-aware comparison to detect the "reverted and replaced" scenario.
|
|
15
|
+
*
|
|
16
|
+
* For modified files (exist in parent), always counts as overlap.
|
|
17
|
+
* For new files, requires content match against shadow branch.
|
|
18
|
+
*/
|
|
19
|
+
export async function filesOverlapWithContent(shadowBranchName, headCommitHash, parentCommitHash, filesTouched, cwd) {
|
|
20
|
+
if (filesTouched.length === 0)
|
|
21
|
+
return false;
|
|
22
|
+
for (const filePath of filesTouched) {
|
|
23
|
+
// Get file from HEAD (committed content)
|
|
24
|
+
const headContent = await gitSafe(['show', `${headCommitHash}:${filePath}`], { cwd });
|
|
25
|
+
if (headContent === null) {
|
|
26
|
+
// File not in HEAD commit - check if it's a deletion
|
|
27
|
+
if (parentCommitHash) {
|
|
28
|
+
const parentContent = await gitSafe(['show', `${parentCommitHash}:${filePath}`], { cwd });
|
|
29
|
+
if (parentContent !== null) {
|
|
30
|
+
// File existed in parent but not in HEAD = deletion = overlap
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
// Check if this is a modified file (exists in parent) or new file
|
|
37
|
+
let isModified = false;
|
|
38
|
+
if (parentCommitHash) {
|
|
39
|
+
const parentContent = await gitSafe(['show', `${parentCommitHash}:${filePath}`], { cwd });
|
|
40
|
+
isModified = parentContent !== null;
|
|
41
|
+
}
|
|
42
|
+
// Modified files always count as overlap
|
|
43
|
+
if (isModified)
|
|
44
|
+
return true;
|
|
45
|
+
// For new files, check content against shadow branch
|
|
46
|
+
const shadowContent = await gitSafe(['show', `refs/heads/${shadowBranchName}:${filePath}`], {
|
|
47
|
+
cwd,
|
|
48
|
+
});
|
|
49
|
+
if (shadowContent === null)
|
|
50
|
+
continue;
|
|
51
|
+
// Compare by hashing - get blob hashes
|
|
52
|
+
const headHash = await gitSafe(['rev-parse', `${headCommitHash}:${filePath}`], { cwd });
|
|
53
|
+
const shadowHash = await gitSafe(['rev-parse', `refs/heads/${shadowBranchName}:${filePath}`], {
|
|
54
|
+
cwd,
|
|
55
|
+
});
|
|
56
|
+
if (headHash !== null && shadowHash !== null && headHash.trim() === shadowHash.trim()) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
// Check for significant content overlap if hashes differ
|
|
60
|
+
if (headContent && shadowContent && hasSignificantContentOverlap(headContent, shadowContent)) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if any staged file overlaps with filesTouched using content comparison.
|
|
68
|
+
*/
|
|
69
|
+
export async function stagedFilesOverlapWithContent(shadowBranchName, stagedFiles, filesTouched, cwd) {
|
|
70
|
+
const touchedSet = new Set(filesTouched);
|
|
71
|
+
for (const stagedPath of stagedFiles) {
|
|
72
|
+
if (!touchedSet.has(stagedPath))
|
|
73
|
+
continue;
|
|
74
|
+
// Check if modified (exists in HEAD) or new
|
|
75
|
+
const headContent = await gitSafe(['show', `HEAD:${stagedPath}`], { cwd });
|
|
76
|
+
const isModified = headContent !== null;
|
|
77
|
+
if (isModified)
|
|
78
|
+
return true;
|
|
79
|
+
// For new files, compare staged content with shadow
|
|
80
|
+
const shadowContent = await gitSafe(['show', `refs/heads/${shadowBranchName}:${stagedPath}`], {
|
|
81
|
+
cwd,
|
|
82
|
+
});
|
|
83
|
+
if (shadowContent === null)
|
|
84
|
+
continue;
|
|
85
|
+
// Get staged content
|
|
86
|
+
const stagedContent = await gitSafe(['show', `:${stagedPath}`], { cwd });
|
|
87
|
+
if (stagedContent === null)
|
|
88
|
+
continue;
|
|
89
|
+
// Compare hashes
|
|
90
|
+
const stagedHash = await gitSafe(['rev-parse', `:${stagedPath}`], { cwd });
|
|
91
|
+
const shadowHash = await gitSafe(['rev-parse', `refs/heads/${shadowBranchName}:${stagedPath}`], { cwd });
|
|
92
|
+
if (stagedHash && shadowHash && stagedHash.trim() === shadowHash.trim()) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
// Check significant overlap
|
|
96
|
+
if (hasSignificantContentOverlap(stagedContent, shadowContent)) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Return files from filesTouched that still have uncommitted agent changes.
|
|
104
|
+
*/
|
|
105
|
+
export async function filesWithRemainingAgentChanges(shadowBranchName, headCommitHash, filesTouched, committedFiles, cwd) {
|
|
106
|
+
const remaining = [];
|
|
107
|
+
for (const filePath of filesTouched) {
|
|
108
|
+
if (!committedFiles.has(filePath)) {
|
|
109
|
+
remaining.push(filePath);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
// File was committed - check if committed content matches shadow
|
|
113
|
+
const commitHash = await gitSafe(['rev-parse', `${headCommitHash}:${filePath}`], { cwd });
|
|
114
|
+
const shadowHash = await gitSafe(['rev-parse', `refs/heads/${shadowBranchName}:${filePath}`], {
|
|
115
|
+
cwd,
|
|
116
|
+
});
|
|
117
|
+
if (commitHash === null || shadowHash === null)
|
|
118
|
+
continue;
|
|
119
|
+
if (commitHash.trim() === shadowHash.trim())
|
|
120
|
+
continue;
|
|
121
|
+
// Content differs - check if working tree is clean for this file
|
|
122
|
+
const workingDiff = await gitSafe(['diff', '--name-only', 'HEAD', '--', filePath], { cwd });
|
|
123
|
+
if (workingDiff !== null && workingDiff.trim() === '') {
|
|
124
|
+
// Working tree is clean - user intentionally wrote different content
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
remaining.push(filePath);
|
|
128
|
+
}
|
|
129
|
+
return remaining;
|
|
130
|
+
}
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Content Overlap Helpers
|
|
133
|
+
// ============================================================================
|
|
134
|
+
/**
|
|
135
|
+
* Check if two file contents share significant lines.
|
|
136
|
+
* Distinguishes partial staging from "reverted and replaced".
|
|
137
|
+
*/
|
|
138
|
+
export function hasSignificantContentOverlap(stagedContent, shadowContent) {
|
|
139
|
+
const shadowLines = extractSignificantLines(shadowContent);
|
|
140
|
+
const stagedLines = extractSignificantLines(stagedContent);
|
|
141
|
+
if (shadowLines.size === 0 || stagedLines.size === 0)
|
|
142
|
+
return false;
|
|
143
|
+
const isVerySmallFile = shadowLines.size < 2 || stagedLines.size < 2;
|
|
144
|
+
const requiredMatches = isVerySmallFile ? 1 : 2;
|
|
145
|
+
let matchCount = 0;
|
|
146
|
+
for (const line of stagedLines) {
|
|
147
|
+
if (shadowLines.has(line)) {
|
|
148
|
+
matchCount++;
|
|
149
|
+
if (matchCount >= requiredMatches)
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Extract significant lines from content (>= 10 chars after trimming).
|
|
157
|
+
* Short lines like `{`, `}`, `});` are filtered as common boilerplate.
|
|
158
|
+
*/
|
|
159
|
+
function extractSignificantLines(content) {
|
|
160
|
+
const lines = new Set();
|
|
161
|
+
for (const line of content.split('\n')) {
|
|
162
|
+
const trimmed = line.trim();
|
|
163
|
+
if (trimmed.length >= 10) {
|
|
164
|
+
lines.add(trimmed);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return lines;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Simple filename-based overlap check (fallback).
|
|
171
|
+
*/
|
|
172
|
+
export function hasOverlappingFiles(stagedFiles, filesTouched) {
|
|
173
|
+
const touchedSet = new Set(filesTouched);
|
|
174
|
+
return stagedFiles.some((f) => touchedSet.has(f));
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=content-overlap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-overlap.js","sourceRoot":"","sources":["../../src/strategy/content-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,gBAAwB,EACxB,cAAsB,EACtB,gBAA+B,EAC/B,YAAsB,EACtB,GAAY;IAEZ,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,yCAAyC;QACzC,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,cAAc,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACtF,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,qDAAqD;YACrD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,gBAAgB,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC1F,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;oBAC3B,8DAA8D;oBAC9D,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YACD,SAAS;QACX,CAAC;QAED,kEAAkE;QAClE,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,gBAAgB,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YAC1F,UAAU,GAAG,aAAa,KAAK,IAAI,CAAC;QACtC,CAAC;QAED,yCAAyC;QACzC,IAAI,UAAU;YAAE,OAAO,IAAI,CAAC;QAE5B,qDAAqD;QACrD,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,cAAc,gBAAgB,IAAI,QAAQ,EAAE,CAAC,EAAE;YAC1F,GAAG;SACJ,CAAC,CAAC;QACH,IAAI,aAAa,KAAK,IAAI;YAAE,SAAS;QAErC,uCAAuC;QACvC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,CAAC,WAAW,EAAE,GAAG,cAAc,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACxF,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,CAAC,WAAW,EAAE,cAAc,gBAAgB,IAAI,QAAQ,EAAE,CAAC,EAAE;YAC5F,GAAG;SACJ,CAAC,CAAC;QAEH,IAAI,QAAQ,KAAK,IAAI,IAAI,UAAU,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACtF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,yDAAyD;QACzD,IAAI,WAAW,IAAI,aAAa,IAAI,4BAA4B,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,CAAC;YAC7F,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,gBAAwB,EACxB,WAAqB,EACrB,YAAsB,EACtB,GAAY;IAEZ,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IAEzC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,SAAS;QAE1C,4CAA4C;QAC5C,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,QAAQ,UAAU,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,GAAG,WAAW,KAAK,IAAI,CAAC;QAExC,IAAI,UAAU;YAAE,OAAO,IAAI,CAAC;QAE5B,oDAAoD;QACpD,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,cAAc,gBAAgB,IAAI,UAAU,EAAE,CAAC,EAAE;YAC5F,GAAG;SACJ,CAAC,CAAC;QACH,IAAI,aAAa,KAAK,IAAI;YAAE,SAAS;QAErC,qBAAqB;QACrB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACzE,IAAI,aAAa,KAAK,IAAI;YAAE,SAAS;QAErC,iBAAiB;QACjB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,CAAC,WAAW,EAAE,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,GAAG,MAAM,OAAO,CAC9B,CAAC,WAAW,EAAE,cAAc,gBAAgB,IAAI,UAAU,EAAE,CAAC,EAC7D,EAAE,GAAG,EAAE,CACR,CAAC;QAEF,IAAI,UAAU,IAAI,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACxE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,4BAA4B;QAC5B,IAAI,4BAA4B,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,gBAAwB,EACxB,cAAsB,EACtB,YAAsB,EACtB,cAA2B,EAC3B,GAAY;IAEZ,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QAED,iEAAiE;QACjE,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,CAAC,WAAW,EAAE,GAAG,cAAc,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1F,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,CAAC,WAAW,EAAE,cAAc,gBAAgB,IAAI,QAAQ,EAAE,CAAC,EAAE;YAC5F,GAAG;SACJ,CAAC,CAAC;QAEH,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,IAAI;YAAE,SAAS;QACzD,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,UAAU,CAAC,IAAI,EAAE;YAAE,SAAS;QAEtD,iEAAiE;QACjE,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5F,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACtD,qEAAqE;YACrE,SAAS;QACX,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,aAAqB,EACrB,aAAqB;IAErB,MAAM,WAAW,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAC;IAE3D,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEnE,MAAM,eAAe,GAAG,WAAW,CAAC,IAAI,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,CAAC;IACrE,MAAM,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,UAAU,EAAE,CAAC;YACb,IAAI,UAAU,IAAI,eAAe;gBAAE,OAAO,IAAI,CAAC;QACjD,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,uBAAuB,CAAC,OAAe;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACzB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAqB,EAAE,YAAsB;IAC/E,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IACzC,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manual Commit Strategy
|
|
3
|
+
*
|
|
4
|
+
* Core strategy implementation that orchestrates session tracking,
|
|
5
|
+
* checkpoint creation, condensation, and git hook integration.
|
|
6
|
+
*
|
|
7
|
+
* Data flow:
|
|
8
|
+
* 1. InitializeSession -> Creates SessionState, calculates initial attribution
|
|
9
|
+
* 2. SaveStep/SaveTaskStep -> Writes to shadow branch via CheckpointStore
|
|
10
|
+
* 3. PrepareCommitMsg -> Adds Entire-Checkpoint trailer to commit messages
|
|
11
|
+
* 4. PostCommit -> Condenses session data, handles carry-forward
|
|
12
|
+
* 5. PrePush -> Pushes metadata branch alongside user push
|
|
13
|
+
*/
|
|
14
|
+
import type { SessionStore } from '../store/session-store.js';
|
|
15
|
+
import type { CheckpointStore } from '../store/checkpoint-store.js';
|
|
16
|
+
import type { Strategy } from './types.js';
|
|
17
|
+
export interface ManualCommitStrategyConfig {
|
|
18
|
+
sessionStore: SessionStore;
|
|
19
|
+
checkpointStore: CheckpointStore;
|
|
20
|
+
cwd?: string;
|
|
21
|
+
/** When a separate session repo is configured, this is its working directory.
|
|
22
|
+
* Used for pushing the checkpoints branch from the correct repo. */
|
|
23
|
+
sessionRepoCwd?: string;
|
|
24
|
+
/** Override for the checkpoints branch name (e.g. project-namespaced). */
|
|
25
|
+
checkpointsBranch?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function createManualCommitStrategy(config: ManualCommitStrategyConfig): Strategy;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a commit message has any content besides comments and our trailer.
|
|
30
|
+
*/
|
|
31
|
+
export declare function hasUserContent(message: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Remove the Entire-Checkpoint trailer line from a commit message.
|
|
34
|
+
*/
|
|
35
|
+
export declare function stripCheckpointTrailer(message: string): string;
|
|
36
|
+
//# sourceMappingURL=manual-commit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual-commit.d.ts","sourceRoot":"","sources":["../../src/strategy/manual-commit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAgCpE,OAAO,KAAK,EACV,QAAQ,EAMT,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,0BAA0B;IACzC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;yEACqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,0BAA0B,GAAG,QAAQ,CA8vBvF;AAiCD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAUvD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM9D"}
|