@indianic/dialout 1.1.1 → 1.2.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/README.md +429 -16
- package/bin/AGENTS.md +44 -0
- package/bin/devdash-agent.js +2 -0
- package/dist/ai-adapters/claude.d.ts +3 -0
- package/dist/ai-adapters/claude.d.ts.map +1 -0
- package/dist/ai-adapters/claude.js +98 -0
- package/dist/ai-adapters/claude.js.map +1 -0
- package/dist/ai-adapters/codex.d.ts +3 -0
- package/dist/ai-adapters/codex.d.ts.map +1 -0
- package/dist/ai-adapters/codex.js +147 -0
- package/dist/ai-adapters/codex.js.map +1 -0
- package/dist/ai-adapters/grok.d.ts +3 -0
- package/dist/ai-adapters/grok.d.ts.map +1 -0
- package/dist/ai-adapters/grok.js +164 -0
- package/dist/ai-adapters/grok.js.map +1 -0
- package/dist/ai-adapters/index.d.ts +5 -0
- package/dist/ai-adapters/index.d.ts.map +1 -0
- package/dist/ai-adapters/index.js +30 -0
- package/dist/ai-adapters/index.js.map +1 -0
- package/dist/ai-adapters/types.d.ts +3 -0
- package/dist/ai-adapters/types.d.ts.map +1 -0
- package/dist/ai-adapters/types.js +7 -0
- package/dist/ai-adapters/types.js.map +1 -0
- package/dist/ai-capabilities/claude.d.ts +4 -0
- package/dist/ai-capabilities/claude.d.ts.map +1 -0
- package/dist/ai-capabilities/claude.js +174 -0
- package/dist/ai-capabilities/claude.js.map +1 -0
- package/dist/ai-capabilities/describe.d.ts +2 -0
- package/dist/ai-capabilities/describe.d.ts.map +1 -0
- package/dist/ai-capabilities/describe.js +31 -0
- package/dist/ai-capabilities/describe.js.map +1 -0
- package/dist/ai-capabilities/fsdeps.d.ts +3 -0
- package/dist/ai-capabilities/fsdeps.d.ts.map +1 -0
- package/dist/ai-capabilities/fsdeps.js +71 -0
- package/dist/ai-capabilities/fsdeps.js.map +1 -0
- package/dist/ai-capabilities/grok.d.ts +5 -0
- package/dist/ai-capabilities/grok.d.ts.map +1 -0
- package/dist/ai-capabilities/grok.js +145 -0
- package/dist/ai-capabilities/grok.js.map +1 -0
- package/dist/ai-capabilities/index.d.ts +4 -0
- package/dist/ai-capabilities/index.d.ts.map +1 -0
- package/dist/ai-capabilities/index.js +94 -0
- package/dist/ai-capabilities/index.js.map +1 -0
- package/dist/ai-capabilities/redact.d.ts +2 -0
- package/dist/ai-capabilities/redact.d.ts.map +1 -0
- package/dist/ai-capabilities/redact.js +27 -0
- package/dist/ai-capabilities/redact.js.map +1 -0
- package/dist/ai-capabilities/types.d.ts +11 -0
- package/dist/ai-capabilities/types.d.ts.map +1 -0
- package/dist/ai-capabilities/types.js +3 -0
- package/dist/ai-capabilities/types.js.map +1 -0
- package/dist/ai-launch.d.ts +35 -0
- package/dist/ai-launch.d.ts.map +1 -0
- package/dist/ai-launch.js +211 -0
- package/dist/ai-launch.js.map +1 -0
- package/dist/ai-session-detector.d.ts +19 -0
- package/dist/ai-session-detector.d.ts.map +1 -0
- package/dist/ai-session-detector.js +79 -0
- package/dist/ai-session-detector.js.map +1 -0
- package/dist/ai-sessions.d.ts +36 -0
- package/dist/ai-sessions.d.ts.map +1 -0
- package/dist/ai-sessions.js +309 -0
- package/dist/ai-sessions.js.map +1 -0
- package/dist/ai-status.d.ts +6 -0
- package/dist/ai-status.d.ts.map +1 -0
- package/dist/ai-status.js +40 -0
- package/dist/ai-status.js.map +1 -0
- package/dist/ai-transcript-locator.d.ts +35 -0
- package/dist/ai-transcript-locator.d.ts.map +1 -0
- package/dist/ai-transcript-locator.js +268 -0
- package/dist/ai-transcript-locator.js.map +1 -0
- package/dist/ai-transcript-tail.d.ts +17 -0
- package/dist/ai-transcript-tail.d.ts.map +1 -0
- package/dist/ai-transcript-tail.js +120 -0
- package/dist/ai-transcript-tail.js.map +1 -0
- package/dist/checklist.d.ts +20 -0
- package/dist/checklist.d.ts.map +1 -0
- package/dist/checklist.js +51 -0
- package/dist/checklist.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1427 -0
- package/dist/cli.js.map +1 -0
- package/dist/command-runner.d.ts +15 -0
- package/dist/command-runner.d.ts.map +1 -0
- package/dist/command-runner.js +84 -0
- package/dist/command-runner.js.map +1 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +152 -0
- package/dist/config.js.map +1 -0
- package/dist/cowork.d.ts +26 -0
- package/dist/cowork.d.ts.map +1 -0
- package/dist/cowork.js +370 -0
- package/dist/cowork.js.map +1 -0
- package/dist/fs-browser.d.ts +6 -0
- package/dist/fs-browser.d.ts.map +1 -0
- package/dist/fs-browser.js +61 -0
- package/dist/fs-browser.js.map +1 -0
- package/dist/has-command.d.ts +12 -0
- package/dist/has-command.d.ts.map +1 -0
- package/dist/has-command.js +24 -0
- package/dist/has-command.js.map +1 -0
- package/dist/heartbeat.d.ts +7 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +50 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/port-scanner.d.ts +4 -0
- package/dist/port-scanner.d.ts.map +1 -0
- package/dist/port-scanner.js +75 -0
- package/dist/port-scanner.js.map +1 -0
- package/dist/project-scanner.d.ts +15 -0
- package/dist/project-scanner.d.ts.map +1 -0
- package/dist/project-scanner.js +333 -0
- package/dist/project-scanner.js.map +1 -0
- package/dist/pty-manager.d.ts +28 -0
- package/dist/pty-manager.d.ts.map +1 -0
- package/dist/pty-manager.js +506 -0
- package/dist/pty-manager.js.map +1 -0
- package/dist/service-installer.d.ts +95 -0
- package/dist/service-installer.d.ts.map +1 -0
- package/dist/service-installer.js +911 -0
- package/dist/service-installer.js.map +1 -0
- package/dist/single-instance.d.ts +20 -0
- package/dist/single-instance.d.ts.map +1 -0
- package/dist/single-instance.js +151 -0
- package/dist/single-instance.js.map +1 -0
- package/dist/ssh-local-network.d.ts +26 -0
- package/dist/ssh-local-network.d.ts.map +1 -0
- package/dist/ssh-local-network.js +169 -0
- package/dist/ssh-local-network.js.map +1 -0
- package/dist/terminal-detect.d.ts +52 -0
- package/dist/terminal-detect.d.ts.map +1 -0
- package/dist/terminal-detect.js +147 -0
- package/dist/terminal-detect.js.map +1 -0
- package/dist/terminal-markers.d.ts +52 -0
- package/dist/terminal-markers.d.ts.map +1 -0
- package/dist/terminal-markers.js +174 -0
- package/dist/terminal-markers.js.map +1 -0
- package/dist/tmux-manager.d.ts +35 -0
- package/dist/tmux-manager.d.ts.map +1 -0
- package/dist/tmux-manager.js +274 -0
- package/dist/tmux-manager.js.map +1 -0
- package/dist/update-check.d.ts +3 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +202 -0
- package/dist/update-check.js.map +1 -0
- package/dist/websocket.d.ts +8 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +472 -0
- package/dist/websocket.js.map +1 -0
- package/node_modules/@dialout/shared/README.md +16 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts +8 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.js +41 -0
- package/node_modules/@dialout/shared/dist/capabilities.d.ts +25 -0
- package/node_modules/@dialout/shared/dist/capabilities.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/capabilities.js +2 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.d.ts +33 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.js +61 -0
- package/node_modules/@dialout/shared/dist/command-filter.d.ts +4 -0
- package/node_modules/@dialout/shared/dist/command-filter.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/command-filter.js +49 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts +6 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.js +24 -0
- package/node_modules/@dialout/shared/dist/events.d.ts +37 -0
- package/node_modules/@dialout/shared/dist/events.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/events.js +13 -0
- package/node_modules/@dialout/shared/dist/index.d.ts +21 -0
- package/node_modules/@dialout/shared/dist/index.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/index.js +37 -0
- package/node_modules/@dialout/shared/dist/kinds.d.ts +2 -0
- package/node_modules/@dialout/shared/dist/kinds.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/kinds.js +2 -0
- package/node_modules/@dialout/shared/dist/notify.d.ts +3 -0
- package/node_modules/@dialout/shared/dist/notify.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/notify.js +31 -0
- package/node_modules/@dialout/shared/dist/permission.d.ts +4 -0
- package/node_modules/@dialout/shared/dist/permission.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/permission.js +8 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.d.ts +3 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.js +11 -0
- package/node_modules/@dialout/shared/dist/session.d.ts +19 -0
- package/node_modules/@dialout/shared/dist/session.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/session.js +6 -0
- package/node_modules/@dialout/shared/dist/terminal-name.d.ts +25 -0
- package/node_modules/@dialout/shared/dist/terminal-name.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/terminal-name.js +63 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.d.ts +9 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.js +30 -0
- package/node_modules/@dialout/shared/package.json +37 -0
- package/node_modules/@dialout/shared/src/ai-chat-prefs.test.ts +40 -0
- package/node_modules/@dialout/shared/src/ai-chat-prefs.ts +39 -0
- package/node_modules/@dialout/shared/src/capabilities.ts +30 -0
- package/node_modules/@dialout/shared/src/chat-blocks.test.ts +65 -0
- package/node_modules/@dialout/shared/src/chat-blocks.ts +79 -0
- package/node_modules/@dialout/shared/src/command-filter.test.ts +76 -0
- package/node_modules/@dialout/shared/src/command-filter.ts +45 -0
- package/node_modules/@dialout/shared/src/composer-behaviour.test.ts +31 -0
- package/node_modules/@dialout/shared/src/composer-behaviour.ts +22 -0
- package/node_modules/@dialout/shared/src/events.ts +27 -0
- package/node_modules/@dialout/shared/src/index.ts +32 -0
- package/node_modules/@dialout/shared/src/kinds.ts +5 -0
- package/node_modules/@dialout/shared/src/notify.test.ts +49 -0
- package/node_modules/@dialout/shared/src/notify.ts +30 -0
- package/node_modules/@dialout/shared/src/permission.ts +10 -0
- package/node_modules/@dialout/shared/src/scroll-pin.test.ts +23 -0
- package/node_modules/@dialout/shared/src/scroll-pin.ts +13 -0
- package/node_modules/@dialout/shared/src/session.ts +25 -0
- package/node_modules/@dialout/shared/src/terminal-name.ts +82 -0
- package/node_modules/@dialout/shared/src/tool-appearance.test.ts +41 -0
- package/node_modules/@dialout/shared/src/tool-appearance.ts +39 -0
- package/package.json +54 -14
- package/scripts/postinstall.js +79 -0
- package/scripts/prepack.js +45 -0
- package/bin/dialout.js +0 -13
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.groupEvents = groupEvents;
|
|
4
|
+
// Grouping only ever merges ADJACENT events, so the worst case for an adapter
|
|
5
|
+
// that interleaves is two blocks instead of one — never a reordering.
|
|
6
|
+
function groupEvents(events) {
|
|
7
|
+
const blocks = [];
|
|
8
|
+
let lastStatus = null;
|
|
9
|
+
events.forEach((e, i) => {
|
|
10
|
+
const key = `${('id' in e && e.id) || ('forId' in e && e.forId) || e.kind}-${i}`;
|
|
11
|
+
const tail = blocks[blocks.length - 1];
|
|
12
|
+
if (e.kind === 'message') {
|
|
13
|
+
blocks.push(e.role === 'user'
|
|
14
|
+
? { kind: 'user', key, text: e.text || '' }
|
|
15
|
+
: { kind: 'assistant', key, text: e.text || '' });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (e.kind === 'tool_call') {
|
|
19
|
+
const item = {
|
|
20
|
+
id: e.id || key,
|
|
21
|
+
name: e.name || 'tool',
|
|
22
|
+
summary: e.summary || '',
|
|
23
|
+
ok: null, resultPreview: null, resultLines: null,
|
|
24
|
+
};
|
|
25
|
+
if (tail && tail.kind === 'tools')
|
|
26
|
+
tail.items.push(item);
|
|
27
|
+
else
|
|
28
|
+
blocks.push({ kind: 'tools', key, items: [item] });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (e.kind === 'tool_result') {
|
|
32
|
+
// Search backwards: the call is usually in the current block, but a
|
|
33
|
+
// slow tool can return after a message has split the trace.
|
|
34
|
+
for (let b = blocks.length - 1; b >= 0; b--) {
|
|
35
|
+
const blk = blocks[b];
|
|
36
|
+
if (blk.kind !== 'tools')
|
|
37
|
+
continue;
|
|
38
|
+
const item = blk.items.find((t) => t.id === e.forId);
|
|
39
|
+
if (!item)
|
|
40
|
+
continue;
|
|
41
|
+
item.ok = e.ok !== false;
|
|
42
|
+
item.resultPreview = e.preview || '';
|
|
43
|
+
item.resultLines = e.preview ? e.preview.split('\n').length : 0;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
return; // orphan result: drop it rather than invent a row
|
|
47
|
+
}
|
|
48
|
+
if (e.kind === 'thinking') {
|
|
49
|
+
blocks.push({ kind: 'thinking', key, text: e.text || '' });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (e.kind === 'state') {
|
|
53
|
+
const status = e.status || '';
|
|
54
|
+
if (status && status !== lastStatus) {
|
|
55
|
+
lastStatus = status;
|
|
56
|
+
blocks.push({ kind: 'status', key, status });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return blocks;
|
|
61
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-filter.d.ts","sourceRoot":"","sources":["../src/command-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,gBAAgB,CAAC;AAI/D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxD;AAuBD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAW9E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.commandQuery = commandQuery;
|
|
4
|
+
exports.rankCommands = rankCommands;
|
|
5
|
+
// The menu opens only when the slash starts the message. A slash anywhere else
|
|
6
|
+
// is a path, a date, or a fraction — not a command.
|
|
7
|
+
function commandQuery(text) {
|
|
8
|
+
if (!text.startsWith('/'))
|
|
9
|
+
return null;
|
|
10
|
+
const rest = text.slice(1);
|
|
11
|
+
// A space means the command has been chosen and arguments are being typed.
|
|
12
|
+
if (/\s/.test(rest))
|
|
13
|
+
return null;
|
|
14
|
+
return rest;
|
|
15
|
+
}
|
|
16
|
+
// User commands are the ones they wrote; plugins outnumber them 52 to 29 on a
|
|
17
|
+
// real install, so source is the tie-breaker or the list buries them.
|
|
18
|
+
const SOURCE_RANK = {
|
|
19
|
+
user: 0, project: 1, builtin: 2, plugin: 3,
|
|
20
|
+
};
|
|
21
|
+
// Lower is better.
|
|
22
|
+
function score(c, q) {
|
|
23
|
+
const name = c.name.toLowerCase();
|
|
24
|
+
const bare = name.includes(':') ? name.slice(name.indexOf(':') + 1) : name;
|
|
25
|
+
const desc = c.description.toLowerCase();
|
|
26
|
+
if (!q)
|
|
27
|
+
return 40;
|
|
28
|
+
if (bare.startsWith(q))
|
|
29
|
+
return 0;
|
|
30
|
+
if (name.startsWith(q))
|
|
31
|
+
return 10; // the plugin prefix
|
|
32
|
+
if (bare.includes(q))
|
|
33
|
+
return 20;
|
|
34
|
+
if (name.includes(q))
|
|
35
|
+
return 25;
|
|
36
|
+
if (desc.includes(q))
|
|
37
|
+
return 30;
|
|
38
|
+
return Infinity; // no match at all
|
|
39
|
+
}
|
|
40
|
+
function rankCommands(commands, query) {
|
|
41
|
+
const q = query.trim().toLowerCase();
|
|
42
|
+
return commands
|
|
43
|
+
.map((c) => ({ c, s: score(c, q) }))
|
|
44
|
+
.filter((x) => x.s !== Infinity)
|
|
45
|
+
.sort((a, b) => a.s - b.s
|
|
46
|
+
|| SOURCE_RANK[a.c.source] - SOURCE_RANK[b.c.source]
|
|
47
|
+
|| a.c.name.localeCompare(b.c.name))
|
|
48
|
+
.map((x) => x.c);
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composer-behaviour.d.ts","sourceRoot":"","sources":["../src/composer-behaviour.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,oBAAoB,sBAAsB,CAAC;AAWxD,wBAAgB,mBAAmB,CACjC,CAAC,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,EACrC,oBAAoB,EAAE,OAAO,GAC5B,OAAO,CAIT"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.COARSE_POINTER_QUERY = void 0;
|
|
4
|
+
exports.shouldSubmitOnEnter = shouldSubmitOnEnter;
|
|
5
|
+
// The compact key bar exists for a device with a finger and no real keyboard.
|
|
6
|
+
// That is a pointer question, not a width one: a half-width desktop window is
|
|
7
|
+
// not a phone, and an iPad in landscape is not a desktop.
|
|
8
|
+
exports.COARSE_POINTER_QUERY = '(pointer: coarse)';
|
|
9
|
+
// Enter sends where there is a real keyboard. On an on-screen keyboard the
|
|
10
|
+
// Enter key is conventionally a newline, and a stray one would fire a
|
|
11
|
+
// half-typed message — so there the send button is the only way to send.
|
|
12
|
+
//
|
|
13
|
+
// The second argument is deliberately "on-screen keyboard only", not "coarse
|
|
14
|
+
// pointer". They are not the same thing: an iPad with a keyboard cover is a
|
|
15
|
+
// coarse pointer WITH a real Enter key, and treating it as a phone made Enter
|
|
16
|
+
// useless there. The caller combines the pointer test with the hardware
|
|
17
|
+
// inference in useHardwareKeyboard.
|
|
18
|
+
function shouldSubmitOnEnter(e, onScreenKeyboardOnly) {
|
|
19
|
+
if (e.key !== 'Enter')
|
|
20
|
+
return false;
|
|
21
|
+
if (e.shiftKey)
|
|
22
|
+
return false; // Shift+Enter is a newline everywhere
|
|
23
|
+
return !onScreenKeyboardOnly;
|
|
24
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type AiStatus = 'working' | 'waiting_input' | 'waiting_approval' | 'idle';
|
|
2
|
+
export type AiEvent = {
|
|
3
|
+
kind: 'message';
|
|
4
|
+
role: 'user' | 'assistant';
|
|
5
|
+
text: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
at?: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'tool_call';
|
|
10
|
+
name: string;
|
|
11
|
+
summary: string;
|
|
12
|
+
input?: unknown;
|
|
13
|
+
id?: string;
|
|
14
|
+
at?: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'tool_result';
|
|
17
|
+
forId: string;
|
|
18
|
+
ok: boolean;
|
|
19
|
+
preview: string;
|
|
20
|
+
at?: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'thinking';
|
|
23
|
+
text: string;
|
|
24
|
+
id?: string;
|
|
25
|
+
at?: string;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'state';
|
|
28
|
+
status: AiStatus;
|
|
29
|
+
at?: string;
|
|
30
|
+
};
|
|
31
|
+
export interface AiAdapter {
|
|
32
|
+
toEvents(record: unknown): AiEvent[];
|
|
33
|
+
title(record: unknown): string | null;
|
|
34
|
+
}
|
|
35
|
+
export declare const PREVIEW_LIMIT = 2000;
|
|
36
|
+
export declare function preview(text: string): string;
|
|
37
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,eAAe,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAEjF,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,SAAS,CAAC;IAAK,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3F;IAAE,IAAI,EAAE,WAAW,CAAC;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GACjG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,UAAU,CAAC;IAAI,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAO,MAAM,EAAE,QAAQ,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D,MAAM,WAAW,SAAS;IAExB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;IAErC,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CACvC;AAKD,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The one shape the whole feature speaks. The browser never learns which
|
|
3
|
+
// vendor produced a session, which is the entire point of the adapter layer.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.PREVIEW_LIMIT = void 0;
|
|
6
|
+
exports.preview = preview;
|
|
7
|
+
// Tool output is routinely megabytes (a full test run, a large file read).
|
|
8
|
+
// Only a preview crosses the socket; the full text is never needed to follow
|
|
9
|
+
// a conversation, and shipping it would stall a phone on mobile data.
|
|
10
|
+
exports.PREVIEW_LIMIT = 2000;
|
|
11
|
+
function preview(text) {
|
|
12
|
+
return text.length <= exports.PREVIEW_LIMIT ? text : `${text.slice(0, exports.PREVIEW_LIMIT)}\n…truncated`;
|
|
13
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type { AiKind } from './kinds';
|
|
2
|
+
export type { AiStatus, AiEvent, AiAdapter } from './events';
|
|
3
|
+
export { PREVIEW_LIMIT, preview } from './events';
|
|
4
|
+
export type { PermissionMode } from './permission';
|
|
5
|
+
export { PERMISSION_MODES, isPermissionMode } from './permission';
|
|
6
|
+
export type { AiSessionSummary } from './session';
|
|
7
|
+
export { REPLAY_LIMIT } from './session';
|
|
8
|
+
export type { CommandSource, AiCommand, McpServerInfo, AiCapabilities } from './capabilities';
|
|
9
|
+
export { NOTIFY_COOLDOWN_MS, shouldNotifyAi } from './notify';
|
|
10
|
+
export type { ToolItem, ChatBlock } from './chat-blocks';
|
|
11
|
+
export { groupEvents } from './chat-blocks';
|
|
12
|
+
export { PIN_THRESHOLD_PX, shouldFollow } from './scroll-pin';
|
|
13
|
+
export type { ToolClass, ToolAppearance } from './tool-appearance';
|
|
14
|
+
export { toolClass, toolAppearance } from './tool-appearance';
|
|
15
|
+
export { commandQuery, rankCommands } from './command-filter';
|
|
16
|
+
export { COARSE_POINTER_QUERY, shouldSubmitOnEnter } from './composer-behaviour';
|
|
17
|
+
export type { PrefStore } from './ai-chat-prefs';
|
|
18
|
+
export { FUNCTION_KEYS_PREF, getFunctionKeysVisible, setFunctionKeysVisible } from './ai-chat-prefs';
|
|
19
|
+
export type { TerminalNameVars } from './terminal-name';
|
|
20
|
+
export { DEFAULT_TERMINAL_TEMPLATE, TERMINAL_NAME_TOKENS, factsFromSession, renderTerminalName } from './terminal-name';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAElD,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE9F,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE9D,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9D,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAErG,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderTerminalName = exports.factsFromSession = exports.TERMINAL_NAME_TOKENS = exports.DEFAULT_TERMINAL_TEMPLATE = exports.setFunctionKeysVisible = exports.getFunctionKeysVisible = exports.FUNCTION_KEYS_PREF = exports.shouldSubmitOnEnter = exports.COARSE_POINTER_QUERY = exports.rankCommands = exports.commandQuery = exports.toolAppearance = exports.toolClass = exports.shouldFollow = exports.PIN_THRESHOLD_PX = exports.groupEvents = exports.shouldNotifyAi = exports.NOTIFY_COOLDOWN_MS = exports.REPLAY_LIMIT = exports.isPermissionMode = exports.PERMISSION_MODES = exports.preview = exports.PREVIEW_LIMIT = void 0;
|
|
4
|
+
var events_1 = require("./events");
|
|
5
|
+
Object.defineProperty(exports, "PREVIEW_LIMIT", { enumerable: true, get: function () { return events_1.PREVIEW_LIMIT; } });
|
|
6
|
+
Object.defineProperty(exports, "preview", { enumerable: true, get: function () { return events_1.preview; } });
|
|
7
|
+
var permission_1 = require("./permission");
|
|
8
|
+
Object.defineProperty(exports, "PERMISSION_MODES", { enumerable: true, get: function () { return permission_1.PERMISSION_MODES; } });
|
|
9
|
+
Object.defineProperty(exports, "isPermissionMode", { enumerable: true, get: function () { return permission_1.isPermissionMode; } });
|
|
10
|
+
var session_1 = require("./session");
|
|
11
|
+
Object.defineProperty(exports, "REPLAY_LIMIT", { enumerable: true, get: function () { return session_1.REPLAY_LIMIT; } });
|
|
12
|
+
var notify_1 = require("./notify");
|
|
13
|
+
Object.defineProperty(exports, "NOTIFY_COOLDOWN_MS", { enumerable: true, get: function () { return notify_1.NOTIFY_COOLDOWN_MS; } });
|
|
14
|
+
Object.defineProperty(exports, "shouldNotifyAi", { enumerable: true, get: function () { return notify_1.shouldNotifyAi; } });
|
|
15
|
+
var chat_blocks_1 = require("./chat-blocks");
|
|
16
|
+
Object.defineProperty(exports, "groupEvents", { enumerable: true, get: function () { return chat_blocks_1.groupEvents; } });
|
|
17
|
+
var scroll_pin_1 = require("./scroll-pin");
|
|
18
|
+
Object.defineProperty(exports, "PIN_THRESHOLD_PX", { enumerable: true, get: function () { return scroll_pin_1.PIN_THRESHOLD_PX; } });
|
|
19
|
+
Object.defineProperty(exports, "shouldFollow", { enumerable: true, get: function () { return scroll_pin_1.shouldFollow; } });
|
|
20
|
+
var tool_appearance_1 = require("./tool-appearance");
|
|
21
|
+
Object.defineProperty(exports, "toolClass", { enumerable: true, get: function () { return tool_appearance_1.toolClass; } });
|
|
22
|
+
Object.defineProperty(exports, "toolAppearance", { enumerable: true, get: function () { return tool_appearance_1.toolAppearance; } });
|
|
23
|
+
var command_filter_1 = require("./command-filter");
|
|
24
|
+
Object.defineProperty(exports, "commandQuery", { enumerable: true, get: function () { return command_filter_1.commandQuery; } });
|
|
25
|
+
Object.defineProperty(exports, "rankCommands", { enumerable: true, get: function () { return command_filter_1.rankCommands; } });
|
|
26
|
+
var composer_behaviour_1 = require("./composer-behaviour");
|
|
27
|
+
Object.defineProperty(exports, "COARSE_POINTER_QUERY", { enumerable: true, get: function () { return composer_behaviour_1.COARSE_POINTER_QUERY; } });
|
|
28
|
+
Object.defineProperty(exports, "shouldSubmitOnEnter", { enumerable: true, get: function () { return composer_behaviour_1.shouldSubmitOnEnter; } });
|
|
29
|
+
var ai_chat_prefs_1 = require("./ai-chat-prefs");
|
|
30
|
+
Object.defineProperty(exports, "FUNCTION_KEYS_PREF", { enumerable: true, get: function () { return ai_chat_prefs_1.FUNCTION_KEYS_PREF; } });
|
|
31
|
+
Object.defineProperty(exports, "getFunctionKeysVisible", { enumerable: true, get: function () { return ai_chat_prefs_1.getFunctionKeysVisible; } });
|
|
32
|
+
Object.defineProperty(exports, "setFunctionKeysVisible", { enumerable: true, get: function () { return ai_chat_prefs_1.setFunctionKeysVisible; } });
|
|
33
|
+
var terminal_name_1 = require("./terminal-name");
|
|
34
|
+
Object.defineProperty(exports, "DEFAULT_TERMINAL_TEMPLATE", { enumerable: true, get: function () { return terminal_name_1.DEFAULT_TERMINAL_TEMPLATE; } });
|
|
35
|
+
Object.defineProperty(exports, "TERMINAL_NAME_TOKENS", { enumerable: true, get: function () { return terminal_name_1.TERMINAL_NAME_TOKENS; } });
|
|
36
|
+
Object.defineProperty(exports, "factsFromSession", { enumerable: true, get: function () { return terminal_name_1.factsFromSession; } });
|
|
37
|
+
Object.defineProperty(exports, "renderTerminalName", { enumerable: true, get: function () { return terminal_name_1.renderTerminalName; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../src/kinds.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../src/notify.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAI1C,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,KAAK,EAAE,MAAM,GACZ,OAAO,CAcT"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// When an AI session change is worth interrupting someone for.
|
|
3
|
+
//
|
|
4
|
+
// Pure so it can be tested without starting a server. This is the logic most
|
|
5
|
+
// capable of annoying a user into switching notifications off, so it is
|
|
6
|
+
// deliberately conservative.
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.NOTIFY_COOLDOWN_MS = void 0;
|
|
9
|
+
exports.shouldNotifyAi = shouldNotifyAi;
|
|
10
|
+
exports.NOTIFY_COOLDOWN_MS = 120_000;
|
|
11
|
+
const WAITING = new Set(['waiting_input', 'waiting_approval']);
|
|
12
|
+
function shouldNotifyAi(previous, next, lastNotifiedAt, nowMs) {
|
|
13
|
+
// Nothing to say about a session we are seeing for the first time: it was
|
|
14
|
+
// probably already sitting there before anyone subscribed, and announcing
|
|
15
|
+
// it would mean a burst on every agent reconnect.
|
|
16
|
+
if (previous === undefined)
|
|
17
|
+
return false;
|
|
18
|
+
if (previous === next)
|
|
19
|
+
return false;
|
|
20
|
+
// Only a transition INTO waiting counts. Notifying on the state itself
|
|
21
|
+
// would re-fire every five seconds for as long as the session sat there.
|
|
22
|
+
if (!WAITING.has(next))
|
|
23
|
+
return false;
|
|
24
|
+
// Only work that was actually running is worth being pulled back to; idle
|
|
25
|
+
// sessions drifting into 'waiting' are not news.
|
|
26
|
+
if (previous !== 'working')
|
|
27
|
+
return false;
|
|
28
|
+
if (lastNotifiedAt && nowMs - lastNotifiedAt < exports.NOTIFY_COOLDOWN_MS)
|
|
29
|
+
return false;
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;AAE5E,eAAO,MAAM,gBAAgB,EAAE,cAAc,EAAkD,CAAC;AAEhG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,cAAc,CAEvE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PERMISSION_MODES = void 0;
|
|
4
|
+
exports.isPermissionMode = isPermissionMode;
|
|
5
|
+
exports.PERMISSION_MODES = ['plan', 'default', 'acceptEdits', 'dontAsk'];
|
|
6
|
+
function isPermissionMode(value) {
|
|
7
|
+
return exports.PERMISSION_MODES.includes(value);
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll-pin.d.ts","sourceRoot":"","sources":["../src/scroll-pin.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,MAAyB,GACnC,OAAO,CAET"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PIN_THRESHOLD_PX = void 0;
|
|
4
|
+
exports.shouldFollow = shouldFollow;
|
|
5
|
+
// A terminal follows the tail unless you have scrolled away from it. Pulled
|
|
6
|
+
// out of the component so the threshold is a tested constant rather than a
|
|
7
|
+
// number buried in an effect.
|
|
8
|
+
exports.PIN_THRESHOLD_PX = 80;
|
|
9
|
+
function shouldFollow(scrollTop, scrollHeight, clientHeight, threshold = exports.PIN_THRESHOLD_PX) {
|
|
10
|
+
return scrollHeight - scrollTop - clientHeight <= threshold;
|
|
11
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AiKind } from './kinds';
|
|
2
|
+
import type { AiStatus } from './events';
|
|
3
|
+
import type { PermissionMode } from './permission';
|
|
4
|
+
export interface AiSessionSummary {
|
|
5
|
+
tmuxName: string;
|
|
6
|
+
kind: AiKind;
|
|
7
|
+
title: string;
|
|
8
|
+
folder: string;
|
|
9
|
+
folderPath: string;
|
|
10
|
+
gitBranch: string;
|
|
11
|
+
profile: string;
|
|
12
|
+
status: AiStatus;
|
|
13
|
+
origin: 'tmux' | 'launched';
|
|
14
|
+
permissionMode?: PermissionMode;
|
|
15
|
+
updatedAt: number;
|
|
16
|
+
transcript: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const REPLAY_LIMIT = 200;
|
|
19
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,CAAC;IAEjB,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;IAC5B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAGlB,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,eAAO,MAAM,YAAY,MAAM,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.REPLAY_LIMIT = void 0;
|
|
4
|
+
// Replay cap. Opening a month-old session must not flood the socket, and a
|
|
5
|
+
// phone cannot render ten thousand bubbles anyway.
|
|
6
|
+
exports.REPLAY_LIMIT = 200;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface TerminalNameVars {
|
|
2
|
+
machine_name?: string;
|
|
3
|
+
folder_name?: string;
|
|
4
|
+
folder_path?: string;
|
|
5
|
+
date?: string;
|
|
6
|
+
time?: string;
|
|
7
|
+
ampm?: string;
|
|
8
|
+
git_branch?: string;
|
|
9
|
+
term_program?: string;
|
|
10
|
+
short_id?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const DEFAULT_TERMINAL_TEMPLATE = "[machine_name]-[folder_name]-[date]-[time][ampm]";
|
|
13
|
+
export declare const TERMINAL_NAME_TOKENS: string[];
|
|
14
|
+
export declare function factsFromSession(s: {
|
|
15
|
+
machineName: string;
|
|
16
|
+
folder: string | null;
|
|
17
|
+
folderPath: string | null;
|
|
18
|
+
createdLocal: string | null;
|
|
19
|
+
startedAt: string | null;
|
|
20
|
+
gitBranch: string | null;
|
|
21
|
+
termProgram: string | null;
|
|
22
|
+
tmuxName: string;
|
|
23
|
+
}): TerminalNameVars;
|
|
24
|
+
export declare function renderTerminalName(template: string, vars: TerminalNameVars, fallback: string): string;
|
|
25
|
+
//# sourceMappingURL=terminal-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-name.d.ts","sourceRoot":"","sources":["../src/terminal-name.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,yBAAyB,qDAAqD,CAAC;AAE5F,eAAO,MAAM,oBAAoB,UAIhC,CAAC;AAgBF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,gBAAgB,CAcnB;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,gBAAgB,EACtB,QAAQ,EAAE,MAAM,GACf,MAAM,CAeR"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Pure terminal-name rendering. Shared by the /terminals list, the attach
|
|
3
|
+
// header, and the mobile list so one name shows everywhere. No React, no I/O.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.TERMINAL_NAME_TOKENS = exports.DEFAULT_TERMINAL_TEMPLATE = void 0;
|
|
6
|
+
exports.factsFromSession = factsFromSession;
|
|
7
|
+
exports.renderTerminalName = renderTerminalName;
|
|
8
|
+
exports.DEFAULT_TERMINAL_TEMPLATE = '[machine_name]-[folder_name]-[date]-[time][ampm]';
|
|
9
|
+
exports.TERMINAL_NAME_TOKENS = [
|
|
10
|
+
'machine_name', 'folder_name', 'folder_path',
|
|
11
|
+
'date', 'time', 'ampm',
|
|
12
|
+
'git_branch', 'term_program', 'short_id',
|
|
13
|
+
];
|
|
14
|
+
function timeParts(iso) {
|
|
15
|
+
if (!iso)
|
|
16
|
+
return { date: '', time: '', ampm: '' };
|
|
17
|
+
const d = new Date(iso);
|
|
18
|
+
if (Number.isNaN(d.getTime()))
|
|
19
|
+
return { date: '', time: '', ampm: '' };
|
|
20
|
+
const yyyy = d.getFullYear();
|
|
21
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
|
22
|
+
const dd = String(d.getDate()).padStart(2, '0');
|
|
23
|
+
let h = d.getHours();
|
|
24
|
+
const ampm = h < 12 ? 'am' : 'pm';
|
|
25
|
+
h = h % 12;
|
|
26
|
+
if (h === 0)
|
|
27
|
+
h = 12;
|
|
28
|
+
const min = String(d.getMinutes()).padStart(2, '0');
|
|
29
|
+
return { date: `${yyyy}-${mm}-${dd}`, time: `${h}:${min}`, ampm };
|
|
30
|
+
}
|
|
31
|
+
function factsFromSession(s) {
|
|
32
|
+
const t = timeParts(s.createdLocal || s.startedAt);
|
|
33
|
+
const shortId = (s.tmuxName.split('-').pop() || s.tmuxName).slice(0, 8);
|
|
34
|
+
return {
|
|
35
|
+
machine_name: s.machineName || '',
|
|
36
|
+
folder_name: s.folder || '',
|
|
37
|
+
folder_path: s.folderPath || '',
|
|
38
|
+
date: t.date,
|
|
39
|
+
time: t.time,
|
|
40
|
+
ampm: t.ampm,
|
|
41
|
+
git_branch: s.gitBranch || '',
|
|
42
|
+
term_program: s.termProgram && s.termProgram !== 'unknown' ? s.termProgram : '',
|
|
43
|
+
short_id: shortId,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function renderTerminalName(template, vars, fallback) {
|
|
47
|
+
if (!template)
|
|
48
|
+
return fallback;
|
|
49
|
+
let out = template;
|
|
50
|
+
for (const token of exports.TERMINAL_NAME_TOKENS) {
|
|
51
|
+
const value = vars[token] ?? '';
|
|
52
|
+
if (value) {
|
|
53
|
+
out = out.split(`[${token}]`).join(value);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const re = new RegExp(`(?:[-_ ]+)?\\[${token}\\]|\\[${token}\\](?:[-_ ]+)?`, 'g');
|
|
57
|
+
out = out.replace(re, '');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
out = out.replace(/\[[a-z_]+\]/g, '');
|
|
61
|
+
out = out.replace(/[-_]{2,}/g, (m) => m[0]).replace(/^[-_ ]+|[-_ ]+$/g, '').trim();
|
|
62
|
+
return out || fallback;
|
|
63
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type ToolClass = 'read' | 'search' | 'run' | 'write' | 'failure' | 'other';
|
|
2
|
+
export interface ToolAppearance {
|
|
3
|
+
cls: ToolClass;
|
|
4
|
+
glyph: string;
|
|
5
|
+
colorVar: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function toolClass(name: string): ToolClass;
|
|
8
|
+
export declare function toolAppearance(name: string, ok?: boolean): ToolAppearance;
|
|
9
|
+
//# sourceMappingURL=tool-appearance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-appearance.d.ts","sourceRoot":"","sources":["../src/tool-appearance.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAElF,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAsBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAEjD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAO,GAAG,cAAc,CAGtE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// A tool's colour says what it DID, not which vendor produced it. Reading a
|
|
3
|
+
// twenty-step run should show its shape without reading a word.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.toolClass = toolClass;
|
|
6
|
+
exports.toolAppearance = toolAppearance;
|
|
7
|
+
const BY_NAME = {
|
|
8
|
+
read: 'read', glob: 'read', ls: 'read', notebookread: 'read',
|
|
9
|
+
grep: 'search', websearch: 'search', webfetch: 'search',
|
|
10
|
+
bash: 'run', task: 'run', agent: 'run',
|
|
11
|
+
edit: 'write', write: 'write', multiedit: 'write', notebookedit: 'write',
|
|
12
|
+
};
|
|
13
|
+
const GLYPH = {
|
|
14
|
+
read: '◇', search: '⌕', run: '▸', write: '✎', failure: '✕', other: '·',
|
|
15
|
+
};
|
|
16
|
+
const COLOR = {
|
|
17
|
+
read: '--accent',
|
|
18
|
+
search: '--tool-search',
|
|
19
|
+
run: '--tool-run',
|
|
20
|
+
write: '--static',
|
|
21
|
+
failure: '--offline',
|
|
22
|
+
other: '--dim',
|
|
23
|
+
};
|
|
24
|
+
function toolClass(name) {
|
|
25
|
+
return BY_NAME[String(name || '').trim().toLowerCase()] ?? 'other';
|
|
26
|
+
}
|
|
27
|
+
function toolAppearance(name, ok = true) {
|
|
28
|
+
const cls = ok ? toolClass(name) : 'failure';
|
|
29
|
+
return { cls, glyph: GLYPH[cls], colorVar: COLOR[cls] };
|
|
30
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dialout/shared",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Types and constants shared by the Dialout server, agent and mobile app.",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"registry": "https://registry.npmjs.org"
|
|
7
|
+
},
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./src/index.ts",
|
|
14
|
+
"require": "./dist/index.js",
|
|
15
|
+
"default": "./src/index.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"src",
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"test": "vitest run"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"typescript": "^5.8.3",
|
|
28
|
+
"vitest": "^4.1.10"
|
|
29
|
+
},
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"homepage": "https://www.dialout.dev",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/indianic/dialout.git",
|
|
35
|
+
"directory": "packages/devdash-shared"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
+
import { getFunctionKeysVisible, setFunctionKeysVisible } from './ai-chat-prefs';
|
|
3
|
+
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
const store: Record<string, string> = {};
|
|
6
|
+
vi.stubGlobal('window', {
|
|
7
|
+
localStorage: {
|
|
8
|
+
getItem: (k: string) => (k in store ? store[k] : null),
|
|
9
|
+
setItem: (k: string, v: string) => { store[k] = v; },
|
|
10
|
+
removeItem: (k: string) => { delete store[k]; },
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('ai-chat-prefs', () => {
|
|
16
|
+
it('defaults to hidden and round-trips', () => {
|
|
17
|
+
expect(getFunctionKeysVisible()).toBe(false);
|
|
18
|
+
setFunctionKeysVisible(true);
|
|
19
|
+
expect(getFunctionKeysVisible()).toBe(true);
|
|
20
|
+
setFunctionKeysVisible(false);
|
|
21
|
+
expect(getFunctionKeysVisible()).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Server render has no window at all; reading must not throw.
|
|
25
|
+
it('returns the default when there is no window', () => {
|
|
26
|
+
vi.stubGlobal('window', undefined);
|
|
27
|
+
expect(getFunctionKeysVisible()).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('survives a localStorage that throws (private mode, blocked storage)', () => {
|
|
31
|
+
vi.stubGlobal('window', {
|
|
32
|
+
localStorage: {
|
|
33
|
+
getItem: () => { throw new Error('blocked'); },
|
|
34
|
+
setItem: () => { throw new Error('blocked'); },
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
expect(getFunctionKeysVisible()).toBe(false);
|
|
38
|
+
expect(() => setFunctionKeysVisible(true)).not.toThrow();
|
|
39
|
+
});
|
|
40
|
+
});
|