@solaqua/gji 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/back.d.ts +13 -0
- package/dist/back.js +74 -0
- package/dist/cli.js +43 -0
- package/dist/gji-bundle.mjs +653 -484
- package/dist/go.js +2 -0
- package/dist/history-command.d.ts +7 -0
- package/dist/history-command.js +15 -0
- package/dist/history.d.ts +9 -0
- package/dist/history.js +46 -0
- package/dist/init.js +7 -0
- package/dist/new.js +3 -0
- package/dist/pr.js +3 -0
- package/man/man1/gji-back.1 +13 -0
- package/man/man1/gji-clean.1 +1 -1
- package/man/man1/gji-completion.1 +1 -1
- package/man/man1/gji-config.1 +1 -1
- package/man/man1/gji-go.1 +1 -1
- package/man/man1/gji-history.1 +13 -0
- package/man/man1/gji-init.1 +1 -1
- package/man/man1/gji-ls.1 +1 -1
- package/man/man1/gji-new.1 +1 -1
- package/man/man1/gji-pr.1 +1 -1
- package/man/man1/gji-remove.1 +1 -1
- package/man/man1/gji-root.1 +1 -1
- package/man/man1/gji-status.1 +1 -1
- package/man/man1/gji-sync.1 +1 -1
- package/man/man1/gji-trigger-hook.1 +1 -1
- package/man/man1/gji.1 +9 -1
- package/package.json +1 -1
package/dist/back.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type HistoryEntry } from './history.js';
|
|
2
|
+
export declare const BACK_OUTPUT_FILE_ENV = "GJI_BACK_OUTPUT_FILE";
|
|
3
|
+
export interface BackCommandOptions {
|
|
4
|
+
cwd: string;
|
|
5
|
+
home?: string;
|
|
6
|
+
n?: number;
|
|
7
|
+
print?: boolean;
|
|
8
|
+
stderr: (chunk: string) => void;
|
|
9
|
+
stdout: (chunk: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function runBackCommand(options: BackCommandOptions): Promise<number>;
|
|
12
|
+
export declare function formatHistoryList(history: HistoryEntry[], cwd: string): string;
|
|
13
|
+
export declare function formatAge(timestamp: number): string;
|
package/dist/back.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { access } from 'node:fs/promises';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import { loadEffectiveConfig } from './config.js';
|
|
4
|
+
import { extractHooks, runHook } from './hooks.js';
|
|
5
|
+
import { appendHistory, loadHistory } from './history.js';
|
|
6
|
+
import { detectRepository } from './repo.js';
|
|
7
|
+
import { writeShellOutput } from './shell-handoff.js';
|
|
8
|
+
export const BACK_OUTPUT_FILE_ENV = 'GJI_BACK_OUTPUT_FILE';
|
|
9
|
+
export async function runBackCommand(options) {
|
|
10
|
+
const history = await loadHistory(options.home);
|
|
11
|
+
const steps = options.n ?? 1;
|
|
12
|
+
if (steps < 1) {
|
|
13
|
+
options.stderr('gji back: step count must be at least 1\n');
|
|
14
|
+
return 1;
|
|
15
|
+
}
|
|
16
|
+
let found = 0;
|
|
17
|
+
let target;
|
|
18
|
+
for (const entry of history) {
|
|
19
|
+
if (entry.path === options.cwd)
|
|
20
|
+
continue;
|
|
21
|
+
try {
|
|
22
|
+
await access(entry.path);
|
|
23
|
+
found++;
|
|
24
|
+
if (found === steps) {
|
|
25
|
+
target = entry;
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Path no longer exists — skip to the next entry
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (!target) {
|
|
34
|
+
options.stderr('gji back: no previous worktree in history\n');
|
|
35
|
+
options.stderr("Hint: Use 'gji go', 'gji new', or 'gji pr' to navigate between worktrees\n");
|
|
36
|
+
return 1;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const repository = await detectRepository(target.path);
|
|
40
|
+
const config = await loadEffectiveConfig(repository.repoRoot, options.home, options.stderr);
|
|
41
|
+
const hooks = extractHooks(config);
|
|
42
|
+
await runHook(hooks.afterEnter, target.path, { branch: target.branch ?? undefined, path: target.path, repo: basename(repository.repoRoot) }, options.stderr);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Not in a git repo or hooks unavailable — proceed without hook
|
|
46
|
+
}
|
|
47
|
+
await appendHistory(target.path, target.branch, options.home);
|
|
48
|
+
await writeShellOutput(BACK_OUTPUT_FILE_ENV, target.path, options.stdout);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
export function formatHistoryList(history, cwd) {
|
|
52
|
+
const branchWidth = Math.max('BRANCH'.length, ...history.map((e) => (e.branch ?? '(detached)').length));
|
|
53
|
+
const lines = [' ' + 'BRANCH'.padEnd(branchWidth) + ' WHEN PATH'];
|
|
54
|
+
for (const entry of history) {
|
|
55
|
+
const isCurrent = entry.path === cwd;
|
|
56
|
+
const branch = (entry.branch ?? '(detached)').padEnd(branchWidth);
|
|
57
|
+
const when = formatAge(entry.timestamp).padEnd(10);
|
|
58
|
+
lines.push(`${isCurrent ? '*' : ' '} ${branch} ${when} ${entry.path}`);
|
|
59
|
+
}
|
|
60
|
+
return lines.join('\n') + '\n';
|
|
61
|
+
}
|
|
62
|
+
export function formatAge(timestamp) {
|
|
63
|
+
const seconds = Math.floor((Date.now() - timestamp) / 1000);
|
|
64
|
+
if (seconds < 60)
|
|
65
|
+
return 'just now';
|
|
66
|
+
const minutes = Math.floor(seconds / 60);
|
|
67
|
+
if (minutes < 60)
|
|
68
|
+
return `${minutes}m ago`;
|
|
69
|
+
const hours = Math.floor(minutes / 60);
|
|
70
|
+
if (hours < 24)
|
|
71
|
+
return `${hours}h ago`;
|
|
72
|
+
const days = Math.floor(hours / 24);
|
|
73
|
+
return `${days}d ago`;
|
|
74
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import updateNotifier from 'update-notifier';
|
|
4
|
+
import { runBackCommand } from './back.js';
|
|
4
5
|
import { runCleanCommand } from './clean.js';
|
|
6
|
+
import { runHistoryCommand } from './history-command.js';
|
|
5
7
|
import { runCompletionCommand } from './completion.js';
|
|
6
8
|
import { runConfigCommand } from './config-command.js';
|
|
7
9
|
import { runGoCommand } from './go.js';
|
|
@@ -116,6 +118,16 @@ function registerCommands(program) {
|
|
|
116
118
|
.option('--dry-run', 'show what would be created without executing any git commands or writing files')
|
|
117
119
|
.option('--json', 'emit JSON on success or error instead of human-readable output')
|
|
118
120
|
.action(notImplemented('pr'));
|
|
121
|
+
program
|
|
122
|
+
.command('back [n]')
|
|
123
|
+
.description('navigate to the previously visited worktree, optionally N steps back')
|
|
124
|
+
.option('--print', 'print the resolved worktree path explicitly')
|
|
125
|
+
.action(notImplemented('back'));
|
|
126
|
+
program
|
|
127
|
+
.command('history')
|
|
128
|
+
.description('show navigation history')
|
|
129
|
+
.option('--json', 'print history as JSON')
|
|
130
|
+
.action(notImplemented('history'));
|
|
119
131
|
program
|
|
120
132
|
.command('go [branch]')
|
|
121
133
|
.description('print or select a worktree path')
|
|
@@ -223,6 +235,37 @@ function attachCommandActions(program, options) {
|
|
|
223
235
|
throw commanderExit(exitCode);
|
|
224
236
|
}
|
|
225
237
|
});
|
|
238
|
+
program.commands
|
|
239
|
+
.find((command) => command.name() === 'back')
|
|
240
|
+
?.action(async (n, commandOptions) => {
|
|
241
|
+
if (n !== undefined && !/^\d+$/.test(n)) {
|
|
242
|
+
options.stderr(`gji back: invalid step count: ${n}\n`);
|
|
243
|
+
throw commanderExit(1);
|
|
244
|
+
}
|
|
245
|
+
const steps = n !== undefined ? parseInt(n, 10) : undefined;
|
|
246
|
+
const exitCode = await runBackCommand({
|
|
247
|
+
cwd: options.cwd,
|
|
248
|
+
n: steps,
|
|
249
|
+
print: commandOptions.print,
|
|
250
|
+
stderr: options.stderr,
|
|
251
|
+
stdout: options.stdout,
|
|
252
|
+
});
|
|
253
|
+
if (exitCode !== 0) {
|
|
254
|
+
throw commanderExit(exitCode);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
program.commands
|
|
258
|
+
.find((command) => command.name() === 'history')
|
|
259
|
+
?.action(async (commandOptions) => {
|
|
260
|
+
const exitCode = await runHistoryCommand({
|
|
261
|
+
cwd: options.cwd,
|
|
262
|
+
json: commandOptions.json,
|
|
263
|
+
stdout: options.stdout,
|
|
264
|
+
});
|
|
265
|
+
if (exitCode !== 0) {
|
|
266
|
+
throw commanderExit(exitCode);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
226
269
|
program.commands
|
|
227
270
|
.find((command) => command.name() === 'go')
|
|
228
271
|
?.action(async (branch, commandOptions) => {
|