diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..bb87206 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,174 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write # for GitHub Releases + id-token: write # for npm provenance (if enabled) + +jobs: + # ---------------------------------------------------------------------- + # Validate + # ---------------------------------------------------------------------- + validate: + name: Validate before release + runs-on: ubuntu-latest + timeout-minutes: 15 + outputs: + version: ${{ steps.version.outputs.version }} + channel: ${{ steps.version.outputs.channel }} + is_mandatory: ${{ steps.version.outputs.is_mandatory }} + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'pnpm' + + - run: pnpm install --frozen-lockfile + - run: pnpm typecheck + - run: pnpm test + - run: pnpm build + + - id: version + name: Parse version + channel from tag + run: | + TAG="${GITHUB_REF#refs/tags/}" + VERSION="${TAG#v}" + CHANNEL="stable" + IS_MANDATORY="false" + if [[ "$VERSION" == *-nightly.* ]]; then CHANNEL="nightly"; fi + if [[ "$VERSION" == *-beta.* ]]; then CHANNEL="beta"; fi + if [[ "$VERSION" == *+security.* ]]; then IS_MANDATORY="true"; fi + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "channel=$CHANNEL" >> $GITHUB_OUTPUT + echo "is_mandatory=$IS_MANDATORY" >> $GITHUB_OUTPUT + echo "Released as version=$VERSION channel=$CHANNEL mandatory=$IS_MANDATORY" + + # ---------------------------------------------------------------------- + # Publish CLI to npm + # ---------------------------------------------------------------------- + publish-cli: + name: Publish deepcode-cli to npm + needs: validate + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'pnpm' + registry-url: https://registry.npmjs.org + + - run: pnpm install --frozen-lockfile + - run: pnpm build + + - name: Set CLI version from tag + run: | + cd apps/cli + npm version "${{ needs.validate.outputs.version }}" --no-git-tag-version + + - name: Publish + run: | + cd apps/cli + # On beta/nightly, publish with --tag so default `latest` + # stays on stable. + if [ "${{ needs.validate.outputs.channel }}" = "stable" ]; then + pnpm publish --no-git-checks --access public + else + pnpm publish --no-git-checks --access public --tag ${{ needs.validate.outputs.channel }} + fi + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + # ---------------------------------------------------------------------- + # Build + sign Mac client (.dmg) + # ---------------------------------------------------------------------- + build-mac: + name: Build + sign + notarize Mac client + needs: validate + runs-on: macos-14 + if: false # Disabled until apps/desktop has actual Electron code (M6) + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + + - name: Set version + run: | + cd apps/desktop + npm version "${{ needs.validate.outputs.version }}" --no-git-tag-version + + - name: Build (electron-builder) + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + CSC_LINK: ${{ secrets.CSC_LINK }} + CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} + run: | + cd apps/desktop + pnpm electron-builder --mac --arm64 --x64 --publish never + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: mac-release + path: | + apps/desktop/release/*.dmg + apps/desktop/release/latest-mac.yml + + # ---------------------------------------------------------------------- + # GitHub Release + # ---------------------------------------------------------------------- + github-release: + name: Publish GitHub Release + needs: [validate, publish-cli] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + + - name: Mark mandatory in latest-mac.yml if applicable + if: needs.validate.outputs.is_mandatory == 'true' + run: | + echo "Note: this release tag has +security.X suffix — Mac client auto-update will be marked mandatory." + + - name: Generate release notes from PR labels + id: notes + run: | + # Lightweight: extract section between last tag and HEAD; group by label. + # Real implementation lands in scripts/gen-release-notes.ts (M9-ext). + PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + if [ -n "$PREV_TAG" ]; then + RANGE="$PREV_TAG..HEAD" + else + RANGE="HEAD" + fi + { + echo "## Changes" + git log --pretty=format:'- %s' $RANGE + } > release-notes.md + cat release-notes.md + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + name: ${{ needs.validate.outputs.version }} + body_path: release-notes.md + prerelease: ${{ needs.validate.outputs.channel != 'stable' }} + generate_release_notes: false + # files: omitted until M6 mac artifacts exist diff --git a/apps/cli/src/repl.ts b/apps/cli/src/repl.ts index 01126f2..8a75388 100644 --- a/apps/cli/src/repl.ts +++ b/apps/cli/src/repl.ts @@ -115,9 +115,12 @@ export async function startRepl(opts: ReplOpts): Promise { home: opts.home, maxBytes: (settings.memoryLoadCapKB ?? 100) * 1024, }); + // Locate built-in skills dir (packaged with @deepcode/core) + const builtinSkillsDir = await resolveBuiltinSkillsDir(); const skills = await loadSkills({ cwd, home: opts.home, + builtinDir: builtinSkillsDir, overrides: settings.skillOverrides, }); const styles = await loadOutputStyles({ cwd, home: opts.home }); @@ -317,3 +320,29 @@ function formatToolInput(input: Record): string { function truncate(s: string, n: number): string { return s.length > n ? s.slice(0, n) + '…' : s; } + +/** + * Find the bundled built-in skills directory. + * In dev: /packages/core/skills/. + * In published package: packaged inside @deepcode/core/skills/. + * Returns undefined if not found. + */ +async function resolveBuiltinSkillsDir(): Promise { + const { createRequire } = await import('node:module'); + const require_ = createRequire(import.meta.url); + try { + // Resolve any file inside the package, then walk up to find skills/ + const corePkg = require_.resolve('@deepcode/core/package.json'); + const path = await import('node:path'); + const fs = await import('node:fs/promises'); + const skillsDir = path.join(path.dirname(corePkg), 'skills'); + try { + await fs.access(skillsDir); + return skillsDir; + } catch { + return undefined; + } + } catch { + return undefined; + } +} diff --git a/docs/BEHAVIOR_PARITY.md b/docs/BEHAVIOR_PARITY.md new file mode 100644 index 0000000..12b25c9 --- /dev/null +++ b/docs/BEHAVIOR_PARITY.md @@ -0,0 +1,180 @@ +# Behavior Parity — DeepCode vs Claude Code + +> This document tracks where DeepCode's behavior **aligns with**, **deviates from**, or **deliberately enhances** Claude Code. It grows alongside the codebase. Last updated reflects what main contains. + +Legend: `✅` matches · `🟡` matches with caveats · `🔄` deferred · `⚠️` deliberately differs · `🆕` DeepCode-only addition + +--- + +## Slash commands (30+ in Claude Code, 14 shipped in DeepCode) + +| Command | Claude Code | DeepCode | Status | +| --------------------- | ----------- | -------------------------- | ------------------------------------------------------------------------------------------ | +| `/help` | ✓ | ✓ | ✅ | +| `/clear` | ✓ | ✓ | ✅ | +| `/exit` / `/quit` | ✓ | ✓ | ✅ | +| `/status` / `/doctor` | ✓ | ✓ | ✅ | +| `/model` | ✓ | ✓ | ✅ DeepCode constrains to deepseek-\* (model picker doesn't show foreign providers) | +| `/mode` | ✓ | ✓ | ✅ | +| `/effort` | ✓ | ✓ | 🟡 — UI selector deferred to GUI (M6); CLI works | +| `/cost` / `/usage` | ✓ | ✓ | ✅ | +| `/context` | ✓ | ✓ | ✅ | +| `/config` | ✓ | ✓ (read-only) | 🟡 — Claude Code's `/config` is interactive editor; ours is JSON dump (M3c-ext for editor) | +| `/resume` | ✓ | ✓ (list only) | 🟡 — Claude Code has fuzzy picker; ours lists; pick via `--resume ` | +| `/init` | ✓ | ✓ (stub) | 🔄 — multi-phase interactive flow deferred to M3c-ext | +| `/mcp` | ✓ | ✓ | ✅ | +| `/add-dir` | ✓ | ✓ (records intent) | 🟡 — M3 will enforce | +| `/todos` | ✓ | ✓ (stub) | 🔄 — wired with TodoWrite tool (M3+) | +| `/compact` | ✓ | ✓ auto-trigger | 🟡 — manual `/compact` slash command not exposed yet (auto works via agent loop) | +| `/btw` | ✓ | ✗ | 🔄 | +| `/recap` | ✓ | ✗ | 🔄 | +| `/rewind` | ✓ | ✗ | 🔄 M7 | +| `/voice` | ✓ | ✗ | 🔄 M8 | +| `/teleport` | ✓ | ✗ | 🔄 M8 | +| `/desktop` | ✓ | ✗ | 🔄 M6 | +| `/background` | ✓ | ✗ | 🔄 (paired with TaskCreate M3.15.3) | +| `/batch` | ✓ | ✗ | 🔄 | +| `/tasks` | ✓ | ✗ | 🔄 | +| `/plan` | ✓ | ✗ | 🔄 — set via `/mode plan` in DeepCode | +| `/login` / `/logout` | ✓ | ✗ | 🔄 — DeepCode currently uses re-onboarding (clear creds + restart) | +| `/export` | ✓ | ✗ | 🔄 | +| `/bug` | ✓ | ✗ | 🔄 | +| `/upgrade` | ✓ | ✓ (hint only) | 🟡 | +| `/pr_comments` | ✓ | ✗ | 🔄 | +| `/review` | ✓ | ✗ (skill avail) | 🟡 — via Skill tool | +| `/security-review` | ✓ | ✗ (skill avail) | 🟡 — via Skill tool | +| `/schedule` | ✓ | ✗ (skill avail) | 🟡 | +| `/loop` | ✓ | ✗ (skill avail) | 🟡 | +| `/terminal-setup` | ✓ | ✗ | 🔄 | +| `/vim` | ✓ | ✗ | 🔄 M8 | +| `/agents` | ✓ | ✗ (read .deepcode/agents/) | 🔄 | +| `/hooks` | ✓ | ✗ | 🔄 | +| `/skills` | ✓ | ✗ | 🔄 | +| `/permissions` | ✓ | ✗ | 🔄 | +| `/privacy-settings` | ✓ | ✗ | 🔄 | +| `/migrate-installer` | ✓ | ✗ | 🔄 | +| `/release-notes` | ✓ | ✗ | 🔄 | + +--- + +## Settings.json fields + +Tracked in `packages/core/src/config/types.ts`. Roughly 50 fields total; most are stubbed (schema-known but not actively consumed). M2 loads + merges all of them. Subsystems consume as they ship. + +Specific deviations: + +- ⚠️ `model` enum: only `deepseek-chat` / `deepseek-reasoner` / `deepseek-v4-flash` / `deepseek-v4-pro` (DeepSeek constraint). Aliases align. +- 🆕 `update.*` for Mac client auto-update via electron-updater (Claude Code has its own equivalent). +- 🟡 `managed/MDM policy` layer: explicit non-goal v1 per §0.2 — schema reserved. + +## Hook events + +| Event | Claude Code | DeepCode | Status | +| ---------------- | ----------- | -------- | -------------------------------------------- | +| PreToolUse | ✓ | ✓ | ✅ | +| PostToolUse | ✓ | ✓ | ✅ | +| Stop | ✓ | ✓ | ✅ — fires when agent loop ends (any reason) | +| SubagentStop | ✓ | 🔄 | M4+ wiring | +| PreCompact | ✓ | ✓ | ✅ — fires through compaction event bus | +| PostCompact | ✓ | ✓ | ✅ | +| SessionStart | ✓ | ✓ | ✅ | +| SessionEnd | ✓ | ✓ | ✅ | +| UserPromptSubmit | ✓ | ✓ | ✅ | +| Notification | ✓ | 🔄 | M8 | + +## Hook handler types + +| Type | Claude Code | DeepCode | Status | +| ---------- | ----------- | -------- | ----------------------------------------------------------------------- | +| `command` | ✓ | ✓ | ✅ — JSON-on-stdin contract, JSON-on-stdout decoded | +| `http` | ✓ | ✓ | ✅ — fetch POST, response.text → stdout; `allowedHttpHookUrls` enforced | +| `prompt` | ✓ | ✓ | ✅ — synthesizes additionalContext (no exec) | +| `mcp_tool` | ✓ | 🔄 stub | M5+ | +| `agent` | ✓ | 🔄 stub | M4+ | +| `if` field | ✓ | ✓ | ✅ permission-rule syntax filter | + +## Modes + +| Mode | Claude Code | DeepCode | Status | +| --------------------- | ----------- | -------- | --------------------------------------- | +| default | ✓ | ✓ | ✅ | +| acceptEdits | ✓ | ✓ | ✅ | +| plan | ✓ | ✓ | ✅ | +| auto (LLM classifier) | ✓ | 🔄 | falls back to default behavior; M3c-ext | +| dontAsk | ✓ | ✓ | ✅ | +| bypassPermissions | ✓ | ✓ | ✅ sandbox still enforces | + +## Memory system + +- ✅ `CLAUDE.md` ↔ `DEEPCODE.md` (different filename, same semantics) +- ✅ `~/.claude/CLAUDE.md` ↔ `~/.deepcode/DEEPCODE.md` +- ✅ Hierarchical walk cwd → root +- ✅ `@-import` recursion (≤ 4 hops, cycle detection) +- ✅ `AGENTS.md` auto-import (cross-tool interop) +- ✅ `.deepcode/rules/*.md` (path-scoped frontmatter deferred to M4) +- 🔄 Auto-memory (`~/.deepcode/projects//memory/`) — schema defined, agent-side writes M4+ + +## MCP + +- ✅ stdio transport +- ✅ list_tools + call_tool with `mcp____` qualification +- ✅ `/mcp` slash + auto-connect from settings + per-server enabled/disabled +- 🔄 http / sse transports (M3c-ext) +- 🔄 OAuth (M3c-ext) +- 🔄 headersHelper (M3c-ext) +- 🔄 Elicitation hooks (M5+) +- 🔄 `deepcode mcp serve` (reverse exposure) — M5+ +- 🔄 MCP resources via `@server:proto://path` (M3c-ext) + +## Tools + +| Tool | Claude Code | DeepCode | Status | +| ------------------------------------------------------------------------------ | ----------- | -------- | ------------------------------------------- | +| Read | ✓ | ✓ | ✅ | +| Write | ✓ | ✓ | ✅ | +| Edit | ✓ | ✓ | ✅ | +| Bash | ✓ | ✓ | ✅ + M3.5 sandbox wrap | +| Grep | ✓ | ✓ | ✅ via ripgrep | +| Glob | ✓ | ✓ | ✅ via fs.glob | +| Skill | ✓ | ✓ | ✅ M5 | +| Task (subagents) | ✓ | 🔄 | M4 sub-agent files load; agent dispatch M4+ | +| NotebookEdit | ✓ | 🔄 | M8 | +| AskUserQuestion | ✓ | 🔄 | M3c+ | +| ExitPlanMode | ✓ | 🔄 | enforced via /mode | +| EnterWorktree / ExitWorktree | ✓ | 🔄 | M8 | +| ToolSearch (deferred load) | ✓ | 🔄 | M3c+ | +| TaskCreate / Monitor / TaskList / TaskGet / TaskOutput / TaskStop / TaskUpdate | ✓ | 🔄 | M8 (background tasks) | +| CronCreate / CronList / CronDelete | ✓ | 🔄 | M8 (cron daemon) | +| ScheduleWakeup | ✓ | 🔄 | M8 | +| WebFetch | ✓ | 🔄 | M3c+ | +| WebSearch | ✓ | 🔄 | M3c+ | +| TodoWrite | ✓ | 🔄 | M3c+ | + +## CLI flags + +| Flag | Status | +| ---------------------------------------------------------------------------- | ------------------------------- | +| `--help` / `--version` | ✅ | +| `--mode` / `--permission-mode` | ✅ | +| `--model` / `--effort` | ✅ | +| `--max-turns` | ✅ | +| `--system-prompt` / `--append-system-prompt[-file]` | ✅ | +| `--allowedTools` / `--disallowedTools` | ✅ | +| `--bare` | 🔄 (parsed, semantics deferred) | +| `--settings` / `--agents` / `--mcp-config` / `--plugin-dir` / `--plugin-url` | 🔄 (parsed only) | +| `--no-plugins` / `--strict` | 🔄 (parsed only) | +| `-p` headless | 🔄 M8 | +| `--output-format` / `--json-schema` / `--include-partial-messages` | 🔄 M8 | +| `--resume ` / `--continue` / `--fork-session` | 🔄 M3c+ | + +## What DeepCode adds that Claude Code doesn't have (yet) + +| Feature | Note | +| ----------------- | ------------------------------------------------------------------------------------------------------------ | +| `sandbox.*` field | macOS sandbox-exec + Linux bwrap wrapping for Bash tool, opt-in | +| `update.*` field | electron-updater integration with GitHub Releases for Mac client (Claude Code's update is upstream-specific) | +| Cat-shaped icon | (...what) | + +--- + +_This document will be kept current as each PR lands. M9 release pipeline includes a check that fails CI if a new public behavior isn't documented here._ diff --git a/packages/core/package.json b/packages/core/package.json index 18bc585..1090c58 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -15,6 +15,7 @@ }, "files": [ "dist/", + "skills/", "README.md" ], "scripts": { diff --git a/packages/core/scripts/effort-bench.ts b/packages/core/scripts/effort-bench.ts new file mode 100644 index 0000000..11428f3 --- /dev/null +++ b/packages/core/scripts/effort-bench.ts @@ -0,0 +1,179 @@ +#!/usr/bin/env node +// effort-bench — measure DeepSeek API actual response under each effort tier. +// Spec: docs/design/effort-levels.md §6 +// +// Usage: +// DEEPSEEK_API_KEY=sk-... pnpm -F @deepcode/core tsx scripts/effort-bench.ts +// +// Output: +// - stdout: human summary table +// - docs/design/effort-levels-measured.csv (next to the design doc) +// +// Each scenario × each effort tier runs once. NOTE: this burns real API tokens — +// estimated ~¥0.5 per full sweep. Reads credentials from ~/.deepcode/credentials.json +// or DEEPSEEK_API_KEY env var. + +import { promises as fs } from 'node:fs'; +import { homedir } from 'node:os'; +import { join } from 'node:path'; +import { DeepSeekProvider, EFFORT_PARAMS, type Effort } from '../src/index.js'; + +interface Scenario { + name: string; + description: string; + model: 'deepseek-chat' | 'deepseek-reasoner'; + prompt: string; + systemPrompt?: string; +} + +const SCENARIOS: Scenario[] = [ + { + name: 'simple-fix', + description: 'Quick targeted bug-fix scenario', + model: 'deepseek-chat', + prompt: + 'I have a TypeScript file `src/foo.ts` with a typo "calue" — what one-line fix do I apply?', + }, + { + name: 'medium-refactor', + description: 'Mid-sized refactoring scenario', + model: 'deepseek-chat', + prompt: + 'Sketch the steps to extract retry+backoff logic from src/http-client.ts into a reusable src/retry.ts (with TS types).', + }, + { + name: 'complex-reasoning', + description: 'Multi-step reasoning scenario', + model: 'deepseek-reasoner', + prompt: + 'Walk me through migrating a Prisma schema to drizzle: outline the steps, the edge cases, and what could go wrong.', + }, +]; + +const EFFORTS: Effort[] = ['low', 'medium', 'high', 'xhigh', 'max']; + +interface BenchRow { + scenario: string; + model: string; + effort: Effort; + maxTokens: number; + temperature: number; + durationMs: number; + inputTokens: number; + outputTokens: number; + reasoningTokens: number; + finishReason: string; + costYuan: number; +} + +async function resolveKey(): Promise { + if (process.env.DEEPSEEK_API_KEY) return process.env.DEEPSEEK_API_KEY; + try { + const raw = await fs.readFile(join(homedir(), '.deepcode', 'credentials.json'), 'utf8'); + const parsed = JSON.parse(raw) as { apiKey?: string }; + if (parsed.apiKey) return parsed.apiKey; + } catch { + /* fall through */ + } + throw new Error( + 'No DEEPSEEK_API_KEY env var or ~/.deepcode/credentials.json — set one before running effort-bench', + ); +} + +function calcCostYuan( + model: string, + usage: { inputTokens: number; outputTokens: number; reasoningTokens: number }, +): number { + const isReasoner = model.includes('reasoner'); + const inputRate = 1.0; // ¥/M + const outputRate = isReasoner ? 16.0 : 2.0; + const reasoningRate = isReasoner ? 4.0 : 0; + return ( + (usage.inputTokens / 1e6) * inputRate + + (usage.outputTokens / 1e6) * outputRate + + (usage.reasoningTokens / 1e6) * reasoningRate + ); +} + +async function runOne(provider: DeepSeekProvider, sc: Scenario, effort: Effort): Promise { + const params = EFFORT_PARAMS[effort]; + const t0 = Date.now(); + const result = await provider.runTurn({ + model: sc.model, + systemPrompt: sc.systemPrompt ?? 'You are DeepCode, a coding assistant. Be concise.', + tools: [], + messages: [{ role: 'user', content: [{ type: 'text', text: sc.prompt }] }], + maxTokens: params.maxTokens, + temperature: params.temperature, + }); + const dt = Date.now() - t0; + return { + scenario: sc.name, + model: sc.model, + effort, + maxTokens: params.maxTokens, + temperature: params.temperature, + durationMs: dt, + inputTokens: result.usage.inputTokens, + outputTokens: result.usage.outputTokens, + reasoningTokens: result.usage.reasoningTokens, + finishReason: result.stopReason, + costYuan: calcCostYuan(sc.model, result.usage), + }; +} + +async function main(): Promise { + const apiKey = await resolveKey(); + const provider = new DeepSeekProvider({ apiKey }); + + const rows: BenchRow[] = []; + console.log('Running effort-bench across scenarios × effort tiers...\n'); + + for (const sc of SCENARIOS) { + console.log(`▸ ${sc.name} (${sc.model})`); + for (const eff of EFFORTS) { + process.stdout.write(` ${eff.padEnd(7)} `); + try { + const row = await runOne(provider, sc, eff); + rows.push(row); + process.stdout.write( + `· ${row.durationMs.toString().padStart(5)}ms · in=${row.inputTokens} out=${row.outputTokens} reasoning=${row.reasoningTokens} · ¥${row.costYuan.toFixed(4)}\n`, + ); + } catch (err) { + process.stdout.write(`· FAILED: ${(err as Error).message}\n`); + } + } + console.log(''); + } + + // CSV output + const header = + 'scenario,model,effort,maxTokens,temperature,durationMs,inputTokens,outputTokens,reasoningTokens,finishReason,costYuan'; + const lines = [header]; + for (const r of rows) { + lines.push( + [ + r.scenario, + r.model, + r.effort, + r.maxTokens, + r.temperature, + r.durationMs, + r.inputTokens, + r.outputTokens, + r.reasoningTokens, + r.finishReason, + r.costYuan.toFixed(6), + ].join(','), + ); + } + // Write CSV next to the design doc + const outPath = '../../docs/design/effort-levels-measured.csv'; + await fs.writeFile(outPath, lines.join('\n') + '\n', 'utf8'); + console.log(`\nWrote ${outPath} (${rows.length} rows)`); +} + +main().catch((err) => { + console.error('effort-bench failed:', err); + process.exit(1); +}); diff --git a/packages/core/skills/code-review/SKILL.md b/packages/core/skills/code-review/SKILL.md new file mode 100644 index 0000000..76a5257 --- /dev/null +++ b/packages/core/skills/code-review/SKILL.md @@ -0,0 +1,12 @@ +--- +name: code-review +description: Review the current diff for correctness bugs. Cite file:line. +--- + +# code-review + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/consolidate-memory/SKILL.md b/packages/core/skills/consolidate-memory/SKILL.md new file mode 100644 index 0000000..54c4c63 --- /dev/null +++ b/packages/core/skills/consolidate-memory/SKILL.md @@ -0,0 +1,12 @@ +--- +name: consolidate-memory +description: Walk ~/.deepcode/memory/, merge duplicates, prune the index. +--- + +# consolidate-memory + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/deepseek-api/SKILL.md b/packages/core/skills/deepseek-api/SKILL.md new file mode 100644 index 0000000..fa67145 --- /dev/null +++ b/packages/core/skills/deepseek-api/SKILL.md @@ -0,0 +1,12 @@ +--- +name: deepseek-api +description: Help build/debug DeepSeek API usage (openai-compatible). +--- + +# deepseek-api + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/fewer-permission-prompts/SKILL.md b/packages/core/skills/fewer-permission-prompts/SKILL.md new file mode 100644 index 0000000..dbf4317 --- /dev/null +++ b/packages/core/skills/fewer-permission-prompts/SKILL.md @@ -0,0 +1,12 @@ +--- +name: fewer-permission-prompts +description: Scan transcripts, propose .deepcode/settings.json allow rules. +--- + +# fewer-permission-prompts + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/init/SKILL.md b/packages/core/skills/init/SKILL.md new file mode 100644 index 0000000..2364830 --- /dev/null +++ b/packages/core/skills/init/SKILL.md @@ -0,0 +1,12 @@ +--- +name: init +description: Generate a starter DEEPCODE.md after exploring the codebase. +--- + +# init + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/keybindings-help/SKILL.md b/packages/core/skills/keybindings-help/SKILL.md new file mode 100644 index 0000000..f3cf07f --- /dev/null +++ b/packages/core/skills/keybindings-help/SKILL.md @@ -0,0 +1,12 @@ +--- +name: keybindings-help +description: Help edit ~/.deepcode/keybindings.json. +--- + +# keybindings-help + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/loop/SKILL.md b/packages/core/skills/loop/SKILL.md new file mode 100644 index 0000000..9486f3b --- /dev/null +++ b/packages/core/skills/loop/SKILL.md @@ -0,0 +1,12 @@ +--- +name: loop +description: Run a command on a recurring interval (poll CI etc.). +--- + +# loop + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/pdf/SKILL.md b/packages/core/skills/pdf/SKILL.md new file mode 100644 index 0000000..d7e70d1 --- /dev/null +++ b/packages/core/skills/pdf/SKILL.md @@ -0,0 +1,12 @@ +--- +name: pdf +description: Read/extract/combine/split PDFs. +--- + +# pdf + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/review/SKILL.md b/packages/core/skills/review/SKILL.md new file mode 100644 index 0000000..38a0afa --- /dev/null +++ b/packages/core/skills/review/SKILL.md @@ -0,0 +1,12 @@ +--- +name: review +description: Review the current PR (uses gh CLI). +--- + +# review + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/run/SKILL.md b/packages/core/skills/run/SKILL.md new file mode 100644 index 0000000..2f86cb6 --- /dev/null +++ b/packages/core/skills/run/SKILL.md @@ -0,0 +1,12 @@ +--- +name: run +description: Launch this project's app to see a change in action. +--- + +# run + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/schedule/SKILL.md b/packages/core/skills/schedule/SKILL.md new file mode 100644 index 0000000..7d61d7a --- /dev/null +++ b/packages/core/skills/schedule/SKILL.md @@ -0,0 +1,12 @@ +--- +name: schedule +description: Schedule a one-off or cron task via DeepCode's daemon. +--- + +# schedule + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/security-review/SKILL.md b/packages/core/skills/security-review/SKILL.md new file mode 100644 index 0000000..78c929e --- /dev/null +++ b/packages/core/skills/security-review/SKILL.md @@ -0,0 +1,12 @@ +--- +name: security-review +description: Review pending changes for security issues (secrets, injections, SSRF, auth). +--- + +# security-review + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/skill-creator/SKILL.md b/packages/core/skills/skill-creator/SKILL.md new file mode 100644 index 0000000..128b995 --- /dev/null +++ b/packages/core/skills/skill-creator/SKILL.md @@ -0,0 +1,12 @@ +--- +name: skill-creator +description: Help author a new skill — frontmatter + body + best-trigger description. +--- + +# skill-creator + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/update-config/SKILL.md b/packages/core/skills/update-config/SKILL.md new file mode 100644 index 0000000..2095a42 --- /dev/null +++ b/packages/core/skills/update-config/SKILL.md @@ -0,0 +1,12 @@ +--- +name: update-config +description: Modify settings.json / hooks / permissions safely + explain trade-offs. +--- + +# update-config + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description. diff --git a/packages/core/skills/verify/SKILL.md b/packages/core/skills/verify/SKILL.md new file mode 100644 index 0000000..9daf8e4 --- /dev/null +++ b/packages/core/skills/verify/SKILL.md @@ -0,0 +1,12 @@ +--- +name: verify +description: Run the app + tests + confirm the change actually works (not just unit-tests-green). +--- + +# verify + +(M4 baseline — body authored as quick guidance; can be expanded by the user via `/skill edit` or directly editing this file.) + +## When to invoke + +The agent should invoke this skill when the user request matches the description.