@agi-fans/oh-my-dsh 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -5
- package/config/cordis.yml +3 -0
- package/lib/args.d.ts +35 -0
- package/lib/args.js +26 -1
- package/lib/bin.js +5 -1
- package/lib/completions.d.ts +3 -0
- package/lib/completions.js +52 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -29,11 +29,11 @@ Run `/login` once inside omdsh to validate and save your DeepSeek API key, then
|
|
|
29
29
|
|
|
30
30
|
## Highlights
|
|
31
31
|
|
|
32
|
-
- **Durable conversations:**
|
|
32
|
+
- **Durable conversations:** search, pin, rename, and resume sessions in `/sessions`; rewind, retry, compact, and export complete transcripts as Markdown or standalone HTML.
|
|
33
33
|
- **Four real session controls:** choose a Harness Agent preset (Standard, PTC, Minimal, or Cordis), Workflow (Default or Plan), tool presentation (Native, Code, or Both), and Access (Read only, Workspace write, or Full access).
|
|
34
34
|
- **Rich terminal input:** mention project files and other sessions with `@`, paste clipboard images, reuse persistent prompt history, edit multiline prompts externally, and retrieve queued follow-ups.
|
|
35
35
|
- **Readable tool activity:** follow streaming calls and live subagent progress, press Down on an empty composer then Enter (or use Alt+A directly) to select a child in the keyboard-driven Agent Hub, steer a continuable child from its transcript, inspect distinct Input and Output sections, expand long results, and keep domain-specific presentation owned by tool plugins.
|
|
36
|
-
- **Live operational context:** see Agent, Workflow, Tools, Access, model, reasoning effort, workspace, Git state, context pressure, tokens, TTFT, throughput, cache, timings, turns, and steps without leaving the composer.
|
|
36
|
+
- **Live operational context:** see Agent, Workflow, Tools, Access, model, reasoning effort, workspace, Git state, context pressure, tokens, TTFT, throughput, cache, timings, turns, and steps without leaving the composer; use `/context` for an inline projection-backed breakdown that remains in the transcript.
|
|
37
37
|
- **Responsive by design:** retain settled transcript layout, coalesce scroll updates, emit row-level terminal diffs, and preserve correct display-cell alignment for CJK text and emoji.
|
|
38
38
|
|
|
39
39
|
## Learn
|
|
@@ -48,7 +48,7 @@ Run `/login` once inside omdsh to validate and save your DeepSeek API key, then
|
|
|
48
48
|
|
|
49
49
|
DeepSeek Harness provides a capable agent runtime and a strong architectural idea: everything is a plugin. oh-my-dsh brings that runtime into a calm, keyboard-driven terminal experience without creating a second agent core or hiding Harness behind a parallel abstraction.
|
|
50
50
|
|
|
51
|
-
The TUI remains a presentation and interaction layer. Sessions, tools, permissions, models, Skills, MCP servers, commands, and telemetry come from Harness services and plugins; omdsh composes them into a terminal application and adds the interface behavior needed to use them comfortably.
|
|
51
|
+
The TUI remains a presentation and interaction layer. Sessions, tools, permissions, models, Skills, MCP servers, commands, and telemetry come from Harness services and plugins; omdsh composes them into a terminal application and adds the interface behavior needed to use them comfortably. `/trajectory` opens a keyboard-driven event ledger with Turn/Step grouping, live following, search, folding, timing, token usage, tool payloads, results, and schemas. `/context` reads the same client-visible Harness projections as the status footer and distinguishes provider-anchored occupancy from heuristic prompt composition.
|
|
52
52
|
|
|
53
53
|
The project follows four principles:
|
|
54
54
|
|
|
@@ -83,9 +83,17 @@ See the reproducible [TUI performance report](https://github.com/agi-fans/oh-my-
|
|
|
83
83
|
|
|
84
84
|
Run `/login` to configure a provider. DeepSeek still opens the official key dashboard, validates the key, and prefers the stored credential over an inherited `DEEPSEEK_API_KEY`. When a mounted provider registers a Harness authorization flow, `/login` lists that flow and its methods and the terminal only renders the notices and prompts the flow asks for. The same command can also activate a catalog API-key provider or add a custom provider with its own id, base URL, protocol, and model ids. `/model` then lists every live route. `/logout` removes an omdsh-managed choice and, for DeepSeek, falls back to the environment when available.
|
|
85
85
|
|
|
86
|
-
Model settings can also come from `$DSH_HOME/settings.yaml`. Skills and MCP configuration are documented in [Skills and MCP](https://github.com/agi-fans/oh-my-dsh/blob/main/docs/skills-and-mcp.md).
|
|
86
|
+
Model settings can also come from `$DSH_HOME/settings.yaml`. Use `/model favorite` and `/model unfavorite` to maintain a small local cycle list, then use `Ctrl+P`/`Alt+P` to move through it and `Ctrl+T` to change reasoning effort. Skills and MCP configuration are documented in [Skills and MCP](https://github.com/agi-fans/oh-my-dsh/blob/main/docs/skills-and-mcp.md).
|
|
87
87
|
|
|
88
|
-
After an upgrade, omdsh can show release notes once at startup. Use `/changelog` for recent entries or `/changelog full` for the complete packaged history. A cached daily npm check reports newer versions without installing anything automatically; both behaviors can be customized in `/settings`.
|
|
88
|
+
After an upgrade, omdsh can show release notes once at startup. Use `/changelog` for recent entries or `/changelog full` for the complete packaged history. A cached daily npm check reports newer versions without installing anything automatically; both behaviors can be customized in `/settings`. Terminal notifications for completed long turns and human prompts are also configured there and remain off by default.
|
|
89
|
+
|
|
90
|
+
Generate shell integration without starting the TUI or making network requests:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
omdsh completions bash
|
|
94
|
+
omdsh completions zsh
|
|
95
|
+
omdsh completions fish
|
|
96
|
+
```
|
|
89
97
|
|
|
90
98
|
## Development
|
|
91
99
|
|
package/config/cordis.yml
CHANGED
|
@@ -287,6 +287,9 @@
|
|
|
287
287
|
- id: tui-command-export
|
|
288
288
|
name: '@agi-fans/dsh-tui/command-export'
|
|
289
289
|
|
|
290
|
+
- id: tui-command-trajectory
|
|
291
|
+
name: '@agi-fans/dsh-tui/command-trajectory'
|
|
292
|
+
|
|
290
293
|
- id: tui-command-integrations
|
|
291
294
|
name: '@agi-fans/dsh-tui/command-integrations'
|
|
292
295
|
|
package/lib/args.d.ts
CHANGED
|
@@ -3,6 +3,39 @@
|
|
|
3
3
|
* overrides, durable --resume, --dump-config, `omdsh plugin`, and help/version.
|
|
4
4
|
* @module @agi-fans/oh-my-dsh
|
|
5
5
|
*/
|
|
6
|
+
export type CompletionShell = 'bash' | 'zsh' | 'fish';
|
|
7
|
+
export declare const OMDSH_CLI_COMMANDS: readonly [{
|
|
8
|
+
readonly name: "plugin";
|
|
9
|
+
readonly description: "Manage profile plugins";
|
|
10
|
+
}, {
|
|
11
|
+
readonly name: "completions";
|
|
12
|
+
readonly description: "Generate shell completion scripts";
|
|
13
|
+
}];
|
|
14
|
+
export declare const OMDSH_CLI_OPTIONS: readonly [{
|
|
15
|
+
readonly names: readonly ["--model"];
|
|
16
|
+
readonly description: "Model route";
|
|
17
|
+
readonly takesValue: true;
|
|
18
|
+
}, {
|
|
19
|
+
readonly names: readonly ["--provider"];
|
|
20
|
+
readonly description: "Provider route";
|
|
21
|
+
readonly takesValue: true;
|
|
22
|
+
}, {
|
|
23
|
+
readonly names: readonly ["-r", "--resume"];
|
|
24
|
+
readonly description: "Resume a durable session";
|
|
25
|
+
readonly takesValue: true;
|
|
26
|
+
}, {
|
|
27
|
+
readonly names: readonly ["--dump-config"];
|
|
28
|
+
readonly description: "Print the composed plugin tree";
|
|
29
|
+
readonly takesValue: false;
|
|
30
|
+
}, {
|
|
31
|
+
readonly names: readonly ["-h", "--help"];
|
|
32
|
+
readonly description: "Show help";
|
|
33
|
+
readonly takesValue: false;
|
|
34
|
+
}, {
|
|
35
|
+
readonly names: readonly ["--version"];
|
|
36
|
+
readonly description: "Show version";
|
|
37
|
+
readonly takesValue: false;
|
|
38
|
+
}];
|
|
6
39
|
export interface OmdshInvocation {
|
|
7
40
|
/** Positional prompt words, joined by spaces (empty when interactive only). */
|
|
8
41
|
prompt: string[];
|
|
@@ -18,6 +51,8 @@ export interface OmdshInvocation {
|
|
|
18
51
|
plugin: boolean;
|
|
19
52
|
/** pnpm arguments after `omdsh plugin`. */
|
|
20
53
|
pluginArgs: string[];
|
|
54
|
+
/** Requested completion script, without booting the application. */
|
|
55
|
+
completions: CompletionShell | undefined;
|
|
21
56
|
/** --help requested. */
|
|
22
57
|
help: boolean;
|
|
23
58
|
}
|
package/lib/args.js
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
* overrides, durable --resume, --dump-config, `omdsh plugin`, and help/version.
|
|
4
4
|
* @module @agi-fans/oh-my-dsh
|
|
5
5
|
*/
|
|
6
|
+
export const OMDSH_CLI_COMMANDS = [
|
|
7
|
+
{ name: 'plugin', description: 'Manage profile plugins' },
|
|
8
|
+
{ name: 'completions', description: 'Generate shell completion scripts' },
|
|
9
|
+
];
|
|
10
|
+
export const OMDSH_CLI_OPTIONS = [
|
|
11
|
+
{ names: ['--model'], description: 'Model route', takesValue: true },
|
|
12
|
+
{ names: ['--provider'], description: 'Provider route', takesValue: true },
|
|
13
|
+
{ names: ['-r', '--resume'], description: 'Resume a durable session', takesValue: true },
|
|
14
|
+
{ names: ['--dump-config'], description: 'Print the composed plugin tree', takesValue: false },
|
|
15
|
+
{ names: ['-h', '--help'], description: 'Show help', takesValue: false },
|
|
16
|
+
{ names: ['--version'], description: 'Show version', takesValue: false },
|
|
17
|
+
];
|
|
6
18
|
const HELP = `
|
|
7
19
|
omdsh — a TUI coding agent on the DeepSeek Harness runtime
|
|
8
20
|
|
|
@@ -11,6 +23,7 @@ Usage:
|
|
|
11
23
|
omdsh plugin add <package>
|
|
12
24
|
omdsh plugin remove <package>
|
|
13
25
|
omdsh plugin <pnpm-args...>
|
|
26
|
+
omdsh completions bash|zsh|fish
|
|
14
27
|
|
|
15
28
|
Options:
|
|
16
29
|
--model <name> model route (default deepseek-v4-flash)
|
|
@@ -39,9 +52,21 @@ export function parseOmdshArgs(argv, version) {
|
|
|
39
52
|
dumpConfig: false,
|
|
40
53
|
plugin: true,
|
|
41
54
|
pluginArgs: argv.slice(1).map(String),
|
|
55
|
+
completions: undefined,
|
|
42
56
|
help: false,
|
|
43
57
|
};
|
|
44
58
|
}
|
|
59
|
+
if (argv[0] === 'completions') {
|
|
60
|
+
const shell = argv[1];
|
|
61
|
+
if (shell !== 'bash' && shell !== 'zsh' && shell !== 'fish')
|
|
62
|
+
usageError('completions requires bash, zsh, or fish');
|
|
63
|
+
if (argv.length !== 2)
|
|
64
|
+
usageError('completions accepts exactly one shell');
|
|
65
|
+
return {
|
|
66
|
+
prompt: [], model: undefined, provider: undefined, resume: undefined, dumpConfig: false,
|
|
67
|
+
plugin: false, pluginArgs: [], completions: shell, help: false,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
45
70
|
const prompt = [];
|
|
46
71
|
let model;
|
|
47
72
|
let provider;
|
|
@@ -94,7 +119,7 @@ export function parseOmdshArgs(argv, version) {
|
|
|
94
119
|
if (dumpConfig && (resume !== undefined || prompt.length > 0)) {
|
|
95
120
|
usageError('--dump-config cannot be combined with a prompt or --resume');
|
|
96
121
|
}
|
|
97
|
-
return { prompt, model, provider, resume, dumpConfig, plugin: false, pluginArgs: [], help };
|
|
122
|
+
return { prompt, model, provider, resume, dumpConfig, plugin: false, pluginArgs: [], completions: undefined, help };
|
|
98
123
|
}
|
|
99
124
|
function usageError(message) {
|
|
100
125
|
console.error('omdsh: ' + message);
|
package/lib/bin.js
CHANGED
|
@@ -20,7 +20,11 @@ if (invocation.model !== undefined)
|
|
|
20
20
|
process.env.OMDSH_MODEL = invocation.model;
|
|
21
21
|
if (invocation.provider !== undefined)
|
|
22
22
|
process.env.OMDSH_PROVIDER = invocation.provider;
|
|
23
|
-
if (invocation.
|
|
23
|
+
if (invocation.completions !== undefined) {
|
|
24
|
+
const { generateCompletions } = await import("./completions.js");
|
|
25
|
+
process.stdout.write(generateCompletions(invocation.completions));
|
|
26
|
+
}
|
|
27
|
+
else if (invocation.plugin) {
|
|
24
28
|
const { dumpErrorMessage, prepareLaunchEnvironment } = await import("./composition.js");
|
|
25
29
|
const { runPlugin } = await import("./plugin.js");
|
|
26
30
|
try {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Shell completion generation from the canonical omdsh CLI metadata. */
|
|
2
|
+
import { OMDSH_CLI_COMMANDS, OMDSH_CLI_OPTIONS } from "./args.js";
|
|
3
|
+
const words = [...OMDSH_CLI_COMMANDS.map(command => command.name), ...OMDSH_CLI_OPTIONS.flatMap(option => option.names)].join(' ');
|
|
4
|
+
function bash() {
|
|
5
|
+
return `# bash completion for omdsh
|
|
6
|
+
_omdsh() {
|
|
7
|
+
local cur prev
|
|
8
|
+
COMPREPLY=()
|
|
9
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
10
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
11
|
+
if [[ "$prev" == "completions" ]]; then COMPREPLY=( $(compgen -W "bash zsh fish" -- "$cur") ); return; fi
|
|
12
|
+
COMPREPLY=( $(compgen -W "${words}" -- "$cur") )
|
|
13
|
+
}
|
|
14
|
+
complete -F _omdsh omdsh
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
function zsh() {
|
|
18
|
+
const options = OMDSH_CLI_OPTIONS.map(option => ` '${option.names.join(',')}[${option.description}]${option.takesValue ? ':value:' : ''}'`).join(' \\\n');
|
|
19
|
+
return `#compdef omdsh
|
|
20
|
+
_omdsh() {
|
|
21
|
+
local -a commands
|
|
22
|
+
commands=(${OMDSH_CLI_COMMANDS.map(command => `'${command.name}:${command.description}'`).join(' ')})
|
|
23
|
+
_arguments -s \\
|
|
24
|
+
${options} \\
|
|
25
|
+
'1:command:->command' '*::argument:->args'
|
|
26
|
+
case $state in
|
|
27
|
+
command) _describe 'command' commands ;;
|
|
28
|
+
args) [[ $words[2] == completions ]] && _values 'shell' bash zsh fish ;;
|
|
29
|
+
esac
|
|
30
|
+
}
|
|
31
|
+
_omdsh "$@"
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
function fish() {
|
|
35
|
+
const options = OMDSH_CLI_OPTIONS.flatMap(option => {
|
|
36
|
+
const long = option.names.find(name => name.startsWith('--'));
|
|
37
|
+
const short = option.names.find(name => /^-[^-]$/u.test(name));
|
|
38
|
+
if (long === undefined)
|
|
39
|
+
return [];
|
|
40
|
+
return [`complete -c omdsh${short === undefined ? '' : ` -s ${short.slice(1)}`} -l ${long.slice(2)}${option.takesValue ? ' -r' : ''} -d '${option.description.replace(/'/gu, "\\'")}'`];
|
|
41
|
+
});
|
|
42
|
+
const commands = OMDSH_CLI_COMMANDS.map(command => `complete -c omdsh -f -n '__fish_use_subcommand' -a '${command.name}' -d '${command.description}'`);
|
|
43
|
+
return ['# fish completion for omdsh', ...options, ...commands, "complete -c omdsh -f -n '__fish_seen_subcommand_from completions' -a 'bash zsh fish'", ''].join('\n');
|
|
44
|
+
}
|
|
45
|
+
export function generateCompletions(shell) {
|
|
46
|
+
if (shell === 'bash')
|
|
47
|
+
return bash();
|
|
48
|
+
if (shell === 'zsh')
|
|
49
|
+
return zsh();
|
|
50
|
+
return fish();
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=completions.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agi-fans/oh-my-dsh",
|
|
3
3
|
"description": "omdsh: TUI coding agent command over the DeepSeek Harness runtime",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.10.0",
|
|
5
5
|
"homepage": "https://github.com/agi-fans/oh-my-dsh#readme",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"@deepseek-ai/dsh-settings-file": "0.1.1-rc.2",
|
|
91
91
|
"@deepseek-ai/dsh-credentials-local": "0.1.1-rc.2",
|
|
92
92
|
"@deepseek-ai/dsh-authorization": "0.1.1-rc.2",
|
|
93
|
-
"@agi-fans/dsh-tui": "^0.
|
|
93
|
+
"@agi-fans/dsh-tui": "^0.10.0"
|
|
94
94
|
},
|
|
95
95
|
"peerDependencies": {
|
|
96
96
|
"@deepseek-ai/cordis": "^4.0.1"
|