chatroom-cli 1.32.1 → 1.33.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +105 -0
- package/dist/infrastructure/git/git-writer.d.ts +48 -0
- package/dist/infrastructure/git/git-writer.d.ts.map +1 -0
- package/dist/infrastructure/git/git-writer.js +127 -0
- package/dist/infrastructure/git/git-writer.js.map +1 -0
- package/dist/infrastructure/git/index.d.ts +3 -2
- package/dist/infrastructure/git/index.d.ts.map +1 -1
- package/dist/infrastructure/git/index.js +2 -1
- package/dist/infrastructure/git/index.js.map +1 -1
- package/dist/infrastructure/git/types.d.ts +25 -0
- package/dist/infrastructure/git/types.d.ts.map +1 -1
- package/dist/infrastructure/git/types.js.map +1 -1
- package/dist/infrastructure/local-actions/execute-local-action.d.ts +4 -1
- package/dist/infrastructure/local-actions/execute-local-action.d.ts.map +1 -1
- package/dist/infrastructure/local-actions/execute-local-action.js +34 -1
- package/dist/infrastructure/local-actions/execute-local-action.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -57867,6 +57867,80 @@ var init_on_daemon_shutdown = __esm(() => {
|
|
|
57867
57867
|
init_api3();
|
|
57868
57868
|
});
|
|
57869
57869
|
|
|
57870
|
+
// src/infrastructure/git/git-writer.ts
|
|
57871
|
+
import { exec as exec6 } from "node:child_process";
|
|
57872
|
+
import { promisify as promisify5 } from "node:util";
|
|
57873
|
+
async function runGit2(args, cwd) {
|
|
57874
|
+
try {
|
|
57875
|
+
const result = await execAsync4(`git ${args}`, {
|
|
57876
|
+
cwd,
|
|
57877
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0", GIT_PAGER: "cat", NO_COLOR: "1" },
|
|
57878
|
+
timeout: 30000
|
|
57879
|
+
});
|
|
57880
|
+
return result;
|
|
57881
|
+
} catch (err) {
|
|
57882
|
+
return { error: err };
|
|
57883
|
+
}
|
|
57884
|
+
}
|
|
57885
|
+
function classifyError2(errMessage) {
|
|
57886
|
+
return { status: "error", message: errMessage.trim() };
|
|
57887
|
+
}
|
|
57888
|
+
async function discardFile(workingDir, filePath) {
|
|
57889
|
+
const result = await runGit2(`checkout -- ${filePath}`, workingDir);
|
|
57890
|
+
if ("error" in result) {
|
|
57891
|
+
return classifyError2(result.error.message);
|
|
57892
|
+
}
|
|
57893
|
+
return { status: "available" };
|
|
57894
|
+
}
|
|
57895
|
+
async function discardAllChanges(workingDir) {
|
|
57896
|
+
const checkoutResult = await runGit2("checkout -- .", workingDir);
|
|
57897
|
+
if ("error" in checkoutResult) {
|
|
57898
|
+
return classifyError2(checkoutResult.error.message);
|
|
57899
|
+
}
|
|
57900
|
+
const cleanResult = await runGit2("clean -fd", workingDir);
|
|
57901
|
+
if ("error" in cleanResult) {
|
|
57902
|
+
return classifyError2(cleanResult.error.message);
|
|
57903
|
+
}
|
|
57904
|
+
return { status: "available" };
|
|
57905
|
+
}
|
|
57906
|
+
async function gitPull(workingDir) {
|
|
57907
|
+
const result = await runGit2("pull", workingDir);
|
|
57908
|
+
if ("error" in result) {
|
|
57909
|
+
const message = result.error.message;
|
|
57910
|
+
if (message.includes("no tracking branch")) {
|
|
57911
|
+
return {
|
|
57912
|
+
status: "error",
|
|
57913
|
+
message: "No tracking branch configured. Set upstream with `git push -u`."
|
|
57914
|
+
};
|
|
57915
|
+
}
|
|
57916
|
+
if (message.includes("conflict")) {
|
|
57917
|
+
return { status: "error", message: "Merge conflict detected. Resolve conflicts manually." };
|
|
57918
|
+
}
|
|
57919
|
+
if (message.includes("Authentication failed") || message.includes("could not read")) {
|
|
57920
|
+
return {
|
|
57921
|
+
status: "error",
|
|
57922
|
+
message: "Authentication failed. Run `gh auth status` to check your GitHub credentials."
|
|
57923
|
+
};
|
|
57924
|
+
}
|
|
57925
|
+
return classifyError2(message);
|
|
57926
|
+
}
|
|
57927
|
+
const stderr = result.stderr.trim();
|
|
57928
|
+
if (stderr && !stderr.includes("Already up to date")) {
|
|
57929
|
+
return { status: "available", message: stderr };
|
|
57930
|
+
}
|
|
57931
|
+
return { status: "available" };
|
|
57932
|
+
}
|
|
57933
|
+
var execAsync4;
|
|
57934
|
+
var init_git_writer = __esm(() => {
|
|
57935
|
+
execAsync4 = promisify5(exec6);
|
|
57936
|
+
});
|
|
57937
|
+
|
|
57938
|
+
// src/infrastructure/git/index.ts
|
|
57939
|
+
var init_git = __esm(() => {
|
|
57940
|
+
init_git_reader();
|
|
57941
|
+
init_git_writer();
|
|
57942
|
+
});
|
|
57943
|
+
|
|
57870
57944
|
// src/infrastructure/local-actions/execute-local-action.ts
|
|
57871
57945
|
import { access as access5 } from "node:fs/promises";
|
|
57872
57946
|
function resolveOpenCommand2(platform) {
|
|
@@ -57910,6 +57984,36 @@ async function executeLocalAction(action, workingDir) {
|
|
|
57910
57984
|
execFireAndForget(`github ${escapeShellArg(workingDir)}`, "open-github-desktop");
|
|
57911
57985
|
return { success: true };
|
|
57912
57986
|
}
|
|
57987
|
+
case "git-discard-file": {
|
|
57988
|
+
const separatorIndex = workingDir.indexOf("::");
|
|
57989
|
+
if (separatorIndex === -1) {
|
|
57990
|
+
return {
|
|
57991
|
+
success: false,
|
|
57992
|
+
error: 'Invalid file path. Expected format: "/path/to/dir::/path/to/file"'
|
|
57993
|
+
};
|
|
57994
|
+
}
|
|
57995
|
+
const dir = workingDir.slice(0, separatorIndex);
|
|
57996
|
+
const filePath = workingDir.slice(separatorIndex + 2);
|
|
57997
|
+
const result = await discardFile(dir, filePath);
|
|
57998
|
+
if (result.status === "error") {
|
|
57999
|
+
return { success: false, error: result.message };
|
|
58000
|
+
}
|
|
58001
|
+
return { success: true };
|
|
58002
|
+
}
|
|
58003
|
+
case "git-discard-all": {
|
|
58004
|
+
const result = await discardAllChanges(workingDir);
|
|
58005
|
+
if (result.status === "error") {
|
|
58006
|
+
return { success: false, error: result.message };
|
|
58007
|
+
}
|
|
58008
|
+
return { success: true };
|
|
58009
|
+
}
|
|
58010
|
+
case "git-pull": {
|
|
58011
|
+
const result = await gitPull(workingDir);
|
|
58012
|
+
if (result.status === "error") {
|
|
58013
|
+
return { success: false, error: result.message };
|
|
58014
|
+
}
|
|
58015
|
+
return { success: true, message: result.message ?? "Pull successful" };
|
|
58016
|
+
}
|
|
57913
58017
|
default: {
|
|
57914
58018
|
const _exhaustive = action;
|
|
57915
58019
|
return { success: false, error: `Unknown action: ${_exhaustive}` };
|
|
@@ -57918,6 +58022,7 @@ async function executeLocalAction(action, workingDir) {
|
|
|
57918
58022
|
}
|
|
57919
58023
|
var init_execute_local_action = __esm(() => {
|
|
57920
58024
|
init_shared_utils();
|
|
58025
|
+
init_git();
|
|
57921
58026
|
});
|
|
57922
58027
|
|
|
57923
58028
|
// src/infrastructure/local-actions/index.ts
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git write operations (modifying the working tree).
|
|
3
|
+
*
|
|
4
|
+
* All functions return discriminated unions — no throws.
|
|
5
|
+
* Errors from git (non-zero exit) or missing git installation are
|
|
6
|
+
* captured and returned as `{ status: 'error' }`.
|
|
7
|
+
*/
|
|
8
|
+
import type { GitDiscardResult, GitPullResult } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Discard changes to a specific file.
|
|
11
|
+
*
|
|
12
|
+
* Uses `git checkout -- <file>` to restore the file to HEAD.
|
|
13
|
+
*
|
|
14
|
+
* Returns `{ status: 'available' }` on success.
|
|
15
|
+
* Returns `{ status: 'error', message }` on failure.
|
|
16
|
+
*/
|
|
17
|
+
export declare function discardFile(workingDir: string, filePath: string): Promise<GitDiscardResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Discard all changes in the working tree.
|
|
20
|
+
*
|
|
21
|
+
* Uses `git checkout -- .` to restore all tracked files to HEAD,
|
|
22
|
+
* then `git clean -fd` to remove untracked files.
|
|
23
|
+
*
|
|
24
|
+
* Returns `{ status: 'available' }` on success.
|
|
25
|
+
* Returns `{ status: 'error', message }` on failure.
|
|
26
|
+
*
|
|
27
|
+
* Note: This will permanently delete untracked files!
|
|
28
|
+
*/
|
|
29
|
+
export declare function discardAllChanges(workingDir: string): Promise<GitDiscardResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Discard staged changes (unstage all).
|
|
32
|
+
*
|
|
33
|
+
* Uses `git reset HEAD` to unstage all staged changes.
|
|
34
|
+
*
|
|
35
|
+
* Returns `{ status: 'available' }` on success.
|
|
36
|
+
* Returns `{ status: 'error', message }` on failure.
|
|
37
|
+
*/
|
|
38
|
+
export declare function discardStaged(workingDir: string): Promise<GitDiscardResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Perform a git pull from the default remote.
|
|
41
|
+
*
|
|
42
|
+
* Uses `git pull` to fetch and merge from the tracking branch.
|
|
43
|
+
*
|
|
44
|
+
* Returns `{ status: 'available' }` on success.
|
|
45
|
+
* Returns `{ status: 'error', message }` on failure.
|
|
46
|
+
*/
|
|
47
|
+
export declare function gitPull(workingDir: string): Promise<GitPullResult>;
|
|
48
|
+
//# sourceMappingURL=git-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-writer.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/git/git-writer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgClE;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAQjG;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAcrF;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAQjF;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAgCxE"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git write operations (modifying the working tree).
|
|
3
|
+
*
|
|
4
|
+
* All functions return discriminated unions — no throws.
|
|
5
|
+
* Errors from git (non-zero exit) or missing git installation are
|
|
6
|
+
* captured and returned as `{ status: 'error' }`.
|
|
7
|
+
*/
|
|
8
|
+
import { exec } from 'node:child_process';
|
|
9
|
+
import { promisify } from 'node:util';
|
|
10
|
+
const execAsync = promisify(exec);
|
|
11
|
+
/**
|
|
12
|
+
* Run a git command in `cwd`.
|
|
13
|
+
* Returns `{ stdout, stderr }` on success, `{ error }` on failure.
|
|
14
|
+
* Never throws.
|
|
15
|
+
*/
|
|
16
|
+
async function runGit(args, cwd) {
|
|
17
|
+
try {
|
|
18
|
+
const result = await execAsync(`git ${args}`, {
|
|
19
|
+
cwd,
|
|
20
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: '0', GIT_PAGER: 'cat', NO_COLOR: '1' },
|
|
21
|
+
timeout: 30_000, // 30s timeout for destructive operations
|
|
22
|
+
});
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
return { error: err };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Classify a git error into a structured result.
|
|
31
|
+
*/
|
|
32
|
+
function classifyError(errMessage) {
|
|
33
|
+
return { status: 'error', message: errMessage.trim() };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Discard changes to a specific file.
|
|
37
|
+
*
|
|
38
|
+
* Uses `git checkout -- <file>` to restore the file to HEAD.
|
|
39
|
+
*
|
|
40
|
+
* Returns `{ status: 'available' }` on success.
|
|
41
|
+
* Returns `{ status: 'error', message }` on failure.
|
|
42
|
+
*/
|
|
43
|
+
export async function discardFile(workingDir, filePath) {
|
|
44
|
+
const result = await runGit(`checkout -- ${filePath}`, workingDir);
|
|
45
|
+
if ('error' in result) {
|
|
46
|
+
return classifyError(result.error.message);
|
|
47
|
+
}
|
|
48
|
+
return { status: 'available' };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Discard all changes in the working tree.
|
|
52
|
+
*
|
|
53
|
+
* Uses `git checkout -- .` to restore all tracked files to HEAD,
|
|
54
|
+
* then `git clean -fd` to remove untracked files.
|
|
55
|
+
*
|
|
56
|
+
* Returns `{ status: 'available' }` on success.
|
|
57
|
+
* Returns `{ status: 'error', message }` on failure.
|
|
58
|
+
*
|
|
59
|
+
* Note: This will permanently delete untracked files!
|
|
60
|
+
*/
|
|
61
|
+
export async function discardAllChanges(workingDir) {
|
|
62
|
+
// First, checkout all tracked files
|
|
63
|
+
const checkoutResult = await runGit('checkout -- .', workingDir);
|
|
64
|
+
if ('error' in checkoutResult) {
|
|
65
|
+
return classifyError(checkoutResult.error.message);
|
|
66
|
+
}
|
|
67
|
+
// Then, clean untracked files and directories
|
|
68
|
+
const cleanResult = await runGit('clean -fd', workingDir);
|
|
69
|
+
if ('error' in cleanResult) {
|
|
70
|
+
return classifyError(cleanResult.error.message);
|
|
71
|
+
}
|
|
72
|
+
return { status: 'available' };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Discard staged changes (unstage all).
|
|
76
|
+
*
|
|
77
|
+
* Uses `git reset HEAD` to unstage all staged changes.
|
|
78
|
+
*
|
|
79
|
+
* Returns `{ status: 'available' }` on success.
|
|
80
|
+
* Returns `{ status: 'error', message }` on failure.
|
|
81
|
+
*/
|
|
82
|
+
export async function discardStaged(workingDir) {
|
|
83
|
+
const result = await runGit('reset HEAD', workingDir);
|
|
84
|
+
if ('error' in result) {
|
|
85
|
+
return classifyError(result.error.message);
|
|
86
|
+
}
|
|
87
|
+
return { status: 'available' };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Perform a git pull from the default remote.
|
|
91
|
+
*
|
|
92
|
+
* Uses `git pull` to fetch and merge from the tracking branch.
|
|
93
|
+
*
|
|
94
|
+
* Returns `{ status: 'available' }` on success.
|
|
95
|
+
* Returns `{ status: 'error', message }` on failure.
|
|
96
|
+
*/
|
|
97
|
+
export async function gitPull(workingDir) {
|
|
98
|
+
const result = await runGit('pull', workingDir);
|
|
99
|
+
if ('error' in result) {
|
|
100
|
+
const message = result.error.message;
|
|
101
|
+
// Check for common specific errors to provide better messages
|
|
102
|
+
if (message.includes('no tracking branch')) {
|
|
103
|
+
return {
|
|
104
|
+
status: 'error',
|
|
105
|
+
message: 'No tracking branch configured. Set upstream with `git push -u`.',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (message.includes('conflict')) {
|
|
109
|
+
return { status: 'error', message: 'Merge conflict detected. Resolve conflicts manually.' };
|
|
110
|
+
}
|
|
111
|
+
if (message.includes('Authentication failed') || message.includes('could not read')) {
|
|
112
|
+
return {
|
|
113
|
+
status: 'error',
|
|
114
|
+
message: 'Authentication failed. Run `gh auth status` to check your GitHub credentials.',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return classifyError(message);
|
|
118
|
+
}
|
|
119
|
+
// Check stderr for non-fatal warnings (like "Already up to date.")
|
|
120
|
+
const stderr = result.stderr.trim();
|
|
121
|
+
if (stderr && !stderr.includes('Already up to date')) {
|
|
122
|
+
// Pull succeeded but with warnings - still available
|
|
123
|
+
return { status: 'available', message: stderr };
|
|
124
|
+
}
|
|
125
|
+
return { status: 'available' };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=git-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-writer.js","sourceRoot":"","sources":["../../../src/infrastructure/git/git-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Git infrastructure — public API.
|
|
3
3
|
*
|
|
4
|
-
* Re-exports all types and
|
|
4
|
+
* Re-exports all types and functions from the git sub-module.
|
|
5
5
|
*/
|
|
6
|
-
export type { DiffStat, GitCommit, GitBranchResult, GitDiffStatResult, GitFullDiffResult, GitCommitDetailResult, } from './types.js';
|
|
6
|
+
export type { DiffStat, GitCommit, GitBranchResult, GitDiffStatResult, GitFullDiffResult, GitCommitDetailResult, GitDiscardResult, GitPullResult, } from './types.js';
|
|
7
7
|
export { FULL_DIFF_MAX_BYTES, makeGitStateKey } from './types.js';
|
|
8
8
|
export { isGitRepo, getBranch, isDirty, getDiffStat, getFullDiff, getRecentCommits, getCommitDetail, parseDiffStatLine, } from './git-reader.js';
|
|
9
|
+
export { discardFile, discardAllChanges, discardStaged, gitPull } from './git-writer.js';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/git/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EACV,QAAQ,EACR,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/git/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EACV,QAAQ,EACR,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE,OAAO,EACL,SAAS,EACT,SAAS,EACT,OAAO,EACP,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Git infrastructure — public API.
|
|
3
3
|
*
|
|
4
|
-
* Re-exports all types and
|
|
4
|
+
* Re-exports all types and functions from the git sub-module.
|
|
5
5
|
*/
|
|
6
6
|
export { FULL_DIFF_MAX_BYTES, makeGitStateKey } from './types.js';
|
|
7
7
|
export { isGitRepo, getBranch, isDirty, getDiffStat, getFullDiff, getRecentCommits, getCommitDetail, parseDiffStatLine, } from './git-reader.js';
|
|
8
|
+
export { discardFile, discardAllChanges, discardStaged, gitPull } from './git-writer.js';
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/git/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/git/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE,OAAO,EACL,SAAS,EACT,SAAS,EACT,OAAO,EACP,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -88,6 +88,31 @@ export type GitCommitDetailResult = {
|
|
|
88
88
|
status: 'error';
|
|
89
89
|
message: string;
|
|
90
90
|
};
|
|
91
|
+
/**
|
|
92
|
+
* Result of discard operations (`discardFile`, `discardAllChanges`, `discardStaged`).
|
|
93
|
+
*
|
|
94
|
+
* - `available`: operation succeeded
|
|
95
|
+
* - `error`: operation failed with message
|
|
96
|
+
*/
|
|
97
|
+
export type GitDiscardResult = {
|
|
98
|
+
status: 'available';
|
|
99
|
+
} | {
|
|
100
|
+
status: 'error';
|
|
101
|
+
message: string;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Result of `gitPull`.
|
|
105
|
+
*
|
|
106
|
+
* - `available`: pull succeeded (may include non-fatal message)
|
|
107
|
+
* - `error`: pull failed with message
|
|
108
|
+
*/
|
|
109
|
+
export type GitPullResult = {
|
|
110
|
+
status: 'available';
|
|
111
|
+
message?: string;
|
|
112
|
+
} | {
|
|
113
|
+
status: 'error';
|
|
114
|
+
message: string;
|
|
115
|
+
};
|
|
91
116
|
/** Maximum byte size for full diff content before truncation. */
|
|
92
117
|
export declare const FULL_DIFF_MAX_BYTES = 500000;
|
|
93
118
|
/** Number of commits to fetch per page for git history. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/git/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/git/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,SAAS,EACT,cAAc,EACf,MAAM,mDAAmD,CAAC;AAG3D,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;AAIpD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAC3C;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,KAAK,CAAA;CAAE,GAC1D;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,GACzD;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,KAAK,CAAA;CAAE,GAC1D;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,GACzD;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9F;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,iEAAiE;AACjE,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAE3C,2DAA2D;AAC3D,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE7E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/infrastructure/git/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/infrastructure/git/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuFH,iEAAiE;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC,CAAC,SAAS;AAErD,2DAA2D;AAC3D,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,UAAkB;IACnE,OAAO,GAAG,SAAS,KAAK,UAAU,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Local Action Executor
|
|
3
3
|
*
|
|
4
|
-
* Shared module for executing local actions (open-vscode, open-finder, open-github-desktop).
|
|
4
|
+
* Shared module for executing local actions (open-vscode, open-finder, open-github-desktop, git operations).
|
|
5
5
|
* Used by both:
|
|
6
6
|
* - The local HTTP API routes (for direct localhost calls from Chrome)
|
|
7
7
|
* - The daemon command loop (for Convex-relayed actions from Safari/all browsers)
|
|
@@ -12,6 +12,9 @@ export type { LocalActionType };
|
|
|
12
12
|
/** Result of executing a local action. */
|
|
13
13
|
export type LocalActionResult = {
|
|
14
14
|
success: true;
|
|
15
|
+
} | {
|
|
16
|
+
success: true;
|
|
17
|
+
message: string;
|
|
15
18
|
} | {
|
|
16
19
|
success: false;
|
|
17
20
|
error: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-local-action.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/local-actions/execute-local-action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"execute-local-action.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/local-actions/execute-local-action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkBH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAEjF,8DAA8D;AAC9D,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,0CAA0C;AAC1C,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBtC;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,CAAC,CA8E5B"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Local Action Executor
|
|
3
3
|
*
|
|
4
|
-
* Shared module for executing local actions (open-vscode, open-finder, open-github-desktop).
|
|
4
|
+
* Shared module for executing local actions (open-vscode, open-finder, open-github-desktop, git operations).
|
|
5
5
|
* Used by both:
|
|
6
6
|
* - The local HTTP API routes (for direct localhost calls from Chrome)
|
|
7
7
|
* - The daemon command loop (for Convex-relayed actions from Safari/all browsers)
|
|
8
8
|
*/
|
|
9
9
|
import { access } from 'node:fs/promises';
|
|
10
10
|
import { escapeShellArg, isCliAvailable, execFireAndForget, } from '../local-api/routes/shared-utils.js';
|
|
11
|
+
import { discardFile as gitDiscardFile, discardAllChanges as gitDiscardAll, gitPull, } from '../git/index.js';
|
|
11
12
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
12
13
|
/**
|
|
13
14
|
* Resolve the platform-specific command used to open a folder in the file explorer.
|
|
@@ -66,6 +67,38 @@ export async function executeLocalAction(action, workingDir) {
|
|
|
66
67
|
execFireAndForget(`github ${escapeShellArg(workingDir)}`, 'open-github-desktop');
|
|
67
68
|
return { success: true };
|
|
68
69
|
}
|
|
70
|
+
case 'git-discard-file': {
|
|
71
|
+
// Extract file path from workingDir parameter (format: "directory::filePath")
|
|
72
|
+
// We use workingDir parameter to carry both directory and file path
|
|
73
|
+
const separatorIndex = workingDir.indexOf('::');
|
|
74
|
+
if (separatorIndex === -1) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
error: 'Invalid file path. Expected format: "/path/to/dir::/path/to/file"',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const dir = workingDir.slice(0, separatorIndex);
|
|
81
|
+
const filePath = workingDir.slice(separatorIndex + 2);
|
|
82
|
+
const result = await gitDiscardFile(dir, filePath);
|
|
83
|
+
if (result.status === 'error') {
|
|
84
|
+
return { success: false, error: result.message };
|
|
85
|
+
}
|
|
86
|
+
return { success: true };
|
|
87
|
+
}
|
|
88
|
+
case 'git-discard-all': {
|
|
89
|
+
const result = await gitDiscardAll(workingDir);
|
|
90
|
+
if (result.status === 'error') {
|
|
91
|
+
return { success: false, error: result.message };
|
|
92
|
+
}
|
|
93
|
+
return { success: true };
|
|
94
|
+
}
|
|
95
|
+
case 'git-pull': {
|
|
96
|
+
const result = await gitPull(workingDir);
|
|
97
|
+
if (result.status === 'error') {
|
|
98
|
+
return { success: false, error: result.message };
|
|
99
|
+
}
|
|
100
|
+
return { success: true, message: result.message ?? 'Pull successful' };
|
|
101
|
+
}
|
|
69
102
|
default: {
|
|
70
103
|
// Exhaustive check
|
|
71
104
|
const _exhaustive = action;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-local-action.js","sourceRoot":"","sources":["../../../src/infrastructure/local-actions/execute-local-action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EACL,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"execute-local-action.js","sourceRoot":"","sources":["../../../src/infrastructure/local-actions/execute-local-action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EACL,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EACL,WAAW,IAAI,cAAc,EAC7B,iBAAiB,IAAI,aAAa,EAClC,OAAO,GACR,MAAM,iBAAiB,CAAC;AAezB,iFAAiF;AAEjF;;GAEG;AACH,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,UAAU,CAAC;QACpB;YACE,OAAO,UAAU,CAAC;IACtB,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAuB,EACvB,UAAkB;IAElB,4BAA4B;IAC5B,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,UAAU,EAAE,EAAE,CAAC;IACzE,CAAC;IAED,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;YAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EACH,0GAA0G;iBAC7G,CAAC;YACJ,CAAC;YACD,iBAAiB,CAAC,QAAQ,cAAc,CAAC,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;YACvE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,GAAG,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACjD,iBAAiB,CAAC,GAAG,GAAG,IAAI,cAAc,CAAC,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;YACzE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;YACjD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;YACnE,CAAC;YACD,iBAAiB,CAAC,UAAU,cAAc,CAAC,UAAU,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC;YACjF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,KAAK,kBAAkB,CAAC,CAAC,CAAC;YACxB,8EAA8E;YAC9E,oEAAoE;YACpE,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,cAAc,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC1B,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,mEAAmE;iBAC3E,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;YACtD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACnD,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACnD,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;YACvB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,CAAC;YAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACnD,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;YACzC,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACnD,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACzE,CAAC;QAED,OAAO,CAAC,CAAC,CAAC;YACR,mBAAmB;YACnB,MAAM,WAAW,GAAU,MAAM,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,WAAW,EAAE,EAAE,CAAC;QACrE,CAAC;IACH,CAAC;AACH,CAAC"}
|