@aiwayds/dsh-tui-pi 0.1.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/LICENSE +21 -0
- package/README.md +324 -0
- package/bin/dsh-tui-pi +5 -0
- package/cordis.patch.yml +9 -0
- package/lib/append-system.d.ts +66 -0
- package/lib/append-system.js +161 -0
- package/lib/append-system.js.map +1 -0
- package/lib/commands.d.ts +53 -0
- package/lib/commands.js +167 -0
- package/lib/commands.js.map +1 -0
- package/lib/dsh-events.d.ts +106 -0
- package/lib/dsh-events.js +30 -0
- package/lib/dsh-events.js.map +1 -0
- package/lib/editor.d.ts +28 -0
- package/lib/editor.js +70 -0
- package/lib/editor.js.map +1 -0
- package/lib/footer.d.ts +36 -0
- package/lib/footer.js +112 -0
- package/lib/footer.js.map +1 -0
- package/lib/frame.d.ts +35 -0
- package/lib/frame.js +75 -0
- package/lib/frame.js.map +1 -0
- package/lib/git.d.ts +17 -0
- package/lib/git.js +51 -0
- package/lib/git.js.map +1 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.js +781 -0
- package/lib/index.js.map +1 -0
- package/lib/instructions.d.ts +29 -0
- package/lib/instructions.js +67 -0
- package/lib/instructions.js.map +1 -0
- package/lib/live-widgets.d.ts +85 -0
- package/lib/live-widgets.js +218 -0
- package/lib/live-widgets.js.map +1 -0
- package/lib/messages.d.ts +277 -0
- package/lib/messages.js +734 -0
- package/lib/messages.js.map +1 -0
- package/lib/permission.d.ts +27 -0
- package/lib/permission.js +48 -0
- package/lib/permission.js.map +1 -0
- package/lib/provider-catalog.d.ts +114 -0
- package/lib/provider-catalog.js +124 -0
- package/lib/provider-catalog.js.map +1 -0
- package/lib/quotes.d.ts +28 -0
- package/lib/quotes.js +144 -0
- package/lib/quotes.js.map +1 -0
- package/lib/reload.d.ts +23 -0
- package/lib/reload.js +171 -0
- package/lib/reload.js.map +1 -0
- package/lib/selectors.d.ts +48 -0
- package/lib/selectors.js +261 -0
- package/lib/selectors.js.map +1 -0
- package/lib/session.d.ts +157 -0
- package/lib/session.js +555 -0
- package/lib/session.js.map +1 -0
- package/lib/sessions.d.ts +73 -0
- package/lib/sessions.js +253 -0
- package/lib/sessions.js.map +1 -0
- package/lib/settings.d.ts +180 -0
- package/lib/settings.js +1328 -0
- package/lib/settings.js.map +1 -0
- package/lib/text.d.ts +22 -0
- package/lib/text.js +45 -0
- package/lib/text.js.map +1 -0
- package/lib/theme/index.d.ts +79 -0
- package/lib/theme/index.js +121 -0
- package/lib/theme/index.js.map +1 -0
- package/lib/theme/palette.d.ts +56 -0
- package/lib/theme/palette.js +154 -0
- package/lib/theme/palette.js.map +1 -0
- package/lib/theme-settings.d.ts +68 -0
- package/lib/theme-settings.js +223 -0
- package/lib/theme-settings.js.map +1 -0
- package/lib/tui.d.ts +70 -0
- package/lib/tui.js +206 -0
- package/lib/tui.js.map +1 -0
- package/lib/welcome.d.ts +91 -0
- package/lib/welcome.js +281 -0
- package/lib/welcome.js.map +1 -0
- package/package.json +50 -0
- package/patches/@earendil-works__pi-tui.patch +72 -0
- package/pnpm-workspace.yaml +2 -0
- package/templates/APPEND_SYSTEM.md +34 -0
package/lib/frame.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framed overlay chrome — the shared full box (`┌─┐`) every pi SelectList /
|
|
3
|
+
* SettingsList overlay gets, so a popup reads as one bounded surface instead
|
|
4
|
+
* of panel rows floating directly on the chat canvas.
|
|
5
|
+
*
|
|
6
|
+
* Replaces pi agent's DynamicBorder (bare `─` lines) with a complete box:
|
|
7
|
+
* `┌───┐` top, `│ │` side-bordered content rows, `└───┘` bottom. Width
|
|
8
|
+
* passed to `showOverlay` is unchanged — the box is self-contained within it
|
|
9
|
+
* (child renders at width − 2).
|
|
10
|
+
*
|
|
11
|
+
* The frame also paints the panel backdrop: every row (borders, spacers, and
|
|
12
|
+
* each child line — including the raw separator/search rows pi's SettingsList
|
|
13
|
+
* pushes without any theme call) is laid on a full-width canvasSubtle
|
|
14
|
+
* background, so the popup reads as one solid rectangle instead of stripes
|
|
15
|
+
* of text-width highlight.
|
|
16
|
+
*/
|
|
17
|
+
import { ansiBg, ansiFg, RESET } from "./theme/index.js";
|
|
18
|
+
import { visibleWidth } from "./text.js";
|
|
19
|
+
/**
|
|
20
|
+
* Paint one overlay row on the panel backdrop: `line` (which may carry its
|
|
21
|
+
* own SGR styling) is laid on a canvasSubtle background running the full
|
|
22
|
+
* overlay width. Theme fns nest RESETs (bold → fg → bg wrappers each append
|
|
23
|
+
* one), and a row can reset mid-line too (SettingsList's label/value split
|
|
24
|
+
* emits an empty styled value), so the backdrop is re-applied after every
|
|
25
|
+
* RESET — then the right-side padding is painted on the backdrop as well.
|
|
26
|
+
* Empty separator rows become plain full-width backdrop.
|
|
27
|
+
*/
|
|
28
|
+
function fillLine(theme, line, width) {
|
|
29
|
+
const pad = Math.max(0, width - visibleWidth(line));
|
|
30
|
+
const bg = ansiBg(theme.palette.canvasSubtle);
|
|
31
|
+
const content = line.replace(/\x1b\[0m/g, `\x1b[0m${bg}`);
|
|
32
|
+
return bg + content + bg + ' '.repeat(pad) + RESET;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Full-box wrapper for one overlay component: `┌─┐` top border, `│`-bordered
|
|
36
|
+
* content rows, `└─┘` bottom border — each with a blank spacer row inside
|
|
37
|
+
* the box for breathing room, colored `palette.borderDefault` on the panel's
|
|
38
|
+
* canvasSubtle backdrop. Every row spans the full overlay width on that
|
|
39
|
+
* backdrop (see fillLine); the child renders at width − 2.
|
|
40
|
+
*/
|
|
41
|
+
export class FramedOverlay {
|
|
42
|
+
theme;
|
|
43
|
+
child;
|
|
44
|
+
constructor(theme, child) {
|
|
45
|
+
this.theme = theme;
|
|
46
|
+
this.child = child;
|
|
47
|
+
}
|
|
48
|
+
invalidate() {
|
|
49
|
+
this.child.invalidate();
|
|
50
|
+
}
|
|
51
|
+
render(width) {
|
|
52
|
+
const contentWidth = Math.max(1, width - 2);
|
|
53
|
+
const borderFg = ansiFg(this.theme.palette.borderDefault);
|
|
54
|
+
const border = (chars) => borderFg + chars + RESET;
|
|
55
|
+
// Side-bordered content row: the child's own styling runs between the
|
|
56
|
+
// two `│`s; fillLine re-applies the backdrop after any mid-line RESETs.
|
|
57
|
+
const content = (line) => `${borderFg}│${line}${borderFg}│`;
|
|
58
|
+
const blankRow = `${borderFg}│${' '.repeat(contentWidth)}│`;
|
|
59
|
+
return [
|
|
60
|
+
fillLine(this.theme, border(`┌${'─'.repeat(contentWidth)}┐`), width),
|
|
61
|
+
fillLine(this.theme, blankRow, width),
|
|
62
|
+
...this.child.render(contentWidth).map(line => fillLine(this.theme, content(line), width)),
|
|
63
|
+
fillLine(this.theme, blankRow, width),
|
|
64
|
+
fillLine(this.theme, border(`└${'─'.repeat(contentWidth)}┘`), width),
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
handleInput(data) {
|
|
68
|
+
this.child.handleInput?.(data);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Build the framed wrapper for `child` (see FramedOverlay). */
|
|
72
|
+
export function wrapFramedOverlay(theme, child) {
|
|
73
|
+
return new FramedOverlay(theme, child);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=frame.js.map
|
package/lib/frame.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame.js","sourceRoot":"","sources":["../src/frame.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAiB,MAAM,kBAAkB,CAAA;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC;;;;;;;;GAQG;AACH,SAAS,QAAQ,CAAC,KAAe,EAAE,IAAY,EAAE,KAAa;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;IACnD,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;IACzD,OAAO,EAAE,GAAG,OAAO,GAAG,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IACP,KAAK,CAAU;IACf,KAAK,CAAW;IAEjC,YAAY,KAAe,EAAE,KAAgB;QAC3C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,UAAU;QACR,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAA;IACzB,CAAC;IAED,MAAM,CAAC,KAAa;QAClB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;QAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QACzD,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAA;QAC1D,sEAAsE;QACtE,wEAAwE;QACxE,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,QAAQ,IAAI,IAAI,GAAG,QAAQ,GAAG,CAAA;QACnE,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAA;QAC3D,OAAO;YACL,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;YACpE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC;YACrC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;YAC1F,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC;YACrC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;SACrE,CAAA;IACH,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;CACF;AAED,gEAAgE;AAChE,MAAM,UAAU,iBAAiB,CAAC,KAAe,EAAE,KAAgB;IACjE,OAAO,IAAI,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACxC,CAAC"}
|
package/lib/git.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git branch watcher for the session cwd: polls `git rev-parse` every few
|
|
3
|
+
* seconds and caches the result. Readers get O(1) access — the footer and the
|
|
4
|
+
* editor top border never spawn git themselves during render.
|
|
5
|
+
*/
|
|
6
|
+
export declare class GitBranchWatcher {
|
|
7
|
+
private readonly cwd;
|
|
8
|
+
private branch;
|
|
9
|
+
private timer;
|
|
10
|
+
private running;
|
|
11
|
+
constructor(cwd: string, intervalMs?: number);
|
|
12
|
+
getBranch(): string | undefined;
|
|
13
|
+
dispose(): void;
|
|
14
|
+
private refresh;
|
|
15
|
+
/** Called when the branch value actually changed. */
|
|
16
|
+
onChange: (() => void) | undefined;
|
|
17
|
+
}
|
package/lib/git.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git branch watcher for the session cwd: polls `git rev-parse` every few
|
|
3
|
+
* seconds and caches the result. Readers get O(1) access — the footer and the
|
|
4
|
+
* editor top border never spawn git themselves during render.
|
|
5
|
+
*/
|
|
6
|
+
import { execFile } from 'node:child_process';
|
|
7
|
+
export class GitBranchWatcher {
|
|
8
|
+
cwd;
|
|
9
|
+
branch;
|
|
10
|
+
timer;
|
|
11
|
+
running = false;
|
|
12
|
+
constructor(cwd, intervalMs = 5000) {
|
|
13
|
+
this.cwd = cwd;
|
|
14
|
+
this.timer = setInterval(() => { void this.refresh(); }, intervalMs);
|
|
15
|
+
this.timer.unref?.();
|
|
16
|
+
void this.refresh();
|
|
17
|
+
}
|
|
18
|
+
getBranch() {
|
|
19
|
+
return this.branch;
|
|
20
|
+
}
|
|
21
|
+
dispose() {
|
|
22
|
+
if (this.timer !== undefined)
|
|
23
|
+
clearInterval(this.timer);
|
|
24
|
+
this.timer = undefined;
|
|
25
|
+
}
|
|
26
|
+
async refresh() {
|
|
27
|
+
if (this.running)
|
|
28
|
+
return;
|
|
29
|
+
this.running = true;
|
|
30
|
+
try {
|
|
31
|
+
const branch = await new Promise(resolvePromise => {
|
|
32
|
+
execFile('git', ['-C', this.cwd, 'rev-parse', '--abbrev-ref', 'HEAD'], { timeout: 2000 }, (error, stdout) => {
|
|
33
|
+
if (error !== null)
|
|
34
|
+
return resolvePromise(undefined);
|
|
35
|
+
const value = stdout.trim();
|
|
36
|
+
resolvePromise(value === '' ? undefined : value);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
if (branch !== this.branch) {
|
|
40
|
+
this.branch = branch;
|
|
41
|
+
this.onChange?.();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
this.running = false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Called when the branch value actually changed. */
|
|
49
|
+
onChange;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=git.js.map
|
package/lib/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE7C,MAAM,OAAO,gBAAgB;IACV,GAAG,CAAQ;IACpB,MAAM,CAAoB;IAC1B,KAAK,CAA4B;IACjC,OAAO,GAAG,KAAK,CAAA;IAEvB,YAAY,GAAW,EAAE,UAAU,GAAG,IAAI;QACxC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC,OAAO,EAAE,CAAA,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;QACnE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;QACpB,KAAK,IAAI,CAAC,OAAO,EAAE,CAAA;IACrB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACvD,IAAI,CAAC,KAAK,GAAG,SAAS,CAAA;IACxB,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAM;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAqB,cAAc,CAAC,EAAE;gBACpE,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;oBAC1G,IAAI,KAAK,KAAK,IAAI;wBAAE,OAAO,cAAc,CAAC,SAAS,CAAC,CAAA;oBACpD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;oBAC3B,cAAc,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;gBAClD,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;YACF,IAAI,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;gBACpB,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAA;YACnB,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACtB,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,QAAQ,CAA0B;CACnC"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-tui-pi — pi-style terminal UI for DeepSeek Harness.
|
|
3
|
+
*
|
|
4
|
+
* Cordis plugin entry, mounted as a dsh profile bundle (`dsh.bundle.patch`).
|
|
5
|
+
* The TUI runs in-process inside the dsh tree: it renders with
|
|
6
|
+
* `@earendil-works/pi-tui`, talks to dsh services directly (ctx.agents,
|
|
7
|
+
* ctx.commands, session events), and keeps dsh's slash commands untouched.
|
|
8
|
+
*
|
|
9
|
+
* @module dsh-tui-pi
|
|
10
|
+
*/
|
|
11
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
12
|
+
export declare const name = "dsh-tui-pi";
|
|
13
|
+
/** The TUI drives the agent factory and registers slash commands. */
|
|
14
|
+
export declare const inject: string[];
|
|
15
|
+
export declare function apply(ctx: Context): void;
|