@sagmans/dsh-tui 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 +266 -0
- package/cordis.patch.yml +123 -0
- package/lib/agent/fork.d.ts +24 -0
- package/lib/agent/fork.d.ts.map +1 -0
- package/lib/agent/fork.js +25 -0
- package/lib/agent/fork.js.map +1 -0
- package/lib/agent/history.d.ts +78 -0
- package/lib/agent/history.d.ts.map +1 -0
- package/lib/agent/history.js +179 -0
- package/lib/agent/history.js.map +1 -0
- package/lib/agent/host.d.ts +58 -0
- package/lib/agent/host.d.ts.map +1 -0
- package/lib/agent/host.js +59 -0
- package/lib/agent/host.js.map +1 -0
- package/lib/agent/model.d.ts +61 -0
- package/lib/agent/model.d.ts.map +1 -0
- package/lib/agent/model.js +92 -0
- package/lib/agent/model.js.map +1 -0
- package/lib/agent/present.d.ts +12 -0
- package/lib/agent/present.d.ts.map +1 -0
- package/lib/agent/present.js +52 -0
- package/lib/agent/present.js.map +1 -0
- package/lib/agent/presets.d.ts +75 -0
- package/lib/agent/presets.d.ts.map +1 -0
- package/lib/agent/presets.js +117 -0
- package/lib/agent/presets.js.map +1 -0
- package/lib/agent/projections.d.ts +16 -0
- package/lib/agent/projections.d.ts.map +1 -0
- package/lib/agent/projections.js +31 -0
- package/lib/agent/projections.js.map +1 -0
- package/lib/agent/status.d.ts +46 -0
- package/lib/agent/status.d.ts.map +1 -0
- package/lib/agent/status.js +67 -0
- package/lib/agent/status.js.map +1 -0
- package/lib/cards.d.ts +88 -0
- package/lib/cards.d.ts.map +1 -0
- package/lib/cards.js +218 -0
- package/lib/cards.js.map +1 -0
- package/lib/compat/probe.d.ts +33 -0
- package/lib/compat/probe.d.ts.map +1 -0
- package/lib/compat/probe.js +74 -0
- package/lib/compat/probe.js.map +1 -0
- package/lib/config.d.ts +13 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +49 -0
- package/lib/config.js.map +1 -0
- package/lib/contracts.d.ts +32 -0
- package/lib/contracts.d.ts.map +1 -0
- package/lib/contracts.js +2 -0
- package/lib/contracts.js.map +1 -0
- package/lib/export.d.ts +15 -0
- package/lib/export.d.ts.map +1 -0
- package/lib/export.js +52 -0
- package/lib/export.js.map +1 -0
- package/lib/gates.d.ts +85 -0
- package/lib/gates.d.ts.map +1 -0
- package/lib/gates.js +216 -0
- package/lib/gates.js.map +1 -0
- package/lib/identity.d.ts +33 -0
- package/lib/identity.d.ts.map +1 -0
- package/lib/identity.js +49 -0
- package/lib/identity.js.map +1 -0
- package/lib/index.d.ts +24 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1196 -0
- package/lib/index.js.map +1 -0
- package/lib/input/completion.d.ts +22 -0
- package/lib/input/completion.d.ts.map +1 -0
- package/lib/input/completion.js +27 -0
- package/lib/input/completion.js.map +1 -0
- package/lib/input/submission.d.ts +62 -0
- package/lib/input/submission.d.ts.map +1 -0
- package/lib/input/submission.js +80 -0
- package/lib/input/submission.js.map +1 -0
- package/lib/jobs.d.ts +64 -0
- package/lib/jobs.d.ts.map +1 -0
- package/lib/jobs.js +123 -0
- package/lib/jobs.js.map +1 -0
- package/lib/startup.d.ts +17 -0
- package/lib/startup.d.ts.map +1 -0
- package/lib/startup.js +67 -0
- package/lib/startup.js.map +1 -0
- package/lib/subagents.d.ts +74 -0
- package/lib/subagents.d.ts.map +1 -0
- package/lib/subagents.js +141 -0
- package/lib/subagents.js.map +1 -0
- package/lib/terminal/bell.d.ts +18 -0
- package/lib/terminal/bell.d.ts.map +1 -0
- package/lib/terminal/bell.js +16 -0
- package/lib/terminal/bell.js.map +1 -0
- package/lib/terminal/clipboard.d.ts +11 -0
- package/lib/terminal/clipboard.d.ts.map +1 -0
- package/lib/terminal/clipboard.js +18 -0
- package/lib/terminal/clipboard.js.map +1 -0
- package/lib/terminal/restore.d.ts +17 -0
- package/lib/terminal/restore.d.ts.map +1 -0
- package/lib/terminal/restore.js +43 -0
- package/lib/terminal/restore.js.map +1 -0
- package/lib/terminal/title.d.ts +22 -0
- package/lib/terminal/title.d.ts.map +1 -0
- package/lib/terminal/title.js +34 -0
- package/lib/terminal/title.js.map +1 -0
- package/lib/text.d.ts +19 -0
- package/lib/text.d.ts.map +1 -0
- package/lib/text.js +61 -0
- package/lib/text.js.map +1 -0
- package/lib/theme.d.ts +47 -0
- package/lib/theme.d.ts.map +1 -0
- package/lib/theme.js +84 -0
- package/lib/theme.js.map +1 -0
- package/lib/transcript.d.ts +91 -0
- package/lib/transcript.d.ts.map +1 -0
- package/lib/transcript.js +315 -0
- package/lib/transcript.js.map +1 -0
- package/lib/ui/dock.d.ts +36 -0
- package/lib/ui/dock.d.ts.map +1 -0
- package/lib/ui/dock.js +110 -0
- package/lib/ui/dock.js.map +1 -0
- package/lib/ui/markdown.d.ts +17 -0
- package/lib/ui/markdown.d.ts.map +1 -0
- package/lib/ui/markdown.js +35 -0
- package/lib/ui/markdown.js.map +1 -0
- package/lib/ui/picker.d.ts +103 -0
- package/lib/ui/picker.d.ts.map +1 -0
- package/lib/ui/picker.js +165 -0
- package/lib/ui/picker.js.map +1 -0
- package/lib/ui/rows.d.ts +30 -0
- package/lib/ui/rows.d.ts.map +1 -0
- package/lib/ui/rows.js +49 -0
- package/lib/ui/rows.js.map +1 -0
- package/lib/ui/status.d.ts +49 -0
- package/lib/ui/status.d.ts.map +1 -0
- package/lib/ui/status.js +90 -0
- package/lib/ui/status.js.map +1 -0
- package/lib/ui/view.d.ts +56 -0
- package/lib/ui/view.d.ts.map +1 -0
- package/lib/ui/view.js +184 -0
- package/lib/ui/view.js.map +1 -0
- package/lib/work.d.ts +39 -0
- package/lib/work.d.ts.map +1 -0
- package/lib/work.js +97 -0
- package/lib/work.js.map +1 -0
- package/package.json +109 -0
package/lib/ui/status.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { truncateToWidth } from '@earendil-works/pi-tui';
|
|
2
|
+
import { displayText } from "../text.js";
|
|
3
|
+
const THOUSAND = 1000;
|
|
4
|
+
const HUNDRED_THOUSAND = 100 * THOUSAND;
|
|
5
|
+
const MILLION = 1_000_000;
|
|
6
|
+
const SECOND_MS = 1000;
|
|
7
|
+
const MINUTE_MS = 60 * SECOND_MS;
|
|
8
|
+
/** Path segments kept for a directory outside the home; a terminal row is not a file browser. */
|
|
9
|
+
const PATH_SEGMENTS = 2;
|
|
10
|
+
/** Compact a token count, because the exact number changes nothing a reader decides. */
|
|
11
|
+
export function formatTokens(count) {
|
|
12
|
+
if (count >= MILLION)
|
|
13
|
+
return `${(count / MILLION).toFixed(1)}M`;
|
|
14
|
+
// A decimal on a five-digit count is noise: 128.0k reads worse than 128k.
|
|
15
|
+
if (count >= HUNDRED_THOUSAND)
|
|
16
|
+
return `${Math.round(count / THOUSAND)}k`;
|
|
17
|
+
if (count >= THOUSAND)
|
|
18
|
+
return `${(count / THOUSAND).toFixed(1)}k`;
|
|
19
|
+
return String(count);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Shorten an absolute path for the footer: the reader's own home becomes `~`,
|
|
23
|
+
* and only a path from outside it is cut down to its tail.
|
|
24
|
+
*
|
|
25
|
+
* A home path keeps every directory between `~` and the leaf. Dropping those
|
|
26
|
+
* away would name a location that does not exist, which is worse than a long one.
|
|
27
|
+
*/
|
|
28
|
+
export function shortPath(path, home) {
|
|
29
|
+
if (home !== undefined && home !== '' && (path === home || path.startsWith(`${home}/`))) {
|
|
30
|
+
const rest = path.slice(home.length).replace(/^\//u, '');
|
|
31
|
+
return rest === '' ? '~/' : `~/${rest}`;
|
|
32
|
+
}
|
|
33
|
+
const segments = path.split('/').filter(segment => segment !== '');
|
|
34
|
+
if (segments.length <= PATH_SEGMENTS)
|
|
35
|
+
return path;
|
|
36
|
+
return `…/${segments.slice(-PATH_SEGMENTS).join('/')}`;
|
|
37
|
+
}
|
|
38
|
+
function elapsed(ms) {
|
|
39
|
+
if (ms < MINUTE_MS)
|
|
40
|
+
return `${Math.max(1, Math.round(ms / SECOND_MS))}s`;
|
|
41
|
+
return `${Math.floor(ms / MINUTE_MS)}m${String(Math.round((ms % MINUTE_MS) / SECOND_MS)).padStart(2, '0')}s`;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* One line of state, ordered by what a reader asks first: is it working, what is
|
|
45
|
+
* it, how full is the context, and where am I.
|
|
46
|
+
*/
|
|
47
|
+
export function formatStatus(facts, width, theme) {
|
|
48
|
+
const parts = [];
|
|
49
|
+
if (facts.activity === 'working') {
|
|
50
|
+
parts.push(facts.elapsedMs === undefined ? '▶ working' : `▶ working ${elapsed(facts.elapsedMs)}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
parts.push('● ready');
|
|
54
|
+
}
|
|
55
|
+
// The mode comes first: it decides which tools exist at all, so a reader who
|
|
56
|
+
// saw a tool disappear needs it before the model that ran it.
|
|
57
|
+
if (facts.agentPreset !== undefined && facts.agentPreset !== '')
|
|
58
|
+
parts.push(facts.agentPreset);
|
|
59
|
+
if (facts.model !== undefined && facts.model !== '') {
|
|
60
|
+
const route = facts.provider === undefined || facts.provider === '' ? facts.model : `${facts.provider}/${facts.model}`;
|
|
61
|
+
parts.push(facts.effort === undefined || facts.effort === '' ? route : `${route} (${facts.effort})`);
|
|
62
|
+
}
|
|
63
|
+
if (facts.preset !== undefined && facts.preset !== '')
|
|
64
|
+
parts.push(facts.preset);
|
|
65
|
+
if (facts.contextTokens !== undefined) {
|
|
66
|
+
parts.push(facts.contextWindow === undefined
|
|
67
|
+
? `ctx ${formatTokens(facts.contextTokens)}`
|
|
68
|
+
: `ctx ${formatTokens(facts.contextTokens)}/${formatTokens(facts.contextWindow)}`);
|
|
69
|
+
}
|
|
70
|
+
if (facts.cacheRate !== undefined)
|
|
71
|
+
parts.push(`cache ${Math.round(facts.cacheRate * 100)}%`);
|
|
72
|
+
parts.push(shortPath(facts.cwd, facts.home));
|
|
73
|
+
return theme.dim(truncateToWidth(displayText(parts.join(' · ')), width, '…'));
|
|
74
|
+
}
|
|
75
|
+
/** A one-row view of the state around the transcript. */
|
|
76
|
+
export class StatusBar {
|
|
77
|
+
facts;
|
|
78
|
+
theme;
|
|
79
|
+
constructor(facts, theme) {
|
|
80
|
+
this.facts = facts;
|
|
81
|
+
this.theme = theme;
|
|
82
|
+
}
|
|
83
|
+
invalidate() {
|
|
84
|
+
// The facts are read on every render; nothing is cached.
|
|
85
|
+
}
|
|
86
|
+
render(width) {
|
|
87
|
+
return width <= 0 ? [] : [formatStatus(this.facts(), width, this.theme)];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/ui/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AA2BxC,MAAM,QAAQ,GAAG,IAAI,CAAA;AACrB,MAAM,gBAAgB,GAAG,GAAG,GAAG,QAAQ,CAAA;AACvC,MAAM,OAAO,GAAG,SAAS,CAAA;AACzB,MAAM,SAAS,GAAG,IAAI,CAAA;AACtB,MAAM,SAAS,GAAG,EAAE,GAAG,SAAS,CAAA;AAChC,iGAAiG;AACjG,MAAM,aAAa,GAAG,CAAC,CAAA;AAEvB,wFAAwF;AACxF,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,KAAK,IAAI,OAAO;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAA;IAC/D,0EAA0E;IAC1E,IAAI,KAAK,IAAI,gBAAgB;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAA;IACxE,IAAI,KAAK,IAAI,QAAQ;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAA;IACjE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAwB;IAC9D,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC;QACxF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QACxD,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;IACzC,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAA;IAClE,IAAI,QAAQ,CAAC,MAAM,IAAI,aAAa;QAAE,OAAO,IAAI,CAAA;IACjD,OAAO,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;AACxD,CAAC;AAED,SAAS,OAAO,CAAC,EAAU;IACzB,IAAI,EAAE,GAAG,SAAS;QAAE,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,CAAA;IACxE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAA;AAC9G,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAkB,EAAE,KAAa,EAAE,KAAe;IAC7E,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;IACnG,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACvB,CAAC;IACD,6EAA6E;IAC7E,8DAA8D;IAC9D,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IAC9F,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAA;QACtH,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IACtG,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC/E,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS;YAC1C,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;YAC5C,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;IACtF,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5F,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5C,OAAO,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;AAC/E,CAAC;AAED,yDAAyD;AACzD,MAAM,OAAO,SAAS;IAED;IACA;IAFnB,YACmB,KAAwB,EACxB,KAAe;QADf,UAAK,GAAL,KAAK,CAAmB;QACxB,UAAK,GAAL,KAAK,CAAU;IAC/B,CAAC;IAEJ,UAAU;QACR,yDAAyD;IAC3D,CAAC;IAED,MAAM,CAAC,KAAa;QAClB,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1E,CAAC;CACF"}
|
package/lib/ui/view.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Component } from '@earendil-works/pi-tui';
|
|
2
|
+
import type { GateCard } from '../gates.ts';
|
|
3
|
+
import type { TranscriptEntry, TranscriptModel } from '../transcript.ts';
|
|
4
|
+
import type { TuiTheme } from '../theme.ts';
|
|
5
|
+
import type { MarkdownRenderer } from './markdown.ts';
|
|
6
|
+
import type { PickerCard } from './picker.ts';
|
|
7
|
+
import { RowCache } from './rows.ts';
|
|
8
|
+
/** Which rows the reader has opened; one key decides for every row of a kind. */
|
|
9
|
+
export interface ViewState {
|
|
10
|
+
readonly expandCards: boolean;
|
|
11
|
+
readonly expandReasoning: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Renders the transcript rows and any pending gate as terminal lines.
|
|
15
|
+
*
|
|
16
|
+
* The component stays a pure projection: it holds no cache of its own, so a
|
|
17
|
+
* resize, a resume, or an open gate redraws the same rows without replaying
|
|
18
|
+
* anything. Everything it draws came from a model, a tool, or a file, so the
|
|
19
|
+
* text passes through the display escaping before it is styled.
|
|
20
|
+
*/
|
|
21
|
+
/** What sits below the transcript while the reader is being asked something. */
|
|
22
|
+
export interface TranscriptViewOptions {
|
|
23
|
+
readonly state?: () => ViewState;
|
|
24
|
+
readonly gate?: () => GateCard | undefined;
|
|
25
|
+
readonly picker?: () => PickerCard | undefined;
|
|
26
|
+
/** Injectable so a test can see that a repaint reused the rows it had. */
|
|
27
|
+
readonly rows?: RowCache<TranscriptEntry>;
|
|
28
|
+
}
|
|
29
|
+
export declare class TranscriptView implements Component {
|
|
30
|
+
private readonly model;
|
|
31
|
+
private readonly theme;
|
|
32
|
+
private readonly markdown;
|
|
33
|
+
private readonly options;
|
|
34
|
+
private readonly rows;
|
|
35
|
+
constructor(model: TranscriptModel, theme: TuiTheme, markdown: MarkdownRenderer, options?: TranscriptViewOptions);
|
|
36
|
+
private get viewState();
|
|
37
|
+
/** The cache's own account of the work it avoided; a test reads this. */
|
|
38
|
+
rowStats(): {
|
|
39
|
+
readonly hits: number;
|
|
40
|
+
readonly misses: number;
|
|
41
|
+
readonly size: number;
|
|
42
|
+
};
|
|
43
|
+
invalidate(): void;
|
|
44
|
+
/** Wrap one text block under a prefix, keeping the prefix's column budget. */
|
|
45
|
+
private pushWrapped;
|
|
46
|
+
/** Render assistant text as markdown: the model writes structure, the reader reads it. */
|
|
47
|
+
private pushMarkdown;
|
|
48
|
+
private pushReasoning;
|
|
49
|
+
private pushCard;
|
|
50
|
+
private pushPicker;
|
|
51
|
+
private pushGate;
|
|
52
|
+
/** The rows one transcript entry becomes. */
|
|
53
|
+
private renderEntry;
|
|
54
|
+
render(width: number): string[];
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/ui/view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAmD,MAAM,wBAAwB,CAAA;AAExG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACxE,OAAO,KAAK,EAAoB,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAKpC,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;CAClC;AAID;;;;;;;GAOG;AACH,gFAAgF;AAChF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,SAAS,CAAA;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAA;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,UAAU,GAAG,SAAS,CAAA;IAC9C,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;CAC1C;AAED,qBAAa,cAAe,YAAW,SAAS;IAI5C,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;gBAG7B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE,qBAA0B;IAKtD,OAAO,KAAK,SAAS,GAEpB;IAED,yEAAyE;IACzE,QAAQ,IAAI;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAIrF,UAAU,IAAI,IAAI;IAMlB,8EAA8E;IAC9E,OAAO,CAAC,WAAW;IAenB,0FAA0F;IAC1F,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,QAAQ;IAiBhB,OAAO,CAAC,UAAU;IA0BlB,OAAO,CAAC,QAAQ;IAmBhB,6CAA6C;IAC7C,OAAO,CAAC,WAAW;IAuBnB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CA+BhC"}
|
package/lib/ui/view.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from '@earendil-works/pi-tui';
|
|
2
|
+
import { cardDetailRows } from "../cards.js";
|
|
3
|
+
import { displayText } from "../text.js";
|
|
4
|
+
import { RowCache } from "./rows.js";
|
|
5
|
+
const DETAIL_INDENT = ' ';
|
|
6
|
+
const OPTION_INDENT = ' ';
|
|
7
|
+
const ALL_COLLAPSED = { expandCards: false, expandReasoning: false };
|
|
8
|
+
export class TranscriptView {
|
|
9
|
+
model;
|
|
10
|
+
theme;
|
|
11
|
+
markdown;
|
|
12
|
+
options;
|
|
13
|
+
rows;
|
|
14
|
+
constructor(model, theme, markdown, options = {}) {
|
|
15
|
+
this.model = model;
|
|
16
|
+
this.theme = theme;
|
|
17
|
+
this.markdown = markdown;
|
|
18
|
+
this.options = options;
|
|
19
|
+
this.rows = options.rows ?? new RowCache();
|
|
20
|
+
}
|
|
21
|
+
get viewState() {
|
|
22
|
+
return this.options.state?.() ?? ALL_COLLAPSED;
|
|
23
|
+
}
|
|
24
|
+
/** The cache's own account of the work it avoided; a test reads this. */
|
|
25
|
+
rowStats() {
|
|
26
|
+
return this.rows.stats();
|
|
27
|
+
}
|
|
28
|
+
invalidate() {
|
|
29
|
+
// The rows are keyed by width and expansion state, so a real change misses
|
|
30
|
+
// anyway; an explicit invalidate means the caller wants them rebuilt.
|
|
31
|
+
this.rows.clear();
|
|
32
|
+
}
|
|
33
|
+
/** Wrap one text block under a prefix, keeping the prefix's column budget. */
|
|
34
|
+
pushWrapped(lines, text, width, prefix, style) {
|
|
35
|
+
const lead = visibleWidth(prefix);
|
|
36
|
+
const indent = ' '.repeat(lead);
|
|
37
|
+
const wrapped = wrapTextWithAnsi(displayText(text), Math.max(1, width - lead));
|
|
38
|
+
wrapped.forEach((line, index) => {
|
|
39
|
+
lines.push(style(truncateToWidth(`${index === 0 ? prefix : indent}${line}`, width, '')));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/** Render assistant text as markdown: the model writes structure, the reader reads it. */
|
|
43
|
+
pushMarkdown(lines, text, width, prefix) {
|
|
44
|
+
const lead = visibleWidth(prefix);
|
|
45
|
+
const indent = ' '.repeat(lead);
|
|
46
|
+
const rendered = this.markdown.render(displayText(text), Math.max(1, width - lead));
|
|
47
|
+
rendered.forEach((line, index) => {
|
|
48
|
+
// The renderer pads to its width for background styling we do not use.
|
|
49
|
+
const trimmed = line.replace(/[ \t]+$/u, '');
|
|
50
|
+
// A blank markdown line stays blank: indenting it would leave trailing
|
|
51
|
+
// spaces in the frame for a row that shows nothing.
|
|
52
|
+
if (trimmed === '') {
|
|
53
|
+
lines.push('');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
lines.push(truncateToWidth(`${index === 0 ? prefix : indent}${trimmed}`, width, '…'));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
pushReasoning(lines, entry, width) {
|
|
60
|
+
lines.push(this.theme.dim(truncateToWidth(`${this.theme.glyphs.reasoning} ${displayText(entry.summary)}`, width, '')));
|
|
61
|
+
if (!this.viewState.expandReasoning)
|
|
62
|
+
return;
|
|
63
|
+
for (const line of entry.body.split('\n')) {
|
|
64
|
+
this.pushWrapped(lines, line, width, DETAIL_INDENT, this.theme.dim);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
pushCard(lines, card, width) {
|
|
68
|
+
const expanded = this.viewState.expandCards;
|
|
69
|
+
const { lines: detail, hidden } = cardDetailRows(card, expanded);
|
|
70
|
+
const mark = card.failed ? '✗' : '⚒';
|
|
71
|
+
lines.push(this.theme.tool(truncateToWidth(`${mark} ${displayText(card.title)}`, width, '')));
|
|
72
|
+
for (const row of detail) {
|
|
73
|
+
const style = row.startsWith('+')
|
|
74
|
+
? this.theme.added
|
|
75
|
+
: row.startsWith('-') ? this.theme.removed : this.theme.dim;
|
|
76
|
+
lines.push(style(truncateToWidth(`${DETAIL_INDENT}${displayText(row)}`, width, '')));
|
|
77
|
+
}
|
|
78
|
+
if (hidden > 0) {
|
|
79
|
+
const hint = expanded ? `${hidden} more lines not shown` : `… ${hidden} more lines · ctrl+o shows them`;
|
|
80
|
+
lines.push(this.theme.dim(truncateToWidth(`${DETAIL_INDENT}${hint}`, width, '')));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
pushPicker(lines, picker, width) {
|
|
84
|
+
lines.push('');
|
|
85
|
+
lines.push(this.theme.bold(truncateToWidth(`↻ ${displayText(picker.title)}`, width, '')));
|
|
86
|
+
if (picker.note !== undefined) {
|
|
87
|
+
this.pushWrapped(lines, picker.note, width, DETAIL_INDENT, this.theme.bold);
|
|
88
|
+
}
|
|
89
|
+
if (picker.filter !== '') {
|
|
90
|
+
lines.push(this.theme.dim(truncateToWidth(`${DETAIL_INDENT}filter: ${displayText(picker.filter)}`, width, '')));
|
|
91
|
+
}
|
|
92
|
+
if (picker.above > 0) {
|
|
93
|
+
lines.push(this.theme.dim(truncateToWidth(`${OPTION_INDENT}… ${picker.above} newer`, width, '')));
|
|
94
|
+
}
|
|
95
|
+
for (const row of picker.rows) {
|
|
96
|
+
const cursor = row.current ? '❯' : ' ';
|
|
97
|
+
const text = row.description === undefined
|
|
98
|
+
? `${cursor} ${row.label}`
|
|
99
|
+
: `${cursor} ${row.label} — ${row.description}`;
|
|
100
|
+
const style = row.current ? this.theme.bold : (value) => value;
|
|
101
|
+
lines.push(style(truncateToWidth(`${OPTION_INDENT}${displayText(text)}`, width, '')));
|
|
102
|
+
}
|
|
103
|
+
if (picker.below > 0) {
|
|
104
|
+
lines.push(this.theme.dim(truncateToWidth(`${OPTION_INDENT}… ${picker.below} older`, width, '')));
|
|
105
|
+
}
|
|
106
|
+
lines.push(this.theme.dim(truncateToWidth(`${OPTION_INDENT}${displayText(picker.hint)}`, width, '')));
|
|
107
|
+
}
|
|
108
|
+
pushGate(lines, gate, width) {
|
|
109
|
+
lines.push('');
|
|
110
|
+
lines.push(this.theme.bold(truncateToWidth(`${gate.kind === 'approval' ? '⚠' : '?'} ${displayText(gate.title)}`, width, '')));
|
|
111
|
+
for (const detail of gate.detail) {
|
|
112
|
+
this.pushWrapped(lines, detail, width, DETAIL_INDENT, this.theme.dim);
|
|
113
|
+
}
|
|
114
|
+
gate.options.forEach((option, position) => {
|
|
115
|
+
const box = option.selected ? '[x]' : '[ ]';
|
|
116
|
+
const cursor = option.current ? '❯' : ' ';
|
|
117
|
+
const label = displayText(option.label);
|
|
118
|
+
const text = option.description === undefined
|
|
119
|
+
? `${cursor} ${box} ${position + 1}. ${label}`
|
|
120
|
+
: `${cursor} ${box} ${position + 1}. ${label} — ${displayText(option.description)}`;
|
|
121
|
+
const style = option.current ? this.theme.bold : (value) => value;
|
|
122
|
+
lines.push(style(truncateToWidth(`${OPTION_INDENT}${text}`, width, '')));
|
|
123
|
+
});
|
|
124
|
+
lines.push(this.theme.dim(truncateToWidth(`${OPTION_INDENT}${displayText(gate.hint)}`, width, '')));
|
|
125
|
+
}
|
|
126
|
+
/** The rows one transcript entry becomes. */
|
|
127
|
+
renderEntry(entry, lines, width, glyphs) {
|
|
128
|
+
switch (entry.kind) {
|
|
129
|
+
case 'tool':
|
|
130
|
+
this.pushCard(lines, entry.card, width);
|
|
131
|
+
return;
|
|
132
|
+
case 'reasoning':
|
|
133
|
+
this.pushReasoning(lines, entry, width);
|
|
134
|
+
return;
|
|
135
|
+
case 'assistant':
|
|
136
|
+
this.pushMarkdown(lines, entry.text, width, `${glyphs.assistant} `);
|
|
137
|
+
return;
|
|
138
|
+
case 'user':
|
|
139
|
+
this.pushWrapped(lines, entry.text, width, `${glyphs.user} `, this.theme.bold);
|
|
140
|
+
return;
|
|
141
|
+
case 'notice':
|
|
142
|
+
this.pushWrapped(lines, entry.text, width, `${glyphs.notice} `, this.theme.notice);
|
|
143
|
+
return;
|
|
144
|
+
case 'marker':
|
|
145
|
+
this.pushWrapped(lines, entry.text, width, `${glyphs.marker} `, this.theme.marker);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
render(width) {
|
|
150
|
+
if (width <= 0)
|
|
151
|
+
return [];
|
|
152
|
+
const { glyphs } = this.theme;
|
|
153
|
+
const state = this.viewState;
|
|
154
|
+
const tag = `${width}|${state.expandCards ? 'c' : '-'}${state.expandReasoning ? 'r' : '-'}`;
|
|
155
|
+
const lines = [];
|
|
156
|
+
const settled = this.model.settledCount();
|
|
157
|
+
const entries = this.model.entries();
|
|
158
|
+
for (const [index, entry] of entries.entries()) {
|
|
159
|
+
// The in-flight rows change on every frame, so caching them would only
|
|
160
|
+
// fill the cache with objects nobody will ask for again.
|
|
161
|
+
if (index >= settled) {
|
|
162
|
+
this.renderEntry(entry, lines, width, glyphs);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const cached = this.rows.lookup(entry, tag);
|
|
166
|
+
if (cached !== undefined) {
|
|
167
|
+
lines.push(...cached);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const rendered = [];
|
|
171
|
+
this.renderEntry(entry, rendered, width, glyphs);
|
|
172
|
+
this.rows.store(entry, tag, rendered);
|
|
173
|
+
lines.push(...rendered);
|
|
174
|
+
}
|
|
175
|
+
const picker = this.options.picker?.();
|
|
176
|
+
if (picker !== undefined)
|
|
177
|
+
this.pushPicker(lines, picker, width);
|
|
178
|
+
const gate = this.options.gate?.();
|
|
179
|
+
if (gate !== undefined)
|
|
180
|
+
this.pushGate(lines, gate, width);
|
|
181
|
+
return lines;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/ui/view.ts"],"names":[],"mappings":"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"}
|
package/lib/work.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { FoldableEvent } from './transcript.ts';
|
|
2
|
+
/** One entry of the agent's todo list, as the tool writes it. */
|
|
3
|
+
export interface TodoEntry {
|
|
4
|
+
readonly content: string;
|
|
5
|
+
readonly status: 'pending' | 'in_progress' | 'completed';
|
|
6
|
+
}
|
|
7
|
+
/** The goal a continuation loop is driving, when one is set. */
|
|
8
|
+
export interface GoalState {
|
|
9
|
+
readonly objective: string;
|
|
10
|
+
readonly roundsStarted: number;
|
|
11
|
+
readonly maxRounds: number | undefined;
|
|
12
|
+
}
|
|
13
|
+
/** What the agent is working on, folded from durable events. */
|
|
14
|
+
export interface WorkState {
|
|
15
|
+
readonly planMode: boolean;
|
|
16
|
+
readonly todos: readonly TodoEntry[] | undefined;
|
|
17
|
+
readonly goal: GoalState | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** What the reader most needs to see first: work in flight, then work left. */
|
|
20
|
+
export declare function orderTodos(todos: readonly TodoEntry[]): readonly TodoEntry[];
|
|
21
|
+
/** The todo list as plain lines, for a reader who asked for it by name. */
|
|
22
|
+
export declare function describeTodos(todos: readonly TodoEntry[] | undefined): string;
|
|
23
|
+
/**
|
|
24
|
+
* Fold the agent's work state out of durable events.
|
|
25
|
+
*
|
|
26
|
+
* The state is folded rather than read from a service so a resumed session
|
|
27
|
+
* shows exactly what the live one did, and so a composition without the
|
|
28
|
+
* projection registry still tells the reader what the agent is doing. Each of
|
|
29
|
+
* these events is a whole-value snapshot: the latest one wins.
|
|
30
|
+
*/
|
|
31
|
+
export declare class WorkFold {
|
|
32
|
+
private planMode;
|
|
33
|
+
private todos;
|
|
34
|
+
private goal;
|
|
35
|
+
state(): WorkState;
|
|
36
|
+
reset(): void;
|
|
37
|
+
apply(event: FoldableEvent): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=work.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work.d.ts","sourceRoot":"","sources":["../src/work.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,iEAAiE;AACjE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,CAAA;CACzD;AAED,gEAAgE;AAChE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED,gEAAgE;AAChE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAA;IAChD,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAA;CACrC;AA6BD,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,SAAS,EAAE,CAG5E;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,MAAM,CAK7E;AAED;;;;;;;GAOG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,IAAI,CAAuB;IAEnC,KAAK,IAAI,SAAS;IAMlB,KAAK,IAAI,IAAI;IAMb,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;CAkClC"}
|
package/lib/work.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const EMPTY = { planMode: false, todos: undefined, goal: undefined };
|
|
2
|
+
function asRecord(value) {
|
|
3
|
+
return typeof value === 'object' && value !== null ? value : undefined;
|
|
4
|
+
}
|
|
5
|
+
const TODO_STATUSES = new Set(['pending', 'in_progress', 'completed']);
|
|
6
|
+
function todoEntries(value) {
|
|
7
|
+
if (!Array.isArray(value))
|
|
8
|
+
return [];
|
|
9
|
+
const entries = [];
|
|
10
|
+
for (const item of value) {
|
|
11
|
+
const record = asRecord(item);
|
|
12
|
+
const status = record?.status;
|
|
13
|
+
if (typeof record?.content !== 'string')
|
|
14
|
+
continue;
|
|
15
|
+
if (typeof status !== 'string' || !TODO_STATUSES.has(status))
|
|
16
|
+
continue;
|
|
17
|
+
entries.push({ content: record.content, status: status });
|
|
18
|
+
}
|
|
19
|
+
return entries;
|
|
20
|
+
}
|
|
21
|
+
const TODO_GLYPHS = {
|
|
22
|
+
pending: '☐',
|
|
23
|
+
in_progress: '▸',
|
|
24
|
+
completed: '☑',
|
|
25
|
+
};
|
|
26
|
+
/** What the reader most needs to see first: work in flight, then work left. */
|
|
27
|
+
export function orderTodos(todos) {
|
|
28
|
+
const rank = { in_progress: 0, pending: 1, completed: 2 };
|
|
29
|
+
return [...todos].sort((left, right) => rank[left.status] - rank[right.status]);
|
|
30
|
+
}
|
|
31
|
+
/** The todo list as plain lines, for a reader who asked for it by name. */
|
|
32
|
+
export function describeTodos(todos) {
|
|
33
|
+
if (todos === undefined || todos.length === 0)
|
|
34
|
+
return 'no todo list has been written in this session';
|
|
35
|
+
const done = todos.filter(todo => todo.status === 'completed').length;
|
|
36
|
+
const rows = orderTodos(todos).map(todo => ` ${TODO_GLYPHS[todo.status]} ${todo.content}`);
|
|
37
|
+
return [`todos · ${done}/${todos.length} done`, ...rows].join('\n');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Fold the agent's work state out of durable events.
|
|
41
|
+
*
|
|
42
|
+
* The state is folded rather than read from a service so a resumed session
|
|
43
|
+
* shows exactly what the live one did, and so a composition without the
|
|
44
|
+
* projection registry still tells the reader what the agent is doing. Each of
|
|
45
|
+
* these events is a whole-value snapshot: the latest one wins.
|
|
46
|
+
*/
|
|
47
|
+
export class WorkFold {
|
|
48
|
+
planMode = false;
|
|
49
|
+
todos;
|
|
50
|
+
goal;
|
|
51
|
+
state() {
|
|
52
|
+
return this.planMode || this.todos !== undefined || this.goal !== undefined
|
|
53
|
+
? { planMode: this.planMode, todos: this.todos, goal: this.goal }
|
|
54
|
+
: EMPTY;
|
|
55
|
+
}
|
|
56
|
+
reset() {
|
|
57
|
+
this.planMode = false;
|
|
58
|
+
this.todos = undefined;
|
|
59
|
+
this.goal = undefined;
|
|
60
|
+
}
|
|
61
|
+
apply(event) {
|
|
62
|
+
const data = asRecord(event.data) ?? {};
|
|
63
|
+
switch (event.type) {
|
|
64
|
+
case 'plan/mode':
|
|
65
|
+
this.planMode = data.active === true;
|
|
66
|
+
return;
|
|
67
|
+
case 'todo/write': {
|
|
68
|
+
const entries = todoEntries(data.todos);
|
|
69
|
+
this.todos = entries.length === 0 ? undefined : entries;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
case 'goal/change': {
|
|
73
|
+
if (data.operation === 'clear' || data.goal === undefined) {
|
|
74
|
+
this.goal = undefined;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const goal = asRecord(data.goal);
|
|
78
|
+
const objective = goal?.objective;
|
|
79
|
+
if (typeof objective !== 'string')
|
|
80
|
+
return;
|
|
81
|
+
const maxRounds = goal?.maxGoalRounds;
|
|
82
|
+
const roundsStarted = typeof data.roundsStarted === 'number'
|
|
83
|
+
? data.roundsStarted
|
|
84
|
+
: typeof goal?.roundsStarted === 'number' ? goal.roundsStarted : 0;
|
|
85
|
+
this.goal = {
|
|
86
|
+
objective,
|
|
87
|
+
roundsStarted,
|
|
88
|
+
maxRounds: typeof maxRounds === 'number' ? maxRounds : undefined,
|
|
89
|
+
};
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
default:
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=work.js.map
|
package/lib/work.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work.js","sourceRoot":"","sources":["../src/work.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sagmans/dsh-tui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Terminal (CLI TUI) surface for DeepSeek Harness: interactive dsh in a terminal, no browser required",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"deepseek-harness",
|
|
7
|
+
"dsh",
|
|
8
|
+
"dsh-plugin",
|
|
9
|
+
"plugin",
|
|
10
|
+
"tui",
|
|
11
|
+
"terminal",
|
|
12
|
+
"cordis"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "lib/index.js",
|
|
17
|
+
"types": "lib/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./lib/index.d.ts",
|
|
21
|
+
"default": "./lib/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./startup": {
|
|
24
|
+
"types": "./lib/startup.d.ts",
|
|
25
|
+
"default": "./lib/startup.js"
|
|
26
|
+
},
|
|
27
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"lib",
|
|
32
|
+
"cordis.patch.yml",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/sagmans/dsh-tui.git"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/sagmans/dsh-tui#readme",
|
|
40
|
+
"bugs": "https://github.com/sagmans/dsh-tui/issues",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22.19"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public",
|
|
46
|
+
"registry": "https://registry.npmjs.org/"
|
|
47
|
+
},
|
|
48
|
+
"dsh": {
|
|
49
|
+
"bundle": {
|
|
50
|
+
"patch": "./cordis.patch.yml"
|
|
51
|
+
},
|
|
52
|
+
"compatibility": {
|
|
53
|
+
"dsh": ">=0.1.5-rc.1 <0.1.6",
|
|
54
|
+
"dshReleases": {
|
|
55
|
+
"0.1.5-rc.1": "compatible"
|
|
56
|
+
},
|
|
57
|
+
"profiles": [
|
|
58
|
+
"tui"
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "tsc -p tsconfig.json",
|
|
64
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json",
|
|
65
|
+
"test": "vitest run",
|
|
66
|
+
"test:release": "python3 -m unittest discover -s tests/release -p 'test_*.py'",
|
|
67
|
+
"prepare": "npm run build",
|
|
68
|
+
"prepack": "npm run build",
|
|
69
|
+
"prepublishOnly": "npm run typecheck && npm test",
|
|
70
|
+
"drive": "node tools/pty-drive.mjs"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@deepseek-ai/dsh-agent-presets": "0.1.5-rc.1",
|
|
74
|
+
"@deepseek-ai/dsh-code-runtime-worker-thread": "0.1.5-rc.1",
|
|
75
|
+
"@deepseek-ai/dsh-cordis-host-runner": "0.1.5-rc.1",
|
|
76
|
+
"@earendil-works/pi-tui": "0.85.1",
|
|
77
|
+
"commander": "^15.0.0"
|
|
78
|
+
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
81
|
+
"@deepseek-ai/dsh-agent": "0.1.5-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-agent-default-model": "0.1.5-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-agent-loop": "0.1.5-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-cmdline": "0.1.5-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-commands": "0.1.5-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-llm": "0.1.5-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-session": "0.1.5-rc.1",
|
|
88
|
+
"@deepseek-ai/dsh-tools": "0.1.5-rc.1",
|
|
89
|
+
"@deepseek-ai/dsh-user-approval": "0.1.5-rc.1",
|
|
90
|
+
"@deepseek-ai/dsh-user-questions": "0.1.5-rc.1"
|
|
91
|
+
},
|
|
92
|
+
"devDependencies": {
|
|
93
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
94
|
+
"@deepseek-ai/dsh-agent": "0.1.5-rc.1",
|
|
95
|
+
"@deepseek-ai/dsh-agent-default-model": "0.1.5-rc.1",
|
|
96
|
+
"@deepseek-ai/dsh-agent-loop": "0.1.5-rc.1",
|
|
97
|
+
"@deepseek-ai/dsh-cmdline": "0.1.5-rc.1",
|
|
98
|
+
"@deepseek-ai/dsh-commands": "0.1.5-rc.1",
|
|
99
|
+
"@deepseek-ai/dsh-llm": "0.1.5-rc.1",
|
|
100
|
+
"@deepseek-ai/dsh-session": "0.1.5-rc.1",
|
|
101
|
+
"@deepseek-ai/dsh-tools": "0.1.5-rc.1",
|
|
102
|
+
"@deepseek-ai/dsh-user-approval": "0.1.5-rc.1",
|
|
103
|
+
"@deepseek-ai/dsh-user-questions": "0.1.5-rc.1",
|
|
104
|
+
"@types/node": "^24.0.0",
|
|
105
|
+
"node-pty": "1.1.0",
|
|
106
|
+
"typescript": "^5.9.0",
|
|
107
|
+
"vitest": "^4.1.0"
|
|
108
|
+
}
|
|
109
|
+
}
|