Repository navigation
Expand file tree
/
Copy pathcmd-mod-bookmarks.ts
More file actions
77 lines (77 loc) · 2.28 KB
/
Copy pathcmd-mod-bookmarks.ts
File metadata and controls
77 lines (77 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import type {ModApi, SessionNode} from './api.js';
import {hasControlCharacters} from './text.js';
export function labelledNodes(
nodes: readonly SessionNode[],
): readonly SessionNode[] {
return nodes.flatMap(node => [
...(node.label ? [node] : []),
...labelledNodes(node.children),
]);
}
export default function register(cmd: ModApi): void {
cmd.addCommand({
name: 'bookmark',
description: 'Label the current session point for returning later',
argumentHint: '<label>',
handler: ({args}) => {
const label = args.trim();
if (!label || label.length > 80 || hasControlCharacters(label))
return {
message:
'Use /bookmark <label> (1–80 characters, single line).',
};
if (!cmd.isIdle())
return {
message:
'Wait until the current run finishes before bookmarking.',
};
const targetId = cmd.sessions.leafId();
if (!targetId)
return {
message:
'No session point available yet. Run a prompt first.',
};
cmd.sessions.setLabel({targetId, label});
return {message: `Bookmarked: ${label}`};
},
});
cmd.addCommand({
name: 'bookmarks',
description: 'List labelled points in the active session',
handler: () => {
const nodes = labelledNodes(cmd.sessions.tree());
return {
message: nodes.length
? nodes.map(node => `${node.label} — ${node.id}`).join('\n')
: 'No bookmarks in this session.',
};
},
});
cmd.addCommand({
name: 'jump-bookmark',
description: 'Return to a labelled session point by exact label or ID',
argumentHint: '<label-or-id>',
handler: async ({args}) => {
if (!cmd.isIdle())
return {
message:
'Wait until the current run finishes before navigating.',
};
const query = args.trim();
if (!query) return {message: 'Use /jump-bookmark <label-or-id>.'};
const matches = labelledNodes(cmd.sessions.tree()).filter(
node => node.id === query || node.label === query,
);
if (matches.length !== 1)
return {
message: matches.length
? 'That label is ambiguous; use the ID from /bookmarks.'
: 'Bookmark not found. Use /bookmarks.',
};
const node = matches[0];
if (!node) return {message: 'Bookmark not found.'};
await cmd.sessions.navigateTree({targetId: node.id});
return {message: `Returned to: ${node.label}`};
},
});
}