openspec-playwright 0.3.72 → 0.3.74

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.
Files changed (57) hide show
  1. package/README.md +11 -10
  2. package/README.zh-CN.md +5 -4
  3. package/dist/commands/doctor.js +65 -1
  4. package/dist/commands/doctor.js.map +1 -1
  5. package/dist/commands/editors/adapters/claude.d.ts +5 -0
  6. package/dist/commands/editors/adapters/claude.js +79 -0
  7. package/dist/commands/editors/adapters/claude.js.map +1 -0
  8. package/dist/commands/editors/adapters/cline.d.ts +15 -0
  9. package/dist/commands/editors/adapters/cline.js +63 -0
  10. package/dist/commands/editors/adapters/cline.js.map +1 -0
  11. package/dist/commands/editors/adapters/cursor.d.ts +15 -0
  12. package/dist/commands/editors/adapters/cursor.js +79 -0
  13. package/dist/commands/editors/adapters/cursor.js.map +1 -0
  14. package/dist/commands/editors/adapters/dsh.d.ts +27 -0
  15. package/dist/commands/editors/adapters/dsh.js +67 -0
  16. package/dist/commands/editors/adapters/dsh.js.map +1 -0
  17. package/dist/commands/editors/adapters/omp.d.ts +24 -0
  18. package/dist/commands/editors/adapters/omp.js +73 -0
  19. package/dist/commands/editors/adapters/omp.js.map +1 -0
  20. package/dist/commands/editors/adapters/opencode.d.ts +8 -0
  21. package/dist/commands/editors/adapters/opencode.js +133 -0
  22. package/dist/commands/editors/adapters/opencode.js.map +1 -0
  23. package/dist/commands/editors/adapters/pi.d.ts +27 -0
  24. package/dist/commands/editors/adapters/pi.js +64 -0
  25. package/dist/commands/editors/adapters/pi.js.map +1 -0
  26. package/dist/commands/editors/project-rules.d.ts +69 -0
  27. package/dist/commands/editors/project-rules.js +246 -0
  28. package/dist/commands/editors/project-rules.js.map +1 -0
  29. package/dist/commands/editors/registry.d.ts +12 -0
  30. package/dist/commands/editors/registry.js +59 -0
  31. package/dist/commands/editors/registry.js.map +1 -0
  32. package/dist/commands/editors/shared.d.ts +37 -0
  33. package/dist/commands/editors/shared.js +92 -0
  34. package/dist/commands/editors/shared.js.map +1 -0
  35. package/dist/commands/editors/tool-selection.d.ts +17 -0
  36. package/dist/commands/editors/tool-selection.js +60 -0
  37. package/dist/commands/editors/tool-selection.js.map +1 -0
  38. package/dist/commands/editors/types.d.ts +82 -0
  39. package/dist/commands/editors/types.js +41 -0
  40. package/dist/commands/editors/types.js.map +1 -0
  41. package/dist/commands/editors.d.ts +32 -309
  42. package/dist/commands/editors.js +38 -960
  43. package/dist/commands/editors.js.map +1 -1
  44. package/dist/commands/init.js +12 -15
  45. package/dist/commands/init.js.map +1 -1
  46. package/dist/commands/uninstall.js +7 -1
  47. package/dist/commands/uninstall.js.map +1 -1
  48. package/dist/commands/update.d.ts +8 -0
  49. package/dist/commands/update.js +13 -2
  50. package/dist/commands/update.js.map +1 -1
  51. package/dist/shared/codegraph.d.ts +20 -0
  52. package/dist/shared/codegraph.js +46 -0
  53. package/dist/shared/codegraph.js.map +1 -0
  54. package/dist/shared/index.d.ts +2 -0
  55. package/dist/shared/index.js +1 -0
  56. package/dist/shared/index.js.map +1 -1
  57. package/package.json +4 -3
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Core types and the `defineAdapter` factory for the editor adapter
3
+ * layer. Zero internal dependencies — every other editors/* module may
4
+ * import from this file.
5
+ */
6
+ import { join } from "path";
7
+ /** Build the command metadata for the /opsx:e2e command. */
8
+ export function buildCommandMeta(body) {
9
+ return {
10
+ id: "e2e",
11
+ name: "OPSX: E2E",
12
+ description: "Run Playwright E2E verification for an OpenSpec change",
13
+ category: "OpenSpec",
14
+ tags: ["openspec", "playwright", "e2e", "testing"],
15
+ body,
16
+ };
17
+ }
18
+ const noop = () => { };
19
+ const alwaysFalse = () => false;
20
+ /**
21
+ * Build an `EditorAdapter` from a partial init object. Fills in
22
+ * defaults so each adapter only declares what's actually different.
23
+ */
24
+ export function defineAdapter(init) {
25
+ return {
26
+ id: init.id,
27
+ label: init.label,
28
+ displayName: init.displayName,
29
+ detect: init.detect,
30
+ commandFilePath: init.commandFilePath,
31
+ formatCommand: init.formatCommand,
32
+ supportsMcp: init.supportsMcp ?? true,
33
+ projectRulesPath: init.projectRulesPath ?? ((root) => join(root, "AGENTS.md")),
34
+ isMcpInstalled: init.isMcpInstalled ?? alwaysFalse,
35
+ installMcp: init.installMcp ?? noop,
36
+ removeMcp: init.removeMcp ?? noop,
37
+ registerInstructions: init.registerInstructions,
38
+ extraArtifacts: init.extraArtifacts,
39
+ };
40
+ }
41
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/commands/editors/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO;QACL,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,wDAAwD;QACrE,QAAQ,EAAE,UAAU;QACpB,IAAI,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC;QAClD,IAAI;KACL,CAAC;AACJ,CAAC;AAkFD,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;AACtB,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;QACrC,gBAAgB,EACd,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC9D,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,WAAW;QAClD,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;QACnC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;QACjC,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;QAC/C,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC;AACJ,CAAC"}
@@ -1,310 +1,33 @@
1
- /** Escape a value for safe inclusion in a YAML frontmatter scalar. */
2
- export declare function escapeYamlValue(value: string): string;
3
- /** Format tags as a YAML inline array. */
4
- export declare function formatTagsArray(tags: string[]): string;
5
1
  /**
6
- * OpenCode slash-command names are hyphenated (`/opsx-e2e`), Claude's are
7
- * colon-prefixed (`/opsx:e2e`). Rewrite all `/opsx:` references in a
8
- * command body for OpenCode installation.
9
- */
10
- export declare function transformToHyphenCommands(text: string): string;
11
- export interface CommandMeta {
12
- id: string;
13
- name: string;
14
- description: string;
15
- category: string;
16
- tags: string[];
17
- body: string;
18
- }
19
- /** Build the command metadata for the /opsx:e2e command. */
20
- export declare function buildCommandMeta(body: string): CommandMeta;
21
- export type EditorId = "claude" | "opencode" | "cline" | "cursor" | "pi" | "omp" | "dsh";
22
- export interface ExtraArtifact {
23
- relativePath: string;
24
- contents: string;
25
- }
26
- export interface EditorAdapter {
27
- id: EditorId;
28
- /** Short label used in log messages. */
29
- label: string;
30
- /** Human-readable name used in user-facing messages. */
31
- displayName: string;
32
- /**
33
- * True if this editor's config dir is present in the project.
34
- * Some adapters (Pi, Oh My Pi) also treat a global config dir in the
35
- * user's home as a detection signal `homeDir` lets tests inject a
36
- * fake home so detection stays hermetic.
37
- */
38
- detect(projectRoot: string, homeDir?: string): boolean;
39
- /**
40
- * True when this editor has an MCP client to configure. False skips all
41
- * MCP install/check/remove phases (Pi has no MCP client).
42
- */
43
- supportsMcp?: boolean;
44
- /** Relative path of the command file inside the project. */
45
- commandFilePath(id: string): string;
46
- /** Format command file contents (frontmatter + body). */
47
- formatCommand(meta: CommandMeta): string;
48
- /** Absolute path of the project rules file. */
49
- projectRulesPath(projectRoot: string): string;
50
- /** True if MCP server `serverName` is already configured. */
51
- isMcpInstalled(projectRoot: string, serverName: string): boolean;
52
- /** Install MCP server config in this editor. */
53
- installMcp(projectRoot: string, serverName: string, command: string[]): void;
54
- /** Remove MCP server config from this editor. */
55
- removeMcp(projectRoot: string, serverName: string): void;
56
- /** Optional: register project rules file path in editor config. */
57
- registerInstructions?(projectRoot: string, instructions: string[]): void;
58
- /** Optional: secondary files written alongside commandFilePath (Cursor skill). */
59
- extraArtifacts?(meta: CommandMeta): ExtraArtifact[];
60
- }
61
- /**
62
- * Input shape for `defineAdapter` — declares the contract for an editor
63
- * adapter with sensible defaults for the no-MCP-client case (Pi, dsh).
64
- * All required-by-behavior fields are still required; optional ones
65
- * (supportsMcp, projectRulesPath, isMcpInstalled, installMcp, removeMcp)
66
- * fall back to defaults.
67
- */
68
- export interface EditorAdapterInit {
69
- id: EditorId;
70
- label: string;
71
- displayName: string;
72
- detect: EditorAdapter["detect"];
73
- commandFilePath: EditorAdapter["commandFilePath"];
74
- formatCommand: EditorAdapter["formatCommand"];
75
- /** Optional: true by default; set false for editors without an MCP client. */
76
- supportsMcp?: boolean;
77
- /** Optional: defaults to `<root>/AGENTS.md`. Override for Claude (CLAUDE.md). */
78
- projectRulesPath?: EditorAdapter["projectRulesPath"];
79
- /** Required when supportsMcp !== false. Defaults to `() => false`. */
80
- isMcpInstalled?: EditorAdapter["isMcpInstalled"];
81
- /** Required when supportsMcp !== false. Defaults to a no-op. */
82
- installMcp?: EditorAdapter["installMcp"];
83
- /** Required when supportsMcp !== false. Defaults to a no-op. */
84
- removeMcp?: EditorAdapter["removeMcp"];
85
- registerInstructions?: EditorAdapter["registerInstructions"];
86
- extraArtifacts?: EditorAdapter["extraArtifacts"];
87
- }
88
- /**
89
- * Build an `EditorAdapter` from a partial init object. Fills in
90
- * defaults so each adapter only declares what's actually different.
91
- */
92
- export declare function defineAdapter(init: EditorAdapterInit): EditorAdapter;
93
- export declare function formatClaudeCommand(meta: CommandMeta): string;
94
- export declare function getClaudeCommandPath(id: string): string;
95
- export declare function hasClaudeCode(projectRoot: string): boolean;
96
- export declare function formatOpenCodeCommand(meta: CommandMeta): string;
97
- export declare function getOpenCodeCommandPath(id: string): string;
98
- export declare function hasOpenCode(projectRoot: string): boolean;
99
- /**
100
- * Cline stores project-level config in `.cline/` (skills/, rules/, mcp.json).
101
- * `.clinerules/` is the legacy rules-only directory, still auto-detected.
102
- *
103
- * Conventions follow the Cline documentation (2026):
104
- * - Skills: `.cline/skills/<name>/SKILL.md` with YAML frontmatter
105
- * (name + description). Triggered via `/<name>` slash command.
106
- * - MCP: `.cline/mcp.json` with `{ "mcpServers": { ... } }` structure.
107
- * - Rules: Cline auto-detects `AGENTS.md` — no wrapper file needed.
108
- */
109
- export declare function formatClineCommand(meta: CommandMeta): string;
110
- export declare function getClineCommandPath(id: string): string;
111
- export declare function hasCline(projectRoot: string): boolean;
112
- export interface McpStdioServer {
113
- command: string;
114
- args: string[];
115
- }
116
- export type McpServersFile = Record<string, unknown> & {
117
- mcpServers: Record<string, McpStdioServer>;
118
- };
119
- /**
120
- * Read an MCP config file with a top-level `mcpServers` map, or null if
121
- * missing/unparseable. Preserves unknown top-level fields.
122
- */
123
- export declare function readMcpServersFile(configPath: string): McpServersFile | null;
124
- /** Write an MCP config file, creating parent directories if needed. */
125
- export declare function writeMcpServersFile(configPath: string, config: McpServersFile): void;
126
- export declare function isMcpServerInFile(configPath: string, serverName: string): boolean;
127
- export declare function installMcpServerInFile(configPath: string, serverName: string, command: string[]): void;
128
- export declare function removeMcpServerFromFile(configPath: string, serverName: string): void;
129
- /**
130
- * Cursor slash commands are plain markdown (no frontmatter); the filename
131
- * is the command name. `$1` is the change-name argument.
132
- */
133
- export declare function formatCursorCommand(meta: CommandMeta): string;
134
- export declare function getCursorCommandPath(id: string): string;
135
- export declare function getCursorSkillPath(id: string): string;
136
- /**
137
- * Cursor Agent Skill — explicit invocation only (`disable-model-invocation`).
138
- * No `$1` placeholders (those belong to the slash command file).
139
- */
140
- export declare function formatCursorSkill(meta: CommandMeta): string;
141
- export declare function hasCursor(projectRoot: string): boolean;
142
- /**
143
- * Pi stores project resources in `.pi/` (skills/, prompts/, extensions/).
144
- * Prompt templates are Markdown with optional YAML frontmatter; the
145
- * filename becomes the slash command name (`opsx-e2e.md` → `/opsx-e2e`),
146
- * `description` feeds autocomplete, and `argument-hint` shows expected
147
- * arguments. `$1` / `$ARGUMENTS` placeholders expand at prompt time.
148
- *
149
- * Conventions follow the Pi docs (packages/coding-agent/docs):
150
- * - Prompts: `.pi/prompts/*.md`, invoked via `/name`.
151
- * - Skills: `.pi/skills/` (root `.md` files or `SKILL.md` dirs),
152
- * invoked via `/skill:name`.
153
- * - Rules: Pi loads `AGENTS.md` (or `CLAUDE.md`) walking up from cwd
154
- * natively — no wrapper file needed.
155
- * - MCP: Pi has NO MCP client (built-in tools only). The adapter
156
- * still implements the interface with no-ops and declares
157
- * `supportsMcp: false` so shared MCP phases skip it.
158
- */
159
- export declare function formatPiCommand(meta: CommandMeta): string;
160
- export declare function getPiCommandPath(id: string): string;
161
- /**
162
- * True when Pi is in use: a project `.pi/` dir, or a global Pi config dir
163
- * (`~/.pi/agent/`, created by Pi on first run). The home signal lets
164
- * `openspec-pw init` detect Pi in a fresh project that has no `.pi/` yet.
165
- */
166
- export declare function hasPi(projectRoot: string, homeDir?: string): boolean;
167
- /**
168
- * Oh My Pi (omp) stores project slash commands in `.omp/commands/*.md`
169
- * (non-recursive scan, project before user). Native commands are parsed
170
- * with FATAL frontmatter parsing, so the YAML must be valid; `name`
171
- * overrides the filename and `description` feeds autocomplete. `$1` /
172
- * `$ARGUMENTS` placeholders expand at prompt time.
173
- *
174
- * Conventions follow the omp docs (docs/slash-command-internals.md,
175
- * docs/mcp-config.md):
176
- * - Commands: `.omp/commands/*.md`, invoked via `/name`.
177
- * - MCP: `.omp/mcp.json` with `{ "mcpServers": { ... } }` — same
178
- * shape as Cline/Cursor. omp also inherits `.claude/` /
179
- * `.cursor/` / opencode MCP configs when present.
180
- * - Rules: omp reads `AGENTS.md` natively — no wrapper file needed.
181
- */
182
- export declare function formatOmpCommand(meta: CommandMeta): string;
183
- export declare function getOmpCommandPath(id: string): string;
184
- /**
185
- * True when Oh My Pi is in use: a project `.omp/` dir, or a global omp
186
- * config dir (`~/.omp/agent/`, created by omp on first run).
187
- */
188
- export declare function hasOmp(projectRoot: string, homeDir?: string): boolean;
189
- /**
190
- * DeepSeek Harness (dsh) stores project skills in `.dsh/skills/` — the
191
- * `project-dsh` local provider root, rank 100 (highest local priority).
192
- * Skills are directory bundles (`<name>/SKILL.md`) with YAML frontmatter
193
- * (name + description); the kebab-case name becomes the model-invocable
194
- * skill name (`opsx-e2e`).
195
- *
196
- * Conventions follow the dsh skills subsystem (docs/subsystems/skills.md):
197
- * - Skills: `.dsh/skills/<name>/SKILL.md`, invoked via the `skill` tool.
198
- * - Rules: dsh reads `AGENTS.md` / `CLAUDE.md` natively (default
199
- * instructionFileCandidates) — no wrapper file needed.
200
- * - MCP: dsh configures MCP via `cordis.yml` plugin config
201
- * (@deepseek-ai/dsh-mcp-client), not a simple mcpServers file —
202
- * the adapter declares `supportsMcp: false` so shared MCP phases
203
- * skip it (configure Playwright MCP manually in cordis.yml).
204
- * - Detected via `.dsh/` or the global `~/.dsh/` (DSH_HOME).
205
- */
206
- export declare function formatDshCommand(meta: CommandMeta): string;
207
- export declare function getDshCommandPath(id: string): string;
208
- /**
209
- * True when DeepSeek Harness is in use: a project `.dsh/` dir, or the global
210
- * dsh home (`~/.dsh/`, DSH_HOME). The home signal lets `openspec-pw init`
211
- * detect dsh in a fresh project that has no `.dsh/` yet.
212
- */
213
- export declare function hasDsh(projectRoot: string, homeDir?: string): boolean;
214
- /**
215
- * Parse the `--tools` flag value for `openspec-pw init`.
216
- *
217
- * Returns the selected editor ids, or `null` when the flag was not provided.
218
- * Mirrors the upstream OpenSpec `openspec init --tools` semantics:
219
- * - "all" → every registered editor
220
- * - "none" → no editors
221
- * - comma-separated ids, case-insensitive; "oh-my-pi" aliases "omp"
222
- * - mixing "all"/"none" with specific ids, or unknown ids, throw
223
- * - duplicate ids are deduplicated preserving first-occurrence order
224
- */
225
- export declare function resolveToolsArg(toolsArg: string | undefined): EditorId[] | null;
226
- export declare function getAdapter(id: EditorId): EditorAdapter | undefined;
227
- /** All registered editors, regardless of detection. */
228
- export declare function getAllAdapters(): EditorAdapter[];
229
- export declare function detectAdapters(projectRoot: string, homeDir?: string): EditorAdapter[];
230
- /** Slash-command hint for user-facing messages. */
231
- export declare function slashCommandForAdapter(adapter: EditorAdapter): string;
232
- /** Relative paths installCommand writes for this adapter + meta. */
233
- export declare function listCommandArtifactPaths(adapter: EditorAdapter, meta: CommandMeta): string[];
234
- /** Install the command file (and optional extraArtifacts) for one adapter. */
235
- export declare function installCommand(adapter: EditorAdapter, meta: CommandMeta, projectRoot: string): void;
236
- /**
237
- * Read the OPENSPEC marker block from a rules file, or `null` when the file
238
- * is missing / has no markers. Used by drift detection and update to decide
239
- * whether a rules file needs rewriting.
240
- */
241
- export declare function readOpenSpecBlock(projectRoot: string, adapter: EditorAdapter): string | null;
242
- /**
243
- * Whether a rules file's OPENSPEC block matches the expected content.
244
- * A missing file or absent/truncated markers counts as "does not match"
245
- * (the caller will rewrite it), which keeps update idempotent but safe.
246
- */
247
- export declare function blockMatchesExpected(projectRoot: string, adapter: EditorAdapter, expected: string): boolean;
248
- /**
249
- * Install employee-grade standards into the editor's rules file
250
- * (CLAUDE.md for Claude, AGENTS.md for OpenCode, Cline, and Cursor). Wraps content in
251
- * `<!-- OPENSPEC:START -->` / `<!-- OPENSPEC:END -->` markers so future
252
- * updates can replace the block without touching the rest of the file.
253
- */
254
- export declare function installOpenSpecBlock(projectRoot: string, standardsContent: string, adapter?: EditorAdapter): void;
255
- /**
256
- * The expected OPENSPEC block content for a thin CLAUDE.md wrapper
257
- * (CodeGraph-first guidance + `@AGENTS.md` import). Exported so drift
258
- * detection / update can compare against it.
259
- *
260
- * The `@AGENTS.md` line is Claude Code's documented way to reuse AGENTS.md
261
- * inside CLAUDE.md — AGENTS.md is NOT read by default ("Claude Code reads
262
- * CLAUDE.md, not AGENTS.md"). Contract per
263
- * https://code.claude.com/docs/en/memory.md:
264
- * - Position is irrelevant — the doc says "@ ... anywhere in your CLAUDE.md"
265
- * (examples even inline it mid-sentence or in a list item). The one real
266
- * constraint: the `@` line must NOT sit inside a code span (backticks) or
267
- * a fenced code block — the resolver skips those. This wrapper keeps the
268
- * import at the end of the block as a bare line.
269
- * - The path resolves relative to the importing CLAUDE.md; import recursion
270
- * is capped at 4 hops.
271
- * - Block-level HTML comments (`<!-- ... -->`) are stripped before context
272
- * injection, so the OPENSPEC markers vanish while the live `@AGENTS.md`
273
- * line inside them is still honored.
274
- */
275
- export declare function claudeWrapperStandardsContent(): string;
276
- /**
277
- * Install a thin CLAUDE.md that imports AGENTS.md.
278
- *
279
- * Uses the same OPENSPEC:START/END markers as the full standards block so
280
- * `cleanProjectRules` can remove it uniformly. The CodeGraph-first block is
281
- * written directly into CLAUDE.md (before the @AGENTS.md import) so Claude
282
- * Code picks it up without depending on the import.
283
- *
284
- * Also handles migration: if CLAUDE.md has an existing OPENSPEC:START block
285
- * (old format that wrote standards directly to CLAUDE.md), calling
286
- * `installOpenSpecBlock` replaces the content with the CodeGraph block +
287
- * `@AGENTS.md` import.
288
- */
289
- export declare function installClaudeWrapper(projectRoot: string): void;
290
- /**
291
- * Route employee-grade standards into project rules files.
292
- *
293
- * AGENTS.md is always the single source of truth, regardless of which
294
- * editors are detected. If Claude is in use, a thin CLAUDE.md wrapper
295
- * with `@AGENTS.md` import is created so Claude loads AGENTS.md as
296
- * its project rules. Cline and Cursor auto-detect AGENTS.md natively — no
297
- * wrapper needed.
298
- */
299
- export declare function installProjectRules(projectRoot: string, standardsContent: string, detected: EditorAdapter[]): void;
300
- /** Remove all OpenSpec marker blocks from AGENTS.md (always) and CLAUDE.md (for claude adapter). */
301
- export declare function cleanProjectRules(adapter: EditorAdapter, projectRoot: string): void;
302
- /** Read the employee-grade standards source file (empty string if missing). */
303
- export declare function readEmployeeStandards(srcPath: string): string;
304
- export declare const claudeAdapter: EditorAdapter;
305
- export declare const opencodeAdapter: EditorAdapter;
306
- export declare const clineAdapter: EditorAdapter;
307
- export declare const cursorAdapter: EditorAdapter;
308
- export declare const piAdapter: EditorAdapter;
309
- export declare const ompAdapter: EditorAdapter;
310
- export declare const dshAdapter: EditorAdapter;
2
+ * ─────────────────────────────────────────────────────────────────────────
3
+ * FACADE FILE implementation lives in ./editors/*
4
+ * ─────────────────────────────────────────────────────────────────────────
5
+ * This file only re-exports the public API of the editor adapter layer so
6
+ * every existing `import ... from ".../editors.js"` keeps working.
7
+ *
8
+ * Why a facade instead of letting callers import "./editors/index.js"?
9
+ * Node ESM and TypeScript nodenext do NOT resolve directory indexes:
10
+ * `"./editors.js"` with only `editors/index.ts` on disk fails (TS2307).
11
+ * Keeping this thin file preserves zero-churn imports for all callers.
12
+ *
13
+ * Do NOT add logic here. Add implementations under ./editors/ and
14
+ * re-export below.
15
+ *
16
+ * Re-export order matters for adapter self-registration: importing the
17
+ * adapter modules loads them, and each calls `registerAdapter()` the
18
+ * order below fixes ADAPTERS registration order (claude → opencode →
19
+ * cline → cursor → pi → omp → dsh), which `resolveToolsArg("all")`, the
20
+ * interactive prompt order, and tests/editors-tools.test.ts depend on.
21
+ */
22
+ export { type CommandMeta, buildCommandMeta, type EditorId, type ExtraArtifact, type EditorAdapter, type EditorAdapterInit, defineAdapter, } from "./editors/types.js";
23
+ export { escapeYamlValue, formatTagsArray, transformToHyphenCommands, type McpStdioServer, type McpServersFile, readMcpServersFile, writeMcpServersFile, isMcpServerInFile, installMcpServerInFile, removeMcpServerFromFile, } from "./editors/shared.js";
24
+ export { registerAdapter, getAdapter, getAllAdapters, detectAdapters, slashCommandForAdapter, listCommandArtifactPaths, installCommand, } from "./editors/registry.js";
25
+ export { formatClaudeCommand, getClaudeCommandPath, hasClaudeCode, claudeAdapter, } from "./editors/adapters/claude.js";
26
+ export { formatOpenCodeCommand, getOpenCodeCommandPath, hasOpenCode, opencodeAdapter, readOpenCodeInstructions, } from "./editors/adapters/opencode.js";
27
+ export { formatClineCommand, getClineCommandPath, hasCline, clineAdapter, } from "./editors/adapters/cline.js";
28
+ export { formatCursorCommand, getCursorCommandPath, getCursorSkillPath, formatCursorSkill, hasCursor, cursorAdapter, } from "./editors/adapters/cursor.js";
29
+ export { formatPiCommand, getPiCommandPath, hasPi, piAdapter, } from "./editors/adapters/pi.js";
30
+ export { formatOmpCommand, getOmpCommandPath, hasOmp, ompAdapter, } from "./editors/adapters/omp.js";
31
+ export { formatDshCommand, getDshCommandPath, hasDsh, dshAdapter, } from "./editors/adapters/dsh.js";
32
+ export { resolveToolsArg } from "./editors/tool-selection.js";
33
+ export { readOpenSpecBlock, blockMatchesExpected, installOpenSpecBlock, claudeWrapperStandardsContent, installClaudeWrapper, installProjectRules, cleanProjectRules, readEmployeeStandards, } from "./editors/project-rules.js";