@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.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +266 -0
  3. package/cordis.patch.yml +123 -0
  4. package/lib/agent/fork.d.ts +24 -0
  5. package/lib/agent/fork.d.ts.map +1 -0
  6. package/lib/agent/fork.js +25 -0
  7. package/lib/agent/fork.js.map +1 -0
  8. package/lib/agent/history.d.ts +78 -0
  9. package/lib/agent/history.d.ts.map +1 -0
  10. package/lib/agent/history.js +179 -0
  11. package/lib/agent/history.js.map +1 -0
  12. package/lib/agent/host.d.ts +58 -0
  13. package/lib/agent/host.d.ts.map +1 -0
  14. package/lib/agent/host.js +59 -0
  15. package/lib/agent/host.js.map +1 -0
  16. package/lib/agent/model.d.ts +61 -0
  17. package/lib/agent/model.d.ts.map +1 -0
  18. package/lib/agent/model.js +92 -0
  19. package/lib/agent/model.js.map +1 -0
  20. package/lib/agent/present.d.ts +12 -0
  21. package/lib/agent/present.d.ts.map +1 -0
  22. package/lib/agent/present.js +52 -0
  23. package/lib/agent/present.js.map +1 -0
  24. package/lib/agent/presets.d.ts +75 -0
  25. package/lib/agent/presets.d.ts.map +1 -0
  26. package/lib/agent/presets.js +117 -0
  27. package/lib/agent/presets.js.map +1 -0
  28. package/lib/agent/projections.d.ts +16 -0
  29. package/lib/agent/projections.d.ts.map +1 -0
  30. package/lib/agent/projections.js +31 -0
  31. package/lib/agent/projections.js.map +1 -0
  32. package/lib/agent/status.d.ts +46 -0
  33. package/lib/agent/status.d.ts.map +1 -0
  34. package/lib/agent/status.js +67 -0
  35. package/lib/agent/status.js.map +1 -0
  36. package/lib/cards.d.ts +88 -0
  37. package/lib/cards.d.ts.map +1 -0
  38. package/lib/cards.js +218 -0
  39. package/lib/cards.js.map +1 -0
  40. package/lib/compat/probe.d.ts +33 -0
  41. package/lib/compat/probe.d.ts.map +1 -0
  42. package/lib/compat/probe.js +74 -0
  43. package/lib/compat/probe.js.map +1 -0
  44. package/lib/config.d.ts +13 -0
  45. package/lib/config.d.ts.map +1 -0
  46. package/lib/config.js +49 -0
  47. package/lib/config.js.map +1 -0
  48. package/lib/contracts.d.ts +32 -0
  49. package/lib/contracts.d.ts.map +1 -0
  50. package/lib/contracts.js +2 -0
  51. package/lib/contracts.js.map +1 -0
  52. package/lib/export.d.ts +15 -0
  53. package/lib/export.d.ts.map +1 -0
  54. package/lib/export.js +52 -0
  55. package/lib/export.js.map +1 -0
  56. package/lib/gates.d.ts +85 -0
  57. package/lib/gates.d.ts.map +1 -0
  58. package/lib/gates.js +216 -0
  59. package/lib/gates.js.map +1 -0
  60. package/lib/identity.d.ts +33 -0
  61. package/lib/identity.d.ts.map +1 -0
  62. package/lib/identity.js +49 -0
  63. package/lib/identity.js.map +1 -0
  64. package/lib/index.d.ts +24 -0
  65. package/lib/index.d.ts.map +1 -0
  66. package/lib/index.js +1196 -0
  67. package/lib/index.js.map +1 -0
  68. package/lib/input/completion.d.ts +22 -0
  69. package/lib/input/completion.d.ts.map +1 -0
  70. package/lib/input/completion.js +27 -0
  71. package/lib/input/completion.js.map +1 -0
  72. package/lib/input/submission.d.ts +62 -0
  73. package/lib/input/submission.d.ts.map +1 -0
  74. package/lib/input/submission.js +80 -0
  75. package/lib/input/submission.js.map +1 -0
  76. package/lib/jobs.d.ts +64 -0
  77. package/lib/jobs.d.ts.map +1 -0
  78. package/lib/jobs.js +123 -0
  79. package/lib/jobs.js.map +1 -0
  80. package/lib/startup.d.ts +17 -0
  81. package/lib/startup.d.ts.map +1 -0
  82. package/lib/startup.js +67 -0
  83. package/lib/startup.js.map +1 -0
  84. package/lib/subagents.d.ts +74 -0
  85. package/lib/subagents.d.ts.map +1 -0
  86. package/lib/subagents.js +141 -0
  87. package/lib/subagents.js.map +1 -0
  88. package/lib/terminal/bell.d.ts +18 -0
  89. package/lib/terminal/bell.d.ts.map +1 -0
  90. package/lib/terminal/bell.js +16 -0
  91. package/lib/terminal/bell.js.map +1 -0
  92. package/lib/terminal/clipboard.d.ts +11 -0
  93. package/lib/terminal/clipboard.d.ts.map +1 -0
  94. package/lib/terminal/clipboard.js +18 -0
  95. package/lib/terminal/clipboard.js.map +1 -0
  96. package/lib/terminal/restore.d.ts +17 -0
  97. package/lib/terminal/restore.d.ts.map +1 -0
  98. package/lib/terminal/restore.js +43 -0
  99. package/lib/terminal/restore.js.map +1 -0
  100. package/lib/terminal/title.d.ts +22 -0
  101. package/lib/terminal/title.d.ts.map +1 -0
  102. package/lib/terminal/title.js +34 -0
  103. package/lib/terminal/title.js.map +1 -0
  104. package/lib/text.d.ts +19 -0
  105. package/lib/text.d.ts.map +1 -0
  106. package/lib/text.js +61 -0
  107. package/lib/text.js.map +1 -0
  108. package/lib/theme.d.ts +47 -0
  109. package/lib/theme.d.ts.map +1 -0
  110. package/lib/theme.js +84 -0
  111. package/lib/theme.js.map +1 -0
  112. package/lib/transcript.d.ts +91 -0
  113. package/lib/transcript.d.ts.map +1 -0
  114. package/lib/transcript.js +315 -0
  115. package/lib/transcript.js.map +1 -0
  116. package/lib/ui/dock.d.ts +36 -0
  117. package/lib/ui/dock.d.ts.map +1 -0
  118. package/lib/ui/dock.js +110 -0
  119. package/lib/ui/dock.js.map +1 -0
  120. package/lib/ui/markdown.d.ts +17 -0
  121. package/lib/ui/markdown.d.ts.map +1 -0
  122. package/lib/ui/markdown.js +35 -0
  123. package/lib/ui/markdown.js.map +1 -0
  124. package/lib/ui/picker.d.ts +103 -0
  125. package/lib/ui/picker.d.ts.map +1 -0
  126. package/lib/ui/picker.js +165 -0
  127. package/lib/ui/picker.js.map +1 -0
  128. package/lib/ui/rows.d.ts +30 -0
  129. package/lib/ui/rows.d.ts.map +1 -0
  130. package/lib/ui/rows.js +49 -0
  131. package/lib/ui/rows.js.map +1 -0
  132. package/lib/ui/status.d.ts +49 -0
  133. package/lib/ui/status.d.ts.map +1 -0
  134. package/lib/ui/status.js +90 -0
  135. package/lib/ui/status.js.map +1 -0
  136. package/lib/ui/view.d.ts +56 -0
  137. package/lib/ui/view.d.ts.map +1 -0
  138. package/lib/ui/view.js +184 -0
  139. package/lib/ui/view.js.map +1 -0
  140. package/lib/work.d.ts +39 -0
  141. package/lib/work.d.ts.map +1 -0
  142. package/lib/work.js +97 -0
  143. package/lib/work.js.map +1 -0
  144. package/package.json +109 -0
@@ -0,0 +1,117 @@
1
+ import { projectionRecord, projectionString } from "./projections.js";
2
+ /**
3
+ * Read a `/preset` argument.
4
+ *
5
+ * A bare command opens the picker because choosing by eye is the point of a
6
+ * selector; anything else is an id, which is the token the session log records.
7
+ */
8
+ export function parsePresetArgument(argument) {
9
+ const id = argument.trim();
10
+ return id === '' ? { kind: 'pick' } : { kind: 'switch', id };
11
+ }
12
+ /**
13
+ * One-line gloss for the modes this deployment ships.
14
+ *
15
+ * The Web app translates the same four ids from its own locale bundle; a
16
+ * terminal has no such bundle, so the copy lives here. A preset this table does
17
+ * not name is not ours to describe: it speaks for itself through its metadata.
18
+ */
19
+ const SHIPPED_GLOSS = {
20
+ standard: 'full agent: editing, shell, search, skills, planning, goals, subagents, workflows',
21
+ ptc: 'the same agent, with its tools reached through one TypeScript program',
22
+ minimal: 'one tool: a persistent shell',
23
+ cordis: 'harness authoring: runtime inspection and composition guidance',
24
+ };
25
+ /** How one preset appears in the picker. */
26
+ export function describePreset(preset, currentId) {
27
+ const gloss = SHIPPED_GLOSS[preset.id];
28
+ const described = preset.broken !== undefined
29
+ ? `cannot start: ${preset.broken}`
30
+ : [gloss ?? preset.name, gloss === undefined ? preset.description : undefined,
31
+ preset.trust === 'user' ? 'authored here' : undefined]
32
+ .filter(part => part !== undefined && part !== '')
33
+ .join(' · ');
34
+ return {
35
+ label: preset.id,
36
+ description: described === '' ? undefined : described,
37
+ current: preset.id === currentId,
38
+ };
39
+ }
40
+ /** The projection key the roster advances and this surface reads. */
41
+ export const AGENT_PRESET_KEY = 'agentPreset';
42
+ /** The projection key a session's turn boundary lives under. */
43
+ const TURN_BOUNDARY_KEY = 'turnBoundary';
44
+ function asRecord(value) {
45
+ return typeof value === 'object' && value !== null ? value : undefined;
46
+ }
47
+ function textOr(value) {
48
+ return typeof value === 'string' && value !== '' ? value : undefined;
49
+ }
50
+ /** One roster row, or undefined when it names no usable id. */
51
+ function toSummary(value) {
52
+ const record = asRecord(value);
53
+ const id = textOr(record?.id);
54
+ if (id === undefined)
55
+ return undefined;
56
+ return {
57
+ id,
58
+ trust: record?.trust === 'user' ? 'user' : 'system',
59
+ name: textOr(record?.name),
60
+ description: textOr(record?.description),
61
+ broken: textOr(record?.broken),
62
+ };
63
+ }
64
+ function numberOr(value) {
65
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
66
+ }
67
+ /**
68
+ * Wrap the roster in the little of it a terminal needs.
69
+ *
70
+ * The seam is optional here: a composition that dropped the row still runs the
71
+ * surface, it just has no mode to choose. Every call is guarded because the
72
+ * service arrives from another package and its shape is this surface's
73
+ * assumption, not its contract.
74
+ */
75
+ export function createPresetRoster(ctx) {
76
+ const service = ctx.get('agentPresets');
77
+ if (typeof service?.list !== 'function' || typeof service.mount !== 'function')
78
+ return undefined;
79
+ const defaultId = textOr(service.defaultId);
80
+ if (defaultId === undefined)
81
+ return undefined;
82
+ return {
83
+ defaultId,
84
+ list: async () => {
85
+ const rows = await service.list?.() ?? [];
86
+ return rows.flatMap(row => toSummary(row) ?? []);
87
+ },
88
+ resolve: async (id) => {
89
+ const resolved = await service.resolve?.(id);
90
+ const summary = toSummary(resolved);
91
+ if (summary === undefined) {
92
+ throw new Error(`agentPresets: the roster resolved ${id === undefined ? 'its default' : `"${id}"`} to nothing usable`);
93
+ }
94
+ return summary;
95
+ },
96
+ mount: async (agentCtx, id) => {
97
+ await service.mount?.(agentCtx, id);
98
+ },
99
+ select: async (agent, id) => {
100
+ const select = service.select;
101
+ if (typeof select !== 'function')
102
+ throw new Error('agentPresets: this roster cannot switch a session');
103
+ return await select.call(service, agent, id);
104
+ },
105
+ current: session => projectionString(ctx, session, AGENT_PRESET_KEY),
106
+ started: session => {
107
+ const boundary = projectionRecord(ctx, session, TURN_BOUNDARY_KEY);
108
+ if (boundary === undefined)
109
+ return false;
110
+ const open = boundary.openTurnStartSeq;
111
+ if (open !== null && open !== undefined)
112
+ return true;
113
+ return (numberOr(boundary.lastTurn) ?? 0) > 0;
114
+ },
115
+ };
116
+ }
117
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src/agent/presets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ /**
3
+ * One session projection's state.
4
+ *
5
+ * A composition without a projection registry, and a session whose projection
6
+ * unit is not registered, both leave the key simply absent — and the surface
7
+ * reads projections while rendering, where a missing fact may cost a segment
8
+ * but never the session. A registered unit that throws is treated the same way
9
+ * for the same reason.
10
+ */
11
+ export declare function projectionState(ctx: Context, session: unknown, key: string): unknown;
12
+ /** One projection's state when it is a record. */
13
+ export declare function projectionRecord(ctx: Context, session: unknown, key: string): Record<string, unknown> | undefined;
14
+ /** One projection's state when it is a non-empty string. */
15
+ export declare function projectionString(ctx: Context, session: unknown, key: string): string | undefined;
16
+ //# sourceMappingURL=projections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projections.d.ts","sourceRoot":"","sources":["../../src/agent/projections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOlD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAQpF;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAGrC;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGhG"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * One session projection's state.
3
+ *
4
+ * A composition without a projection registry, and a session whose projection
5
+ * unit is not registered, both leave the key simply absent — and the surface
6
+ * reads projections while rendering, where a missing fact may cost a segment
7
+ * but never the session. A registered unit that throws is treated the same way
8
+ * for the same reason.
9
+ */
10
+ export function projectionState(ctx, session, key) {
11
+ const projections = ctx.get('sessionProjections');
12
+ if (projections?.stateOf === undefined)
13
+ return undefined;
14
+ try {
15
+ return projections.stateOf(session, key);
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ /** One projection's state when it is a record. */
22
+ export function projectionRecord(ctx, session, key) {
23
+ const state = projectionState(ctx, session, key);
24
+ return typeof state === 'object' && state !== null ? state : undefined;
25
+ }
26
+ /** One projection's state when it is a non-empty string. */
27
+ export function projectionString(ctx, session, key) {
28
+ const state = projectionState(ctx, session, key);
29
+ return typeof state === 'string' && state !== '' ? state : undefined;
30
+ }
31
+ //# sourceMappingURL=projections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projections.js","sourceRoot":"","sources":["../../src/agent/projections.ts"],"names":[],"mappings":"AAOA;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,OAAgB,EAAE,GAAW;IACzE,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAA4B,CAAA;IAC5E,IAAI,WAAW,EAAE,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxD,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,gBAAgB,CAC9B,GAAY,EACZ,OAAgB,EAChB,GAAW;IAEX,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,SAAS,CAAA;AACnG,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,GAAY,EAAE,OAAgB,EAAE,GAAW;IAC1E,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtE,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { SessionId } from '@deepseek-ai/dsh-session';
3
+ import type { StatusFacts } from '../ui/status.ts';
4
+ /** Whether a turn is running and when it started. */
5
+ export interface ActivityState {
6
+ readonly running: boolean;
7
+ readonly startedAt: number | undefined;
8
+ }
9
+ /**
10
+ * The token-usage projection state.
11
+ *
12
+ * The unit projects `{ totals, last }` — a flat usage object is the wrong shape
13
+ * and reading it silently yields nothing, so the reader is pinned by a test.
14
+ */
15
+ export declare function usageTotals(state: unknown): Record<string, unknown> | undefined;
16
+ /**
17
+ * Share of prompt tokens a provider served from cache.
18
+ *
19
+ * Read tokens against the uncached ones: a hit rate is what a reader can act on
20
+ * (it is what caching buys), while the raw counts belong in `/status`.
21
+ */
22
+ export declare function cacheRate(usage: Record<string, unknown> | undefined): number | undefined;
23
+ /**
24
+ * Gather what the footer states.
25
+ *
26
+ * Every service is optional and every read is guarded: the footer is the least
27
+ * important thing on screen, and a composition that omits the model directory or
28
+ * the token meter should cost the reader a segment, not the session.
29
+ */
30
+ /** Where the footer reads its facts from. */
31
+ export interface StatusSources {
32
+ readonly sessionId: () => SessionId;
33
+ readonly activity: () => ActivityState;
34
+ /**
35
+ * A route the reader chose for this session, which outranks the composition
36
+ * default: the footer must show the model the next step will actually use.
37
+ */
38
+ readonly override?: (() => {
39
+ readonly provider?: string;
40
+ readonly model?: string;
41
+ readonly reasoningEffort?: string;
42
+ } | undefined) | undefined;
43
+ readonly home?: string | undefined;
44
+ }
45
+ export declare function createStatusFacts(ctx: Context, sources: StatusSources): () => StatusFacts;
46
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/agent/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAIlD,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAiBD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAE/E;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAMxF;AAUD;;;;;;GAMG;AACH,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,SAAS,CAAA;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,aAAa,CAAA;IACtC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM;QACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAClC,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,WAAW,CAiCzF"}
@@ -0,0 +1,67 @@
1
+ import { AGENT_PRESET_KEY } from "./presets.js";
2
+ import { projectionRecord, projectionString } from "./projections.js";
3
+ /**
4
+ * The token-usage projection state.
5
+ *
6
+ * The unit projects `{ totals, last }` — a flat usage object is the wrong shape
7
+ * and reading it silently yields nothing, so the reader is pinned by a test.
8
+ */
9
+ export function usageTotals(state) {
10
+ return asRecord(asRecord(state)?.totals);
11
+ }
12
+ /**
13
+ * Share of prompt tokens a provider served from cache.
14
+ *
15
+ * Read tokens against the uncached ones: a hit rate is what a reader can act on
16
+ * (it is what caching buys), while the raw counts belong in `/status`.
17
+ */
18
+ export function cacheRate(usage) {
19
+ const read = numberOr(usage?.cacheReadTokens);
20
+ const uncached = numberOr(usage?.uncachedInputTokens);
21
+ if (read === undefined || uncached === undefined)
22
+ return undefined;
23
+ const total = read + uncached;
24
+ return total === 0 ? undefined : read / total;
25
+ }
26
+ function asRecord(value) {
27
+ return typeof value === 'object' && value !== null ? value : undefined;
28
+ }
29
+ function numberOr(value) {
30
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
31
+ }
32
+ export function createStatusFacts(ctx, sources) {
33
+ return () => {
34
+ const override = sources.override?.();
35
+ const selection = override ?? ctx.get('agentDefaultModel')?.currentSelection?.();
36
+ const session = ctx.get('sessions')?.get?.(sources.sessionId());
37
+ let preset;
38
+ if (session !== undefined) {
39
+ try {
40
+ preset = ctx.get('permissionPresets')?.current?.(session);
41
+ }
42
+ catch {
43
+ preset = undefined;
44
+ }
45
+ }
46
+ const pressure = session === undefined ? undefined : projectionRecord(ctx, session, 'contextPressure');
47
+ const totals = session === undefined ? undefined : usageTotals(projectionRecord(ctx, session, 'tokenUsage'));
48
+ const state = sources.activity();
49
+ return {
50
+ activity: state.running ? 'working' : 'idle',
51
+ elapsedMs: state.startedAt === undefined ? undefined : Date.now() - state.startedAt,
52
+ provider: selection?.provider,
53
+ model: selection?.model,
54
+ effort: selection?.reasoningEffort,
55
+ agentPreset: session === undefined ? undefined : projectionString(ctx, session, AGENT_PRESET_KEY),
56
+ preset,
57
+ contextTokens: numberOr(pressure?.pressureTokens),
58
+ contextWindow: numberOr(pressure?.contextWindow),
59
+ cacheRate: cacheRate(totals),
60
+ uncachedInputTokens: numberOr(totals?.uncachedInputTokens),
61
+ outputTokens: numberOr(totals?.outputTokens),
62
+ cwd: process.cwd(),
63
+ home: sources.home,
64
+ };
65
+ };
66
+ }
67
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/agent/status.ts"],"names":[],"mappings":"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"}
package/lib/cards.d.ts ADDED
@@ -0,0 +1,88 @@
1
+ import type { FileDiff, ToolCallView, ToolResultView } from '@deepseek-ai/dsh-tools';
2
+ /** What a tool's result presenter receives, plus the call arguments it was asked with. */
3
+ export interface ToolResultInput {
4
+ readonly argumentsJson: string;
5
+ readonly content: unknown;
6
+ readonly isError: boolean;
7
+ readonly meta: unknown;
8
+ }
9
+ /**
10
+ * How the surface asks a tool to present itself.
11
+ *
12
+ * The seam is a plain interface so the transcript fold stays pure: the host
13
+ * adapter is the only part that touches the tool registry.
14
+ */
15
+ export interface ToolPresenter {
16
+ call(name: string, argumentsJson: string): ToolCard | undefined;
17
+ result(name: string, input: ToolResultInput): ToolCard | undefined;
18
+ }
19
+ /** Which treatment a card gets; mirrors the tool's declared render intent. */
20
+ export type ToolCardKind = 'generic' | 'terminal' | 'diff' | 'search' | 'read' | 'web';
21
+ /** One renderable tool row: a header plus the detail rows kept for rendering. */
22
+ export interface ToolCard {
23
+ readonly kind: ToolCardKind;
24
+ readonly title: string;
25
+ /** Rows retained for rendering, already capped at CARD_DETAIL_MAX. */
26
+ readonly detail: readonly string[];
27
+ readonly failed: boolean;
28
+ /** Rows the tool actually presented, which retention may have cut short. */
29
+ readonly totalLines: number;
30
+ }
31
+ /** Detail rows a settled card shows before it is summarized. */
32
+ export declare const CARD_DETAIL_LIMIT = 10;
33
+ /**
34
+ * Detail rows retained on a card at all.
35
+ *
36
+ * A collapse key must be able to show more than the summary does, and a tool
37
+ * that prints a hundred thousand lines must not keep the whole transcript in
38
+ * memory for a reader who will never scroll that far.
39
+ */
40
+ export declare const CARD_DETAIL_MAX = 200;
41
+ /** Character budget for one detail row, so a minified file cannot flood the viewport. */
42
+ export declare const CARD_LINE_LIMIT = 200;
43
+ /**
44
+ * The rows a card shows right now, and how many the reader is not seeing.
45
+ *
46
+ * Expansion is a view decision rather than a card field so one key press can
47
+ * change every card at once without rebuilding the transcript.
48
+ */
49
+ export declare function cardDetailRows(card: ToolCard, expanded: boolean): {
50
+ lines: readonly string[];
51
+ hidden: number;
52
+ };
53
+ /**
54
+ * Build a card from raw lines.
55
+ *
56
+ * Every path that turns text into a card goes through here, so a tool with no
57
+ * presenter — or a result whose presenter declined — cannot keep a hundred
58
+ * thousand lines alive in the transcript.
59
+ */
60
+ export declare function cardFromLines(kind: ToolCardKind, title: string, lines: readonly string[], failed: boolean): ToolCard;
61
+ /** Text lines carried by model-facing content blocks. */
62
+ export declare function contentLines(content: unknown): string[];
63
+ /**
64
+ * Collapse one call and its result into the single row the reader sees.
65
+ *
66
+ * The pending row already told the reader what the tool is doing, so the
67
+ * settled row keeps that header and swaps in the outcome; a result that
68
+ * presents nothing keeps the call's detail rather than blanking the row.
69
+ */
70
+ export declare function mergeCards(call: ToolCard | undefined, result: ToolCard | undefined): ToolCard;
71
+ /**
72
+ * Render one file change as a bounded unified hunk.
73
+ *
74
+ * Only the changed middle is shown: a presenter has the prior and next text but
75
+ * no hunk list, so trimming the shared prefix and suffix yields the same region
76
+ * a full diff would highlight without paying for a line-diff computation on
77
+ * every frame.
78
+ */
79
+ export declare function renderFileDiff(diff: FileDiff): string[];
80
+ /** Map a tool's pending-call intent to a card, falling back to the raw call name. */
81
+ export declare function cardOfCall(view: ToolCallView | undefined, fallbackName: string): ToolCard;
82
+ /** Map a tool's result intent to a card, falling back to the model-facing text. */
83
+ export declare function cardOfResult(view: ToolResultView | undefined, input: {
84
+ readonly fallbackTitle: string;
85
+ readonly failed: boolean;
86
+ readonly contentLines: readonly string[];
87
+ }): ToolCard;
88
+ //# sourceMappingURL=cards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../src/cards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,QAAQ,EAOR,YAAY,EACZ,cAAc,EAEf,MAAM,wBAAwB,CAAA;AAE/B,0FAA0F;AAC1F,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAA;IAC/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,QAAQ,GAAG,SAAS,CAAA;CACnE;AAED,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAA;AAEtF,iFAAiF;AACjF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,gEAAgE;AAChE,eAAO,MAAM,iBAAiB,KAAK,CAAA;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,MAAM,CAAA;AAElC,yFAAyF;AACzF,eAAO,MAAM,eAAe,MAAM,CAAA;AAUlC;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAG9G;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,OAAO,GACd,QAAQ,CAGV;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAYvD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAW7F;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAsBvD;AAOD,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,QAAQ,CA2BzF;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAC1B,IAAI,EAAE,cAAc,GAAG,SAAS,EAChC,KAAK,EAAE;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC5G,QAAQ,CA6DV"}
package/lib/cards.js ADDED
@@ -0,0 +1,218 @@
1
+ /** Detail rows a settled card shows before it is summarized. */
2
+ export const CARD_DETAIL_LIMIT = 10;
3
+ /**
4
+ * Detail rows retained on a card at all.
5
+ *
6
+ * A collapse key must be able to show more than the summary does, and a tool
7
+ * that prints a hundred thousand lines must not keep the whole transcript in
8
+ * memory for a reader who will never scroll that far.
9
+ */
10
+ export const CARD_DETAIL_MAX = 200;
11
+ /** Character budget for one detail row, so a minified file cannot flood the viewport. */
12
+ export const CARD_LINE_LIMIT = 200;
13
+ function clipLine(text) {
14
+ return text.length <= CARD_LINE_LIMIT ? text : `${text.slice(0, CARD_LINE_LIMIT - 1)}…`;
15
+ }
16
+ function bound(lines) {
17
+ return { detail: lines.slice(0, CARD_DETAIL_MAX).map(clipLine), totalLines: lines.length };
18
+ }
19
+ /**
20
+ * The rows a card shows right now, and how many the reader is not seeing.
21
+ *
22
+ * Expansion is a view decision rather than a card field so one key press can
23
+ * change every card at once without rebuilding the transcript.
24
+ */
25
+ export function cardDetailRows(card, expanded) {
26
+ const lines = card.detail.slice(0, expanded ? CARD_DETAIL_MAX : CARD_DETAIL_LIMIT);
27
+ return { lines, hidden: Math.max(0, card.totalLines - lines.length) };
28
+ }
29
+ /**
30
+ * Build a card from raw lines.
31
+ *
32
+ * Every path that turns text into a card goes through here, so a tool with no
33
+ * presenter — or a result whose presenter declined — cannot keep a hundred
34
+ * thousand lines alive in the transcript.
35
+ */
36
+ export function cardFromLines(kind, title, lines, failed) {
37
+ const bounded = bound(lines);
38
+ return { kind, title, detail: bounded.detail, failed, totalLines: bounded.totalLines };
39
+ }
40
+ /** Text lines carried by model-facing content blocks. */
41
+ export function contentLines(content) {
42
+ if (!Array.isArray(content))
43
+ return [];
44
+ const lines = [];
45
+ for (const block of content) {
46
+ if (typeof block !== 'object' || block === null)
47
+ continue;
48
+ const record = block;
49
+ // Any block that carries text counts; a tool-result block also holds its
50
+ // model-facing content one level deeper.
51
+ if (typeof record.text === 'string')
52
+ lines.push(...record.text.split('\n'));
53
+ if (Array.isArray(record.content))
54
+ lines.push(...contentLines(record.content));
55
+ }
56
+ return lines;
57
+ }
58
+ /**
59
+ * Collapse one call and its result into the single row the reader sees.
60
+ *
61
+ * The pending row already told the reader what the tool is doing, so the
62
+ * settled row keeps that header and swaps in the outcome; a result that
63
+ * presents nothing keeps the call's detail rather than blanking the row.
64
+ */
65
+ export function mergeCards(call, result) {
66
+ const base = call ?? result;
67
+ if (base === undefined)
68
+ throw new Error('mergeCards requires at least one card');
69
+ if (call === undefined || result === undefined)
70
+ return base;
71
+ return {
72
+ kind: result.kind === 'generic' ? call.kind : result.kind,
73
+ title: call.title,
74
+ detail: result.detail.length > 0 ? result.detail : call.detail,
75
+ failed: result.failed,
76
+ totalLines: result.detail.length > 0 ? result.totalLines : call.totalLines,
77
+ };
78
+ }
79
+ /**
80
+ * Render one file change as a bounded unified hunk.
81
+ *
82
+ * Only the changed middle is shown: a presenter has the prior and next text but
83
+ * no hunk list, so trimming the shared prefix and suffix yields the same region
84
+ * a full diff would highlight without paying for a line-diff computation on
85
+ * every frame.
86
+ */
87
+ export function renderFileDiff(diff) {
88
+ const before = diff.oldText === null ? [] : diff.oldText.split('\n');
89
+ const after = diff.newText.split('\n');
90
+ let head = 0;
91
+ while (head < before.length && head < after.length && before[head] === after[head])
92
+ head += 1;
93
+ let tail = 0;
94
+ while (tail < before.length - head
95
+ && tail < after.length - head
96
+ && before[before.length - 1 - tail] === after[after.length - 1 - tail])
97
+ tail += 1;
98
+ const removed = before.slice(head, before.length - tail);
99
+ const added = after.slice(head, after.length - tail);
100
+ // "new" keys off the absent prior text, not off an empty hunk: an unchanged
101
+ // file has no removals either and must not read as a creation.
102
+ const header = diff.oldText === null ? 'new' : `-${removed.length} +${added.length}`;
103
+ const lines = [`${diff.path} ${header}`];
104
+ if (head > 0)
105
+ lines.push(`@@ ${head} unchanged line${head === 1 ? '' : 's'} before`);
106
+ for (const line of removed)
107
+ lines.push(`-${line}`);
108
+ for (const line of added)
109
+ lines.push(`+${line}`);
110
+ if (tail > 0)
111
+ lines.push(`@@ ${tail} unchanged line${tail === 1 ? '' : 's'} after`);
112
+ return lines;
113
+ }
114
+ function title(view, fallback) {
115
+ const declared = view.title?.trim() ?? '';
116
+ return declared === '' ? fallback : declared;
117
+ }
118
+ /** Map a tool's pending-call intent to a card, falling back to the raw call name. */
119
+ export function cardOfCall(view, fallbackName) {
120
+ if (view === undefined) {
121
+ return { kind: 'generic', title: fallbackName, detail: [], failed: false, totalLines: 0 };
122
+ }
123
+ switch (view.card) {
124
+ case 'terminal': {
125
+ const terminal = view;
126
+ const lines = terminal.description === undefined || terminal.description === '' ? [] : [terminal.description];
127
+ if (terminal.cwd !== undefined && terminal.cwd !== '')
128
+ lines.push(`cwd ${terminal.cwd}`);
129
+ return { kind: 'terminal', title: title(terminal, fallbackName), detail: bound(lines).detail, failed: false, totalLines: 0 };
130
+ }
131
+ case 'diff': {
132
+ const diff = view;
133
+ const lines = diff.diffs.flatMap(renderFileDiff);
134
+ const bounded = bound(lines);
135
+ return { kind: 'diff', title: title(diff, fallbackName), detail: bounded.detail, failed: false, totalLines: bounded.totalLines };
136
+ }
137
+ default: {
138
+ const generic = view;
139
+ const lines = contentLines(generic.content);
140
+ if (generic.rawInput !== undefined && lines.length === 0) {
141
+ lines.push(typeof generic.rawInput === 'string' ? generic.rawInput : JSON.stringify(generic.rawInput));
142
+ }
143
+ const bounded = bound(lines);
144
+ return { kind: 'generic', title: title(generic, fallbackName), detail: bounded.detail, failed: false, totalLines: bounded.totalLines };
145
+ }
146
+ }
147
+ }
148
+ /** Map a tool's result intent to a card, falling back to the model-facing text. */
149
+ export function cardOfResult(view, input) {
150
+ const failed = input.failed;
151
+ if (view === undefined) {
152
+ const bounded = bound(input.contentLines);
153
+ return { kind: 'generic', title: input.fallbackTitle, detail: bounded.detail, failed, totalLines: bounded.totalLines };
154
+ }
155
+ switch (view.card) {
156
+ case 'terminal': {
157
+ const terminal = view;
158
+ const lines = (terminal.output ?? '').split('\n');
159
+ const status = terminal.signal !== undefined && terminal.signal !== ''
160
+ ? `signal ${terminal.signal}`
161
+ : terminal.exitCode === undefined ? undefined : `exit ${terminal.exitCode}`;
162
+ if (status !== undefined)
163
+ lines.push(status);
164
+ const bounded = bound(lines);
165
+ return { kind: 'terminal', title: title(terminal, input.fallbackTitle), detail: bounded.detail, failed, totalLines: bounded.totalLines };
166
+ }
167
+ case 'diff': {
168
+ const diff = view;
169
+ const bounded = bound(diff.diffs.flatMap(renderFileDiff));
170
+ return { kind: 'diff', title: title(diff, input.fallbackTitle), detail: bounded.detail, failed, totalLines: bounded.totalLines };
171
+ }
172
+ case 'search': {
173
+ const search = view;
174
+ const lines = search.shape === 'paths'
175
+ ? [...search.paths]
176
+ : search.files.flatMap(file => file.matches.map(match => `${file.path}:${match.lineNumber}: ${match.line}`));
177
+ if (search.truncated)
178
+ lines.push(`… ${search.total} total`);
179
+ const bounded = bound(lines);
180
+ return { kind: 'search', title: title(search, input.fallbackTitle), detail: bounded.detail, failed, totalLines: bounded.totalLines };
181
+ }
182
+ case 'read': {
183
+ const read = view;
184
+ const lines = read.lines.length > 0
185
+ ? read.lines.map(line => `${line.number}: ${line.text}`)
186
+ : contentLines(read.content);
187
+ lines.unshift(`${read.path} (from line ${read.offset}, ${read.totalLines} total)`);
188
+ const bounded = bound(lines);
189
+ return { kind: 'read', title: title(read, input.fallbackTitle), detail: bounded.detail, failed, totalLines: bounded.totalLines };
190
+ }
191
+ case 'web': {
192
+ const web = view;
193
+ const lines = [];
194
+ if (web.kind === 'search') {
195
+ if (web.answer !== undefined && web.answer !== '')
196
+ lines.push(...web.answer.split('\n'));
197
+ for (const source of web.sources)
198
+ lines.push(source.title === undefined ? source.url : `${source.title} — ${source.url}`);
199
+ if (web.truncated)
200
+ lines.push('… more sources');
201
+ }
202
+ else {
203
+ lines.push(`${web.url} → ${web.statusCode}`);
204
+ if (web.truncated)
205
+ lines.push('… body truncated');
206
+ }
207
+ const bounded = bound(lines);
208
+ return { kind: 'web', title: title(web, input.fallbackTitle), detail: bounded.detail, failed, totalLines: bounded.totalLines };
209
+ }
210
+ default: {
211
+ const generic = view;
212
+ const lines = contentLines(generic.content);
213
+ const bounded = bound(lines.length > 0 ? lines : input.contentLines);
214
+ return { kind: 'generic', title: title(generic, input.fallbackTitle), detail: bounded.detail, failed, totalLines: bounded.totalLines };
215
+ }
216
+ }
217
+ }
218
+ //# sourceMappingURL=cards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cards.js","sourceRoot":"","sources":["../src/cards.ts"],"names":[],"mappings":"AAgDA,gEAAgE;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAEnC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;AAElC,yFAAyF;AACzF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;AAElC,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,GAAG,CAAC,CAAC,GAAG,CAAA;AACzF,CAAC;AAED,SAAS,KAAK,CAAC,KAAwB;IACrC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;AAC5F,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc,EAAE,QAAiB;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAA;IAClF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;AACvE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAkB,EAClB,KAAa,EACb,KAAwB,EACxB,MAAe;IAEf,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;IAC5B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;AACxF,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAA;IACtC,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,SAAQ;QACzD,MAAM,MAAM,GAAG,KAAgC,CAAA;QAC/C,yEAAyE;QACzE,yCAAyC;QACzC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;IAChF,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAA0B,EAAE,MAA4B;IACjF,MAAM,IAAI,GAAG,IAAI,IAAI,MAAM,CAAA;IAC3B,IAAI,IAAI,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IAChF,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAC3D,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI;QACzD,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;QAC9D,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU;KAC3E,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACpE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACtC,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,OAAO,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC;QAAE,IAAI,IAAI,CAAC,CAAA;IAC7F,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,OACE,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI;WACxB,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI;WAC1B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC;QACtE,IAAI,IAAI,CAAC,CAAA;IACX,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACxD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACpD,4EAA4E;IAC5E,+DAA+D;IAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAA;IACpF,MAAM,KAAK,GAAa,CAAC,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,CAAA;IACnD,IAAI,IAAI,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,kBAAkB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IACpF,KAAK,MAAM,IAAI,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;IAClD,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;IAChD,IAAI,IAAI,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,kBAAkB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAA;IACnF,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,KAAK,CAAC,IAAwB,EAAE,QAAgB;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IACzC,OAAO,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC9C,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,UAAU,CAAC,IAA8B,EAAE,YAAoB;IAC7E,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAA;IAC3F,CAAC;IACD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,QAAQ,GAAG,IAAwB,CAAA;YACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,KAAK,SAAS,IAAI,QAAQ,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;YAC7G,IAAI,QAAQ,CAAC,GAAG,KAAK,SAAS,IAAI,QAAQ,CAAC,GAAG,KAAK,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAA;YACxF,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAA;QAC9H,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,IAAI,GAAG,IAAoB,CAAA;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;YAChD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QAClI,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,OAAO,GAAG,IAAuB,CAAA;YACvC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;YAC3C,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzD,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;YACxG,CAAC;YACD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YAC5B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QACxI,CAAC;IACH,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,YAAY,CAC1B,IAAgC,EAChC,KAA6G;IAE7G,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;IAC3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QACzC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;IACxH,CAAC;IACD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,QAAQ,GAAG,IAA0B,CAAA;YAC3C,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,EAAE;gBACpE,CAAC,CAAC,UAAU,QAAQ,CAAC,MAAM,EAAE;gBAC7B,CAAC,CAAC,QAAQ,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,QAAQ,CAAC,QAAQ,EAAE,CAAA;YAC7E,IAAI,MAAM,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YAC5B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QAC1I,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,IAAI,GAAG,IAAsB,CAAA;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAA;YACzD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QAClI,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,MAAM,GAAG,IAAwB,CAAA;YACvC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,OAAO;gBACpC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;gBACnB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;YAC9G,IAAI,MAAM,CAAC,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAA;YAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YAC5B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QACtI,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,IAAI,GAAG,IAAsB,CAAA;YACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBACjC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBACxD,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC9B,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,eAAe,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,UAAU,SAAS,CAAC,CAAA;YAClF,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QAClI,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,GAAG,GAAG,IAAqB,CAAA;YACjC,MAAM,KAAK,GAAa,EAAE,CAAA;YAC1B,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1B,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE;oBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;gBACxF,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO;oBAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;gBACzH,IAAI,GAAG,CAAC,SAAS;oBAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;YACjD,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,CAAA;gBAC5C,IAAI,GAAG,CAAC,SAAS;oBAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;YACnD,CAAC;YACD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YAC5B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QAChI,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,OAAO,GAAG,IAAyB,CAAA;YACzC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;YAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;YACpE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QACxI,CAAC;IACH,CAAC;AACH,CAAC"}