@thinkingsage/kanon 0.8.0

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 (199) hide show
  1. package/CHANGELOG.md +410 -0
  2. package/LICENSE +21 -0
  3. package/README.md +168 -0
  4. package/bridge/mcp-server.cjs +14171 -0
  5. package/package.json +98 -0
  6. package/src/adapters/capabilities.ts +178 -0
  7. package/src/adapters/claude-code.ts +110 -0
  8. package/src/adapters/cline.ts +98 -0
  9. package/src/adapters/codex.ts +173 -0
  10. package/src/adapters/copilot.ts +106 -0
  11. package/src/adapters/cursor.ts +97 -0
  12. package/src/adapters/degradation.ts +95 -0
  13. package/src/adapters/index.ts +324 -0
  14. package/src/adapters/kiro-frontmatter.ts +139 -0
  15. package/src/adapters/kiro-inclusion.ts +86 -0
  16. package/src/adapters/kiro.ts +412 -0
  17. package/src/adapters/qdeveloper.ts +115 -0
  18. package/src/adapters/types.ts +81 -0
  19. package/src/adapters/windsurf.ts +96 -0
  20. package/src/admin.ts +283 -0
  21. package/src/asset-conventions.ts +118 -0
  22. package/src/attribution-backfill.ts +319 -0
  23. package/src/attribution-report.ts +95 -0
  24. package/src/attribution.ts +239 -0
  25. package/src/backends/github.ts +194 -0
  26. package/src/backends/http.ts +122 -0
  27. package/src/backends/index.ts +39 -0
  28. package/src/backends/local.ts +47 -0
  29. package/src/backends/s3.ts +157 -0
  30. package/src/backends/types.ts +59 -0
  31. package/src/base-cache.ts +270 -0
  32. package/src/browse-ui.ts +3754 -0
  33. package/src/browse.ts +1038 -0
  34. package/src/build.ts +1108 -0
  35. package/src/catalog.ts +204 -0
  36. package/src/cli-deprecated.ts +29 -0
  37. package/src/cli.ts +773 -0
  38. package/src/collection-admin.ts +287 -0
  39. package/src/collection-builder.ts +464 -0
  40. package/src/collections.ts +116 -0
  41. package/src/compatibility.ts +105 -0
  42. package/src/config.ts +743 -0
  43. package/src/eval/rubrics/kiro-progressive-steering.ts +841 -0
  44. package/src/eval.ts +1169 -0
  45. package/src/file-writer.ts +61 -0
  46. package/src/format-registry.ts +141 -0
  47. package/src/guild/auto-updater.ts +163 -0
  48. package/src/guild/backend-resolver.ts +49 -0
  49. package/src/guild/cli.ts +592 -0
  50. package/src/guild/collection-expander.ts +47 -0
  51. package/src/guild/global-cache.ts +247 -0
  52. package/src/guild/hook-generator.ts +100 -0
  53. package/src/guild/manifest.ts +154 -0
  54. package/src/guild/path-utils.ts +12 -0
  55. package/src/guild/sync.ts +622 -0
  56. package/src/guild/version-resolver.ts +42 -0
  57. package/src/help/metadata.ts +445 -0
  58. package/src/help/renderer.ts +265 -0
  59. package/src/help/typo-suggester.ts +25 -0
  60. package/src/hooks/expression.ts +493 -0
  61. package/src/hooks/pipeline.ts +141 -0
  62. package/src/import.ts +773 -0
  63. package/src/importers/claude-code.ts +134 -0
  64. package/src/importers/cline.ts +103 -0
  65. package/src/importers/codex.ts +140 -0
  66. package/src/importers/copilot.ts +103 -0
  67. package/src/importers/cursor.ts +105 -0
  68. package/src/importers/index.ts +390 -0
  69. package/src/importers/kiro.ts +110 -0
  70. package/src/importers/qdeveloper.ts +103 -0
  71. package/src/importers/types.ts +54 -0
  72. package/src/importers/windsurf.ts +104 -0
  73. package/src/install.ts +1005 -0
  74. package/src/manifest-admin.ts +306 -0
  75. package/src/mcp-bridge.ts +240 -0
  76. package/src/mutation/delta.ts +50 -0
  77. package/src/mutation/history.ts +66 -0
  78. package/src/mutation/operators.ts +524 -0
  79. package/src/mutation/runner.ts +332 -0
  80. package/src/new.ts +106 -0
  81. package/src/outcomes/collision.ts +127 -0
  82. package/src/outcomes/normalize.ts +208 -0
  83. package/src/outcomes/registry.ts +173 -0
  84. package/src/parser.ts +446 -0
  85. package/src/provenance-backfill-cli.ts +319 -0
  86. package/src/provenance-backfill.ts +520 -0
  87. package/src/publish.ts +354 -0
  88. package/src/reconcile-orchestrator.ts +502 -0
  89. package/src/reconcile-report-renderer.ts +176 -0
  90. package/src/resolve-body.ts +15 -0
  91. package/src/rosetta/builtins/compatibility-profiles.ts +297 -0
  92. package/src/rosetta/builtins/contracts.ts +1033 -0
  93. package/src/rosetta/builtins/pretty-printers/claude-code-native.ts +122 -0
  94. package/src/rosetta/builtins/pretty-printers/cline-native.ts +50 -0
  95. package/src/rosetta/builtins/pretty-printers/codex-native.ts +127 -0
  96. package/src/rosetta/builtins/pretty-printers/copilot-native.ts +50 -0
  97. package/src/rosetta/builtins/pretty-printers/cursor-native.ts +50 -0
  98. package/src/rosetta/builtins/pretty-printers/index.ts +81 -0
  99. package/src/rosetta/builtins/pretty-printers/kiro-native.ts +166 -0
  100. package/src/rosetta/builtins/pretty-printers/kiro-power.ts +108 -0
  101. package/src/rosetta/builtins/pretty-printers/kiro-skill.ts +88 -0
  102. package/src/rosetta/builtins/pretty-printers/qdeveloper-native.ts +51 -0
  103. package/src/rosetta/builtins/pretty-printers/superpowers.ts +97 -0
  104. package/src/rosetta/builtins/pretty-printers/windsurf-native.ts +50 -0
  105. package/src/rosetta/builtins/sources/claude-code-native.ts +348 -0
  106. package/src/rosetta/builtins/sources/cline-native.ts +176 -0
  107. package/src/rosetta/builtins/sources/codex-native.ts +343 -0
  108. package/src/rosetta/builtins/sources/copilot-native.ts +178 -0
  109. package/src/rosetta/builtins/sources/cursor-native.ts +176 -0
  110. package/src/rosetta/builtins/sources/index.ts +95 -0
  111. package/src/rosetta/builtins/sources/kiro-native.ts +462 -0
  112. package/src/rosetta/builtins/sources/kiro-power.ts +285 -0
  113. package/src/rosetta/builtins/sources/kiro-skill.ts +230 -0
  114. package/src/rosetta/builtins/sources/qdeveloper-native.ts +181 -0
  115. package/src/rosetta/builtins/sources/superpowers.ts +240 -0
  116. package/src/rosetta/builtins/sources/windsurf-native.ts +176 -0
  117. package/src/rosetta/builtins/targets/claude-code.ts +181 -0
  118. package/src/rosetta/builtins/targets/cline.ts +87 -0
  119. package/src/rosetta/builtins/targets/codex.ts +226 -0
  120. package/src/rosetta/builtins/targets/copilot.ts +103 -0
  121. package/src/rosetta/builtins/targets/cursor.ts +87 -0
  122. package/src/rosetta/builtins/targets/index.ts +60 -0
  123. package/src/rosetta/builtins/targets/kiro.ts +278 -0
  124. package/src/rosetta/builtins/targets/qdeveloper.ts +103 -0
  125. package/src/rosetta/builtins/targets/windsurf.ts +87 -0
  126. package/src/rosetta/canonical.ts +729 -0
  127. package/src/rosetta/compatibility.ts +432 -0
  128. package/src/rosetta/contracts.ts +329 -0
  129. package/src/rosetta/detector.ts +724 -0
  130. package/src/rosetta/diagnostics.ts +630 -0
  131. package/src/rosetta/engine-bootstrap.ts +103 -0
  132. package/src/rosetta/engine.ts +744 -0
  133. package/src/rosetta/index.ts +381 -0
  134. package/src/rosetta/inspection.ts +530 -0
  135. package/src/rosetta/plan.ts +448 -0
  136. package/src/rosetta/provenance-digest.ts +369 -0
  137. package/src/rosetta/reconcile.ts +812 -0
  138. package/src/rosetta/redaction.ts +467 -0
  139. package/src/rosetta/registry.ts +712 -0
  140. package/src/rosetta/renderers.ts +571 -0
  141. package/src/rosetta/request-guard.ts +335 -0
  142. package/src/rosetta/resolution.ts +419 -0
  143. package/src/rosetta/source-accounting.ts +233 -0
  144. package/src/rosetta/templates.ts +129 -0
  145. package/src/rosetta-cli.ts +717 -0
  146. package/src/rosetta-docs-generator.ts +793 -0
  147. package/src/rosetta-profiles-cli.ts +367 -0
  148. package/src/schemas.ts +1712 -0
  149. package/src/spec-coordination.ts +1141 -0
  150. package/src/temper.ts +747 -0
  151. package/src/template-bundle-loader.ts +312 -0
  152. package/src/template-engine.ts +53 -0
  153. package/src/translation-application-policy.ts +496 -0
  154. package/src/translation-orchestrator.ts +1013 -0
  155. package/src/translation-plan-applier.ts +473 -0
  156. package/src/tutorial.ts +305 -0
  157. package/src/validate.ts +1093 -0
  158. package/src/versioning.ts +553 -0
  159. package/src/wizard.ts +660 -0
  160. package/src/workspace.ts +237 -0
  161. package/templates/eval-contexts/claude-code.md.njk +6 -0
  162. package/templates/eval-contexts/cline.md.njk +6 -0
  163. package/templates/eval-contexts/copilot.md.njk +6 -0
  164. package/templates/eval-contexts/cursor.md.njk +6 -0
  165. package/templates/eval-contexts/kiro.md.njk +10 -0
  166. package/templates/eval-contexts/qdeveloper.md.njk +6 -0
  167. package/templates/eval-contexts/windsurf.md.njk +6 -0
  168. package/templates/harness-adapters/_base/attribution-footer.md.njk +17 -0
  169. package/templates/harness-adapters/_base/base.md.njk +16 -0
  170. package/templates/harness-adapters/claude-code/claude.md.njk +1 -0
  171. package/templates/harness-adapters/claude-code/mcp.json.njk +1 -0
  172. package/templates/harness-adapters/claude-code/settings.json.njk +1 -0
  173. package/templates/harness-adapters/claude-code/skill-library-index.md.njk +13 -0
  174. package/templates/harness-adapters/claude-code/skill.md.njk +19 -0
  175. package/templates/harness-adapters/cline/hook.sh.njk +4 -0
  176. package/templates/harness-adapters/cline/mcp.json.njk +1 -0
  177. package/templates/harness-adapters/cline/rule.md.njk +1 -0
  178. package/templates/harness-adapters/codex/agents-md.md.njk +6 -0
  179. package/templates/harness-adapters/codex/agents-pointer.md.njk +16 -0
  180. package/templates/harness-adapters/codex/skill.md.njk +27 -0
  181. package/templates/harness-adapters/copilot/agents.md.njk +1 -0
  182. package/templates/harness-adapters/copilot/instructions.md.njk +1 -0
  183. package/templates/harness-adapters/copilot/scoped.md.njk +6 -0
  184. package/templates/harness-adapters/cursor/mcp.json.njk +1 -0
  185. package/templates/harness-adapters/cursor/rule.md.njk +6 -0
  186. package/templates/harness-adapters/kiro/hook.json.njk +1 -0
  187. package/templates/harness-adapters/kiro/mcp.json.njk +1 -0
  188. package/templates/harness-adapters/kiro/power-steering.md.njk +3 -0
  189. package/templates/harness-adapters/kiro/power.md.njk +12 -0
  190. package/templates/harness-adapters/kiro/steering.md.njk +16 -0
  191. package/templates/harness-adapters/qdeveloper/agent.md.njk +1 -0
  192. package/templates/harness-adapters/qdeveloper/mcp.json.njk +1 -0
  193. package/templates/harness-adapters/qdeveloper/rule.md.njk +1 -0
  194. package/templates/harness-adapters/windsurf/mcp.json.njk +1 -0
  195. package/templates/harness-adapters/windsurf/rule.md.njk +1 -0
  196. package/templates/harness-adapters/windsurf/workflow.md.njk +1 -0
  197. package/templates/knowledge/hooks.yaml.njk +4 -0
  198. package/templates/knowledge/knowledge.md.njk +53 -0
  199. package/templates/knowledge/mcp-servers.yaml.njk +2 -0
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Rosetta Stone — Codex Target Translator
3
+ *
4
+ * Wraps the existing codex adapter logic with resolved variants, body overrides,
5
+ * template bundles, effective compatibility actions, structured diagnostics,
6
+ * and deterministic TranslationPlan output.
7
+ *
8
+ * CONSTRAINTS:
9
+ * - NO filesystem, process, clock, random, Git, or network imports
10
+ * - Pure function only
11
+ *
12
+ * Requirements: 6.1, 6.5, 6.6, 7.3, 7.5, 13.8
13
+ */
14
+
15
+ import type {
16
+ DegradationRecord,
17
+ KnowledgeArtifact,
18
+ McpServerDefinition,
19
+ OutputFile,
20
+ TranslationDiagnostic,
21
+ } from "../../../schemas";
22
+ import { isStdioServer } from "../../../schemas";
23
+ import {
24
+ evaluateCompatibility,
25
+ identifyUsedCapabilities,
26
+ resolveEffectiveProfile,
27
+ } from "../../compatibility";
28
+ import { createDiagnostic } from "../../diagnostics";
29
+ import { createPlan } from "../../plan";
30
+ import type {
31
+ TargetTranslationOutput,
32
+ TargetTranslatorContext,
33
+ } from "../../registry";
34
+
35
+ // ═══════════════════════════════════════════════════════════════════════════════
36
+ // Codex Target Translator
37
+ // ═══════════════════════════════════════════════════════════════════════════════
38
+
39
+ /**
40
+ * Translate a canonical KnowledgeArtifact into Codex harness-native output.
41
+ *
42
+ * Handles `agents-md` and `skill` variants:
43
+ * - agents-md: produces a repo-wide AGENTS.md with full body
44
+ * - skill: produces .codex/skills/<name>/SKILL.md with references and an
45
+ * AGENTS.md pointer
46
+ *
47
+ * Applies body overrides for "codex" harness when available.
48
+ */
49
+ export function translateCodexTarget(
50
+ artifact: Record<string, unknown>,
51
+ context: TargetTranslatorContext,
52
+ ): TargetTranslationOutput {
53
+ const diagnostics: TranslationDiagnostic[] = [];
54
+ const degradations: DegradationRecord[] = [];
55
+
56
+ const art = artifact as unknown as KnowledgeArtifact;
57
+ const { format, variant, canonicalSchemaVersion, templates } = context;
58
+
59
+ // Resolve body override for codex harness
60
+ const body = art.bodyOverrides?.codex ?? art.body;
61
+
62
+ // Evaluate compatibility
63
+ const variantContract = format.variants[variant];
64
+ const effectiveProfile = resolveEffectiveProfile(format, variantContract);
65
+ const usedCapabilities = identifyUsedCapabilities(art);
66
+ const evaluation = evaluateCompatibility(
67
+ effectiveProfile,
68
+ usedCapabilities,
69
+ art,
70
+ );
71
+ diagnostics.push(...evaluation.diagnostics);
72
+ degradations.push(...evaluation.degradations);
73
+
74
+ // Collect degraded sections for inline rendering
75
+ const degradedSections: string[] = [];
76
+ for (const deg of degradations) {
77
+ if (deg.action === "inline") {
78
+ degradedSections.push(
79
+ `<!-- Degraded: ${deg.capability} (${deg.affectedValueCount} value(s) affected) -->`,
80
+ );
81
+ }
82
+ }
83
+
84
+ // Render output files
85
+ const outputFiles: OutputFile[] = [];
86
+ const skillName = art.name;
87
+
88
+ const renderContext = {
89
+ artifact: art,
90
+ body,
91
+ degradedSections,
92
+ };
93
+
94
+ if (variant === "skill") {
95
+ // Native Codex skill discovery path + AGENTS.md pointer
96
+ const skillContent = templates.render("codex/skill.md.njk", renderContext);
97
+ outputFiles.push({
98
+ relativePath: `.codex/skills/${skillName}/SKILL.md`,
99
+ content: skillContent,
100
+ executable: false,
101
+ });
102
+
103
+ // Workflow phase files under references/
104
+ for (const wf of art.workflows) {
105
+ outputFiles.push({
106
+ relativePath: `.codex/skills/${skillName}/references/${wf.filename}`,
107
+ content: wf.content,
108
+ executable: false,
109
+ });
110
+ }
111
+
112
+ // AGENTS.md pointer
113
+ const pointerContent = templates.render(
114
+ "codex/agents-pointer.md.njk",
115
+ renderContext,
116
+ );
117
+ outputFiles.push({
118
+ relativePath: "AGENTS.md",
119
+ content: pointerContent,
120
+ executable: false,
121
+ });
122
+ } else {
123
+ // "agents-md" variant (default): repo-wide AGENTS.md with full body
124
+ const agentsContent = templates.render(
125
+ "codex/agents-md.md.njk",
126
+ renderContext,
127
+ );
128
+ outputFiles.push({
129
+ relativePath: "AGENTS.md",
130
+ content: agentsContent,
131
+ executable: false,
132
+ });
133
+ }
134
+
135
+ // MCP servers → .codex/config.toml
136
+ if (art.mcpServers.length > 0) {
137
+ const tomlContent = buildCodexMcpToml(art.mcpServers);
138
+ outputFiles.push({
139
+ relativePath: ".codex/config.toml",
140
+ content: tomlContent,
141
+ executable: false,
142
+ });
143
+ }
144
+
145
+ // Hooks diagnostic — Codex has no declarative hook system
146
+ if (art.hooks.length > 0) {
147
+ diagnostics.push(
148
+ createDiagnostic("RS_COMPATIBILITY_NONE", {
149
+ formatId: format.id,
150
+ message:
151
+ "Codex has no declarative event-hook system; hook definitions are omitted.",
152
+ remediation:
153
+ "Implement hooks as manual guidance or shell scripts for Codex environments.",
154
+ canonical: {
155
+ artifactName: art.name,
156
+ fieldPath: "hooks",
157
+ },
158
+ }),
159
+ );
160
+ }
161
+
162
+ // Build plan deterministically
163
+ const plan = createPlan(format.id, canonicalSchemaVersion, outputFiles, {
164
+ variant,
165
+ });
166
+
167
+ return { plan, diagnostics, degradations };
168
+ }
169
+
170
+ // ═══════════════════════════════════════════════════════════════════════════════
171
+ // Internal Helpers — TOML Generation
172
+ // ═══════════════════════════════════════════════════════════════════════════════
173
+
174
+ /** TOML string literal — escape backslashes and double quotes. */
175
+ function tomlString(value: string): string {
176
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
177
+ }
178
+
179
+ /** TOML dotted-table key segment. */
180
+ function tomlKey(value: string): string {
181
+ return /^[A-Za-z0-9_-]+$/.test(value) ? value : tomlString(value);
182
+ }
183
+
184
+ /** TOML inline array of strings. */
185
+ function tomlStringArray(values: string[]): string {
186
+ return `[${values.map((v) => tomlString(v)).join(", ")}]`;
187
+ }
188
+
189
+ /** TOML inline table of string env vars. */
190
+ function tomlEnvTable(env: Record<string, string>): string {
191
+ const pairs = Object.entries(env).map(([k, v]) => `${k} = ${tomlString(v)}`);
192
+ return `{ ${pairs.join(", ")} }`;
193
+ }
194
+
195
+ /**
196
+ * Serialize canonical MCP server definitions into Codex `config.toml` form.
197
+ * Codex registers servers under `[mcp_servers.<name>]` tables.
198
+ */
199
+ function buildCodexMcpToml(servers: McpServerDefinition[]): string {
200
+ const blocks: string[] = [
201
+ "# Generated by Kanon — merge into ~/.codex/config.toml or .codex/config.toml",
202
+ ];
203
+ for (const server of servers) {
204
+ const lines = [`[mcp_servers.${tomlKey(server.name)}]`];
205
+ if (isStdioServer(server)) {
206
+ lines.push(`command = ${tomlString(server.command)}`);
207
+ if (server.args.length > 0) {
208
+ lines.push(`args = ${tomlStringArray(server.args)}`);
209
+ }
210
+ if (Object.keys(server.env).length > 0) {
211
+ lines.push(`env = ${tomlEnvTable(server.env)}`);
212
+ }
213
+ } else {
214
+ // URL-based (SSE / streamable HTTP) servers.
215
+ lines.push(`url = ${tomlString(server.url)}`);
216
+ if (server.env && Object.keys(server.env).length > 0) {
217
+ lines.push(`env = ${tomlEnvTable(server.env)}`);
218
+ }
219
+ }
220
+ if (server.timeout) {
221
+ lines.push(`startup_timeout_ms = ${server.timeout}`);
222
+ }
223
+ blocks.push(lines.join("\n"));
224
+ }
225
+ return `${blocks.join("\n\n")}\n`;
226
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Rosetta Stone — Copilot Target Translator
3
+ *
4
+ * Translates a canonical KnowledgeArtifact into GitHub Copilot's native output
5
+ * format (.github/copilot-instructions.md or agent file per variant).
6
+ *
7
+ * CONSTRAINTS:
8
+ * - NO filesystem, process, clock, random, Git, or network imports
9
+ * - Pure function only
10
+ *
11
+ * Requirements: 6.1, 6.5, 6.6, 12.2, 12.5, 13.8
12
+ */
13
+
14
+ import type {
15
+ DegradationRecord,
16
+ KnowledgeArtifact,
17
+ OutputFile,
18
+ TranslationDiagnostic,
19
+ } from "../../../schemas";
20
+ import {
21
+ evaluateCompatibility,
22
+ identifyUsedCapabilities,
23
+ resolveEffectiveProfile,
24
+ } from "../../compatibility";
25
+ import { codePointCompare } from "../../contracts";
26
+ import { createPlan } from "../../plan";
27
+ import type {
28
+ TargetTranslationOutput,
29
+ TargetTranslatorContext,
30
+ } from "../../registry";
31
+
32
+ // ═══════════════════════════════════════════════════════════════════════════════
33
+ // Copilot Target Translator
34
+ // ═══════════════════════════════════════════════════════════════════════════════
35
+
36
+ /**
37
+ * Translate a canonical artifact into Copilot-native output files.
38
+ *
39
+ * Supports variants:
40
+ * - "instructions" (default): .github/copilot-instructions.md
41
+ * - "agent": AGENTS.md
42
+ */
43
+ export function translateCopilotTarget(
44
+ artifact: Record<string, unknown>,
45
+ context: TargetTranslatorContext,
46
+ ): TargetTranslationOutput {
47
+ const diagnostics: TranslationDiagnostic[] = [];
48
+ const degradations: DegradationRecord[] = [];
49
+
50
+ const art = artifact as unknown as KnowledgeArtifact;
51
+ const { format, variant, canonicalSchemaVersion, templates } = context;
52
+
53
+ // Resolve body override for copilot harness
54
+ const body = art.bodyOverrides?.copilot ?? art.body;
55
+
56
+ // Evaluate compatibility
57
+ const variantContract = format.variants[variant];
58
+ const effectiveProfile = resolveEffectiveProfile(format, variantContract);
59
+ const usedCapabilities = identifyUsedCapabilities(art);
60
+ const evaluation = evaluateCompatibility(
61
+ effectiveProfile,
62
+ usedCapabilities,
63
+ art,
64
+ );
65
+ diagnostics.push(...evaluation.diagnostics);
66
+ degradations.push(...evaluation.degradations);
67
+
68
+ // Render output files
69
+ const outputFiles: OutputFile[] = [];
70
+
71
+ if (variant === "agent") {
72
+ // Agent variant: AGENTS.md
73
+ const content = templates.render("copilot/agents.md.njk", {
74
+ artifact: art,
75
+ body,
76
+ });
77
+ outputFiles.push({
78
+ relativePath: "AGENTS.md",
79
+ content,
80
+ executable: false,
81
+ });
82
+ } else {
83
+ // Default "instructions" variant: .github/copilot-instructions.md
84
+ const content = templates.render("copilot/instructions.md.njk", {
85
+ artifact: art,
86
+ body,
87
+ });
88
+ outputFiles.push({
89
+ relativePath: ".github/copilot-instructions.md",
90
+ content,
91
+ executable: false,
92
+ });
93
+ }
94
+
95
+ // Sort output files deterministically by path
96
+ outputFiles.sort((a, b) => codePointCompare(a.relativePath, b.relativePath));
97
+
98
+ const plan = createPlan(format.id, canonicalSchemaVersion, outputFiles, {
99
+ variant,
100
+ });
101
+
102
+ return { plan, diagnostics, degradations };
103
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Rosetta Stone — Cursor Target Translator
3
+ *
4
+ * Translates a canonical KnowledgeArtifact into Cursor's native output
5
+ * format (.cursor/rules/<name>.mdc).
6
+ *
7
+ * CONSTRAINTS:
8
+ * - NO filesystem, process, clock, random, Git, or network imports
9
+ * - Pure function only
10
+ *
11
+ * Requirements: 6.1, 6.5, 6.6, 12.2, 12.5, 13.8
12
+ */
13
+
14
+ import type {
15
+ DegradationRecord,
16
+ KnowledgeArtifact,
17
+ OutputFile,
18
+ TranslationDiagnostic,
19
+ } from "../../../schemas";
20
+ import {
21
+ evaluateCompatibility,
22
+ identifyUsedCapabilities,
23
+ resolveEffectiveProfile,
24
+ } from "../../compatibility";
25
+ import { codePointCompare } from "../../contracts";
26
+ import { createPlan } from "../../plan";
27
+ import type {
28
+ TargetTranslationOutput,
29
+ TargetTranslatorContext,
30
+ } from "../../registry";
31
+
32
+ // ═══════════════════════════════════════════════════════════════════════════════
33
+ // Cursor Target Translator
34
+ // ═══════════════════════════════════════════════════════════════════════════════
35
+
36
+ /**
37
+ * Translate a canonical artifact into Cursor-native output files.
38
+ *
39
+ * Produces .cursor/rules/<artifact-name>.mdc
40
+ */
41
+ export function translateCursorTarget(
42
+ artifact: Record<string, unknown>,
43
+ context: TargetTranslatorContext,
44
+ ): TargetTranslationOutput {
45
+ const diagnostics: TranslationDiagnostic[] = [];
46
+ const degradations: DegradationRecord[] = [];
47
+
48
+ const art = artifact as unknown as KnowledgeArtifact;
49
+ const { format, variant, canonicalSchemaVersion, templates } = context;
50
+
51
+ // Resolve body override for cursor harness
52
+ const body = art.bodyOverrides?.cursor ?? art.body;
53
+
54
+ // Evaluate compatibility
55
+ const variantContract = format.variants[variant];
56
+ const effectiveProfile = resolveEffectiveProfile(format, variantContract);
57
+ const usedCapabilities = identifyUsedCapabilities(art);
58
+ const evaluation = evaluateCompatibility(
59
+ effectiveProfile,
60
+ usedCapabilities,
61
+ art,
62
+ );
63
+ diagnostics.push(...evaluation.diagnostics);
64
+ degradations.push(...evaluation.degradations);
65
+
66
+ // Render output files
67
+ const outputFiles: OutputFile[] = [];
68
+
69
+ const content = templates.render("cursor/rule.md.njk", {
70
+ artifact: art,
71
+ body,
72
+ });
73
+ outputFiles.push({
74
+ relativePath: `.cursor/rules/${art.name}.mdc`,
75
+ content,
76
+ executable: false,
77
+ });
78
+
79
+ // Sort output files deterministically by path
80
+ outputFiles.sort((a, b) => codePointCompare(a.relativePath, b.relativePath));
81
+
82
+ const plan = createPlan(format.id, canonicalSchemaVersion, outputFiles, {
83
+ variant,
84
+ });
85
+
86
+ return { plan, diagnostics, degradations };
87
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Rosetta Stone — Built-in Target Translator Registry
3
+ *
4
+ * Exports all target translators and a lookup map from format identifiers
5
+ * to their translator implementations.
6
+ *
7
+ * CONSTRAINTS:
8
+ * - NO filesystem, process, clock, random, Git, or network imports
9
+ * - Pure re-exports only
10
+ *
11
+ * Requirements: 6.1, 6.5, 6.6, 7.3, 7.5, 12.2, 12.5, 13.8
12
+ */
13
+
14
+ import type { FormatIdentifier } from "../../../schemas";
15
+ import type { TargetTranslator } from "../../registry";
16
+ import { translateClaudeCodeTarget } from "./claude-code";
17
+ import { translateClineTarget } from "./cline";
18
+ import { translateCodexTarget } from "./codex";
19
+ import { translateCopilotTarget } from "./copilot";
20
+ import { translateCursorTarget } from "./cursor";
21
+ import { translateKiroTarget } from "./kiro";
22
+ import { translateQDeveloperTarget } from "./qdeveloper";
23
+ import { translateWindsurfTarget } from "./windsurf";
24
+
25
+ // ═══════════════════════════════════════════════════════════════════════════════
26
+ // Re-exports
27
+ // ═══════════════════════════════════════════════════════════════════════════════
28
+
29
+ export { translateClaudeCodeTarget } from "./claude-code";
30
+ export { translateClineTarget } from "./cline";
31
+ export { translateCodexTarget } from "./codex";
32
+ export { translateCopilotTarget } from "./copilot";
33
+ export { translateCursorTarget } from "./cursor";
34
+ export { translateKiroTarget } from "./kiro";
35
+ export { translateQDeveloperTarget } from "./qdeveloper";
36
+ export { translateWindsurfTarget } from "./windsurf";
37
+
38
+ // ═══════════════════════════════════════════════════════════════════════════════
39
+ // Target Translator Map
40
+ // ═══════════════════════════════════════════════════════════════════════════════
41
+
42
+ /**
43
+ * Maps format identifiers to their target translators.
44
+ *
45
+ * These handle outbound translation from canonical artifacts to harness-native
46
+ * output files.
47
+ */
48
+ export const TARGET_TRANSLATORS: ReadonlyMap<
49
+ FormatIdentifier,
50
+ TargetTranslator
51
+ > = new Map<FormatIdentifier, TargetTranslator>([
52
+ ["kiro" as FormatIdentifier, translateKiroTarget],
53
+ ["claude-code" as FormatIdentifier, translateClaudeCodeTarget],
54
+ ["codex" as FormatIdentifier, translateCodexTarget],
55
+ ["copilot" as FormatIdentifier, translateCopilotTarget],
56
+ ["cursor" as FormatIdentifier, translateCursorTarget],
57
+ ["windsurf" as FormatIdentifier, translateWindsurfTarget],
58
+ ["cline" as FormatIdentifier, translateClineTarget],
59
+ ["qdeveloper" as FormatIdentifier, translateQDeveloperTarget],
60
+ ]);