@toddzheng024/dscode 0.4.0 → 0.5.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/cli.mjs CHANGED
@@ -6,5 +6,5 @@ import { runEmailClient } from './email/cli.mjs';
6
6
  const release = JSON.parse(readFileSync(new URL('./release.json', import.meta.url), 'utf8'));
7
7
  const args = process.argv.slice(2);
8
8
  if (args[0] === '--version') console.log(release.version);
9
- else if (args[0] === '--help' || args[0] === '-h') console.log(`DSCODE ${release.version}\n\n dscode Start; first launch installs the Hub preset\n dscode install [version] Install an exact preset release\n dscode update [version] Upgrade (default: launcher release)\n dscode history List retained preset revisions\n dscode rollback [revision] Restore a retained revision\n dscode doctor Check the installed Hub profile\n dscode email configure FILE Import a Google Desktop OAuth client JSON\n dscode email alias set NAME ADDRESS | list | remove NAME\n dscode email connect Connect Gmail in the browser\n dscode email sync|status Sync or inspect Gmail OAuth\n dscode email imap-sync|imap-status Sync or inspect IMAP (/email then i to set up)\n dscode sessions List running sessions\n dscode send ID [--steer|--defer] TEXT Send or leave a note\n --title TITLE Set the session title when sending\n dscode read ID [--after SEQ] Read an immutable event page\n dscode watch ID [--after SEQ] Subscribe to session events\n dscode mailbox ID Read messages and deferred notes\n dscode watch-mailbox ID Subscribe to mailbox events\n dscode reply ID --reply-to REQUEST TEXT Send a final reply\n dscode cancel ID MESSAGE Cancel a request or unclaimed message\n dscode new-task ID Explicitly reset communication budget while idle\n dscode resume [SESSION_ID] Resume a session (default: latest)\n dscode --continue Continue the previous session\n dscode --resume SESSION_ID Resume a session\n dscode --cwd DIRECTORY Work in a directory\n\nState: $DSCODE_HOME or ~/.local/share/dscode-hub\nDeepSeek credentials: /login in the TUI saves to ~/.dscode/credentials.yaml.\nAn existing DEEPSEEK_API_KEY environment variable takes precedence.`);
9
+ else if (args[0] === '--help' || args[0] === '-h') console.log(`DSCODE ${release.version}\n\n dscode Start; first launch installs the Hub preset\n dscode install [version] Install an exact preset release\n dscode update [version] Upgrade (default: launcher release)\n dscode history List retained preset revisions\n dscode rollback [revision] Restore a retained revision\n dscode doctor [--local|--preview] Analyze recent runtime logs and session traces\n dscode email configure FILE Import a Google Desktop OAuth client JSON\n dscode email alias set NAME ADDRESS | list | remove NAME\n dscode email connect Connect Gmail in the browser\n dscode email sync|status Sync or inspect Gmail OAuth\n dscode email imap-sync|imap-status Sync or inspect IMAP (/email then i to set up)\n dscode sessions List running sessions\n dscode send ID [--steer|--defer] TEXT Send or leave a note\n --title TITLE Set the session title when sending\n dscode read ID [--after SEQ] Read an immutable event page\n dscode watch ID [--after SEQ] Subscribe to session events\n dscode mailbox ID Read messages and deferred notes\n dscode watch-mailbox ID Subscribe to mailbox events\n dscode reply ID --reply-to REQUEST TEXT Send a final reply\n dscode cancel ID MESSAGE Cancel a request or unclaimed message\n dscode new-task ID Explicitly reset communication budget while idle\n dscode resume [SESSION_ID] Resume a session (default: latest)\n dscode --continue Continue the previous session\n dscode --resume SESSION_ID Resume a session\n dscode --cwd DIRECTORY Work in a directory\n\nState: $DSCODE_HOME or ~/.local/share/dscode-hub\nDeepSeek credentials: /login in the TUI saves to ~/.dscode/credentials.yaml.\nAn existing DEEPSEEK_API_KEY environment variable takes precedence.`);
10
10
  else (args[0] === 'email' ? runEmailClient(args.slice(1)) : CLIENT_COMMANDS.includes(args[0]) ? runClient(args, stateHome()) : run(args, release)).catch(error => { console.error(error.message); process.exitCode = 1; });
package/manager.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { readFileSync, existsSync } from 'node:fs';
1
+ import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
2
  import { dirname, join, resolve } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { homedir } from 'node:os';
@@ -25,10 +25,14 @@ export function commandPlan(args, release, installed) {
25
25
  if (rest.length > 1 || rest[0]?.startsWith('-')) throw Error('Usage: dscode rollback [revision]');
26
26
  return { hub: ['profile', 'rollback', ...rest, ...flags] };
27
27
  }
28
- if (command === 'history' || command === 'doctor') {
28
+ if (command === 'history') {
29
29
  if (rest.length) throw Error('Usage: dscode ' + command);
30
30
  return { hub: ['profile', command, ...flags] };
31
31
  }
32
+ if (command === 'doctor') {
33
+ if (rest.length > 1 || rest[0] && !['--local', '--preview'].includes(rest[0])) throw Error('Usage: dscode doctor [--local|--preview]');
34
+ return { doctor: rest[0]?.slice(2) ?? 'analyze' };
35
+ }
32
36
  return { launch: args, install: !installed };
33
37
  }
34
38
  // Recommendations are advisory. Resolve from the installed bundle (including
@@ -79,6 +83,21 @@ export async function run(args, release) {
79
83
  child.once('error', error => { cleanup(); reject(error); });
80
84
  child.once('exit', (code, signal) => { cleanup(); code === 0 ? resolvePromise() : reject(Error(`DSCODE process exited: ${signal ?? code}`)); });
81
85
  });
86
+ if (args[0] === 'doctor') {
87
+ const mode = commandPlan(args, release, true).doctor;
88
+ const profile = join(home, 'profiles/dscode');
89
+ const state = join(home, '.hub/installations/dscode/current.json');
90
+ if (!existsSync(state) || !existsSync(join(profile, 'package.json'))) throw Error('DSCODE is not installed. Run dscode install first.');
91
+ const dsh = join(profile, 'node_modules/@deepseek-ai/dsh/lib/bin.js');
92
+ const runner = join(profile, 'node_modules', release.bundle, 'plugins/tui-tools/doctor-cli.mjs');
93
+ if (!existsSync(dsh) || !existsSync(runner)) throw Error('DSCODE installation is incomplete. Run dscode update first.');
94
+ const overlay = join(home, 'diagnostics', 'doctor-cli.patch.yml');
95
+ mkdirSync(join(home, 'diagnostics'), { recursive: true, mode: 0o700 });
96
+ writeFileSync(overlay, `${['tui-startup', 'tui-runner', 'dscode-session-bridge', 'dscode-session-cards', 'dscode-memory', 'dscode-email-tools', 'dscode-hooks', 'dscode-auto-review', 'dscode-session-metrics', 'dscode-tui-tools']
97
+ .map(id => `- id: ${id}\n disabled: true`).join('\n')}\n- insert:\n - id: dscode-doctor-cli\n name: ${JSON.stringify(runner)}\n config:\n local: ${mode === 'local'}\n preview: ${mode === 'preview'}\n`, { mode: 0o600 });
98
+ await exec(dsh, ['--profile', 'dscode', '--patch', overlay]);
99
+ return;
100
+ }
82
101
  const releaseLock = await acquireLock(home);
83
102
  let lease;
84
103
  try {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.4.0",
2
+ "version": "0.5.0",
3
3
  "type": "module",
4
4
  "license": "MIT",
5
5
  "author": "Todd Zheng",
package/release.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "slug": "dscode",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "runtime": "0.1.5-rc.1",
5
5
  "bundle": "@toddzheng024/dscode-bundle"
6
6
  }