@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.
- package/CHANGELOG.md +410 -0
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/bridge/mcp-server.cjs +14171 -0
- package/package.json +98 -0
- package/src/adapters/capabilities.ts +178 -0
- package/src/adapters/claude-code.ts +110 -0
- package/src/adapters/cline.ts +98 -0
- package/src/adapters/codex.ts +173 -0
- package/src/adapters/copilot.ts +106 -0
- package/src/adapters/cursor.ts +97 -0
- package/src/adapters/degradation.ts +95 -0
- package/src/adapters/index.ts +324 -0
- package/src/adapters/kiro-frontmatter.ts +139 -0
- package/src/adapters/kiro-inclusion.ts +86 -0
- package/src/adapters/kiro.ts +412 -0
- package/src/adapters/qdeveloper.ts +115 -0
- package/src/adapters/types.ts +81 -0
- package/src/adapters/windsurf.ts +96 -0
- package/src/admin.ts +283 -0
- package/src/asset-conventions.ts +118 -0
- package/src/attribution-backfill.ts +319 -0
- package/src/attribution-report.ts +95 -0
- package/src/attribution.ts +239 -0
- package/src/backends/github.ts +194 -0
- package/src/backends/http.ts +122 -0
- package/src/backends/index.ts +39 -0
- package/src/backends/local.ts +47 -0
- package/src/backends/s3.ts +157 -0
- package/src/backends/types.ts +59 -0
- package/src/base-cache.ts +270 -0
- package/src/browse-ui.ts +3754 -0
- package/src/browse.ts +1038 -0
- package/src/build.ts +1108 -0
- package/src/catalog.ts +204 -0
- package/src/cli-deprecated.ts +29 -0
- package/src/cli.ts +773 -0
- package/src/collection-admin.ts +287 -0
- package/src/collection-builder.ts +464 -0
- package/src/collections.ts +116 -0
- package/src/compatibility.ts +105 -0
- package/src/config.ts +743 -0
- package/src/eval/rubrics/kiro-progressive-steering.ts +841 -0
- package/src/eval.ts +1169 -0
- package/src/file-writer.ts +61 -0
- package/src/format-registry.ts +141 -0
- package/src/guild/auto-updater.ts +163 -0
- package/src/guild/backend-resolver.ts +49 -0
- package/src/guild/cli.ts +592 -0
- package/src/guild/collection-expander.ts +47 -0
- package/src/guild/global-cache.ts +247 -0
- package/src/guild/hook-generator.ts +100 -0
- package/src/guild/manifest.ts +154 -0
- package/src/guild/path-utils.ts +12 -0
- package/src/guild/sync.ts +622 -0
- package/src/guild/version-resolver.ts +42 -0
- package/src/help/metadata.ts +445 -0
- package/src/help/renderer.ts +265 -0
- package/src/help/typo-suggester.ts +25 -0
- package/src/hooks/expression.ts +493 -0
- package/src/hooks/pipeline.ts +141 -0
- package/src/import.ts +773 -0
- package/src/importers/claude-code.ts +134 -0
- package/src/importers/cline.ts +103 -0
- package/src/importers/codex.ts +140 -0
- package/src/importers/copilot.ts +103 -0
- package/src/importers/cursor.ts +105 -0
- package/src/importers/index.ts +390 -0
- package/src/importers/kiro.ts +110 -0
- package/src/importers/qdeveloper.ts +103 -0
- package/src/importers/types.ts +54 -0
- package/src/importers/windsurf.ts +104 -0
- package/src/install.ts +1005 -0
- package/src/manifest-admin.ts +306 -0
- package/src/mcp-bridge.ts +240 -0
- package/src/mutation/delta.ts +50 -0
- package/src/mutation/history.ts +66 -0
- package/src/mutation/operators.ts +524 -0
- package/src/mutation/runner.ts +332 -0
- package/src/new.ts +106 -0
- package/src/outcomes/collision.ts +127 -0
- package/src/outcomes/normalize.ts +208 -0
- package/src/outcomes/registry.ts +173 -0
- package/src/parser.ts +446 -0
- package/src/provenance-backfill-cli.ts +319 -0
- package/src/provenance-backfill.ts +520 -0
- package/src/publish.ts +354 -0
- package/src/reconcile-orchestrator.ts +502 -0
- package/src/reconcile-report-renderer.ts +176 -0
- package/src/resolve-body.ts +15 -0
- package/src/rosetta/builtins/compatibility-profiles.ts +297 -0
- package/src/rosetta/builtins/contracts.ts +1033 -0
- package/src/rosetta/builtins/pretty-printers/claude-code-native.ts +122 -0
- package/src/rosetta/builtins/pretty-printers/cline-native.ts +50 -0
- package/src/rosetta/builtins/pretty-printers/codex-native.ts +127 -0
- package/src/rosetta/builtins/pretty-printers/copilot-native.ts +50 -0
- package/src/rosetta/builtins/pretty-printers/cursor-native.ts +50 -0
- package/src/rosetta/builtins/pretty-printers/index.ts +81 -0
- package/src/rosetta/builtins/pretty-printers/kiro-native.ts +166 -0
- package/src/rosetta/builtins/pretty-printers/kiro-power.ts +108 -0
- package/src/rosetta/builtins/pretty-printers/kiro-skill.ts +88 -0
- package/src/rosetta/builtins/pretty-printers/qdeveloper-native.ts +51 -0
- package/src/rosetta/builtins/pretty-printers/superpowers.ts +97 -0
- package/src/rosetta/builtins/pretty-printers/windsurf-native.ts +50 -0
- package/src/rosetta/builtins/sources/claude-code-native.ts +348 -0
- package/src/rosetta/builtins/sources/cline-native.ts +176 -0
- package/src/rosetta/builtins/sources/codex-native.ts +343 -0
- package/src/rosetta/builtins/sources/copilot-native.ts +178 -0
- package/src/rosetta/builtins/sources/cursor-native.ts +176 -0
- package/src/rosetta/builtins/sources/index.ts +95 -0
- package/src/rosetta/builtins/sources/kiro-native.ts +462 -0
- package/src/rosetta/builtins/sources/kiro-power.ts +285 -0
- package/src/rosetta/builtins/sources/kiro-skill.ts +230 -0
- package/src/rosetta/builtins/sources/qdeveloper-native.ts +181 -0
- package/src/rosetta/builtins/sources/superpowers.ts +240 -0
- package/src/rosetta/builtins/sources/windsurf-native.ts +176 -0
- package/src/rosetta/builtins/targets/claude-code.ts +181 -0
- package/src/rosetta/builtins/targets/cline.ts +87 -0
- package/src/rosetta/builtins/targets/codex.ts +226 -0
- package/src/rosetta/builtins/targets/copilot.ts +103 -0
- package/src/rosetta/builtins/targets/cursor.ts +87 -0
- package/src/rosetta/builtins/targets/index.ts +60 -0
- package/src/rosetta/builtins/targets/kiro.ts +278 -0
- package/src/rosetta/builtins/targets/qdeveloper.ts +103 -0
- package/src/rosetta/builtins/targets/windsurf.ts +87 -0
- package/src/rosetta/canonical.ts +729 -0
- package/src/rosetta/compatibility.ts +432 -0
- package/src/rosetta/contracts.ts +329 -0
- package/src/rosetta/detector.ts +724 -0
- package/src/rosetta/diagnostics.ts +630 -0
- package/src/rosetta/engine-bootstrap.ts +103 -0
- package/src/rosetta/engine.ts +744 -0
- package/src/rosetta/index.ts +381 -0
- package/src/rosetta/inspection.ts +530 -0
- package/src/rosetta/plan.ts +448 -0
- package/src/rosetta/provenance-digest.ts +369 -0
- package/src/rosetta/reconcile.ts +812 -0
- package/src/rosetta/redaction.ts +467 -0
- package/src/rosetta/registry.ts +712 -0
- package/src/rosetta/renderers.ts +571 -0
- package/src/rosetta/request-guard.ts +335 -0
- package/src/rosetta/resolution.ts +419 -0
- package/src/rosetta/source-accounting.ts +233 -0
- package/src/rosetta/templates.ts +129 -0
- package/src/rosetta-cli.ts +717 -0
- package/src/rosetta-docs-generator.ts +793 -0
- package/src/rosetta-profiles-cli.ts +367 -0
- package/src/schemas.ts +1712 -0
- package/src/spec-coordination.ts +1141 -0
- package/src/temper.ts +747 -0
- package/src/template-bundle-loader.ts +312 -0
- package/src/template-engine.ts +53 -0
- package/src/translation-application-policy.ts +496 -0
- package/src/translation-orchestrator.ts +1013 -0
- package/src/translation-plan-applier.ts +473 -0
- package/src/tutorial.ts +305 -0
- package/src/validate.ts +1093 -0
- package/src/versioning.ts +553 -0
- package/src/wizard.ts +660 -0
- package/src/workspace.ts +237 -0
- package/templates/eval-contexts/claude-code.md.njk +6 -0
- package/templates/eval-contexts/cline.md.njk +6 -0
- package/templates/eval-contexts/copilot.md.njk +6 -0
- package/templates/eval-contexts/cursor.md.njk +6 -0
- package/templates/eval-contexts/kiro.md.njk +10 -0
- package/templates/eval-contexts/qdeveloper.md.njk +6 -0
- package/templates/eval-contexts/windsurf.md.njk +6 -0
- package/templates/harness-adapters/_base/attribution-footer.md.njk +17 -0
- package/templates/harness-adapters/_base/base.md.njk +16 -0
- package/templates/harness-adapters/claude-code/claude.md.njk +1 -0
- package/templates/harness-adapters/claude-code/mcp.json.njk +1 -0
- package/templates/harness-adapters/claude-code/settings.json.njk +1 -0
- package/templates/harness-adapters/claude-code/skill-library-index.md.njk +13 -0
- package/templates/harness-adapters/claude-code/skill.md.njk +19 -0
- package/templates/harness-adapters/cline/hook.sh.njk +4 -0
- package/templates/harness-adapters/cline/mcp.json.njk +1 -0
- package/templates/harness-adapters/cline/rule.md.njk +1 -0
- package/templates/harness-adapters/codex/agents-md.md.njk +6 -0
- package/templates/harness-adapters/codex/agents-pointer.md.njk +16 -0
- package/templates/harness-adapters/codex/skill.md.njk +27 -0
- package/templates/harness-adapters/copilot/agents.md.njk +1 -0
- package/templates/harness-adapters/copilot/instructions.md.njk +1 -0
- package/templates/harness-adapters/copilot/scoped.md.njk +6 -0
- package/templates/harness-adapters/cursor/mcp.json.njk +1 -0
- package/templates/harness-adapters/cursor/rule.md.njk +6 -0
- package/templates/harness-adapters/kiro/hook.json.njk +1 -0
- package/templates/harness-adapters/kiro/mcp.json.njk +1 -0
- package/templates/harness-adapters/kiro/power-steering.md.njk +3 -0
- package/templates/harness-adapters/kiro/power.md.njk +12 -0
- package/templates/harness-adapters/kiro/steering.md.njk +16 -0
- package/templates/harness-adapters/qdeveloper/agent.md.njk +1 -0
- package/templates/harness-adapters/qdeveloper/mcp.json.njk +1 -0
- package/templates/harness-adapters/qdeveloper/rule.md.njk +1 -0
- package/templates/harness-adapters/windsurf/mcp.json.njk +1 -0
- package/templates/harness-adapters/windsurf/rule.md.njk +1 -0
- package/templates/harness-adapters/windsurf/workflow.md.njk +1 -0
- package/templates/knowledge/hooks.yaml.njk +4 -0
- package/templates/knowledge/knowledge.md.njk +53 -0
- package/templates/knowledge/mcp-servers.yaml.njk +2 -0
package/src/workspace.ts
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { exists, readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import * as yaml from "js-yaml";
|
|
4
|
+
import {
|
|
5
|
+
SUPPORTED_HARNESSES,
|
|
6
|
+
type ValidationError,
|
|
7
|
+
type WorkspaceConfig,
|
|
8
|
+
WorkspaceConfigSchema,
|
|
9
|
+
} from "./schemas";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Load workspace config from forge.config.ts or kanon.config.yaml.
|
|
13
|
+
* Prefers .ts if both exist (with a warning).
|
|
14
|
+
*/
|
|
15
|
+
export async function loadWorkspaceConfig(
|
|
16
|
+
rootDir: string,
|
|
17
|
+
): Promise<{ config: WorkspaceConfig; source: string } | null> {
|
|
18
|
+
const tsPath = join(rootDir, "forge.config.ts");
|
|
19
|
+
const yamlPath = join(rootDir, "forge.config.yaml");
|
|
20
|
+
|
|
21
|
+
const tsExists = await exists(tsPath);
|
|
22
|
+
const yamlExists = await exists(yamlPath);
|
|
23
|
+
|
|
24
|
+
if (!tsExists && !yamlExists) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (tsExists && yamlExists) {
|
|
29
|
+
console.warn(
|
|
30
|
+
"Warning: Both forge.config.ts and forge.config.yaml exist. Preferring forge.config.ts.",
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (tsExists) {
|
|
35
|
+
const mod = await import(resolve(tsPath));
|
|
36
|
+
const raw = mod.default ?? mod;
|
|
37
|
+
const result = WorkspaceConfigSchema.safeParse(raw);
|
|
38
|
+
if (!result.success) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Invalid workspace config in forge.config.ts: ${result.error.message}`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return { config: result.data, source: tsPath };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// YAML path
|
|
47
|
+
const raw = await readFile(yamlPath, "utf-8");
|
|
48
|
+
const parsed = yaml.load(raw) as Record<string, unknown> | null;
|
|
49
|
+
|
|
50
|
+
if (!parsed || typeof parsed !== "object") {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Extract workspace-specific fields from the full config
|
|
55
|
+
const workspaceFields: Record<string, unknown> = {};
|
|
56
|
+
if ("knowledgeSources" in parsed)
|
|
57
|
+
workspaceFields.knowledgeSources = parsed.knowledgeSources;
|
|
58
|
+
if ("sharedMcpServers" in parsed)
|
|
59
|
+
workspaceFields.sharedMcpServers = parsed.sharedMcpServers;
|
|
60
|
+
if ("defaults" in parsed) workspaceFields.defaults = parsed.defaults;
|
|
61
|
+
if ("projects" in parsed) workspaceFields.projects = parsed.projects;
|
|
62
|
+
|
|
63
|
+
// If no workspace fields are present, return null
|
|
64
|
+
if (!workspaceFields.knowledgeSources && !workspaceFields.projects) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const result = WorkspaceConfigSchema.safeParse(workspaceFields);
|
|
69
|
+
if (!result.success) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Invalid workspace config in forge.config.yaml: ${result.error.message}`,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return { config: result.data, source: yamlPath };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Validate workspace config against filesystem and known artifacts.
|
|
79
|
+
* Returns an array of validation errors.
|
|
80
|
+
*/
|
|
81
|
+
export async function validateWorkspaceConfig(
|
|
82
|
+
config: WorkspaceConfig,
|
|
83
|
+
rootDir: string,
|
|
84
|
+
knownArtifacts: Set<string>,
|
|
85
|
+
): Promise<ValidationError[]> {
|
|
86
|
+
const errors: ValidationError[] = [];
|
|
87
|
+
const validHarnesses = new Set<string>(SUPPORTED_HARNESSES);
|
|
88
|
+
|
|
89
|
+
for (const project of config.projects) {
|
|
90
|
+
// Validate root path exists
|
|
91
|
+
const projectRoot = resolve(rootDir, project.root);
|
|
92
|
+
if (!(await exists(projectRoot))) {
|
|
93
|
+
errors.push({
|
|
94
|
+
field: `projects.${project.name}.root`,
|
|
95
|
+
message: `Project root directory does not exist: ${project.root}`,
|
|
96
|
+
filePath: "forge.config.yaml",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Validate harness names
|
|
101
|
+
for (const harness of project.harnesses) {
|
|
102
|
+
if (!validHarnesses.has(harness)) {
|
|
103
|
+
errors.push({
|
|
104
|
+
field: `projects.${project.name}.harnesses`,
|
|
105
|
+
message: `Unknown harness name: ${harness}`,
|
|
106
|
+
filePath: "forge.config.yaml",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Validate artifact include/exclude references
|
|
112
|
+
if (project.artifacts?.include) {
|
|
113
|
+
for (const name of project.artifacts.include) {
|
|
114
|
+
if (!knownArtifacts.has(name)) {
|
|
115
|
+
errors.push({
|
|
116
|
+
field: `projects.${project.name}.artifacts.include`,
|
|
117
|
+
message: `Unknown artifact name: ${name}`,
|
|
118
|
+
filePath: "forge.config.yaml",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (project.artifacts?.exclude) {
|
|
124
|
+
for (const name of project.artifacts.exclude) {
|
|
125
|
+
if (!knownArtifacts.has(name)) {
|
|
126
|
+
errors.push({
|
|
127
|
+
field: `projects.${project.name}.artifacts.exclude`,
|
|
128
|
+
message: `Unknown artifact name: ${name}`,
|
|
129
|
+
filePath: "forge.config.yaml",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Validate knowledgeSources paths exist
|
|
137
|
+
for (const source of config.knowledgeSources) {
|
|
138
|
+
const sourcePath = resolve(rootDir, source);
|
|
139
|
+
if (!(await exists(sourcePath))) {
|
|
140
|
+
errors.push({
|
|
141
|
+
field: "knowledgeSources",
|
|
142
|
+
message: `Knowledge source directory does not exist: ${source}`,
|
|
143
|
+
filePath: "forge.config.yaml",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Validate default harnesses
|
|
149
|
+
if (config.defaults?.harnesses) {
|
|
150
|
+
for (const harness of config.defaults.harnesses) {
|
|
151
|
+
if (!validHarnesses.has(harness)) {
|
|
152
|
+
errors.push({
|
|
153
|
+
field: "defaults.harnesses",
|
|
154
|
+
message: `Unknown harness name in defaults: ${harness}`,
|
|
155
|
+
filePath: "forge.config.yaml",
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return errors;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Merge artifacts from multiple knowledge source directories.
|
|
166
|
+
* Detects name conflicts when the same artifact name appears in multiple sources.
|
|
167
|
+
*/
|
|
168
|
+
export async function mergeKnowledgeSources(
|
|
169
|
+
sources: string[],
|
|
170
|
+
rootDir: string,
|
|
171
|
+
): Promise<{
|
|
172
|
+
artifacts: Map<string, string>;
|
|
173
|
+
conflicts: Array<{ name: string; sources: string[] }>;
|
|
174
|
+
}> {
|
|
175
|
+
// Map artifact name → source path (first occurrence)
|
|
176
|
+
const artifacts = new Map<string, string>();
|
|
177
|
+
// Track all sources per artifact name for conflict detection
|
|
178
|
+
const seen = new Map<string, string[]>();
|
|
179
|
+
|
|
180
|
+
for (const source of sources) {
|
|
181
|
+
const sourcePath = resolve(rootDir, source);
|
|
182
|
+
let entries: string[];
|
|
183
|
+
try {
|
|
184
|
+
entries = await readdir(sourcePath);
|
|
185
|
+
} catch {
|
|
186
|
+
// Skip non-existent or unreadable directories
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
for (const entry of entries) {
|
|
191
|
+
// Skip hidden files and non-directories
|
|
192
|
+
if (entry.startsWith(".")) continue;
|
|
193
|
+
|
|
194
|
+
const entryPath = join(sourcePath, entry);
|
|
195
|
+
const knowledgeFile = join(entryPath, "knowledge.md");
|
|
196
|
+
if (!(await exists(knowledgeFile))) continue;
|
|
197
|
+
|
|
198
|
+
const existing = seen.get(entry);
|
|
199
|
+
if (existing) {
|
|
200
|
+
existing.push(source);
|
|
201
|
+
} else {
|
|
202
|
+
seen.set(entry, [source]);
|
|
203
|
+
artifacts.set(entry, entryPath);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Build conflicts array
|
|
209
|
+
const conflicts: Array<{ name: string; sources: string[] }> = [];
|
|
210
|
+
for (const [name, srcs] of seen) {
|
|
211
|
+
if (srcs.length > 1) {
|
|
212
|
+
conflicts.push({ name, sources: srcs });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return { artifacts, conflicts };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Serialize a WorkspaceConfig to YAML string.
|
|
221
|
+
*/
|
|
222
|
+
export function serializeWorkspaceConfig(config: WorkspaceConfig): string {
|
|
223
|
+
return yaml.dump(config, {
|
|
224
|
+
indent: 2,
|
|
225
|
+
lineWidth: -1,
|
|
226
|
+
noRefs: true,
|
|
227
|
+
sortKeys: false,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Parse a YAML string into a validated WorkspaceConfig.
|
|
233
|
+
*/
|
|
234
|
+
export function parseWorkspaceConfigYaml(yamlStr: string): WorkspaceConfig {
|
|
235
|
+
const parsed = yaml.load(yamlStr);
|
|
236
|
+
return WorkspaceConfigSchema.parse(parsed);
|
|
237
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{# Simulates how Kiro injects steering file content into the LLM context #}
|
|
2
|
+
You are Kiro, an AI assistant and IDE built to assist developers.
|
|
3
|
+
|
|
4
|
+
The following steering file has been loaded into your context:
|
|
5
|
+
|
|
6
|
+
{{ prompt }}
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
User: {{ user_query }}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{%- if artifact.frontmatter.attribution and artifact.frontmatter.attribution.upstream | length -%}
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Sources & credits
|
|
6
|
+
{% for u in artifact.frontmatter.attribution.upstream %}
|
|
7
|
+
- **{{ u.work }}** — {{ u.authors | join(", ") if u.authors | length else "(author unknown)" }} [{{ u.relationship }}]{% if u.license %} ({{ u.license }}){% endif %}{% if u.url %} — {{ u.url }}{% endif %}
|
|
8
|
+
{% endfor %}
|
|
9
|
+
{%- if artifact.frontmatter.attribution["curated-by"] %}
|
|
10
|
+
|
|
11
|
+
Curated by {{ artifact.frontmatter.attribution["curated-by"] }}.
|
|
12
|
+
{%- endif %}
|
|
13
|
+
{%- if artifact.frontmatter.attribution.notice %}
|
|
14
|
+
|
|
15
|
+
{{ artifact.frontmatter.attribution.notice }}
|
|
16
|
+
{%- endif %}
|
|
17
|
+
{%- endif -%}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{% block frontmatter %}{% endblock %}
|
|
2
|
+
{% block header %}
|
|
3
|
+
{# Generated by Kanon from knowledge/{{ artifact.name }} — do not edit #}
|
|
4
|
+
{% endblock %}
|
|
5
|
+
{% block body %}
|
|
6
|
+
{{ artifact.body }}
|
|
7
|
+
{% endblock %}
|
|
8
|
+
{% block workflows %}
|
|
9
|
+
{% for workflow in artifact.workflows %}
|
|
10
|
+
|
|
11
|
+
## {{ workflow.name }}
|
|
12
|
+
|
|
13
|
+
{{ workflow.content }}
|
|
14
|
+
{% endfor %}
|
|
15
|
+
{% endblock %}
|
|
16
|
+
{% block footer %}{% include "../_base/attribution-footer.md.njk" %}{% endblock %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ mcpConfig | dump(2) }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ settings | dump(2) }}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-library
|
|
3
|
+
description: "Lists every skill installed by this plugin, with a one-line description and how to invoke each. Use when asked what skills are installed, to list skills, or to show the library."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Installed Skills
|
|
7
|
+
|
|
8
|
+
| Skill | Type | Description |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
{% for entry in qualifying %}| `{{ entry.name }}` | {{ entry.type }} | {{ entry.description }} |
|
|
11
|
+
{% endfor %}
|
|
12
|
+
|
|
13
|
+
Ask about any skill by name, or describe what you're trying to do — Claude Code matches your request to the skill whose own trigger phrases fit best.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
2
|
+
{% block frontmatter %}
|
|
3
|
+
---
|
|
4
|
+
name: {{ artifact.name }}
|
|
5
|
+
description: {{ artifact.frontmatter.description | dump | safe }}
|
|
6
|
+
---
|
|
7
|
+
{% endblock %}
|
|
8
|
+
{% block workflows %}
|
|
9
|
+
{% if artifact.workflows | length %}
|
|
10
|
+
|
|
11
|
+
## Reference Pointers
|
|
12
|
+
|
|
13
|
+
Load these only when the workflow calls for them (progressive disclosure):
|
|
14
|
+
|
|
15
|
+
{% for workflow in artifact.workflows %}
|
|
16
|
+
- `references/{{ workflow.filename }}` — {{ workflow.name }}
|
|
17
|
+
{% endfor %}
|
|
18
|
+
{% endif %}
|
|
19
|
+
{% endblock %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ mcpConfig | dump(2) }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{# Generated by Kanon from knowledge/{{ artifact.name }} — do not edit #}
|
|
2
|
+
# Repository Agents Guide
|
|
3
|
+
|
|
4
|
+
Keep this file short and repo-wide. Point to deeper docs when detail is conditional.
|
|
5
|
+
|
|
6
|
+
## {{ artifact.frontmatter.displayName | default(artifact.frontmatter.name | titleCase) }}
|
|
7
|
+
|
|
8
|
+
{{ artifact.frontmatter.description }}
|
|
9
|
+
|
|
10
|
+
**Trigger:** When a task matches this skill, read and follow
|
|
11
|
+
`.codex/skills/{{ artifact.name }}/SKILL.md`. That file carries the full
|
|
12
|
+
workflow; its `references/` directory holds phase detail to load on demand.
|
|
13
|
+
{% if artifact.frontmatter.keywords | length %}
|
|
14
|
+
|
|
15
|
+
**Keywords:** {{ artifact.frontmatter.keywords | join(", ") }}
|
|
16
|
+
{% endif %}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
2
|
+
{% block frontmatter %}
|
|
3
|
+
---
|
|
4
|
+
name: {{ artifact.name }}
|
|
5
|
+
description: {{ artifact.frontmatter.description | dump | safe }}
|
|
6
|
+
{% if artifact.frontmatter.keywords | length %}
|
|
7
|
+
keywords: {{ artifact.frontmatter.keywords | dump }}
|
|
8
|
+
{% endif %}
|
|
9
|
+
---
|
|
10
|
+
{% endblock %}
|
|
11
|
+
{% block workflows %}
|
|
12
|
+
{% if artifact.workflows | length %}
|
|
13
|
+
|
|
14
|
+
## Reference Pointers
|
|
15
|
+
|
|
16
|
+
Load these only when the workflow calls for them (progressive disclosure):
|
|
17
|
+
|
|
18
|
+
{% for workflow in artifact.workflows %}
|
|
19
|
+
- `references/{{ workflow.filename }}` — {{ workflow.name }}
|
|
20
|
+
{% endfor %}
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% endblock %}
|
|
23
|
+
{% block footer %}
|
|
24
|
+
{% for section in degradedSections %}
|
|
25
|
+
{{ section }}
|
|
26
|
+
{% endfor %}
|
|
27
|
+
{% endblock %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ mcpConfig | dump(2) }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ hook | dump(2) }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ mcpConfig | dump(2) }}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
2
|
+
{% block frontmatter %}
|
|
3
|
+
---
|
|
4
|
+
name: "{{ artifact.frontmatter.name }}"
|
|
5
|
+
displayName: "{{ artifact.frontmatter.displayName | default(artifact.frontmatter.name) }}"
|
|
6
|
+
description: "{{ artifact.frontmatter.description }}"
|
|
7
|
+
keywords: {{ artifact.frontmatter.keywords | dump }}
|
|
8
|
+
author: "{{ artifact.frontmatter.author }}"
|
|
9
|
+
---
|
|
10
|
+
{% endblock %}
|
|
11
|
+
{# Inline workflow content into POWER.md by default. Set harness-config.kiro.inline-workflows: false to keep POWER.md lean and rely on separate steering files (official-power style). #}
|
|
12
|
+
{% block workflows %}{% if harnessConfig["inline-workflows"] != false %}{{ super() }}{% endif %}{% endblock %}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
2
|
+
{% block frontmatter %}
|
|
3
|
+
---
|
|
4
|
+
inclusion: {{ inclusion }}
|
|
5
|
+
{% if inclusion == "fileMatch" and fileMatchPattern %}
|
|
6
|
+
fileMatchPattern: "{{ fileMatchPattern }}"
|
|
7
|
+
{% endif %}
|
|
8
|
+
{% if artifact.frontmatter.description %}
|
|
9
|
+
description: {{ artifact.frontmatter.description | dump | safe }}
|
|
10
|
+
{% endif %}
|
|
11
|
+
---
|
|
12
|
+
{% endblock %}
|
|
13
|
+
{% block header %}
|
|
14
|
+
{{ auditComment | safe }}
|
|
15
|
+
{# Generated by Kanon from knowledge/{{ artifact.name }} — do not edit #}
|
|
16
|
+
{% endblock %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ mcpConfig | dump(2) }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ mcpConfig | dump(2) }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "../_base/base.md.njk" %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ workflow.content }}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{ name }}
|
|
3
|
+
displayName: {{ displayName }}
|
|
4
|
+
description: "TODO: Add description"
|
|
5
|
+
keywords: []
|
|
6
|
+
author: "TODO: Add author"
|
|
7
|
+
version: "0.1.0"
|
|
8
|
+
harnesses:
|
|
9
|
+
- kiro
|
|
10
|
+
- claude-code
|
|
11
|
+
- copilot
|
|
12
|
+
- cursor
|
|
13
|
+
- windsurf
|
|
14
|
+
- cline
|
|
15
|
+
- qdeveloper
|
|
16
|
+
type: skill
|
|
17
|
+
inclusion: always
|
|
18
|
+
# Categories: testing, security, code-style, devops, documentation, architecture, debugging, performance, accessibility
|
|
19
|
+
categories: []
|
|
20
|
+
# Ecosystem: freeform kebab-case values, e.g. typescript, python, react, bun
|
|
21
|
+
ecosystem: []
|
|
22
|
+
# Depends: artifact names this artifact depends on
|
|
23
|
+
depends: []
|
|
24
|
+
# Enhances: artifact names this artifact enhances
|
|
25
|
+
enhances: []
|
|
26
|
+
# Bazaar metadata (optional — remove comments to activate)
|
|
27
|
+
maturity: experimental
|
|
28
|
+
# trust: official|partner|community|experimental
|
|
29
|
+
# license: MIT
|
|
30
|
+
# audience: beginner|intermediate|advanced
|
|
31
|
+
# risk-level: low|medium|high
|
|
32
|
+
# model-assumptions: []
|
|
33
|
+
# id: "@org/artifact-name"
|
|
34
|
+
# collections: [] # kebab-case collection names this artifact belongs to
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# {{ displayName }}
|
|
38
|
+
|
|
39
|
+
## Overview
|
|
40
|
+
|
|
41
|
+
TODO: What this artifact does, when to use it, and why it matters.
|
|
42
|
+
|
|
43
|
+
## Best Practices
|
|
44
|
+
|
|
45
|
+
TODO: Key principles, rules, or guidelines.
|
|
46
|
+
|
|
47
|
+
## Examples
|
|
48
|
+
|
|
49
|
+
TODO: Real-world usage scenarios showing the artifact in action.
|
|
50
|
+
|
|
51
|
+
## Troubleshooting
|
|
52
|
+
|
|
53
|
+
TODO: Common mistakes, pitfalls, and what to do when things go wrong.
|