@orquentra/codebuddy 2.6.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CLAUDE_CODEX.md +6 -4
  2. package/WORKFLOW.md +5 -5
  3. package/dist/{chunk-U4HAJLIB.js → chunk-3QGW53GD.js} +16 -3
  4. package/dist/chunk-3QGW53GD.js.map +1 -0
  5. package/dist/{chunk-L5AYZC3F.js → chunk-5EDGAZQN.js} +438 -68
  6. package/dist/chunk-5EDGAZQN.js.map +1 -0
  7. package/dist/chunk-5UH3BEQR.js +32 -0
  8. package/dist/chunk-5UH3BEQR.js.map +1 -0
  9. package/dist/{chunk-JFDRBPYF.js → chunk-6JCKMIQY.js} +2 -2
  10. package/dist/{chunk-UN57FKQX.js → chunk-AK2UAE32.js} +152 -862
  11. package/dist/chunk-AK2UAE32.js.map +1 -0
  12. package/dist/{chunk-GDJH7XJC.js → chunk-AL6VBTNA.js} +77 -3
  13. package/dist/chunk-AL6VBTNA.js.map +1 -0
  14. package/dist/{chunk-WHZSVY2L.js → chunk-AQHPEJR6.js} +94 -23
  15. package/dist/chunk-AQHPEJR6.js.map +1 -0
  16. package/dist/{chunk-PCE4STAY.js → chunk-BQM7FJ7D.js} +6 -6
  17. package/dist/chunk-BQM7FJ7D.js.map +1 -0
  18. package/dist/{chunk-XBJQKCLU.js → chunk-CAEPHLHC.js} +13 -9
  19. package/dist/chunk-CAEPHLHC.js.map +1 -0
  20. package/dist/chunk-CG5B3LYG.js +66 -0
  21. package/dist/chunk-CG5B3LYG.js.map +1 -0
  22. package/dist/chunk-CSRD5OQA.js +79 -0
  23. package/dist/chunk-CSRD5OQA.js.map +1 -0
  24. package/dist/{chunk-IHQM2ZDV.js → chunk-DFV2SK6C.js} +1 -1
  25. package/dist/{chunk-IHQM2ZDV.js.map → chunk-DFV2SK6C.js.map} +1 -1
  26. package/dist/chunk-EEUFU7KV.js +1634 -0
  27. package/dist/chunk-EEUFU7KV.js.map +1 -0
  28. package/dist/{chunk-UFZD3JAA.js → chunk-ESZXCZIN.js} +3 -3
  29. package/dist/{chunk-PYLH4MH5.js → chunk-FJOTP632.js} +1 -1
  30. package/dist/{chunk-SYWJG5NA.js → chunk-GKNYMNFM.js} +17 -7
  31. package/dist/{chunk-SYWJG5NA.js.map → chunk-GKNYMNFM.js.map} +1 -1
  32. package/dist/{chunk-JPHJBCZB.js → chunk-HPOR6YXA.js} +3 -2
  33. package/dist/chunk-HPOR6YXA.js.map +1 -0
  34. package/dist/chunk-JUAFCLRB.js +1014 -0
  35. package/dist/chunk-JUAFCLRB.js.map +1 -0
  36. package/dist/{chunk-776EQXDV.js → chunk-KNR2P2UY.js} +110 -83
  37. package/dist/chunk-KNR2P2UY.js.map +1 -0
  38. package/dist/{chunk-N34XHWBA.js → chunk-LCSBL5TT.js} +24 -11
  39. package/dist/chunk-LCSBL5TT.js.map +1 -0
  40. package/dist/{chunk-QDBDYCM2.js → chunk-MSUAVR3R.js} +76 -11
  41. package/dist/chunk-MSUAVR3R.js.map +1 -0
  42. package/dist/{chunk-6MKEIDX5.js → chunk-SFMIMLXR.js} +2 -2
  43. package/dist/chunk-TGFTKWOR.js +16 -0
  44. package/dist/chunk-TGFTKWOR.js.map +1 -0
  45. package/dist/chunk-TUR6YKEE.js +55 -0
  46. package/dist/chunk-TUR6YKEE.js.map +1 -0
  47. package/dist/chunk-Y7D7PUBE.js +321 -0
  48. package/dist/chunk-Y7D7PUBE.js.map +1 -0
  49. package/dist/{chunk-VAKBJV26.js → chunk-YJIA2MFL.js} +918 -2238
  50. package/dist/chunk-YJIA2MFL.js.map +1 -0
  51. package/dist/cli/index.js +14 -3
  52. package/dist/cli/index.js.map +1 -1
  53. package/dist/{cloud-7WM3YLI4.js → cloud-LXZUR3U2.js} +3 -3
  54. package/dist/{codebuddy-DM-i0Fu5.d.ts → codebuddy-DO7ZhoWn.d.ts} +37 -3
  55. package/dist/config-GEZFLXK6.js +12 -0
  56. package/dist/docker-autostart-KDME7TVC.js +12 -0
  57. package/dist/index.d.ts +48 -3
  58. package/dist/index.js +32 -25
  59. package/dist/langgraph/index.d.ts +1 -1
  60. package/dist/lean-command-CWJAVQ5G.js +18 -0
  61. package/dist/local-ST4WMRCG.js +17 -0
  62. package/dist/{main-HFHLGID4.js → main-AHNGHC4L.js} +327 -329
  63. package/dist/main-AHNGHC4L.js.map +1 -0
  64. package/dist/{memory-4RGVLPKG.js → memory-TGHVTBME.js} +9 -8
  65. package/dist/memory-TGHVTBME.js.map +1 -0
  66. package/dist/operations-7BTAAUHF.js +26 -0
  67. package/dist/postgres-docker-QQZQ2ABK.js +16 -0
  68. package/dist/pretool-command-3SXQSMAO.js +13 -0
  69. package/dist/{rerank-3P3C2UHN.js → rerank-IQAEWLQR.js} +6 -5
  70. package/dist/rerank-IQAEWLQR.js.map +1 -0
  71. package/dist/runtime-E7JQZ2BZ.js +46 -0
  72. package/dist/runtime-E7JQZ2BZ.js.map +1 -0
  73. package/dist/stdio-HOV4P3DQ.js +12 -0
  74. package/dist/stdio-HOV4P3DQ.js.map +1 -0
  75. package/dist/summaries-XV3JGGCC.js +20 -0
  76. package/dist/summaries-XV3JGGCC.js.map +1 -0
  77. package/dist/{zvec-MAPSJQSR.js → zvec-KP4KNB7Y.js} +10 -3
  78. package/dist/zvec-KP4KNB7Y.js.map +1 -0
  79. package/package.json +7 -10
  80. package/src/db/migrations/0006_fact_idempotency_key.sql +2 -0
  81. package/src/db/migrations/meta/0006_snapshot.json +1258 -0
  82. package/src/db/migrations/meta/_journal.json +7 -0
  83. package/dist/chunk-776EQXDV.js.map +0 -1
  84. package/dist/chunk-GDJH7XJC.js.map +0 -1
  85. package/dist/chunk-JPHJBCZB.js.map +0 -1
  86. package/dist/chunk-L5AYZC3F.js.map +0 -1
  87. package/dist/chunk-N34XHWBA.js.map +0 -1
  88. package/dist/chunk-PCE4STAY.js.map +0 -1
  89. package/dist/chunk-PQK3GKZH.js +0 -98
  90. package/dist/chunk-PQK3GKZH.js.map +0 -1
  91. package/dist/chunk-QDBDYCM2.js.map +0 -1
  92. package/dist/chunk-U4HAJLIB.js.map +0 -1
  93. package/dist/chunk-UN57FKQX.js.map +0 -1
  94. package/dist/chunk-VAKBJV26.js.map +0 -1
  95. package/dist/chunk-WHZSVY2L.js.map +0 -1
  96. package/dist/chunk-XBJQKCLU.js.map +0 -1
  97. package/dist/config-KFEHLV6W.js +0 -11
  98. package/dist/lean-command-C5YPFKHP.js +0 -15
  99. package/dist/local-OTOY56B4.js +0 -13
  100. package/dist/main-HFHLGID4.js.map +0 -1
  101. package/dist/memory-4RGVLPKG.js.map +0 -1
  102. package/dist/operations-LOBAQRLO.js +0 -24
  103. package/dist/pretool-command-MQQ2UNQM.js +0 -10
  104. package/dist/rerank-3P3C2UHN.js.map +0 -1
  105. package/dist/summaries-ZBV5IN7Y.js +0 -18
  106. /package/dist/{chunk-JFDRBPYF.js.map → chunk-6JCKMIQY.js.map} +0 -0
  107. /package/dist/{chunk-UFZD3JAA.js.map → chunk-ESZXCZIN.js.map} +0 -0
  108. /package/dist/{chunk-PYLH4MH5.js.map → chunk-FJOTP632.js.map} +0 -0
  109. /package/dist/{chunk-6MKEIDX5.js.map → chunk-SFMIMLXR.js.map} +0 -0
  110. /package/dist/{cloud-7WM3YLI4.js.map → cloud-LXZUR3U2.js.map} +0 -0
  111. /package/dist/{config-KFEHLV6W.js.map → config-GEZFLXK6.js.map} +0 -0
  112. /package/dist/{lean-command-C5YPFKHP.js.map → docker-autostart-KDME7TVC.js.map} +0 -0
  113. /package/dist/{local-OTOY56B4.js.map → lean-command-CWJAVQ5G.js.map} +0 -0
  114. /package/dist/{operations-LOBAQRLO.js.map → local-ST4WMRCG.js.map} +0 -0
  115. /package/dist/{pretool-command-MQQ2UNQM.js.map → operations-7BTAAUHF.js.map} +0 -0
  116. /package/dist/{summaries-ZBV5IN7Y.js.map → postgres-docker-QQZQ2ABK.js.map} +0 -0
  117. /package/dist/{zvec-MAPSJQSR.js.map → pretool-command-3SXQSMAO.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/pretool.ts","../src/hooks/pretool-command.ts"],"sourcesContent":["import { open, stat } from \"node:fs/promises\";\nimport { extname, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport { extractSymbolTable, supportsSymbols } from \"../indexer/symbols.js\";\nimport type { HookInput } from \"./runtime.js\";\n\n/**\n * PreToolUse tool guard (Claude Code): cut tool output that would otherwise\n * stay in context for the rest of the session, without touching permissions.\n *\n * - Read of a large file with no range → denied with an outline (symbols or\n * headings with line ranges) and how to read a range or the whole file.\n * The model sees the deny reason; any Read with offset/limit passes.\n * - Grep in content mode with no head_limit → the same input plus a limit.\n *\n * Never emits `permissionDecision: \"allow\"`: Claude Code checks permissions on\n * the (possibly rewritten) input as usual. Verified on Claude Code 2.1.287.\n */\n/**\n * Only files whose full read is clearly expensive: below this, an agent that\n * re-reads the whole file after the outline (observed live) costs a turn for\n * nothing.\n */\nexport const TOOL_GUARD = {\n readLines: 1_000,\n readBytes: 80_000,\n /** Symbols shorter than this are noise in an outline (one-line constants). */\n outlineMinSymbolLines: 3,\n /** Fewer top-level symbols than this: list class methods too. */\n minTopLevelEntries: 10,\n outlineEntries: 40,\n blockLines: 100,\n grepHeadLimit: 100,\n} as const;\n\n/** Read renders these itself (images, PDFs, notebooks); never guard them. */\nconst SPECIAL_READ = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".bmp\",\n \".svg\",\n \".pdf\",\n \".ipynb\",\n]);\nconst MAX_GUARD_BYTES = 2_000_000;\n\nexport type PreToolDecision = {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\";\n permissionDecision?: \"deny\";\n permissionDecisionReason?: string;\n updatedInput?: Record<string, unknown>;\n };\n} | null;\n\nexport async function decidePreTool(\n input: HookInput,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<PreToolDecision> {\n if (env.CODEBUDDY_TOOL_GUARD === \"0\") return null;\n const toolInput = input.tool_input ?? {};\n if (input.tool_name === \"Grep\") return capGrep(toolInput);\n if (input.tool_name === \"Read\") return guardRead(resolve(input.cwd ?? process.cwd()), toolInput);\n return null;\n}\n\nfunction capGrep(toolInput: Record<string, unknown>): PreToolDecision {\n if (toolInput.output_mode !== \"content\" || toolInput.head_limit !== undefined) return null;\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n updatedInput: { ...toolInput, head_limit: TOOL_GUARD.grepHeadLimit },\n },\n };\n}\n\nasync function guardRead(\n root: string,\n toolInput: Record<string, unknown>,\n): Promise<PreToolDecision> {\n if (toolInput.offset !== undefined || toolInput.limit !== undefined) return null;\n const filePath = toolInput.file_path;\n if (typeof filePath !== \"string\" || !filePath) return null;\n const absolute = isAbsolute(filePath) ? resolve(filePath) : resolve(root, filePath);\n const rel = relative(root, absolute);\n if (rel === \"\" || rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) return null;\n if (SPECIAL_READ.has(extname(absolute).toLowerCase())) return null;\n let size: number;\n try {\n const info = await stat(absolute);\n if (!info.isFile()) return null;\n size = info.size;\n } catch {\n return null;\n }\n if (size > MAX_GUARD_BYTES) return null; // Read refuses huge files itself.\n const text = await readText(absolute);\n if (text === null) return null;\n const lines = text.split(/\\r?\\n/);\n if (lines.at(-1) === \"\") lines.pop();\n if (lines.length <= TOOL_GUARD.readLines && size <= TOOL_GUARD.readBytes) return null;\n\n const path = rel.replace(/\\\\/g, \"/\");\n const outline = outlineOf(path, text, lines);\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: [\n `CodeBuddy read guard: ${path} is ${lines.length} lines (~${Math.ceil(size / 4)} tokens), too large to read whole.`,\n `Outline: ${outline.join(\"; \")}`,\n \"Read only the part you need with offset and limit (offset = first line, limit = line count).\",\n \"To find specific text, use Grep with output_mode content and -n instead of reading the file.\",\n `To read the whole file anyway, call Read again with limit: ${lines.length}.`,\n ].join(\"\\n\"),\n },\n };\n}\n\n/** Whole file as UTF-8 text, or null when it looks binary. */\nasync function readText(path: string): Promise<string | null> {\n const handle = await open(path, \"r\");\n try {\n const content = await handle.readFile();\n if (content.includes(0)) return null;\n return content.toString(\"utf8\");\n } finally {\n await handle.close();\n }\n}\n\nfunction outlineOf(path: string, text: string, lines: string[]): string[] {\n const cap = (entries: string[]) =>\n entries.length > TOOL_GUARD.outlineEntries\n ? [\n ...entries.slice(0, TOOL_GUARD.outlineEntries),\n `… ${entries.length - TOOL_GUARD.outlineEntries} more`,\n ]\n : entries;\n if (supportsSymbols(path)) {\n const table = extractSymbolTable(text).filter(\n (symbol) => symbol.endLine - symbol.startLine + 1 >= TOOL_GUARD.outlineMinSymbolLines,\n );\n const topLevel = table.filter((symbol) => symbol.kind !== \"method\");\n // One big class says little on its own; then list its methods (`Class.method`).\n const symbols = topLevel.length >= TOOL_GUARD.minTopLevelEntries ? topLevel : table;\n if (symbols.length > 0) {\n // The symbol table is capped, so say where the outline stops covering the file.\n const covered = Math.max(...symbols.map((symbol) => symbol.endLine));\n return [\n ...cap(symbols.map((s) => `${s.name} L${s.startLine}-${s.endLine}`)),\n ...(covered < lines.length ? [`not outlined L${covered + 1}-${lines.length}`] : []),\n ];\n }\n }\n if (/\\.mdx?$/i.test(path)) {\n const headings = lines.flatMap((line, i) =>\n /^#{1,4}\\s+\\S/.test(line) ? [`${line.trim().slice(0, 80)} L${i + 1}`] : [],\n );\n if (headings.length > 0) return cap(headings);\n }\n const blocks: string[] = [];\n for (let start = 1; start <= lines.length; start += TOOL_GUARD.blockLines) {\n blocks.push(`L${start}-${Math.min(lines.length, start + TOOL_GUARD.blockLines - 1)}`);\n }\n return cap(blocks);\n}\n","import { decidePreTool } from \"./pretool.js\";\nimport { failSoft, readHookInput, writeStdout } from \"./stdio.js\";\n\n/** `codebuddy hooks pretool`: runs on every Read/Grep, so it loads only its own module. */\nexport async function runPreToolHookCommand(): Promise<void> {\n await failSoft(async () => {\n const decision = await decidePreTool(await readHookInput());\n if (decision) await writeStdout(JSON.stringify(decision));\n });\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/planner/budget.ts","../src/core/ids.ts"],"sourcesContent":["import { Tiktoken } from \"js-tiktoken/lite\";\nimport cl100kBase from \"js-tiktoken/ranks/cl100k_base\";\nimport { getModelContextWindow } from \"../providers/models.js\";\n\nlet encoder: Tiktoken | null = null;\n\nfunction getEncoder(): Tiktoken {\n if (!encoder) {\n encoder = new Tiktoken(cl100kBase);\n }\n return encoder;\n}\n\n/** cl100k pre-tokenizer: BPE merges never cross these pieces, so counts add up. */\nconst PIECE = new RegExp(cl100kBase.pat_str, \"gu\");\nconst SPECIAL_TOKENS = Object.keys(cl100kBase.special_tokens);\n// ponytail: cleared when full rather than LRU; source and JSON pieces repeat\n// heavily, so a simple bound keeps the hit rate high.\nconst MAX_CACHED_PIECES = 200_000;\nconst pieceTokens = new Map<string, number>();\n\n/**\n * Exact cl100k token count. A context request tokenizes nearly the same JSON\n * several times (stats, stages, budget fixed point, delivery), so BPE results\n * are memoized per pre-tokenized piece; the sum equals `encode(text).length`.\n */\nexport function countTokens(text: string): number {\n if (!text) return 0;\n try {\n // `encode` rejects special-token text; keep the same fallback for it.\n if (SPECIAL_TOKENS.some((token) => text.includes(token))) throw new Error(\"special token\");\n let total = 0;\n for (const [piece] of text.matchAll(PIECE)) {\n let count = pieceTokens.get(piece);\n if (count === undefined) {\n count = getEncoder().encode(piece).length;\n if (pieceTokens.size >= MAX_CACHED_PIECES) pieceTokens.clear();\n pieceTokens.set(piece, count);\n }\n total += count;\n }\n return total;\n } catch {\n return Math.max(1, Math.ceil(text.length / 4));\n }\n}\n\nexport type BudgetClampResult = {\n budget: number;\n clamped: boolean;\n reason?: string;\n};\n\nexport function clampBudgetForCallerModel(\n requestedBudget: number,\n callerModel: string | undefined,\n): BudgetClampResult {\n if (!callerModel) {\n return { budget: requestedBudget, clamped: false };\n }\n const ctx = getModelContextWindow(callerModel);\n if (!ctx) {\n return { budget: requestedBudget, clamped: false };\n }\n const headroom = Math.floor(ctx * 0.75);\n if (requestedBudget > headroom) {\n return {\n budget: headroom,\n clamped: true,\n reason: `budget ${requestedBudget} exceeds 75% of ${callerModel} context window (${ctx}); clamped to ${headroom}.`,\n };\n }\n return { budget: requestedBudget, clamped: false };\n}\n","import { createHash, randomBytes } from \"node:crypto\";\n\nconst CROCKFORD = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\nexport function generateUlid(now: number = Date.now()): string {\n let timePart = \"\";\n let ts = now;\n for (let i = 0; i < 10; i++) {\n timePart = (CROCKFORD[ts % 32] ?? \"0\") + timePart;\n ts = Math.floor(ts / 32);\n }\n\n const bytes = randomBytes(10);\n let randPart = \"\";\n for (let i = 0; i < 16; i++) {\n const bitOffset = i * 5;\n const byteIndex = Math.floor(bitOffset / 8);\n const bitInByte = bitOffset % 8;\n const hi = bytes[byteIndex] ?? 0;\n const lo = bytes[byteIndex + 1] ?? 0;\n const combined = ((hi << 8) | lo) >>> 0;\n const shift = 16 - bitInByte - 5;\n const value = (combined >>> shift) & 0x1f;\n randPart += CROCKFORD[value] ?? \"0\";\n }\n\n return timePart + randPart;\n}\n\nexport function generateSessionId(now?: number): string {\n return `sess_${generateUlid(now).toLowerCase()}`;\n}\n\nexport function generateEntityId(prefix: string, now?: number): string {\n return `${prefix}_${generateUlid(now).toLowerCase()}`;\n}\n\nexport function computeContentHash(namespace: string, sessionId: string, content: string): string {\n return createHash(\"sha256\").update(`${namespace}\\x1f${sessionId}\\x1f${content}`).digest(\"hex\");\n}\n\nexport function computeFactHash(namespace: string, content: string): string {\n return createHash(\"sha256\").update(`${namespace}\\x1ffact\\x1f${content}`).digest(\"hex\");\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +0,0 @@
1
- import {
2
- redactLlmKeys,
3
- resolveLlmConfig
4
- } from "./chunk-6MKEIDX5.js";
5
- import "./chunk-776EQXDV.js";
6
- import "./chunk-PZ5AY32C.js";
7
- export {
8
- redactLlmKeys,
9
- resolveLlmConfig
10
- };
11
- //# sourceMappingURL=config-KFEHLV6W.js.map
@@ -1,15 +0,0 @@
1
- import {
2
- runLeanHookCommand
3
- } from "./chunk-N34XHWBA.js";
4
- import "./chunk-PYLH4MH5.js";
5
- import "./chunk-SYWJG5NA.js";
6
- import "./chunk-L5AYZC3F.js";
7
- import "./chunk-PQK3GKZH.js";
8
- import "./chunk-XBJQKCLU.js";
9
- import "./chunk-JPHJBCZB.js";
10
- import "./chunk-776EQXDV.js";
11
- import "./chunk-PZ5AY32C.js";
12
- export {
13
- runLeanHookCommand
14
- };
15
- //# sourceMappingURL=lean-command-C5YPFKHP.js.map
@@ -1,13 +0,0 @@
1
- import {
2
- LocalModelProvider,
3
- modelCacheDir,
4
- rerankLocally
5
- } from "./chunk-U4HAJLIB.js";
6
- import "./chunk-JPHJBCZB.js";
7
- import "./chunk-PZ5AY32C.js";
8
- export {
9
- LocalModelProvider,
10
- modelCacheDir,
11
- rerankLocally
12
- };
13
- //# sourceMappingURL=local-OTOY56B4.js.map