@antst/dashi 0.1.0-alpha.7 → 0.1.0-alpha.8

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.
@@ -1,4 +1,5 @@
1
1
  import { createRenderer } from './renderer.js';
2
+ import { runEditor } from './external-editor.js';
2
3
  import { initialViewState, reduce, } from './state.js';
3
4
  import { createTerminalGuard } from './terminal-guard.js';
4
5
  function suspendProcess() {
@@ -44,7 +45,14 @@ export function createTerminalShell(options) {
44
45
  async function run(effect) {
45
46
  switch (effect.type) {
46
47
  case 'activate-overlay':
47
- await options.activateOverlay?.(effect.value);
48
+ if (effect.value.kind === 'open-file') {
49
+ const path = effect.value.path;
50
+ await guard.withCookedTerminal(() => runEditor(process.env.EDITOR?.trim() || 'vi', path, options.cwd)).catch(error => {
51
+ dispatch({ type: 'runtime-error', message: error instanceof Error ? error.message : String(error) });
52
+ });
53
+ }
54
+ else
55
+ await options.activateOverlay?.(effect.value);
48
56
  return;
49
57
  case 'attach': {
50
58
  try {
@@ -0,0 +1,5 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { Agent } from '@deepseek-ai/dsh-agent';
3
+ import type { Overlay } from './state.js';
4
+ import { type ToolPresenter } from './tool-presentation.js';
5
+ export declare function diffOverlay(ctx: Context, agent: Agent, presenter: ToolPresenter, mode: '' | 'turn', signal: AbortSignal): Promise<Overlay>;
@@ -0,0 +1,23 @@
1
+ import { boundedBody } from './tool-presentation.js';
2
+ import { foldCells } from './transcript.js';
3
+ export async function diffOverlay(ctx, agent, presenter, mode, signal) {
4
+ if (mode === 'turn') {
5
+ const events = agent.session.snapshotEvents();
6
+ const start = events.map(event => event.type).lastIndexOf('turn/start');
7
+ const cells = (start < 0 ? [] : foldCells(events.slice(start), presenter)).filter(cell => cell.pending !== true && cell.tool?.card === 'diff' && (cell.tool.diffs?.length ?? 0) > 0);
8
+ return { cells, kind: 'info', lines: cells.length === 0 ? ['No write/edit changes in the last turn.'] : [], title: 'Last turn diff' };
9
+ }
10
+ const command = 'git diff --no-ext-diff --no-color HEAD --';
11
+ const result = await ctx.shell.run(ctx.shell.resolve({
12
+ command, sandboxPolicy: ctx.sandboxPolicy.resolve({ session: agent.session }), signal,
13
+ stdoutMaxBytes: 64 * 1024, timeoutMs: 30_000, workdir: agent.session.header.cwd,
14
+ }));
15
+ const output = [result.stdout.text, result.stderr.text].filter(Boolean).join('\n');
16
+ const cell = {
17
+ key: 'diff:working', kind: result.exitCode === 0 ? 'tool' : 'error', text: 'git diff',
18
+ tool: { card: 'terminal', title: 'git diff', status: result.exitCode === 0 ? output === '' ? 'clean' : 'changed'
19
+ : result.exitCode === null ? result.signal ?? 'failed' : `exit ${String(result.exitCode)}`,
20
+ ...(output === '' ? {} : { body: boundedBody(output) }) },
21
+ };
22
+ return { cells: [cell], kind: 'info', lines: [], title: 'Working tree diff' };
23
+ }
@@ -1,2 +1,3 @@
1
+ export declare function runEditor(command: string, file: string, cwd: string): Promise<void>;
1
2
  /** Edit one draft through the user's terminal editor and always remove its file. */
2
3
  export declare function editDraftExternally(text: string, cwd: string): Promise<string>;
@@ -2,7 +2,7 @@ import { spawn } from 'node:child_process';
2
2
  import { mkdtemp, readFile, rm, rmdir, writeFile } from 'node:fs/promises';
3
3
  import { tmpdir } from 'node:os';
4
4
  import { join } from 'node:path';
5
- function runEditor(command, file, cwd) {
5
+ export function runEditor(command, file, cwd) {
6
6
  return new Promise((resolve, reject) => {
7
7
  const child = spawn('/bin/sh', ['-c', `exec ${command} "$1"`, 'dashi-editor', file], {
8
8
  cwd, stdio: 'inherit',
package/lib/help.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const VERSION_LINE: string;
2
+ export declare const FLAG_HELP: readonly ["Launch flags: --inline | --fullscreen · --accessible · -r, --resume [NAME|UUID] · -c, --continue · --all · --name TITLE", " --model ID [--provider ID] · --effort LEVEL · --permission PRESET", " --yolo | --dangerously-skip-permissions · --image PATH · -h, --help"];
package/lib/help.js ADDED
@@ -0,0 +1,6 @@
1
+ import dashi from '../package.json' with { type: 'json' };
2
+ import dsh from '@deepseek-ai/dsh-cmdline/package.json' with { type: 'json' };
3
+ export const VERSION_LINE = `dashi ${dashi.version} on DSH ${dsh.version}`;
4
+ export const FLAG_HELP = [
5
+ 'Launch flags: --inline | --fullscreen · --accessible · -r, --resume [NAME|UUID] · -c, --continue · --all · --name TITLE', ' --model ID [--provider ID] · --effort LEVEL · --permission PRESET', ' --yolo | --dangerously-skip-permissions · --image PATH · -h, --help'
6
+ ];
package/lib/index.js CHANGED
@@ -6,13 +6,14 @@ import { createTerminalShell } from './application.js';
6
6
  import { sessionOverlay } from './catalogs.js';
7
7
  import { readClipboardImage } from './clipboard-image.js';
8
8
  import { editDraftExternally } from './external-editor.js';
9
+ import { FLAG_HELP, VERSION_LINE } from './help.js';
9
10
  import { formatSessionList, isSessionId, parseSessionListArgs, sessionMatches, sessionNotFound, } from './session-list.js';
10
11
  import { createSessionRuntime } from './session-runtime.js';
11
12
  import { TuiRoot } from './tui-root.js';
12
13
  export const name = 'dashi';
13
14
  export const inject = [
14
- 'agentPresets', 'agents', 'attachments', 'cmdlineArgs', 'commands', 'fs', 'permissionPresets', 'sessionController',
15
- 'sandboxPolicy', 'sessionProjections', 'sessionQuery', 'sessions', 'shell', 'skills', 'tools',
15
+ 'agentPresets', 'agents', 'attachments', 'cmdlineArgs', 'commands', 'fs', 'loader', 'permissionPresets',
16
+ 'pluginInventory', 'sessionController', 'sandboxPolicy', 'sessionProjections', 'sessionQuery', 'sessions', 'settings', 'shell', 'skills', 'tools',
16
17
  ];
17
18
  const validatedVersions = JSON.parse(readFileSync(new URL('../validated-dsh-versions.json', import.meta.url), 'utf8'));
18
19
  function parseArgs(args) {
@@ -154,6 +155,11 @@ export function apply(ctx) {
154
155
  throw new Error('dashi: the launcher must provide ctx.appExit, ctx.appReady, and ctx.cmdlineArgs');
155
156
  }
156
157
  const args = cmdline.get();
158
+ if (args.length === 1 && (args[0] === '--help' || args[0] === '-h')) {
159
+ process.stdout.write(`${VERSION_LINE}\n\nUsage: dashi [options] [prompt]\n\n${FLAG_HELP.join('\n')}\n`);
160
+ exit(0);
161
+ return;
162
+ }
157
163
  if (args[0] === 'sessions') {
158
164
  const options = parseSessionListArgs(args);
159
165
  if (options === undefined) {
package/lib/input.js CHANGED
@@ -102,6 +102,8 @@ export function installInput(tui, bindings) {
102
102
  bindings.dispatch({ type: 'overlay-move', offset: -1 });
103
103
  else if (matchesKey(data, 'down'))
104
104
  bindings.dispatch({ type: 'overlay-move', offset: 1 });
105
+ else if (matchesKey(data, 'ctrl+o'))
106
+ bindings.dispatch({ type: 'toggle-tool-mode' });
105
107
  else if (matchesKey(data, 'enter'))
106
108
  bindings.dispatch({ type: 'overlay-submit', execute: true });
107
109
  else if (matchesKey(data, 'tab'))
@@ -0,0 +1,3 @@
1
+ import type { Agent } from '@deepseek-ai/dsh-agent';
2
+ import type { Overlay } from './state.js';
3
+ export declare function memoryOverlay(agent: Agent): Overlay;
package/lib/memory.js ADDED
@@ -0,0 +1,27 @@
1
+ import { resolve } from 'node:path';
2
+ import { resolveDshHome } from '@deepseek-ai/dsh-home-paths';
3
+ export function memoryOverlay(agent) {
4
+ const cwd = agent.session.header.cwd ?? process.cwd();
5
+ let root = cwd;
6
+ const active = new Map();
7
+ for (const seq of agent.session.surface.nodes) {
8
+ const event = agent.session.eventAt(seq);
9
+ if (event?.type !== 'user/message' || event.data.source.kind !== 'agent-instructions')
10
+ continue;
11
+ const source = event.data.source, identity = source.baselineIdentity === undefined
12
+ ? undefined : JSON.parse(source.baselineIdentity);
13
+ if (typeof identity?.projectRoot === 'string')
14
+ root = resolve(cwd, identity.projectRoot);
15
+ for (const change of source.changes) {
16
+ if (change.action === 'remove')
17
+ active.delete(change.scope);
18
+ else
19
+ active.set(change.scope, { path: change.path, scope: change.scope.split('\0')[0] ?? change.scope });
20
+ }
21
+ }
22
+ return { cursor: 0, kind: 'list', options: [...active.values()].map(item => {
23
+ const homePath = /^(?:~\/\.dsh|\$DSH_HOME)\/(.*)$/u.exec(item.path)?.[1];
24
+ return { detail: `scope ${item.scope}`, label: item.path,
25
+ value: { kind: 'open-file', path: resolve(homePath === undefined ? root : resolveDshHome(), homePath ?? item.path) } };
26
+ }), purpose: 'memory', title: 'Memory' };
27
+ }
package/lib/renderer.js CHANGED
@@ -268,9 +268,11 @@ export function createRenderer(options) {
268
268
  if (overlay.kind === 'details')
269
269
  return detailsPanel(overlay, state, width, rows);
270
270
  if (overlay.kind === 'info') {
271
+ const cards = overlay.cells?.flatMap(cell => wrapTextWithAnsi(cellText(cell, state.toolMode, accessible), width)) ?? [];
271
272
  return [
272
- `${BOLD_CYAN}${announcement(plain(overlay.title), overlay.lines.length)}${RESET}`,
273
+ `${BOLD_CYAN}${announcement(plain(overlay.title), overlay.lines.length + (overlay.cells?.length ?? 0))}${RESET}`,
273
274
  ...overlay.lines.flatMap(value => wrapTextWithAnsi(plain(value, true), width)),
275
+ ...cards,
274
276
  `${DIM}Enter or Esc to close${RESET}`,
275
277
  ].slice(0, Math.max(2, rows - 3));
276
278
  }
@@ -1,14 +1,16 @@
1
1
  import { createUserMessage } from '@deepseek-ai/dsh-llm';
2
2
  import { SessionId, SessionSeq } from '@deepseek-ai/dsh-session';
3
3
  import { agentPresetOverlay, completionOptions, contextOverlay, currentModel, modelOverlay, permissionOverlay, searchOverlay, sessionOverlay, statusOverlay, } from './catalogs.js';
4
+ import { diffOverlay } from './diff-view.js';
4
5
  import { eventsFromRecords } from './history-records.js';
5
6
  import { admitDraftImages, encodeDraftImages, readDraftImages } from './image-input.js';
6
7
  import { contextPercent, jobViews, subagentViews } from './presentation.js';
7
8
  import { humanPrompt, humanPrompts, inheritedTurn, rewindActionOverlay, rewindOverlay, } from './rewind.js';
8
9
  import { createToolPresenter } from './tool-presentation.js';
9
- import { runHumanShell } from './shell-command.js';
10
+ import { quoteShellWord, runHumanShell } from './shell-command.js';
10
11
  import { markdownTranscript } from './session-export.js';
11
12
  import { isSessionId, sessionMatches, sessionNotFound } from './session-list.js';
13
+ import { memoryOverlay } from './memory.js';
12
14
  import { foldCells, pendingShellCells } from './transcript.js';
13
15
  function detail(error) {
14
16
  return error instanceof Error ? error.message : String(error);
@@ -71,6 +73,17 @@ async function firstControl(iterator) {
71
73
  function usage(raw, expected) {
72
74
  return raw.trim() === '' ? undefined : { kind: 'error', text: `usage: ${expected}` };
73
75
  }
76
+ function configValue(raw) {
77
+ try {
78
+ return JSON.parse(raw);
79
+ }
80
+ catch {
81
+ return raw;
82
+ }
83
+ }
84
+ function configLayer(value) {
85
+ return value === undefined ? '—' : JSON.stringify(value);
86
+ }
74
87
  /** Create or resume the exact current root and own its replaceable terminal binding. */
75
88
  export async function createSessionRuntime(ctx, options, tuiRoot, dispatch, decisions) {
76
89
  const lifetime = new AbortController();
@@ -491,6 +504,82 @@ export async function createSessionRuntime(ctx, options, tuiRoot, dispatch, deci
491
504
  return { kind: 'success' };
492
505
  },
493
506
  },
507
+ {
508
+ name: 'memory', description: 'Open an instruction file loaded by DSH',
509
+ handler: (invocation) => {
510
+ const invalid = ensureCurrent(invocation) ?? usage(invocation.rawInput, '/memory');
511
+ if (invalid !== undefined)
512
+ return invalid;
513
+ dispatch({ type: 'open-overlay', overlay: memoryOverlay(bound.agent) });
514
+ return { kind: 'success' };
515
+ },
516
+ },
517
+ {
518
+ name: 'config', description: 'Show or update native DSH settings', input: { hint: '[NAMESPACE KEY=VALUE]' },
519
+ handler: async (invocation) => {
520
+ const stale = ensureCurrent(invocation);
521
+ if (stale !== undefined)
522
+ return stale;
523
+ const raw = invocation.rawInput.trim();
524
+ if (raw === '')
525
+ return { kind: 'success', text: ctx.settings.describe({ redactSecrets: true }).map(item => `${String(item.ns)}\n value: ${configLayer(item.value)}\n base: ${configLayer(item.base)}\n user: ${configLayer(item.user)}`).join('\n') };
526
+ const match = /^(\S+)\s+([^\s=]+)=(.*)$/su.exec(raw);
527
+ if (match?.[1] === undefined || match[2] === undefined || match[3] === undefined) {
528
+ return { kind: 'error', text: 'usage: /config [NAMESPACE KEY=VALUE]' };
529
+ }
530
+ const value = configValue(match[3]);
531
+ if (match[2].includes('.'))
532
+ await ctx.settings.mutate(match[1], [{ op: 'set', path: match[2].split('.'), value }]);
533
+ else
534
+ await ctx.settings.update(match[1], { [match[2]]: value });
535
+ return { kind: 'success', text: `updated ${match[1]}.${match[2]}` };
536
+ },
537
+ },
538
+ {
539
+ name: 'diff', description: 'Show working tree or last-turn file changes', input: { hint: '[turn]' }, handler: async (invocation) => {
540
+ const invalid = ensureCurrent(invocation);
541
+ if (invalid !== undefined)
542
+ return invalid;
543
+ const mode = invocation.rawInput.trim();
544
+ if (mode !== '' && mode !== 'turn')
545
+ return { kind: 'error', text: 'usage: /diff [turn]' };
546
+ dispatch({ type: 'open-overlay', overlay: await diffOverlay(ctx, bound.agent, bound.presenter, mode, lifetime.signal) });
547
+ return { kind: 'success' };
548
+ },
549
+ },
550
+ {
551
+ name: 'plugins', description: 'List the running profile plugins',
552
+ handler: async (invocation) => {
553
+ const stale = ensureCurrent(invocation);
554
+ if (stale !== undefined)
555
+ return stale;
556
+ if (invocation.rawInput.trim() !== '')
557
+ return { kind: 'error', text: 'usage: /plugins' };
558
+ const servers = new Map();
559
+ for (const entry of ctx.loader.entries())
560
+ if (entry.options.name === '@deepseek-ai/dsh-mcp-client'
561
+ && typeof entry.options.config?.serverName === 'string')
562
+ servers.set(entry.id, entry.options.config.serverName);
563
+ const snapshot = await ctx.get('pluginInventory').list();
564
+ return { kind: 'success', text: snapshot.entries.map(entry => `${String(entry.entryId)} · ${entry.moduleName}${servers.has(String(entry.entryId)) ? ` · ${servers.get(String(entry.entryId))}` : ''} · ${entry.enabled ? 'enabled' : 'disabled'} · ${entry.fiberPhase ?? 'inactive'}`).join('\n') };
565
+ },
566
+ },
567
+ {
568
+ name: 'plugin', description: 'Run DSH profile plugin management', input: { hint: 'ARGS' },
569
+ handler: async (invocation) => {
570
+ const stale = ensureCurrent(invocation);
571
+ if (stale !== undefined)
572
+ return stale;
573
+ if (invocation.rawInput.trim() === '')
574
+ return { kind: 'error', text: 'usage: /plugin ARGS' };
575
+ const command = `dsh plugin --profile ${quoteShellWord(decodeURIComponent(new URL(ctx.baseUrl).pathname).split('/').at(-2))}${invocation.rawInput}`;
576
+ const [message, result] = await bound.agent.runMaintenance(signal => runHumanShell(ctx, bound.agent, command, signal, 'changes load on the next launch; exit and run dashi again'));
577
+ bound.agent.inject(message);
578
+ await ctx.sessions.flush(bound.agent.session);
579
+ publish(bound);
580
+ return result.exitCode === 0 ? { kind: 'success' } : { kind: 'error', text: `dsh plugin exited ${String(result.exitCode ?? result.signal ?? 'without status')}` };
581
+ },
582
+ },
494
583
  {
495
584
  name: 'new', description: 'Start a new session', input: { hint: '[--name TITLE]' },
496
585
  handler: async (invocation) => {
@@ -1027,7 +1116,8 @@ export async function createSessionRuntime(ctx, options, tuiRoot, dispatch, deci
1027
1116
  if (attachments.length > 0)
1028
1117
  throw new Error('!command does not accept image attachments');
1029
1118
  await bound.agent.runMaintenance(async (signal) => {
1030
- bound.agent.inject(await runHumanShell(ctx, bound.agent, command, signal));
1119
+ const [message] = await runHumanShell(ctx, bound.agent, command, signal);
1120
+ bound.agent.inject(message);
1031
1121
  await ctx.sessions.flush(bound.agent.session);
1032
1122
  });
1033
1123
  publish(bound);
@@ -5,5 +5,6 @@ import type { ShellRunResult } from '@deepseek-ai/dsh-shell';
5
5
  export declare const HUMAN_SHELL_TIMEOUT_MS = 30000;
6
6
  export declare const HUMAN_SHELL_STREAM_BYTES: number;
7
7
  export declare function shellResultText(command: string, result: ShellRunResult): string;
8
+ export declare function quoteShellWord(value: string): string;
8
9
  /** Run an explicit human command through DSH and identify its next-step context. */
9
- export declare function runHumanShell(ctx: Context, agent: Agent, command: string, signal: AbortSignal): Promise<UserMessage>;
10
+ export declare function runHumanShell(ctx: Context, agent: Agent, command: string, signal: AbortSignal, success?: string): Promise<readonly [UserMessage, ShellRunResult]>;
@@ -1,4 +1,5 @@
1
1
  import { boundContextSummary, createUserMessage } from '@deepseek-ai/dsh-llm';
2
+ import { resolveDshHome } from '@deepseek-ai/dsh-home-paths';
2
3
  export const HUMAN_SHELL_TIMEOUT_MS = 30_000;
3
4
  export const HUMAN_SHELL_STREAM_BYTES = 32 * 1024;
4
5
  function tail(output) {
@@ -42,21 +43,23 @@ export function shellResultText(command, result) {
42
43
  }
43
44
  return parts.join('\n');
44
45
  }
46
+ export function quoteShellWord(value) { return `'${value.replaceAll("'", "'\\''")}'`; }
45
47
  /** Run an explicit human command through DSH and identify its next-step context. */
46
- export async function runHumanShell(ctx, agent, command, signal) {
48
+ export async function runHumanShell(ctx, agent, command, signal, success) {
47
49
  const result = await ctx.shell.run(ctx.shell.resolve({
48
50
  command,
51
+ env: { DSH_HOME: resolveDshHome() },
49
52
  sandboxPolicy: ctx.sandboxPolicy.resolve({ session: agent.session }),
50
53
  signal,
51
54
  stdoutMaxBytes: HUMAN_SHELL_STREAM_BYTES,
52
55
  timeoutMs: HUMAN_SHELL_TIMEOUT_MS,
53
56
  workdir: agent.session.header.cwd,
54
57
  }));
55
- return createUserMessage({
56
- content: [{ type: 'text', text: shellResultText(command, result) }],
57
- source: {
58
- form: 'notice', kind: 'plugin', plugin: 'dashi',
59
- summary: boundContextSummary(`Shell: ${command.replace(/\s+/gu, ' ').trim()}`),
60
- },
61
- });
58
+ return [createUserMessage({
59
+ content: [{ type: 'text', text: shellResultText(command, result) + (result.exitCode === 0 && success ? `\n${success}` : '') }],
60
+ source: {
61
+ form: 'notice', kind: 'plugin', plugin: 'dashi',
62
+ summary: boundContextSummary(`Shell: ${command.replace(/\s+/gu, ' ').trim()}`),
63
+ },
64
+ }), result];
62
65
  }
package/lib/state.d.ts CHANGED
@@ -137,6 +137,9 @@ export type OverlayValue = {
137
137
  readonly effort?: string;
138
138
  readonly model: string;
139
139
  readonly provider: string;
140
+ } | {
141
+ readonly kind: 'open-file';
142
+ readonly path: string;
140
143
  } | {
141
144
  readonly interrupt?: true;
142
145
  readonly kind: 'fork';
@@ -197,9 +200,10 @@ export type Overlay = {
197
200
  readonly kind: 'list';
198
201
  readonly notice?: string;
199
202
  readonly options: readonly OverlayOption[];
200
- readonly purpose: 'agents' | 'completion' | 'model' | 'permission' | 'resume' | 'rewind' | 'rewind-action' | 'search';
203
+ readonly purpose: 'agents' | 'completion' | 'memory' | 'model' | 'permission' | 'resume' | 'rewind' | 'rewind-action' | 'search';
201
204
  readonly title: string;
202
205
  } | {
206
+ readonly cells?: readonly TerminalCell[];
203
207
  readonly kind: 'info';
204
208
  readonly lines: readonly string[];
205
209
  readonly title: string;
package/lib/state.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { FLAG_HELP, VERSION_LINE } from './help.js';
1
2
  export function initialViewState(cwd, inline, root, cells = [], prompts = [], historyHasMore = false, attachments = []) {
2
3
  return {
3
4
  attachments, cells, composer: '', cwd, decisions: [], exitArmed: false, historyHasMore, inline,
@@ -31,6 +32,7 @@ function help() {
31
32
  kind: 'info',
32
33
  title: 'Help',
33
34
  lines: [
35
+ VERSION_LINE,
34
36
  'Enter send · Ctrl+J newline · Ctrl+T steer/next turn',
35
37
  'Esc interrupt · Ctrl+C clear/interrupt · Ctrl+C/D again within 2s to exit',
36
38
  '/ and @ complete live · Tab insert · Shift+Tab permission · Ctrl+O cards',
@@ -39,8 +41,9 @@ function help() {
39
41
  'Ctrl+B activity details for jobs and subagents',
40
42
  '@ paths require DSH file-reference · Ctrl+V pastes an image · Backspace removes it',
41
43
  'Ctrl+S stash · Ctrl+G editor · F1 help · Ctrl+L redraw · Ctrl+Z suspend',
42
- '/new /clear /resume [--all] [NAME|UUID] /fork /rewind /rename /model /permission /agents /queue · launch -r/-c --model/--effort/--permission/--yolo',
43
- '/status /context /tasks /history /export /copy /exit',
44
+ '/new /clear /resume [--all] [NAME|UUID] /fork /rewind /rename /model /permission /agents /queue',
45
+ '/status /context /memory /config /diff /plugins /plugin /tasks /history /export /copy /exit',
46
+ ...FLAG_HELP,
44
47
  ],
45
48
  };
46
49
  }
package/lib/transcript.js CHANGED
@@ -29,7 +29,8 @@ function shellCell(message, pending) {
29
29
  function collapsedContextCell(message, key) {
30
30
  const source = message.source;
31
31
  const form = source.form;
32
- if (source.kind !== 'plugin' || !['instructions', 'catalog', 'snapshot', 'notice', 'recall'].includes(String(form))) {
32
+ if (source.kind !== 'agent-instructions'
33
+ && (source.kind !== 'plugin' || !['instructions', 'catalog', 'snapshot', 'notice', 'recall'].includes(String(form)))) {
33
34
  return undefined;
34
35
  }
35
36
  const text = messageText(message.content);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antst/dashi",
3
- "version": "0.1.0-alpha.7",
3
+ "version": "0.1.0-alpha.8",
4
4
  "description": "A terminal UI for DeepSeek Harness",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -37,7 +37,9 @@
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@deepseek-ai/cordis": "4.0.2",
40
+ "@deepseek-ai/cordis-plugin-loader": "1.0.3",
40
41
  "@deepseek-ai/dsh-agent": "0.1.2-rc.1",
42
+ "@deepseek-ai/dsh-agent-instructions": "0.1.2-rc.1",
41
43
  "@deepseek-ai/dsh-agent-presets": "0.1.2-rc.1",
42
44
  "@deepseek-ai/dsh-api-session-controller": "0.1.2-rc.1",
43
45
  "@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
@@ -46,6 +48,8 @@
46
48
  "@deepseek-ai/dsh-compaction": "0.1.2-rc.1",
47
49
  "@deepseek-ai/dsh-file-reference": "0.1.2-rc.1",
48
50
  "@deepseek-ai/dsh-fs": "0.1.2-rc.1",
51
+ "@deepseek-ai/dsh-home-paths": "0.1.2-rc.1",
52
+ "@deepseek-ai/dsh-host-plugin-inventory": "0.1.2-rc.1",
49
53
  "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
50
54
  "@deepseek-ai/dsh-permission-presets": "0.1.2-rc.1",
51
55
  "@deepseek-ai/dsh-plan-mode": "0.1.2-rc.1",
@@ -53,6 +57,7 @@
53
57
  "@deepseek-ai/dsh-session": "0.1.2-rc.1",
54
58
  "@deepseek-ai/dsh-session-projection": "0.1.2-rc.1",
55
59
  "@deepseek-ai/dsh-session-query": "0.1.2-rc.1",
60
+ "@deepseek-ai/dsh-settings": "0.1.2-rc.1",
56
61
  "@deepseek-ai/dsh-shell": "0.1.2-rc.1",
57
62
  "@deepseek-ai/dsh-skill": "0.1.2-rc.1",
58
63
  "@deepseek-ai/dsh-subagent": "0.1.2-rc.1",