diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 25b6d331f..fb8daa620 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -134,7 +134,7 @@ jobs:
contents: write
strategy:
fail-fast: false
- # Four marketplace plus five flat — opencode is flat-only. Mirrors the CLI golden
+ # Four marketplace plus six flat — opencode and kilo are flat-only. Mirrors the CLI golden
# snapshot matrix.
matrix:
include:
@@ -147,6 +147,7 @@ jobs:
- { tool: copilot, mode: flat }
- { tool: codex, mode: flat }
- { tool: opencode, mode: flat }
+ - { tool: kilo, mode: flat }
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
diff --git a/.gitignore b/.gitignore
index 8ce3232e3..ccd5ca804 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,3 +69,5 @@ temp/
tmp/
setup-test/
tmp-test/
+.aidd/cache/
+aidd_docs/runs/
diff --git a/README.md b/README.md
index 7507f3b57..568492bd8 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ Why not just write your own commands? → [FAQ](docs/FAQ.md#-why-aidd-instead-of
## ✅ Prerequisites
-- **An AI coding tool** — Claude Code (native), or Cursor / Copilot / Codex / OpenCode (see [Compatibility](#-compatibility)).
+- **An AI coding tool** — Claude Code (native), or Cursor / Copilot / Codex / OpenCode / Kilo Code (see [Compatibility](#-compatibility)).
- **[Node](https://nodejs.org) 22 or later** on your `PATH`, only for the plugin that ships hooks ([what they do](docs/ARCHITECTURE.md#-bundled-hooks)); the workflows themselves are markdown and need nothing.
## 🔌 Compatibility
@@ -49,6 +49,7 @@ Why not just write your own commands? → [FAQ](docs/FAQ.md#-why-aidd-instead-of
| **GitHub Copilot** | ✅ Supported | Marketplace · Flat |
| **Codex** | ✅ Supported | Marketplace · Flat |
| **OpenCode** | ✅ Supported | Flat |
+| **Kilo Code** | ✅ Supported | Flat |
| **Gemini · Mistral** | 🚧 In progress | — |
**Marketplace** = installed and updated through your tool's plugin manager. **Flat** = files copied directly into your project, no plugin manager involved. Install steps per tool → [Other tools](#other-tools).
@@ -174,6 +175,16 @@ codex plugin add aidd-context@aidd-framework # per plugin
+
+Kilo Code — Flat only
+
+1. Unzip the `kilo-flat` archive into your project root → `.kilo/`, including `.kilo/kilo.jsonc`.
+2. Start a new Kilo session so it loads the generated project plugin.
+
+[Plugins documentation](https://kilo.ai/docs/automate/extending/plugins)
+
+
+
## 🚀 Quick start
Three ways in — pick one:
diff --git a/cli/README.md b/cli/README.md
index 846943774..0013c0390 100644
--- a/cli/README.md
+++ b/cli/README.md
@@ -3,7 +3,7 @@
`@ai-driven-dev/cli` installs AI tool runtime configs, IDE integrations, and plugins from an AIDD marketplace into a project.
Every file it writes is hash-tracked in a manifest, so drift is detected and owned files can be restored.
-Supported AI tools: Claude Code, Cursor, GitHub Copilot, Codex, OpenCode. Supported IDE: VS Code.
+Supported AI tools: Claude Code, Cursor, GitHub Copilot, Codex, OpenCode, Kilo Code. Supported IDE: VS Code.
Requires Node.js >= 22.12, and `git` to fetch marketplace plugins.
## Install
@@ -136,8 +136,9 @@ Two output layouts, chosen by `--as`:
| `copilot` | yes | yes | `.github/` |
| `codex` | yes | yes | `.codex/` |
| `opencode` | no | yes | `.opencode/` |
+| `kilo` | no | yes | `.kilo/` |
-OpenCode declares no marketplace contract, so it is flat only. Every other target accepts both layouts.
+OpenCode and Kilo Code declare no marketplace contract, so they are flat only. Every other target accepts both layouts.
## Environment variables
@@ -184,6 +185,7 @@ Per tool, the settings file the CLI writes:
| GitHub Copilot | Plugin recommendations in `.github/copilot/settings.json`, MCP servers in `.vscode/mcp.json`, plus `.vscode/settings.json` when the VS Code tool is installed too |
| Codex | `.codex/config.toml` |
| OpenCode | `opencode.json`, or `opencode.jsonc` when that is the one present |
+| Kilo Code | `.kilo/kilo.jsonc` by default; an existing `kilo.json[c]` is reused |
| VS Code | `.vscode/settings.json`, `.vscode/extensions.json`, `.vscode/keybindings.json` |
## More
diff --git a/cli/aidd_docs/memory/codebase-map.md b/cli/aidd_docs/memory/codebase-map.md
index 90fe9aac2..9297dd07a 100644
--- a/cli/aidd_docs/memory/codebase-map.md
+++ b/cli/aidd_docs/memory/codebase-map.md
@@ -51,6 +51,7 @@ src/
│ │ │ ├── codex/
│ │ │ ├── copilot/
│ │ │ ├── cursor/
+│ │ │ ├── kilo/
│ │ │ ├── opencode/
│ │ │ └── vscode/
│ │ └── infrastructure/
diff --git a/cli/assets/configs/kilo/kilo.json b/cli/assets/configs/kilo/kilo.json
new file mode 100644
index 000000000..9f2bb73a0
--- /dev/null
+++ b/cli/assets/configs/kilo/kilo.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://app.kilo.ai/config.json",
+ "instructions": [".kilo/rules/**/*.md"]
+}
diff --git a/cli/scripts/smoke-tools.sh b/cli/scripts/smoke-tools.sh
index da217b49c..3c5eba1e6 100755
--- a/cli/scripts/smoke-tools.sh
+++ b/cli/scripts/smoke-tools.sh
@@ -17,7 +17,7 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
CLI="$ROOT/dist/cli.js"
FRAMEWORK_FIXTURE="$ROOT/tests/fixtures/framework"
-AI_TOOLS=(claude cursor copilot codex opencode)
+AI_TOOLS=(claude cursor copilot codex opencode kilo)
IDE_TOOLS=(vscode)
# Canonical leaf-command surface. Coverage = exercised / total.
@@ -322,7 +322,7 @@ if true; then
run "sync --force" 0 "" "$BASE" -- sync --force
repaired "sync --force" "$tgt"
- section "framework install/update/remove --tool × all 5 AI tools + vscode"
+ section "framework install/update/remove --tool × all 6 AI tools + vscode"
run "framework update (all)" 0 "" "$BASE" -- framework update
run "framework rules" 0 "" "$BASE" -- framework rules
run "framework rules --json" 0 "" "$BASE" -- framework rules --json
diff --git a/cli/src/contexts/framework/application/framework/translator/built-tree-materialization-translator.ts b/cli/src/contexts/framework/application/framework/translator/built-tree-materialization-translator.ts
index 4d5d63561..41257fa54 100644
--- a/cli/src/contexts/framework/application/framework/translator/built-tree-materialization-translator.ts
+++ b/cli/src/contexts/framework/application/framework/translator/built-tree-materialization-translator.ts
@@ -15,6 +15,7 @@ import type { AiToolId } from "../../../../../kernel/tool.js";
import type { MarketplaceRegistry } from "../../../../distribution/domain/ports/marketplace-registry.js";
import {
frameworkBuildModeFor,
+ getAiToolConfig,
resolvePluginsCapability,
} from "../../../../tools/domain/registry.js";
import type { PluginDistribution } from "../../../../translate/domain/plugin-distribution.js";
@@ -158,7 +159,7 @@ export class BuiltTreeMaterializationTranslator implements PluginTranslator {
const files: InstallationFile[] = [];
for (const abs of absPaths) {
const rel = posixRelative(builtDir, abs);
- if (!this.belongsToPlugin(rel, name) && !hookPaths.has(rel)) continue;
+ if (!this.belongsToPlugin(rel, name, toolId) && !hookPaths.has(rel)) continue;
const content = await this.fs.readFile(abs);
files.push(
new InstallationFile({ relativePath: rel, content, hash: this.hasher.hash(content) })
@@ -167,9 +168,10 @@ export class BuiltTreeMaterializationTranslator implements PluginTranslator {
return files;
}
- private belongsToPlugin(rel: string, name: string): boolean {
+ private belongsToPlugin(rel: string, name: string, toolId: AiToolId): boolean {
const segments = rel.split("/");
- if (segments[0] !== ".opencode" || segments.length < 3) return false;
+ const toolDirectory = getAiToolConfig(toolId).directory.replace(/\/$/, "");
+ if (segments[0] !== toolDirectory || segments.length < 3) return false;
// `skills/` nests the whole plugin under one exactly-named segment; every other flat section
// hyphen-prefixes the leaf segment.
if (segments[1] === "skills") return segments[2] === name;
@@ -181,7 +183,7 @@ export class BuiltTreeMaterializationTranslator implements PluginTranslator {
const flatHooksDir = plugins?.flatHooksDir;
if (plugins === null || flatHooksDir === null || flatHooksDir === undefined) return new Set();
const name = dist.manifest.name;
- return new Set(
+ const paths = new Set(
dist.components.hooks
.filter((f) => f.relativePath !== "hooks/hooks.json")
.map((f) =>
@@ -193,6 +195,15 @@ export class BuiltTreeMaterializationTranslator implements PluginTranslator {
)
)
);
+ const bridge = plugins.flatHooksBridge;
+ const hooksJson = dist.components.hooks.find((f) => f.relativePath === "hooks/hooks.json");
+ const hasOwnBridge =
+ bridge !== null &&
+ dist.components.hooks.some((f) => f.relativePath.endsWith(`/${bridge.skipIfSourceHas}`));
+ if (bridge !== null && hooksJson !== undefined && !hasOwnBridge) {
+ if (bridge.generate(hooksJson.content, name) !== null) paths.add(bridge.path(name));
+ }
+ return paths;
}
private async findMarketplace(name: string, projectRoot: string) {
diff --git a/cli/src/contexts/framework/application/install/install-runtime-config-use-case.ts b/cli/src/contexts/framework/application/install/install-runtime-config-use-case.ts
index d67612fdf..9b8cdfbc7 100644
--- a/cli/src/contexts/framework/application/install/install-runtime-config-use-case.ts
+++ b/cli/src/contexts/framework/application/install/install-runtime-config-use-case.ts
@@ -7,6 +7,7 @@ import type { FileWriter } from "../../../../kernel/ports/file-writer.js";
import type { Hasher } from "../../../../kernel/ports/hasher.js";
import type { Logger } from "../../../../kernel/ports/logger.js";
import type { AiToolId } from "../../../../kernel/tool.js";
+import { McpCapability } from "../../../tools/domain/capabilities/mcp-capability.js";
import { SettingsCapability } from "../../../tools/domain/capabilities/settings-capability.js";
import type { FileMerger } from "../../../tools/domain/ports/file-merger.js";
import { getToolConfig, isAiTool } from "../../../tools/domain/registry.js";
@@ -78,16 +79,33 @@ export class InstallRuntimeConfigUseCase {
if (!isAiTool(toolConfig) || !toolConfig.configOutputPaths) return [];
const files: InstallationFile[] = [];
for (const [fileName, outputPath] of Object.entries(toolConfig.configOutputPaths)) {
+ const resolvedPath = await this.resolveConfigPath(toolConfig, fileName, outputPath, options);
const asset = this.assets.loadConfigAsset(options.toolId, fileName);
const content = typeof asset === "string" ? asset : JSON.stringify(asset, null, 2);
- if (await this.isUserOwned(outputPath, options)) continue;
+ if (await this.isUserOwned(resolvedPath, options)) continue;
files.push(
- new InstallationFile({ relativePath: outputPath, content, hash: this.hasher.hash(content) })
+ new InstallationFile({
+ relativePath: resolvedPath,
+ content,
+ hash: this.hasher.hash(content),
+ })
);
}
return files;
}
+ private async resolveConfigPath(
+ toolConfig: Extract, { kind: "ai" }>,
+ fileName: string,
+ outputPath: string,
+ options: InstallRuntimeConfigOptions
+ ): Promise {
+ const caps = toolConfig.capabilities as Record;
+ const mcp = caps.mcp;
+ if (!(mcp instanceof McpCapability) || mcp.params.outputPath !== fileName) return outputPath;
+ return mcp.resolveOutput(options.projectRoot, this.fs);
+ }
+
private buildStaticSettingsFiles(options: InstallRuntimeConfigOptions): InstallationFile[] {
const toolConfig = getToolConfig(options.toolId);
if (!isAiTool(toolConfig)) return [];
diff --git a/cli/src/contexts/tools/domain/formats/opencode-mcp-merge.ts b/cli/src/contexts/tools/domain/formats/opencode-mcp-merge.ts
index 55dba42ca..35cfe70cc 100644
--- a/cli/src/contexts/tools/domain/formats/opencode-mcp-merge.ts
+++ b/cli/src/contexts/tools/domain/formats/opencode-mcp-merge.ts
@@ -43,7 +43,8 @@ export function mergeOpencodeMcp(
export function buildOpencodeFlatConfig(
baseConfig: string,
existing: string | null,
- incoming: Record
+ incoming: Record,
+ mergedKeys: readonly string[] = []
): string {
const base = JSON.parse(baseConfig) as Record;
const { full, mcp } = parseExisting(existing);
@@ -52,11 +53,21 @@ export function buildOpencodeFlatConfig(
delete userKeys.mcp;
const mergedMcp = { ...mcp, ...incoming };
const result: Record = { ...base, ...userKeys };
+ for (const key of mergedKeys) {
+ const existingValues = arrayEntries(full[key]);
+ const baseValues = arrayEntries(base[key]);
+ const generated = baseValues.filter((value) => !existingValues.includes(value));
+ result[key] = [...existingValues, ...generated];
+ }
delete result.mcp;
if (Object.keys(mergedMcp).length > 0) result.mcp = mergedMcp;
return JSON.stringify(result, null, 2);
}
+function arrayEntries(value: unknown): readonly unknown[] {
+ return Array.isArray(value) ? value : [];
+}
+
/** Removes servers previously contributed by a plugin from opencode.json's mcp section. A key
* absent from `entries` is left untouched. */
export function unmergeOpencodeMcp(
diff --git a/cli/src/contexts/tools/domain/profiles/kilo/build.ts b/cli/src/contexts/tools/domain/profiles/kilo/build.ts
new file mode 100644
index 000000000..9c16bdc4c
--- /dev/null
+++ b/cli/src/contexts/tools/domain/profiles/kilo/build.ts
@@ -0,0 +1,138 @@
+/** Kilo's project distribution is flat. Its config and MCP format follow the OpenCode runtime,
+ * but Kilo has its own .kilo/ discovery paths and bundled base configuration. */
+
+import { join } from "node:path";
+import { parseFrontmatter, serializeFrontmatter } from "../../../../../kernel/markdown.js";
+import {
+ flatHooksPathWithLoaderEntry,
+ flatMcpKeyPrefix,
+ genericFlatAgentPath,
+ genericFlatSkillTreePath,
+} from "../../../../../kernel/materialization/flat-paths.js";
+import { rewriteRelativeLinks } from "../../../../../kernel/materialization/relative-link-rewrite.js";
+import type { FileReader } from "../../../../../kernel/ports/file-reader.js";
+import type { FileWriter } from "../../../../../kernel/ports/file-writer.js";
+import type { ToolBuildContract } from "../../build-contract.js";
+import { buildOpencodeFlatConfig } from "../../formats/opencode-mcp-merge.js";
+import { transformMcpToOpencode } from "../opencode/build.js";
+import { generateKiloHooksBridge } from "./kilo-hooks-bridge.js";
+import {
+ KILO_DIRECTORY,
+ KILO_HOOKS_DIR,
+ KILO_PLUGIN_DIR,
+ KILO_PLUGIN_ENTRY_BASENAME,
+ makeKiloHooksBridgePath,
+ resolveKiloConfigPath,
+} from "./kilo-paths.js";
+
+type FsType = FileReader & FileWriter;
+
+function kiloFlatAgentPath(plugin: string, rel: string): string {
+ return genericFlatAgentPath(
+ `${KILO_DIRECTORY}agents/`,
+ plugin,
+ rel.replace(/^agents\//, ""),
+ ".md"
+ );
+}
+
+function kiloFlatSkillPath(plugin: string, rel: string): string {
+ return genericFlatSkillTreePath(`${KILO_DIRECTORY}skills/`, plugin, rel.replace(/^skills\//, ""));
+}
+
+function kiloFlatResolveTarget(plugin: string, rel: string): string {
+ if (rel.startsWith("agents/")) return kiloFlatAgentPath(plugin, rel);
+ if (rel.startsWith("skills/")) return kiloFlatSkillPath(plugin, rel);
+ return rel;
+}
+
+function kiloFlatHooksPath(plugin: string, rel: string): string {
+ return flatHooksPathWithLoaderEntry(
+ KILO_HOOKS_DIR,
+ { dir: KILO_PLUGIN_DIR, baseName: KILO_PLUGIN_ENTRY_BASENAME },
+ plugin,
+ rel
+ );
+}
+
+function transformKiloFlatAgent(content: string, plugin: string, outName: string): string {
+ const { frontmatter, body } = parseFrontmatter(content);
+ const flatRelPath = kiloFlatAgentPath(plugin, `agents/${outName}`);
+ const rewrittenBody = rewriteRelativeLinks(body, {
+ currentFilePluginRelative: flatRelPath,
+ resolveTargetPath: (rel) => kiloFlatResolveTarget(plugin, rel),
+ });
+ return serializeFrontmatter(
+ { ...frontmatter, name: `${plugin}-${outName.replace(/\.md$/, "")}`, mode: "subagent" },
+ rewrittenBody
+ );
+}
+
+async function collectKiloMcp(
+ builtPlugins: readonly string[],
+ sourceDir: string,
+ fs: FsType
+): Promise> {
+ const incoming: Record = {};
+ for (const plugin of builtPlugins) {
+ const mcpSrc = `${sourceDir}/plugins/${plugin}/.mcp.json`;
+ if (!(await fs.fileExists(mcpSrc))) continue;
+ const transformed = JSON.parse(transformMcpToOpencode(await fs.readFile(mcpSrc))) as {
+ mcp?: Record;
+ };
+ for (const [key, value] of Object.entries(transformed.mcp ?? {})) {
+ incoming[`${flatMcpKeyPrefix(plugin)}${key}`] = value;
+ }
+ }
+ return incoming;
+}
+
+export function buildKiloFlatContract(): ToolBuildContract {
+ return {
+ manifestFileRelative: null,
+ synthesizeManifest: null,
+ manifestSchemaName: null,
+ artifacts: {
+ skills: {
+ supported: true,
+ source: { kind: "fullTree", srcDir: "skills" },
+ path: kiloFlatSkillPath,
+ rewriteSkillName: true,
+ },
+ agents: {
+ supported: true,
+ source: { kind: "filteredTree", srcDir: "agents", inputExt: ".md" },
+ path: kiloFlatAgentPath,
+ transform: transformKiloFlatAgent,
+ },
+ mcp: { supported: false },
+ hooks: {
+ supported: true,
+ source: { kind: "hooksBundle", jsonPath: "hooks/hooks.json", scriptDir: "hooks" },
+ path: kiloFlatHooksPath,
+ skipHooksJson: true,
+ hooksBridge: {
+ generate: generateKiloHooksBridge,
+ path: makeKiloHooksBridgePath,
+ skipIfSourceHas: KILO_PLUGIN_ENTRY_BASENAME,
+ },
+ },
+ rules: { supported: false },
+ commands: { supported: false },
+ },
+ buildMarketplaceCatalog: null,
+ buildMarketplaceEntry: null,
+ emitConfigArtifact: async (builtPlugins, outDir, sourceDir, fs, _validator, assetProvider) => {
+ const configPath = join(outDir, await resolveKiloConfigPath(outDir, fs));
+ const existing = (await fs.fileExists(configPath)) ? await fs.readFile(configPath) : null;
+ const incoming = await collectKiloMcp(builtPlugins, sourceDir, fs);
+ const asset = assetProvider.loadConfigAsset("kilo", "kilo.json");
+ const base = typeof asset === "string" ? asset : JSON.stringify(asset);
+ await fs.writeFile(
+ configPath,
+ buildOpencodeFlatConfig(base, existing, incoming, ["instructions"])
+ );
+ return 1;
+ },
+ };
+}
diff --git a/cli/src/contexts/tools/domain/profiles/kilo/kilo-hooks-bridge.ts b/cli/src/contexts/tools/domain/profiles/kilo/kilo-hooks-bridge.ts
new file mode 100644
index 000000000..de57459d7
--- /dev/null
+++ b/cli/src/contexts/tools/domain/profiles/kilo/kilo-hooks-bridge.ts
@@ -0,0 +1,109 @@
+/**
+ * Kilo loads JavaScript modules from `.kilo/plugin/` and requires a default descriptor with
+ * `{ id, server }`. Declarative hooks.json has no Kilo runtime, so this generator turns its
+ * replayable SessionStart commands into that native module. Kilo documents `session.created` as
+ * the session lifecycle event; other Claude hook events deliberately remain unsupported until
+ * their Kilo payloads have been captured.
+ */
+
+interface ClaudeHookItem {
+ readonly command?: string;
+}
+
+interface ClaudeMatcherGroup {
+ readonly hooks?: readonly ClaudeHookItem[];
+}
+
+interface ClaudeHooksShape {
+ readonly hooks?: Record;
+}
+
+interface ParsedHookCall {
+ readonly script: string;
+ readonly args: readonly string[];
+}
+
+const COMMAND_PATTERN = /^node\s+\$\{CLAUDE_PLUGIN_ROOT\}\/hooks\/(\S+)(.*)$/;
+
+function parseCommand(command: string | undefined): ParsedHookCall | null {
+ if (typeof command !== "string") return null;
+ const match = COMMAND_PATTERN.exec(command.trim());
+ if (match === null) return null;
+ const [, script, rest] = match;
+ return { script, args: rest.trim().length === 0 ? [] : rest.trim().split(/\s+/) };
+}
+
+/** Parses only the one declarative event whose Kilo mapping is documented and intended here. */
+export function parseKiloSessionStartHooks(rawHooksJson: string): readonly ParsedHookCall[] {
+ const parsed = JSON.parse(rawHooksJson) as ClaudeHooksShape;
+ return (parsed.hooks?.SessionStart ?? []).flatMap((group) =>
+ (group.hooks ?? []).flatMap((hook) => {
+ const parsedHook = parseCommand(hook.command);
+ return parsedHook === null ? [] : [parsedHook];
+ })
+ );
+}
+
+function toIdentifier(plugin: string): string {
+ return `${plugin
+ .split("-")
+ .filter(Boolean)
+ .map((part) => part[0]?.toUpperCase() + part.slice(1))
+ .join("")}KiloHooks`;
+}
+
+/** Generates Kilo's default plugin descriptor, or no file where hooks.json has no replayable
+ * SessionStart command. The generated module keeps errors non-blocking so a failed memory
+ * refresh cannot prevent Kilo from creating a session. */
+export function generateKiloHooksBridge(rawHooksJson: string, plugin: string): string | null {
+ const sessionStart = parseKiloSessionStartHooks(rawHooksJson);
+ if (sessionStart.length === 0) return null;
+ const identifier = toIdentifier(plugin);
+ return `// Generated by aidd from plugins/${plugin}/hooks/hooks.json - do not edit by hand.
+import { spawn } from "node:child_process";
+import { fileURLToPath } from "node:url";
+
+const HOOKS_DIR = fileURLToPath(new URL("../hooks/${plugin}/", import.meta.url));
+const SESSION_START = ${JSON.stringify(sessionStart)};
+
+function runHook(script, args, payload, directory) {
+ const child = spawn("node", [HOOKS_DIR + script, ...args], {
+ cwd: directory,
+ stdio: ["pipe", "ignore", "ignore"],
+ timeout: 5000,
+ });
+ child.on("error", (error) => reportHookFailure(script, error));
+ child.stdin.on("error", (error) => reportHookFailure(script, error));
+ child.stdin.end(JSON.stringify(payload));
+}
+
+function reportHookFailure(script, error) {
+ console.warn("[aidd] Kilo session-start hook " + script + " failed: " + String(error));
+}
+
+function sessionStartCallsFor(event, directory) {
+ if (event?.type !== "session.created") return [];
+ return SESSION_START.map((hook) => ({
+ script: hook.script,
+ args: hook.args,
+ payload: { hook_event_name: "SessionStart", session_id: null, cwd: directory },
+ }));
+}
+
+const ${identifier} = async ({ directory }) => ({
+ event: async ({ event }) => {
+ try {
+ for (const call of sessionStartCallsFor(event, directory)) {
+ runHook(call.script, call.args, call.payload, directory);
+ }
+ } catch (error) {
+ console.warn("[aidd] Kilo session-start hook dispatch failed: " + String(error));
+ }
+ },
+});
+
+${identifier}.sessionStartCallsFor = sessionStartCallsFor;
+
+export default { id: "${plugin}-hooks", server: ${identifier} };
+`;
+}
diff --git a/cli/src/contexts/tools/domain/profiles/kilo/kilo-paths.ts b/cli/src/contexts/tools/domain/profiles/kilo/kilo-paths.ts
new file mode 100644
index 000000000..e3ec31b80
--- /dev/null
+++ b/cli/src/contexts/tools/domain/profiles/kilo/kilo-paths.ts
@@ -0,0 +1,37 @@
+/** Paths Kilo scans in a project. Kept apart from the profile so the build contract and the
+ * later hooks bridge share one declaration rather than duplicate Kilo's plugin layout. */
+
+import { join } from "node:path";
+import { KiloDualConfigError } from "../../../../../kernel/errors.js";
+import type { FileReader } from "../../../../../kernel/ports/file-reader.js";
+
+export const KILO_DIRECTORY = ".kilo/";
+export const KILO_HOOKS_DIR = `${KILO_DIRECTORY}hooks/`;
+export const KILO_PLUGIN_DIR = `${KILO_DIRECTORY}plugin/`;
+export const KILO_PLUGIN_ENTRY_BASENAME = "kilo-plugin.js";
+export const KILO_PROJECT_CONFIG_JSON = `${KILO_DIRECTORY}kilo.json`;
+export const KILO_PROJECT_CONFIG_JSONC = `${KILO_DIRECTORY}kilo.jsonc`;
+
+const KILO_LEGACY_CONFIG_JSON = "kilo.json";
+const KILO_LEGACY_CONFIG_JSONC = "kilo.jsonc";
+
+export function makeKiloHooksBridgePath(plugin: string): string {
+ return `${KILO_PLUGIN_DIR}${plugin}-hooks.js`;
+}
+
+/** Prefer the config beside Kilo's project artifacts. Existing root-level configuration stays
+ * user-owned and is reused rather than creating a second configuration variant. */
+export async function resolveKiloConfigPath(projectRoot: string, fs: FileReader): Promise {
+ const projectJson = await fs.fileExists(join(projectRoot, KILO_PROJECT_CONFIG_JSON));
+ const projectJsonc = await fs.fileExists(join(projectRoot, KILO_PROJECT_CONFIG_JSONC));
+ if (projectJson && projectJsonc) throw new KiloDualConfigError();
+ if (projectJsonc) return KILO_PROJECT_CONFIG_JSONC;
+ if (projectJson) return KILO_PROJECT_CONFIG_JSON;
+
+ const legacyJson = await fs.fileExists(join(projectRoot, KILO_LEGACY_CONFIG_JSON));
+ const legacyJsonc = await fs.fileExists(join(projectRoot, KILO_LEGACY_CONFIG_JSONC));
+ if (legacyJson && legacyJsonc) throw new KiloDualConfigError();
+ if (legacyJsonc) return KILO_LEGACY_CONFIG_JSONC;
+ if (legacyJson) return KILO_LEGACY_CONFIG_JSON;
+ return KILO_PROJECT_CONFIG_JSONC;
+}
diff --git a/cli/src/contexts/tools/domain/profiles/kilo/profile.ts b/cli/src/contexts/tools/domain/profiles/kilo/profile.ts
new file mode 100644
index 000000000..4778bb776
--- /dev/null
+++ b/cli/src/contexts/tools/domain/profiles/kilo/profile.ts
@@ -0,0 +1,115 @@
+import { AgentsCapability } from "../../capabilities/agents-capability.js";
+import { CommandsCapability } from "../../capabilities/commands-capability.js";
+import { CONFIG_MCP } from "../../capabilities/config-refs.js";
+import { McpCapability } from "../../capabilities/mcp-capability.js";
+import { PluginsCapability } from "../../capabilities/plugins-capability.js";
+import { RulesCapability } from "../../capabilities/rules-capability.js";
+import { SkillsCapability } from "../../capabilities/skills-capability.js";
+import type {
+ AiTool,
+ HasAgents,
+ HasCommands,
+ HasMcp,
+ HasPlugins,
+ HasRules,
+ HasSkills,
+} from "../../contracts.js";
+import {
+ buildAiddCommandFilePath,
+ convertCommandFrontmatterNoHint,
+ stripToolSuffix,
+} from "../../formats/command.js";
+import { registerTool } from "../../registry.js";
+import { transformMcpToOpencode } from "../opencode/build.js";
+import { buildKiloFlatContract } from "./build.js";
+import { generateKiloHooksBridge } from "./kilo-hooks-bridge.js";
+import {
+ KILO_DIRECTORY,
+ KILO_HOOKS_DIR,
+ KILO_PLUGIN_DIR,
+ KILO_PLUGIN_ENTRY_BASENAME,
+ makeKiloHooksBridgePath,
+ resolveKiloConfigPath,
+} from "./kilo-paths.js";
+
+const TOOL_SUFFIX = ".kilo.md";
+
+export const kilo: AiTool = {
+ kind: "ai",
+ toolId: "kilo",
+ distributionProbes: { marketplace: ["kilo.json"] },
+ directory: KILO_DIRECTORY,
+ toolSuffix: TOOL_SUFFIX,
+ displayName: "Kilo Code",
+ telemetryLocalRead: {
+ kind: "unsupported",
+ reason: "Kilo OpenTelemetry is experimental and not yet supported by AIDD.",
+ },
+ telemetryTaskAttributable: false,
+ signalDir: ".kilo/commands",
+ configOutputPaths: { "kilo.json": ".kilo/kilo.jsonc" },
+ buildContracts: { flat: buildKiloFlatContract },
+
+ capabilities: {
+ agents: new AgentsCapability({
+ directory: KILO_DIRECTORY,
+ toolSuffix: TOOL_SUFFIX,
+ format: "markdown",
+ convertFrontmatter: (fm) => ({ description: fm.description, mode: "subagent" }),
+ }),
+ skills: new SkillsCapability({
+ directory: KILO_DIRECTORY,
+ toolSuffix: TOOL_SUFFIX,
+ buildInstallPath: (fileName) =>
+ `${KILO_DIRECTORY}skills/${stripToolSuffix(TOOL_SUFFIX, fileName)}`,
+ convertFrontmatter: (fm) => fm,
+ }),
+ commands: new CommandsCapability({
+ directory: KILO_DIRECTORY,
+ toolSuffix: TOOL_SUFFIX,
+ buildInstallPath: (fileName) => buildAiddCommandFilePath(KILO_DIRECTORY, fileName),
+ convertFrontmatter: (fm, relativeFileName) =>
+ convertCommandFrontmatterNoHint(fm, relativeFileName),
+ }),
+ rules: new RulesCapability({
+ directory: KILO_DIRECTORY,
+ toolSuffix: TOOL_SUFFIX,
+ buildInstallPath: (fileName) =>
+ `${KILO_DIRECTORY}rules/${stripToolSuffix(TOOL_SUFFIX, fileName)}`,
+ convertFrontmatter: (fm) =>
+ fm.alwaysApply === false && fm.description !== undefined
+ ? { description: fm.description }
+ : {},
+ }),
+ mcp: new McpCapability({
+ outputPath: "kilo.json",
+ format: "json",
+ entrySection: "mcp",
+ mergeStrategy: "framework-prime",
+ transformContent: transformMcpToOpencode,
+ consumes: [CONFIG_MCP],
+ resolveOutputPath: resolveKiloConfigPath,
+ }),
+ plugins: new PluginsCapability({
+ mode: "flat",
+ flatNamespacePrefix: "aidd-",
+ acceptsHooks: true,
+ flatHooksDir: KILO_HOOKS_DIR,
+ flatHooksLoaderEntry: { dir: KILO_PLUGIN_DIR, baseName: KILO_PLUGIN_ENTRY_BASENAME },
+ flatHooksBridge: {
+ generate: generateKiloHooksBridge,
+ path: makeKiloHooksBridgePath,
+ skipIfSourceHas: KILO_PLUGIN_ENTRY_BASENAME,
+ },
+ }),
+ },
+
+ rewriteContent(content: string): string {
+ return content.replace(
+ /(@?)\.kilo\/commands\/(\d+)[_-][^/]+\/([^\s]+)/g,
+ "$1.kilo/commands/aidd/$2/$3"
+ );
+ },
+};
+
+registerTool(kilo);
diff --git a/cli/src/kernel/errors.ts b/cli/src/kernel/errors.ts
index d55531434..eb8d07e08 100644
--- a/cli/src/kernel/errors.ts
+++ b/cli/src/kernel/errors.ts
@@ -130,6 +130,13 @@ export class OpencodeDualConfigError extends Error {
}
}
+export class KiloDualConfigError extends Error {
+ constructor() {
+ super("Both Kilo JSON and JSONC config variants exist at the same location. Remove one.");
+ this.name = "KiloDualConfigError";
+ }
+}
+
export class PackageManagerDetectionError extends Error {
constructor(commands: readonly string[]) {
super(`Could not detect package manager. Run manually:\n ${commands.join("\n ")}`);
diff --git a/cli/src/kernel/tool.ts b/cli/src/kernel/tool.ts
index 291d92bba..6f8b968f5 100644
--- a/cli/src/kernel/tool.ts
+++ b/cli/src/kernel/tool.ts
@@ -1,6 +1,6 @@
import { UnknownAiToolIdError } from "./errors.js";
-export type AiToolId = "claude" | "cursor" | "copilot" | "opencode" | "codex";
+export type AiToolId = "claude" | "cursor" | "copilot" | "opencode" | "kilo" | "codex";
export type IdeToolId = "vscode";
export type ToolId = AiToolId | IdeToolId;
export type ToolCategory = "ai" | "ide";
@@ -10,6 +10,7 @@ export const AI_TOOL_IDS: readonly AiToolId[] = [
"cursor",
"copilot",
"opencode",
+ "kilo",
"codex",
];
export const IDE_TOOL_IDS: readonly IdeToolId[] = ["vscode"];
diff --git a/cli/src/presentation/commands/translate.ts b/cli/src/presentation/commands/translate.ts
index ba6dd806f..79830cce0 100644
--- a/cli/src/presentation/commands/translate.ts
+++ b/cli/src/presentation/commands/translate.ts
@@ -70,7 +70,10 @@ export function registerTranslateCommand(program: Command): void {
"Convert an arbitrary source into a target-native plugin tree — records nothing (see `sync` for the manifest-driven, tracked version)"
)
.argument("", "Path to the source framework directory")
- .requiredOption("--to ", "Conversion target (claude, cursor, copilot, codex, opencode)")
+ .requiredOption(
+ "--to ",
+ "Conversion target (claude, cursor, copilot, codex, opencode, kilo)"
+ )
.requiredOption("--out ", "Output directory (marketplace dist or project root)")
.option("--as ", "Output layout", "marketplace")
.option("--force", "Overwrite existing files at canonical paths under --out")
diff --git a/cli/src/presentation/prompts/menu-use-case.ts b/cli/src/presentation/prompts/menu-use-case.ts
index 3e8833bb6..b58ae19d3 100644
--- a/cli/src/presentation/prompts/menu-use-case.ts
+++ b/cli/src/presentation/prompts/menu-use-case.ts
@@ -44,7 +44,7 @@ const INSTALLED_NODES: MenuNode[] = [
value: "doctor-tool",
description: "Scope the report to a single AI or IDE tool",
command: ["doctor", "--tool"],
- inputPrompt: "Tool (e.g. claude, cursor, copilot, codex, opencode, vscode)",
+ inputPrompt: "Tool (e.g. claude, cursor, copilot, codex, opencode, kilo, vscode)",
},
{
name: "Plugins",
@@ -64,7 +64,7 @@ const INSTALLED_NODES: MenuNode[] = [
value: "framework-install",
description: "Add a tool to this project",
command: ["framework", "install", "--tool"],
- inputPrompt: "Tool (e.g. claude, cursor, copilot, codex, opencode, vscode)",
+ inputPrompt: "Tool (e.g. claude, cursor, copilot, codex, opencode, kilo, vscode)",
},
{
name: "Remove",
diff --git a/cli/src/runtime/assets/asset-loader.ts b/cli/src/runtime/assets/asset-loader.ts
index a6dba9ac1..2377e545a 100644
--- a/cli/src/runtime/assets/asset-loader.ts
+++ b/cli/src/runtime/assets/asset-loader.ts
@@ -6,6 +6,7 @@ import copilotVscodeSettings from "../../../assets/configs/copilot/vscode-settin
type: "json",
};
import cursorSettings from "../../../assets/configs/cursor/settings.json" with { type: "json" };
+import kiloJson from "../../../assets/configs/kilo/kilo.json" with { type: "json" };
import opencodeJson from "../../../assets/configs/opencode/opencode.json" with { type: "json" };
import vscodeExtensions from "../../../assets/configs/vscode/extensions.json" with { type: "json" };
import vscodeKeybindings from "../../../assets/configs/vscode/keybindings.json" with {
@@ -26,6 +27,7 @@ const CONFIG_ASSETS: Readonly {
+ it("copies Kilo's namespaced flat files and the generated bridge", async () => {
+ const fs = new InMemoryFileAdapter();
+ fs.setFile(`${KILO_BUILT}/.kilo/skills/aidd-vcs/01-commit/SKILL.md`, "skill");
+ fs.setFile(`${KILO_BUILT}/.kilo/agents/aidd-vcs-helper.md`, "agent");
+ fs.setFile(`${KILO_BUILT}/.kilo/hooks/aidd-vcs/update_memory.js`, "hook");
+ fs.setFile(`${KILO_BUILT}/.kilo/plugin/aidd-vcs-hooks.js`, "bridge");
+ fs.setFile(`${KILO_BUILT}/.kilo/agents/aidd-dev-helper.md`, "other");
+
+ const manifest = Manifest.create();
+ manifest.addTool("kilo", "test", []);
+ const translator = new BuiltTreeMaterializationTranslator(
+ fs,
+ new DeterministicHasher(),
+ () => "/home/u",
+ fakeEnsureBuiltMarketplace(),
+ await makeRegistry()
+ );
+ const distribution = new PluginDistribution({
+ manifest: { name: "aidd-vcs", version: "1.0.0" },
+ format: "claude",
+ files: [],
+ components: {
+ commands: [],
+ agents: [],
+ rules: [],
+ skills: [],
+ mcp: [],
+ hooks: [
+ { relativePath: "hooks/hooks.json", content: sessionStartHooksJson() },
+ { relativePath: "hooks/update_memory.js", content: "hook" },
+ ],
+ },
+ });
+
+ await translator.addPlugin(
+ distribution,
+ "kilo",
+ { kind: "local", path: "/plugin-source" },
+ PROJECT_ROOT,
+ manifest,
+ "aidd-framework"
+ );
+
+ expect(fs.getFile(`${PROJECT_ROOT}/.kilo/skills/aidd-vcs/01-commit/SKILL.md`)).toBe("skill");
+ expect(fs.getFile(`${PROJECT_ROOT}/.kilo/agents/aidd-vcs-helper.md`)).toBe("agent");
+ expect(fs.getFile(`${PROJECT_ROOT}/.kilo/hooks/aidd-vcs/update_memory.js`)).toBe("hook");
+ expect(fs.getFile(`${PROJECT_ROOT}/.kilo/plugin/aidd-vcs-hooks.js`)).toBe("bridge");
+ expect(fs.has(`${PROJECT_ROOT}/.kilo/agents/aidd-dev-helper.md`)).toBe(false);
+ });
+});
+
+function sessionStartHooksJson(): string {
+ const root = "$" + "{CLAUDE_PLUGIN_ROOT}";
+ return JSON.stringify({
+ hooks: {
+ SessionStart: [{ hooks: [{ command: `node ${root}/hooks/update_memory.js` }] }],
+ },
+ });
+}
diff --git a/cli/tests/contexts/framework/application/install/install-runtime-config-use-case.unit.test.ts b/cli/tests/contexts/framework/application/install/install-runtime-config-use-case.unit.test.ts
index e7f661ad4..6c7682887 100644
--- a/cli/tests/contexts/framework/application/install/install-runtime-config-use-case.unit.test.ts
+++ b/cli/tests/contexts/framework/application/install/install-runtime-config-use-case.unit.test.ts
@@ -157,6 +157,42 @@ describe("InstallRuntimeConfigUseCase", () => {
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining(".claude/settings.json"));
});
+ it("writes Kilo's project-local JSONC config on a fresh install", async () => {
+ const deps = await buildUnitDeps(PROJECT_ROOT);
+ await initProject(deps, PROJECT_ROOT);
+ const manifest = (await deps.manifestRepo.load()) ?? Manifest.create();
+
+ await buildUseCase(deps).execute({
+ toolId: "kilo",
+ projectRoot: PROJECT_ROOT,
+ manifest,
+ force: false,
+ version: "1.0.0",
+ });
+
+ expect(deps.fs.has(join(PROJECT_ROOT, ".kilo/kilo.jsonc"))).toBe(true);
+ expect(deps.fs.has(join(PROJECT_ROOT, "kilo.json"))).toBe(false);
+ });
+
+ it("reuses Kilo's existing root JSONC config instead of creating a project-local config", async () => {
+ const deps = await buildUnitDeps(PROJECT_ROOT);
+ await initProject(deps, PROJECT_ROOT);
+ await deps.fs.writeFile(join(PROJECT_ROOT, "kilo.jsonc"), '{"user": true}');
+ const manifest = (await deps.manifestRepo.load()) ?? Manifest.create();
+
+ await buildUseCase(deps).execute({
+ toolId: "kilo",
+ projectRoot: PROJECT_ROOT,
+ manifest,
+ force: false,
+ version: "1.0.0",
+ });
+
+ expect(deps.fs.has(join(PROJECT_ROOT, "kilo.json"))).toBe(false);
+ expect(deps.fs.getFile(join(PROJECT_ROOT, "kilo.jsonc"))).toBe('{"user": true}');
+ expect(deps.fs.has(join(PROJECT_ROOT, ".kilo/kilo.jsonc"))).toBe(false);
+ });
+
describe("copilot requiresTool gate", () => {
it("does not create .vscode/settings.json when vscode is not installed", async () => {
const deps = await buildUnitDeps(PROJECT_ROOT);
diff --git a/cli/tests/contexts/framework/application/list-installed-rules-use-case.unit.test.ts b/cli/tests/contexts/framework/application/list-installed-rules-use-case.unit.test.ts
index c4755378a..d483673b4 100644
--- a/cli/tests/contexts/framework/application/list-installed-rules-use-case.unit.test.ts
+++ b/cli/tests/contexts/framework/application/list-installed-rules-use-case.unit.test.ts
@@ -6,6 +6,7 @@ import "../../../../src/contexts/tools/domain/profiles/claude/profile.js";
import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import { ListInstalledRulesUseCase } from "../../../../src/contexts/framework/application/list-installed-rules-use-case.js";
import type { FileReader } from "../../../../src/kernel/ports/file-reader.js";
@@ -40,6 +41,7 @@ describe("ListInstalledRulesUseCase — every tool's installed rules, in one ans
[at(".cursor/rules/1-naming.mdc")]: "---\n---\n",
[at(".github/instructions/01-naming.instructions.md")]: "---\n---\n",
[at(".codex/rules/1-naming.md")]: "---\n---\n",
+ [at(".kilo/rules/1-naming.md")]: "---\n---\n",
[at(".opencode/rules/1-naming.md")]: "---\n---\n",
})
);
@@ -51,6 +53,7 @@ describe("ListInstalledRulesUseCase — every tool's installed rules, in one ans
"codex",
"copilot",
"cursor",
+ "kilo",
"opencode",
]);
});
diff --git a/cli/tests/contexts/framework/application/uninstall-use-case.unit.test.ts b/cli/tests/contexts/framework/application/uninstall-use-case.unit.test.ts
index 7f85cc001..878c20138 100644
--- a/cli/tests/contexts/framework/application/uninstall-use-case.unit.test.ts
+++ b/cli/tests/contexts/framework/application/uninstall-use-case.unit.test.ts
@@ -116,7 +116,7 @@ describe("uninstall — refusals", () => {
})
).rejects.toThrow(
new InputRequiredError(
- "At least one tool ID is required. Valid tools: claude, cursor, copilot, opencode, codex, vscode"
+ "At least one tool ID is required. Valid tools: claude, cursor, copilot, opencode, kilo, codex, vscode"
)
);
});
diff --git a/cli/tests/contexts/framework/domain/plugin-asset-translation.unit.test.ts b/cli/tests/contexts/framework/domain/plugin-asset-translation.unit.test.ts
index e889af5c2..a49f34034 100644
--- a/cli/tests/contexts/framework/domain/plugin-asset-translation.unit.test.ts
+++ b/cli/tests/contexts/framework/domain/plugin-asset-translation.unit.test.ts
@@ -6,11 +6,13 @@ import "../../../../src/contexts/tools/domain/profiles/claude/profile.js";
import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import { claude } from "../../../../src/contexts/tools/domain/profiles/claude/profile.js";
import { codex } from "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import { copilot } from "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import { cursor } from "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import { kilo } from "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import { opencode } from "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import { getAiToolConfig } from "../../../../src/contexts/tools/domain/registry.js";
import { PluginContentTranslator } from "../../../../src/contexts/translate/domain/content-translator.js";
@@ -77,7 +79,7 @@ describe("installing the plugin carries a skill's own script, on every tool", ()
});
}
- for (const tool of [claude, codex, copilot, cursor, opencode]) {
+ for (const tool of [claude, codex, copilot, cursor, kilo, opencode]) {
it(`${tool.toolId} installs it byte for byte`, () => {
const installed = translator
.translate(distributionOf(), tool)
diff --git a/cli/tests/contexts/telemetry/application/diagnose-telemetry-use-case.unit.test.ts b/cli/tests/contexts/telemetry/application/diagnose-telemetry-use-case.unit.test.ts
index 091d508cd..317e35411 100644
--- a/cli/tests/contexts/telemetry/application/diagnose-telemetry-use-case.unit.test.ts
+++ b/cli/tests/contexts/telemetry/application/diagnose-telemetry-use-case.unit.test.ts
@@ -4,6 +4,7 @@ import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import { Manifest } from "../../../../src/contexts/framework/domain/manifest.js";
import { InstalledPlugin } from "../../../../src/contexts/framework/domain/plugins/installed-plugin.js";
import type { ManifestRepository } from "../../../../src/contexts/framework/domain/ports/manifest-repository.js";
@@ -650,6 +651,7 @@ describe("DiagnoseTelemetryUseCase — the setup it prints", () => {
expect(result.uncovered).toStrictEqual([
{ tool: "cursor", reason: "It writes no token count in any file it produces." },
+ { tool: "kilo", reason: "Kilo telemetry has not been measured." },
]);
});
});
diff --git a/cli/tests/contexts/telemetry/application/read-local-cost-sweep.unit.test.ts b/cli/tests/contexts/telemetry/application/read-local-cost-sweep.unit.test.ts
index 258e0deff..17ab982f3 100644
--- a/cli/tests/contexts/telemetry/application/read-local-cost-sweep.unit.test.ts
+++ b/cli/tests/contexts/telemetry/application/read-local-cost-sweep.unit.test.ts
@@ -4,6 +4,7 @@ import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import {
type LocalCostToolReport,
ReadLocalCostUseCase,
@@ -71,6 +72,15 @@ const CURSOR_NOT_COVERED: LocalCostToolReport = {
reason: "It writes no token count in any file it produces.",
};
+const KILO_NOT_COVERED: LocalCostToolReport = {
+ tool: "kilo",
+ status: "not-covered",
+ recordsFound: 0,
+ recordsStored: 0,
+ sessionsFailed: 0,
+ reason: "Kilo telemetry has not been measured.",
+};
+
function sessionJournal(vendorId: string, host = "claude-code"): RunJournal {
return {
boundaries: [],
@@ -167,6 +177,7 @@ describe("which sessions a sweep reads", () => {
notAsked("cursor"),
notAsked("copilot"),
notAsked("opencode"),
+ notAsked("kilo"),
notAsked("codex"),
],
});
@@ -192,6 +203,7 @@ describe("which sessions a sweep reads", () => {
notAsked("cursor"),
notAsked("copilot"),
notAsked("opencode"),
+ notAsked("kilo"),
notAsked("codex"),
],
refusedReason:
@@ -216,6 +228,7 @@ describe("one session's answers, tool by tool", () => {
CURSOR_NOT_COVERED,
notAsked("copilot"),
notAsked("opencode"),
+ KILO_NOT_COVERED,
notAsked("codex"),
],
},
diff --git a/cli/tests/contexts/telemetry/application/read-local-cost-use-case.unit.test.ts b/cli/tests/contexts/telemetry/application/read-local-cost-use-case.unit.test.ts
index 388511732..dea20b167 100644
--- a/cli/tests/contexts/telemetry/application/read-local-cost-use-case.unit.test.ts
+++ b/cli/tests/contexts/telemetry/application/read-local-cost-use-case.unit.test.ts
@@ -8,6 +8,7 @@ import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import { ReadLocalCostUseCase } from "../../../../src/contexts/telemetry/application/read-local-cost-use-case.js";
import { mapCodexRolloutToSinkRecords } from "../../../../src/contexts/telemetry/domain/formats/codex-rollout.js";
import type { RunJournal } from "../../../../src/contexts/telemetry/domain/ports/run-journal-reader.js";
diff --git a/cli/tests/contexts/telemetry/application/report-cost-use-case.unit.test.ts b/cli/tests/contexts/telemetry/application/report-cost-use-case.unit.test.ts
index 0f198d500..9204a849e 100644
--- a/cli/tests/contexts/telemetry/application/report-cost-use-case.unit.test.ts
+++ b/cli/tests/contexts/telemetry/application/report-cost-use-case.unit.test.ts
@@ -6,6 +6,7 @@ import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import { ReadLocalCostUseCase } from "../../../../src/contexts/telemetry/application/read-local-cost-use-case.js";
import { ReportCostUseCase } from "../../../../src/contexts/telemetry/application/report-cost-use-case.js";
import { toMicroUsd } from "../../../../src/contexts/telemetry/domain/cost-report.js";
@@ -1001,6 +1002,17 @@ describe("ReportCostUseCase — what it assembles for the report", () => {
taskAttributable: true,
},
},
+ {
+ tool: "kilo",
+ coverage: "not-covered",
+ reason: "Kilo OpenTelemetry is experimental and not yet supported by AIDD.",
+ capability: {
+ localRead: null,
+ export: null,
+ journalAttributable: false,
+ taskAttributable: false,
+ },
+ },
{
tool: "codex",
coverage: "covered",
diff --git a/cli/tests/contexts/telemetry/application/tool-attribution.unit.test.ts b/cli/tests/contexts/telemetry/application/tool-attribution.unit.test.ts
index e22146052..81c5a609b 100644
--- a/cli/tests/contexts/telemetry/application/tool-attribution.unit.test.ts
+++ b/cli/tests/contexts/telemetry/application/tool-attribution.unit.test.ts
@@ -8,6 +8,7 @@ import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import { ReadLocalCostUseCase } from "../../../../src/contexts/telemetry/application/read-local-cost-use-case.js";
import { mapClaudeCodeTranscriptToSinkRecords } from "../../../../src/contexts/telemetry/domain/formats/claude-code-transcript.js";
import type { SessionCostReader } from "../../../../src/contexts/telemetry/domain/ports/session-cost-reader.js";
diff --git a/cli/tests/contexts/telemetry/domain/cost-report-envelope.unit.test.ts b/cli/tests/contexts/telemetry/domain/cost-report-envelope.unit.test.ts
index 01de37b9d..10031afc9 100644
--- a/cli/tests/contexts/telemetry/domain/cost-report-envelope.unit.test.ts
+++ b/cli/tests/contexts/telemetry/domain/cost-report-envelope.unit.test.ts
@@ -8,6 +8,7 @@ import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import {
buildCostReport,
type CostReport,
diff --git a/cli/tests/contexts/telemetry/domain/metrics-contract.unit.test.ts b/cli/tests/contexts/telemetry/domain/metrics-contract.unit.test.ts
index bbd09f1a4..259256c5e 100644
--- a/cli/tests/contexts/telemetry/domain/metrics-contract.unit.test.ts
+++ b/cli/tests/contexts/telemetry/domain/metrics-contract.unit.test.ts
@@ -10,6 +10,7 @@ import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import { ReadLocalCostUseCase } from "../../../../src/contexts/telemetry/application/read-local-cost-use-case.js";
import type { LocalCostCandidateRecord } from "../../../../src/contexts/telemetry/domain/ports/session-cost-reader.js";
import { NULL_PERSON_IDENTITY_READER } from "../../../helpers/ports/in-memory-person-identity-reader.js";
diff --git a/cli/tests/contexts/telemetry/infrastructure/telemetry-evidence-adapter.integration.test.ts b/cli/tests/contexts/telemetry/infrastructure/telemetry-evidence-adapter.integration.test.ts
index 12843be44..2a94dbdd0 100644
--- a/cli/tests/contexts/telemetry/infrastructure/telemetry-evidence-adapter.integration.test.ts
+++ b/cli/tests/contexts/telemetry/infrastructure/telemetry-evidence-adapter.integration.test.ts
@@ -9,6 +9,7 @@ import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import { TelemetryEvidenceAdapter } from "../../../../src/contexts/telemetry/infrastructure/telemetry-evidence-adapter.js";
/**
diff --git a/cli/tests/contexts/tools/domain/build-hooks-support-declaration.unit.test.ts b/cli/tests/contexts/tools/domain/build-hooks-support-declaration.unit.test.ts
index 8649c2308..73557fb4a 100644
--- a/cli/tests/contexts/tools/domain/build-hooks-support-declaration.unit.test.ts
+++ b/cli/tests/contexts/tools/domain/build-hooks-support-declaration.unit.test.ts
@@ -11,6 +11,8 @@ import { buildCopilotFlatContract } from "../../../../src/contexts/tools/domain/
import { copilot } from "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import { buildCursorFlatContract } from "../../../../src/contexts/tools/domain/profiles/cursor/build.js";
import { cursor } from "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import { buildKiloFlatContract } from "../../../../src/contexts/tools/domain/profiles/kilo/build.js";
+import { kilo } from "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import { buildOpencodeFlatContract } from "../../../../src/contexts/tools/domain/profiles/opencode/build.js";
import { opencode } from "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
@@ -28,6 +30,7 @@ const FLAT_CONTRACTS: ReadonlyArray<[HooksDeclaringTool, () => ToolBuildContract
[cursor, buildCursorFlatContract],
[copilot, buildCopilotFlatContract],
[codex, buildCodexFlatContract],
+ [kilo, buildKiloFlatContract],
[opencode, buildOpencodeFlatContract],
];
diff --git a/cli/tests/contexts/tools/domain/formats/opencode-mcp-merge.unit.test.ts b/cli/tests/contexts/tools/domain/formats/opencode-mcp-merge.unit.test.ts
index df7076b69..8f9423a9d 100644
--- a/cli/tests/contexts/tools/domain/formats/opencode-mcp-merge.unit.test.ts
+++ b/cli/tests/contexts/tools/domain/formats/opencode-mcp-merge.unit.test.ts
@@ -220,6 +220,16 @@ describe("buildOpencodeFlatConfig", () => {
expect(config.theme).toBe("dark");
expect(config.mcp.user).toEqual(REMOTE_SERVER);
});
+
+ it("preserves duplicate user instructions while appending generated entries once", () => {
+ const existing = JSON.stringify({
+ instructions: ["user.md", "user.md", ".opencode/rules/**/*.md"],
+ });
+ const config = JSON.parse(buildOpencodeFlatConfig(BASE, existing, {}, ["instructions"])) as {
+ instructions: string[];
+ };
+ expect(config.instructions).toEqual(["user.md", "user.md", ".opencode/rules/**/*.md"]);
+ });
});
describe("unmergeOpencodeMcp", () => {
diff --git a/cli/tests/contexts/tools/domain/plugin-root-token-declaration.unit.test.ts b/cli/tests/contexts/tools/domain/plugin-root-token-declaration.unit.test.ts
index 066ef9544..468a9a00d 100644
--- a/cli/tests/contexts/tools/domain/plugin-root-token-declaration.unit.test.ts
+++ b/cli/tests/contexts/tools/domain/plugin-root-token-declaration.unit.test.ts
@@ -9,6 +9,7 @@ import "../../../../src/contexts/tools/domain/profiles/claude/profile.js";
import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import type { PluginsCapability } from "../../../../src/contexts/tools/domain/capabilities/plugins-capability.js";
import { getAiToolConfig } from "../../../../src/contexts/tools/domain/registry.js";
diff --git a/cli/tests/contexts/tools/domain/profiles/kilo/build.unit.test.ts b/cli/tests/contexts/tools/domain/profiles/kilo/build.unit.test.ts
new file mode 100644
index 000000000..88ea585f8
--- /dev/null
+++ b/cli/tests/contexts/tools/domain/profiles/kilo/build.unit.test.ts
@@ -0,0 +1,108 @@
+import { describe, expect, it } from "vitest";
+import type { ArtifactContract } from "../../../../../../src/contexts/tools/domain/build-contract.js";
+import { buildKiloFlatContract } from "../../../../../../src/contexts/tools/domain/profiles/kilo/build.js";
+import { KiloDualConfigError } from "../../../../../../src/kernel/errors.js";
+import { InMemoryFileAdapter } from "../../../../../helpers/ports/in-memory-file-adapter.js";
+
+function supported(artifact: ArtifactContract): Extract {
+ if (!artifact.supported) throw new Error("artifact is declared unsupported");
+ return artifact;
+}
+
+describe("buildKiloFlatContract", () => {
+ it("places agents, skills, hook scripts and its generated bridge under .kilo", () => {
+ const { artifacts } = buildKiloFlatContract();
+ expect(supported(artifacts.agents).path("aidd-dev", "agents/reviewer.md")).toBe(
+ ".kilo/agents/aidd-dev-reviewer.md"
+ );
+ expect(supported(artifacts.skills).path("aidd-dev", "skills/01-plan/SKILL.md")).toBe(
+ ".kilo/skills/aidd-dev/01-plan/SKILL.md"
+ );
+ const hooks = supported(artifacts.hooks);
+ expect(hooks.path("aidd-context", "hooks/update_memory.js")).toBe(
+ ".kilo/hooks/aidd-context/update_memory.js"
+ );
+ expect(hooks.path("aidd-context", "hooks/kilo-plugin.js")).toBe(".kilo/plugin/aidd-context.js");
+ expect(hooks.hooksBridge?.path("aidd-context")).toBe(".kilo/plugin/aidd-context-hooks.js");
+ });
+
+ it("writes Kilo's project-local base config and Kilo-compatible MCP entries", async () => {
+ const fs = new InMemoryFileAdapter({
+ "/source/plugins/aidd-dev/.mcp.json": JSON.stringify({
+ mcpServers: { context: { command: "node", args: ["server.js"] } },
+ }),
+ });
+ await buildKiloFlatContract().emitConfigArtifact?.(
+ ["aidd-dev"],
+ "/out",
+ "/source",
+ fs,
+ { validate: () => undefined },
+ {
+ loadConfigAsset: () => ({
+ $schema: "https://app.kilo.ai/config.json",
+ instructions: [".kilo/rules/**/*.md"],
+ }),
+ loadSchema: () => ({}),
+ }
+ );
+
+ expect(JSON.parse(fs.getFile("/out/.kilo/kilo.jsonc") ?? "null")).toEqual({
+ $schema: "https://app.kilo.ai/config.json",
+ instructions: [".kilo/rules/**/*.md"],
+ mcp: {
+ "aidd-dev-context": { type: "local", command: ["node", "server.js"], enabled: true },
+ },
+ });
+ });
+
+ it("merges existing JSONC instructions without duplicates", async () => {
+ const fs = new InMemoryFileAdapter({
+ "/out/.kilo/kilo.jsonc":
+ '{\n // project-owned\n "instructions": ["project.md", ".kilo/rules/**/*.md"],\n "theme": "dark",\n}',
+ });
+ const emit = buildKiloFlatContract().emitConfigArtifact;
+ const asset = {
+ loadConfigAsset: () => ({
+ $schema: "https://app.kilo.ai/config.json",
+ instructions: [".kilo/rules/**/*.md"],
+ }),
+ loadSchema: () => ({}),
+ };
+ await emit?.([], "/out", "/source", fs, { validate: () => undefined }, asset);
+ const once = fs.getFile("/out/.kilo/kilo.jsonc");
+ await emit?.([], "/out", "/source", fs, { validate: () => undefined }, asset);
+
+ expect(JSON.parse(once ?? "null")).toEqual({
+ $schema: "https://app.kilo.ai/config.json",
+ instructions: ["project.md", ".kilo/rules/**/*.md"],
+ theme: "dark",
+ });
+ expect(fs.getFile("/out/.kilo/kilo.jsonc")).toBe(once);
+ expect(fs.getFile("/out/.kilo/kilo.json")).toBeUndefined();
+ });
+
+ it("rejects ambiguous Kilo config files without modifying either", async () => {
+ const fs = new InMemoryFileAdapter({
+ "/out/.kilo/kilo.json": "{}",
+ "/out/.kilo/kilo.jsonc": "{}",
+ });
+ const emit = buildKiloFlatContract().emitConfigArtifact;
+
+ await expect(
+ emit?.(
+ [],
+ "/out",
+ "/source",
+ fs,
+ { validate: () => undefined },
+ {
+ loadConfigAsset: () => ({}),
+ loadSchema: () => ({}),
+ }
+ )
+ ).rejects.toThrow(KiloDualConfigError);
+ expect(fs.getFile("/out/.kilo/kilo.json")).toBe("{}");
+ expect(fs.getFile("/out/.kilo/kilo.jsonc")).toBe("{}");
+ });
+});
diff --git a/cli/tests/contexts/tools/domain/profiles/kilo/kilo-hooks-bridge.unit.test.ts b/cli/tests/contexts/tools/domain/profiles/kilo/kilo-hooks-bridge.unit.test.ts
new file mode 100644
index 000000000..ac692a003
--- /dev/null
+++ b/cli/tests/contexts/tools/domain/profiles/kilo/kilo-hooks-bridge.unit.test.ts
@@ -0,0 +1,83 @@
+import { mkdtemp, rm, writeFile } from "node:fs/promises";
+import { tmpdir } from "node:os";
+import { join } from "node:path";
+import { pathToFileURL } from "node:url";
+import { describe, expect, it } from "vitest";
+import {
+ generateKiloHooksBridge,
+ parseKiloSessionStartHooks,
+} from "../../../../../../src/contexts/tools/domain/profiles/kilo/kilo-hooks-bridge.js";
+
+const ROOT = "$" + "{CLAUDE_PLUGIN_ROOT}";
+
+describe("Kilo hooks bridge", () => {
+ it("keeps only replayable SessionStart commands", () => {
+ expect(
+ parseKiloSessionStartHooks(
+ JSON.stringify({
+ hooks: {
+ SessionStart: [
+ {
+ hooks: [
+ { command: `node ${ROOT}/hooks/update_memory.js --quiet` },
+ { command: "python ignored.py" },
+ ],
+ },
+ ],
+ Stop: [{ hooks: [{ command: `node ${ROOT}/hooks/stop.js` }] }],
+ },
+ })
+ )
+ ).toEqual([{ script: "update_memory.js", args: ["--quiet"] }]);
+ });
+
+ it("returns no module when hooks.json has no replayable SessionStart command", () => {
+ expect(
+ generateKiloHooksBridge(JSON.stringify({ hooks: { Stop: [] } }), "aidd-context")
+ ).toBeNull();
+ });
+
+ it("generates an importable Kilo default descriptor and maps SessionStart to session.created", async () => {
+ const generated = generateKiloHooksBridge(
+ JSON.stringify({
+ hooks: {
+ SessionStart: [{ hooks: [{ command: `node ${ROOT}/hooks/update_memory.js` }] }],
+ },
+ }),
+ "aidd-context"
+ );
+
+ expect(generated).toContain(
+ 'export default { id: "aidd-context-hooks", server: AiddContextKiloHooks }'
+ );
+ expect(generated).toContain('event?.type !== "session.created"');
+ expect(generated).toContain('hook_event_name: "SessionStart"');
+ expect(generated).toContain("Kilo session-start hook");
+
+ const directory = await mkdtemp(join(tmpdir(), "aidd-kilo-hooks-bridge-"));
+ try {
+ const modulePath = join(directory, "bridge.mjs");
+ await writeFile(modulePath, generated ?? "", "utf8");
+ const module = (await import(pathToFileURL(modulePath).href)) as {
+ default: {
+ id: string;
+ server: {
+ sessionStartCallsFor: (event: unknown, cwd: string) => readonly unknown[];
+ };
+ };
+ };
+ expect(module.default.id).toBe("aidd-context-hooks");
+ expect(
+ module.default.server.sessionStartCallsFor({ type: "session.created" }, "/project")
+ ).toEqual([
+ {
+ script: "update_memory.js",
+ args: [],
+ payload: { hook_event_name: "SessionStart", session_id: null, cwd: "/project" },
+ },
+ ]);
+ } finally {
+ await rm(directory, { recursive: true, force: true });
+ }
+ });
+});
diff --git a/cli/tests/contexts/tools/domain/profiles/kilo/profile.unit.test.ts b/cli/tests/contexts/tools/domain/profiles/kilo/profile.unit.test.ts
new file mode 100644
index 000000000..be859c694
--- /dev/null
+++ b/cli/tests/contexts/tools/domain/profiles/kilo/profile.unit.test.ts
@@ -0,0 +1,68 @@
+import { describe, expect, it } from "vitest";
+import { kilo } from "../../../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
+import { KiloDualConfigError } from "../../../../../../src/kernel/errors.js";
+import { FileHash } from "../../../../../../src/kernel/file.js";
+import type { FileReader } from "../../../../../../src/kernel/ports/file-reader.js";
+
+function makeFs(existingPaths: string[]): FileReader {
+ return {
+ fileExists: async (path) =>
+ existingPaths.includes(path.replaceAll("\\", "/").replace(/^\/project\//, "")),
+ isExecutable: async () => false,
+ realpath: async (path) => path,
+ readFile: async () => "",
+ readFileHash: async () => new FileHash("00000000000000000000000000000000"),
+ listDirectory: async () => [],
+ listFilesRecursive: async () => [],
+ };
+}
+
+describe("kilo", () => {
+ it("declares a flat build with Kilo's agents and skills paths", () => {
+ expect(kilo.buildContracts?.flat).toBeDefined();
+ expect(kilo.capabilities.agents.buildInstallPath("reviewer.kilo.md")).toBe(
+ ".kilo/agents/reviewer.md"
+ );
+ expect(kilo.capabilities.skills.buildInstallPath("01-plan/SKILL.kilo.md")).toBe(
+ ".kilo/skills/01-plan/SKILL.md"
+ );
+ expect(kilo.capabilities.commands.buildInstallPath("01-plan/greet.md")).toBe(
+ ".kilo/commands/aidd/01/greet.md"
+ );
+ expect(kilo.capabilities.rules.buildInstallPath("standards.kilo.md")).toBe(
+ ".kilo/rules/standards.md"
+ );
+ });
+
+ it("prefers project-local JSONC and reuses an existing Kilo config", async () => {
+ expect(await kilo.capabilities.mcp.resolveOutput("/project", makeFs([]))).toBe(
+ ".kilo/kilo.jsonc"
+ );
+ expect(await kilo.capabilities.mcp.resolveOutput("/project", makeFs([".kilo/kilo.json"]))).toBe(
+ ".kilo/kilo.json"
+ );
+ expect(await kilo.capabilities.mcp.resolveOutput("/project", makeFs(["kilo.jsonc"]))).toBe(
+ "kilo.jsonc"
+ );
+ await expect(
+ kilo.capabilities.mcp.resolveOutput("/project", makeFs(["kilo.json", "kilo.jsonc"]))
+ ).rejects.toThrow(KiloDualConfigError);
+ await expect(
+ kilo.capabilities.mcp.resolveOutput(
+ "/project",
+ makeFs([".kilo/kilo.json", ".kilo/kilo.jsonc"])
+ )
+ ).rejects.toThrow(KiloDualConfigError);
+ });
+
+ it("delivers hook scripts under .kilo/hooks and generates a bridge under .kilo/plugin", () => {
+ expect(kilo.capabilities.plugins).toMatchObject({
+ mode: "flat",
+ acceptsHooks: true,
+ flatHooksDir: ".kilo/hooks/",
+ });
+ expect(kilo.capabilities.plugins.flatHooksBridge?.path("aidd-context")).toBe(
+ ".kilo/plugin/aidd-context-hooks.js"
+ );
+ });
+});
diff --git a/cli/tests/contexts/tools/domain/registry-conformance.unit.test.ts b/cli/tests/contexts/tools/domain/registry-conformance.unit.test.ts
index 052803d28..f1d6525be 100644
--- a/cli/tests/contexts/tools/domain/registry-conformance.unit.test.ts
+++ b/cli/tests/contexts/tools/domain/registry-conformance.unit.test.ts
@@ -6,6 +6,7 @@ import "../../../../src/contexts/tools/domain/profiles/claude/profile.js";
import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import "../../../../src/contexts/tools/domain/profiles/vscode/profile.js";
import type { ToolBuildContract } from "../../../../src/contexts/tools/domain/build-contract.js";
@@ -139,6 +140,7 @@ describe("telemetryLocalRead — exact declarations, phase 2 of local-cost-read"
opencode: { kind: "declared" },
copilot: { kind: "declared" },
cursor: { kind: "unsupported", reason: "token count" },
+ kilo: { kind: "unsupported", reason: "telemetry has not been measured" },
};
it.each(Object.entries(EXPECTED))("%s", (toolId, expected) => {
@@ -392,6 +394,7 @@ describe("every tool says where its own installed rules live", () => {
codex: { directory: ".codex/rules/", extension: ".md" },
copilot: { directory: ".github/instructions/", extension: ".instructions.md" },
cursor: { directory: ".cursor/rules/", extension: ".mdc" },
+ kilo: { directory: ".kilo/rules/", extension: ".md" },
opencode: { directory: ".opencode/rules/", extension: ".md" },
};
diff --git a/cli/tests/contexts/tools/domain/telemetry-route-supply.unit.test.ts b/cli/tests/contexts/tools/domain/telemetry-route-supply.unit.test.ts
index 2c9191acb..e45b601e7 100644
--- a/cli/tests/contexts/tools/domain/telemetry-route-supply.unit.test.ts
+++ b/cli/tests/contexts/tools/domain/telemetry-route-supply.unit.test.ts
@@ -5,6 +5,7 @@ import "../../../../src/contexts/tools/domain/profiles/claude/profile.js";
import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import { mapClaudeCodeTranscriptToSinkRecords } from "../../../../src/contexts/telemetry/domain/formats/claude-code-transcript.js";
import { mapCodexRolloutToSinkRecords } from "../../../../src/contexts/telemetry/domain/formats/codex-rollout.js";
diff --git a/cli/tests/contexts/tools/domain/tool-config.unit.test.ts b/cli/tests/contexts/tools/domain/tool-config.unit.test.ts
index 7c037aaa1..ddb69df31 100644
--- a/cli/tests/contexts/tools/domain/tool-config.unit.test.ts
+++ b/cli/tests/contexts/tools/domain/tool-config.unit.test.ts
@@ -25,8 +25,16 @@ const makeStubConfig = (toolId: AiToolId, toolSuffix: string): AiTool =
});
describe("VALID_TOOL_IDS", () => {
- it("contains exactly claude, cursor, copilot, opencode, codex, vscode", () => {
- expect(VALID_TOOL_IDS).toEqual(["claude", "cursor", "copilot", "opencode", "codex", "vscode"]);
+ it("contains exactly claude, cursor, copilot, opencode, kilo, codex, vscode", () => {
+ expect(VALID_TOOL_IDS).toEqual([
+ "claude",
+ "cursor",
+ "copilot",
+ "opencode",
+ "kilo",
+ "codex",
+ "vscode",
+ ]);
});
});
@@ -52,7 +60,14 @@ describe("stripToolSuffix()", () => {
describe("toolIdsForCategory()", () => {
it("returns AI tool IDs for 'ai'", () => {
- expect(toolIdsForCategory("ai")).toEqual(["claude", "cursor", "copilot", "opencode", "codex"]);
+ expect(toolIdsForCategory("ai")).toEqual([
+ "claude",
+ "cursor",
+ "copilot",
+ "opencode",
+ "kilo",
+ "codex",
+ ]);
});
it("returns IDE tool IDs for 'ide'", () => {
diff --git a/cli/tests/contexts/tools/infrastructure/host-marketplace-registry-reader-adapter.integration.test.ts b/cli/tests/contexts/tools/infrastructure/host-marketplace-registry-reader-adapter.integration.test.ts
index 3a8045a45..ceeaaa307 100644
--- a/cli/tests/contexts/tools/infrastructure/host-marketplace-registry-reader-adapter.integration.test.ts
+++ b/cli/tests/contexts/tools/infrastructure/host-marketplace-registry-reader-adapter.integration.test.ts
@@ -8,6 +8,7 @@ import "../../../../src/contexts/tools/domain/profiles/claude/profile.js";
import "../../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import "../../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import "../../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import { nativeActivationOf } from "../../../../src/contexts/tools/domain/registry.js";
import { hostMarketplaceRegistryReaders } from "../../../../src/contexts/tools/infrastructure/host-marketplace-registry-reader-adapter.js";
diff --git a/cli/tests/e2e/framework-build.e2e.test.ts b/cli/tests/e2e/framework-build.e2e.test.ts
index 659058548..5eab0766e 100644
--- a/cli/tests/e2e/framework-build.e2e.test.ts
+++ b/cli/tests/e2e/framework-build.e2e.test.ts
@@ -593,6 +593,31 @@ describe.concurrent("E2E: aidd translate", () => {
}
});
+ it("--target kilo --flat emits its agents, skills, generated hooks bridge and project config", async () => {
+ const { tempDir, projectDir, fakeHome, cleanup } = await createTestEnv("fw-flat-kilo");
+ try {
+ const projRoot = join(tempDir, "proj");
+ await mkdir(projRoot, { recursive: true });
+ const result = await runCli(
+ ["translate", FRAMEWORK_PATH, "--to", "kilo", "--as", "flat", "--out", projRoot],
+ projectDir,
+ fakeHome
+ );
+ expect(result.exitCode).toBe(0);
+ expect(existsSync(join(projRoot, ".kilo", "agents"))).toBe(true);
+ expect(existsSync(join(projRoot, ".kilo", "skills"))).toBe(true);
+ expect(existsSync(join(projRoot, ".kilo", "plugin", "aidd-test-hooks.js"))).toBe(true);
+ const kilo = JSON.parse(
+ await readFile(join(projRoot, ".kilo", "kilo.jsonc"), "utf-8")
+ ) as Record;
+ expect(kilo.$schema).toBe("https://app.kilo.ai/config.json");
+ expect(kilo.instructions).toEqual([".kilo/rules/**/*.md"]);
+ expect(kilo.mcp).toBeDefined();
+ } finally {
+ await cleanup();
+ }
+ });
+
it("AC #7: --target opencode (non-flat) exits 1 with unsupported error", async () => {
const { tempDir, projectDir, fakeHome, cleanup } = await createTestEnv("fw-opencode-no-flat");
try {
diff --git a/cli/tests/e2e/helpers.ts b/cli/tests/e2e/helpers.ts
index 751f7dc11..4a2ce22bf 100644
--- a/cli/tests/e2e/helpers.ts
+++ b/cli/tests/e2e/helpers.ts
@@ -196,7 +196,16 @@ export function sandboxedEnv(
// A minimal PATH, not the runner's own: the OpenCode reader shells out to an `opencode`
// binary and waits up to 10s for it, so a machine carrying the tool pays a cost one
// without it does not.
- const base = { ...withoutGitEnv(process.env), PATH: pathWithoutAidd(), Path: pathWithoutAidd() };
+ const base: NodeJS.ProcessEnv = {
+ ...withoutGitEnv(process.env),
+ PATH: pathWithoutAidd(),
+ Path: pathWithoutAidd(),
+ };
+ // The test runner may itself be nested in Codex or Claude. Host session variables must not
+ // leak into a sandboxed child, otherwise a Claude fixture can be classified as Codex before
+ // the test's explicit `env` is applied.
+ delete base.CODEX_THREAD_ID;
+ delete base.CLAUDE_CODE_SESSION_ID;
if (options?.realHome) {
return { ...base, ...extra, AIDD_USER_CONFIG_DIR: join(fakeHome, ".config", "aidd") };
}
diff --git a/cli/tests/e2e/kilo-runtime.e2e.test.ts b/cli/tests/e2e/kilo-runtime.e2e.test.ts
new file mode 100644
index 000000000..e51c20ba8
--- /dev/null
+++ b/cli/tests/e2e/kilo-runtime.e2e.test.ts
@@ -0,0 +1,162 @@
+import { spawn } from "node:child_process";
+import { existsSync } from "node:fs";
+import { mkdir, readFile, writeFile } from "node:fs/promises";
+import { join } from "node:path";
+import { setTimeout as delay } from "node:timers/promises";
+import { describe, expect, it } from "vitest";
+import { REPOSITORY_ROOT } from "../helpers/repository-root.js";
+import { createTestEnv, execFileAsync, runCli, sandboxedEnv } from "./helpers.js";
+
+const describeKiloRuntime = process.env.KILO_RUNTIME_SMOKE === "1" ? describe : describe.skip;
+const KILO_PREFIX = join(
+ process.env.APPDATA ?? join(process.env.USERPROFILE ?? "", "AppData", "Roaming"),
+ "npm",
+ "node_modules",
+ "@kilocode",
+ "cli"
+);
+const KILO_BIN =
+ process.platform !== "win32"
+ ? "kilo"
+ : ([
+ join(KILO_PREFIX, "node_modules", "@kilocode", "cli-windows-x64", "bin", "kilo.exe"),
+ join(
+ KILO_PREFIX,
+ "node_modules",
+ "@kilocode",
+ "cli-windows-x64-baseline",
+ "bin",
+ "kilo.exe"
+ ),
+ join(KILO_PREFIX, "node_modules", "@kilocode", "cli-windows-arm64", "bin", "kilo.exe"),
+ ].find((path) => existsSync(path)) ?? join(process.env.APPDATA ?? "", "npm", "kilo.cmd"));
+const KILO_SHELL = KILO_BIN.endsWith(".cmd");
+
+async function markerContent(path: string): Promise {
+ try {
+ return await readFile(path, "utf8");
+ } catch {
+ return "";
+ }
+}
+
+async function waitForMarker(path: string): Promise {
+ for (let attempt = 0; attempt < 50; attempt += 1) {
+ const content = await markerContent(path);
+ if (content !== "") return content;
+ await delay(100);
+ }
+ return markerContent(path);
+}
+
+async function startKilo(directory: string, env: NodeJS.ProcessEnv) {
+ const child = spawn(KILO_BIN, ["serve", "--hostname", "127.0.0.1", "--port", "0"], {
+ cwd: directory,
+ env,
+ shell: KILO_SHELL,
+ stdio: ["ignore", "pipe", "pipe"],
+ });
+ const output = Promise.withResolvers();
+ let text = "";
+ const collect = (chunk: Buffer) => {
+ text += chunk.toString();
+ const match = text.match(/kilo server listening on http:\/\/127\.0\.0\.1:(\d+)/);
+ if (match) output.resolve(match[1]);
+ };
+ child.stdout.on("data", collect);
+ child.stderr.on("data", collect);
+ const timer = setTimeout(() => output.reject(new Error(`Kilo did not start:\n${text}`)), 15000);
+ try {
+ const port = await output.promise;
+ return { child, port };
+ } catch (error) {
+ await stopKilo(child);
+ throw error;
+ } finally {
+ clearTimeout(timer);
+ }
+}
+
+async function stopKilo(child: ReturnType): Promise {
+ const exited = Promise.withResolvers();
+ child.once("exit", () => exited.resolve());
+ if (child.exitCode === null) {
+ child.kill("SIGTERM");
+ }
+ if (child.exitCode !== null) exited.resolve();
+ if (KILO_SHELL && process.platform === "win32" && child.pid !== undefined) {
+ try {
+ await execFileAsync("taskkill", ["/pid", String(child.pid), "/t", "/f"]);
+ } catch (error) {
+ const message = String(error);
+ if (
+ child.exitCode === null &&
+ !message.includes("introuvable") &&
+ !message.includes("not found")
+ ) {
+ throw error;
+ }
+ }
+ }
+ await Promise.race([exited.promise, delay(5000)]);
+}
+
+describeKiloRuntime("E2E: real Kilo runtime", () => {
+ it("loads the generated plugin and fires session.created through Kilo", async () => {
+ const { tempDir, projectDir, fakeHome, cleanup } = await createTestEnv("kilo-runtime");
+ let child: ReturnType | undefined;
+ try {
+ const generatedProject = join(tempDir, "generated");
+ await mkdir(generatedProject, { recursive: true });
+ const build = await runCli(
+ ["translate", REPOSITORY_ROOT, "--to", "kilo", "--as", "flat", "--out", generatedProject],
+ projectDir,
+ fakeHome
+ );
+ expect(build.exitCode, build.stderr).toBe(0);
+
+ const env = sandboxedEnv(fakeHome);
+ const skills = await execFileAsync(KILO_BIN, ["debug", "skill"], {
+ cwd: generatedProject,
+ env,
+ shell: process.platform === "win32",
+ maxBuffer: 8 * 1024 * 1024,
+ });
+ const discoveredSkills = JSON.parse(skills.stdout) as Array<{ location?: string }>;
+ expect(
+ discoveredSkills.filter((skill) =>
+ skill.location?.replaceAll("\\", "/").includes(".kilo/skills/aidd-")
+ ).length
+ ).toBe(50);
+
+ const agents = await execFileAsync(KILO_BIN, ["agent", "list"], {
+ cwd: generatedProject,
+ env,
+ shell: process.platform === "win32",
+ maxBuffer: 8 * 1024 * 1024,
+ });
+ expect(agents.stdout).toContain("aidd-dev-checker");
+ expect(agents.stdout).toContain("aidd-dev-executor");
+
+ const marker = join(generatedProject, "session-start.marker");
+ await writeFile(
+ join(generatedProject, ".kilo", "hooks", "aidd-context", "update_memory.js"),
+ `require("node:fs").appendFileSync(${JSON.stringify(marker)}, "fired\\n");\n`
+ );
+ const bridgePath = join(generatedProject, ".kilo", "plugin", "aidd-context-hooks.js");
+ expect(existsSync(bridgePath)).toBe(true);
+
+ const started = await startKilo(generatedProject, env);
+ child = started.child;
+ const response = await fetch(`http://127.0.0.1:${started.port}/session`, {
+ method: "POST",
+ headers: { "x-kilo-directory": generatedProject },
+ });
+ expect(response.ok).toBe(true);
+ expect(await waitForMarker(marker)).toBe("fired\n");
+ } finally {
+ if (child) await stopKilo(child);
+ await cleanup();
+ }
+ }, 120000);
+});
diff --git a/cli/tests/e2e/persona.e2e.test.ts b/cli/tests/e2e/persona.e2e.test.ts
index a25d9ccf5..e690918af 100644
--- a/cli/tests/e2e/persona.e2e.test.ts
+++ b/cli/tests/e2e/persona.e2e.test.ts
@@ -54,7 +54,7 @@ describe.concurrent("E2E: persona journeys", () => {
projectDir,
fakeHome,
`
-spawn node ${cliPath()}
+spawn ${process.execPath} ${cliPath()}
expect {
-re {AI-Driven Development CLI} { puts "BANNER_OK" }
timeout { puts "TIMEOUT"; exit 1 }
@@ -241,7 +241,7 @@ exit 0
projectDir,
fakeHome,
`
-spawn bash -c "cd '${projectDir}' && node ${cliPath()}"
+spawn bash -c "cd '${projectDir}' && ${process.execPath} ${cliPath()}"
expect {
-re {AI-Driven Development CLI} { puts "BANNER_OK" }
timeout { puts "TIMEOUT"; exit 1 }
diff --git a/cli/tests/fixtures/cli-owns-read/expected-envelope.json b/cli/tests/fixtures/cli-owns-read/expected-envelope.json
index dd6ee3795..00d396af9 100644
--- a/cli/tests/fixtures/cli-owns-read/expected-envelope.json
+++ b/cli/tests/fixtures/cli-owns-read/expected-envelope.json
@@ -207,6 +207,20 @@
"requests": 0
}
},
+ {
+ "tool": "kilo",
+ "coverage": "not-covered",
+ "reason": "Kilo OpenTelemetry is experimental and not yet supported by AIDD.",
+ "capability": {
+ "local_read": null,
+ "export": null,
+ "journal_attributable": false,
+ "task_attributable": false
+ },
+ "totals": {
+ "requests": 0
+ }
+ },
{
"tool": "codex",
"coverage": "covered",
diff --git a/cli/tests/fixtures/framework/plugins/aidd-test/hooks/hooks.json b/cli/tests/fixtures/framework/plugins/aidd-test/hooks/hooks.json
index 51eaba2e2..cd671f51e 100644
--- a/cli/tests/fixtures/framework/plugins/aidd-test/hooks/hooks.json
+++ b/cli/tests/fixtures/framework/plugins/aidd-test/hooks/hooks.json
@@ -1,5 +1,15 @@
{
"hooks": {
+ "SessionStart": [
+ {
+ "hooks": [
+ {
+ "type": "command",
+ "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/session-start.js"
+ }
+ ]
+ }
+ ],
"PreToolUse": [
{
"hooks": [
diff --git a/cli/tests/fixtures/framework/plugins/aidd-test/hooks/session-start.js b/cli/tests/fixtures/framework/plugins/aidd-test/hooks/session-start.js
new file mode 100644
index 000000000..e954de435
--- /dev/null
+++ b/cli/tests/fixtures/framework/plugins/aidd-test/hooks/session-start.js
@@ -0,0 +1,2 @@
+// Fixture command replayed by the generated OpenCode and Kilo session-start bridges.
+process.exit(0);
diff --git a/cli/tests/golden/framework-build-golden.e2e.test.ts b/cli/tests/golden/framework-build-golden.e2e.test.ts
index 1c9da1fd9..9d6686ec8 100644
--- a/cli/tests/golden/framework-build-golden.e2e.test.ts
+++ b/cli/tests/golden/framework-build-golden.e2e.test.ts
@@ -20,7 +20,7 @@ type TargetSnapshot = Record; // rel-path → sha256
type GoldenSnapshot = Record; // key → files
const MARKETPLACE_TARGETS = ["copilot", "codex", "claude", "cursor"] as const;
-const FLAT_TARGETS = ["claude", "cursor", "copilot", "codex", "opencode"] as const;
+const FLAT_TARGETS = ["claude", "cursor", "copilot", "codex", "opencode", "kilo"] as const;
const FROZEN_CELLS = new Set([
...MARKETPLACE_TARGETS,
@@ -107,7 +107,7 @@ async function captureAllCells(
return captured;
}
-describe.concurrent("Framework build golden — 9-cell matrix", () => {
+describe.concurrent("Framework build golden — 10-cell matrix", () => {
// Two full 9-cell builds measured just past the 60s default on a Windows runner, not a
// hang. Raised per test so no other e2e file's budget moves.
it("snapshot is deterministic (two captures of each target are byte-identical)", async () => {
@@ -154,7 +154,7 @@ describe.concurrent("Framework build golden — 9-cell matrix", () => {
}
}, 120_000);
- it("every one of the 9 cells is byte-identical to its stored baseline", async () => {
+ it("every one of the 10 cells is byte-identical to its stored baseline", async () => {
const { tempDir, projectDir, fakeHome, cleanup } = await createTestEnv("fb-golden-baseline");
try {
const captured = await captureAllCells(projectDir, fakeHome, tempDir);
diff --git a/cli/tests/golden/snapshots/framework-build/golden.json b/cli/tests/golden/snapshots/framework-build/golden.json
index ae1e4c4af..0673c7634 100644
--- a/cli/tests/golden/snapshots/framework-build/golden.json
+++ b/cli/tests/golden/snapshots/framework-build/golden.json
@@ -11,10 +11,10 @@
"plugins/aidd-vcs/skills/03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
"plugins/aidd-vcs/skills/02-pull-request/SKILL.md": "cea82673d19b5a77d2fbbb60c6961802b3cd3c04fd098da0ab32ed6ef5e596d7",
"plugins/aidd-vcs/skills/02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- "plugins/aidd-vcs/skills/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- "plugins/aidd-vcs/skills/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
"plugins/aidd-vcs/skills/02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ "plugins/aidd-vcs/skills/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
"plugins/aidd-vcs/skills/02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ "plugins/aidd-vcs/skills/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
"plugins/aidd-vcs/skills/02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
"plugins/aidd-vcs/skills/01-commit/SKILL.md": "9d4fb8c3091dbc72e77bb8be77e8842d1204add3589e8dffccebb36ec5e5d680",
"plugins/aidd-vcs/skills/01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -130,17 +130,17 @@
"plugins/aidd-context/skills/02-project-init/SKILL.md": "771551e0929afbf631088e98e4d0ddc267b1ef87e393381e493171c599a50762",
"plugins/aidd-context/skills/02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
"plugins/aidd-context/skills/02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ "plugins/aidd-context/skills/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
"plugins/aidd-context/skills/02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
"plugins/aidd-context/skills/02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- "plugins/aidd-context/skills/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
"plugins/aidd-context/skills/02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
"plugins/aidd-context/skills/02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- "plugins/aidd-context/skills/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ "plugins/aidd-context/skills/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -211,10 +211,10 @@
"plugins/aidd-vcs/skills/03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
"plugins/aidd-vcs/skills/02-pull-request/SKILL.md": "9a4258f4b2206b7502469191b628f4dccf70ef194cbec839c8992fd08bf74d2f",
"plugins/aidd-vcs/skills/02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- "plugins/aidd-vcs/skills/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- "plugins/aidd-vcs/skills/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
"plugins/aidd-vcs/skills/02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ "plugins/aidd-vcs/skills/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
"plugins/aidd-vcs/skills/02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ "plugins/aidd-vcs/skills/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
"plugins/aidd-vcs/skills/02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
"plugins/aidd-vcs/skills/01-commit/SKILL.md": "613de1c46477fa90b18b12145cb032bb481b6d75afbc55020129643351a6ee47",
"plugins/aidd-vcs/skills/01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -330,17 +330,17 @@
"plugins/aidd-context/skills/02-project-init/SKILL.md": "f957b5662aaa85b206916067d8a91dba7dac6660df1bb6f1f8772530726bfa08",
"plugins/aidd-context/skills/02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
"plugins/aidd-context/skills/02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ "plugins/aidd-context/skills/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
"plugins/aidd-context/skills/02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
"plugins/aidd-context/skills/02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- "plugins/aidd-context/skills/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
"plugins/aidd-context/skills/02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
"plugins/aidd-context/skills/02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- "plugins/aidd-context/skills/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ "plugins/aidd-context/skills/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -411,10 +411,10 @@
"plugins/aidd-vcs/skills/03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
"plugins/aidd-vcs/skills/02-pull-request/SKILL.md": "cea82673d19b5a77d2fbbb60c6961802b3cd3c04fd098da0ab32ed6ef5e596d7",
"plugins/aidd-vcs/skills/02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- "plugins/aidd-vcs/skills/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- "plugins/aidd-vcs/skills/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
"plugins/aidd-vcs/skills/02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ "plugins/aidd-vcs/skills/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
"plugins/aidd-vcs/skills/02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ "plugins/aidd-vcs/skills/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
"plugins/aidd-vcs/skills/02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
"plugins/aidd-vcs/skills/01-commit/SKILL.md": "9d4fb8c3091dbc72e77bb8be77e8842d1204add3589e8dffccebb36ec5e5d680",
"plugins/aidd-vcs/skills/01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -530,17 +530,17 @@
"plugins/aidd-context/skills/02-project-init/SKILL.md": "771551e0929afbf631088e98e4d0ddc267b1ef87e393381e493171c599a50762",
"plugins/aidd-context/skills/02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
"plugins/aidd-context/skills/02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ "plugins/aidd-context/skills/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
"plugins/aidd-context/skills/02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
"plugins/aidd-context/skills/02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- "plugins/aidd-context/skills/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
"plugins/aidd-context/skills/02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
"plugins/aidd-context/skills/02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- "plugins/aidd-context/skills/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ "plugins/aidd-context/skills/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -611,10 +611,10 @@
"plugins/aidd-vcs/skills/03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
"plugins/aidd-vcs/skills/02-pull-request/SKILL.md": "cea82673d19b5a77d2fbbb60c6961802b3cd3c04fd098da0ab32ed6ef5e596d7",
"plugins/aidd-vcs/skills/02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- "plugins/aidd-vcs/skills/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- "plugins/aidd-vcs/skills/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
"plugins/aidd-vcs/skills/02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ "plugins/aidd-vcs/skills/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
"plugins/aidd-vcs/skills/02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ "plugins/aidd-vcs/skills/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
"plugins/aidd-vcs/skills/02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
"plugins/aidd-vcs/skills/01-commit/SKILL.md": "9d4fb8c3091dbc72e77bb8be77e8842d1204add3589e8dffccebb36ec5e5d680",
"plugins/aidd-vcs/skills/01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -730,17 +730,17 @@
"plugins/aidd-context/skills/02-project-init/SKILL.md": "771551e0929afbf631088e98e4d0ddc267b1ef87e393381e493171c599a50762",
"plugins/aidd-context/skills/02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
"plugins/aidd-context/skills/02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ "plugins/aidd-context/skills/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
"plugins/aidd-context/skills/02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
"plugins/aidd-context/skills/02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- "plugins/aidd-context/skills/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
"plugins/aidd-context/skills/02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
"plugins/aidd-context/skills/02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- "plugins/aidd-context/skills/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ "plugins/aidd-context/skills/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
"plugins/aidd-context/skills/02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -813,10 +813,10 @@
".claude/skills/aidd-vcs-03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
".claude/skills/aidd-vcs-02-pull-request/SKILL.md": "80c8d4f2dc28e4d1b67d418c12a865ba74ffc8b57720eb05bdf1e1fca3b82a6a",
".claude/skills/aidd-vcs-02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- ".claude/skills/aidd-vcs-02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- ".claude/skills/aidd-vcs-02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".claude/skills/aidd-vcs-02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ ".claude/skills/aidd-vcs-02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
".claude/skills/aidd-vcs-02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ ".claude/skills/aidd-vcs-02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".claude/skills/aidd-vcs-02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
".claude/skills/aidd-vcs-01-commit/SKILL.md": "1825b3994a89c0394271c3437a772e74892e4bfb5fac9c2dbc90739544404585",
".claude/skills/aidd-vcs-01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -923,17 +923,17 @@
".claude/skills/aidd-context-02-project-init/SKILL.md": "4bd40beb8290018b6fa58b651d3681e13465b39b84c3e4c0c39964aefcc52002",
".claude/skills/aidd-context-02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
".claude/skills/aidd-context-02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ ".claude/skills/aidd-context-02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".claude/skills/aidd-context-02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
".claude/skills/aidd-context-02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- ".claude/skills/aidd-context-02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".claude/skills/aidd-context-02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
".claude/skills/aidd-context-02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- ".claude/skills/aidd-context-02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".claude/skills/aidd-context-02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
".claude/skills/aidd-context-02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
".claude/skills/aidd-context-02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
".claude/skills/aidd-context-02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
".claude/skills/aidd-context-02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ ".claude/skills/aidd-context-02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".claude/skills/aidd-context-02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
".claude/skills/aidd-context-02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
".claude/skills/aidd-context-02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -1004,10 +1004,10 @@
".cursor/skills/aidd-vcs-03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
".cursor/skills/aidd-vcs-02-pull-request/SKILL.md": "80c8d4f2dc28e4d1b67d418c12a865ba74ffc8b57720eb05bdf1e1fca3b82a6a",
".cursor/skills/aidd-vcs-02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- ".cursor/skills/aidd-vcs-02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- ".cursor/skills/aidd-vcs-02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".cursor/skills/aidd-vcs-02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ ".cursor/skills/aidd-vcs-02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
".cursor/skills/aidd-vcs-02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ ".cursor/skills/aidd-vcs-02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".cursor/skills/aidd-vcs-02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
".cursor/skills/aidd-vcs-01-commit/SKILL.md": "1825b3994a89c0394271c3437a772e74892e4bfb5fac9c2dbc90739544404585",
".cursor/skills/aidd-vcs-01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -1114,17 +1114,17 @@
".cursor/skills/aidd-context-02-project-init/SKILL.md": "4bd40beb8290018b6fa58b651d3681e13465b39b84c3e4c0c39964aefcc52002",
".cursor/skills/aidd-context-02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
".cursor/skills/aidd-context-02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ ".cursor/skills/aidd-context-02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".cursor/skills/aidd-context-02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
".cursor/skills/aidd-context-02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- ".cursor/skills/aidd-context-02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".cursor/skills/aidd-context-02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
".cursor/skills/aidd-context-02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- ".cursor/skills/aidd-context-02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".cursor/skills/aidd-context-02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
".cursor/skills/aidd-context-02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
".cursor/skills/aidd-context-02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
".cursor/skills/aidd-context-02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
".cursor/skills/aidd-context-02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ ".cursor/skills/aidd-context-02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".cursor/skills/aidd-context-02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
".cursor/skills/aidd-context-02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
".cursor/skills/aidd-context-02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -1194,10 +1194,10 @@
".github/skills/aidd-vcs-03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
".github/skills/aidd-vcs-02-pull-request/SKILL.md": "80c8d4f2dc28e4d1b67d418c12a865ba74ffc8b57720eb05bdf1e1fca3b82a6a",
".github/skills/aidd-vcs-02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- ".github/skills/aidd-vcs-02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- ".github/skills/aidd-vcs-02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".github/skills/aidd-vcs-02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ ".github/skills/aidd-vcs-02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
".github/skills/aidd-vcs-02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ ".github/skills/aidd-vcs-02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".github/skills/aidd-vcs-02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
".github/skills/aidd-vcs-01-commit/SKILL.md": "1825b3994a89c0394271c3437a772e74892e4bfb5fac9c2dbc90739544404585",
".github/skills/aidd-vcs-01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -1304,17 +1304,17 @@
".github/skills/aidd-context-02-project-init/SKILL.md": "4bd40beb8290018b6fa58b651d3681e13465b39b84c3e4c0c39964aefcc52002",
".github/skills/aidd-context-02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
".github/skills/aidd-context-02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ ".github/skills/aidd-context-02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".github/skills/aidd-context-02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
".github/skills/aidd-context-02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- ".github/skills/aidd-context-02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".github/skills/aidd-context-02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
".github/skills/aidd-context-02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- ".github/skills/aidd-context-02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".github/skills/aidd-context-02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
".github/skills/aidd-context-02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
".github/skills/aidd-context-02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
".github/skills/aidd-context-02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
".github/skills/aidd-context-02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ ".github/skills/aidd-context-02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".github/skills/aidd-context-02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
".github/skills/aidd-context-02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
".github/skills/aidd-context-02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -1392,10 +1392,10 @@
".agents/skills/aidd-vcs-03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
".agents/skills/aidd-vcs-02-pull-request/SKILL.md": "80c8d4f2dc28e4d1b67d418c12a865ba74ffc8b57720eb05bdf1e1fca3b82a6a",
".agents/skills/aidd-vcs-02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- ".agents/skills/aidd-vcs-02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- ".agents/skills/aidd-vcs-02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".agents/skills/aidd-vcs-02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ ".agents/skills/aidd-vcs-02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
".agents/skills/aidd-vcs-02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ ".agents/skills/aidd-vcs-02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".agents/skills/aidd-vcs-02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
".agents/skills/aidd-vcs-01-commit/SKILL.md": "1825b3994a89c0394271c3437a772e74892e4bfb5fac9c2dbc90739544404585",
".agents/skills/aidd-vcs-01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -1502,17 +1502,17 @@
".agents/skills/aidd-context-02-project-init/SKILL.md": "4bd40beb8290018b6fa58b651d3681e13465b39b84c3e4c0c39964aefcc52002",
".agents/skills/aidd-context-02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
".agents/skills/aidd-context-02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ ".agents/skills/aidd-context-02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".agents/skills/aidd-context-02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
".agents/skills/aidd-context-02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- ".agents/skills/aidd-context-02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".agents/skills/aidd-context-02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
".agents/skills/aidd-context-02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- ".agents/skills/aidd-context-02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".agents/skills/aidd-context-02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
".agents/skills/aidd-context-02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
".agents/skills/aidd-context-02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
".agents/skills/aidd-context-02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
".agents/skills/aidd-context-02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ ".agents/skills/aidd-context-02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".agents/skills/aidd-context-02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
".agents/skills/aidd-context-02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
".agents/skills/aidd-context-02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -1577,10 +1577,10 @@
".opencode/skills/aidd-vcs/03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
".opencode/skills/aidd-vcs/02-pull-request/SKILL.md": "b2dbed7de2a3a4b2e646f874747a8e45d5fc25fdfc7c82ce9487e29c7e416ecf",
".opencode/skills/aidd-vcs/02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
- ".opencode/skills/aidd-vcs/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
- ".opencode/skills/aidd-vcs/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".opencode/skills/aidd-vcs/02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ ".opencode/skills/aidd-vcs/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
".opencode/skills/aidd-vcs/02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ ".opencode/skills/aidd-vcs/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
".opencode/skills/aidd-vcs/02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
".opencode/skills/aidd-vcs/01-commit/SKILL.md": "7b88897ab9d7a5e2f6d7d9b2d424a8a77d54cdbfe547d94b0288cdacda411a50",
".opencode/skills/aidd-vcs/01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
@@ -1687,17 +1687,17 @@
".opencode/skills/aidd-context/02-project-init/SKILL.md": "a0d80b727082d5d8c992cce9fd3ae9921cc0479c98ca2fbdf105bd414504a3e8",
".opencode/skills/aidd-context/02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
".opencode/skills/aidd-context/02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ ".opencode/skills/aidd-context/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".opencode/skills/aidd-context/02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
".opencode/skills/aidd-context/02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
- ".opencode/skills/aidd-context/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
".opencode/skills/aidd-context/02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
".opencode/skills/aidd-context/02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
- ".opencode/skills/aidd-context/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".opencode/skills/aidd-context/02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
".opencode/skills/aidd-context/02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
".opencode/skills/aidd-context/02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
".opencode/skills/aidd-context/02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
".opencode/skills/aidd-context/02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ ".opencode/skills/aidd-context/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
".opencode/skills/aidd-context/02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
".opencode/skills/aidd-context/02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
".opencode/skills/aidd-context/02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
@@ -1754,5 +1754,196 @@
".opencode/agents/aidd-dev-implementer.md": "4b4fe709e0ed56b097b697a49f6adfc200cccaad36a0e978a12e4f062a3a5e38",
".opencode/agents/aidd-dev-planner.md": "c83648c34068b6fa762fdc6b073e31cb3e9dfe5bd5bf2fd7e2cb4ad3e865feee",
".opencode/agents/aidd-dev-reviewer.md": "30e2dbb93309d23fc99cbce36a4fcfd0b6d76e49c3425979827727327ba697a6"
+ },
+ "kilo:flat": {
+ "kilo.json": "2a0f1462f19fb169d4258eb3934e64e48a0a5c54dd5ad64ae903ca01b9de6588",
+ ".kilo/skills/aidd-vcs/04-issue-create/SKILL.md": "3d71c4f442441512d458a180781d51db6e33317578844e76f992ef45fe5ef82b",
+ ".kilo/skills/aidd-vcs/04-issue-create/evals/scenarios.json": "d113c62aae4867e425737948c39c9f687f56c3d37234eca345a2f65f1a234c30",
+ ".kilo/skills/aidd-vcs/04-issue-create/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
+ ".kilo/skills/aidd-vcs/04-issue-create/assets/issue-template.md": "66b4ef6090208512205fce0bb16edbbcf0ffb19009eae76dc317d738c7a10cdc",
+ ".kilo/skills/aidd-vcs/04-issue-create/actions/01-issue-create.md": "e3f60414fa3ce2d78583e5cb118dad8df956927aa86e2f6e802031a7d742d7ed",
+ ".kilo/skills/aidd-vcs/03-release-tag/SKILL.md": "9ab62918018e35219437cada51c447a4e3b620cfd19e034714dd278140a61f8a",
+ ".kilo/skills/aidd-vcs/03-release-tag/evals/scenarios.json": "fdba5d61f815b956512f84baf712cde92be651593282b43ac173b2459ee9eca3",
+ ".kilo/skills/aidd-vcs/03-release-tag/assets/release-template.md": "bce05178ae5ea7da6c356849ba69eebd249ba344c94a3c571d7d40be9d4e9e27",
+ ".kilo/skills/aidd-vcs/03-release-tag/actions/01-release-tag.md": "b2f6c6cce5f7c83f83e4b2fd84c7aae3888bdfcd29f1be3d3e2bc362b18eae6b",
+ ".kilo/skills/aidd-vcs/02-pull-request/SKILL.md": "b2dbed7de2a3a4b2e646f874747a8e45d5fc25fdfc7c82ce9487e29c7e416ecf",
+ ".kilo/skills/aidd-vcs/02-pull-request/evals/scenarios.json": "63f63e6b13038672fbe325509deb32a9b25a50a996b687c001dfc74815a0dccd",
+ ".kilo/skills/aidd-vcs/02-pull-request/assets/branch.md": "92880244478c3e48c4f105e3ab2f9c09850778f84f1e44108ff8e912ccb0bea3",
+ ".kilo/skills/aidd-vcs/02-pull-request/assets/CONTRIBUTING.md": "1372c7512c02c26e21643ae523a98d7c90ff92c03633532a8c417b4ca8d9e75f",
+ ".kilo/skills/aidd-vcs/02-pull-request/assets/pull_request.md": "66939eaae42c729f3b05f8dcc2546a1e4227441d9d156d692fc7ced89d07a11f",
+ ".kilo/skills/aidd-vcs/02-pull-request/assets/README.md": "fb774bb7e5a19a39b21619879ee5045d7b3a0952be3f4b61aea524b93e9c9086",
+ ".kilo/skills/aidd-vcs/02-pull-request/actions/01-pull-request.md": "3c3753569b5f336e6c53ac8312ba6f9538ccc711e16fb7847ca1ebf04250a790",
+ ".kilo/skills/aidd-vcs/01-commit/SKILL.md": "7b88897ab9d7a5e2f6d7d9b2d424a8a77d54cdbfe547d94b0288cdacda411a50",
+ ".kilo/skills/aidd-vcs/01-commit/evals/scenarios.json": "bdefba21f63f7ef737ff3431077278cc45b722e85ba4b66e3a4adf4d34e0b2ff",
+ ".kilo/skills/aidd-vcs/01-commit/assets/commit-template.md": "b3c392c5c3faecc903bf80eb2bd287d2a02e42d4c3896490a5745d66fca60bf2",
+ ".kilo/skills/aidd-vcs/01-commit/actions/01-commit.md": "06ded7f8c23e950b3b1a76b0bb89c219d1ca161cb8f9a02e04e8083ad7061dc0",
+ ".kilo/skills/aidd-refine/03-condense/SKILL.md": "23c039ac8ef9bdcfd96d51803bf8bbdd64942ff8bcaf02eae54a94c889cd69d0",
+ ".kilo/skills/aidd-refine/03-condense/references/intensity-levels.md": "8e6aa26fc675a2d30dbb4df13e68d0ce6d2844c88bafd39e0ea3f2945e3276f1",
+ ".kilo/skills/aidd-refine/03-condense/evals/scenarios.json": "c03016b5e98c5a9a8b6680035bf8ee0f2a75edc5ce33e33cf1e1430cd91f55ec",
+ ".kilo/skills/aidd-refine/03-condense/actions/01-condense.md": "bffb26d5a306bc90f40614b29ca21e9a2151dc5ba82880c857e29c39486a16fd",
+ ".kilo/skills/aidd-refine/02-challenge/SKILL.md": "124b3f2688cb56887dc1de5118ac1315896aefc4d3440a98088a7020e8acce10",
+ ".kilo/skills/aidd-refine/02-challenge/references/confidence-rubric.md": "714f1bfd0c33f2adf911c93e9bb2f113be9fd29bad07d83e54be293fc44de823",
+ ".kilo/skills/aidd-refine/02-challenge/evals/scenarios.json": "332403843b5b5d99a9dcb3464f298ca3b7274edbd1b5c337407a4dd977bc19a5",
+ ".kilo/skills/aidd-refine/02-challenge/actions/01-challenge.md": "6f47920ccec8682708789e07583e32698695f1274bf883757ab13fca6f3e76c0",
+ ".kilo/skills/aidd-refine/01-brainstorm/SKILL.md": "1d08f27c800c81ed05ddca0b55813523708fcf7a3be994c43d306d4c290aa212",
+ ".kilo/skills/aidd-refine/01-brainstorm/references/ambiguity-detection.md": "c869338af0d8e0bdde5915000ce44980fef750cc40d070d4055bcba4c1334e0f",
+ ".kilo/skills/aidd-refine/01-brainstorm/evals/scenarios.json": "c6858f3b6b8efa666e2c7f21f4325f5e57297e3fdfc475b836f3ce5de9d635bf",
+ ".kilo/skills/aidd-refine/01-brainstorm/assets/question-templates.md": "bd744429e69f26caf37359e2b1d1c38dc4faba1a2c54dfaa99bfde48da0dc3c8",
+ ".kilo/skills/aidd-refine/01-brainstorm/actions/01-capture-request.md": "bc133963be4eeb68d6653a65f88f2e1820d711d6d7bf74b79a6225fff7b8e6c8",
+ ".kilo/skills/aidd-refine/01-brainstorm/actions/02-ask-probing-questions.md": "d8a25b7e2c0861bc4bce878e7d10dcda279855fa0db06d1997ad84f3e5682d54",
+ ".kilo/skills/aidd-refine/01-brainstorm/actions/03-integrate-answers.md": "b6f2c34f4f03cca48e83ed6fff5936e8ddbecae5fef1f597e99fd764e13f32cd",
+ ".kilo/skills/aidd-refine/01-brainstorm/actions/04-refine-and-validate.md": "4a6368a3e189c3022f133050f996eda3d9195281a3e4bbabdd120f5b8b414c3c",
+ ".kilo/skills/aidd-refine/01-brainstorm/actions/05-confirm-approval.md": "3c6c8184910a210bb6698c2c010aebec88a28313b31bbed0ef9c1189530cd6fe",
+ ".kilo/skills/aidd-pm/05-spec/SKILL.md": "491ab7edd5e2d1aea74e462730fac310df5289298b73fb803b88ea348965ccca",
+ ".kilo/skills/aidd-pm/05-spec/assets/spec-template.md": "2f7e446c4ec58d05a471212e9ab3ba64395bdd059943620d02bf1bf5c98777c2",
+ ".kilo/skills/aidd-pm/05-spec/assets/spec-validator.yml": "2358c6f0baa5656ddcff9410149cf8261d54199d8722f77769f76ca0d7c8cf18",
+ ".kilo/skills/aidd-pm/04-clarity/SKILL.md": "384d1711225afd5270cb6276f9d65ed7390812fbac4de49a2e9735d88dcf486a",
+ ".kilo/skills/aidd-pm/03-prd/SKILL.md": "d68b21e05bfe9a66f051948ce95317b72245fd05f48a8e9acf3d339ba3538469",
+ ".kilo/skills/aidd-pm/03-prd/assets/prd-template.md": "af01423720e8c9527ff12a2e9ad1de39c6e63c6569359be08defd0a059aabea9",
+ ".kilo/skills/aidd-pm/03-prd/assets/task-template.md": "c0069ed2ecce4742629dccd6be709d4e5a71f3db3821310c381c054aeb479289",
+ ".kilo/skills/aidd-pm/03-prd/actions/01-prd.md": "c0da6597f8c465ad50a17a07543152f53de1fbccc28cd906763d439004084a22",
+ ".kilo/skills/aidd-pm/02-user-stories-create/SKILL.md": "1cb352618908536a4605ca12ff82e2f3ca4ebce44261f44c6350ec2f758185aa",
+ ".kilo/skills/aidd-pm/02-user-stories-create/assets/user-story-template.md": "59ecd98d00057313414a74a94c19c0f2d167957e1080b880ee68a69a31948320",
+ ".kilo/skills/aidd-pm/02-user-stories-create/actions/01-create-user-stories.md": "6fad8968a1e787c197764c4a8c09b17c521ae5ea2286a5082addc717bd72b1e6",
+ ".kilo/skills/aidd-pm/01-ticket-info/SKILL.md": "e2fd826ddfde64bbe9f8287f2493b4117ce6bd0ad3485bbce896e235077dd513",
+ ".kilo/skills/aidd-pm/01-ticket-info/actions/01-ticket-info.md": "f075ea6ff626534dbe0826d06b67fae93b6488ec4c5c7a3d857f1d05f73d0630",
+ ".kilo/skills/aidd-dev/08-for-sure/SKILL.md": "dbcce912442017c2e091365bfb2b9ee75fb272327d213e2ebd9bcab7dab24248",
+ ".kilo/skills/aidd-dev/08-for-sure/actions/01-init-tracking.md": "3ce6bb19135e5d31c4d2ad1c2151c1563886a611f2399b47624368268a79dcdf",
+ ".kilo/skills/aidd-dev/08-for-sure/actions/02-auto-accept.md": "235818118c772c0f499ea0668bfbc7bd00c2aae34e6bbd8b13b912fddfa79705",
+ ".kilo/skills/aidd-dev/08-for-sure/actions/03-autonomous-loop.md": "b19d4520ad716def3c2a4611c37725cba9af713cd4bcb668c237e874e1e43843",
+ ".kilo/skills/aidd-dev/07-debug/SKILL.md": "f93f3eb8a71c580692e2048c9d475e1933c0717cc86881bdea8e889f7fbfd498",
+ ".kilo/skills/aidd-dev/07-debug/references/mermaid-conventions.md": "85826285744909dd4c4706b82f0dbeff4f88a8f191cb22d538aa12c3c96365eb",
+ ".kilo/skills/aidd-dev/07-debug/assets/task-template.md": "c0069ed2ecce4742629dccd6be709d4e5a71f3db3821310c381c054aeb479289",
+ ".kilo/skills/aidd-dev/07-debug/actions/01-reproduce.md": "7e902e5aadc9162b444b341deb33f2a683000c1cc4722ad856496f9d740ec17d",
+ ".kilo/skills/aidd-dev/07-debug/actions/02-debug.md": "dc3900ce6fb76074b88034d7b7316f4051d78a1828caa3acef9786e8ea582b18",
+ ".kilo/skills/aidd-dev/07-debug/actions/03-reflect-issue.md": "3d5f18634618737870da4c783c7525cee25e09d942faee80125dd7536978ce12",
+ ".kilo/skills/aidd-dev/06-refactor/SKILL.md": "914ac56ba86d951b01dd90b3ec23760ccba233f5b6357ed9987c8aa3e0a44f8c",
+ ".kilo/skills/aidd-dev/06-refactor/actions/01-performance.md": "1f7d500967de58875aeb14b732a1af377b17edff8654f4365b3f29743debb3c7",
+ ".kilo/skills/aidd-dev/06-refactor/actions/02-security.md": "db55b81ab824d81b765189296deb1ce31fdb134edac186baf22a2c3bb1cde938",
+ ".kilo/skills/aidd-dev/05-test/SKILL.md": "a65b9feb5b674a0cdef00934cf4cc0d7884e9728b8228add38b720493db82637",
+ ".kilo/skills/aidd-dev/05-test/actions/01-test.md": "f6db9653cd29729c51653df7afe473fae4ae45bb126a694a367bfd84fa1785a4",
+ ".kilo/skills/aidd-dev/05-test/actions/02-test-journey.md": "1eeb85da69abc3f1fc3e5671e83962f44fcb5686d9ca5972eeb2ba4cab31306d",
+ ".kilo/skills/aidd-dev/04-review/SKILL.md": "c9c2552d6f5375b1b8004d948e5ae608607bfb6884325dfa7635b84c9fdf7b95",
+ ".kilo/skills/aidd-dev/04-review/assets/code-review-template.md": "e270c4b6b8c69e4fbbbcc08c2f91cc9a09fc8ad155b6f52cec3e3d34a262324d",
+ ".kilo/skills/aidd-dev/04-review/assets/review-functional-template.md": "a84b48347caf4d09d84994b07329e4d05c8053d45630b37d47ca3ccb386e3146",
+ ".kilo/skills/aidd-dev/04-review/assets/review-template.md": "b0ad0ab703e4d9ed960bd324bc37efe5f682cbcd40ed6293791d9074f174201c",
+ ".kilo/skills/aidd-dev/04-review/actions/01-review-code.md": "8d5e4fc6c9243a83025961ae40146f1d96f321d9ff4d93ab74c370bbc53c18ed",
+ ".kilo/skills/aidd-dev/04-review/actions/02-review-functional.md": "9e5d837715f5610a42f1c294b0fa71277538e2629dc47cf09675487dcfa98324",
+ ".kilo/skills/aidd-dev/03-audit/SKILL.md": "7947c0dc728f51d82dd1e605e315458c1855664a92783d30acd927f263e58fc4",
+ ".kilo/skills/aidd-dev/03-audit/actions/01-audit.md": "0371ae3d0c9a383f8b90657f3381717f323742bad922df2c1c508f6db013267e",
+ ".kilo/skills/aidd-dev/02-assert/SKILL.md": "e17e52f9342a882be2a483c02911b4c02db21b8f6732a45a50cb5c84a89b152a",
+ ".kilo/skills/aidd-dev/02-assert/assets/task-template.md": "c0069ed2ecce4742629dccd6be709d4e5a71f3db3821310c381c054aeb479289",
+ ".kilo/skills/aidd-dev/02-assert/actions/01-assert.md": "b8a9680e7cf956f2e1ff7720f755586e2523d6951c35ec686ded659f7fa3a4b1",
+ ".kilo/skills/aidd-dev/02-assert/actions/02-assert-architecture.md": "e5d7effa39f33c045e4d605ed909d46ddf7562e2a0199eb2e39fcc8f3fc92620",
+ ".kilo/skills/aidd-dev/02-assert/actions/03-assert-frontend.md": "ed9751b32580c7fd3fbe02a8205cbb5d85a8e7bc38f982b5130b810950bbd091",
+ ".kilo/skills/aidd-dev/01-plan/SKILL.md": "17bfdcd576432b2c0d9aee7b2cdcef5888bd2e7a2e5ee28f72b15d7b4e4b7bbd",
+ ".kilo/skills/aidd-dev/01-plan/references/mermaid-conventions.md": "85826285744909dd4c4706b82f0dbeff4f88a8f191cb22d538aa12c3c96365eb",
+ ".kilo/skills/aidd-dev/01-plan/assets/master-plan-template.md": "f793f2bc8fad34f056e824def49527552f50cf12e43f0929731d64278376b822",
+ ".kilo/skills/aidd-dev/01-plan/assets/plan-template.md": "cf462e831d994230c811c71eaa72a8f9880536ba3b657b70342083dee00ab254",
+ ".kilo/skills/aidd-dev/01-plan/assets/tech-choice-template.md": "c9f16f9b598aded5953127b4bf2768b95d7abda0b75d937e0b31dfee9317c40a",
+ ".kilo/skills/aidd-dev/01-plan/actions/01-plan.md": "c480fc1cffe39f117003b5aeea23e10f808952a0eeea067dbc0ab44c0af992ff",
+ ".kilo/skills/aidd-dev/01-plan/actions/02-components-behavior.md": "cacb673334d8947c3c252feaaf0ef50c269c06c5cf8f51b45663cbd42402e094",
+ ".kilo/skills/aidd-dev/01-plan/actions/03-image-extract-details.md": "6f6cddd0893888c71b0aed5ecfe48217afe0eef10feec6415db433bfcc69f8e3",
+ ".kilo/skills/aidd-dev/00-sdlc/SKILL.md": "5cfd0552e267b714302f535418fdcad6d0fadd463503f464e49637e7beab6913",
+ ".kilo/skills/aidd-context/06-discovery/SKILL.md": "977b633166ecf11224966df8a19d4661252269d5459fe3524987c705f995bae1",
+ ".kilo/skills/aidd-context/06-discovery/actions/01-find-skill.md": "600caf7822017bfe75d40773e1673ada784227b98f5b88d4ba98a57822fa0dcf",
+ ".kilo/skills/aidd-context/05-learn/SKILL.md": "c877eeb8892249fc9a13ea73d63493973fcfcc00c81709011e2cfcd788aa812b",
+ ".kilo/skills/aidd-context/05-learn/assets/adr-template.md": "1f9feb18109b178226885ab7edabc3d1c4dd2a77dd1fa7345be856643107ac16",
+ ".kilo/skills/aidd-context/05-learn/assets/decision-template.md": "1e6229157fd0a07c090ce0bd159336a13554975e146966b306bf25665a179938",
+ ".kilo/skills/aidd-context/05-learn/actions/01-learn.md": "92400bfcc2cdfe9f0bad8f2feadd7d28dce882240fe58971d25dfa880521d8bb",
+ ".kilo/skills/aidd-context/04-mermaid/SKILL.md": "52b138ad705b624e09b77e6467cb2caddd85f3c172cf0ffde83a4981cc82309c",
+ ".kilo/skills/aidd-context/04-mermaid/references/mermaid-conventions.md": "85826285744909dd4c4706b82f0dbeff4f88a8f191cb22d538aa12c3c96365eb",
+ ".kilo/skills/aidd-context/04-mermaid/actions/01-mermaid.md": "f70b18f429701d0c3b46a4c6e75153c732ee9e06a16aa01efec05e810ac7a6dd",
+ ".kilo/skills/aidd-context/03-context-generate/SKILL.md": "56bc1ab9a3e93f65285c265ef07dbb96ac34a1c42294dbf4658147a524d0c373",
+ ".kilo/skills/aidd-context/03-context-generate/references/agents-coordination.md": "eaaa31ed554a53f7870151307853e1add7e3ddd1de8e442b8d5e7c5698ab0098",
+ ".kilo/skills/aidd-context/03-context-generate/references/ai-mapping.md": "4ad192b5ae53c7ceadff165a1cef8c3f24949498375bedc0cc359194dea3117e",
+ ".kilo/skills/aidd-context/03-context-generate/references/naming-conventions.md": "fd39d00b1449f0770ee89aad9f6e84d21e1fee2efc0ff547a240b0e18f648cd8",
+ ".kilo/skills/aidd-context/03-context-generate/references/rule-structure.md": "c8ce6eea6dbaae5309a77237d702db193a7748db5c581d0918f17db3989e414f",
+ ".kilo/skills/aidd-context/03-context-generate/references/rule-writing.md": "e4cddd88dca3162d576a1b616c419f5ff2f3b7681a09a569da68358f3713c9e6",
+ ".kilo/skills/aidd-context/03-context-generate/references/skill-structure.md": "2b6114ff8aa30f1a5d7bfd3bf0d7d87e429cb8d65ba13b369e6cdc9c8bec501c",
+ ".kilo/skills/aidd-context/03-context-generate/evals/scenarios.json": "db355f13f2ca3499f912f39ada136472f9bc993846564aeaeb6eab371d485520",
+ ".kilo/skills/aidd-context/03-context-generate/assets/skills/action-template.md": "8bd80e05dcbb10e24adb668778fd9dfb058c92193c52c6012e9f5cc11305103c",
+ ".kilo/skills/aidd-context/03-context-generate/assets/skills/evals-template.md": "c0468fe9869895b42f7a59b48f7613ca4ef3b1af93acb7c41dc063559964ff27",
+ ".kilo/skills/aidd-context/03-context-generate/assets/skills/skill-template.md": "f30bc5a47574cc85dc0daddfa1abd0d7f8bd8a39e201fbb3df5784506a61b13a",
+ ".kilo/skills/aidd-context/03-context-generate/assets/rules/rule-template.md": "200ec56d8ed43acd51b94df783f7de9236b00a6e5398a98a30640d02edb76ba1",
+ ".kilo/skills/aidd-context/03-context-generate/assets/agents/agent-template.md": "476802721ac4947d741b4bd17626860c4914037992a2ebf0ef282553f819aa25",
+ ".kilo/skills/aidd-context/03-context-generate/actions/skills/01-capture-intent.md": "850c9b7dab101eba66284950eb3b8b612aca3ad40a1b13fcdc5ac181d1f72069",
+ ".kilo/skills/aidd-context/03-context-generate/actions/skills/02-design-evals.md": "fc51fb2c85a7462fe27586ddc3cc5c2699214dcd059c28f7ab8daf26a6479ced",
+ ".kilo/skills/aidd-context/03-context-generate/actions/skills/03-decompose-actions.md": "8bf7ff1ac05d968fc7a3e9b6aa5de3df3be04b07e96517cbe06268baec4151fc",
+ ".kilo/skills/aidd-context/03-context-generate/actions/skills/04-draft-skill.md": "08946a56b720408bee9c63cd7141e6c869e6818610546f8a42628fe6d2e12514",
+ ".kilo/skills/aidd-context/03-context-generate/actions/skills/05-write-actions.md": "948ac436af5e9c9e897b8c4e44b12a278943bff2b93afc10b4ddaee587d58cc5",
+ ".kilo/skills/aidd-context/03-context-generate/actions/skills/06-validate.md": "658c1077b03c461bb0c3fa17db047e4d2fbc3874f4d4fbd2e3dc5df606aa03ee",
+ ".kilo/skills/aidd-context/03-context-generate/actions/rules/01-generate-rules.md": "855b9adf65b0b0cc31ca15c68b8ac37da6a816c9a6416fbc3aea424cffa238c3",
+ ".kilo/skills/aidd-context/03-context-generate/actions/agents/01-generate-agent.md": "3dce30335eba1d60c5a62d43184d133eed621bbc344e9277ab0f05ead443e0ba",
+ ".kilo/skills/aidd-context/02-project-init/SKILL.md": "a0d80b727082d5d8c992cce9fd3ae9921cc0479c98ca2fbdf105bd414504a3e8",
+ ".kilo/skills/aidd-context/02-project-init/references/mapping-ai-context-file.md": "cf251454634037d4affd1d27cee2593c555dfe29305b521d3bed4564f4cad273",
+ ".kilo/skills/aidd-context/02-project-init/assets/AGENTS.md": "8b3d349220e9f96b45dedf316eeb2b3418666d96d0a4f64d315cadfc9ef337ae",
+ ".kilo/skills/aidd-context/02-project-init/assets/golden-principles.md": "e83c582a9e1477a42531734deed90061f4e004ea28e1b1616bf714070856c888",
+ ".kilo/skills/aidd-context/02-project-init/assets/GUIDELINES.md": "bf41995402b46268ba53ceec41be00c455004603f69035349b6ff3bef14cc18a",
+ ".kilo/skills/aidd-context/02-project-init/assets/README.md": "575086cda27a386806a28c1bb4865cb5f974dc3fe6e39ca8bdd2c19764cf2059",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/workflows/README.md": "33d50760dfde22feb8878cf3e24d399a748eef8ed2df630f465d673d9f125a53",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/stack/README.md": "8dbccfc7d47424411b7725374247b50973a962fff777b272a23109b7e0f2a099",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/architecture.md": "f00c02db4135a43e99f5bdd7888f40f290e39dd4a65bb1539eca9a06c9873427",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/codebase-map.md": "5d1d184bc70c93e0073cb64312f4fa8d50fcf465b0da982f37bde25d624a5386",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/coding-assertions.md": "2e3d7b16f85e8af3cf9971c3b0c23409653e8d693c969ff11892c5a4f10bea90",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/deployment.md": "361e80ebbddda1f0497856530e7a5a35cd2c8ae56df2a6ef64268657de333d28",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/project-brief.md": "0240ee41e05c6091bd136b7c3b18f603731128941c987449917886b191e38e90",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/README.md": "66e6275cd7e7187ca520ad8f2f3c57ebecf967742901e00085c139fd9eea5892",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/testing.md": "760e58855270ee9210b20987b3f01b537b25f6108f8d164e2a88000f4cb278b7",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/vcs.md": "3eccc51898b8c0c17245a737c9fa540f30706676ea01ff771d6898f3861060f1",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/frontend/browsing.md": "f8ab234ba45571979a5dbc2181859a8f6859cd56c9d86371560516b3323dd8a1",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/frontend/design.md": "edcaa8ab125acd64d330a32abac102fa3d0b37b45ef03a9552c71c885c1ea847",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/frontend/forms.md": "662dd1b62a9d3fef587cf38f1c2f6fe3de2d0cb226a9ec50dd7b576bf824115b",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/backend/api-docs.md": "09b9633c1d8c3b5a11bf0d171abf148bf159836ae96223a78a52b9e56ffb52e8",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/backend/backend-communication.md": "87d548e12bed0fa2a2d7601fe1c36d810f40051abd713cc3d4462582319babde",
+ ".kilo/skills/aidd-context/02-project-init/assets/templates/memory/backend/database.md": "899ceb107598c8b9a1adc3ff7cf8b6217e4582553f5c27f3e22b9e7fb0f555b9",
+ ".kilo/skills/aidd-context/02-project-init/actions/01-init-context-file.md": "33c907084418ec22f8c22381fbefecfbf3d88c250781c852059bf611be0f2ae2",
+ ".kilo/skills/aidd-context/02-project-init/actions/02-scaffold-docs.md": "c07f175692241d477b029441a2a984c2fff6de0041ff6f47a6851d73900a1ac3",
+ ".kilo/skills/aidd-context/02-project-init/actions/03-generate-memory.md": "f7cde767985a1d7ca8c2d74c1ffcc11eac2232a97e26b46573533eefcdd5ac96",
+ ".kilo/skills/aidd-context/02-project-init/actions/04-review-memory.md": "211ad0ad0d7c4925acbd8a41f775a16b09de51b85d9f3fc6f972170ac63fd353",
+ ".kilo/skills/aidd-context/02-project-init/actions/05-init-rules-skeleton.md": "12924f4535c083e114a5a4a4ef148e4aa2c8c4c436d23c8f50e152f869e3be2c",
+ ".kilo/skills/aidd-context/02-project-init/actions/06-sync-memory.md": "3f6825c8d230cea72f729aee15cf6136b613b7a9b07ddec237b91fe5ad3be59b",
+ ".kilo/skills/aidd-context/01-bootstrap/SKILL.md": "3f4dd3a7b87d16ad35fdd3a671c5cd27f6fb55e8a0131b46f667e5a43ecb3308",
+ ".kilo/skills/aidd-context/01-bootstrap/references/stack-heuristics.md": "17f7c0df7b19090f42c26ddf70df1049897b3973d9c1bf8df358b87a1cc9985a",
+ ".kilo/skills/aidd-context/01-bootstrap/evals/scenarios.json": "c5998a91c584d561618dbabe66f21bd8f446260731778de4f467a70a6da21784",
+ ".kilo/skills/aidd-context/01-bootstrap/assets/checklist.md": "64b84a7712ca78bc1901d2c78c183310336a4abe1b5890a689c3cf166b026d21",
+ ".kilo/skills/aidd-context/01-bootstrap/assets/install-template.md": "cd67115a7b11fddea0258810b9cee1d35c3e12840f515c5364fa769cad9d6a60",
+ ".kilo/skills/aidd-context/01-bootstrap/actions/01-gather-needs.md": "b3251034285434b06775ab4a59ffe27259bb23cb97ac65927c946a4846ea946d",
+ ".kilo/skills/aidd-context/01-bootstrap/actions/02-propose-candidates.md": "57376071d9d0b011c5f19ba218a3ef28c3bf1fba1220a87260806a2d79e341d6",
+ ".kilo/skills/aidd-context/01-bootstrap/actions/03-audit-candidates.md": "def30caedeca0babb4500b2081fe46bdcaf72ee911e4ad94ae860b068c2ee0e0",
+ ".kilo/skills/aidd-context/01-bootstrap/actions/04-pick-and-design.md": "1444ede4a16e6df368792d7f214e0bb61912621a9c266205e031ec73151606e7",
+ ".kilo/skills/aidd-context/01-bootstrap/actions/05-write-install-md.md": "c94afb152683cc29f10d2d4451632265b7fdc763a8a41b69f8ddc2c00b81dfd0",
+ ".kilo/skills/aidd-async-dev/03-review/SKILL.md": "495817892fff18cd760e7005b493b8de61049c9dbd71596edf136e3a434b2d4b",
+ ".kilo/skills/aidd-async-dev/03-review/references/stop-conditions.md": "47280ec7ebb0bd2d25bb7bf7dd716f5ef41a0ad8163653fa139981b5283e7ba0",
+ ".kilo/skills/aidd-async-dev/03-review/evals/scenarios.json": "562d462eedcb589487585a6840d3077a8cce760ea4ecd5e416a8a01b8472d995",
+ ".kilo/skills/aidd-async-dev/03-review/actions/skills/01-collect-comments.md": "a7494fcd9ec705cf76d36ed9b7ce59b2d9ed6e82ce64084e2ed935d52ab57527",
+ ".kilo/skills/aidd-async-dev/03-review/actions/skills/02-detect-stop.md": "b5d40992028d2e0a1d59f31dd699237005ebb51d9c70a648aca7f757f7449659",
+ ".kilo/skills/aidd-async-dev/03-review/actions/skills/03-fix-iteration.md": "a3133409542ed6fc8e9b814658be68504e646cc44ed58ca749251c6b6dd45f25",
+ ".kilo/skills/aidd-async-dev/03-review/actions/skills/04-finalize.md": "bf01c103e3940fda6fd07092bd35f44993f24cdd25ec7ff5c52004b20a37cb17",
+ ".kilo/skills/aidd-async-dev/02-run/SKILL.md": "6d82a4799255b30a52e691817e214b12c22547ebe0796547d036df474b6a41c0",
+ ".kilo/skills/aidd-async-dev/02-run/evals/scenarios.json": "cf78e4c46ac988912a7de98b1a1143c439d3c744bef234d7294f17b4836a84d0",
+ ".kilo/skills/aidd-async-dev/02-run/actions/skills/01-poll-ready.md": "38b0767d080c60149fc4dd1b04395c72b6cda204bd2152d2f9be54db814626fd",
+ ".kilo/skills/aidd-async-dev/02-run/actions/skills/02-resolve-deps.md": "9ede89ff3396287bde2ed9fed6e8068a8411b9190dc446ec392badaf31a52a5f",
+ ".kilo/skills/aidd-async-dev/02-run/actions/skills/03-acquire-lock.md": "0a9b54f4bc9ebdb653932b57bd9d61e9ee7248d86104bc95841617beb4eeeee5",
+ ".kilo/skills/aidd-async-dev/02-run/actions/skills/04-check-sdlc.md": "1934b9f0fb5824736349070ceca67105892ef7e4f319ca95ae955f564e821633",
+ ".kilo/skills/aidd-async-dev/02-run/actions/skills/05-delegate-sdlc.md": "3142a7d2ee15d1871fecc1b4977ff3fb43b9a343f25913a54cc943d9fab31a7c",
+ ".kilo/skills/aidd-async-dev/02-run/actions/skills/06-write-audit.md": "3cfbabf8f6c6e267994afcf189d17234eac4c3bb35ab68408776f1acb644b6ba",
+ ".kilo/skills/aidd-async-dev/02-run/actions/skills/07-emit-webhook.md": "4c8fe76bdf265386247a636dafc9365946114afa54c479ef13abfd929d7af3db",
+ ".kilo/skills/aidd-async-dev/01-setup/SKILL.md": "bb3a30cd1e18d37751cd31e9d72d82cfb755d9787085485d2f6052aa1c3742bf",
+ ".kilo/skills/aidd-async-dev/01-setup/references/auth-modes.md": "4122f895e4b210fce0e8f4cac81a79f6711eca56edac02ac43235359a77c2f62",
+ ".kilo/skills/aidd-async-dev/01-setup/evals/scenarios.json": "79b49984a0999a3f34348bedbf8e7fe815ebdddf825701fabfedbe39f7a1ede2",
+ ".kilo/skills/aidd-async-dev/01-setup/assets/config-template.json": "d47d1d93014157d525f48f3c96626472d940fafffc0deb106af2371db97b4e83",
+ ".kilo/skills/aidd-async-dev/01-setup/assets/workflow-template.yml": "203382209de920a9405b85cc89817ddf0f731a7604e8a465fc4fb3c32589d168",
+ ".kilo/skills/aidd-async-dev/01-setup/actions/skills/01-detect-context.md": "83f3ba3022dd75fa2597a872a55e8f75173762f932ed39ae73d8181c0b1b4536",
+ ".kilo/skills/aidd-async-dev/01-setup/actions/skills/02-ask-config.md": "986335d1e86a633d0083fe4488aae58266a82ec35d0cdb0b74f0bbcea70e6f4e",
+ ".kilo/skills/aidd-async-dev/01-setup/actions/skills/03-generate-workflow.md": "11f7ec6c03284d0524179f71337691301a6362cf77bf3aa666fe41686b4df40b",
+ ".kilo/skills/aidd-async-dev/01-setup/actions/skills/04-write-config.md": "eb7ecb812e8bdaaeba2e56c71c77bf8c14fce0a2c44311ff7985444617635dd5",
+ ".kilo/skills/aidd-async-dev/01-setup/actions/skills/05-bootstrap-labels.md": "f53177ce1c58767f1bdfcfa3e72f7d4cc5e3d4fd782c35c3998815317be108b1",
+ ".kilo/plugin/aidd-context-hooks.js": "3788cd28d080a9183e76f5ad6971e179fbb536bb3df367d523f615829bf13bbb",
+ ".kilo/hooks/aidd-context/update_memory.js": "140d7db788452f5f4c32316d522f595a36e06638b19a42d32e42a1a7324b7149",
+ ".kilo/agents/aidd-async-dev-async-orchestrator.md": "3eb709fb7da8f6df7d4d76c7c69fce0a00b596d7b9522b5dcf3898c7a94d91cf",
+ ".kilo/agents/aidd-dev-implementer.md": "4b4fe709e0ed56b097b697a49f6adfc200cccaad36a0e978a12e4f062a3a5e38",
+ ".kilo/agents/aidd-dev-planner.md": "c83648c34068b6fa762fdc6b073e31cb3e9dfe5bd5bf2fd7e2cb4ad3e865feee",
+ ".kilo/agents/aidd-dev-reviewer.md": "30e2dbb93309d23fc99cbce36a4fcfd0b6d76e49c3425979827727327ba697a6"
}
}
diff --git a/cli/tests/golden/snapshots/help/surface.json b/cli/tests/golden/snapshots/help/surface.json
index 0123934dd..c6e5a284a 100644
--- a/cli/tests/golden/snapshots/help/surface.json
+++ b/cli/tests/golden/snapshots/help/surface.json
@@ -192,7 +192,7 @@
{
"invocation": "aidd translate",
"exitCode": 0,
- "help": "Usage: aidd translate [options] \n\nConvert an arbitrary source into a target-native plugin tree — records nothing\n(see `sync` for the manifest-driven, tracked version)\n\nArguments:\n source Path to the source framework directory\n\nOptions:\n --to Conversion target (claude, cursor, copilot, codex,\n opencode)\n --out Output directory (marketplace dist or project root)\n --as Output layout (default: \"marketplace\")\n --force Overwrite existing files at canonical paths under\n --out\n -h, --help display help for command"
+ "help": "Usage: aidd translate [options] \n\nConvert an arbitrary source into a target-native plugin tree — records nothing\n(see `sync` for the manifest-driven, tracked version)\n\nArguments:\n source Path to the source framework directory\n\nOptions:\n --to Conversion target (claude, cursor, copilot, codex,\n opencode, kilo)\n --out Output directory (marketplace dist or project root)\n --as Output layout (default: \"marketplace\")\n --force Overwrite existing files at canonical paths under\n --out\n -h, --help display help for command"
},
{
"invocation": "aidd update",
diff --git a/cli/tests/golden/snapshots/phase0/snapshot.json b/cli/tests/golden/snapshots/phase0/snapshot.json
index e28a34f61..cb62f0206 100644
--- a/cli/tests/golden/snapshots/phase0/snapshot.json
+++ b/cli/tests/golden/snapshots/phase0/snapshot.json
@@ -52,6 +52,7 @@
"cache/built//aidd-framework/claude/plugins/aidd-test/agents/code-reviewer.md",
"cache/built//aidd-framework/claude/plugins/aidd-test/hooks/check.sh",
"cache/built//aidd-framework/claude/plugins/aidd-test/hooks/hooks.json",
+ "cache/built//aidd-framework/claude/plugins/aidd-test/hooks/session-start.js",
"cache/built//aidd-framework/claude/plugins/aidd-test/skills/commit/SKILL.md",
"cache/built//aidd-framework/claude/plugins/aidd-test/skills/hello.md",
"manifest.json",
@@ -244,6 +245,7 @@
"filesWritten": [
".cursor/hooks.json",
".cursor/hooks/aidd-test/check.sh",
+ ".cursor/hooks/aidd-test/session-start.js",
".cursor/settings.json"
],
"manifest": {
@@ -311,7 +313,7 @@
{
"command": "doctor",
"exitCode": 0,
- "stdout": "\nAI tools:\n claude (v): 1 files, 0 merge files\n cursor (v): 1 files, 0 merge files\n\nDrift:\nAI tools:\n claude (v): in sync\n cursor (v):\n + .cursor/hooks/aidd-test/check.sh\n + .cursor/hooks.json\n 0 modified, 0 deleted, 2 added\nIDE tools:\n (none installed)\nPlugins:\n (all in sync)\n\nAI:\n\nInstallation is healthy\n",
+ "stdout": "\nAI tools:\n claude (v): 1 files, 0 merge files\n cursor (v): 1 files, 0 merge files\n\nDrift:\nAI tools:\n claude (v): in sync\n cursor (v):\n + .cursor/hooks/aidd-test/check.sh\n + .cursor/hooks/aidd-test/session-start.js\n + .cursor/hooks.json\n 0 modified, 0 deleted, 3 added\nIDE tools:\n (none installed)\nPlugins:\n (all in sync)\n\nAI:\n\nInstallation is healthy\n",
"stderr": "Warning: /.claude/plugins/installed_plugins.json could not be read — ENOENT\n Fix: The plugin does not load until claude's own CLI has run and answered this.\n",
"filesWritten": [],
"manifest": {
@@ -379,7 +381,7 @@
{
"command": "doctor",
"exitCode": 1,
- "stdout": "\nAI tools:\n claude (v): 1 files, 0 merge files\n cursor (v): 1 files, 0 merge files\n\nDrift:\nAI tools:\n claude (v):\n ~ .claude/settings.json\n 1 modified, 0 deleted, 0 added\n cursor (v):\n + .cursor/hooks/aidd-test/check.sh\n + .cursor/hooks.json\n 0 modified, 0 deleted, 2 added\nIDE tools:\n (none installed)\nPlugins:\n (all in sync)\n\nAI:\n",
+ "stdout": "\nAI tools:\n claude (v): 1 files, 0 merge files\n cursor (v): 1 files, 0 merge files\n\nDrift:\nAI tools:\n claude (v):\n ~ .claude/settings.json\n 1 modified, 0 deleted, 0 added\n cursor (v):\n + .cursor/hooks/aidd-test/check.sh\n + .cursor/hooks/aidd-test/session-start.js\n + .cursor/hooks.json\n 0 modified, 0 deleted, 3 added\nIDE tools:\n (none installed)\nPlugins:\n (all in sync)\n\nAI:\n",
"stderr": "Warning: /.claude/plugins/installed_plugins.json could not be read — ENOENT\n Fix: The plugin does not load until claude's own CLI has run and answered this.\nWarning: Modified tracked file: .claude/settings.json\n Fix: Run `aidd sync --force` to revert to the framework version.\n",
"filesWritten": [],
"manifest": {
@@ -515,7 +517,7 @@
{
"command": "doctor",
"exitCode": 0,
- "stdout": "\nAI tools:\n claude (v): 1 files, 0 merge files\n cursor (v): 1 files, 0 merge files\n\nDrift:\nAI tools:\n claude (v): in sync\n cursor (v):\n + .cursor/hooks/aidd-test/check.sh\n + .cursor/hooks.json\n 0 modified, 0 deleted, 2 added\nIDE tools:\n (none installed)\nPlugins:\n (all in sync)\n\nAI:\n\nInstallation is healthy\n",
+ "stdout": "\nAI tools:\n claude (v): 1 files, 0 merge files\n cursor (v): 1 files, 0 merge files\n\nDrift:\nAI tools:\n claude (v): in sync\n cursor (v):\n + .cursor/hooks/aidd-test/check.sh\n + .cursor/hooks/aidd-test/session-start.js\n + .cursor/hooks.json\n 0 modified, 0 deleted, 3 added\nIDE tools:\n (none installed)\nPlugins:\n (all in sync)\n\nAI:\n\nInstallation is healthy\n",
"stderr": "Warning: /.claude/plugins/installed_plugins.json could not be read — ENOENT\n Fix: The plugin does not load until claude's own CLI has run and answered this.\n",
"filesWritten": [],
"manifest": {
@@ -629,6 +631,7 @@
"cache/built//aidd-framework/claude/plugins/aidd-test/agents/code-reviewer.md",
"cache/built//aidd-framework/claude/plugins/aidd-test/hooks/check.sh",
"cache/built//aidd-framework/claude/plugins/aidd-test/hooks/hooks.json",
+ "cache/built//aidd-framework/claude/plugins/aidd-test/hooks/session-start.js",
"cache/built//aidd-framework/claude/plugins/aidd-test/skills/commit/SKILL.md",
"cache/built//aidd-framework/claude/plugins/aidd-test/skills/hello.md",
"cache/built//aidd-framework/cursor/.build-version",
@@ -638,6 +641,7 @@
"cache/built//aidd-framework/cursor/plugins/aidd-test/agents/code-reviewer.md",
"cache/built//aidd-framework/cursor/plugins/aidd-test/hooks/check.sh",
"cache/built//aidd-framework/cursor/plugins/aidd-test/hooks/hooks.json",
+ "cache/built//aidd-framework/cursor/plugins/aidd-test/hooks/session-start.js",
"cache/built//aidd-framework/cursor/plugins/aidd-test/skills/commit/SKILL.md",
"cache/built//aidd-framework/cursor/plugins/aidd-test/skills/hello.md",
"manifest.json",
@@ -692,7 +696,7 @@
"command": "[errors] framework install --tool not-a-tool",
"exitCode": 1,
"stdout": "",
- "stderr": "Error: Unknown tool: not-a-tool. Valid tools: claude, cursor, copilot, opencode, codex, vscode\n",
+ "stderr": "Error: Unknown tool: not-a-tool. Valid tools: claude, cursor, copilot, opencode, kilo, codex, vscode\n",
"filesWritten": [],
"manifest": null
},
diff --git a/cli/tests/helpers/ports/build-unit-deps.ts b/cli/tests/helpers/ports/build-unit-deps.ts
index b6a741d30..31078da33 100644
--- a/cli/tests/helpers/ports/build-unit-deps.ts
+++ b/cli/tests/helpers/ports/build-unit-deps.ts
@@ -4,6 +4,7 @@ import "../../../src/contexts/tools/domain/profiles/claude/profile.js";
import "../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import "../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import "../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import "../../../src/contexts/tools/domain/profiles/vscode/profile.js";
import { PluginCatalogRepositoryAdapter } from "../../../src/contexts/distribution/infrastructure/plugin-catalog-repository-adapter.js";
diff --git a/cli/tests/presentation/commands/translate-wiring.integration.test.ts b/cli/tests/presentation/commands/translate-wiring.integration.test.ts
index e54b82ef1..5fb23b017 100644
--- a/cli/tests/presentation/commands/translate-wiring.integration.test.ts
+++ b/cli/tests/presentation/commands/translate-wiring.integration.test.ts
@@ -5,6 +5,7 @@ import "../../../src/contexts/tools/domain/profiles/claude/profile.js";
import "../../../src/contexts/tools/domain/profiles/codex/profile.js";
import "../../../src/contexts/tools/domain/profiles/copilot/profile.js";
import "../../../src/contexts/tools/domain/profiles/cursor/profile.js";
+import "../../../src/contexts/tools/domain/profiles/kilo/profile.js";
import "../../../src/contexts/tools/domain/profiles/opencode/profile.js";
import "../../../src/contexts/tools/domain/profiles/vscode/profile.js";
import { supportedBuildTargets } from "../../../src/contexts/translate/domain/build-target.js";
@@ -208,7 +209,11 @@ describe("aidd translate — the help surface", () => {
option.defaultValue,
])
).toEqual([
- ["--to ", "Conversion target (claude, cursor, copilot, codex, opencode)", undefined],
+ [
+ "--to ",
+ "Conversion target (claude, cursor, copilot, codex, opencode, kilo)",
+ undefined,
+ ],
["--out ", "Output directory (marketplace dist or project root)", undefined],
["--as ", "Output layout", "marketplace"],
["--force", "Overwrite existing files at canonical paths under --out", undefined],
diff --git a/cli/tests/presentation/prompts/interactive-menu-use-case.unit.test.ts b/cli/tests/presentation/prompts/interactive-menu-use-case.unit.test.ts
index 172391913..fa4015ae1 100644
--- a/cli/tests/presentation/prompts/interactive-menu-use-case.unit.test.ts
+++ b/cli/tests/presentation/prompts/interactive-menu-use-case.unit.test.ts
@@ -522,10 +522,13 @@ describe("interactive menu — the command each pick hands over", () => {
});
it.each([
- [["inspect", "doctor-tool"], "Tool (e.g. claude, cursor, copilot, codex, opencode, vscode)"],
+ [
+ ["inspect", "doctor-tool"],
+ "Tool (e.g. claude, cursor, copilot, codex, opencode, kilo, vscode)",
+ ],
[
["manage-tools", "framework-install"],
- "Tool (e.g. claude, cursor, copilot, codex, opencode, vscode)",
+ "Tool (e.g. claude, cursor, copilot, codex, opencode, kilo, vscode)",
],
[["manage-tools", "framework-remove"], "Tool to remove"],
[["manage-tools", "framework-update-one"], "Tool to update"],
diff --git a/cli/tests/runtime/assets/asset-loader.unit.test.ts b/cli/tests/runtime/assets/asset-loader.unit.test.ts
index fc1457a1f..6aac77242 100644
--- a/cli/tests/runtime/assets/asset-loader.unit.test.ts
+++ b/cli/tests/runtime/assets/asset-loader.unit.test.ts
@@ -22,6 +22,16 @@ describe("BundledAssetProviderAdapter.loadConfigAsset", () => {
});
});
+ describe("kilo", () => {
+ it("returns parsed kilo.json with its project rules instructions", () => {
+ const asset = provider.loadConfigAsset("kilo", "kilo.json") as Record;
+ expect(asset).toMatchObject({
+ $schema: "https://app.kilo.ai/config.json",
+ instructions: [".kilo/rules/**/*.md"],
+ });
+ });
+ });
+
describe("codex", () => {
it("returns config.toml as raw string", () => {
const asset = provider.loadConfigAsset("codex", "config.toml");
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 9b03ff651..84d394d63 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -4,14 +4,14 @@ Most "how do I…" answers live in the README; this page covers what isn't docum
## 🤔 Why AIDD instead of your own skills?
-You can write your own Claude Code skills — nothing stops you. AIDD exists because that setup is work every team repeats and re-debugs alone: the router/action split ([Skill](GLOSSARY.md#-skill) glossary entry), the plan → implement → review gating, the plugin packaging and versioning, the multi-tool support (Cursor, Copilot, Codex, OpenCode). AIDD ships that scaffolding pre-built and maintained, so you start from a working SDLC loop and only author the skill content specific to your project. If your workflow doesn't match the framework's shape, [`CREATE_PLUGIN.md`](CREATE_PLUGIN.md) shows how to build on the same scaffolding instead of replacing it.
+You can write your own Claude Code skills — nothing stops you. AIDD exists because that setup is work every team repeats and re-debugs alone: the router/action split ([Skill](GLOSSARY.md#-skill) glossary entry), the plan → implement → review gating, the plugin packaging and versioning, the multi-tool support (Cursor, Copilot, Codex, OpenCode, Kilo Code). AIDD ships that scaffolding pre-built and maintained, so you start from a working SDLC loop and only author the skill content specific to your project. If your workflow doesn't match the framework's shape, [`CREATE_PLUGIN.md`](CREATE_PLUGIN.md) shows how to build on the same scaffolding instead of replacing it.
## 📦 Install, update, other tools
- **Install / first run** → [Quick start](../README.md#-quick-start).
- **Update plugins** → `/plugin marketplace update aidd-framework`, or see [Versioning & updates](MARKETPLACE.md#-versioning--updates).
- **Private repo?** Yes — `/plugin marketplace add` just needs GitHub read access (via `gh auth login` or a PAT).
-- **Cursor / Copilot / Codex / OpenCode?** Each other tool installs via its own native mechanism (project files, local plugins, or a plugin command) from the [release](https://github.com/ai-driven-dev/framework/releases/latest) archives. Steps per tool → [Other tools](../README.md#other-tools).
+- **Cursor / Copilot / Codex / OpenCode / Kilo Code?** Each other tool installs via its own native mechanism (project files, local plugins, or a plugin command) from the [release](https://github.com/ai-driven-dev/framework/releases/latest) archives. Steps per tool → [Other tools](../README.md#other-tools).
## 💸 Cost and quotas
diff --git a/docs/MAINTAINERS.md b/docs/MAINTAINERS.md
index d57d64a3f..4014b0884 100644
--- a/docs/MAINTAINERS.md
+++ b/docs/MAINTAINERS.md
@@ -68,7 +68,7 @@ release-please opens/updates a `chore: release main` PR on each push to `main`.
3. CI tags each bumped package, creates the GitHub Releases, and attaches the bundles:
- `aidd-framework-marketplace-X.Y.Z.zip` (`.claude-plugin/` + `plugins/`)
- `-vX.Y.Z.zip`
- - `aidd-framework---X.Y.Z.zip` - per-tool distributions (9 archives: 4 marketplace claude/cursor/copilot/codex + 5 flat incl. opencode), produced by the `build-per-tool` matrix job in `ci.yml`. It builds the CLI from this run's own checkout and runs `translate --to --out --as ` — no published-version pin to bump.
+ - `aidd-framework---X.Y.Z.zip` - per-tool distributions (10 archives: 4 marketplace claude/cursor/copilot/codex + 6 flat incl. opencode and kilo), produced by the `build-per-tool` matrix job in `ci.yml`. It builds the CLI from this run's own checkout and runs `translate --to --out --as ` — no published-version pin to bump.
Versions live in `.release-please-manifest.json`. Forcing a version / pre-release: `release-as` in `release-please-config.json` (remove it after the release ships).
diff --git a/scripts/__tests__/smoke-real-user-scope-tool-list-parity.test.js b/scripts/__tests__/smoke-real-user-scope-tool-list-parity.test.js
index 3f58f7be8..93ffd51bb 100644
--- a/scripts/__tests__/smoke-real-user-scope-tool-list-parity.test.js
+++ b/scripts/__tests__/smoke-real-user-scope-tool-list-parity.test.js
@@ -45,12 +45,14 @@ describe("smoke-real.sh drives --scope user with the tools the profiles support"
assert.deepEqual([...scriptUserAiList()].sort(), [...supported].sort());
});
- it("leaves out the AI tool that declares neither, which setup --scope user refuses", () => {
+ it("leaves out AI tools that declare neither, which setup --scope user refuses", () => {
const unsupported = aiToolIds().filter((id) => !declaresUserScopeActivation(id));
- assert.deepEqual(unsupported, ["opencode"]);
- assert.ok(
- !scriptUserAiList().includes("opencode"),
- "smoke-real.sh's user_ai_list names opencode, which setup --scope user refuses outright"
- );
+ assert.deepEqual([...unsupported].sort(), ["kilo", "opencode"]);
+ for (const toolId of unsupported) {
+ assert.ok(
+ !scriptUserAiList().includes(toolId),
+ `smoke-real.sh's user_ai_list names ${toolId}, which setup --scope user refuses outright`
+ );
+ }
});
});