Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
version: ${{ steps.version.outputs.version }}
channel: ${{ steps.version.outputs.channel }}
is_mandatory: ${{ steps.version.outputs.is_mandatory }}
has_apple: ${{ steps.credentials.outputs.has_apple }}
has_npm: ${{ steps.credentials.outputs.has_npm }}
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
Expand Down Expand Up @@ -56,6 +58,25 @@ jobs:
- run: pnpm docs:check
- run: pnpm release:check

# Which publication legs can even run. A job that cannot possibly succeed
# should be skipped, not failed — a red release for a missing credential
# teaches people to ignore red releases.
- name: Detect available publishing credentials
id: credentials
run: |
if [ -n "${{ secrets.APPLE_ID }}" ] && [ -n "${{ secrets.CSC_LINK }}" ]; then
echo "has_apple=true" >> "$GITHUB_OUTPUT"
else
echo "has_apple=false" >> "$GITHUB_OUTPUT"
echo "::warning::Apple signing secrets absent — skipping the Mac client build. See docs/RELEASING.md."
fi
if [ -n "${{ secrets.NPM_TOKEN }}" ]; then
echo "has_npm=true" >> "$GITHUB_OUTPUT"
else
echo "has_npm=false" >> "$GITHUB_OUTPUT"
echo "::warning::NPM_TOKEN absent — skipping the npm publish. See docs/RELEASING.md."
fi

- name: Install Chromium
run: pnpm --filter @deepcode/desktop exec playwright install --with-deps chromium

Expand Down Expand Up @@ -93,10 +114,13 @@ jobs:
# Publish CLI to npm
# ----------------------------------------------------------------------
publish-cli:
name: Publish deepcode-cli to npm
name: Publish @deepcode/cli to npm
# Avoid a partial release: do not publish npm until both installable
# desktop/editor artifacts have built successfully.
needs: [validate, build-vscode, build-mac]
# The anti-partial-release rule stands: npm still waits on both installable
# artifacts. It additionally needs a token to exist at all.
if: needs.validate.outputs.has_npm == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
Expand Down Expand Up @@ -209,6 +233,7 @@ jobs:
build-mac:
name: Build + sign + notarize Mac client (Tauri)
needs: validate
if: needs.validate.outputs.has_apple == 'true'
runs-on: macos-14
timeout-minutes: 30
steps:
Expand Down Expand Up @@ -333,6 +358,16 @@ jobs:
github-release:
name: Publish GitHub Release
needs: [validate, publish-cli, build-vscode, build-mac]
# Ship what was actually built. `always()` is required because a skipped
# dependency would otherwise skip this job too — but the guard still refuses
# to publish when something tried and *failed*, so a broken build never
# becomes a release.
if: >-
always()
&& needs.validate.result == 'success'
&& needs.build-vscode.result == 'success'
&& needs.build-mac.result != 'failure'
&& needs.publish-cli.result != 'failure'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
Expand All @@ -346,6 +381,7 @@ jobs:
- run: pnpm install --frozen-lockfile

- name: Download Mac DMG
if: needs.build-mac.result == 'success'
uses: actions/download-artifact@v8
with:
name: mac-release
Expand All @@ -367,6 +403,14 @@ jobs:
FROM=$(git rev-list --max-parents=0 HEAD)
fi
npx tsx scripts/gen-release-notes.ts "$FROM" HEAD > release-notes.md
# A release page missing an artifact reads as "there is no Mac build"
# rather than "it was not produced this time". Say which.
if [ "${{ needs.build-mac.result }}" != "success" ]; then
printf '\n---\n\n> **No macOS build in this release.** Apple signing credentials were not configured when it was cut; see `docs/RELEASING.md`.\n' >> release-notes.md
fi
if [ "${{ needs.publish-cli.result }}" != "success" ]; then
printf '\n> **Not published to npm.** `NPM_TOKEN` was not configured when this release was cut; install from source or the VSIX.\n' >> release-notes.md
fi
cat release-notes.md

- name: Create GitHub Release
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ adopted, what was rejected, and where the implementation diverged from the plan.

### ⚠️ Breaking

- **The CLI is published as `@deepcode/cli`, not `deepcode-cli`.** Install with
`npm i -g @deepcode/cli`. The unscoped name on npm belongs to an unrelated
project, so it was never ours to publish to. The binary is still `deepcode`
and nothing about the tool's behaviour changes. (#249)
- **Unattended runs no longer inherit a permissive permission mode.** A
`permissions.defaultMode` of `bypassPermissions` or `acceptEdits` — chosen for
interactive convenience — is clamped to `default` for scheduled jobs, which
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ DeepCode 让 DeepSeek 可以在本地代码库中执行读取、编辑、命令

```bash
# 1. 装 CLI
npm i -g deepcode-cli
npm i -g @deepcode/cli

# 2. 设 DeepSeek key(首次启动会引导)
deepcode
Expand Down Expand Up @@ -82,7 +82,7 @@ packages/
core/ # @deepcode/core — agent loop, providers, tools, MCP, sandbox, hooks (UI-agnostic)
shared-ui/ # @deepcode/shared-ui — types shared between CLI + Mac client + VS Code
apps/
cli/ # deepcode-cli — Node.js CLI (npm publishable)
cli/ # @deepcode/cli — Node.js CLI (npm publishable)
desktop/ # @deepcode/desktop — Tauri 2 + React Mac client
vscode/ # deepcode — VS Code extension (app-server protocol client)
lsp/ # @deepcode/lsp — LSP bridge for Neovim/Emacs/Sublime (v1.1)
Expand Down
4 changes: 2 additions & 2 deletions apps/cli/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# deepcode-cli
# @deepcode/cli

DeepCode CLI — Node.js 一键安装的命令行 AI 编程代理。

## Install (post-v1)

```bash
npm i -g deepcode-cli
npm i -g @deepcode/cli
deepcode --help
```

Expand Down
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "deepcode-cli",
"name": "@deepcode/cli",
"version": "0.3.0",
"description": "DeepCode CLI — DeepSeek-powered AI coding agent for real codebases",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ async function main(): Promise<number> {
return doctor();
}
if (args.upgrade) {
process.stdout.write(`Run: npm i -g deepcode-cli@latest\n`);
process.stdout.write(`Run: npm i -g @deepcode/cli@latest\n`);
process.stdout.write(`(The Mac client updates itself; only the CLI needs this.)\n`);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ export const UpgradeCommand: SlashCommand = {
run() {
return [
`DeepCode CLI v${VERSION}`,
'Update the CLI: npm i -g deepcode-cli@latest',
'Update the CLI: npm i -g @deepcode/cli@latest',
'The macOS desktop app auto-updates via GitHub Releases.',
];
},
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/parity-commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ 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/);
expect(out).toContain('npm i -g @deepcode/cli@latest');
});

it('/privacy-settings shows data locations + the DeepSeek endpoint', async () => {
Expand Down
2 changes: 1 addition & 1 deletion docs/MIGRATION_FROM_CLAUDE_CODE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The copy below is only needed if you want DeepCode to own its own copies.

```bash
# 1. Install DeepCode CLI
npm install -g deepcode-cli
npm install -g @deepcode/cli

# 2. Set your DeepSeek key
mkdir -p ~/.deepcode
Expand Down
23 changes: 20 additions & 3 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,19 @@ build failure cannot create an avoidable partial release.
### 1. GitHub Actions secrets

Set these in repo settings → Secrets and variables → Actions → New
repository secret. All six are required for the complete release graph.
repository secret. All six are required for the _complete_ release graph.

**A release without them still works, partially.** `validate` detects which
credential sets are present and skips the legs it cannot run:

| Missing | Effect |
| ------------- | ---------------------------------------------------------------- |
| Apple secrets | `build-mac` is **skipped**; no DMG, and the release notes say so |
| `NPM_TOKEN` | `publish-cli` is **skipped**; nothing is published to npm |
| Neither | GitHub Release still ships with the VSIX and source |

Skipped, not failed — a red release for a missing credential teaches people to
ignore red releases. A job that actually _fails_ still blocks the release.

| Secret | Purpose |
| ----------------------------- | ----------------------------------------------------------------- |
Expand All @@ -19,7 +31,7 @@ repository secret. All six are required for the complete release graph.
| `APPLE_TEAM_ID` | 10-character team ID (from developer.apple.com → membership) |
| `CSC_LINK` | Base64-encoded `.p12` of the Developer ID Application cert |
| `CSC_KEY_PASSWORD` | Password used when exporting the `.p12` |
| `NPM_TOKEN` | npm access token with `publish` scope |
| `NPM_TOKEN` | npm access token with `publish` scope for the `@deepcode` scope |

### 2. Export the Developer ID certificate

Expand Down Expand Up @@ -48,6 +60,11 @@ App-specific passwords → Generate. Save the 16-char password as
[npmjs.com](https://www.npmjs.com) → account → Access Tokens → Generate
new token → **Automation** (CI-friendly) → save as `NPM_TOKEN`.

The CLI publishes as **`@deepcode/cli`**. The unscoped `deepcode-cli` on npm
belongs to an unrelated project, so the `@deepcode` org must exist and the token
must be able to publish into it. The workflow already passes `--access public`,
which scoped packages need in order not to default to private.

## Releasing

```bash
Expand Down Expand Up @@ -151,7 +168,7 @@ download manually; the "Relaunch to update" flow lights up once the feed exists.

## After a release

- Verify: `npm view deepcode-cli@<version>` shows the new version
- Verify: `npm view @deepcode/cli@<version>` shows the new version
- Verify: `https://github.com/oratis/deepcode/releases/tag/v<version>`
has the DMG and version-matched VSIX attached
- Optional: announce in the README / homepage
Expand Down
2 changes: 1 addition & 1 deletion docs/cli-flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ deepcode upgrade # CLI self-update
| `-h`, `--help` | Print usage | M2 ✅ |
| `-v`, `--version` | Print version | M2 ✅ |
| `doctor` | Health check (runtime, credentials, config provenance/trust/issues) | M2 ✅ |
| `upgrade` | Print `npm i -g deepcode-cli@latest` hint | M2 ✅ |
| `upgrade` | Print `npm i -g @deepcode/cli@latest` hint | M2 ✅ |
| `-p`, `--print <prompt>` | Headless one-shot | M8 |

## Session shaping
Expand Down
2 changes: 1 addition & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ permission, and recovery behavior is still being unified; see the

```bash
# 1. Install
npm i -g deepcode-cli
npm i -g @deepcode/cli

# 2. Start the REPL — the first run walks you through setting your DeepSeek key
deepcode
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/config/claude-compat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// The migration guide asked people to `mv ~/.claude/... ~/.deepcode/...` before
// DeepCode would see anything they had. That is five steps of grit in front of
// `npm i -g deepcode-cli && deepcode`, and it is the first thing a migrating
// `npm i -g @deepcode/cli && deepcode`, and it is the first thing a migrating
// user hits.

import { mkdir, mkdtemp, writeFile } from 'node:fs/promises';
Expand Down
Loading