diff --git a/apps/cli/src/commands.ts b/apps/cli/src/commands.ts index 3f45a59..0fa5c6c 100644 --- a/apps/cli/src/commands.ts +++ b/apps/cli/src/commands.ts @@ -16,6 +16,7 @@ import { estimateCost, redact, EFFORT_PARAMS, + VERSION, type Credentials, type Effort, } from '@deepcode/core'; @@ -1023,6 +1024,34 @@ export const PrCommentsCommand: SlashCommand = { }, }; +export const UpgradeCommand: SlashCommand = { + name: '/upgrade', + description: 'Show the current version and how to update.', + run() { + return [ + `DeepCode CLI v${VERSION}`, + 'Update the CLI: npm i -g deepcode-cli@latest', + 'The macOS desktop app auto-updates via GitHub Releases.', + ]; + }, +}; + +export const PrivacySettingsCommand: SlashCommand = { + name: '/privacy-settings', + description: 'Show where your data lives and what is sent to DeepSeek.', + run(_args, ctx) { + const base = ctx.creds?.baseURL || 'https://api.deepseek.com'; + return [ + 'Privacy — DeepCode is local-first:', + ' • Credentials: ~/.deepcode/credentials.json (chmod 600), or an OS keychain via apiKeyHelper.', + ' • Sessions, history & snapshots: ~/.deepcode/sessions/ — local files on this machine.', + ` • Prompts, file contents & tool output are sent to the DeepSeek API (${base}) to generate responses, handled per DeepSeek's policy.`, + ' • Plugin / hook subprocesses run with DeepSeek credentials stripped from their env.', + ' • Full threat model: docs/security-model.md.', + ]; + }, +}; + export const BUILTIN_COMMANDS: SlashCommand[] = [ HelpCommand, ClearCommand, @@ -1056,6 +1085,8 @@ export const BUILTIN_COMMANDS: SlashCommand[] = [ LoginCommand, LogoutCommand, PrCommentsCommand, + UpgradeCommand, + PrivacySettingsCommand, ]; // ────────────────────────────────────────────────────────────────────────── diff --git a/apps/cli/src/parity-commands.test.ts b/apps/cli/src/parity-commands.test.ts index ec6c948..4e9a790 100644 --- a/apps/cli/src/parity-commands.test.ts +++ b/apps/cli/src/parity-commands.test.ts @@ -134,3 +134,23 @@ describe('/pr_comments', () => { expect(out).toMatch(/no open pull request|needs the github cli|failed/i); }); }); + +describe('/upgrade + /privacy-settings', () => { + it('/upgrade shows the version + update instructions', async () => { + const out = (await reg.match('/upgrade')!.cmd.run([], ctx())).join('\n'); + expect(out).toMatch(/DeepCode CLI v\d/); + expect(out).toMatch(/npm i -g deepcode-cli@latest/); + }); + + it('/privacy-settings shows data locations + the DeepSeek endpoint', async () => { + const out = ( + await reg + .match('/privacy-settings')! + .cmd.run([], ctx({ creds: { apiKey: 'x', baseURL: 'https://api.deepseek.com/v1' } })) + ).join('\n'); + expect(out).toMatch(/credentials\.json/); + expect(out).toMatch(/sessions/); + expect(out).toMatch(/api\.deepseek\.com/); + expect(out).toMatch(/security-model\.md/); + }); +}); diff --git a/docs/BEHAVIOR_PARITY.md b/docs/BEHAVIOR_PARITY.md index 92547a7..ebf4333 100644 --- a/docs/BEHAVIOR_PARITY.md +++ b/docs/BEHAVIOR_PARITY.md @@ -53,7 +53,7 @@ Legend: `✅` matches · `🟡` matches with caveats · `🔄` deferred · `⚠ | `/login` / `/logout` | ✓ | ✓ | ✅ — /logout clears creds + exits; /login stores a new key (next launch) | | `/export` | ✓ | ✓ | ✅ — writes the conversation to a markdown file | | `/bug` (alias `/feedback`) | ✓ | ✓ | ✅ — prints a prefilled GitHub issue link (model/mode/effort in the body) | -| `/upgrade` | ✓ | ✗ | 🔄 — no slash command; the `deepcode upgrade` CLI subcommand prints an upgrade hint | +| `/upgrade` | ✓ | ✓ | ✅ — prints version + `npm i -g deepcode-cli@latest` (also the `deepcode upgrade` subcommand) | | `/pr_comments` | ✓ | ✓ | ✅ — `gh pr view` comments for the current branch's PR | | `/review` | ✓ | ✗ (skill avail) | 🟡 — via Skill tool | | `/security-review` | ✓ | ✗ (skill avail) | 🟡 — via Skill tool | @@ -66,7 +66,7 @@ Legend: `✅` matches · `🟡` matches with caveats · `🔄` deferred · `⚠ | `/hooks` | ✓ | ✓ | ✅ — lists hooks configured in settings.json | | `/skills` | ✓ | ✓ | ✅ — lists built-in + user + project skills | | `/permissions` | ✓ | ✓ (read-only) | 🟡 — shows rules + default mode (interactive editor deferred) | -| `/privacy-settings` | ✓ | ✗ | 🔄 | +| `/privacy-settings` | ✓ | ✓ | ✅ — summarizes local data locations + what's sent to the DeepSeek API (read-only) | | `/migrate-installer` | ✓ | ✗ | 🔄 | | `/release-notes` | ✓ | ✓ | ✅ — prints the latest `CHANGELOG.md` entry |