feat(cli): mark meta and upgrade commands experimental

This commit is contained in:
Turtle
2026-07-31 20:16:19 +08:00
parent d64b032311
commit 60a0bcd358
24 files changed
+107 -115

No files matched your search

+13 -11
View File
@@ -2,8 +2,9 @@
* Commander adapter for the `dsh` command-line entry: the one place argv is
* parsed and routed to a mode. `bin.ts` switches on the returned discriminant
* and dynamic-imports that mode's module. One program: the default (no
* subcommand) is the TUI/headless surface with option-only flags; `meta` and
* `web` are real subcommands. Commander owns `--help`/`--version` and parse
* subcommand) is the TUI/headless surface with option-only flags;
* `experimental-meta` and `web` are real subcommands. Commander owns
* `--help`/`--version` and parse
* errors — it prints and exits at the point of failure (a domain failure routes through
* `command.error`), so this returns only a resolved mode.
* @module @deepseek-ai/dsh/args
@@ -51,8 +52,8 @@ interface MetaInvocation {
}
/**
* Guided fresh-session entry: `dsh upgrade` seeds the first turn with the
* `dsh-upgrade` skill. It always mints a
* Guided fresh-session entry: `dsh experimental-upgrade` seeds the first turn
* with the `dsh-upgrade` skill. It always mints a
* fresh session in the invoking directory and takes no options — `--resume`,
* `--config`, and `-p` are rejected as mistyped, so there is nothing to carry.
*/
@@ -248,14 +249,15 @@ Examples:
}
// Registration order is the rendered help order, so daily use comes first
// and the harness-development surfaces (`web --dev`, `meta`) come last.
// `upgrade` is a guided fresh-session entry: it takes no options and always
// mints a fresh session, so nothing is left to carry.
// and the harness-development surfaces (`web --dev`, `experimental-meta`)
// come last. `experimental-upgrade` is a guided fresh-session entry: it
// takes no options and always mints a fresh session, so nothing is left to
// carry.
program
.command('upgrade')
.command('experimental-upgrade')
.description('update this dsh installation to the latest version')
.action(() => {
rejectParentOptions('upgrade')
rejectParentOptions('experimental-upgrade')
resolved = { mode: 'upgrade' }
})
@@ -283,10 +285,10 @@ Examples:
})
program
.command('meta')
.command('experimental-meta')
.description('work on the dsh source that runs this command, from any directory')
.action(() => {
rejectParentOptions('meta')
rejectParentOptions('experimental-meta')
resolved = { mode: 'meta' }
})
+13 -10
View File
@@ -8,10 +8,11 @@
* from it, so `dsh` acts on whatever project it is launched in. Session storage
* is the exception — it lives under the Harness home so `/resume` reaches every
* workspace, and an in-place resume enters the selected session's own directory.
* `dsh meta` is the one exception — it makes this harness checkout the
* workspace. `dsh upgrade` is a fresh session whose first turn auto-invokes a
* bundled skill. After boot, the agent's system prompt is told the path to this
* harness checkout so it can find its own source.
* `dsh experimental-meta` is the one exception — it makes this harness
* checkout the workspace. `dsh experimental-upgrade` is a fresh session whose
* first turn auto-invokes a bundled skill. After boot, the agent's system
* prompt is told the path to this harness checkout so it can find its own
* source.
* @module @deepseek-ai/dsh/tui
*/
@@ -59,7 +60,7 @@ const SESSION_QUERY_DB = `session-query-${String(process.pid)}-${randomUUID()}.d
// The harness checkout root: three hops up from apps/cli/{src,lib}, resolved
// from this bin's location so it holds however `dsh` is launched (a PATH
// symlink, an arbitrary cwd). The agent is told where its own source lives.
/** The harness checkout used as the `dsh meta` workspace and source prompt path. */
/** The harness checkout used as the `dsh experimental-meta` workspace and source prompt path. */
export const SOURCE_ROOT = fileURLToPath(new URL('../../..', import.meta.url))
/* v8 ignore start -- composition over the unit-tested dsh-app-boot helpers;
@@ -76,10 +77,11 @@ export const SOURCE_ROOT = fileURLToPath(new URL('../../..', import.meta.url))
* {@link CONFIGURED_AGENT_IDENTITIES_KEY}, so no config key selects the session
* and an overlay replacing the agent row cannot drop it.
* @param workspace - a directory to make the workspace instead of the invoking
* one, or `undefined` to keep the cwd. Only `dsh meta` passes it.
* one, or `undefined` to keep the cwd. Only `dsh experimental-meta` passes it.
* @param initialSkill - a bundled skill to auto-invoke as a fresh session's
* first turn, or `undefined`. Set only by `dsh upgrade` and ignored on a resume,
* so it never re-fires; reaches the app through {@link INITIAL_SKILL_KEY}.
* first turn, or `undefined`. Set only by `dsh experimental-upgrade` and
* ignored on a resume, so it never re-fires; reaches the app through
* {@link INITIAL_SKILL_KEY}.
* @param configReplace - a config path to boot as the ENTIRE tree, bypassing the
* shared base, the TUI overlay, and the personal overlay alike, or `undefined`
* to compose them; already parsed from `--config-replace`.
@@ -122,8 +124,9 @@ export async function runTui(
const entry = process.argv[1]
const execve = process.execve?.bind(process)
const app: { current?: Context } = {}
// Resume always enters the default surface because meta rejects parent
// options, including `--resume`. The resumed session already persists its cwd.
// Resume always enters the default surface because experimental-meta rejects
// parent options, including `--resume`. The resumed session already persists
// its cwd.
const resumeArgs = (sessionId: string): string[] => [
`--resume=${sessionId}`,
// Both config flags must survive the handoff: resuming into a different