Skip to content

Commit 5e4cd94

Browse files
committed
LLM Code Walkthrough.
1 parent 22b1c8f commit 5e4cd94

9 files changed

Lines changed: 980 additions & 57 deletions

File tree

bin/codiff-app

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,28 @@ done
1515

1616
script_dir="$(CDPATH= cd -P "$(dirname "$source_path")" >/dev/null 2>&1 && pwd)"
1717
app_path="$(CDPATH= cd -P "$script_dir/../../../.." >/dev/null 2>&1 && pwd)"
18-
repository_path="${1:-$PWD}"
18+
repository_path=""
19+
walkthrough=0
1920

20-
open -n "$app_path" --args "$repository_path"
21+
for arg in "$@"; do
22+
case "$arg" in
23+
--walkthrough|-w)
24+
walkthrough=1
25+
;;
26+
-*)
27+
;;
28+
*)
29+
if [ -z "$repository_path" ]; then
30+
repository_path="$arg"
31+
fi
32+
;;
33+
esac
34+
done
35+
36+
repository_path="${repository_path:-$PWD}"
37+
38+
if [ "$walkthrough" -eq 1 ]; then
39+
open -n "$app_path" --args --walkthrough "$repository_path"
40+
else
41+
open -n "$app_path" --args "$repository_path"
42+
fi

bin/codiff.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,29 @@ import { fileURLToPath } from 'node:url';
77
import electron from 'electron';
88

99
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
10-
const requestedPath = resolve(process.argv[2] ?? process.cwd());
10+
11+
const parseArguments = (args) => {
12+
let walkthrough = false;
13+
let requestedPath = null;
14+
15+
for (const arg of args) {
16+
if (arg === '--walkthrough' || arg === '-w') {
17+
walkthrough = true;
18+
continue;
19+
}
20+
21+
if (!arg.startsWith('-') && requestedPath == null) {
22+
requestedPath = arg;
23+
}
24+
}
25+
26+
return {
27+
requestedPath: resolve(requestedPath ?? process.cwd()),
28+
walkthrough,
29+
};
30+
};
31+
32+
const { requestedPath, walkthrough } = parseArguments(process.argv.slice(2));
1133

1234
if (!existsSync(resolve(root, 'dist/index.html')) && !process.env.ELECTRON_RENDERER_URL) {
1335
console.error('Codiff has not been built yet. Run `pnpm build` first.');
@@ -18,6 +40,7 @@ const child = spawn(electron, [root], {
1840
env: {
1941
...process.env,
2042
CODIFF_REPOSITORY_PATH: requestedPath,
43+
CODIFF_WALKTHROUGH: walkthrough ? '1' : '',
2144
},
2245
stdio: 'inherit',
2346
});

electron/main.cjs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ const {
3030
readRepositoryState,
3131
validateRepositoryPath,
3232
} = require('./git-state.cjs');
33+
const { readWalkthrough } = require('./walkthrough.cjs');
3334

3435
const root = dirname(__dirname);
3536
const repositoryWatchers = new Map();
3637
const windowRepositories = new Map();
38+
const windowLaunchOptions = new Map();
3739
let preferences = {
3840
showWhitespace: false,
3941
};
@@ -43,9 +45,21 @@ const getCommandLineRepositoryPath = (commandLine = process.argv) => {
4345
return args.find((arg) => arg && !arg.startsWith('-'));
4446
};
4547

48+
const getCommandLineLaunchOptions = (commandLine = process.argv) => {
49+
const args = commandLine.slice(process.defaultApp ? 2 : 1);
50+
return {
51+
walkthrough:
52+
process.env.CODIFF_WALKTHROUGH === '1' ||
53+
args.includes('--walkthrough') ||
54+
args.includes('-w'),
55+
};
56+
};
57+
4658
const getLaunchPath = () =>
4759
resolve(process.env.CODIFF_REPOSITORY_PATH || getCommandLineRepositoryPath() || process.cwd());
4860

61+
const getLaunchOptions = () => getCommandLineLaunchOptions();
62+
4963
const getPreferencesPath = () => join(app.getPath('userData'), 'preferences.json');
5064

5165
const readPreferences = () => {
@@ -138,7 +152,7 @@ const openRepositoryFolder = async (browserWindow) => {
138152
});
139153

140154
if (!result.canceled && result.filePaths[0]) {
141-
createWindow(result.filePaths[0]);
155+
createWindow(result.filePaths[0], { walkthrough: false });
142156
}
143157
};
144158

@@ -279,7 +293,7 @@ const buildApplicationMenu = () =>
279293
},
280294
]);
281295

282-
const createWindow = (repositoryPath) => {
296+
const createWindow = (repositoryPath, launchOptions = { walkthrough: false }) => {
283297
const display = screen.getPrimaryDisplay();
284298
const { height, width } = display.workAreaSize;
285299
const window = new BrowserWindow({
@@ -303,6 +317,7 @@ const createWindow = (repositoryPath) => {
303317

304318
const webContentsId = window.webContents.id;
305319
windowRepositories.set(webContentsId, repositoryPath);
320+
windowLaunchOptions.set(webContentsId, launchOptions);
306321
startRepositoryWatcher(window, repositoryPath);
307322
window.once('ready-to-show', () => window.show());
308323
window.on('closed', () => {
@@ -312,6 +327,7 @@ const createWindow = (repositoryPath) => {
312327
}
313328
repositoryWatchers.delete(webContentsId);
314329
windowRepositories.delete(webContentsId);
330+
windowLaunchOptions.delete(webContentsId);
315331
});
316332

317333
const rendererURL = process.env.ELECTRON_RENDERER_URL;
@@ -322,7 +338,12 @@ const createWindow = (repositoryPath) => {
322338
}
323339
};
324340

325-
const lock = !squirrelStartup && app.requestSingleInstanceLock({ repositoryPath: getLaunchPath() });
341+
const lock =
342+
!squirrelStartup &&
343+
app.requestSingleInstanceLock({
344+
launchOptions: getLaunchOptions(),
345+
repositoryPath: getLaunchPath(),
346+
});
326347

327348
if (squirrelStartup || !lock) {
328349
app.quit();
@@ -336,18 +357,19 @@ if (squirrelStartup || !lock) {
336357
getCommandLineRepositoryPath(commandLine) ||
337358
workingDirectory,
338359
),
360+
additionalData?.launchOptions || getCommandLineLaunchOptions(commandLine),
339361
);
340362
});
341363

342364
app.on('ready', () => {
343365
preferences = readPreferences();
344366
Menu.setApplicationMenu(buildApplicationMenu());
345-
createWindow(getLaunchPath());
367+
createWindow(getLaunchPath(), getLaunchOptions());
346368
});
347369

348370
app.on('activate', () => {
349371
if (BrowserWindow.getAllWindows().length === 0) {
350-
createWindow(getLaunchPath());
372+
createWindow(getLaunchPath(), getLaunchOptions());
351373
}
352374
});
353375

@@ -363,6 +385,20 @@ ipcMain.handle('codiff:getRepositoryState', async (event, source) => {
363385
return state;
364386
});
365387

388+
ipcMain.handle(
389+
'codiff:getLaunchOptions',
390+
(event) =>
391+
windowLaunchOptions.get(event.sender.id) || {
392+
walkthrough: false,
393+
},
394+
);
395+
396+
ipcMain.handle('codiff:getWalkthrough', async (event, source) => {
397+
const repositoryPath = windowRepositories.get(event.sender.id) || getLaunchPath();
398+
const state = await readRepositoryState(repositoryPath, source);
399+
return readWalkthrough(state);
400+
});
401+
366402
ipcMain.handle('codiff:getDiffSectionContent', async (event, request) => {
367403
const repositoryPath = windowRepositories.get(event.sender.id) || getLaunchPath();
368404
return readDiffSectionContent(repositoryPath, request);

electron/preload.cjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ const { contextBridge, ipcRenderer } = require('electron');
33
contextBridge.exposeInMainWorld('codiff', {
44
getDiffSectionContent: (request) => ipcRenderer.invoke('codiff:getDiffSectionContent', request),
55
getGitIdentity: () => ipcRenderer.invoke('codiff:getGitIdentity'),
6+
getLaunchOptions: () => ipcRenderer.invoke('codiff:getLaunchOptions'),
67
getPreferences: () => ipcRenderer.invoke('codiff:getPreferences'),
78
getRepositoryHistory: (limit) => ipcRenderer.invoke('codiff:getRepositoryHistory', limit),
89
getRepositoryState: (source) => ipcRenderer.invoke('codiff:getRepositoryState', source),
10+
getWalkthrough: (source) => ipcRenderer.invoke('codiff:getWalkthrough', source),
911
onFindInDiffs: (callback) => {
1012
const listener = () => callback();
1113
ipcRenderer.on('codiff:findInDiffs', listener);

0 commit comments

Comments
 (0)