devworkspace 0.3.0 → 0.3.2
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/CHANGELOG.md +42 -1
- package/README.md +8 -5
- package/dist/agents/claude/adapter.d.ts +3 -14
- package/dist/agents/claude/adapter.js +46 -49
- package/dist/agents/claude/adapter.js.map +1 -1
- package/dist/agents/codex/adapter.d.ts +2 -0
- package/dist/agents/codex/adapter.js +61 -0
- package/dist/agents/codex/adapter.js.map +1 -0
- package/dist/agents/copilot/adapter.d.ts +2 -0
- package/dist/agents/copilot/adapter.js +62 -0
- package/dist/agents/copilot/adapter.js.map +1 -0
- package/dist/agents/cursor/adapter.d.ts +2 -0
- package/dist/agents/cursor/adapter.js +127 -0
- package/dist/agents/cursor/adapter.js.map +1 -0
- package/dist/agents/index.d.ts +15 -0
- package/dist/agents/index.js +54 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/shared.d.ts +20 -0
- package/dist/agents/shared.js +76 -0
- package/dist/agents/shared.js.map +1 -0
- package/dist/agents/types.d.ts +16 -1
- package/dist/agents/types.js.map +1 -1
- package/dist/cli/args.d.ts +42 -0
- package/dist/cli/args.js +12 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/help.js +64 -10
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/render.d.ts +12 -1
- package/dist/cli/render.js +188 -0
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/run.js +100 -9
- package/dist/cli/run.js.map +1 -1
- package/dist/config/schemas.d.ts +6 -0
- package/dist/config/schemas.js +6 -0
- package/dist/config/schemas.js.map +1 -1
- package/dist/core/version.d.ts +7 -0
- package/dist/core/version.js +13 -0
- package/dist/core/version.js.map +1 -1
- package/dist/core/workspace.d.ts +1 -0
- package/dist/core/workspace.js +1 -0
- package/dist/core/workspace.js.map +1 -1
- package/dist/discovery/commands.d.ts +1 -0
- package/dist/discovery/commands.js +3 -1
- package/dist/discovery/commands.js.map +1 -1
- package/dist/features/schema.d.ts +3 -0
- package/dist/features/schema.js +79 -0
- package/dist/features/schema.js.map +1 -0
- package/dist/features/types.d.ts +77 -0
- package/dist/features/types.js +2 -0
- package/dist/features/types.js.map +1 -0
- package/dist/features/validate.d.ts +14 -0
- package/dist/features/validate.js +124 -0
- package/dist/features/validate.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/claudePlugin.d.ts +12 -0
- package/dist/integrations/adapters/claudePlugin.js +37 -8
- package/dist/integrations/adapters/claudePlugin.js.map +1 -1
- package/dist/integrations/adapters/pluginSkill.js +5 -0
- package/dist/integrations/adapters/pluginSkill.js.map +1 -1
- package/dist/security/files.js +10 -2
- package/dist/security/files.js.map +1 -1
- package/dist/security/redact.js +1 -1
- package/dist/security/redact.js.map +1 -1
- package/dist/services/agent.d.ts +12 -2
- package/dist/services/agent.js +96 -14
- package/dist/services/agent.js.map +1 -1
- package/dist/services/analysis.js +3 -3
- package/dist/services/analysis.js.map +1 -1
- package/dist/services/doctor.js +65 -14
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/drift.d.ts +21 -0
- package/dist/services/drift.js +89 -0
- package/dist/services/drift.js.map +1 -0
- package/dist/services/features.d.ts +22 -0
- package/dist/services/features.js +105 -0
- package/dist/services/features.js.map +1 -0
- package/dist/services/graph.d.ts +97 -0
- package/dist/services/graph.js +342 -0
- package/dist/services/graph.js.map +1 -0
- package/dist/services/refresh.js +15 -0
- package/dist/services/refresh.js.map +1 -1
- package/dist/services/reset.js +45 -5
- package/dist/services/reset.js.map +1 -1
- package/dist/services/setup.d.ts +56 -0
- package/dist/services/setup.js +116 -0
- package/dist/services/setup.js.map +1 -0
- package/dist/services/status.d.ts +8 -0
- package/dist/services/status.js +78 -10
- package/dist/services/status.js.map +1 -1
- package/dist/services/tasks.js +6 -1
- package/dist/services/tasks.js.map +1 -1
- package/dist/services/verify.d.ts +11 -0
- package/dist/services/verify.js +64 -2
- package/dist/services/verify.js.map +1 -1
- package/dist/tasks/routing.js +14 -10
- package/dist/tasks/routing.js.map +1 -1
- package/dist/tasks/task.js +6 -2
- package/dist/tasks/task.js.map +1 -1
- package/dist/verification/scope.js +1 -1
- package/dist/verification/scope.js.map +1 -1
- package/docs/agents.md +60 -0
- package/docs/architecture-report/01-executive-summary.md +168 -0
- package/docs/architecture-report/02-system-architecture.md +356 -0
- package/docs/architecture-report/03-tools-and-technologies.md +112 -0
- package/docs/architecture-report/04-execution-flows.md +257 -0
- package/docs/architecture-report/05-codebase-map.md +150 -0
- package/docs/architecture-report/06-command-reference.md +446 -0
- package/docs/architecture-report/07-data-flow-and-integrations.md +268 -0
- package/docs/architecture-report/08-build-test-deployment.md +185 -0
- package/docs/architecture-report/09-security-and-reliability.md +165 -0
- package/docs/architecture-report/10-feature-status.md +110 -0
- package/docs/architecture-report/11-glossary.md +97 -0
- package/docs/architecture-report/README.md +103 -0
- package/docs/architecture-report/diagrams.md +446 -0
- package/docs/architecture.md +2 -2
- package/docs/getting-started.md +38 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes are documented here. This project follows [Semantic Versioning](https://semver.org/). Workspace schema changes are called out under **Breaking**.
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [0.3.2] - 2026-11-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Single-Command Repository Setup (`devworkspace setup`)**:
|
|
9
|
+
- One-command onboarding workflow inspecting project structure, initializing `.devworkspace/`, discovering verification contracts, checking integration status, and validating overall health.
|
|
10
|
+
- Automatically verifies command contracts against real package manifests and execution directories (`cwd`), reporting drift before task execution.
|
|
11
|
+
- Safe and idempotent; preserves existing project UUID, user overrides, and custom commands across repeated executions.
|
|
12
|
+
- **Feature-Level Knowledge Map & Verification (`devworkspace feature`)**:
|
|
13
|
+
- Introduced typed, backward-compatible feature schema in `.devworkspace/context/features.json` connecting frontend entry points, API routes, backend services, database models, and unit tests.
|
|
14
|
+
- Added `devworkspace feature list`, `devworkspace feature show <id>`, `devworkspace feature add`, and `devworkspace feature validate`.
|
|
15
|
+
- Feature validator inspects real repository files and code symbols on disk, distinguishing verified facts from inferred entries and flagging broken references.
|
|
16
|
+
- **Bounded Graphify Knowledge Graph Tracing (`devworkspace graph`)**:
|
|
17
|
+
- Added `devworkspace graph status` and `devworkspace graph trace [--from <node|path>] [--depth <n>]` supporting Graphify's output format (`graphify-out/graph.json`).
|
|
18
|
+
- Traversal is bounded by BFS depth limits with cycle protection and edge deduplication.
|
|
19
|
+
- Verifies graph nodes against real repository files and code symbols, tagging unverified nodes or references as hypotheses (`[hypothesis]`).
|
|
20
|
+
- **Verification Integrity & Contract Drift Prevention**:
|
|
21
|
+
- Prevents vacuous test passes: detects zero-test executions (`0 passed, 0 failed`) and flags them as unverified rather than false successes.
|
|
22
|
+
- Reports command-contract drift in `devworkspace doctor` when configured checks reference missing npm scripts or non-existent working directories.
|
|
23
|
+
- **CLI Provenance & Version Diagnostics**:
|
|
24
|
+
- Reports exact CLI version, executable path, and execution mode (`source-checkout`, `installed-package`, `npx-cache`) in `setup` and `doctor`.
|
|
25
|
+
- **Agent-Agnostic Architecture & Multi-Agent Compatibility**:
|
|
26
|
+
- Introduced typed `AgentAdapter` interface and shared section-merging engine in `src/agents/` to decouple DevWorkspace from Claude-specific assumptions.
|
|
27
|
+
- Implemented typed adapters for **Claude Code** (`claude`), **OpenAI Codex / open agent standard** (`codex` / `agents` via `AGENTS.md`), **Cursor** (`cursor` via modern `.cursor/rules/devworkspace.mdc` and legacy `.cursorrules`), and **GitHub Copilot** (`copilot` via `.github/copilot-instructions.md`).
|
|
28
|
+
- Added `devworkspace agent install [--agent claude|codex|cursor|copilot|all]` with support for multi-agent installation (`--agent all`), conflict detection, and CRLF preservation.
|
|
29
|
+
- Added `devworkspace agent list` to inspect installed status, detected files, and capabilities (instructions, skills, plugins, CLI) for each supported coding agent.
|
|
30
|
+
- Decoupled `doctor` and `status` readiness checks from Claude Code; projects using Cursor, Copilot, or Codex achieve `Core workspace: READY` and verify instruction freshness against their configured agent.
|
|
31
|
+
- Enhanced `resetWorkspace({ includeAgentFiles: true })` to cleanly purge managed DevWorkspace blocks and files across all agent integrations while strictly preserving user content outside the managed sections.
|
|
32
|
+
- Updated verification scoping (`NOT_CODE`) to recognize `.cursor/` and `.github/` instruction and rule files (`.mdc`, `.md`) as non-code documents.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## [0.3.1] - 2026-10-14
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- **Installed Claude plugins were reported as NOT_INSTALLED** (Agent Skills, Ponytail) by `status --deep`, `integrations status` and `setup`. Real `claude plugin list --json` output is pretty-printed over many lines, and the 0.3.0 parser kept only a line starting with `[`, which was just `[`. The whole output is now parsed as JSON (a banner before the array is tolerated). Empty, malformed or unexpected output (not an array of plugins with `id`, `scope` and `enabled`) is an error, never an empty list.
|
|
39
|
+
- **A plugin listed at several scopes** is now reported by its enabled entry instead of whichever came first.
|
|
40
|
+
- **Path containment in `safeReadText()`**: Repository text reads now strictly enforce root containment, preventing relative path traversals (`..`), sibling-prefix escapes (`/repo-other` vs `/repo`), out-of-root absolute paths, and ancestor symlink escapes. Sensitive files remain protected across relative and resolved canonical paths.
|
|
41
|
+
- **Read-only task intent and completion enforcement**: Requests with explicit negative constraints (`no-fix`, `no-modify`, `plan-only`, such as "investigate without fixing") now consistently set `readOnly: true`, skip inapplicable verification command requirements, and block task completion at the task gate if files were modified during the task. Keyword routing precedence between release preparation, documentation, and defect types (like memory leaks) has been clarified.
|
|
42
|
+
- **Secret redaction pattern**: Updated Google API key detector regex to match variable 38–40 character lengths (`AIza` prefix with 34–36 characters) without false positives on adjacent identifiers.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
- When the plugin list cannot be read and the installed Claude Code supports `plugin list --json`, `setup` now stops with an explanation and installs nothing. Before, it fell back to installing portable skills through `npx`, so a parse failure alone could trigger an install. Older Claude Code versions still use the portable-skills fallback.
|
|
46
|
+
- `scripts/release-check.mjs`: Production source hygiene scanner distinguishes testing domain regex patterns containing `stub` from genuine unfinished implementation markers.
|
|
6
47
|
|
|
7
48
|
## [0.3.0] - 2026-10-13
|
|
8
49
|
|
package/README.md
CHANGED
|
@@ -91,21 +91,24 @@ devworkspace doctor # check workspace, integrations, security, portabilit
|
|
|
91
91
|
| Command | Purpose |
|
|
92
92
|
| --- | --- |
|
|
93
93
|
| `init` | Create `.devworkspace/` (idempotent, never touches source) |
|
|
94
|
-
| `setup
|
|
94
|
+
| `setup` | One-command setup: initialize workspace, discover commands, verify diagnostics, optionally install integrations (`--integrations`) |
|
|
95
95
|
| `integrations` | `status` (observed, never assumed) and `repair` |
|
|
96
96
|
| `analyze` | Deterministic discovery; writes `discovery.json`, testing contract, onboarding prompt |
|
|
97
|
-
| `agent install` | Add
|
|
97
|
+
| `agent install` | Add managed instruction blocks for your coding agent (`--agent claude\|codex\|cursor\|copilot\|all`) |
|
|
98
|
+
| `agent list` | Show supported and detected coding agent integrations and their capabilities |
|
|
98
99
|
| `status` | Concise overview, read-only (`--deep` also runs the integration health checks; `--json` for tooling) |
|
|
99
100
|
| `doctor` | Health, security and portability checks (`--fix`, `--strict`, `--json`) |
|
|
100
101
|
| `refresh` | Incremental staleness check; writes a refresh prompt when AI re-validation is needed |
|
|
101
102
|
| `context` | Show stored knowledge (`--topic` filters facts and the testing contract; safety rules are always shown; `--full`) |
|
|
102
103
|
| `fact` | `add` / `verify` / `remove` / `list` project knowledge with provenance |
|
|
104
|
+
| `feature` | `list` / `show` / `validate` / `add` feature-level map connecting frontend, backend, database and tests |
|
|
105
|
+
| `graph` | `status` and `trace` bounded knowledge-graph navigation with node and edge verification |
|
|
103
106
|
| `task` | `new` / `list` / `show` / `status` / `update` / `run` / `verify` / `tests` / `attest` with a package-aware completion gate |
|
|
104
107
|
| `testenv` | `declare` / `list` / `revoke` a test environment so database-touching checks may run (local, never committed) |
|
|
105
108
|
| `decision` | Append-only, human-readable decision records |
|
|
106
109
|
| `session` | Save short session summaries (never transcripts) |
|
|
107
110
|
| `export` / `import` | Move portable knowledge between machines safely |
|
|
108
|
-
| `reset` | Delete `.devworkspace/` to start fresh (`--yes` to confirm, `--include-agent-files` to also remove
|
|
111
|
+
| `reset` | Delete `.devworkspace/` to start fresh (`--yes` to confirm, `--include-agent-files` to also remove managed agent instruction blocks/skills) |
|
|
109
112
|
| `migrate` | Upgrade workspace files to the current schema, with backups |
|
|
110
113
|
|
|
111
114
|
Global flags: `--json`, `--cwd <dir>`, `--dry-run` (where it applies), `--debug`, `--no-color`, `--ascii`.
|
|
@@ -127,7 +130,7 @@ Details: [docs/security.md](docs/security.md).
|
|
|
127
130
|
|
|
128
131
|
## Limitations (V1)
|
|
129
132
|
|
|
130
|
-
- Claude Code
|
|
133
|
+
- Multi-agent support includes typed adapters for Claude Code, OpenAI Codex (`AGENTS.md`), Cursor (`.cursor/rules` and `.cursorrules`), and GitHub Copilot (`.github/copilot-instructions.md`).
|
|
131
134
|
- Integration setup needs prerequisites (Python 3.10+ or uv for Graphify; the Claude Code CLI for native plugins, otherwise portable skills with fewer capabilities) and sometimes your approval. It was not run end to end against GitHub on macOS/Linux; see the verification notes in [docs/integrations.md](docs/integrations.md).
|
|
132
135
|
- DevWorkspace does not build Graphify's graph (that uses the model) or uninstall anything.
|
|
133
136
|
- Deep analysis is not attempted for any language; discovery covers manifests, structure and commands for Node, Python, Go, Rust, Java and PHP projects.
|
|
@@ -136,7 +139,7 @@ Details: [docs/security.md](docs/security.md).
|
|
|
136
139
|
|
|
137
140
|
## Documentation
|
|
138
141
|
|
|
139
|
-
[Getting started](docs/getting-started.md) · [Architecture](docs/architecture.md) · [Knowledge model](docs/knowledge.md) · [Testing contract](docs/testing.md) · [Security & privacy](docs/security.md) · [Integrations](docs/integrations.md) · [Claude](docs/claude.md) · [Routing](docs/routing.md) · [Portability](docs/portability.md) · [Benchmarking](docs/benchmarking.md) · [Troubleshooting](docs/troubleshooting.md) · [Contributing](docs/contributing.md)
|
|
142
|
+
[Getting started](docs/getting-started.md) · [Architecture](docs/architecture.md) · [Agents](docs/agents.md) · [Knowledge model](docs/knowledge.md) · [Testing contract](docs/testing.md) · [Security & privacy](docs/security.md) · [Integrations](docs/integrations.md) · [Claude](docs/claude.md) · [Routing](docs/routing.md) · [Portability](docs/portability.md) · [Benchmarking](docs/benchmarking.md) · [Troubleshooting](docs/troubleshooting.md) · [Contributing](docs/contributing.md)
|
|
140
143
|
|
|
141
144
|
## License
|
|
142
145
|
|
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
import type { AgentAdapter
|
|
2
|
-
import { SECTION_END, SECTION_START } from '
|
|
3
|
-
/** Merge the managed block into existing instructions, preserving everything the user wrote. */
|
|
4
|
-
export declare function mergeSection(existing: string | null, block: string, prefix?: string): {
|
|
5
|
-
content: string;
|
|
6
|
-
kind: PlannedChange['kind'];
|
|
7
|
-
note: string;
|
|
8
|
-
};
|
|
1
|
+
import type { AgentAdapter } from '../types.js';
|
|
2
|
+
import { SECTION_END, SECTION_START, SECTION_RE, mergeSection, removeManagedSection } from '../shared.js';
|
|
9
3
|
export declare const claudeAdapter: AgentAdapter;
|
|
10
|
-
|
|
11
|
-
export declare function removeManagedSection(text: string): {
|
|
12
|
-
content: string;
|
|
13
|
-
empty: boolean;
|
|
14
|
-
} | null;
|
|
15
|
-
export { SECTION_START, SECTION_END };
|
|
4
|
+
export { mergeSection, removeManagedSection, SECTION_START, SECTION_END, SECTION_RE };
|
|
@@ -1,46 +1,17 @@
|
|
|
1
|
-
import { promises as fs } from 'node:fs';
|
|
2
1
|
import path from 'node:path';
|
|
3
2
|
import { pathExists } from '../../utils/fs.js';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return text.includes('\r\n') ? '\r\n' : '\n';
|
|
8
|
-
}
|
|
9
|
-
function withEol(text, eol) {
|
|
10
|
-
return text.replace(/\r\n/g, '\n').replace(/\n/g, eol);
|
|
11
|
-
}
|
|
12
|
-
async function readIfExists(file) {
|
|
13
|
-
try {
|
|
14
|
-
return await fs.readFile(file, 'utf8');
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
/** Merge the managed block into existing instructions, preserving everything the user wrote. */
|
|
21
|
-
export function mergeSection(existing, block, prefix = '') {
|
|
22
|
-
if (existing === null) {
|
|
23
|
-
return { content: `${prefix}${block}\n`, kind: 'create', note: 'create with managed section' };
|
|
24
|
-
}
|
|
25
|
-
const eol = detectEol(existing);
|
|
26
|
-
const blockEol = withEol(block, eol);
|
|
27
|
-
const hasStart = existing.includes('<!-- devworkspace:start');
|
|
28
|
-
const hasEnd = existing.includes(SECTION_END);
|
|
29
|
-
if (hasStart !== hasEnd) {
|
|
30
|
-
return { content: existing, kind: 'conflict', note: 'managed section markers are unbalanced; fix or remove the stray marker by hand' };
|
|
31
|
-
}
|
|
32
|
-
if (hasStart && hasEnd) {
|
|
33
|
-
const next = existing.replace(SECTION_RE, () => blockEol);
|
|
34
|
-
return next === existing
|
|
35
|
-
? { content: existing, kind: 'unchanged', note: 'managed section already current' }
|
|
36
|
-
: { content: next, kind: 'update', note: 'refresh managed section; content outside it is untouched' };
|
|
37
|
-
}
|
|
38
|
-
const sep = existing.endsWith('\n') ? eol : eol + eol;
|
|
39
|
-
return { content: `${existing}${sep}${blockEol}${eol}`, kind: 'update', note: 'append managed section; existing instructions preserved' };
|
|
40
|
-
}
|
|
3
|
+
import { which } from '../../utils/proc.js';
|
|
4
|
+
import { SECTION_END, SECTION_START, SECTION_RE, detectEol, withEol, readIfExists, mergeSection, removeManagedSection, } from '../shared.js';
|
|
5
|
+
import { SKILL_MARKER, SKILL_PATH, claudeSection, claudeSkill } from './content.js';
|
|
41
6
|
export const claudeAdapter = {
|
|
42
7
|
id: 'claude',
|
|
43
8
|
displayName: 'Claude Code',
|
|
9
|
+
capabilities: {
|
|
10
|
+
instructions: true,
|
|
11
|
+
skills: true,
|
|
12
|
+
plugins: true,
|
|
13
|
+
cli: true,
|
|
14
|
+
},
|
|
44
15
|
async detectExisting(root) {
|
|
45
16
|
const found = [];
|
|
46
17
|
for (const rel of ['CLAUDE.md', '.claude/CLAUDE.md', 'CLAUDE.local.md', 'AGENTS.md']) {
|
|
@@ -49,6 +20,11 @@ export const claudeAdapter = {
|
|
|
49
20
|
}
|
|
50
21
|
return found;
|
|
51
22
|
},
|
|
23
|
+
async detectAvailable(root) {
|
|
24
|
+
if (await which('claude'))
|
|
25
|
+
return true;
|
|
26
|
+
return pathExists(path.join(root, '.claude'));
|
|
27
|
+
},
|
|
52
28
|
async plan(ctx) {
|
|
53
29
|
const changes = [];
|
|
54
30
|
const root = ctx.root;
|
|
@@ -92,16 +68,37 @@ export const claudeAdapter = {
|
|
|
92
68
|
}
|
|
93
69
|
return changes;
|
|
94
70
|
},
|
|
71
|
+
async unplan(root) {
|
|
72
|
+
const changes = [];
|
|
73
|
+
for (const rel of ['CLAUDE.md', '.claude/CLAUDE.md']) {
|
|
74
|
+
const full = path.join(root, ...rel.split('/'));
|
|
75
|
+
const text = await readIfExists(full);
|
|
76
|
+
if (text === null)
|
|
77
|
+
continue;
|
|
78
|
+
const removed = removeManagedSection(text);
|
|
79
|
+
if (!removed)
|
|
80
|
+
continue;
|
|
81
|
+
changes.push({
|
|
82
|
+
path: rel,
|
|
83
|
+
kind: 'update',
|
|
84
|
+
mode: 'section',
|
|
85
|
+
content: removed.content,
|
|
86
|
+
note: removed.empty ? 'delete file (contained only DevWorkspace block)' : 'remove managed DevWorkspace block',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const skillAbs = path.join(root, ...SKILL_PATH.split('/'));
|
|
90
|
+
const skillText = await readIfExists(skillAbs);
|
|
91
|
+
if (skillText !== null && skillText.includes(SKILL_MARKER)) {
|
|
92
|
+
changes.push({
|
|
93
|
+
path: SKILL_PATH,
|
|
94
|
+
kind: 'update',
|
|
95
|
+
mode: 'owned',
|
|
96
|
+
content: '',
|
|
97
|
+
note: 'delete DevWorkspace skill',
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return changes;
|
|
101
|
+
},
|
|
95
102
|
};
|
|
96
|
-
|
|
97
|
-
export function removeManagedSection(text) {
|
|
98
|
-
if (!SECTION_RE.test(text))
|
|
99
|
-
return null;
|
|
100
|
-
const eol = detectEol(text);
|
|
101
|
-
const blank = eol === '\r\n' ? '(?:\\r\\n){3,}' : '\\n{3,}';
|
|
102
|
-
const next = text.replace(SECTION_RE, '').replace(new RegExp(blank, 'g'), eol + eol);
|
|
103
|
-
const trimmed = next.trim();
|
|
104
|
-
return { content: trimmed === '' ? '' : trimmed + eol, empty: trimmed === '' };
|
|
105
|
-
}
|
|
106
|
-
export { SECTION_START, SECTION_END };
|
|
103
|
+
export { mergeSection, removeManagedSection, SECTION_START, SECTION_END, SECTION_RE };
|
|
107
104
|
//# sourceMappingURL=adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/agents/claude/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { AgentAdapter, AgentContext, PlannedChange } from '../types.js';\nimport { pathExists } from '../../utils/fs.js';\nimport { SECTION_END, SECTION_START, SKILL_MARKER, SKILL_PATH, claudeSection, claudeSkill } from './content.js';\n\nconst SECTION_RE = /<!-- devworkspace:start[^>]*-->[\\s\\S]*?<!-- devworkspace:end -->/;\n\nfunction detectEol(text: string): '\\r\\n' | '\\n' {\n return text.includes('\\r\\n') ? '\\r\\n' : '\\n';\n}\n\nfunction withEol(text: string, eol: '\\r\\n' | '\\n'): string {\n return text.replace(/\\r\\n/g, '\\n').replace(/\\n/g, eol);\n}\n\nasync function readIfExists(file: string): Promise<string | null> {\n try {\n return await fs.readFile(file, 'utf8');\n } catch {\n return null;\n }\n}\n\n/** Merge the managed block into existing instructions, preserving everything the user wrote. */\nexport function mergeSection(existing: string | null, block: string, prefix = ''): { content: string; kind: PlannedChange['kind']; note: string } {\n if (existing === null) {\n return { content: `${prefix}${block}\\n`, kind: 'create', note: 'create with managed section' };\n }\n const eol = detectEol(existing);\n const blockEol = withEol(block, eol);\n const hasStart = existing.includes('<!-- devworkspace:start');\n const hasEnd = existing.includes(SECTION_END);\n if (hasStart !== hasEnd) {\n return { content: existing, kind: 'conflict', note: 'managed section markers are unbalanced; fix or remove the stray marker by hand' };\n }\n if (hasStart && hasEnd) {\n const next = existing.replace(SECTION_RE, () => blockEol);\n return next === existing\n ? { content: existing, kind: 'unchanged', note: 'managed section already current' }\n : { content: next, kind: 'update', note: 'refresh managed section; content outside it is untouched' };\n }\n const sep = existing.endsWith('\\n') ? eol : eol + eol;\n return { content: `${existing}${sep}${blockEol}${eol}`, kind: 'update', note: 'append managed section; existing instructions preserved' };\n}\n\nexport const claudeAdapter: AgentAdapter = {\n id: 'claude',\n displayName: 'Claude Code',\n\n async detectExisting(root: string): Promise<string[]> {\n const found: string[] = [];\n for (const rel of ['CLAUDE.md', '.claude/CLAUDE.md', 'CLAUDE.local.md', 'AGENTS.md']) {\n if (await pathExists(path.join(root, ...rel.split('/')))) found.push(rel);\n }\n return found;\n },\n\n async plan(ctx: AgentContext): Promise<PlannedChange[]> {\n const changes: PlannedChange[] = [];\n const root = ctx.root;\n const rootClaude = path.join(root, 'CLAUDE.md');\n const dotClaude = path.join(root, '.claude', 'CLAUDE.md');\n const rootText = await readIfExists(rootClaude);\n const dotText = await readIfExists(dotClaude);\n const hasAgents = await pathExists(path.join(root, 'AGENTS.md'));\n\n // Prefer the file the project already uses. Claude Code reads AGENTS.md only when no CLAUDE.md exists,\n // so a new CLAUDE.md must import it or the existing instructions would silently stop loading.\n let target = 'CLAUDE.md';\n let text = rootText;\n if (rootText === null && dotText !== null) {\n target = '.claude/CLAUDE.md';\n text = dotText;\n }\n const prefix = text === null && hasAgents ? '@AGENTS.md\\n\\n' : '';\n const merged = mergeSection(text, claudeSection(ctx.projectName), prefix);\n changes.push({\n path: target,\n kind: merged.kind,\n mode: 'section',\n content: merged.content,\n note: merged.note + (prefix ? ' (imports existing AGENTS.md)' : ''),\n });\n\n const skillAbs = path.join(root, ...SKILL_PATH.split('/'));\n const skillExisting = await readIfExists(skillAbs);\n const eol = skillExisting ? detectEol(skillExisting) : '\\n';\n const skill = withEol(claudeSkill(), eol);\n if (skillExisting === null) {\n changes.push({ path: SKILL_PATH, kind: 'create', mode: 'owned', content: skill, note: 'create DevWorkspace skill' });\n } else if (!skillExisting.includes(SKILL_MARKER)) {\n changes.push({ path: SKILL_PATH, kind: 'conflict', mode: 'owned', content: skillExisting, note: 'a user-authored skill already uses this path; left untouched' });\n } else if (skillExisting === skill) {\n changes.push({ path: SKILL_PATH, kind: 'unchanged', mode: 'owned', content: skill, note: 'skill already current' });\n } else {\n changes.push({ path: SKILL_PATH, kind: 'update', mode: 'owned', content: skill, note: 'refresh DevWorkspace skill' });\n }\n return changes;\n },\n};\n\n/** Remove the managed block (and nothing else). Returns null if there is no balanced block. */\nexport function removeManagedSection(text: string): { content: string; empty: boolean } | null {\n if (!SECTION_RE.test(text)) return null;\n const eol = detectEol(text);\n const blank = eol === '\\r\\n' ? '(?:\\\\r\\\\n){3,}' : '\\\\n{3,}';\n const next = text.replace(SECTION_RE, '').replace(new RegExp(blank, 'g'), eol + eol);\n const trimmed = next.trim();\n return { content: trimmed === '' ? '' : trimmed + eol, empty: trimmed === '' };\n}\n\nexport { SECTION_START, SECTION_END };\n"]}
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/agents/claude/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport type { AgentAdapter, AgentContext, PlannedChange } from '../types.js';\nimport { pathExists } from '../../utils/fs.js';\nimport { which } from '../../utils/proc.js';\nimport {\n SECTION_END,\n SECTION_START,\n SECTION_RE,\n detectEol,\n withEol,\n readIfExists,\n mergeSection,\n removeManagedSection,\n} from '../shared.js';\nimport { SKILL_MARKER, SKILL_PATH, claudeSection, claudeSkill } from './content.js';\n\nexport const claudeAdapter: AgentAdapter = {\n id: 'claude',\n displayName: 'Claude Code',\n capabilities: {\n instructions: true,\n skills: true,\n plugins: true,\n cli: true,\n },\n\n async detectExisting(root: string): Promise<string[]> {\n const found: string[] = [];\n for (const rel of ['CLAUDE.md', '.claude/CLAUDE.md', 'CLAUDE.local.md', 'AGENTS.md']) {\n if (await pathExists(path.join(root, ...rel.split('/')))) found.push(rel);\n }\n return found;\n },\n\n async detectAvailable(root: string): Promise<boolean> {\n if (await which('claude')) return true;\n return pathExists(path.join(root, '.claude'));\n },\n\n async plan(ctx: AgentContext): Promise<PlannedChange[]> {\n const changes: PlannedChange[] = [];\n const root = ctx.root;\n const rootClaude = path.join(root, 'CLAUDE.md');\n const dotClaude = path.join(root, '.claude', 'CLAUDE.md');\n const rootText = await readIfExists(rootClaude);\n const dotText = await readIfExists(dotClaude);\n const hasAgents = await pathExists(path.join(root, 'AGENTS.md'));\n\n // Prefer the file the project already uses. Claude Code reads AGENTS.md only when no CLAUDE.md exists,\n // so a new CLAUDE.md must import it or the existing instructions would silently stop loading.\n let target = 'CLAUDE.md';\n let text = rootText;\n if (rootText === null && dotText !== null) {\n target = '.claude/CLAUDE.md';\n text = dotText;\n }\n const prefix = text === null && hasAgents ? '@AGENTS.md\\n\\n' : '';\n const merged = mergeSection(text, claudeSection(ctx.projectName), prefix);\n changes.push({\n path: target,\n kind: merged.kind,\n mode: 'section',\n content: merged.content,\n note: merged.note + (prefix ? ' (imports existing AGENTS.md)' : ''),\n });\n\n const skillAbs = path.join(root, ...SKILL_PATH.split('/'));\n const skillExisting = await readIfExists(skillAbs);\n const eol = skillExisting ? detectEol(skillExisting) : '\\n';\n const skill = withEol(claudeSkill(), eol);\n if (skillExisting === null) {\n changes.push({ path: SKILL_PATH, kind: 'create', mode: 'owned', content: skill, note: 'create DevWorkspace skill' });\n } else if (!skillExisting.includes(SKILL_MARKER)) {\n changes.push({ path: SKILL_PATH, kind: 'conflict', mode: 'owned', content: skillExisting, note: 'a user-authored skill already uses this path; left untouched' });\n } else if (skillExisting === skill) {\n changes.push({ path: SKILL_PATH, kind: 'unchanged', mode: 'owned', content: skill, note: 'skill already current' });\n } else {\n changes.push({ path: SKILL_PATH, kind: 'update', mode: 'owned', content: skill, note: 'refresh DevWorkspace skill' });\n }\n return changes;\n },\n\n async unplan(root: string): Promise<PlannedChange[]> {\n const changes: PlannedChange[] = [];\n for (const rel of ['CLAUDE.md', '.claude/CLAUDE.md']) {\n const full = path.join(root, ...rel.split('/'));\n const text = await readIfExists(full);\n if (text === null) continue;\n const removed = removeManagedSection(text);\n if (!removed) continue;\n changes.push({\n path: rel,\n kind: 'update',\n mode: 'section',\n content: removed.content,\n note: removed.empty ? 'delete file (contained only DevWorkspace block)' : 'remove managed DevWorkspace block',\n });\n }\n const skillAbs = path.join(root, ...SKILL_PATH.split('/'));\n const skillText = await readIfExists(skillAbs);\n if (skillText !== null && skillText.includes(SKILL_MARKER)) {\n changes.push({\n path: SKILL_PATH,\n kind: 'update',\n mode: 'owned',\n content: '',\n note: 'delete DevWorkspace skill',\n });\n }\n return changes;\n },\n};\n\nexport { mergeSection, removeManagedSection, SECTION_START, SECTION_END, SECTION_RE };\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { pathExists } from '../../utils/fs.js';
|
|
3
|
+
import { which } from '../../utils/proc.js';
|
|
4
|
+
import { buildDevWorkspaceSection, mergeSection, readIfExists, removeManagedSection, } from '../shared.js';
|
|
5
|
+
export const codexAdapter = {
|
|
6
|
+
id: 'codex',
|
|
7
|
+
displayName: 'OpenAI Codex / AGENTS.md',
|
|
8
|
+
capabilities: {
|
|
9
|
+
instructions: true,
|
|
10
|
+
skills: false,
|
|
11
|
+
plugins: false,
|
|
12
|
+
cli: false,
|
|
13
|
+
},
|
|
14
|
+
async detectExisting(root) {
|
|
15
|
+
const found = [];
|
|
16
|
+
if (await pathExists(path.join(root, 'AGENTS.md')))
|
|
17
|
+
found.push('AGENTS.md');
|
|
18
|
+
return found;
|
|
19
|
+
},
|
|
20
|
+
async detectAvailable(root) {
|
|
21
|
+
if (await pathExists(path.join(root, 'AGENTS.md')))
|
|
22
|
+
return true;
|
|
23
|
+
return (await which('codex')) !== null;
|
|
24
|
+
},
|
|
25
|
+
async plan(ctx) {
|
|
26
|
+
const target = 'AGENTS.md';
|
|
27
|
+
const full = path.join(ctx.root, target);
|
|
28
|
+
const existing = await readIfExists(full);
|
|
29
|
+
const block = buildDevWorkspaceSection(ctx.projectName, 'OpenAI Codex / AGENTS.md');
|
|
30
|
+
const merged = mergeSection(existing, block);
|
|
31
|
+
return [
|
|
32
|
+
{
|
|
33
|
+
path: target,
|
|
34
|
+
kind: merged.kind,
|
|
35
|
+
mode: 'section',
|
|
36
|
+
content: merged.content,
|
|
37
|
+
note: merged.note,
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
},
|
|
41
|
+
async unplan(root) {
|
|
42
|
+
const target = 'AGENTS.md';
|
|
43
|
+
const full = path.join(root, target);
|
|
44
|
+
const text = await readIfExists(full);
|
|
45
|
+
if (text === null)
|
|
46
|
+
return [];
|
|
47
|
+
const removed = removeManagedSection(text);
|
|
48
|
+
if (!removed)
|
|
49
|
+
return [];
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
path: target,
|
|
53
|
+
kind: 'update',
|
|
54
|
+
mode: 'section',
|
|
55
|
+
content: removed.content,
|
|
56
|
+
note: removed.empty ? 'delete file (contained only DevWorkspace block)' : 'remove managed DevWorkspace block',
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/agents/codex/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,YAAY,EACZ,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAEtB,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,EAAE,EAAE,OAAO;IACX,WAAW,EAAE,0BAA0B;IACvC,YAAY,EAAE;QACZ,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,KAAK;QACd,GAAG,EAAE,KAAK;KACX;IAED,KAAK,CAAC,cAAc,CAAC,IAAY;QAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,IAAY;QAChC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAChE,OAAO,CAAC,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAiB;QAC1B,MAAM,MAAM,GAAG,WAAW,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,wBAAwB,CAAC,GAAG,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAC;QACpF,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAE7C,OAAO;YACL;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;aAClB;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,MAAM,GAAG,WAAW,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAExB,OAAO;YACL;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,iDAAiD,CAAC,CAAC,CAAC,mCAAmC;aAC9G;SACF,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["import path from 'node:path';\nimport type { AgentAdapter, AgentContext, PlannedChange } from '../types.js';\nimport { pathExists } from '../../utils/fs.js';\nimport { which } from '../../utils/proc.js';\nimport {\n buildDevWorkspaceSection,\n mergeSection,\n readIfExists,\n removeManagedSection,\n} from '../shared.js';\n\nexport const codexAdapter: AgentAdapter = {\n id: 'codex',\n displayName: 'OpenAI Codex / AGENTS.md',\n capabilities: {\n instructions: true,\n skills: false,\n plugins: false,\n cli: false,\n },\n\n async detectExisting(root: string): Promise<string[]> {\n const found: string[] = [];\n if (await pathExists(path.join(root, 'AGENTS.md'))) found.push('AGENTS.md');\n return found;\n },\n\n async detectAvailable(root: string): Promise<boolean> {\n if (await pathExists(path.join(root, 'AGENTS.md'))) return true;\n return (await which('codex')) !== null;\n },\n\n async plan(ctx: AgentContext): Promise<PlannedChange[]> {\n const target = 'AGENTS.md';\n const full = path.join(ctx.root, target);\n const existing = await readIfExists(full);\n const block = buildDevWorkspaceSection(ctx.projectName, 'OpenAI Codex / AGENTS.md');\n const merged = mergeSection(existing, block);\n\n return [\n {\n path: target,\n kind: merged.kind,\n mode: 'section',\n content: merged.content,\n note: merged.note,\n },\n ];\n },\n\n async unplan(root: string): Promise<PlannedChange[]> {\n const target = 'AGENTS.md';\n const full = path.join(root, target);\n const text = await readIfExists(full);\n if (text === null) return [];\n const removed = removeManagedSection(text);\n if (!removed) return [];\n\n return [\n {\n path: target,\n kind: 'update',\n mode: 'section',\n content: removed.content,\n note: removed.empty ? 'delete file (contained only DevWorkspace block)' : 'remove managed DevWorkspace block',\n },\n ];\n },\n};\n\n"]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { pathExists } from '../../utils/fs.js';
|
|
3
|
+
import { which } from '../../utils/proc.js';
|
|
4
|
+
import { buildDevWorkspaceSection, mergeSection, readIfExists, removeManagedSection, } from '../shared.js';
|
|
5
|
+
const COPILOT_PATH = '.github/copilot-instructions.md';
|
|
6
|
+
export const copilotAdapter = {
|
|
7
|
+
id: 'copilot',
|
|
8
|
+
displayName: 'GitHub Copilot',
|
|
9
|
+
capabilities: {
|
|
10
|
+
instructions: true,
|
|
11
|
+
skills: false,
|
|
12
|
+
plugins: false,
|
|
13
|
+
cli: false,
|
|
14
|
+
},
|
|
15
|
+
async detectExisting(root) {
|
|
16
|
+
const found = [];
|
|
17
|
+
if (await pathExists(path.join(root, ...COPILOT_PATH.split('/'))))
|
|
18
|
+
found.push(COPILOT_PATH);
|
|
19
|
+
return found;
|
|
20
|
+
},
|
|
21
|
+
async detectAvailable(root) {
|
|
22
|
+
if (await pathExists(path.join(root, ...COPILOT_PATH.split('/'))))
|
|
23
|
+
return true;
|
|
24
|
+
if (await pathExists(path.join(root, '.github')))
|
|
25
|
+
return true;
|
|
26
|
+
return (await which('gh')) !== null;
|
|
27
|
+
},
|
|
28
|
+
async plan(ctx) {
|
|
29
|
+
const full = path.join(ctx.root, ...COPILOT_PATH.split('/'));
|
|
30
|
+
const existing = await readIfExists(full);
|
|
31
|
+
const block = buildDevWorkspaceSection(ctx.projectName, 'GitHub Copilot');
|
|
32
|
+
const merged = mergeSection(existing, block);
|
|
33
|
+
return [
|
|
34
|
+
{
|
|
35
|
+
path: COPILOT_PATH,
|
|
36
|
+
kind: merged.kind,
|
|
37
|
+
mode: 'section',
|
|
38
|
+
content: merged.content,
|
|
39
|
+
note: `${merged.note} (${COPILOT_PATH})`,
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
},
|
|
43
|
+
async unplan(root) {
|
|
44
|
+
const full = path.join(root, ...COPILOT_PATH.split('/'));
|
|
45
|
+
const text = await readIfExists(full);
|
|
46
|
+
if (text === null)
|
|
47
|
+
return [];
|
|
48
|
+
const removed = removeManagedSection(text);
|
|
49
|
+
if (!removed)
|
|
50
|
+
return [];
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
path: COPILOT_PATH,
|
|
54
|
+
kind: 'update',
|
|
55
|
+
mode: 'section',
|
|
56
|
+
content: removed.content,
|
|
57
|
+
note: removed.empty ? 'delete file (contained only DevWorkspace block)' : 'remove managed DevWorkspace block',
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/agents/copilot/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,YAAY,EACZ,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAEtB,MAAM,YAAY,GAAG,iCAAiC,CAAC;AAEvD,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,EAAE,EAAE,SAAS;IACb,WAAW,EAAE,gBAAgB;IAC7B,YAAY,EAAE;QACZ,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,KAAK;QACd,GAAG,EAAE,KAAK;KACX;IAED,KAAK,CAAC,cAAc,CAAC,IAAY;QAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5F,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,IAAY;QAChC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/E,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9D,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAiB;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,wBAAwB,CAAC,GAAG,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAE7C,OAAO;YACL;gBACE,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,KAAK,YAAY,GAAG;aACzC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAExB,OAAO;YACL;gBACE,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,iDAAiD,CAAC,CAAC,CAAC,mCAAmC;aAC9G;SACF,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["import path from 'node:path';\nimport type { AgentAdapter, AgentContext, PlannedChange } from '../types.js';\nimport { pathExists } from '../../utils/fs.js';\nimport { which } from '../../utils/proc.js';\nimport {\n buildDevWorkspaceSection,\n mergeSection,\n readIfExists,\n removeManagedSection,\n} from '../shared.js';\n\nconst COPILOT_PATH = '.github/copilot-instructions.md';\n\nexport const copilotAdapter: AgentAdapter = {\n id: 'copilot',\n displayName: 'GitHub Copilot',\n capabilities: {\n instructions: true,\n skills: false,\n plugins: false,\n cli: false,\n },\n\n async detectExisting(root: string): Promise<string[]> {\n const found: string[] = [];\n if (await pathExists(path.join(root, ...COPILOT_PATH.split('/')))) found.push(COPILOT_PATH);\n return found;\n },\n\n async detectAvailable(root: string): Promise<boolean> {\n if (await pathExists(path.join(root, ...COPILOT_PATH.split('/')))) return true;\n if (await pathExists(path.join(root, '.github'))) return true;\n return (await which('gh')) !== null;\n },\n\n async plan(ctx: AgentContext): Promise<PlannedChange[]> {\n const full = path.join(ctx.root, ...COPILOT_PATH.split('/'));\n const existing = await readIfExists(full);\n const block = buildDevWorkspaceSection(ctx.projectName, 'GitHub Copilot');\n const merged = mergeSection(existing, block);\n\n return [\n {\n path: COPILOT_PATH,\n kind: merged.kind,\n mode: 'section',\n content: merged.content,\n note: `${merged.note} (${COPILOT_PATH})`,\n },\n ];\n },\n\n async unplan(root: string): Promise<PlannedChange[]> {\n const full = path.join(root, ...COPILOT_PATH.split('/'));\n const text = await readIfExists(full);\n if (text === null) return [];\n const removed = removeManagedSection(text);\n if (!removed) return [];\n\n return [\n {\n path: COPILOT_PATH,\n kind: 'update',\n mode: 'section',\n content: removed.content,\n note: removed.empty ? 'delete file (contained only DevWorkspace block)' : 'remove managed DevWorkspace block',\n },\n ];\n },\n};\n\n"]}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { pathExists } from '../../utils/fs.js';
|
|
3
|
+
import { which } from '../../utils/proc.js';
|
|
4
|
+
import { buildDevWorkspaceSection, mergeSection, readIfExists, removeManagedSection, } from '../shared.js';
|
|
5
|
+
const CURSOR_MDC_PATH = '.cursor/rules/devworkspace.mdc';
|
|
6
|
+
export const cursorAdapter = {
|
|
7
|
+
id: 'cursor',
|
|
8
|
+
displayName: 'Cursor',
|
|
9
|
+
capabilities: {
|
|
10
|
+
instructions: true,
|
|
11
|
+
skills: false,
|
|
12
|
+
plugins: false,
|
|
13
|
+
cli: false,
|
|
14
|
+
},
|
|
15
|
+
async detectExisting(root) {
|
|
16
|
+
const found = [];
|
|
17
|
+
if (await pathExists(path.join(root, '.cursorrules')))
|
|
18
|
+
found.push('.cursorrules');
|
|
19
|
+
if (await pathExists(path.join(root, ...CURSOR_MDC_PATH.split('/'))))
|
|
20
|
+
found.push(CURSOR_MDC_PATH);
|
|
21
|
+
if (await pathExists(path.join(root, '.cursor', 'rules')))
|
|
22
|
+
found.push('.cursor/rules');
|
|
23
|
+
return found;
|
|
24
|
+
},
|
|
25
|
+
async detectAvailable(root) {
|
|
26
|
+
if (await pathExists(path.join(root, '.cursor')))
|
|
27
|
+
return true;
|
|
28
|
+
if (await pathExists(path.join(root, '.cursorrules')))
|
|
29
|
+
return true;
|
|
30
|
+
return (await which('cursor')) !== null;
|
|
31
|
+
},
|
|
32
|
+
async plan(ctx) {
|
|
33
|
+
const root = ctx.root;
|
|
34
|
+
const legacyRulesPath = path.join(root, '.cursorrules');
|
|
35
|
+
const hasLegacy = await pathExists(legacyRulesPath);
|
|
36
|
+
if (hasLegacy) {
|
|
37
|
+
// User or project has existing .cursorrules; merge the managed block into it
|
|
38
|
+
const existing = await readIfExists(legacyRulesPath);
|
|
39
|
+
const block = buildDevWorkspaceSection(ctx.projectName, 'Cursor');
|
|
40
|
+
const merged = mergeSection(existing, block);
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
path: '.cursorrules',
|
|
44
|
+
kind: merged.kind,
|
|
45
|
+
mode: 'section',
|
|
46
|
+
content: merged.content,
|
|
47
|
+
note: `${merged.note} (.cursorrules)`,
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
// Modern Cursor rule format (.cursor/rules/devworkspace.mdc)
|
|
52
|
+
const mdcFull = path.join(root, ...CURSOR_MDC_PATH.split('/'));
|
|
53
|
+
const existingMdc = await readIfExists(mdcFull);
|
|
54
|
+
const mdcFrontmatter = [
|
|
55
|
+
'---',
|
|
56
|
+
'description: DevWorkspace development workflow, context, and verification rules',
|
|
57
|
+
'alwaysApply: true',
|
|
58
|
+
'---',
|
|
59
|
+
'',
|
|
60
|
+
].join('\n');
|
|
61
|
+
const block = buildDevWorkspaceSection(ctx.projectName, 'Cursor');
|
|
62
|
+
const fullContent = `${mdcFrontmatter}${block}\n`;
|
|
63
|
+
if (existingMdc === null) {
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
path: CURSOR_MDC_PATH,
|
|
67
|
+
kind: 'create',
|
|
68
|
+
mode: 'owned',
|
|
69
|
+
content: fullContent,
|
|
70
|
+
note: 'create Cursor rule in .cursor/rules/devworkspace.mdc',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
if (existingMdc === fullContent) {
|
|
75
|
+
return [
|
|
76
|
+
{
|
|
77
|
+
path: CURSOR_MDC_PATH,
|
|
78
|
+
kind: 'unchanged',
|
|
79
|
+
mode: 'owned',
|
|
80
|
+
content: fullContent,
|
|
81
|
+
note: 'Cursor rule already current',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
// If existing MDC has custom user content outside devworkspace section, merge into it
|
|
86
|
+
const merged = mergeSection(existingMdc, block);
|
|
87
|
+
return [
|
|
88
|
+
{
|
|
89
|
+
path: CURSOR_MDC_PATH,
|
|
90
|
+
kind: merged.kind,
|
|
91
|
+
mode: 'owned',
|
|
92
|
+
content: merged.content,
|
|
93
|
+
note: `${merged.note} (.cursor/rules/devworkspace.mdc)`,
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
},
|
|
97
|
+
async unplan(root) {
|
|
98
|
+
const changes = [];
|
|
99
|
+
const legacyPath = path.join(root, '.cursorrules');
|
|
100
|
+
const legacyText = await readIfExists(legacyPath);
|
|
101
|
+
if (legacyText !== null) {
|
|
102
|
+
const removed = removeManagedSection(legacyText);
|
|
103
|
+
if (removed) {
|
|
104
|
+
changes.push({
|
|
105
|
+
path: '.cursorrules',
|
|
106
|
+
kind: 'update',
|
|
107
|
+
mode: 'section',
|
|
108
|
+
content: removed.content,
|
|
109
|
+
note: removed.empty ? 'delete file (contained only DevWorkspace block)' : 'remove managed DevWorkspace block',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const mdcPath = path.join(root, ...CURSOR_MDC_PATH.split('/'));
|
|
114
|
+
const mdcText = await readIfExists(mdcPath);
|
|
115
|
+
if (mdcText !== null && mdcText.includes('devworkspace:start')) {
|
|
116
|
+
changes.push({
|
|
117
|
+
path: CURSOR_MDC_PATH,
|
|
118
|
+
kind: 'update',
|
|
119
|
+
mode: 'owned',
|
|
120
|
+
content: '',
|
|
121
|
+
note: 'delete DevWorkspace rule file',
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return changes;
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/agents/cursor/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport type { AgentAdapter, AgentContext, PlannedChange } from '../types.js';\nimport { pathExists } from '../../utils/fs.js';\nimport { which } from '../../utils/proc.js';\nimport {\n buildDevWorkspaceSection,\n mergeSection,\n readIfExists,\n removeManagedSection,\n} from '../shared.js';\n\nconst CURSOR_MDC_PATH = '.cursor/rules/devworkspace.mdc';\n\nexport const cursorAdapter: AgentAdapter = {\n id: 'cursor',\n displayName: 'Cursor',\n capabilities: {\n instructions: true,\n skills: false,\n plugins: false,\n cli: false,\n },\n\n async detectExisting(root: string): Promise<string[]> {\n const found: string[] = [];\n if (await pathExists(path.join(root, '.cursorrules'))) found.push('.cursorrules');\n if (await pathExists(path.join(root, ...CURSOR_MDC_PATH.split('/')))) found.push(CURSOR_MDC_PATH);\n if (await pathExists(path.join(root, '.cursor', 'rules'))) found.push('.cursor/rules');\n return found;\n },\n\n async detectAvailable(root: string): Promise<boolean> {\n if (await pathExists(path.join(root, '.cursor'))) return true;\n if (await pathExists(path.join(root, '.cursorrules'))) return true;\n return (await which('cursor')) !== null;\n },\n\n async plan(ctx: AgentContext): Promise<PlannedChange[]> {\n const root = ctx.root;\n const legacyRulesPath = path.join(root, '.cursorrules');\n const hasLegacy = await pathExists(legacyRulesPath);\n\n if (hasLegacy) {\n // User or project has existing .cursorrules; merge the managed block into it\n const existing = await readIfExists(legacyRulesPath);\n const block = buildDevWorkspaceSection(ctx.projectName, 'Cursor');\n const merged = mergeSection(existing, block);\n return [\n {\n path: '.cursorrules',\n kind: merged.kind,\n mode: 'section',\n content: merged.content,\n note: `${merged.note} (.cursorrules)`,\n },\n ];\n }\n\n // Modern Cursor rule format (.cursor/rules/devworkspace.mdc)\n const mdcFull = path.join(root, ...CURSOR_MDC_PATH.split('/'));\n const existingMdc = await readIfExists(mdcFull);\n const mdcFrontmatter = [\n '---',\n 'description: DevWorkspace development workflow, context, and verification rules',\n 'alwaysApply: true',\n '---',\n '',\n ].join('\\n');\n const block = buildDevWorkspaceSection(ctx.projectName, 'Cursor');\n const fullContent = `${mdcFrontmatter}${block}\\n`;\n\n if (existingMdc === null) {\n return [\n {\n path: CURSOR_MDC_PATH,\n kind: 'create',\n mode: 'owned',\n content: fullContent,\n note: 'create Cursor rule in .cursor/rules/devworkspace.mdc',\n },\n ];\n }\n\n if (existingMdc === fullContent) {\n return [\n {\n path: CURSOR_MDC_PATH,\n kind: 'unchanged',\n mode: 'owned',\n content: fullContent,\n note: 'Cursor rule already current',\n },\n ];\n }\n\n // If existing MDC has custom user content outside devworkspace section, merge into it\n const merged = mergeSection(existingMdc, block);\n return [\n {\n path: CURSOR_MDC_PATH,\n kind: merged.kind,\n mode: 'owned',\n content: merged.content,\n note: `${merged.note} (.cursor/rules/devworkspace.mdc)`,\n },\n ];\n },\n\n async unplan(root: string): Promise<PlannedChange[]> {\n const changes: PlannedChange[] = [];\n const legacyPath = path.join(root, '.cursorrules');\n const legacyText = await readIfExists(legacyPath);\n if (legacyText !== null) {\n const removed = removeManagedSection(legacyText);\n if (removed) {\n changes.push({\n path: '.cursorrules',\n kind: 'update',\n mode: 'section',\n content: removed.content,\n note: removed.empty ? 'delete file (contained only DevWorkspace block)' : 'remove managed DevWorkspace block',\n });\n }\n }\n\n const mdcPath = path.join(root, ...CURSOR_MDC_PATH.split('/'));\n const mdcText = await readIfExists(mdcPath);\n if (mdcText !== null && mdcText.includes('devworkspace:start')) {\n changes.push({\n path: CURSOR_MDC_PATH,\n kind: 'update',\n mode: 'owned',\n content: '',\n note: 'delete DevWorkspace rule file',\n });\n }\n\n return changes;\n },\n};\n\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AgentAdapter } from './types.js';
|
|
2
|
+
export * from './types.js';
|
|
3
|
+
export * from './shared.js';
|
|
4
|
+
export { claudeAdapter } from './claude/adapter.js';
|
|
5
|
+
export { codexAdapter } from './codex/adapter.js';
|
|
6
|
+
export { cursorAdapter } from './cursor/adapter.js';
|
|
7
|
+
export { copilotAdapter } from './copilot/adapter.js';
|
|
8
|
+
export declare const AGENT_ADAPTERS: AgentAdapter[];
|
|
9
|
+
export declare const AGENTS: Record<string, AgentAdapter>;
|
|
10
|
+
export declare function getAgentAdapter(id: string): AgentAdapter | undefined;
|
|
11
|
+
export declare function listAgentAdapters(): AgentAdapter[];
|
|
12
|
+
/** Detect any existing instruction files across all known agent integrations. */
|
|
13
|
+
export declare function detectAllAgentFiles(root: string): Promise<string[]>;
|
|
14
|
+
/** Detect which coding agents appear active or configured in this project. */
|
|
15
|
+
export declare function detectActiveAgents(root: string): Promise<AgentAdapter[]>;
|