windsurf now also answers to devin-desktop (CLI --devin-desktop) for the Windsurf→Devin Desktop rebrand; all paths unchanged. The .devin/skills/ workspace migration is split to #1085. Closes #792.
This commit is contained in:
6
.changeset/792-devin-desktop-alias.md
Normal file
6
.changeset/792-devin-desktop-alias.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
type: Changed
|
||||
pr: 1086
|
||||
---
|
||||
|
||||
**`devin-desktop` runtime alias for the Windsurf→Devin Desktop rebrand** — the `windsurf` runtime now also answers to `devin-desktop` (CLI `--devin-desktop`), aiding discoverability after Cognition rebranded Windsurf as Devin Desktop. All paths are unchanged — global skills still install to `~/.codeium/windsurf/skills/`. (#1086)
|
||||
@@ -410,7 +410,7 @@ function selectRuntimesFromArgs(runtimeArgs) {
|
||||
if (runtimeArgs.includes('--copilot')) selected.push('copilot');
|
||||
if (runtimeArgs.includes('--antigravity')) selected.push('antigravity');
|
||||
if (runtimeArgs.includes('--cursor')) selected.push('cursor');
|
||||
if (runtimeArgs.includes('--windsurf')) selected.push('windsurf');
|
||||
if (runtimeArgs.includes('--windsurf') || runtimeArgs.includes('--devin-desktop')) selected.push('windsurf');
|
||||
if (runtimeArgs.includes('--augment')) selected.push('augment');
|
||||
if (runtimeArgs.includes('--trae')) selected.push('trae');
|
||||
if (runtimeArgs.includes('--qwen')) selected.push('qwen');
|
||||
|
||||
@@ -1209,7 +1209,7 @@ When `runtime` is set, profile tiers (`opus`/`sonnet`/`haiku`) resolve to runtim
|
||||
| `opencode` | `anthropic/claude-opus-4-8` | `anthropic/claude-sonnet-4-6` | `anthropic/claude-haiku-4-5` | (not used) |
|
||||
| `copilot` | `claude-opus-4-8` | `claude-sonnet-4-6` | `claude-haiku-4-5` | (not used) |
|
||||
| `hermes` | `anthropic/claude-opus-4-8` | `anthropic/claude-sonnet-4-6` | `anthropic/claude-haiku-4-5` | (not used) |
|
||||
| Group B (`kilo`, `cline`, `cursor`, `windsurf`, `augment`, `trae`, `codebuddy`, `antigravity`) | (no built-in default — your runtime handles model selection) | | | |
|
||||
| Group B (`kilo`, `cline`, `cursor`, `windsurf` (alias: `devin-desktop`), `augment`, `trae`, `codebuddy`, `antigravity`) | (no built-in default — your runtime handles model selection) | | | |
|
||||
|
||||
> **How these model IDs are sourced.** The catalog (`bin/shared/model-catalog.json`) pins each runtime's tier defaults to that provider's current frontier IDs, and may intentionally carry forward-dated IDs ahead of a provider's public docs. To verify an ID is live before changing it, check the provider's own source/API — e.g. Gemini: gemini-cli `packages/core/src/config/models.ts` or `gemini --model <id> --prompt ping`; Codex: `codex debug models` or the OpenAI Codex models page; Qwen: Alibaba Model Studio model list. Only change an ID that the provider actually rejects — absence from documentation alone is not proof of invalidity.
|
||||
|
||||
|
||||
@@ -826,7 +826,7 @@ WINDSURF_CONFIG_DIR=~/.codeium/windsurf-next npx @opengsd/gsd-core@latest --wind
|
||||
| Codex | (per Codex CLI) | `--config-dir` flag |
|
||||
| Copilot | `~/.copilot` | `COPILOT_CONFIG_DIR` (or `COPILOT_HOME`) |
|
||||
| Cursor | `~/.cursor` | `CURSOR_CONFIG_DIR` |
|
||||
| Windsurf | `~/.codeium/windsurf` | `WINDSURF_CONFIG_DIR` |
|
||||
| Windsurf / Devin Desktop | `~/.codeium/windsurf` | `WINDSURF_CONFIG_DIR` |
|
||||
| Antigravity | auto-detected | `ANTIGRAVITY_CONFIG_DIR` |
|
||||
| Augment | `~/.augment` | `AUGMENT_CONFIG_DIR` |
|
||||
| Trae | `~/.trae` | `TRAE_CONFIG_DIR` |
|
||||
|
||||
@@ -308,13 +308,17 @@ CURSOR_CONFIG_DIR=~/.cursor-alt npx @opengsd/gsd-core@latest --cursor --global
|
||||
|
||||
---
|
||||
|
||||
### Windsurf
|
||||
### Windsurf / Devin Desktop
|
||||
|
||||
Windsurf has rebranded to **Devin Desktop**. Both runtime names are accepted — use either `--windsurf` or `--devin-desktop`.
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --windsurf --global
|
||||
# or equivalently:
|
||||
npx @opengsd/gsd-core@latest --devin-desktop --global
|
||||
```
|
||||
|
||||
Skills land in `~/.codeium/windsurf/`. GSD installs skills, agents, and workspace rules.
|
||||
Skills land in `~/.codeium/windsurf/` (global path unchanged). GSD installs skills, agents, and workspace rules.
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
@@ -456,7 +460,7 @@ A local install writes into the `.claude/` directory at your project root. Local
|
||||
|
||||
## Installing prerelease editions (Next / Nightly / Insiders / Preview)
|
||||
|
||||
Prerelease editions of runtimes (Windsurf Next, Cursor Nightly, VS Code Insiders, Codex preview channels, etc.) read from a sibling config directory. Set the matching `*_CONFIG_DIR` env var before running the installer:
|
||||
Prerelease editions of runtimes (Windsurf Next / Devin Desktop Next, Cursor Nightly, VS Code Insiders, Codex preview channels, etc.) read from a sibling config directory. Set the matching `*_CONFIG_DIR` env var before running the installer:
|
||||
|
||||
```bash
|
||||
WINDSURF_CONFIG_DIR=~/.codeium/windsurf-next npx @opengsd/gsd-core@latest --windsurf --global
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
"windsurf": [
|
||||
"windsurf",
|
||||
"windsurf-cli",
|
||||
"windsurf-next"
|
||||
"windsurf-next",
|
||||
"devin-desktop"
|
||||
],
|
||||
"augment": [
|
||||
"augment",
|
||||
|
||||
@@ -23,7 +23,7 @@ const FALLBACK_ALIASES: Readonly<Record<string, string[]>> = {
|
||||
copilot: ['copilot', 'copilot-cli', 'github-copilot'],
|
||||
antigravity: ['antigravity', 'antigravity-cli', 'antigravity-agent'],
|
||||
cursor: ['cursor', 'cursor-cli', 'cursor-nightly'],
|
||||
windsurf: ['windsurf', 'windsurf-cli', 'windsurf-next'],
|
||||
windsurf: ['windsurf', 'windsurf-cli', 'windsurf-next', 'devin-desktop'],
|
||||
augment: ['augment', 'augment-code', 'augment-cli'],
|
||||
trae: ['trae', 'trae-cli'],
|
||||
qwen: ['qwen', 'qwen-code', 'qwen-cli'],
|
||||
|
||||
@@ -43,6 +43,7 @@ const {
|
||||
buildRuntimePromptText,
|
||||
resolveKiloConfigPath,
|
||||
configureKiloPermissions,
|
||||
selectRuntimesFromArgs,
|
||||
} = require('../bin/install.js');
|
||||
|
||||
const { getGlobalConfigDir } = require('../gsd-core/bin/lib/runtime-homes.cjs');
|
||||
@@ -835,6 +836,20 @@ describe('install — changeset CLI lands at scripts/changeset/cli.cjs (#935)',
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Section 6: Windsurf / devin-desktop alias (#792) ───────────────────────
|
||||
|
||||
describe('install — --devin-desktop CLI flag routes to windsurf runtime (#792)', () => {
|
||||
test('--devin-desktop resolves to ["windsurf"] via selectRuntimesFromArgs', () => {
|
||||
const runtimes = selectRuntimesFromArgs(['--devin-desktop']);
|
||||
assert.deepStrictEqual(runtimes, ['windsurf'],
|
||||
'--devin-desktop must resolve to ["windsurf"] via selectRuntimesFromArgs');
|
||||
});
|
||||
|
||||
test('--windsurf and --devin-desktop both resolve to ["windsurf"]', () => {
|
||||
assert.deepStrictEqual(selectRuntimesFromArgs(['--windsurf']), ['windsurf']);
|
||||
assert.deepStrictEqual(selectRuntimesFromArgs(['--devin-desktop']), ['windsurf']);
|
||||
});
|
||||
});
|
||||
// ─── Section N+1: #767 — disallowedTools injection for read-only agents ──────
|
||||
//
|
||||
// Verifies (installer-behavioral test — drives install() to a temp dir):
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
const { describe, test } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const path = require('node:path');
|
||||
const fs = require('node:fs');
|
||||
|
||||
const ROOT = path.join(__dirname, '..');
|
||||
const {
|
||||
@@ -17,4 +18,56 @@ describe('runtime-name-policy canonical runtime ids', () => {
|
||||
assert.strictEqual(resolveRuntimeNameFromCandidates('', null, 'kimi'), 'kimi');
|
||||
assert.strictEqual(canonicalizeRuntimeName('kimi-cli'), null);
|
||||
});
|
||||
|
||||
test('canonicalizes devin-desktop to windsurf (#792)', () => {
|
||||
assert.strictEqual(canonicalizeRuntimeName('devin-desktop'), 'windsurf');
|
||||
assert.strictEqual(canonicalizeRuntimeName('DEVIN-DESKTOP'), 'windsurf');
|
||||
assert.strictEqual(resolveRuntimeNameFromCandidates('devin-desktop'), 'windsurf');
|
||||
});
|
||||
});
|
||||
|
||||
describe('runtime-name-policy windsurf alias parity — manifest vs FALLBACK_ALIASES (#792)', () => {
|
||||
// DEFECT.GENERATIVE-FIX: manifest and FALLBACK_ALIASES are manually mirrored;
|
||||
// this test fails if they diverge for the windsurf key.
|
||||
const manifestPath = path.join(ROOT, 'gsd-core', 'bin', 'shared', 'runtime-aliases.manifest.json');
|
||||
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
||||
|
||||
test('manifest windsurf array includes devin-desktop', () => {
|
||||
assert.ok(
|
||||
Array.isArray(manifest.windsurf) && manifest.windsurf.includes('devin-desktop'),
|
||||
`runtime-aliases.manifest.json windsurf array must include 'devin-desktop'; got: ${JSON.stringify(manifest.windsurf)}`,
|
||||
);
|
||||
});
|
||||
|
||||
test('FALLBACK_ALIASES windsurf includes devin-desktop (via canonicalization round-trip)', () => {
|
||||
// The built module merges manifest over FALLBACK_ALIASES; if the manifest is present
|
||||
// this verifies the combined set. The manifest test above separately guards the manifest.
|
||||
// Here we verify the live canonicalizer sees devin-desktop -> windsurf.
|
||||
assert.strictEqual(
|
||||
canonicalizeRuntimeName('devin-desktop'),
|
||||
'windsurf',
|
||||
'devin-desktop must resolve to windsurf via alias lookup',
|
||||
);
|
||||
});
|
||||
|
||||
test('manifest and FALLBACK_ALIASES windsurf alias sets are identical', () => {
|
||||
// Read FALLBACK_ALIASES from source to detect manual drift before a build.
|
||||
const srcPath = path.join(ROOT, 'src', 'runtime-name-policy.cts');
|
||||
// allow-test-rule: runtime-contract-is-the-product — FALLBACK_ALIASES source text IS the
|
||||
// product contract for runtimes that can't load the manifest at runtime; verifying
|
||||
// both surfaces contain the same windsurf aliases catches manual-mirror drift.
|
||||
const src = fs.readFileSync(srcPath, 'utf8');
|
||||
const match = src.match(/windsurf:\s*\[([^\]]+)\]/);
|
||||
assert.ok(match, 'FALLBACK_ALIASES windsurf row must exist in src/runtime-name-policy.cts');
|
||||
const srcAliases = match[1]
|
||||
.split(',')
|
||||
.map(s => s.trim().replace(/^['"]|['"]$/g, ''))
|
||||
.filter(Boolean);
|
||||
const manifestAliases = [...manifest.windsurf].sort();
|
||||
assert.deepStrictEqual(
|
||||
[...srcAliases].sort(),
|
||||
manifestAliases,
|
||||
`FALLBACK_ALIASES windsurf=${JSON.stringify(srcAliases.sort())} must match manifest windsurf=${JSON.stringify(manifestAliases)}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user