kirograph 0.28.1 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/architecture/index.js +4 -1
- package/dist/architecture/index.js.map +2 -2
- package/dist/architecture/manifest/index.js +13 -2
- package/dist/architecture/manifest/index.js.map +2 -2
- package/dist/architecture/manifest/python.js +2 -2
- package/dist/architecture/manifest/python.js.map +2 -2
- package/dist/bin/commands/help.js +3 -1
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/install.js +2 -1
- package/dist/bin/commands/install.js.map +2 -2
- package/dist/bin/commands/memory.js +18 -8
- package/dist/bin/commands/memory.js.map +2 -2
- package/dist/bin/commands/reachability.js +7 -2
- package/dist/bin/commands/reachability.js.map +2 -2
- package/dist/bin/commands/status.js +2 -1
- package/dist/bin/commands/status.js.map +2 -2
- package/dist/bin/commands/uninit.js +2 -1
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/commands/vulns.js +26 -6
- package/dist/bin/commands/vulns.js.map +2 -2
- package/dist/bin/commands/wiki.js +56 -0
- package/dist/bin/commands/wiki.js.map +2 -2
- package/dist/bin/installer/common.js +7 -1
- package/dist/bin/installer/common.js.map +2 -2
- package/dist/bin/installer/detect.js +10 -0
- package/dist/bin/installer/detect.js.map +2 -2
- package/dist/bin/installer/hooks.js +13 -8
- package/dist/bin/installer/hooks.js.map +2 -2
- package/dist/bin/installer/steering.js +9 -0
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/antigravity.js +1 -1
- package/dist/bin/installer/targets/antigravity.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +1 -1
- package/dist/bin/installer/targets/claude.js.map +2 -2
- package/dist/bin/installer/targets/codex.js +1 -1
- package/dist/bin/installer/targets/codex.js.map +2 -2
- package/dist/bin/installer/targets/commandcode.js +84 -0
- package/dist/bin/installer/targets/commandcode.js.map +7 -0
- package/dist/bin/installer/targets/copilot.js +1 -1
- package/dist/bin/installer/targets/copilot.js.map +2 -2
- package/dist/bin/installer/targets/cursor.js +2 -2
- package/dist/bin/installer/targets/cursor.js.map +2 -2
- package/dist/bin/installer/targets/devin.js +1 -1
- package/dist/bin/installer/targets/devin.js.map +2 -2
- package/dist/bin/installer/targets/gemini-cli.js +1 -1
- package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
- package/dist/bin/installer/targets/index.js +10 -0
- package/dist/bin/installer/targets/index.js.map +2 -2
- package/dist/bin/installer/targets/opencode.js +1 -1
- package/dist/bin/installer/targets/opencode.js.map +2 -2
- package/dist/bin/installer/targets/windsurf.js +1 -1
- package/dist/bin/installer/targets/windsurf.js.map +2 -2
- package/dist/bin/kirograph.js +1 -1
- package/dist/bin/kirograph.js.map +1 -1
- package/dist/config.js +25 -1
- package/dist/config.js.map +2 -2
- package/dist/core/pipeline.js +18 -6
- package/dist/core/pipeline.js.map +2 -2
- package/dist/extraction/extractor.js +88 -26
- package/dist/extraction/extractor.js.map +2 -2
- package/dist/extraction/grammars.js +38 -3
- package/dist/extraction/grammars.js.map +2 -2
- package/dist/extraction/notebook.js +15 -7
- package/dist/extraction/notebook.js.map +2 -2
- package/dist/extraction/wasm/tree-sitter-bash.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-c.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cpp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-csharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-css.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-dart.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-elisp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-elixir.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-elm.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-embedded_template.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-embeddedtemplate.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-html.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-json.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-kotlin.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-objc.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-ocaml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-php.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-ql.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-rescript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-ruby.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-rust.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-solidity.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-swift.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-systemrdl.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-tlaplus.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-toml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-vue.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-yaml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-zig.wasm +0 -0
- package/dist/frameworks/index.js +68 -7
- package/dist/frameworks/index.js.map +2 -2
- package/dist/jev/client.js +99 -0
- package/dist/jev/client.js.map +7 -0
- package/dist/jev/types.js +17 -0
- package/dist/jev/types.js.map +7 -0
- package/dist/mcp/handlers/memory.js +14 -8
- package/dist/mcp/handlers/memory.js.map +2 -2
- package/dist/mcp/handlers/security.js +5 -3
- package/dist/mcp/handlers/security.js.map +2 -2
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/memory/index.js +13 -1
- package/dist/memory/index.js.map +3 -3
- package/dist/memory/relation-jev.js +59 -0
- package/dist/memory/relation-jev.js.map +7 -0
- package/dist/memory/schema.js +57 -0
- package/dist/memory/schema.js.map +7 -0
- package/dist/security/auth-detection-jev.js +47 -0
- package/dist/security/auth-detection-jev.js.map +7 -0
- package/dist/security/manifest/adapter.js +34 -5
- package/dist/security/manifest/adapter.js.map +3 -3
- package/dist/security/manifest/parser.js +2 -2
- package/dist/security/manifest/parser.js.map +2 -2
- package/dist/security/manifest/plugins/cargo.js +23 -0
- package/dist/security/manifest/plugins/cargo.js.map +2 -2
- package/dist/security/manifest/plugins/composer.js +12 -0
- package/dist/security/manifest/plugins/composer.js.map +2 -2
- package/dist/security/manifest/plugins/gradle.js +12 -0
- package/dist/security/manifest/plugins/gradle.js.map +2 -2
- package/dist/security/manifest/plugins/hex.js +12 -0
- package/dist/security/manifest/plugins/hex.js.map +2 -2
- package/dist/security/manifest/plugins/maven.js +68 -1
- package/dist/security/manifest/plugins/maven.js.map +2 -2
- package/dist/security/manifest/plugins/npm.js +86 -0
- package/dist/security/manifest/plugins/npm.js.map +2 -2
- package/dist/security/manifest/plugins/nuget.js +13 -0
- package/dist/security/manifest/plugins/nuget.js.map +2 -2
- package/dist/security/manifest/plugins/pubspec.js +12 -0
- package/dist/security/manifest/plugins/pubspec.js.map +2 -2
- package/dist/security/manifest/plugins/pyproject.js +12 -0
- package/dist/security/manifest/plugins/pyproject.js.map +2 -2
- package/dist/security/manifest/plugins/rubygems.js +12 -0
- package/dist/security/manifest/plugins/rubygems.js.map +2 -2
- package/dist/security/pipeline.js +5 -2
- package/dist/security/pipeline.js.map +2 -2
- package/dist/security/reachability.js +115 -50
- package/dist/security/reachability.js.map +2 -2
- package/dist/security/types.js.map +1 -1
- package/dist/security/vuln/client.js +45 -1
- package/dist/security/vuln/client.js.map +2 -2
- package/dist/security/vuln/epss-client.js +1 -1
- package/dist/security/vuln/epss-client.js.map +1 -1
- package/dist/security/vuln/osv-adapter.js +144 -32
- package/dist/security/vuln/osv-adapter.js.map +2 -2
- package/dist/sync/index.js +9 -2
- package/dist/sync/index.js.map +2 -2
- package/dist/vectors/libsql-index.js +287 -0
- package/dist/vectors/libsql-index.js.map +7 -0
- package/dist/vectors/turso-index.js +307 -0
- package/dist/vectors/turso-index.js.map +7 -0
- package/dist/wiki/contradiction-jev.js +49 -0
- package/dist/wiki/contradiction-jev.js.map +7 -0
- package/dist/wiki/index.js +13 -0
- package/dist/wiki/index.js.map +2 -2
- package/dist/wiki/ingest.js +2 -0
- package/dist/wiki/ingest.js.map +2 -2
- package/dist/wiki/links.js +53 -0
- package/dist/wiki/links.js.map +7 -0
- package/dist/wiki/lint.js +3 -6
- package/dist/wiki/lint.js.map +2 -2
- package/dist/wiki/rename.js +103 -0
- package/dist/wiki/rename.js.map +7 -0
- package/package.json +3 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/commands/wiki.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * KiroGraph Wiki CLI\n *\n * kirograph wiki init\n * kirograph wiki ingest [source-file]\n * kirograph wiki apply-diff [diff-file]\n * kirograph wiki search <query>\n * kirograph wiki page <slug>\n * kirograph wiki list\n * kirograph wiki lint\n * kirograph wiki reindex\n * kirograph wiki status\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport { dim, reset, violet, bold, section, green } from '../ui';\n\nconst yellow = '\\x1b[33m';\n\nasync function getWiki(cwd: string) {\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n\n if (!KiroGraph.isInitialized(cwd)) {\n console.error(' \u2716 KiroGraph is not initialized. Run `kirograph init` first.');\n process.exit(1);\n }\n const config = await loadConfig(cwd);\n if (!config.enableWiki) {\n console.error(' \u2716 Wiki is not enabled. Set enableWiki: true in .kirograph/config.json');\n process.exit(1);\n }\n\n const cg = await KiroGraph.open(cwd);\n const db = cg.getDatabase();\n db.applyWikiSchema();\n\n const kirographDir = `${cwd}/.kirograph`;\n const wiki = new KiroGraphWiki(db.getRawDb(), kirographDir, {\n autoResolveConflicts: config.wikiAutoResolveConflicts,\n });\n wiki.initialize();\n return wiki;\n}\n\nfunction readStdinSync(): string {\n return fs.readFileSync('/dev/stdin', 'utf8');\n}\n\nexport function register(program: Command): void {\n const wiki = program\n .command('wiki')\n .description('LLM-maintained structured wiki (requires enableWiki: true)');\n\n // \u2500\u2500 init \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('init')\n .description('Initialize wiki: create SCHEMA.md and MANIFEST.md in .kirograph/wiki/')\n .action(async () => {\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n const cwd = process.cwd();\n if (!KiroGraph.isInitialized(cwd)) {\n console.error(' \u2716 KiroGraph is not initialized. Run `kirograph init` first.');\n process.exit(1);\n }\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const config = await loadConfig(cwd);\n const cg = await KiroGraph.open(cwd);\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const w = new KiroGraphWiki(db.getRawDb(), `${cwd}/.kirograph`, {\n autoResolveConflicts: config.wikiAutoResolveConflicts,\n });\n w.initWiki();\n console.log(`\\n ${green}\u2713${reset} Wiki initialized in ${dim}.kirograph/wiki/${reset}`);\n console.log(` ${dim}Edit .kirograph/wiki/SCHEMA.md to customize naming and page structure.${reset}\\n`);\n });\n\n // \u2500\u2500 ingest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('ingest [source]')\n .description('Print the ingest prompt for the LLM (reads file or stdin)')\n .option('--name <name>', 'Source name to include in the prompt')\n .action(async (source: string | undefined, opts: { name?: string }) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n\n let content: string;\n let sourceName = opts.name ?? source ?? 'source';\n\n if (source && fs.existsSync(source)) {\n content = fs.readFileSync(source, 'utf8');\n sourceName = opts.name ?? source;\n } else if (source) {\n content = source;\n } else {\n content = readStdinSync();\n }\n\n const prompt = w.getIngestPrompt(content, sourceName);\n console.log(`\\n ${section('Wiki Ingest Prompt')} ${dim}(pass to LLM, then run wiki apply-diff)${reset}\\n`);\n console.log(prompt);\n console.log();\n });\n\n // \u2500\u2500 apply-diff \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('apply-diff [diff]')\n .description('Apply a WIKI_DIFF string to the wiki (reads file or stdin)')\n .action(async (diff: string | undefined) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n\n let rawDiff: string;\n if (diff && fs.existsSync(diff)) {\n rawDiff = fs.readFileSync(diff, 'utf8');\n } else if (diff) {\n rawDiff = diff;\n } else {\n rawDiff = readStdinSync();\n }\n\n const result = w.applyDiff(rawDiff);\n\n console.log(`\\n ${green}\u2713${reset} Wiki diff applied\\n`);\n if (result.created.length) {\n console.log(` ${violet}Created:${reset} ${result.created.join(', ')}`);\n }\n if (result.updated.length) {\n console.log(` ${violet}Updated:${reset} ${result.updated.join(', ')}`);\n }\n if (result.conflictsResolved.length) {\n console.log(` ${green}Conflicts resolved:${reset} ${result.conflictsResolved.join(', ')}`);\n }\n if (result.conflictsPending.length) {\n console.log(`\\n ${yellow}\u26A1 Conflicts pending (${result.conflictsPending.length}):${reset}`);\n for (const c of result.conflictsPending) {\n console.log(` ${dim} ${c.page} \u00A7${c.section}${reset}`);\n console.log(` existing: \"${c.existing}\"`);\n console.log(` incoming: \"${c.incoming}\" (source: ${c.source})`);\n }\n }\n console.log();\n });\n\n // \u2500\u2500 search \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('search <query>')\n .description('Full-text search over wiki pages')\n .option('--limit <n>', 'Max results', '5')\n .option('--format <fmt>', 'Output format: text, json', 'text')\n .action(async (query: string, opts: { limit: string; format: string }) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const results = w.search(query, parseInt(opts.limit));\n\n if (opts.format === 'json') {\n console.log(JSON.stringify(results.map(r => ({\n slug: r.page.slug,\n title: r.page.title,\n score: r.score,\n updatedAt: r.page.updatedAt,\n })), null, 2));\n return;\n }\n\n if (results.length === 0) {\n console.log(`\\n ${dim}No wiki pages found for \"${query}\"${reset}\\n`);\n return;\n }\n\n console.log(`\\n ${section('Wiki Search:')} ${violet}${bold}${query}${reset}\\n`);\n for (const { page, score } of results) {\n console.log(` ${violet}[${page.slug}]${reset} ${bold}${page.title}${reset} ${dim}score: ${score.toFixed(3)}${reset}`);\n const preview = page.content.split('\\n').find(l => l.trim() && !l.startsWith('#'));\n if (preview) console.log(` ${dim}${preview.trim().slice(0, 120)}${reset}`);\n console.log();\n }\n });\n\n // \u2500\u2500 page \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('page <slug>')\n .description('Print the full content of a wiki page')\n .action(async (slug: string) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const page = w.getPage(slug);\n if (!page) {\n console.error(` \u2716 Wiki page \"${slug}\" not found. Run \\`kirograph wiki list\\` to see available pages.`);\n process.exit(1);\n }\n console.log();\n console.log(page.content);\n });\n\n // \u2500\u2500 list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('list')\n .description('List all wiki pages')\n .option('--format <fmt>', 'Output format: text, json', 'text')\n .action(async (opts: { format: string }) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const pages = w.listPages();\n\n if (opts.format === 'json') {\n console.log(JSON.stringify(pages.map(p => ({\n slug: p.slug,\n title: p.title,\n sourceCount: p.sourceCount,\n updatedAt: p.updatedAt,\n })), null, 2));\n return;\n }\n\n const stats = w.getStats();\n console.log(`\\n ${section('Wiki')} ${dim}${stats.pageCount} page(s)${reset}\\n`);\n if (pages.length === 0) {\n console.log(` ${dim}No pages yet. Run \\`kirograph wiki ingest\\` to add pages.${reset}\\n`);\n return;\n }\n for (const p of pages) {\n const date = new Date(p.updatedAt).toISOString().slice(0, 10);\n console.log(` ${violet}${p.slug.padEnd(32)}${reset} ${p.title} ${dim}(${p.sourceCount} src, ${date})${reset}`);\n }\n console.log();\n });\n\n // \u2500\u2500 lint \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('lint')\n .description('Health check the wiki for issues')\n .action(async () => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const issues = w.lint();\n\n if (issues.length === 0) {\n console.log(`\\n ${green}\u2713${reset} Wiki lint passed \u2014 no issues found.\\n`);\n return;\n }\n\n console.log(`\\n ${section('Wiki Lint')} ${yellow}${issues.length} issue(s)${reset}\\n`);\n for (const issue of issues) {\n const icon = issue.kind === 'contradiction' ? '\u26A1' : issue.kind === 'orphan' ? '\u25CB' : issue.kind === 'broken_link' ? '\uD83D\uDD17' : '\u26A0';\n console.log(` ${icon} ${dim}[${issue.kind}]${reset} ${violet}${issue.slug}${reset}`);\n console.log(` ${issue.detail}`);\n console.log();\n }\n });\n\n // \u2500\u2500 reindex \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('reindex')\n .description('Rebuild SQLite index from .kirograph/wiki/*.md files')\n .action(async () => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const count = w.reindex();\n console.log(`\\n ${green}\u2713${reset} Reindexed ${bold}${count}${reset} wiki page(s)\\n`);\n });\n\n // \u2500\u2500 status \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('status')\n .description('Wiki subsystem stats')\n .action(async () => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const stats = w.getStats();\n const oldest = stats.oldestPage ? new Date(stats.oldestPage).toISOString().slice(0, 10) : 'n/a';\n const newest = stats.newestPage ? new Date(stats.newestPage).toISOString().slice(0, 10) : 'n/a';\n console.log(`\\n ${section('Wiki Status')}\\n`);\n console.log(` Pages: ${bold}${stats.pageCount}${reset}`);\n console.log(` Total sources: ${bold}${stats.totalSources}${reset}`);\n console.log(` Oldest page: ${dim}${oldest}${reset}`);\n console.log(` Newest page: ${dim}${newest}${reset}`);\n console.log(` Wiki dir: ${dim}.kirograph/wiki/${reset}\\n`);\n });\n\n // \u2500\u2500 synthesize (local model) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('synthesize')\n .description('Run local-model wiki synthesis: process the pending source queue (wikiSynthesisMode: local)')\n .option('--quiet', 'suppress progress output')\n .action(async (opts) => {\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n const cwd = process.cwd();\n\n if (!KiroGraph.isInitialized(cwd)) {\n console.error(' \u2716 KiroGraph is not initialized. Run `kirograph init` first.');\n process.exit(1);\n }\n const config = await loadConfig(cwd);\n if (!config.enableWiki) {\n console.error(' \u2716 Wiki is not enabled.');\n process.exit(1);\n }\n if (config.wikiSynthesisMode !== 'local') {\n console.error(' \u2716 wikiSynthesisMode is not \"local\". This command is for local-model synthesis only.');\n process.exit(1);\n }\n\n const cg = await KiroGraph.open(cwd);\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const w = new KiroGraphWiki(db.getRawDb(), `${cwd}/.kirograph`, {\n autoResolveConflicts: config.wikiAutoResolveConflicts,\n });\n w.initialize();\n\n const queueCount = w.getQueueCount();\n if (queueCount === 0) {\n if (!opts.quiet) console.log(`\\n ${dim}Wiki queue is empty \u2014 nothing to synthesize.${reset}\\n`);\n process.exit(0);\n }\n\n if (!opts.quiet) console.log(`\\n ${yellow}\u27F3${reset} Synthesizing ${bold}${queueCount}${reset} queued source(s) with local model...\\n`);\n\n const result = await w.synthesize(config.wikiLocalModel, !!opts.quiet);\n\n if (!opts.quiet) {\n if (result.processed > 0) {\n console.log(` ${green}\u2713${reset} Processed: ${bold}${result.processed}${reset} source(s)`);\n if (result.created.length) console.log(` ${green}\u2713${reset} Created: ${result.created.join(', ')}`);\n if (result.updated.length) console.log(` ${green}\u2713${reset} Updated: ${result.updated.join(', ')}`);\n }\n if (result.errors.length) {\n for (const e of result.errors) console.error(` ${yellow}\u26A0${reset} ${e}`);\n }\n console.log('');\n }\n });\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph Wiki CLI\n *\n * kirograph wiki init\n * kirograph wiki ingest [source-file]\n * kirograph wiki apply-diff [diff-file]\n * kirograph wiki search <query>\n * kirograph wiki page <slug>\n * kirograph wiki list\n * kirograph wiki lint\n * kirograph wiki links <slug>\n * kirograph wiki rename <from> <to>\n * kirograph wiki reindex\n * kirograph wiki status\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport { dim, reset, violet, bold, section, green } from '../ui';\n\nconst yellow = '\\x1b[33m';\n\nasync function getWiki(cwd: string) {\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n\n if (!KiroGraph.isInitialized(cwd)) {\n console.error(' \u2716 KiroGraph is not initialized. Run `kirograph init` first.');\n process.exit(1);\n }\n const config = await loadConfig(cwd);\n if (!config.enableWiki) {\n console.error(' \u2716 Wiki is not enabled. Set enableWiki: true in .kirograph/config.json');\n process.exit(1);\n }\n\n const cg = await KiroGraph.open(cwd);\n const db = cg.getDatabase();\n db.applyWikiSchema();\n\n const kirographDir = `${cwd}/.kirograph`;\n const wiki = new KiroGraphWiki(db.getRawDb(), kirographDir, {\n autoResolveConflicts: config.wikiAutoResolveConflicts,\n });\n wiki.initialize();\n return wiki;\n}\n\nfunction readStdinSync(): string {\n return fs.readFileSync('/dev/stdin', 'utf8');\n}\n\nexport function register(program: Command): void {\n const wiki = program\n .command('wiki')\n .description('LLM-maintained structured wiki (requires enableWiki: true)');\n\n // \u2500\u2500 init \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('init')\n .description('Initialize wiki: create SCHEMA.md and MANIFEST.md in .kirograph/wiki/')\n .action(async () => {\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n const cwd = process.cwd();\n if (!KiroGraph.isInitialized(cwd)) {\n console.error(' \u2716 KiroGraph is not initialized. Run `kirograph init` first.');\n process.exit(1);\n }\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const config = await loadConfig(cwd);\n const cg = await KiroGraph.open(cwd);\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const w = new KiroGraphWiki(db.getRawDb(), `${cwd}/.kirograph`, {\n autoResolveConflicts: config.wikiAutoResolveConflicts,\n });\n w.initWiki();\n console.log(`\\n ${green}\u2713${reset} Wiki initialized in ${dim}.kirograph/wiki/${reset}`);\n console.log(` ${dim}Edit .kirograph/wiki/SCHEMA.md to customize naming and page structure.${reset}\\n`);\n });\n\n // \u2500\u2500 ingest \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('ingest [source]')\n .description('Print the ingest prompt for the LLM (reads file or stdin)')\n .option('--name <name>', 'Source name to include in the prompt')\n .action(async (source: string | undefined, opts: { name?: string }) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n\n let content: string;\n let sourceName = opts.name ?? source ?? 'source';\n\n if (source && fs.existsSync(source)) {\n content = fs.readFileSync(source, 'utf8');\n sourceName = opts.name ?? source;\n } else if (source) {\n content = source;\n } else {\n content = readStdinSync();\n }\n\n const prompt = w.getIngestPrompt(content, sourceName);\n console.log(`\\n ${section('Wiki Ingest Prompt')} ${dim}(pass to LLM, then run wiki apply-diff)${reset}\\n`);\n console.log(prompt);\n console.log();\n });\n\n // \u2500\u2500 apply-diff \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('apply-diff [diff]')\n .description('Apply a WIKI_DIFF string to the wiki (reads file or stdin)')\n .action(async (diff: string | undefined) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n\n let rawDiff: string;\n if (diff && fs.existsSync(diff)) {\n rawDiff = fs.readFileSync(diff, 'utf8');\n } else if (diff) {\n rawDiff = diff;\n } else {\n rawDiff = readStdinSync();\n }\n\n const result = w.applyDiff(rawDiff);\n\n console.log(`\\n ${green}\u2713${reset} Wiki diff applied\\n`);\n if (result.created.length) {\n console.log(` ${violet}Created:${reset} ${result.created.join(', ')}`);\n }\n if (result.updated.length) {\n console.log(` ${violet}Updated:${reset} ${result.updated.join(', ')}`);\n }\n if (result.conflictsResolved.length) {\n console.log(` ${green}Conflicts resolved:${reset} ${result.conflictsResolved.join(', ')}`);\n }\n if (result.conflictsPending.length) {\n console.log(`\\n ${yellow}\u26A1 Conflicts pending (${result.conflictsPending.length}):${reset}`);\n for (const c of result.conflictsPending) {\n console.log(` ${dim} ${c.page} \u00A7${c.section}${reset}`);\n console.log(` existing: \"${c.existing}\"`);\n console.log(` incoming: \"${c.incoming}\" (source: ${c.source})`);\n }\n }\n console.log();\n });\n\n // \u2500\u2500 search \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('search <query>')\n .description('Full-text search over wiki pages')\n .option('--limit <n>', 'Max results', '5')\n .option('--format <fmt>', 'Output format: text, json', 'text')\n .action(async (query: string, opts: { limit: string; format: string }) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const results = w.search(query, parseInt(opts.limit));\n\n if (opts.format === 'json') {\n console.log(JSON.stringify(results.map(r => ({\n slug: r.page.slug,\n title: r.page.title,\n score: r.score,\n updatedAt: r.page.updatedAt,\n })), null, 2));\n return;\n }\n\n if (results.length === 0) {\n console.log(`\\n ${dim}No wiki pages found for \"${query}\"${reset}\\n`);\n return;\n }\n\n console.log(`\\n ${section('Wiki Search:')} ${violet}${bold}${query}${reset}\\n`);\n for (const { page, score } of results) {\n console.log(` ${violet}[${page.slug}]${reset} ${bold}${page.title}${reset} ${dim}score: ${score.toFixed(3)}${reset}`);\n const preview = page.content.split('\\n').find(l => l.trim() && !l.startsWith('#'));\n if (preview) console.log(` ${dim}${preview.trim().slice(0, 120)}${reset}`);\n console.log();\n }\n });\n\n // \u2500\u2500 page \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('page <slug>')\n .description('Print the full content of a wiki page')\n .action(async (slug: string) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const page = w.getPage(slug);\n if (!page) {\n console.error(` \u2716 Wiki page \"${slug}\" not found. Run \\`kirograph wiki list\\` to see available pages.`);\n process.exit(1);\n }\n console.log();\n console.log(page.content);\n });\n\n // \u2500\u2500 list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('list')\n .description('List all wiki pages')\n .option('--format <fmt>', 'Output format: text, json', 'text')\n .action(async (opts: { format: string }) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const pages = w.listPages();\n\n if (opts.format === 'json') {\n console.log(JSON.stringify(pages.map(p => ({\n slug: p.slug,\n title: p.title,\n sourceCount: p.sourceCount,\n updatedAt: p.updatedAt,\n })), null, 2));\n return;\n }\n\n const stats = w.getStats();\n console.log(`\\n ${section('Wiki')} ${dim}${stats.pageCount} page(s)${reset}\\n`);\n if (pages.length === 0) {\n console.log(` ${dim}No pages yet. Run \\`kirograph wiki ingest\\` to add pages.${reset}\\n`);\n return;\n }\n for (const p of pages) {\n const date = new Date(p.updatedAt).toISOString().slice(0, 10);\n console.log(` ${violet}${p.slug.padEnd(32)}${reset} ${p.title} ${dim}(${p.sourceCount} src, ${date})${reset}`);\n }\n console.log();\n });\n\n // \u2500\u2500 lint \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('lint')\n .description('Health check the wiki for issues')\n .action(async () => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const issues = w.lint();\n\n if (issues.length === 0) {\n console.log(`\\n ${green}\u2713${reset} Wiki lint passed \u2014 no issues found.\\n`);\n return;\n }\n\n console.log(`\\n ${section('Wiki Lint')} ${yellow}${issues.length} issue(s)${reset}\\n`);\n for (const issue of issues) {\n const icon = issue.kind === 'contradiction' ? '\u26A1' : issue.kind === 'orphan' ? '\u25CB' : issue.kind === 'broken_link' ? '\uD83D\uDD17' : '\u26A0';\n console.log(` ${icon} ${dim}[${issue.kind}]${reset} ${violet}${issue.slug}${reset}`);\n console.log(` ${issue.detail}`);\n console.log();\n }\n });\n\n // \u2500\u2500 links \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('links <slug>')\n .description('Show outgoing, broken, and incoming [[slug]] links for a page')\n .option('--format <fmt>', 'Output format: text, json', 'text')\n .action(async (slug: string, opts: { format: string }) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const links = w.getLinks(slug);\n\n if (!links) {\n console.error(` \u2716 Wiki page \"${slug}\" not found. Run \\`kirograph wiki list\\` to see available pages.`);\n process.exit(1);\n }\n\n if (opts.format === 'json') {\n console.log(JSON.stringify(links, null, 2));\n return;\n }\n\n console.log(`\\n ${section('Wiki Links:')} ${violet}${bold}${slug}${reset}\\n`);\n\n console.log(` ${bold}Outgoing${reset} ${dim}(${links.outgoing.length})${reset}`);\n if (links.outgoing.length === 0) {\n console.log(` ${dim}(none)${reset}`);\n } else {\n for (const s of links.outgoing) console.log(` ${violet}\u2192${reset} [[${s}]]`);\n }\n\n if (links.broken.length > 0) {\n console.log(`\\n ${yellow}Broken${reset} ${dim}(${links.broken.length})${reset}`);\n for (const s of links.broken) console.log(` ${yellow}\u26A0${reset} [[${s}]] ${dim}\u2014 page does not exist${reset}`);\n }\n\n console.log(`\\n ${bold}Incoming${reset} ${dim}(${links.incoming.length}) \u2014 pages that link here${reset}`);\n if (links.incoming.length === 0) {\n console.log(` ${dim}(none)${reset}`);\n } else {\n for (const s of links.incoming) console.log(` ${violet}\u2190${reset} [[${s}]]`);\n }\n console.log();\n });\n\n // \u2500\u2500 rename \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('rename <from> <to>')\n .description('Rename a page slug, moving its file and updating every [[slug]] reference to it')\n .action(async (from: string, to: string) => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n\n let result;\n try {\n result = w.rename(from, to);\n } catch (err) {\n console.error(` \u2716 ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n console.log(`\\n ${green}\u2713${reset} Renamed ${violet}[[${result.from}]]${reset} \u2192 ${violet}[[${result.to}]]${reset}\\n`);\n if (result.linksUpdated.length > 0) {\n console.log(` ${bold}Links updated in ${result.linksUpdated.length} page(s):${reset}`);\n for (const s of result.linksUpdated) console.log(` ${dim}\u00B7${reset} ${s}`);\n } else {\n console.log(` ${dim}No other pages referenced [[${result.from}]].${reset}`);\n }\n console.log();\n });\n\n // \u2500\u2500 reindex \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('reindex')\n .description('Rebuild SQLite index from .kirograph/wiki/*.md files')\n .action(async () => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const count = w.reindex();\n console.log(`\\n ${green}\u2713${reset} Reindexed ${bold}${count}${reset} wiki page(s)\\n`);\n });\n\n // \u2500\u2500 status \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('status')\n .description('Wiki subsystem stats')\n .action(async () => {\n const cwd = process.cwd();\n const w = await getWiki(cwd);\n const stats = w.getStats();\n const oldest = stats.oldestPage ? new Date(stats.oldestPage).toISOString().slice(0, 10) : 'n/a';\n const newest = stats.newestPage ? new Date(stats.newestPage).toISOString().slice(0, 10) : 'n/a';\n console.log(`\\n ${section('Wiki Status')}\\n`);\n console.log(` Pages: ${bold}${stats.pageCount}${reset}`);\n console.log(` Total sources: ${bold}${stats.totalSources}${reset}`);\n console.log(` Oldest page: ${dim}${oldest}${reset}`);\n console.log(` Newest page: ${dim}${newest}${reset}`);\n console.log(` Wiki dir: ${dim}.kirograph/wiki/${reset}\\n`);\n });\n\n // \u2500\u2500 synthesize (local model) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n wiki\n .command('synthesize')\n .description('Run local-model wiki synthesis: process the pending source queue (wikiSynthesisMode: local)')\n .option('--quiet', 'suppress progress output')\n .action(async (opts) => {\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n const cwd = process.cwd();\n\n if (!KiroGraph.isInitialized(cwd)) {\n console.error(' \u2716 KiroGraph is not initialized. Run `kirograph init` first.');\n process.exit(1);\n }\n const config = await loadConfig(cwd);\n if (!config.enableWiki) {\n console.error(' \u2716 Wiki is not enabled.');\n process.exit(1);\n }\n if (config.wikiSynthesisMode !== 'local') {\n console.error(' \u2716 wikiSynthesisMode is not \"local\". This command is for local-model synthesis only.');\n process.exit(1);\n }\n\n const cg = await KiroGraph.open(cwd);\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const w = new KiroGraphWiki(db.getRawDb(), `${cwd}/.kirograph`, {\n autoResolveConflicts: config.wikiAutoResolveConflicts,\n });\n w.initialize();\n\n const queueCount = w.getQueueCount();\n if (queueCount === 0) {\n if (!opts.quiet) console.log(`\\n ${dim}Wiki queue is empty \u2014 nothing to synthesize.${reset}\\n`);\n process.exit(0);\n }\n\n if (!opts.quiet) console.log(`\\n ${yellow}\u27F3${reset} Synthesizing ${bold}${queueCount}${reset} queued source(s) with local model...\\n`);\n\n const result = await w.synthesize(config.wikiLocalModel, !!opts.quiet);\n\n if (!opts.quiet) {\n if (result.processed > 0) {\n console.log(` ${green}\u2713${reset} Processed: ${bold}${result.processed}${reset} source(s)`);\n if (result.created.length) console.log(` ${green}\u2713${reset} Created: ${result.created.join(', ')}`);\n if (result.updated.length) console.log(` ${green}\u2713${reset} Updated: ${result.updated.join(', ')}`);\n }\n if (result.errors.length) {\n for (const e of result.errors) console.error(` ${yellow}\u26A0${reset} ${e}`);\n }\n console.log('');\n }\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -44,6 +44,7 @@ __export(common_exports, {
|
|
|
44
44
|
removeGeneratedBlock: () => removeGeneratedBlock,
|
|
45
45
|
removeImportLine: () => removeImportLine,
|
|
46
46
|
removeMcpServersConfig: () => removeMcpServersConfig,
|
|
47
|
+
silentCommand: () => silentCommand,
|
|
47
48
|
upsertGeneratedBlock: () => upsertGeneratedBlock,
|
|
48
49
|
writeJson: () => writeJson,
|
|
49
50
|
writeMcpServersConfig: () => writeMcpServersConfig
|
|
@@ -55,7 +56,11 @@ var import_tool_names = require("../../mcp/tool-names");
|
|
|
55
56
|
const KIROGRAPH_SERVER_NAME = "kirograph";
|
|
56
57
|
const KIROGRAPH_COMMAND = "kirograph";
|
|
57
58
|
const KIROGRAPH_MCP_ARGS = ["serve", "--mcp"];
|
|
58
|
-
|
|
59
|
+
function silentCommand(baseCommand) {
|
|
60
|
+
const isWindows = process.platform === "win32";
|
|
61
|
+
return isWindows ? `${baseCommand} >nul 2>&1 || exit /b 0` : `${baseCommand} >/dev/null 2>&1 || true`;
|
|
62
|
+
}
|
|
63
|
+
const KIROGRAPH_SYNC_CMD = silentCommand("kirograph sync-if-dirty --quiet");
|
|
59
64
|
const KIROGRAPH_TOOLS = import_tool_names.KIROGRAPH_TOOL_NAMES;
|
|
60
65
|
const KIROGRAPH_SCOPED_TOOLS = import_tool_names.KIROGRAPH_TOOL_NAMES.map((name) => `@kirograph/${name}`);
|
|
61
66
|
function ensureDir(p) {
|
|
@@ -214,6 +219,7 @@ function printMcpCommand(command) {
|
|
|
214
219
|
removeGeneratedBlock,
|
|
215
220
|
removeImportLine,
|
|
216
221
|
removeMcpServersConfig,
|
|
222
|
+
silentCommand,
|
|
217
223
|
upsertGeneratedBlock,
|
|
218
224
|
writeJson,
|
|
219
225
|
writeMcpServersConfig
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/installer/common.ts"],
|
|
4
|
-
"sourcesContent": ["import * as fs from 'fs';\nimport * as path from 'path';\nimport { KIROGRAPH_TOOL_NAMES } from '../../mcp/tool-names';\nimport type { InstructionOptions } from './instructions';\nimport type { CavemanMode } from './caveman';\n\n/** Single options object passed to every target's installLate(). */\nexport interface LateInstallOptions {\n cavemanMode?: CavemanMode | 'off';\n shellCompressionLevel?: string;\n enableMemory?: boolean;\n enableDocs?: boolean;\n enableData?: boolean;\n enableSecurity?: boolean;\n enableArchitecture?: boolean;\n enablePatterns?: boolean;\n enableWatchmen?: boolean;\n watchmenSynthesisMode?: 'local' | 'agent';\n enableWiki?: boolean;\n wikiSynthesisMode?: 'local' | 'agent';\n wikiLocalModel?: string;\n enableCodeHealth?: boolean;\n enableNavigation?: boolean;\n enableComplexity?: boolean;\n enableGitContext?: boolean;\n enableEditPrimitives?: boolean;\n enableBranch?: boolean;\n enableAgentUtils?: boolean;\n enableGeneralCompression?: boolean;\n trackCallSites?: boolean;\n kiroHookFormat?: 'v1-legacy' | 'v2';\n}\n\nexport type InstallTarget = 'kiro' | 'claude' | 'codex' | 'cursor' | 'antigravity' | 'opencode' | 'windsurf' | 'cline' | 'copilot' | 'copilot-cli' | 'junie' | 'gemini-cli' | 'continue' | 'roo' | 'warp' | 'aider' | 'trae' | 'augment' | 'kilo' | 'amp' | 'devin' | 'replit' | 'goose' | 'openhands' | 'tabnine' | 'mistral-vibe' | 'ibm-bob' | 'crush' | 'droid-factory' | 'forgecode' | 'iflow' | 'qwen' | 'rovo' | 'qoder';\n\nexport const KIROGRAPH_SERVER_NAME = 'kirograph';\nexport const KIROGRAPH_COMMAND = 'kirograph';\nexport const KIROGRAPH_MCP_ARGS = ['serve', '--mcp'];\nexport const KIROGRAPH_SYNC_CMD = 'kirograph sync-if-dirty --quiet 2>/dev/null || true';\nexport const KIROGRAPH_TOOLS = KIROGRAPH_TOOL_NAMES;\nexport const KIROGRAPH_SCOPED_TOOLS = KIROGRAPH_TOOL_NAMES.map(name => `@kirograph/${name}`);\n\nexport function ensureDir(p: string): void {\n fs.mkdirSync(p, { recursive: true });\n}\n\nexport function readJson(p: string): any {\n try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch { return {}; }\n}\n\nexport function writeJson(p: string, data: unknown): void {\n fs.writeFileSync(p, JSON.stringify(data, null, 2) + '\\n');\n}\n\n/**\n * Write MCP server config to a JSON file under the mcpServers key.\n * Returns true if the config was written, false if already configured (idempotent).\n */\nexport function writeMcpServersConfig(configPath: string, serverConfig: object): boolean {\n ensureDir(path.dirname(configPath));\n const existing = readJson(configPath);\n existing.mcpServers = existing.mcpServers ?? {};\n if (existing.mcpServers[KIROGRAPH_SERVER_NAME]) {\n return false; // Already configured\n }\n existing.mcpServers[KIROGRAPH_SERVER_NAME] = serverConfig;\n writeJson(configPath, existing);\n return true;\n}\n\n/**\n * Always write (overwrite) the MCP server config entry, regardless of whether it already exists.\n * Used when the final state is known upfront and idempotency would cause stale data.\n */\nexport function overwriteMcpServersConfig(configPath: string, serverConfig: object): void {\n ensureDir(path.dirname(configPath));\n const existing = readJson(configPath);\n existing.mcpServers = existing.mcpServers ?? {};\n existing.mcpServers[KIROGRAPH_SERVER_NAME] = serverConfig;\n writeJson(configPath, existing);\n}\n\nexport function removeMcpServersConfig(configPath: string): boolean {\n if (!fs.existsSync(configPath)) return false;\n const existing = readJson(configPath);\n if (!existing.mcpServers?.[KIROGRAPH_SERVER_NAME]) return false;\n delete existing.mcpServers[KIROGRAPH_SERVER_NAME];\n writeJson(configPath, existing);\n return true;\n}\n\nexport function appendImportLine(filePath: string, line: string, heading: string): boolean {\n const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';\n if (existing.includes(line)) return false;\n\n const prefix = existing.length > 0 && !existing.endsWith('\\n') ? '\\n' : '';\n const separator = existing.trim().length > 0 ? '\\n' : '';\n fs.writeFileSync(filePath, existing + prefix + separator + heading + '\\n' + line + '\\n');\n return true;\n}\n\nexport function removeImportLine(filePath: string, line: string): boolean {\n if (!fs.existsSync(filePath)) return false;\n const original = fs.readFileSync(filePath, 'utf8');\n const next = original\n .split('\\n')\n .filter(l => l.trim() !== line)\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n');\n if (next === original) return false;\n fs.writeFileSync(filePath, next.endsWith('\\n') ? next : next + '\\n');\n return true;\n}\n\nexport function upsertGeneratedBlock(filePath: string, blockId: string, heading: string, content: string): boolean {\n const start = `<!-- kirograph:${blockId}:start -->`;\n const end = `<!-- kirograph:${blockId}:end -->`;\n const block = `${start}\\n${heading}\\n\\n${content.trim()}\\n${end}`;\n const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';\n const pattern = new RegExp(`${escapeRegExp(start)}[\\\\s\\\\S]*?${escapeRegExp(end)}`);\n\n if (pattern.test(existing)) {\n const next = existing.replace(pattern, block);\n if (next === existing) return false;\n fs.writeFileSync(filePath, next.endsWith('\\n') ? next : next + '\\n');\n return true;\n }\n\n const prefix = existing.length > 0 && !existing.endsWith('\\n') ? '\\n' : '';\n const separator = existing.trim().length > 0 ? '\\n' : '';\n fs.writeFileSync(filePath, existing + prefix + separator + block + '\\n');\n return true;\n}\n\nexport function removeGeneratedBlock(filePath: string, blockId: string): boolean {\n if (!fs.existsSync(filePath)) return false;\n const start = `<!-- kirograph:${blockId}:start -->`;\n const end = `<!-- kirograph:${blockId}:end -->`;\n const original = fs.readFileSync(filePath, 'utf8');\n const pattern = new RegExp(`\\\\n?${escapeRegExp(start)}[\\\\s\\\\S]*?${escapeRegExp(end)}\\\\n?`);\n const next = original.replace(pattern, '\\n').replace(/\\n{3,}/g, '\\n\\n');\n if (next === original) return false;\n fs.writeFileSync(filePath, next.endsWith('\\n') ? next : next + '\\n');\n return true;\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Build InstructionOptions from the installLate parameters.\n * Used by all targets to pass full feature config to buildAgentInstructions.\n */\nexport function buildInstructionOpts(opts: LateInstallOptions, hasHooks?: boolean): InstructionOptions {\n return {\n cavemanMode: opts.cavemanMode,\n shellCompressionLevel: (opts.shellCompressionLevel as InstructionOptions['shellCompressionLevel']) ?? undefined,\n enableArchitecture: opts.enableArchitecture ?? false,\n enableMemory: opts.enableMemory ?? false,\n enableDocs: opts.enableDocs ?? false,\n enableData: opts.enableData ?? false,\n enableSecurity: opts.enableSecurity ?? false,\n enablePatterns: opts.enablePatterns ?? false,\n enableWiki: opts.enableWiki ?? false,\n enableCodeHealth: opts.enableCodeHealth ?? false,\n enableNavigation: opts.enableNavigation ?? false,\n enableComplexity: opts.enableComplexity ?? false,\n enableGitContext: opts.enableGitContext ?? false,\n enableEditPrimitives: opts.enableEditPrimitives ?? false,\n enableBranch: opts.enableBranch ?? false,\n enableAgentUtils: opts.enableAgentUtils ?? false,\n enableGeneralCompression: opts.enableGeneralCompression ?? false,\n trackCallSites: opts.trackCallSites ?? false,\n hasHooks: hasHooks ?? false,\n };\n}\n\nconst violet = '\\x1b[38;5;99m';\nconst resetAnsi = '\\x1b[0m';\nconst dimAnsi = '\\x1b[2m';\nconst boldAnsi = '\\x1b[1m';\n\n/**\n * Print a highlighted MCP config JSON block for targets that need user-scoped setup.\n */\nexport function printMcpSetup(configPath: string, projectRoot: string): void {\n const escapedPath = projectRoot.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n console.log(`\\n ${dimAnsi}Add the MCP server manually:${resetAnsi}`);\n console.log(` ${dimAnsi}Edit${resetAnsi} ${violet}${boldAnsi}${configPath}${resetAnsi} ${dimAnsi}and add:${resetAnsi}`);\n console.log(` ${violet}{${resetAnsi}`);\n console.log(` ${violet} \"mcpServers\": {${resetAnsi}`);\n console.log(` ${violet} \"kirograph\": {${resetAnsi}`);\n console.log(` ${violet} \"command\": \"kirograph\",${resetAnsi}`);\n console.log(` ${violet} \"args\": [\"serve\", \"--mcp\", \"--path\", \"${escapedPath}\"]${resetAnsi}`);\n console.log(` ${violet} }${resetAnsi}`);\n console.log(` ${violet} }${resetAnsi}`);\n console.log(` ${violet}}${resetAnsi}\\n`);\n}\n\n/**\n * Print a highlighted CLI command for MCP registration.\n */\nexport function printMcpCommand(command: string): void {\n console.log(`\\n ${dimAnsi}Add the MCP server with:${resetAnsi}`);\n console.log(` ${violet}${boldAnsi}${command}${resetAnsi}\\n`);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAoB;AACpB,WAAsB;AACtB,wBAAqC;AAiC9B,MAAM,wBAAwB;AAC9B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB,CAAC,SAAS,OAAO;
|
|
4
|
+
"sourcesContent": ["import * as fs from 'fs';\nimport * as path from 'path';\nimport { KIROGRAPH_TOOL_NAMES } from '../../mcp/tool-names';\nimport type { InstructionOptions } from './instructions';\nimport type { CavemanMode } from './caveman';\n\n/** Single options object passed to every target's installLate(). */\nexport interface LateInstallOptions {\n cavemanMode?: CavemanMode | 'off';\n shellCompressionLevel?: string;\n enableMemory?: boolean;\n enableDocs?: boolean;\n enableData?: boolean;\n enableSecurity?: boolean;\n enableArchitecture?: boolean;\n enablePatterns?: boolean;\n enableWatchmen?: boolean;\n watchmenSynthesisMode?: 'local' | 'agent';\n enableWiki?: boolean;\n wikiSynthesisMode?: 'local' | 'agent';\n wikiLocalModel?: string;\n enableCodeHealth?: boolean;\n enableNavigation?: boolean;\n enableComplexity?: boolean;\n enableGitContext?: boolean;\n enableEditPrimitives?: boolean;\n enableBranch?: boolean;\n enableAgentUtils?: boolean;\n enableGeneralCompression?: boolean;\n trackCallSites?: boolean;\n kiroHookFormat?: 'v1-legacy' | 'v2';\n}\n\nexport type InstallTarget = 'kiro' | 'claude' | 'codex' | 'cursor' | 'antigravity' | 'opencode' | 'windsurf' | 'cline' | 'copilot' | 'copilot-cli' | 'junie' | 'gemini-cli' | 'continue' | 'roo' | 'warp' | 'aider' | 'trae' | 'augment' | 'kilo' | 'amp' | 'devin' | 'replit' | 'goose' | 'openhands' | 'tabnine' | 'mistral-vibe' | 'ibm-bob' | 'crush' | 'droid-factory' | 'forgecode' | 'iflow' | 'qwen' | 'rovo' | 'qoder' | 'commandcode';\n\nexport const KIROGRAPH_SERVER_NAME = 'kirograph';\nexport const KIROGRAPH_COMMAND = 'kirograph';\nexport const KIROGRAPH_MCP_ARGS = ['serve', '--mcp'];\n\n/**\n * Wrap a kirograph command so it runs quietly and never fails the host process,\n * emitting shell syntax appropriate for the OS the install is running on.\n *\n * Hook commands are executed by the host agent's shell: POSIX sh/bash on\n * macOS/Linux, cmd.exe on Windows. The two use incompatible syntax for\n * discarding output and swallowing a non-zero exit code:\n * - POSIX: `<cmd> >/dev/null 2>&1 || true`\n * - cmd.exe: `<cmd> >nul 2>&1 || exit /b 0`\n *\n * On Windows `/dev/null` is treated as a literal path and `true` is not a valid\n * command, so the bash form silently breaks hooks (see issue #40).\n *\n * @param baseCommand the kirograph invocation without redirection, e.g. `kirograph sync --quiet`\n */\nexport function silentCommand(baseCommand: string): string {\n const isWindows = process.platform === 'win32';\n return isWindows\n ? `${baseCommand} >nul 2>&1 || exit /b 0`\n : `${baseCommand} >/dev/null 2>&1 || true`;\n}\n\nexport const KIROGRAPH_SYNC_CMD = silentCommand('kirograph sync-if-dirty --quiet');\nexport const KIROGRAPH_TOOLS = KIROGRAPH_TOOL_NAMES;\nexport const KIROGRAPH_SCOPED_TOOLS = KIROGRAPH_TOOL_NAMES.map(name => `@kirograph/${name}`);\n\nexport function ensureDir(p: string): void {\n fs.mkdirSync(p, { recursive: true });\n}\n\nexport function readJson(p: string): any {\n try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch { return {}; }\n}\n\nexport function writeJson(p: string, data: unknown): void {\n fs.writeFileSync(p, JSON.stringify(data, null, 2) + '\\n');\n}\n\n/**\n * Write MCP server config to a JSON file under the mcpServers key.\n * Returns true if the config was written, false if already configured (idempotent).\n */\nexport function writeMcpServersConfig(configPath: string, serverConfig: object): boolean {\n ensureDir(path.dirname(configPath));\n const existing = readJson(configPath);\n existing.mcpServers = existing.mcpServers ?? {};\n if (existing.mcpServers[KIROGRAPH_SERVER_NAME]) {\n return false; // Already configured\n }\n existing.mcpServers[KIROGRAPH_SERVER_NAME] = serverConfig;\n writeJson(configPath, existing);\n return true;\n}\n\n/**\n * Always write (overwrite) the MCP server config entry, regardless of whether it already exists.\n * Used when the final state is known upfront and idempotency would cause stale data.\n */\nexport function overwriteMcpServersConfig(configPath: string, serverConfig: object): void {\n ensureDir(path.dirname(configPath));\n const existing = readJson(configPath);\n existing.mcpServers = existing.mcpServers ?? {};\n existing.mcpServers[KIROGRAPH_SERVER_NAME] = serverConfig;\n writeJson(configPath, existing);\n}\n\nexport function removeMcpServersConfig(configPath: string): boolean {\n if (!fs.existsSync(configPath)) return false;\n const existing = readJson(configPath);\n if (!existing.mcpServers?.[KIROGRAPH_SERVER_NAME]) return false;\n delete existing.mcpServers[KIROGRAPH_SERVER_NAME];\n writeJson(configPath, existing);\n return true;\n}\n\nexport function appendImportLine(filePath: string, line: string, heading: string): boolean {\n const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';\n if (existing.includes(line)) return false;\n\n const prefix = existing.length > 0 && !existing.endsWith('\\n') ? '\\n' : '';\n const separator = existing.trim().length > 0 ? '\\n' : '';\n fs.writeFileSync(filePath, existing + prefix + separator + heading + '\\n' + line + '\\n');\n return true;\n}\n\nexport function removeImportLine(filePath: string, line: string): boolean {\n if (!fs.existsSync(filePath)) return false;\n const original = fs.readFileSync(filePath, 'utf8');\n const next = original\n .split('\\n')\n .filter(l => l.trim() !== line)\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n');\n if (next === original) return false;\n fs.writeFileSync(filePath, next.endsWith('\\n') ? next : next + '\\n');\n return true;\n}\n\nexport function upsertGeneratedBlock(filePath: string, blockId: string, heading: string, content: string): boolean {\n const start = `<!-- kirograph:${blockId}:start -->`;\n const end = `<!-- kirograph:${blockId}:end -->`;\n const block = `${start}\\n${heading}\\n\\n${content.trim()}\\n${end}`;\n const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';\n const pattern = new RegExp(`${escapeRegExp(start)}[\\\\s\\\\S]*?${escapeRegExp(end)}`);\n\n if (pattern.test(existing)) {\n const next = existing.replace(pattern, block);\n if (next === existing) return false;\n fs.writeFileSync(filePath, next.endsWith('\\n') ? next : next + '\\n');\n return true;\n }\n\n const prefix = existing.length > 0 && !existing.endsWith('\\n') ? '\\n' : '';\n const separator = existing.trim().length > 0 ? '\\n' : '';\n fs.writeFileSync(filePath, existing + prefix + separator + block + '\\n');\n return true;\n}\n\nexport function removeGeneratedBlock(filePath: string, blockId: string): boolean {\n if (!fs.existsSync(filePath)) return false;\n const start = `<!-- kirograph:${blockId}:start -->`;\n const end = `<!-- kirograph:${blockId}:end -->`;\n const original = fs.readFileSync(filePath, 'utf8');\n const pattern = new RegExp(`\\\\n?${escapeRegExp(start)}[\\\\s\\\\S]*?${escapeRegExp(end)}\\\\n?`);\n const next = original.replace(pattern, '\\n').replace(/\\n{3,}/g, '\\n\\n');\n if (next === original) return false;\n fs.writeFileSync(filePath, next.endsWith('\\n') ? next : next + '\\n');\n return true;\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Build InstructionOptions from the installLate parameters.\n * Used by all targets to pass full feature config to buildAgentInstructions.\n */\nexport function buildInstructionOpts(opts: LateInstallOptions, hasHooks?: boolean): InstructionOptions {\n return {\n cavemanMode: opts.cavemanMode,\n shellCompressionLevel: (opts.shellCompressionLevel as InstructionOptions['shellCompressionLevel']) ?? undefined,\n enableArchitecture: opts.enableArchitecture ?? false,\n enableMemory: opts.enableMemory ?? false,\n enableDocs: opts.enableDocs ?? false,\n enableData: opts.enableData ?? false,\n enableSecurity: opts.enableSecurity ?? false,\n enablePatterns: opts.enablePatterns ?? false,\n enableWiki: opts.enableWiki ?? false,\n enableCodeHealth: opts.enableCodeHealth ?? false,\n enableNavigation: opts.enableNavigation ?? false,\n enableComplexity: opts.enableComplexity ?? false,\n enableGitContext: opts.enableGitContext ?? false,\n enableEditPrimitives: opts.enableEditPrimitives ?? false,\n enableBranch: opts.enableBranch ?? false,\n enableAgentUtils: opts.enableAgentUtils ?? false,\n enableGeneralCompression: opts.enableGeneralCompression ?? false,\n trackCallSites: opts.trackCallSites ?? false,\n hasHooks: hasHooks ?? false,\n };\n}\n\nconst violet = '\\x1b[38;5;99m';\nconst resetAnsi = '\\x1b[0m';\nconst dimAnsi = '\\x1b[2m';\nconst boldAnsi = '\\x1b[1m';\n\n/**\n * Print a highlighted MCP config JSON block for targets that need user-scoped setup.\n */\nexport function printMcpSetup(configPath: string, projectRoot: string): void {\n const escapedPath = projectRoot.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n console.log(`\\n ${dimAnsi}Add the MCP server manually:${resetAnsi}`);\n console.log(` ${dimAnsi}Edit${resetAnsi} ${violet}${boldAnsi}${configPath}${resetAnsi} ${dimAnsi}and add:${resetAnsi}`);\n console.log(` ${violet}{${resetAnsi}`);\n console.log(` ${violet} \"mcpServers\": {${resetAnsi}`);\n console.log(` ${violet} \"kirograph\": {${resetAnsi}`);\n console.log(` ${violet} \"command\": \"kirograph\",${resetAnsi}`);\n console.log(` ${violet} \"args\": [\"serve\", \"--mcp\", \"--path\", \"${escapedPath}\"]${resetAnsi}`);\n console.log(` ${violet} }${resetAnsi}`);\n console.log(` ${violet} }${resetAnsi}`);\n console.log(` ${violet}}${resetAnsi}\\n`);\n}\n\n/**\n * Print a highlighted CLI command for MCP registration.\n */\nexport function printMcpCommand(command: string): void {\n console.log(`\\n ${dimAnsi}Add the MCP server with:${resetAnsi}`);\n console.log(` ${violet}${boldAnsi}${command}${resetAnsi}\\n`);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -286,6 +286,16 @@ const DETECTORS = [
|
|
|
286
286
|
if (dirExists(path.join(root, ".qoder"))) return { target: "qoder", label: "Qoder", reason: ".qoder/ found in project" };
|
|
287
287
|
return false;
|
|
288
288
|
}
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
target: "commandcode",
|
|
292
|
+
label: "Command Code",
|
|
293
|
+
reason: "",
|
|
294
|
+
detect: () => {
|
|
295
|
+
if (dirExists(path.join(home, ".commandcode"))) return { target: "commandcode", label: "Command Code", reason: "~/.commandcode/ found" };
|
|
296
|
+
if (whichExists("command-code")) return { target: "commandcode", label: "Command Code", reason: "command-code binary found in PATH" };
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
289
299
|
}
|
|
290
300
|
];
|
|
291
301
|
function detectPlatforms(projectRoot) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/installer/detect.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Platform auto-detection for KiroGraph installer.\n *\n * Detects which AI coding tools are installed on the system by checking\n * for known config directories and CLI binaries. Used by `kirograph install`\n * (with no --target flag) to auto-configure all detected platforms.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\nimport type { InstallTarget } from './common';\n\nexport interface PlatformDetector {\n target: InstallTarget;\n label: string;\n /** How the platform was detected (shown to user) */\n reason: string;\n detect: (projectRoot: string) => DetectionResult | false;\n}\n\nexport interface DetectionResult {\n target: InstallTarget;\n label: string;\n reason: string;\n}\n\nfunction whichExists(binary: string): boolean {\n try {\n execSync(`which ${binary}`, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction dirExists(p: string): boolean {\n return fs.existsSync(p) && fs.statSync(p).isDirectory();\n}\n\nfunction fileExists(p: string): boolean {\n return fs.existsSync(p) && fs.statSync(p).isFile();\n}\n\nconst home = process.env.HOME || process.env.USERPROFILE || '';\n\nconst DETECTORS: PlatformDetector[] = [\n {\n target: 'kiro',\n label: 'Kiro',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.kiro'))) return { target: 'kiro', label: 'Kiro', reason: '.kiro/ found in project' };\n if (dirExists(path.join(home, '.kiro'))) return { target: 'kiro', label: 'Kiro', reason: '~/.kiro/ found' };\n return false;\n },\n },\n {\n target: 'claude',\n label: 'Claude Code',\n reason: '',\n detect: (root) => {\n if (fileExists(path.join(root, '.mcp.json'))) return { target: 'claude', label: 'Claude Code', reason: '.mcp.json found in project' };\n if (whichExists('claude')) return { target: 'claude', label: 'Claude Code', reason: 'claude binary on PATH' };\n return false;\n },\n },\n {\n target: 'cursor',\n label: 'Cursor',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.cursor'))) return { target: 'cursor', label: 'Cursor', reason: '.cursor/ found in project' };\n if (dirExists(path.join(home, '.cursor'))) return { target: 'cursor', label: 'Cursor', reason: '~/.cursor/ found' };\n return false;\n },\n },\n {\n target: 'windsurf',\n label: 'Windsurf',\n reason: '',\n detect: () => {\n if (dirExists(path.join(home, '.codeium', 'windsurf'))) return { target: 'windsurf', label: 'Windsurf', reason: '~/.codeium/windsurf/ found' };\n return false;\n },\n },\n {\n target: 'codex',\n label: 'Codex',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.codex'))) return { target: 'codex', label: 'Codex', reason: '.codex/ found in project' };\n if (dirExists(path.join(home, '.codex'))) return { target: 'codex', label: 'Codex', reason: '~/.codex/ found' };\n if (whichExists('codex')) return { target: 'codex', label: 'Codex', reason: 'codex binary on PATH' };\n return false;\n },\n },\n {\n target: 'copilot',\n label: 'GitHub Copilot',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.vscode'))) return { target: 'copilot', label: 'GitHub Copilot', reason: '.vscode/ found in project' };\n if (dirExists(path.join(home, '.vscode'))) return { target: 'copilot', label: 'GitHub Copilot', reason: '~/.vscode/ found' };\n return false;\n },\n },\n {\n target: 'gemini-cli',\n label: 'Gemini CLI',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.gemini'))) return { target: 'gemini-cli', label: 'Gemini CLI', reason: '.gemini/ found in project' };\n if (whichExists('gemini')) return { target: 'gemini-cli', label: 'Gemini CLI', reason: 'gemini binary on PATH' };\n if (dirExists(path.join(home, '.gemini'))) return { target: 'gemini-cli', label: 'Gemini CLI', reason: '~/.gemini/ found' };\n return false;\n },\n },\n {\n target: 'cline',\n label: 'Cline',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.cline'))) return { target: 'cline', label: 'Cline', reason: '.cline/ found in project' };\n if (dirExists(path.join(root, '.clinerules'))) return { target: 'cline', label: 'Cline', reason: '.clinerules/ found in project' };\n return false;\n },\n },\n {\n target: 'roo',\n label: 'Roo Code',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.roo'))) return { target: 'roo', label: 'Roo Code', reason: '.roo/ found in project' };\n return false;\n },\n },\n {\n target: 'warp',\n label: 'Warp',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.warp'))) return { target: 'warp', label: 'Warp', reason: '.warp/ found in project' };\n if (whichExists('warp')) return { target: 'warp', label: 'Warp', reason: 'warp binary on PATH' };\n return false;\n },\n },\n {\n target: 'continue',\n label: 'Continue',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.continue'))) return { target: 'continue', label: 'Continue', reason: '.continue/ found in project' };\n if (dirExists(path.join(home, '.continue'))) return { target: 'continue', label: 'Continue', reason: '~/.continue/ found' };\n return false;\n },\n },\n {\n target: 'opencode',\n label: 'OpenCode',\n reason: '',\n detect: (root) => {\n if (fileExists(path.join(root, '.opencode.json'))) return { target: 'opencode', label: 'OpenCode', reason: '.opencode.json found in project' };\n return false;\n },\n },\n {\n target: 'antigravity',\n label: 'Antigravity',\n reason: '',\n detect: () => {\n if (dirExists(path.join(home, '.gemini', 'antigravity'))) return { target: 'antigravity', label: 'Antigravity', reason: '~/.gemini/antigravity/ found' };\n return false;\n },\n },\n {\n target: 'trae',\n label: 'Trae',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.trae'))) return { target: 'trae', label: 'Trae', reason: '.trae/ found in project' };\n return false;\n },\n },\n {\n target: 'amp',\n label: 'Sourcegraph Amp',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.amp'))) return { target: 'amp', label: 'Sourcegraph Amp', reason: '.amp/ found in project' };\n return false;\n },\n },\n {\n target: 'aider',\n label: 'Aider',\n reason: '',\n detect: () => {\n if (whichExists('aider')) return { target: 'aider', label: 'Aider', reason: 'aider binary on PATH' };\n return false;\n },\n },\n {\n target: 'goose',\n label: 'Block Goose',\n reason: '',\n detect: () => {\n if (whichExists('goose')) return { target: 'goose', label: 'Block Goose', reason: 'goose binary on PATH' };\n return false;\n },\n },\n {\n target: 'junie',\n label: 'JetBrains Junie',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.junie'))) return { target: 'junie', label: 'JetBrains Junie', reason: '.junie/ found in project' };\n return false;\n },\n },\n {\n target: 'augment',\n label: 'Augment Code',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.augment'))) return { target: 'augment', label: 'Augment Code', reason: '.augment/ found in project' };\n return false;\n },\n },\n {\n target: 'kilo',\n label: 'Kilo Code',\n reason: '',\n detect: (root) => {\n if (fileExists(path.join(root, 'kilo.json'))) return { target: 'kilo', label: 'Kilo Code', reason: 'kilo.json found in project' };\n return false;\n },\n },\n {\n target: 'devin',\n label: 'Devin',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.devin'))) return { target: 'devin', label: 'Devin', reason: '.devin/ found in project' };\n return false;\n },\n },\n {\n target: 'openhands',\n label: 'OpenHands',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.openhands'))) return { target: 'openhands', label: 'OpenHands', reason: '.openhands/ found in project' };\n return false;\n },\n },\n {\n target: 'tabnine',\n label: 'Tabnine',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.tabnine'))) return { target: 'tabnine', label: 'Tabnine', reason: '.tabnine/ found in project' };\n return false;\n },\n },\n {\n target: 'replit',\n label: 'Replit Agent',\n reason: '',\n detect: (root) => {\n if (fileExists(path.join(root, '.replit'))) return { target: 'replit', label: 'Replit Agent', reason: '.replit found in project' };\n return false;\n },\n },\n {\n target: 'qoder',\n label: 'Qoder',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.qoder'))) return { target: 'qoder', label: 'Qoder', reason: '.qoder/ found in project' };\n return false;\n },\n },\n];\n\n/**\n * Detect all AI coding platforms installed on this system / in this project.\n * Returns detection results for all platforms that were found.\n */\nexport function detectPlatforms(projectRoot: string): DetectionResult[] {\n const results: DetectionResult[] = [];\n for (const detector of DETECTORS) {\n const result = detector.detect(projectRoot);\n if (result) {\n results.push(result);\n }\n }\n return results;\n}\n\n/**\n * Get just the target names of detected platforms.\n */\nexport function detectTargets(projectRoot: string): InstallTarget[] {\n return detectPlatforms(projectRoot).map(r => r.target);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Platform auto-detection for KiroGraph installer.\n *\n * Detects which AI coding tools are installed on the system by checking\n * for known config directories and CLI binaries. Used by `kirograph install`\n * (with no --target flag) to auto-configure all detected platforms.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { execSync } from 'child_process';\nimport type { InstallTarget } from './common';\n\nexport interface PlatformDetector {\n target: InstallTarget;\n label: string;\n /** How the platform was detected (shown to user) */\n reason: string;\n detect: (projectRoot: string) => DetectionResult | false;\n}\n\nexport interface DetectionResult {\n target: InstallTarget;\n label: string;\n reason: string;\n}\n\nfunction whichExists(binary: string): boolean {\n try {\n execSync(`which ${binary}`, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction dirExists(p: string): boolean {\n return fs.existsSync(p) && fs.statSync(p).isDirectory();\n}\n\nfunction fileExists(p: string): boolean {\n return fs.existsSync(p) && fs.statSync(p).isFile();\n}\n\nconst home = process.env.HOME || process.env.USERPROFILE || '';\n\nconst DETECTORS: PlatformDetector[] = [\n {\n target: 'kiro',\n label: 'Kiro',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.kiro'))) return { target: 'kiro', label: 'Kiro', reason: '.kiro/ found in project' };\n if (dirExists(path.join(home, '.kiro'))) return { target: 'kiro', label: 'Kiro', reason: '~/.kiro/ found' };\n return false;\n },\n },\n {\n target: 'claude',\n label: 'Claude Code',\n reason: '',\n detect: (root) => {\n if (fileExists(path.join(root, '.mcp.json'))) return { target: 'claude', label: 'Claude Code', reason: '.mcp.json found in project' };\n if (whichExists('claude')) return { target: 'claude', label: 'Claude Code', reason: 'claude binary on PATH' };\n return false;\n },\n },\n {\n target: 'cursor',\n label: 'Cursor',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.cursor'))) return { target: 'cursor', label: 'Cursor', reason: '.cursor/ found in project' };\n if (dirExists(path.join(home, '.cursor'))) return { target: 'cursor', label: 'Cursor', reason: '~/.cursor/ found' };\n return false;\n },\n },\n {\n target: 'windsurf',\n label: 'Windsurf',\n reason: '',\n detect: () => {\n if (dirExists(path.join(home, '.codeium', 'windsurf'))) return { target: 'windsurf', label: 'Windsurf', reason: '~/.codeium/windsurf/ found' };\n return false;\n },\n },\n {\n target: 'codex',\n label: 'Codex',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.codex'))) return { target: 'codex', label: 'Codex', reason: '.codex/ found in project' };\n if (dirExists(path.join(home, '.codex'))) return { target: 'codex', label: 'Codex', reason: '~/.codex/ found' };\n if (whichExists('codex')) return { target: 'codex', label: 'Codex', reason: 'codex binary on PATH' };\n return false;\n },\n },\n {\n target: 'copilot',\n label: 'GitHub Copilot',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.vscode'))) return { target: 'copilot', label: 'GitHub Copilot', reason: '.vscode/ found in project' };\n if (dirExists(path.join(home, '.vscode'))) return { target: 'copilot', label: 'GitHub Copilot', reason: '~/.vscode/ found' };\n return false;\n },\n },\n {\n target: 'gemini-cli',\n label: 'Gemini CLI',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.gemini'))) return { target: 'gemini-cli', label: 'Gemini CLI', reason: '.gemini/ found in project' };\n if (whichExists('gemini')) return { target: 'gemini-cli', label: 'Gemini CLI', reason: 'gemini binary on PATH' };\n if (dirExists(path.join(home, '.gemini'))) return { target: 'gemini-cli', label: 'Gemini CLI', reason: '~/.gemini/ found' };\n return false;\n },\n },\n {\n target: 'cline',\n label: 'Cline',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.cline'))) return { target: 'cline', label: 'Cline', reason: '.cline/ found in project' };\n if (dirExists(path.join(root, '.clinerules'))) return { target: 'cline', label: 'Cline', reason: '.clinerules/ found in project' };\n return false;\n },\n },\n {\n target: 'roo',\n label: 'Roo Code',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.roo'))) return { target: 'roo', label: 'Roo Code', reason: '.roo/ found in project' };\n return false;\n },\n },\n {\n target: 'warp',\n label: 'Warp',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.warp'))) return { target: 'warp', label: 'Warp', reason: '.warp/ found in project' };\n if (whichExists('warp')) return { target: 'warp', label: 'Warp', reason: 'warp binary on PATH' };\n return false;\n },\n },\n {\n target: 'continue',\n label: 'Continue',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.continue'))) return { target: 'continue', label: 'Continue', reason: '.continue/ found in project' };\n if (dirExists(path.join(home, '.continue'))) return { target: 'continue', label: 'Continue', reason: '~/.continue/ found' };\n return false;\n },\n },\n {\n target: 'opencode',\n label: 'OpenCode',\n reason: '',\n detect: (root) => {\n if (fileExists(path.join(root, '.opencode.json'))) return { target: 'opencode', label: 'OpenCode', reason: '.opencode.json found in project' };\n return false;\n },\n },\n {\n target: 'antigravity',\n label: 'Antigravity',\n reason: '',\n detect: () => {\n if (dirExists(path.join(home, '.gemini', 'antigravity'))) return { target: 'antigravity', label: 'Antigravity', reason: '~/.gemini/antigravity/ found' };\n return false;\n },\n },\n {\n target: 'trae',\n label: 'Trae',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.trae'))) return { target: 'trae', label: 'Trae', reason: '.trae/ found in project' };\n return false;\n },\n },\n {\n target: 'amp',\n label: 'Sourcegraph Amp',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.amp'))) return { target: 'amp', label: 'Sourcegraph Amp', reason: '.amp/ found in project' };\n return false;\n },\n },\n {\n target: 'aider',\n label: 'Aider',\n reason: '',\n detect: () => {\n if (whichExists('aider')) return { target: 'aider', label: 'Aider', reason: 'aider binary on PATH' };\n return false;\n },\n },\n {\n target: 'goose',\n label: 'Block Goose',\n reason: '',\n detect: () => {\n if (whichExists('goose')) return { target: 'goose', label: 'Block Goose', reason: 'goose binary on PATH' };\n return false;\n },\n },\n {\n target: 'junie',\n label: 'JetBrains Junie',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.junie'))) return { target: 'junie', label: 'JetBrains Junie', reason: '.junie/ found in project' };\n return false;\n },\n },\n {\n target: 'augment',\n label: 'Augment Code',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.augment'))) return { target: 'augment', label: 'Augment Code', reason: '.augment/ found in project' };\n return false;\n },\n },\n {\n target: 'kilo',\n label: 'Kilo Code',\n reason: '',\n detect: (root) => {\n if (fileExists(path.join(root, 'kilo.json'))) return { target: 'kilo', label: 'Kilo Code', reason: 'kilo.json found in project' };\n return false;\n },\n },\n {\n target: 'devin',\n label: 'Devin',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.devin'))) return { target: 'devin', label: 'Devin', reason: '.devin/ found in project' };\n return false;\n },\n },\n {\n target: 'openhands',\n label: 'OpenHands',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.openhands'))) return { target: 'openhands', label: 'OpenHands', reason: '.openhands/ found in project' };\n return false;\n },\n },\n {\n target: 'tabnine',\n label: 'Tabnine',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.tabnine'))) return { target: 'tabnine', label: 'Tabnine', reason: '.tabnine/ found in project' };\n return false;\n },\n },\n {\n target: 'replit',\n label: 'Replit Agent',\n reason: '',\n detect: (root) => {\n if (fileExists(path.join(root, '.replit'))) return { target: 'replit', label: 'Replit Agent', reason: '.replit found in project' };\n return false;\n },\n },\n {\n target: 'qoder',\n label: 'Qoder',\n reason: '',\n detect: (root) => {\n if (dirExists(path.join(root, '.qoder'))) return { target: 'qoder', label: 'Qoder', reason: '.qoder/ found in project' };\n return false;\n },\n },\n {\n target: 'commandcode',\n label: 'Command Code',\n reason: '',\n detect: () => {\n // Command Code stores user/global state in ~/.commandcode/ and ships the\n // `command-code` binary (run as `cmd`). Avoid keying off .mcp.json \u2014 it's\n // shared with other agents (e.g. Claude) and would misfire.\n if (dirExists(path.join(home, '.commandcode'))) return { target: 'commandcode', label: 'Command Code', reason: '~/.commandcode/ found' };\n if (whichExists('command-code')) return { target: 'commandcode', label: 'Command Code', reason: 'command-code binary found in PATH' };\n return false;\n },\n },\n];\n\n/**\n * Detect all AI coding platforms installed on this system / in this project.\n * Returns detection results for all platforms that were found.\n */\nexport function detectPlatforms(projectRoot: string): DetectionResult[] {\n const results: DetectionResult[] = [];\n for (const detector of DETECTORS) {\n const result = detector.detect(projectRoot);\n if (result) {\n results.push(result);\n }\n }\n return results;\n}\n\n/**\n * Get just the target names of detected platforms.\n */\nexport function detectTargets(projectRoot: string): InstallTarget[] {\n return detectPlatforms(projectRoot).map(r => r.target);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -33,8 +33,13 @@ __export(hooks_exports, {
|
|
|
33
33
|
module.exports = __toCommonJS(hooks_exports);
|
|
34
34
|
var fs = __toESM(require("fs"));
|
|
35
35
|
var path = __toESM(require("path"));
|
|
36
|
+
var import_common = require("./common");
|
|
36
37
|
const V2_EXT = ".json";
|
|
37
38
|
const V1_EXT = ".kiro.hook";
|
|
39
|
+
const SYNC_CMD = (0, import_common.silentCommand)("kirograph sync --quiet");
|
|
40
|
+
const WATCHMEN_SYNTH_CMD = (0, import_common.silentCommand)("kirograph mem watchmen synthesize --quiet");
|
|
41
|
+
const WIKI_SYNTH_CMD = (0, import_common.silentCommand)("kirograph wiki synthesize --quiet");
|
|
42
|
+
const WIKI_LINT_CMD = (0, import_common.silentCommand)("kirograph wiki lint");
|
|
38
43
|
function buildWatchmenHook(synthesisMode) {
|
|
39
44
|
if (synthesisMode === "local") {
|
|
40
45
|
return {
|
|
@@ -45,7 +50,7 @@ function buildWatchmenHook(synthesisMode) {
|
|
|
45
50
|
hooks: [{
|
|
46
51
|
name: "KiroGraph Watchmen",
|
|
47
52
|
trigger: "Stop",
|
|
48
|
-
action: { type: "command", command:
|
|
53
|
+
action: { type: "command", command: WATCHMEN_SYNTH_CMD }
|
|
49
54
|
}]
|
|
50
55
|
},
|
|
51
56
|
v1: {
|
|
@@ -53,7 +58,7 @@ function buildWatchmenHook(synthesisMode) {
|
|
|
53
58
|
version: "1.0.0",
|
|
54
59
|
description: "After memory capture, run local model synthesis if enough observations have accumulated.",
|
|
55
60
|
when: { type: "agentStop" },
|
|
56
|
-
then: { type: "runCommand", command:
|
|
61
|
+
then: { type: "runCommand", command: WATCHMEN_SYNTH_CMD }
|
|
57
62
|
}
|
|
58
63
|
};
|
|
59
64
|
}
|
|
@@ -93,7 +98,7 @@ const HOOKS = [
|
|
|
93
98
|
hooks: [{
|
|
94
99
|
name: "KiroGraph Sync on Agent Stop",
|
|
95
100
|
trigger: "Stop",
|
|
96
|
-
action: { type: "command", command:
|
|
101
|
+
action: { type: "command", command: SYNC_CMD }
|
|
97
102
|
}]
|
|
98
103
|
},
|
|
99
104
|
v1: {
|
|
@@ -101,7 +106,7 @@ const HOOKS = [
|
|
|
101
106
|
version: "1.0.0",
|
|
102
107
|
description: "Sync the KiroGraph index when the agent stops, picking up any file edits, creates, or deletes from the session.",
|
|
103
108
|
when: { type: "agentStop" },
|
|
104
|
-
then: { type: "runCommand", command:
|
|
109
|
+
then: { type: "runCommand", command: SYNC_CMD }
|
|
105
110
|
}
|
|
106
111
|
},
|
|
107
112
|
{
|
|
@@ -235,7 +240,7 @@ Skip if the session was trivial (simple bug fix, no new knowledge).`;
|
|
|
235
240
|
hooks: [{
|
|
236
241
|
name: "KiroGraph Wiki Synthesize",
|
|
237
242
|
trigger: "Stop",
|
|
238
|
-
action: { type: "command", command:
|
|
243
|
+
action: { type: "command", command: WIKI_SYNTH_CMD }
|
|
239
244
|
}]
|
|
240
245
|
},
|
|
241
246
|
v1: {
|
|
@@ -243,7 +248,7 @@ Skip if the session was trivial (simple bug fix, no new knowledge).`;
|
|
|
243
248
|
version: "1.0.0",
|
|
244
249
|
description: "After each session, run local-model wiki synthesis over queued sources.",
|
|
245
250
|
when: { type: "agentStop" },
|
|
246
|
-
then: { type: "runCommand", command:
|
|
251
|
+
then: { type: "runCommand", command: WIKI_SYNTH_CMD }
|
|
247
252
|
}
|
|
248
253
|
}, format);
|
|
249
254
|
} else {
|
|
@@ -275,7 +280,7 @@ Skip if the session was trivial (simple bug fix, no new knowledge).`;
|
|
|
275
280
|
hooks: [{
|
|
276
281
|
name: "KiroGraph Wiki Lint",
|
|
277
282
|
trigger: "Stop",
|
|
278
|
-
action: { type: "command", command:
|
|
283
|
+
action: { type: "command", command: WIKI_LINT_CMD }
|
|
279
284
|
}]
|
|
280
285
|
},
|
|
281
286
|
v1: {
|
|
@@ -283,7 +288,7 @@ Skip if the session was trivial (simple bug fix, no new knowledge).`;
|
|
|
283
288
|
version: "1.0.0",
|
|
284
289
|
description: `Run wiki health check every ${lintFreq} sessions to catch broken links, orphan pages, and contradictions.`,
|
|
285
290
|
when: { type: "agentStop" },
|
|
286
|
-
then: { type: "runCommand", command:
|
|
291
|
+
then: { type: "runCommand", command: WIKI_LINT_CMD }
|
|
287
292
|
}
|
|
288
293
|
}, format);
|
|
289
294
|
} else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/installer/hooks.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * KiroGraph Installer \u2014 Kiro hook file management\n *\n * Generates hooks in BOTH formats for compatibility:\n *\n * v2 (new Kiro IDE): `.kiro/hooks/<id>.json`\n * { \"version\": \"v1\", \"hooks\": [{ \"name\", \"trigger\", \"matcher?\", \"action\": { type, command|prompt } }] }\n *\n * v1 (legacy Kiro IDE): `.kiro/hooks/<id>.kiro.hook`\n * { \"name\", \"version\", \"description\", \"when\": { type, toolTypes? }, \"then\": { type, command|prompt } }\n *\n * Old Kiro ignores .json files; new Kiro ignores .kiro.hook files.\n * Writing both ensures KiroGraph works regardless of which IDE version the user runs.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n// \u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst V2_EXT = '.json';\nconst V1_EXT = '.kiro.hook';\n\n// \u2500\u2500 Hook builders \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface HookDef {\n id: string;\n description: string;\n v2: object; // new Kiro IDE format\n v1: object; // legacy Kiro IDE format\n}\n\nfunction buildWatchmenHook(synthesisMode: 'local' | 'agent'): HookDef {\n if (synthesisMode === 'local') {\n return {\n id: 'kirograph-watchmen',\n description: 'After memory capture, run local model synthesis if enough observations have accumulated.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Watchmen',\n trigger: 'Stop',\n action: { type: 'command', command: 'kirograph mem watchmen synthesize --quiet 2>&1 || true' },\n }],\n },\n v1: {\n name: 'KiroGraph Watchmen',\n version: '1.0.0',\n description: 'After memory capture, run local model synthesis if enough observations have accumulated.',\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: 'kirograph mem watchmen synthesize --quiet 2>&1 || true' },\n },\n };\n }\n\n const watchmenPrompt = `Check if KiroGraph Watchmen synthesis should run: call kirograph_mem_store with kind='note' and content='watchmen check'. If the response does not include watchmenReady: true, do nothing and stop.\n\nIf watchmenReady: true:\n1. Call kirograph_mem_search for each kind (decision, error, pattern, architecture, note) with limit 20.\n2. Write or update the workspace brief: upsert the ## KiroGraph Watchmen section in each file listed in targetFiles. For .kiro/steering/kirograph-watchmen.md use inclusion: always frontmatter with sections for Decisions, Known Errors & Fixes, Recurring Patterns, and Architecture Notes. For all other files write a compact ## KiroGraph Watchmen block.\n3. Generate skill files: if skillTargetDir is present in the response, identify recurring procedures (any procedure appearing in 3+ observations). For each, write a .kiro/steering/watchmen-<slug>.md file with inclusion: manual frontmatter, a short title, a \"When to use\" line with trigger phrases, and numbered steps. Prefix all generated files with watchmen- so they are distinguishable from hand-written steering files. Remove any .kiro/steering/watchmen-*.md files from previous runs that no longer match current patterns. If skillTargetDir is absent, embed a ## Recurring Procedures section in each targetFile instead, listing each procedure with trigger context and steps.\n4. Store a kind='summary' observation briefly describing what was synthesized (e.g. \"Synthesized 8 observations: updated kirograph-watchmen.md, wrote watchmen-auth-flow.md and watchmen-test-pattern.md\").`;\n\n return {\n id: 'kirograph-watchmen',\n description: 'After memory capture, check if enough observations have accumulated. If so, synthesize them into workspace brief files.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Watchmen',\n trigger: 'Stop',\n action: { type: 'agent', prompt: watchmenPrompt },\n }],\n },\n v1: {\n name: 'KiroGraph Watchmen',\n version: '1.0.0',\n description: 'After memory capture, check if enough observations have accumulated. If so, synthesize them into workspace brief files.',\n when: { type: 'agentStop' },\n then: { type: 'askAgent', prompt: watchmenPrompt },\n },\n };\n}\n\nconst HOOKS: HookDef[] = [\n {\n id: 'kirograph-sync-if-dirty',\n description: 'Sync the KiroGraph index when the agent stops, picking up any file edits, creates, or deletes from the session.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Sync on Agent Stop',\n trigger: 'Stop',\n action: { type: 'command', command: 'kirograph sync --quiet 2>&1 > /dev/null' },\n }],\n },\n v1: {\n name: 'KiroGraph Sync on Agent Stop',\n version: '1.0.0',\n description: 'Sync the KiroGraph index when the agent stops, picking up any file edits, creates, or deletes from the session.',\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: 'kirograph sync --quiet 2>&1 > /dev/null' },\n },\n },\n {\n id: 'kirograph-compress-hint',\n description: 'Remind the agent to use kirograph_exec for shell commands that benefit from token compression.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Compression Hint',\n trigger: 'PreToolUse',\n matcher: 'execute_bash',\n action: {\n type: 'agent',\n prompt: 'If this shell command is a git operation, GitHub CLI, test runner, linter, build tool, file listing, grep/rg, docker/kubectl, AWS CLI, or package manager command, consider using the kirograph_exec MCP tool instead for 60-90% token savings. The tool compresses output automatically while preserving error details.',\n },\n }],\n },\n v1: {\n name: 'KiroGraph Compression Hint',\n version: '1.0.0',\n description: 'Remind the agent to use kirograph_exec for shell commands that benefit from token compression.',\n when: { type: 'preToolUse', toolTypes: ['shell'] },\n then: {\n type: 'askAgent',\n prompt: 'If this shell command is a git operation, GitHub CLI, test runner, linter, build tool, file listing, grep/rg, docker/kubectl, AWS CLI, or package manager command, consider using the kirograph_exec MCP tool instead for 60-90% token savings. The tool compresses output automatically while preserving error details.',\n },\n },\n },\n {\n id: 'kirograph-mem-capture',\n description: 'Prompt the agent to store important observations in memory at the end of each session.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Memory Capture',\n trigger: 'Stop',\n action: {\n type: 'agent',\n prompt: 'Before ending, review what happened in this session. If there were any important decisions, bug root causes, architecture insights, error patterns, or lessons learned, store them using kirograph_mem_store with the appropriate kind (decision, error, pattern, architecture, note). Keep observations concise \u2014 one fact per observation. Skip if nothing noteworthy happened.',\n },\n }],\n },\n v1: {\n name: 'KiroGraph Memory Capture',\n version: '1.0.0',\n description: 'Prompt the agent to store important observations in memory at the end of each session.',\n when: { type: 'agentStop' },\n then: {\n type: 'askAgent',\n prompt: 'Before ending, review what happened in this session. If there were any important decisions, bug root causes, architecture insights, error patterns, or lessons learned, store them using kirograph_mem_store with the appropriate kind (decision, error, pattern, architecture, note). Keep observations concise \u2014 one fact per observation. Skip if nothing noteworthy happened.',\n },\n },\n },\n];\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction ensureDir(p: string): void {\n fs.mkdirSync(p, { recursive: true });\n}\n\nfunction writeJson(p: string, data: unknown): void {\n fs.writeFileSync(p, JSON.stringify(data, null, 2) + '\\n');\n}\n\n/** Write a hook in both v2 (.json) and v1 (.kiro.hook) formats */\nfunction writeHookDual(hooksDir: string, def: HookDef): void {\n writeJson(path.join(hooksDir, `${def.id}${V2_EXT}`), def.v2);\n writeJson(path.join(hooksDir, `${def.id}${V1_EXT}`), def.v1);\n}\n\n/** Write a hook in the specified format only, removing the other */\nfunction writeHookForFormat(hooksDir: string, def: HookDef, format: KiroHookFormat): void {\n if (format === 'v2') {\n writeJson(path.join(hooksDir, `${def.id}${V2_EXT}`), def.v2);\n // Remove legacy file if it exists\n const legacyPath = path.join(hooksDir, `${def.id}${V1_EXT}`);\n if (fs.existsSync(legacyPath)) fs.unlinkSync(legacyPath);\n } else {\n writeJson(path.join(hooksDir, `${def.id}${V1_EXT}`), def.v1);\n // Remove v2 file if it exists\n const v2Path = path.join(hooksDir, `${def.id}${V2_EXT}`);\n if (fs.existsSync(v2Path)) fs.unlinkSync(v2Path);\n }\n}\n\n/** Remove both format files for a given hook id */\nfunction removeHookDual(hooksDir: string, id: string): void {\n for (const ext of [V2_EXT, V1_EXT]) {\n const p = path.join(hooksDir, `${id}${ext}`);\n if (fs.existsSync(p)) fs.unlinkSync(p);\n }\n}\n\n// \u2500\u2500 Public \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type KiroHookFormat = 'v1-legacy' | 'v2';\n\nexport function writeHooks(kiroDir: string, opts?: { enableCompression?: boolean; enableMemory?: boolean; enableWatchmen?: boolean; watchmenSynthesisMode?: 'local' | 'agent'; enableWiki?: boolean; wikiSynthesisMode?: 'local' | 'agent'; wikiLintFrequency?: number; kiroHookFormat?: KiroHookFormat }): void {\n const hooksDir = path.join(kiroDir, 'hooks');\n ensureDir(hooksDir);\n\n const format = opts?.kiroHookFormat ?? 'v2';\n\n // Remove obsolete hook files from earlier versions\n const obsoleteFiles = [\n 'kirograph-sync-on-save.json', 'kirograph-sync-on-create.json',\n 'kirograph-mark-dirty-on-save.json', 'kirograph-mark-dirty-on-create.json',\n 'kirograph-sync-on-delete.json',\n 'kirograph-mark-dirty-on-save.kiro.hook',\n 'kirograph-mark-dirty-on-create.kiro.hook',\n 'kirograph-sync-on-delete.kiro.hook',\n ];\n for (const old of obsoleteFiles) {\n const p = path.join(hooksDir, old);\n if (fs.existsSync(p)) fs.unlinkSync(p);\n }\n\n for (const def of HOOKS) {\n // Skip compression hook if compression is disabled\n if (def.id === 'kirograph-compress-hint' && opts?.enableCompression === false) {\n removeHookDual(hooksDir, def.id);\n continue;\n }\n // Skip memory hook if memory is disabled\n if (def.id === 'kirograph-mem-capture' && !opts?.enableMemory) {\n removeHookDual(hooksDir, def.id);\n continue;\n }\n writeHookForFormat(hooksDir, def, format);\n }\n\n // Watchmen hook \u2014 built dynamically based on synthesis mode\n if (opts?.enableWatchmen) {\n const mode = opts.watchmenSynthesisMode ?? 'local';\n writeHookForFormat(hooksDir, buildWatchmenHook(mode), format);\n } else {\n removeHookDual(hooksDir, 'kirograph-watchmen');\n }\n\n // Wiki hooks \u2014 ingest trigger + periodic lint\n if (opts?.enableWiki) {\n const lintFreq = opts.wikiLintFrequency ?? 10;\n const wikiMode = opts.wikiSynthesisMode ?? 'agent';\n\n const wikiIngestPrompt = `If this session produced durable knowledge (design decisions, architecture insights, API contracts, process steps, domain facts), consider updating the wiki:\n1. Call kirograph_wiki_ingest with the key findings as source text.\n2. The tool returns a structured prompt. Pass it to yourself to generate a WIKI_DIFF.\n3. Call kirograph_wiki_apply_diff with your generated diff.\nSkip if the session was trivial (simple bug fix, no new knowledge).`;\n\n if (wikiMode === 'local') {\n writeHookForFormat(hooksDir, {\n id: 'kirograph-wiki-ingest',\n description: 'After each session, run local-model wiki synthesis over queued sources.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Wiki Synthesize',\n trigger: 'Stop',\n action: { type: 'command', command: 'kirograph wiki synthesize --quiet 2>&1 || true' },\n }],\n },\n v1: {\n name: 'KiroGraph Wiki Synthesize',\n version: '1.0.0',\n description: 'After each session, run local-model wiki synthesis over queued sources.',\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: 'kirograph wiki synthesize --quiet 2>&1 || true' },\n },\n }, format);\n } else {\n writeHookForFormat(hooksDir, {\n id: 'kirograph-wiki-ingest',\n description: 'At the end of each session, prompt the agent to ingest any relevant knowledge into the wiki.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Wiki Ingest',\n trigger: 'Stop',\n action: { type: 'agent', prompt: wikiIngestPrompt },\n }],\n },\n v1: {\n name: 'KiroGraph Wiki Ingest',\n version: '1.0.0',\n description: 'At the end of each session, prompt the agent to ingest any relevant knowledge into the wiki.',\n when: { type: 'agentStop' },\n then: { type: 'askAgent', prompt: wikiIngestPrompt },\n },\n }, format);\n }\n\n writeHookForFormat(hooksDir, {\n id: 'kirograph-wiki-lint',\n description: `Run wiki health check every ${lintFreq} sessions to catch broken links, orphan pages, and contradictions.`,\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Wiki Lint',\n trigger: 'Stop',\n action: { type: 'command', command: 'kirograph wiki lint 2>&1 || true' },\n }],\n },\n v1: {\n name: 'KiroGraph Wiki Lint',\n version: '1.0.0',\n description: `Run wiki health check every ${lintFreq} sessions to catch broken links, orphan pages, and contradictions.`,\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: 'kirograph wiki lint 2>&1 || true' },\n },\n }, format);\n } else {\n removeHookDual(hooksDir, 'kirograph-wiki-ingest');\n removeHookDual(hooksDir, 'kirograph-wiki-lint');\n }\n\n console.log(` \u2713 Auto-sync hooks written to ${hooksDir}`);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,SAAoB;AACpB,WAAsB;
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph Installer \u2014 Kiro hook file management\n *\n * Generates hooks in BOTH formats for compatibility:\n *\n * v2 (new Kiro IDE): `.kiro/hooks/<id>.json`\n * { \"version\": \"v1\", \"hooks\": [{ \"name\", \"trigger\", \"matcher?\", \"action\": { type, command|prompt } }] }\n *\n * v1 (legacy Kiro IDE): `.kiro/hooks/<id>.kiro.hook`\n * { \"name\", \"version\", \"description\", \"when\": { type, toolTypes? }, \"then\": { type, command|prompt } }\n *\n * Old Kiro ignores .json files; new Kiro ignores .kiro.hook files.\n * Writing both ensures KiroGraph works regardless of which IDE version the user runs.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { silentCommand } from './common';\n\n// \u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst V2_EXT = '.json';\nconst V1_EXT = '.kiro.hook';\n\n// Cross-platform hook commands (see issue #40 \u2014 bash syntax breaks on Windows cmd.exe).\nconst SYNC_CMD = silentCommand('kirograph sync --quiet');\nconst WATCHMEN_SYNTH_CMD = silentCommand('kirograph mem watchmen synthesize --quiet');\nconst WIKI_SYNTH_CMD = silentCommand('kirograph wiki synthesize --quiet');\nconst WIKI_LINT_CMD = silentCommand('kirograph wiki lint');\n\n// \u2500\u2500 Hook builders \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface HookDef {\n id: string;\n description: string;\n v2: object; // new Kiro IDE format\n v1: object; // legacy Kiro IDE format\n}\n\nfunction buildWatchmenHook(synthesisMode: 'local' | 'agent'): HookDef {\n if (synthesisMode === 'local') {\n return {\n id: 'kirograph-watchmen',\n description: 'After memory capture, run local model synthesis if enough observations have accumulated.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Watchmen',\n trigger: 'Stop',\n action: { type: 'command', command: WATCHMEN_SYNTH_CMD },\n }],\n },\n v1: {\n name: 'KiroGraph Watchmen',\n version: '1.0.0',\n description: 'After memory capture, run local model synthesis if enough observations have accumulated.',\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: WATCHMEN_SYNTH_CMD },\n },\n };\n }\n\n const watchmenPrompt = `Check if KiroGraph Watchmen synthesis should run: call kirograph_mem_store with kind='note' and content='watchmen check'. If the response does not include watchmenReady: true, do nothing and stop.\n\nIf watchmenReady: true:\n1. Call kirograph_mem_search for each kind (decision, error, pattern, architecture, note) with limit 20.\n2. Write or update the workspace brief: upsert the ## KiroGraph Watchmen section in each file listed in targetFiles. For .kiro/steering/kirograph-watchmen.md use inclusion: always frontmatter with sections for Decisions, Known Errors & Fixes, Recurring Patterns, and Architecture Notes. For all other files write a compact ## KiroGraph Watchmen block.\n3. Generate skill files: if skillTargetDir is present in the response, identify recurring procedures (any procedure appearing in 3+ observations). For each, write a .kiro/steering/watchmen-<slug>.md file with inclusion: manual frontmatter, a short title, a \"When to use\" line with trigger phrases, and numbered steps. Prefix all generated files with watchmen- so they are distinguishable from hand-written steering files. Remove any .kiro/steering/watchmen-*.md files from previous runs that no longer match current patterns. If skillTargetDir is absent, embed a ## Recurring Procedures section in each targetFile instead, listing each procedure with trigger context and steps.\n4. Store a kind='summary' observation briefly describing what was synthesized (e.g. \"Synthesized 8 observations: updated kirograph-watchmen.md, wrote watchmen-auth-flow.md and watchmen-test-pattern.md\").`;\n\n return {\n id: 'kirograph-watchmen',\n description: 'After memory capture, check if enough observations have accumulated. If so, synthesize them into workspace brief files.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Watchmen',\n trigger: 'Stop',\n action: { type: 'agent', prompt: watchmenPrompt },\n }],\n },\n v1: {\n name: 'KiroGraph Watchmen',\n version: '1.0.0',\n description: 'After memory capture, check if enough observations have accumulated. If so, synthesize them into workspace brief files.',\n when: { type: 'agentStop' },\n then: { type: 'askAgent', prompt: watchmenPrompt },\n },\n };\n}\n\nconst HOOKS: HookDef[] = [\n {\n id: 'kirograph-sync-if-dirty',\n description: 'Sync the KiroGraph index when the agent stops, picking up any file edits, creates, or deletes from the session.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Sync on Agent Stop',\n trigger: 'Stop',\n action: { type: 'command', command: SYNC_CMD },\n }],\n },\n v1: {\n name: 'KiroGraph Sync on Agent Stop',\n version: '1.0.0',\n description: 'Sync the KiroGraph index when the agent stops, picking up any file edits, creates, or deletes from the session.',\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: SYNC_CMD },\n },\n },\n {\n id: 'kirograph-compress-hint',\n description: 'Remind the agent to use kirograph_exec for shell commands that benefit from token compression.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Compression Hint',\n trigger: 'PreToolUse',\n matcher: 'execute_bash',\n action: {\n type: 'agent',\n prompt: 'If this shell command is a git operation, GitHub CLI, test runner, linter, build tool, file listing, grep/rg, docker/kubectl, AWS CLI, or package manager command, consider using the kirograph_exec MCP tool instead for 60-90% token savings. The tool compresses output automatically while preserving error details.',\n },\n }],\n },\n v1: {\n name: 'KiroGraph Compression Hint',\n version: '1.0.0',\n description: 'Remind the agent to use kirograph_exec for shell commands that benefit from token compression.',\n when: { type: 'preToolUse', toolTypes: ['shell'] },\n then: {\n type: 'askAgent',\n prompt: 'If this shell command is a git operation, GitHub CLI, test runner, linter, build tool, file listing, grep/rg, docker/kubectl, AWS CLI, or package manager command, consider using the kirograph_exec MCP tool instead for 60-90% token savings. The tool compresses output automatically while preserving error details.',\n },\n },\n },\n {\n id: 'kirograph-mem-capture',\n description: 'Prompt the agent to store important observations in memory at the end of each session.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Memory Capture',\n trigger: 'Stop',\n action: {\n type: 'agent',\n prompt: 'Before ending, review what happened in this session. If there were any important decisions, bug root causes, architecture insights, error patterns, or lessons learned, store them using kirograph_mem_store with the appropriate kind (decision, error, pattern, architecture, note). Keep observations concise \u2014 one fact per observation. Skip if nothing noteworthy happened.',\n },\n }],\n },\n v1: {\n name: 'KiroGraph Memory Capture',\n version: '1.0.0',\n description: 'Prompt the agent to store important observations in memory at the end of each session.',\n when: { type: 'agentStop' },\n then: {\n type: 'askAgent',\n prompt: 'Before ending, review what happened in this session. If there were any important decisions, bug root causes, architecture insights, error patterns, or lessons learned, store them using kirograph_mem_store with the appropriate kind (decision, error, pattern, architecture, note). Keep observations concise \u2014 one fact per observation. Skip if nothing noteworthy happened.',\n },\n },\n },\n];\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction ensureDir(p: string): void {\n fs.mkdirSync(p, { recursive: true });\n}\n\nfunction writeJson(p: string, data: unknown): void {\n fs.writeFileSync(p, JSON.stringify(data, null, 2) + '\\n');\n}\n\n/** Write a hook in both v2 (.json) and v1 (.kiro.hook) formats */\nfunction writeHookDual(hooksDir: string, def: HookDef): void {\n writeJson(path.join(hooksDir, `${def.id}${V2_EXT}`), def.v2);\n writeJson(path.join(hooksDir, `${def.id}${V1_EXT}`), def.v1);\n}\n\n/** Write a hook in the specified format only, removing the other */\nfunction writeHookForFormat(hooksDir: string, def: HookDef, format: KiroHookFormat): void {\n if (format === 'v2') {\n writeJson(path.join(hooksDir, `${def.id}${V2_EXT}`), def.v2);\n // Remove legacy file if it exists\n const legacyPath = path.join(hooksDir, `${def.id}${V1_EXT}`);\n if (fs.existsSync(legacyPath)) fs.unlinkSync(legacyPath);\n } else {\n writeJson(path.join(hooksDir, `${def.id}${V1_EXT}`), def.v1);\n // Remove v2 file if it exists\n const v2Path = path.join(hooksDir, `${def.id}${V2_EXT}`);\n if (fs.existsSync(v2Path)) fs.unlinkSync(v2Path);\n }\n}\n\n/** Remove both format files for a given hook id */\nfunction removeHookDual(hooksDir: string, id: string): void {\n for (const ext of [V2_EXT, V1_EXT]) {\n const p = path.join(hooksDir, `${id}${ext}`);\n if (fs.existsSync(p)) fs.unlinkSync(p);\n }\n}\n\n// \u2500\u2500 Public \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type KiroHookFormat = 'v1-legacy' | 'v2';\n\nexport function writeHooks(kiroDir: string, opts?: { enableCompression?: boolean; enableMemory?: boolean; enableWatchmen?: boolean; watchmenSynthesisMode?: 'local' | 'agent'; enableWiki?: boolean; wikiSynthesisMode?: 'local' | 'agent'; wikiLintFrequency?: number; kiroHookFormat?: KiroHookFormat }): void {\n const hooksDir = path.join(kiroDir, 'hooks');\n ensureDir(hooksDir);\n\n const format = opts?.kiroHookFormat ?? 'v2';\n\n // Remove obsolete hook files from earlier versions\n const obsoleteFiles = [\n 'kirograph-sync-on-save.json', 'kirograph-sync-on-create.json',\n 'kirograph-mark-dirty-on-save.json', 'kirograph-mark-dirty-on-create.json',\n 'kirograph-sync-on-delete.json',\n 'kirograph-mark-dirty-on-save.kiro.hook',\n 'kirograph-mark-dirty-on-create.kiro.hook',\n 'kirograph-sync-on-delete.kiro.hook',\n ];\n for (const old of obsoleteFiles) {\n const p = path.join(hooksDir, old);\n if (fs.existsSync(p)) fs.unlinkSync(p);\n }\n\n for (const def of HOOKS) {\n // Skip compression hook if compression is disabled\n if (def.id === 'kirograph-compress-hint' && opts?.enableCompression === false) {\n removeHookDual(hooksDir, def.id);\n continue;\n }\n // Skip memory hook if memory is disabled\n if (def.id === 'kirograph-mem-capture' && !opts?.enableMemory) {\n removeHookDual(hooksDir, def.id);\n continue;\n }\n writeHookForFormat(hooksDir, def, format);\n }\n\n // Watchmen hook \u2014 built dynamically based on synthesis mode\n if (opts?.enableWatchmen) {\n const mode = opts.watchmenSynthesisMode ?? 'local';\n writeHookForFormat(hooksDir, buildWatchmenHook(mode), format);\n } else {\n removeHookDual(hooksDir, 'kirograph-watchmen');\n }\n\n // Wiki hooks \u2014 ingest trigger + periodic lint\n if (opts?.enableWiki) {\n const lintFreq = opts.wikiLintFrequency ?? 10;\n const wikiMode = opts.wikiSynthesisMode ?? 'agent';\n\n const wikiIngestPrompt = `If this session produced durable knowledge (design decisions, architecture insights, API contracts, process steps, domain facts), consider updating the wiki:\n1. Call kirograph_wiki_ingest with the key findings as source text.\n2. The tool returns a structured prompt. Pass it to yourself to generate a WIKI_DIFF.\n3. Call kirograph_wiki_apply_diff with your generated diff.\nSkip if the session was trivial (simple bug fix, no new knowledge).`;\n\n if (wikiMode === 'local') {\n writeHookForFormat(hooksDir, {\n id: 'kirograph-wiki-ingest',\n description: 'After each session, run local-model wiki synthesis over queued sources.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Wiki Synthesize',\n trigger: 'Stop',\n action: { type: 'command', command: WIKI_SYNTH_CMD },\n }],\n },\n v1: {\n name: 'KiroGraph Wiki Synthesize',\n version: '1.0.0',\n description: 'After each session, run local-model wiki synthesis over queued sources.',\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: WIKI_SYNTH_CMD },\n },\n }, format);\n } else {\n writeHookForFormat(hooksDir, {\n id: 'kirograph-wiki-ingest',\n description: 'At the end of each session, prompt the agent to ingest any relevant knowledge into the wiki.',\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Wiki Ingest',\n trigger: 'Stop',\n action: { type: 'agent', prompt: wikiIngestPrompt },\n }],\n },\n v1: {\n name: 'KiroGraph Wiki Ingest',\n version: '1.0.0',\n description: 'At the end of each session, prompt the agent to ingest any relevant knowledge into the wiki.',\n when: { type: 'agentStop' },\n then: { type: 'askAgent', prompt: wikiIngestPrompt },\n },\n }, format);\n }\n\n writeHookForFormat(hooksDir, {\n id: 'kirograph-wiki-lint',\n description: `Run wiki health check every ${lintFreq} sessions to catch broken links, orphan pages, and contradictions.`,\n v2: {\n version: 'v1',\n hooks: [{\n name: 'KiroGraph Wiki Lint',\n trigger: 'Stop',\n action: { type: 'command', command: WIKI_LINT_CMD },\n }],\n },\n v1: {\n name: 'KiroGraph Wiki Lint',\n version: '1.0.0',\n description: `Run wiki health check every ${lintFreq} sessions to catch broken links, orphan pages, and contradictions.`,\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: WIKI_LINT_CMD },\n },\n }, format);\n } else {\n removeHookDual(hooksDir, 'kirograph-wiki-ingest');\n removeHookDual(hooksDir, 'kirograph-wiki-lint');\n }\n\n console.log(` \u2713 Auto-sync hooks written to ${hooksDir}`);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1471,9 +1471,14 @@ kirograph wiki search "<query>"
|
|
|
1471
1471
|
kirograph wiki page <slug>
|
|
1472
1472
|
kirograph wiki list
|
|
1473
1473
|
kirograph wiki lint
|
|
1474
|
+
kirograph wiki links <slug> # outgoing/broken/incoming [[slug]] links for a page
|
|
1475
|
+
kirograph wiki rename <from> <to> # move a page + rewrite every [[from]] reference to [[to]]
|
|
1474
1476
|
kirograph wiki status
|
|
1475
1477
|
kirograph wiki reindex
|
|
1476
1478
|
\`\`\`
|
|
1479
|
+
|
|
1480
|
+
Use \`wiki links\` before a \`rename\` to see what else references the page \u2014 \`rename\` rewrites
|
|
1481
|
+
those references automatically, but it's still a file move, not an MCP tool call.
|
|
1477
1482
|
`);
|
|
1478
1483
|
console.log(` \u2713 Wiki workflow steering file written`);
|
|
1479
1484
|
}
|
|
@@ -1513,6 +1518,10 @@ kirograph_mem_store(
|
|
|
1513
1518
|
|
|
1514
1519
|
**topicKey examples:** \`"architecture/auth-model"\`, \`"infra/db-choice"\`, \`"pattern/error-handling"\`
|
|
1515
1520
|
|
|
1521
|
+
Always use a \`kind\` from the list above. If \`memoryStrictWrites: true\` is set, an unrecognized
|
|
1522
|
+
\`kind\` or a blank tag is rejected with the violation named \u2014 fix the call and retry, it isn't
|
|
1523
|
+
silently dropped.
|
|
1524
|
+
|
|
1516
1525
|
## 3. Capture observations from structured text
|
|
1517
1526
|
|
|
1518
1527
|
If you have a markdown block with bullet points under headings like \`## Key Learnings\` or
|