@pugi/cli 0.1.0-beta.10 → 0.1.0-beta.101

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 (464) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/LICENSE +1 -1
  3. package/README.md +55 -11
  4. package/assets/pugi-prozr2-mascot.ansi +9 -0
  5. package/bin/run.js +33 -1
  6. package/dist/commands/deploy.js +40 -40
  7. package/dist/commands/flatten.js +191 -0
  8. package/dist/commands/jobs-watch.js +201 -0
  9. package/dist/commands/jobs.js +42 -27
  10. package/dist/commands/retro.js +210 -0
  11. package/dist/commands/smoke.js +133 -0
  12. package/dist/core/agent-progress/cleanup.js +134 -0
  13. package/dist/core/agent-progress/schema.js +144 -0
  14. package/dist/core/agent-progress/writer.js +101 -0
  15. package/dist/core/agents/adaptive-router.js +330 -0
  16. package/dist/core/agents/query-decomposer.js +297 -0
  17. package/dist/core/agents/registry.js +3 -3
  18. package/dist/core/approvals/shortcut-resolver.js +98 -0
  19. package/dist/core/artifact-chain/dispatcher.js +148 -0
  20. package/dist/core/artifact-chain/exporter.js +164 -0
  21. package/dist/core/artifact-chain/state.js +243 -0
  22. package/dist/core/artifact-chain/steps.js +169 -0
  23. package/dist/core/ask-user/question.js +92 -0
  24. package/dist/core/audit/audit-trail.js +275 -0
  25. package/dist/core/auth/ensure-authenticated.js +129 -0
  26. package/dist/core/auth/env-provider.js +238 -0
  27. package/dist/core/auto-open-browser.js +4 -4
  28. package/dist/core/auto-update/channels.js +122 -0
  29. package/dist/core/auto-update/checker.js +241 -0
  30. package/dist/core/auto-update/state.js +235 -0
  31. package/dist/core/bare-mode/index.js +107 -0
  32. package/dist/core/bash/redirect.js +281 -0
  33. package/dist/core/bash-classifier.js +436 -40
  34. package/dist/core/checkpoint/resumer.js +149 -0
  35. package/dist/core/checkpoint/rewinder.js +291 -0
  36. package/dist/core/checkpoints/shadow-git.js +670 -0
  37. package/dist/core/citations/parser.js +109 -0
  38. package/dist/core/classifier/yolo-classifier.js +88 -0
  39. package/dist/core/codegraph/db.js +506 -0
  40. package/dist/core/codegraph/decision-store.js +248 -0
  41. package/dist/core/codegraph/detect-repo.js +459 -0
  42. package/dist/core/codegraph/install.js +134 -0
  43. package/dist/core/codegraph/offer-hook.js +220 -0
  44. package/dist/core/codegraph/parser.js +598 -0
  45. package/dist/core/codegraph/queries/go.scm +57 -0
  46. package/dist/core/codegraph/queries/javascript.scm +56 -0
  47. package/dist/core/codegraph/queries/python.scm +55 -0
  48. package/dist/core/codegraph/queries/rust.scm +63 -0
  49. package/dist/core/codegraph/queries/typescript.scm +91 -0
  50. package/dist/core/codegraph/reindex.js +218 -0
  51. package/dist/core/codegraph/resolve-edges.js +107 -0
  52. package/dist/core/codegraph/types.js +34 -0
  53. package/dist/core/codegraph/watcher.js +440 -0
  54. package/dist/core/compact/auto-trigger.js +96 -0
  55. package/dist/core/compact/buffer-rewriter.js +115 -0
  56. package/dist/core/compact/summarizer.js +208 -0
  57. package/dist/core/compact/token-counter.js +108 -0
  58. package/dist/core/consensus/anvil-fanout.js +25 -25
  59. package/dist/core/consensus/diff-capture.js +121 -12
  60. package/dist/core/consensus/rubric.js +21 -21
  61. package/dist/core/context/builder.js +6 -6
  62. package/dist/core/context/compaction-events.js +8 -8
  63. package/dist/core/context/compaction.js +31 -31
  64. package/dist/core/context/index.js +15 -8
  65. package/dist/core/context/invariants.js +51 -51
  66. package/dist/core/context/markdown-loader.js +28 -10
  67. package/dist/core/context/markdown-traverse.js +255 -0
  68. package/dist/core/context/pugiignore.js +41 -41
  69. package/dist/core/context/repo-skeleton.js +37 -37
  70. package/dist/core/context/tool-eviction.js +55 -0
  71. package/dist/core/context/watcher.js +32 -32
  72. package/dist/core/context/working-set.js +23 -23
  73. package/dist/core/coordinator/agent-tools.js +77 -0
  74. package/dist/core/coordinator/agent-toolset.js +65 -0
  75. package/dist/core/coordinator/fsm.js +73 -0
  76. package/dist/core/coordinator/mode-fsm.js +70 -0
  77. package/dist/core/cost/rate-card.js +129 -0
  78. package/dist/core/cost/tracker.js +221 -0
  79. package/dist/core/credentials.js +13 -13
  80. package/dist/core/cron/scheduler.js +138 -0
  81. package/dist/core/denial-tracking/index.js +8 -0
  82. package/dist/core/denial-tracking/state.js +264 -0
  83. package/dist/core/diagnostics/probe-runner.js +93 -0
  84. package/dist/core/diagnostics/probes/api.js +46 -0
  85. package/dist/core/diagnostics/probes/auth.js +93 -0
  86. package/dist/core/diagnostics/probes/bare-mode.js +42 -0
  87. package/dist/core/diagnostics/probes/cli-version.js +127 -0
  88. package/dist/core/diagnostics/probes/config.js +72 -0
  89. package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
  90. package/dist/core/diagnostics/probes/disk.js +81 -0
  91. package/dist/core/diagnostics/probes/engine-live.js +46 -0
  92. package/dist/core/diagnostics/probes/git.js +65 -0
  93. package/dist/core/diagnostics/probes/hooks.js +118 -0
  94. package/dist/core/diagnostics/probes/mcp.js +75 -0
  95. package/dist/core/diagnostics/probes/node.js +59 -0
  96. package/dist/core/diagnostics/probes/pnpm.js +36 -0
  97. package/dist/core/diagnostics/probes/pugi-md.js +89 -0
  98. package/dist/core/diagnostics/probes/sandbox.js +67 -0
  99. package/dist/core/diagnostics/probes/session.js +74 -0
  100. package/dist/core/diagnostics/probes/status-snapshot.js +488 -0
  101. package/dist/core/diagnostics/probes/workspace.js +63 -0
  102. package/dist/core/diagnostics/types.js +70 -0
  103. package/dist/core/dispatch/cache-cleanup.js +197 -0
  104. package/dist/core/dispatch/cache-handoff.js +295 -0
  105. package/dist/core/edits/apply-patch-layer-e.js +189 -0
  106. package/dist/core/edits/dispatch.js +333 -7
  107. package/dist/core/edits/format-detector.js +260 -0
  108. package/dist/core/edits/format-matrix.js +26 -0
  109. package/dist/core/edits/fuzzy-ladder.js +650 -0
  110. package/dist/core/edits/index.js +5 -1
  111. package/dist/core/edits/journal.js +199 -0
  112. package/dist/core/edits/layer-a-apply.js +15 -15
  113. package/dist/core/edits/layer-a-fuzzy-apply.js +198 -0
  114. package/dist/core/edits/layer-b-apply.js +9 -9
  115. package/dist/core/edits/layer-c-apply.js +6 -6
  116. package/dist/core/edits/layer-d-ast.js +557 -14
  117. package/dist/core/edits/marker-parser.js +12 -12
  118. package/dist/core/edits/security-gate.js +27 -27
  119. package/dist/core/edits/verify-hook.js +273 -0
  120. package/dist/core/edits/worktree.js +29 -29
  121. package/dist/core/engine/anvil-client.js +214 -26
  122. package/dist/core/engine/auto-compact.js +247 -0
  123. package/dist/core/engine/budgets.js +220 -0
  124. package/dist/core/engine/compact-llm-summarizer.js +124 -0
  125. package/dist/core/engine/context-prefix.js +155 -0
  126. package/dist/core/engine/index.js +1 -1
  127. package/dist/core/engine/intensity.js +163 -0
  128. package/dist/core/engine/intent.js +260 -0
  129. package/dist/core/engine/native-pugi.js +1559 -227
  130. package/dist/core/engine/prompts.js +219 -19
  131. package/dist/core/engine/strip-internal-fields.js +124 -0
  132. package/dist/core/engine/tool-bridge.js +1887 -59
  133. package/dist/core/engine/verification-patterns.js +195 -0
  134. package/dist/core/eval/v1/ledger.js +83 -0
  135. package/dist/core/eval/v1/runner.js +280 -0
  136. package/dist/core/eval/v1/scoring.js +68 -0
  137. package/dist/core/eval/v1/task-loader.js +191 -0
  138. package/dist/core/eval/v1/types.js +14 -0
  139. package/dist/core/eval/v1/verifier.js +176 -0
  140. package/dist/core/eval/v1/yaml-parser.js +250 -0
  141. package/dist/core/evaluation/golden-dataset.js +293 -0
  142. package/dist/core/feedback/queue.js +177 -0
  143. package/dist/core/feedback/submitter.js +145 -0
  144. package/dist/core/file-cache.js +113 -1
  145. package/dist/core/flatten/flatten-repo.js +439 -0
  146. package/dist/core/format/osc8-link.js +28 -0
  147. package/dist/core/hook-chains.js +392 -0
  148. package/dist/core/hooks/citation-verify-hook.js +138 -0
  149. package/dist/core/hooks/citation-verify.js +112 -0
  150. package/dist/core/hooks/events.js +46 -0
  151. package/dist/core/hooks/index.js +15 -0
  152. package/dist/core/hooks/registry.js +216 -0
  153. package/dist/core/hooks/runner.js +236 -0
  154. package/dist/core/hooks/v2/event-emitter.js +115 -0
  155. package/dist/core/hooks/v2/executor.js +282 -0
  156. package/dist/core/hooks/v2/index.js +25 -0
  157. package/dist/core/hooks/v2/lifecycle.js +104 -0
  158. package/dist/core/hooks/v2/loader.js +216 -0
  159. package/dist/core/hooks/v2/matcher.js +125 -0
  160. package/dist/core/hooks/v2/trust.js +143 -0
  161. package/dist/core/hooks/v2/types.js +86 -0
  162. package/dist/core/hooks/worktree-events.js +158 -0
  163. package/dist/core/image/renderer.js +71 -0
  164. package/dist/core/init/detector.js +582 -0
  165. package/dist/core/init/template-renderer.js +242 -0
  166. package/dist/core/jobs/registry.js +18 -18
  167. package/dist/core/ledger/results-tsv.js +142 -0
  168. package/dist/core/log-discipline/stdout-redirect.js +51 -0
  169. package/dist/core/lsp/cache.js +105 -0
  170. package/dist/core/lsp/client.js +551 -41
  171. package/dist/core/lsp/language-detect.js +66 -0
  172. package/dist/core/lsp/post-edit-diagnostics.js +171 -0
  173. package/dist/core/lsp/server-detect.js +173 -0
  174. package/dist/core/lsp/symbol-cache.js +162 -0
  175. package/dist/core/lsp/symbol-tools.js +664 -0
  176. package/dist/core/mcp/client.js +97 -28
  177. package/dist/core/mcp/http-server.js +553 -0
  178. package/dist/core/mcp/orchestrator-config.js +192 -0
  179. package/dist/core/mcp/orchestrator-tools.js +806 -0
  180. package/dist/core/mcp/permission.js +190 -0
  181. package/dist/core/mcp/registry.js +39 -17
  182. package/dist/core/mcp/server-tools.js +219 -0
  183. package/dist/core/mcp/server.js +397 -0
  184. package/dist/core/mcp/trust.js +10 -10
  185. package/dist/core/memory/dual-write.js +416 -0
  186. package/dist/core/memory/passive-extract.js +130 -0
  187. package/dist/core/memory/phase1-kinds.js +20 -0
  188. package/dist/core/memory/secret-scanner.js +304 -0
  189. package/dist/core/memory-sync/queue.js +170 -0
  190. package/dist/core/metrics/extract.js +113 -0
  191. package/dist/core/modes/roo-modes.js +68 -0
  192. package/dist/core/notes/notes-paths.js +113 -0
  193. package/dist/core/notes/notes-recorder.js +140 -0
  194. package/dist/core/notes/notes-writer.js +53 -0
  195. package/dist/core/notes/renderers.js +0 -0
  196. package/dist/core/notes/slug.js +105 -0
  197. package/dist/core/onboarding/ensure-initialized.js +133 -0
  198. package/dist/core/onboarding/marker.js +111 -0
  199. package/dist/core/onboarding/telemetry-state.js +108 -0
  200. package/dist/core/output-style/presets.js +176 -0
  201. package/dist/core/output-style/state.js +185 -0
  202. package/dist/core/path-security.js +287 -5
  203. package/dist/core/permission.js +82 -22
  204. package/dist/core/permissions/auto-classifier.js +124 -0
  205. package/dist/core/permissions/bash-parser.js +371 -0
  206. package/dist/core/permissions/circuit-breaker.js +83 -0
  207. package/dist/core/permissions/constrained-edit.js +91 -0
  208. package/dist/core/permissions/gate.js +278 -0
  209. package/dist/core/permissions/index.js +20 -0
  210. package/dist/core/permissions/mode.js +174 -0
  211. package/dist/core/permissions/network-egress.js +137 -0
  212. package/dist/core/permissions/state.js +241 -0
  213. package/dist/core/permissions/tool-class.js +107 -0
  214. package/dist/core/plan-mode/ui-state.js +51 -0
  215. package/dist/core/plans/plan-artifact.js +721 -0
  216. package/dist/core/policy-limits/etag-store.js +122 -0
  217. package/dist/core/prd-check/parser.js +215 -0
  218. package/dist/core/prd-check/reporter.js +127 -0
  219. package/dist/core/prd-check/session-review.js +557 -0
  220. package/dist/core/prd-check/verifiers.js +223 -0
  221. package/dist/core/prompt-cache/client-cache.js +99 -0
  222. package/dist/core/prompts/assembly.js +29 -0
  223. package/dist/core/prompts/registry.js +364 -0
  224. package/dist/core/pugi-gitignore.js +52 -0
  225. package/dist/core/pugi-md/cc-compat-rules.js +735 -0
  226. package/dist/core/pugi-md/context-injector.js +76 -0
  227. package/dist/core/pugi-md/walk-up.js +207 -0
  228. package/dist/core/python/uv-installer.js +270 -0
  229. package/dist/core/python/uv-resolver.js +83 -0
  230. package/dist/core/rate-limit/narrator.js +146 -0
  231. package/dist/core/recipes/cli-types.js +20 -0
  232. package/dist/core/recipes/loader.js +103 -0
  233. package/dist/core/recipes/runner.js +345 -0
  234. package/dist/core/recipes/schema.js +587 -0
  235. package/dist/core/release-notes/parser.js +241 -0
  236. package/dist/core/release-notes/state.js +116 -0
  237. package/dist/core/repl/ask.js +37 -37
  238. package/dist/core/repl/cancellation.js +26 -26
  239. package/dist/core/repl/cap-warning.js +4 -4
  240. package/dist/core/repl/clipboard-read.js +11 -11
  241. package/dist/core/repl/dispatch-fsm.js +12 -12
  242. package/dist/core/repl/engine-bridge.js +303 -0
  243. package/dist/core/repl/history-search.js +15 -15
  244. package/dist/core/repl/history.js +28 -18
  245. package/dist/core/repl/kill-ring.js +5 -5
  246. package/dist/core/repl/model-pricing.js +135 -0
  247. package/dist/core/repl/privacy-banner.js +22 -22
  248. package/dist/core/repl/session.js +2690 -229
  249. package/dist/core/repl/slash-commands.js +540 -41
  250. package/dist/core/repl/store/index.js +1 -1
  251. package/dist/core/repl/store/jsonl-log.js +22 -22
  252. package/dist/core/repl/store/lockfile.js +10 -10
  253. package/dist/core/repl/store/session-store.js +136 -107
  254. package/dist/core/repl/store/types.js +15 -15
  255. package/dist/core/repl/store/uuid-v7.js +12 -12
  256. package/dist/core/repl/tool-route.js +382 -0
  257. package/dist/core/repl/workspace-context.js +43 -21
  258. package/dist/core/repo-map/build.js +125 -0
  259. package/dist/core/repo-map/cache.js +185 -0
  260. package/dist/core/repo-map/extractor.js +254 -0
  261. package/dist/core/repo-map/formatter.js +145 -0
  262. package/dist/core/repo-map/page-rank.js +105 -0
  263. package/dist/core/repo-map/scanner.js +211 -0
  264. package/dist/core/retro/git-collector.js +251 -0
  265. package/dist/core/retro/health-card.js +25 -0
  266. package/dist/core/retro/metrics.js +342 -0
  267. package/dist/core/retro/narrative.js +249 -0
  268. package/dist/core/retro/plane-collector.js +274 -0
  269. package/dist/core/retro/pr-issue-link.js +65 -0
  270. package/dist/core/retro/types.js +16 -0
  271. package/dist/core/retry-budget/budget.js +284 -0
  272. package/dist/core/retry-budget/index.js +5 -0
  273. package/dist/core/retry-budget/retry-cap.js +74 -0
  274. package/dist/core/routing/lead-worker.js +43 -0
  275. package/dist/core/routing/pre-flight-estimator.js +108 -0
  276. package/dist/core/runs/run-tree.js +103 -0
  277. package/dist/core/sandboxing/adapter.js +43 -0
  278. package/dist/core/sandboxing/bubblewrap.js +209 -0
  279. package/dist/core/sandboxing/index.js +78 -0
  280. package/dist/core/sandboxing/none.js +19 -0
  281. package/dist/core/sandboxing/policy.js +97 -0
  282. package/dist/core/sandboxing/seatbelt.js +231 -0
  283. package/dist/core/security/injection-scanner.js +367 -0
  284. package/dist/core/security/output-filter.js +418 -0
  285. package/dist/core/session/env-file.js +105 -0
  286. package/dist/core/session/section-budgets.js +140 -0
  287. package/dist/core/session.js +119 -0
  288. package/dist/core/settings.js +402 -5
  289. package/dist/core/share/formatter.js +271 -0
  290. package/dist/core/share/redactor.js +221 -0
  291. package/dist/core/share/uploader.js +267 -0
  292. package/dist/core/skills/defaults.js +30 -30
  293. package/dist/core/skills/loader.js +22 -22
  294. package/dist/core/skills/sources.js +27 -27
  295. package/dist/core/smoke/headless-driver.js +174 -0
  296. package/dist/core/smoke/orchestrator.js +194 -0
  297. package/dist/core/smoke/runner.js +238 -0
  298. package/dist/core/smoke/scenario-parser.js +316 -0
  299. package/dist/core/statusline.js +99 -0
  300. package/dist/core/subagents/dispatcher-real.js +600 -0
  301. package/dist/core/subagents/dispatcher.js +146 -52
  302. package/dist/core/subagents/index.js +19 -6
  303. package/dist/core/subagents/isolation-matrix.js +213 -0
  304. package/dist/core/subagents/spawn.js +19 -4
  305. package/dist/core/telemetry/emitter.js +229 -0
  306. package/dist/core/telemetry/queue.js +251 -0
  307. package/dist/core/theme/context.js +91 -0
  308. package/dist/core/theme/presets.js +228 -0
  309. package/dist/core/theme/state.js +181 -0
  310. package/dist/core/todos/invariant.js +10 -0
  311. package/dist/core/todos/state.js +177 -0
  312. package/dist/core/tool-schema/compressor.js +89 -0
  313. package/dist/core/transport/version-interceptor.js +166 -0
  314. package/dist/core/trust.js +2 -2
  315. package/dist/core/tui/thinking-block.js +64 -0
  316. package/dist/core/vim/keymap.js +288 -0
  317. package/dist/core/vim/state.js +92 -0
  318. package/dist/core/watch-markers/marker-watcher.js +133 -0
  319. package/dist/core/worktree/include-parser.js +249 -0
  320. package/dist/core/worktree-manager/cleanup.js +123 -0
  321. package/dist/core/worktree-manager/manager.js +303 -0
  322. package/dist/index.js +36 -0
  323. package/dist/runtime/bootstrap.js +190 -0
  324. package/dist/runtime/cli.js +4403 -561
  325. package/dist/runtime/commands/agents.js +31 -31
  326. package/dist/runtime/commands/budget.js +5 -5
  327. package/dist/runtime/commands/cancel.js +231 -0
  328. package/dist/runtime/commands/chain.js +489 -0
  329. package/dist/runtime/commands/codegraph-status.js +227 -0
  330. package/dist/runtime/commands/compact.js +297 -0
  331. package/dist/runtime/commands/config.js +74 -40
  332. package/dist/runtime/commands/cost.js +199 -0
  333. package/dist/runtime/commands/delegate.js +27 -4
  334. package/dist/runtime/commands/dispatch.js +126 -0
  335. package/dist/runtime/commands/doctor.js +579 -0
  336. package/dist/runtime/commands/eval-v1.js +266 -0
  337. package/dist/runtime/commands/feedback.js +184 -0
  338. package/dist/runtime/commands/hooks.js +187 -0
  339. package/dist/runtime/commands/index-cmd.js +459 -0
  340. package/dist/runtime/commands/init.js +254 -0
  341. package/dist/runtime/commands/lsp.js +200 -38
  342. package/dist/runtime/commands/mcp.js +935 -0
  343. package/dist/runtime/commands/memory.js +582 -0
  344. package/dist/runtime/commands/model.js +237 -0
  345. package/dist/runtime/commands/onboarding.js +275 -0
  346. package/dist/runtime/commands/patch.js +12 -12
  347. package/dist/runtime/commands/permissions.js +112 -0
  348. package/dist/runtime/commands/plan.js +143 -0
  349. package/dist/runtime/commands/prd-check.js +285 -0
  350. package/dist/runtime/commands/privacy.js +17 -17
  351. package/dist/runtime/commands/recipe.js +325 -0
  352. package/dist/runtime/commands/redo-blob-store.js +92 -0
  353. package/dist/runtime/commands/redo.js +361 -0
  354. package/dist/runtime/commands/release-notes.js +229 -0
  355. package/dist/runtime/commands/repo-map.js +95 -0
  356. package/dist/runtime/commands/report.js +299 -0
  357. package/dist/runtime/commands/resume.js +118 -0
  358. package/dist/runtime/commands/review-consensus.js +68 -53
  359. package/dist/runtime/commands/rewind.js +333 -0
  360. package/dist/runtime/commands/roster.js +14 -14
  361. package/dist/runtime/commands/servers-cli.js +182 -0
  362. package/dist/runtime/commands/servers.js +236 -0
  363. package/dist/runtime/commands/sessions.js +163 -0
  364. package/dist/runtime/commands/share.js +316 -0
  365. package/dist/runtime/commands/skills.js +31 -31
  366. package/dist/runtime/commands/status.js +186 -0
  367. package/dist/runtime/commands/stickers.js +82 -0
  368. package/dist/runtime/commands/style.js +194 -0
  369. package/dist/runtime/commands/theme.js +196 -0
  370. package/dist/runtime/commands/undo.js +54 -22
  371. package/dist/runtime/commands/update.js +289 -0
  372. package/dist/runtime/commands/vim.js +140 -0
  373. package/dist/runtime/commands/worktree.js +8 -8
  374. package/dist/runtime/commands/worktrees.js +155 -0
  375. package/dist/runtime/deprecation-warning.js +69 -0
  376. package/dist/runtime/engine-exit-code.js +50 -0
  377. package/dist/runtime/headless-repl.js +195 -0
  378. package/dist/runtime/headless.js +548 -0
  379. package/dist/runtime/load-hooks-or-exit.js +71 -0
  380. package/dist/runtime/plan-decompose.js +22 -22
  381. package/dist/runtime/sigint-guard.js +272 -0
  382. package/dist/runtime/stream-renderer.js +195 -0
  383. package/dist/runtime/update-check.js +28 -28
  384. package/dist/runtime/version.js +65 -0
  385. package/dist/runtime/worktree-bootstrap.js +579 -0
  386. package/dist/skills/bundled/batch.js +617 -0
  387. package/dist/skills/bundled/index.js +45 -0
  388. package/dist/skills/bundled/loop.js +358 -0
  389. package/dist/skills/bundled/remember.js +383 -0
  390. package/dist/skills/bundled/simplify.js +289 -0
  391. package/dist/skills/bundled/skillify.js +373 -0
  392. package/dist/skills/bundled/stuck.js +558 -0
  393. package/dist/skills/bundled/verify.js +439 -0
  394. package/dist/testing/vcr.js +486 -0
  395. package/dist/tools/agent-tool.js +229 -0
  396. package/dist/tools/apply-patch.js +89 -28
  397. package/dist/tools/ask-user-question.js +337 -0
  398. package/dist/tools/ask-user.js +115 -0
  399. package/dist/tools/bash.js +811 -49
  400. package/dist/tools/brief.js +224 -0
  401. package/dist/tools/cron.js +433 -0
  402. package/dist/tools/enter-worktree.js +250 -0
  403. package/dist/tools/exit-worktree.js +147 -0
  404. package/dist/tools/file-tools.js +161 -44
  405. package/dist/tools/http-request.js +336 -0
  406. package/dist/tools/lsp-tools.js +377 -1
  407. package/dist/tools/mcp-tool.js +260 -0
  408. package/dist/tools/multi-edit.js +361 -0
  409. package/dist/tools/powershell.js +268 -0
  410. package/dist/tools/registry.js +120 -5
  411. package/dist/tools/server-tools.js +892 -0
  412. package/dist/tools/skill-tool.js +96 -0
  413. package/dist/tools/sleep.js +99 -0
  414. package/dist/tools/synthetic-output.js +133 -0
  415. package/dist/tools/tasks.js +208 -0
  416. package/dist/tools/todo-write.js +184 -0
  417. package/dist/tools/verify-plan-execution.js +295 -0
  418. package/dist/tools/web-fetch-injection-scanner.js +207 -0
  419. package/dist/tools/web-fetch.js +195 -10
  420. package/dist/tools/web-search.js +458 -0
  421. package/dist/tui/agent-progress-card.js +111 -0
  422. package/dist/tui/agent-tree.js +22 -1
  423. package/dist/tui/ask-modal.js +14 -14
  424. package/dist/tui/ask-user-question-chips.js +315 -0
  425. package/dist/tui/ask-user-question-prompt.js +203 -0
  426. package/dist/tui/compact-banner.js +81 -0
  427. package/dist/tui/conversation-pane.js +85 -11
  428. package/dist/tui/cost-table.js +111 -0
  429. package/dist/tui/device-flow.js +2 -2
  430. package/dist/tui/doctor-table.js +46 -0
  431. package/dist/tui/feedback-prompt.js +156 -0
  432. package/dist/tui/input-box.js +247 -32
  433. package/dist/tui/login-picker.js +3 -3
  434. package/dist/tui/markdown-render.js +6 -6
  435. package/dist/tui/multi-file-diff-approval.js +375 -0
  436. package/dist/tui/onboarding-wizard.js +240 -0
  437. package/dist/tui/permissions-picker.js +86 -0
  438. package/dist/tui/render.js +36 -1
  439. package/dist/tui/repl-render.js +239 -25
  440. package/dist/tui/repl-splash-art.js +16 -16
  441. package/dist/tui/repl-splash-mascot.js +48 -24
  442. package/dist/tui/repl-splash.js +22 -22
  443. package/dist/tui/repl.js +125 -45
  444. package/dist/tui/slash-palette.js +6 -6
  445. package/dist/tui/splash.js +2 -2
  446. package/dist/tui/status-bar.js +109 -31
  447. package/dist/tui/status-table.js +7 -0
  448. package/dist/tui/stickers-art.js +136 -0
  449. package/dist/tui/style-table.js +28 -0
  450. package/dist/tui/theme-table.js +29 -0
  451. package/dist/tui/thinking-spinner.js +123 -0
  452. package/dist/tui/tool-stream-pane.js +53 -4
  453. package/dist/tui/update-banner.js +27 -2
  454. package/dist/tui/vim-input.js +267 -0
  455. package/dist/tui/welcome-banner.js +107 -0
  456. package/dist/tui/welcome-data.js +293 -0
  457. package/dist/tui/workspace-context.js +2 -2
  458. package/package.json +29 -6
  459. package/test/scenarios/codegen-create-file.scenario.txt +13 -0
  460. package/test/scenarios/compact-force.scenario.txt +12 -0
  461. package/test/scenarios/identity.scenario.txt +11 -0
  462. package/test/scenarios/persona-handoff.scenario.txt +12 -0
  463. package/test/scenarios/walkback.scenario.txt +12 -0
  464. package/dist/core/engine/compaction-hook.js +0 -154
@@ -0,0 +1,598 @@
1
+ /**
2
+ * Pugi local symbol index - tree-sitter parser (PR L1).
3
+ *
4
+ * Reads one source file, parses it with the appropriate tree-sitter
5
+ * grammar, runs the language's symbol + edge query
6
+ * (`./queries/<lang>.scm`), and emits a `ParseResult`:
7
+ *
8
+ * - `symbols`: complete `Symbol[]` ready for `db.ts:insertSymbols`.
9
+ * - `pendingEdges`: name-keyed edges. `db.Edge` requires assigned
10
+ * SQLite row ids on both endpoints, which the parser cannot
11
+ * supply - the orchestrator (in `runtime/commands/index-cmd.ts`)
12
+ * inserts symbols first, builds a name map per file, and then
13
+ * resolves pending edges before calling `insertEdges`. Cross-file
14
+ * edges land when the target symbol exists in the index at flush
15
+ * time.
16
+ *
17
+ * Design decisions:
18
+ *
19
+ * - The contract types in `./types.ts` are FROZEN. We extend the
20
+ * `ParseResult` shape locally (add `pendingEdges`) rather than
21
+ * changing `Edge` to carry names. `db.ts` stays single-purpose.
22
+ * - Tree-sitter has built-in error recovery via `SyntaxNode.hasError`.
23
+ * Broken sources still produce a partial tree; we walk it as-is
24
+ * and surface the partial symbol set rather than throwing. This
25
+ * mirrors Aider / Cody / Sourcegraph - all production indexers
26
+ * swallow parse errors and trust the user to notice via downstream
27
+ * symptoms.
28
+ * - The performance budget (200 ms per 5K LOC file) is enforced by
29
+ * `setTimeoutMicros` on the parser and a wall-clock check after
30
+ * the query pass. Over-budget files emit to stderr (unless
31
+ * silenced) rather than throwing.
32
+ * - Query files (`.scm`) are loaded once per process and the
33
+ * compiled `Parser.Query` instances are cached on the grammar.
34
+ * The query constructor is the expensive step (~30-50 ms for a
35
+ * 20-pattern query) - the cache keeps reindex throughput high.
36
+ *
37
+ * Native dependency caveat: `tree-sitter` + the per-language grammar
38
+ * packages are native modules. The `node-gyp-build` runtime they ship
39
+ * resolves prebuilt binaries for darwin-{arm64,x64},
40
+ * linux-{arm64,x64}, win32-arm64 - the set the @pugi/cli customer
41
+ * matrix actually covers. On an unsupported platform `require()`
42
+ * throws at the top-level import; we lazy-load the grammar (and the
43
+ * runtime itself, via dynamic import) so a missing prebuild degrades
44
+ * to "unsupported file type" rather than crashing the CLI on startup.
45
+ * See `loadBindings`.
46
+ */
47
+ import { promises as fs, readFileSync } from 'node:fs';
48
+ import { extname, dirname, resolve } from 'node:path';
49
+ import { fileURLToPath } from 'node:url';
50
+ import { performance } from 'node:perf_hooks';
51
+ /** Wall-clock perf budget in milliseconds for a single file. */
52
+ const PERF_BUDGET_MS = 200;
53
+ /**
54
+ * tree-sitter accepts a microseconds timeout on the parser itself.
55
+ * We cap parsing at 2x the wall-clock budget to give the query
56
+ * phase headroom while still bounding pathological cases.
57
+ */
58
+ const PARSER_TIMEOUT_MICROS = PERF_BUDGET_MS * 1000 * 2;
59
+ /**
60
+ * Extensions the parser handles. Mirror of the docs in `db.ts` /
61
+ * `types.ts:IndexedLanguage`. Anything not in this map returns an
62
+ * empty ParseResult without touching tree-sitter at all.
63
+ */
64
+ const EXT_TO_LANG = Object.freeze({
65
+ '.ts': 'typescript',
66
+ '.tsx': 'tsx',
67
+ '.js': 'javascript',
68
+ '.jsx': 'javascript',
69
+ '.mjs': 'javascript',
70
+ '.cjs': 'javascript',
71
+ '.py': 'python',
72
+ '.go': 'go',
73
+ '.rs': 'rust',
74
+ });
75
+ /**
76
+ * Stable list of file extensions the v1 parser supports. Exported
77
+ * so the watcher (PR L2) and the CLI command (`pugi index`) can
78
+ * pre-filter the file walk without instantiating a parser. The set
79
+ * mirrors `INDEXED_LANGUAGES` in `./types.ts`.
80
+ */
81
+ export const PARSEABLE_EXTENSIONS = Object.freeze([
82
+ '.ts',
83
+ '.tsx',
84
+ '.js',
85
+ '.jsx',
86
+ '.mjs',
87
+ '.cjs',
88
+ '.py',
89
+ '.go',
90
+ '.rs',
91
+ ]);
92
+ /** Tag for the typescript-with-jsx variant of the tree-sitter grammar. */
93
+ const TSX_TAG = 'tsx';
94
+ let bindingsCache = null;
95
+ let bindingsError = null;
96
+ let bindingsErrorReported = false;
97
+ /**
98
+ * Lazy-load tree-sitter runtime + grammar bindings. Bundled here so
99
+ * that a missing prebuild on the host platform produces a "no
100
+ * parser" branch rather than a startup-time `require()` throw that
101
+ * crashes `pugi` before the operator sees a prompt.
102
+ *
103
+ * Returns null when the native module is unavailable. Callers
104
+ * downgrade to "unsupported file type" - the CLI logs the underlying
105
+ * error to stderr once per process for transparency.
106
+ */
107
+ async function loadBindings(quiet) {
108
+ if (bindingsCache)
109
+ return bindingsCache;
110
+ if (bindingsError) {
111
+ if (!quiet && !bindingsErrorReported) {
112
+ bindingsErrorReported = true;
113
+ process.stderr.write(`pugi index: tree-sitter unavailable on this platform - ${bindingsError.message}\n`);
114
+ }
115
+ return null;
116
+ }
117
+ try {
118
+ // Dynamic import so a missing prebuild surfaces as a normal
119
+ // Error and the rest of the CLI keeps working. `tree-sitter`
120
+ // itself ships a CJS entry; the ESM dynamic import wraps it
121
+ // transparently.
122
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
123
+ const tsModule = await import('tree-sitter');
124
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
+ const ParserCtor = tsModule.default ?? tsModule;
126
+ const QueryCtor = ParserCtor.Query;
127
+ if (typeof QueryCtor !== 'function') {
128
+ throw new Error('tree-sitter module loaded but Parser.Query is missing - rebuild the native binding');
129
+ }
130
+ const langs = new Map();
131
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
132
+ const pickLang = async (
133
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
134
+ importer,
135
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
+ pick) => {
137
+ const mod = await importer();
138
+ const language = pick(mod);
139
+ if (!language) {
140
+ throw new Error('grammar load produced no Language object');
141
+ }
142
+ return language;
143
+ };
144
+ const typescript = await pickLang(() => import('tree-sitter-typescript'), (m) => m.typescript ?? m.default?.typescript);
145
+ const tsx = await pickLang(() => import('tree-sitter-typescript'), (m) => m.tsx ?? m.default?.tsx);
146
+ const javascript = await pickLang(() => import('tree-sitter-javascript'), (m) => m.default ?? m);
147
+ const python = await pickLang(() => import('tree-sitter-python'), (m) => m.default ?? m);
148
+ const go = await pickLang(() => import('tree-sitter-go'), (m) => m.default ?? m);
149
+ const rust = await pickLang(() => import('tree-sitter-rust'), (m) => m.default ?? m);
150
+ const tsQuerySrc = readQuerySource('typescript');
151
+ const jsQuerySrc = readQuerySource('javascript');
152
+ const pyQuerySrc = readQuerySource('python');
153
+ const goQuerySrc = readQuerySource('go');
154
+ const rsQuerySrc = readQuerySource('rust');
155
+ langs.set('typescript', {
156
+ language: typescript,
157
+ query: new QueryCtor(typescript, tsQuerySrc),
158
+ });
159
+ langs.set(TSX_TAG, {
160
+ language: tsx,
161
+ query: new QueryCtor(tsx, tsQuerySrc),
162
+ });
163
+ langs.set('javascript', {
164
+ language: javascript,
165
+ query: new QueryCtor(javascript, jsQuerySrc),
166
+ });
167
+ langs.set('python', {
168
+ language: python,
169
+ query: new QueryCtor(python, pyQuerySrc),
170
+ });
171
+ langs.set('go', {
172
+ language: go,
173
+ query: new QueryCtor(go, goQuerySrc),
174
+ });
175
+ langs.set('rust', {
176
+ language: rust,
177
+ query: new QueryCtor(rust, rsQuerySrc),
178
+ });
179
+ bindingsCache = { ParserCtor, langs };
180
+ return bindingsCache;
181
+ }
182
+ catch (err) {
183
+ bindingsError = err instanceof Error ? err : new Error(String(err));
184
+ if (!quiet && !bindingsErrorReported) {
185
+ bindingsErrorReported = true;
186
+ process.stderr.write(`pugi index: tree-sitter unavailable on this platform - ${bindingsError.message}\n`);
187
+ }
188
+ return null;
189
+ }
190
+ }
191
+ /**
192
+ * Reset the bindings cache. Exposed for tests so a forced reload
193
+ * exercises the cold path. Not part of the public API.
194
+ */
195
+ export function __resetBindingsCacheForTests() {
196
+ bindingsCache = null;
197
+ bindingsError = null;
198
+ bindingsErrorReported = false;
199
+ }
200
+ /**
201
+ * Resolve `<here>/queries/<lang>.scm`. tsc copies the `.scm` files
202
+ * to `dist/core/codegraph/queries/` via `scripts/copy-queries.mjs`;
203
+ * at runtime (both via `tsx` against `src/` and via `node` against
204
+ * `dist/`) `import.meta.url` already points to the right tree.
205
+ */
206
+ function readQuerySource(lang) {
207
+ const here = dirname(fileURLToPath(import.meta.url));
208
+ const path = resolve(here, 'queries', `${lang}.scm`);
209
+ return readFileSync(path, 'utf8');
210
+ }
211
+ /**
212
+ * Resolve the language tag for a given file path. Returns null when
213
+ * the extension is not in the v1 set. Exported for the watcher and
214
+ * tests; the CLI does the same check via PARSEABLE_EXTENSIONS first.
215
+ */
216
+ export function detectLanguage(path) {
217
+ const ext = extname(path).toLowerCase();
218
+ return EXT_TO_LANG[ext] ?? null;
219
+ }
220
+ /**
221
+ * Parse one source file. The signature is the stable contract that
222
+ * db.ts, the watcher (PR L2), and the MCP tools (PR L3) consume.
223
+ *
224
+ * Behavior summary:
225
+ *
226
+ * - Unsupported extension - `{symbols: [], pendingEdges: [],
227
+ * language: null}` without reading the file.
228
+ * - tree-sitter unavailable (no prebuild) - same shape, plus a
229
+ * one-time stderr message.
230
+ * - Source bytes large or syntactically broken - partial result;
231
+ * `SyntaxNode.hasError` does not abort the walk.
232
+ * - Perf budget exceeded - result is returned anyway; a one-line
233
+ * warning to stderr (unless `opts.quiet`) so reindex throughput
234
+ * issues surface without aborting the run.
235
+ *
236
+ * Throws only on un-recoverable IO errors (file disappeared
237
+ * mid-read on the supplied workspace). Callers wrap in try/catch
238
+ * when they want to tolerate that as well.
239
+ */
240
+ export async function parseFile(path, opts = {}) {
241
+ const language = detectLanguage(path);
242
+ if (!language) {
243
+ return { symbols: [], pendingEdges: [], language: null, parseMs: 0 };
244
+ }
245
+ const bindings = await loadBindings(opts.quiet === true);
246
+ if (!bindings) {
247
+ return { symbols: [], pendingEdges: [], language: null, parseMs: 0 };
248
+ }
249
+ const langEntry = bindings.langs.get(language);
250
+ if (!langEntry) {
251
+ return { symbols: [], pendingEdges: [], language: null, parseMs: 0 };
252
+ }
253
+ const source = opts.sourceOverride !== undefined
254
+ ? opts.sourceOverride
255
+ : await fs.readFile(path, 'utf8');
256
+ const relPath = opts.relPath ?? path;
257
+ const start = performance.now();
258
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
259
+ const parser = new bindings.ParserCtor();
260
+ parser.setLanguage(langEntry.language);
261
+ // node-tree-sitter's `setTimeoutMicros` is a hard cap that returns
262
+ // null from `parse()` when exceeded. We catch null and emit an
263
+ // empty result so the rest of the index walk keeps making progress.
264
+ if (typeof parser.setTimeoutMicros === 'function') {
265
+ parser.setTimeoutMicros(PARSER_TIMEOUT_MICROS);
266
+ }
267
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
268
+ let tree = null;
269
+ try {
270
+ tree = parser.parse(source);
271
+ }
272
+ catch (err) {
273
+ if (!opts.quiet) {
274
+ process.stderr.write(`pugi index: parse error in ${relPath}: ${err instanceof Error ? err.message : String(err)}\n`);
275
+ }
276
+ return {
277
+ symbols: [],
278
+ pendingEdges: [],
279
+ language: tagForResult(language),
280
+ parseMs: performance.now() - start,
281
+ };
282
+ }
283
+ if (!tree || !tree.rootNode) {
284
+ return {
285
+ symbols: [],
286
+ pendingEdges: [],
287
+ language: tagForResult(language),
288
+ parseMs: performance.now() - start,
289
+ };
290
+ }
291
+ const { symbols, pendingEdges } = extract(tree.rootNode, langEntry.query, relPath, language);
292
+ const parseMs = performance.now() - start;
293
+ if (parseMs > PERF_BUDGET_MS && !opts.quiet) {
294
+ const loc = countLines(source);
295
+ process.stderr.write(`pugi index: ${relPath} parsed in ${parseMs.toFixed(1)} ms (${loc} LOC) - over ${PERF_BUDGET_MS} ms budget\n`);
296
+ }
297
+ return {
298
+ symbols,
299
+ pendingEdges,
300
+ language: tagForResult(language),
301
+ parseMs,
302
+ };
303
+ }
304
+ /**
305
+ * Map the tree-sitter grammar tag back to the customer-facing
306
+ * language label used by `Symbol` / `IndexedLanguage`. We collapse
307
+ * the tsx grammar back to `typescript` so the FTS5 + db layer sees
308
+ * one tag per extension family.
309
+ */
310
+ function tagForResult(grammarTag) {
311
+ if (grammarTag === TSX_TAG)
312
+ return 'typescript';
313
+ return grammarTag;
314
+ }
315
+ /**
316
+ * Walk every capture produced by the language query and split it
317
+ * into `Symbol` rows and `PendingEdge` entries. The capture-name
318
+ * convention is documented in each `.scm` file head; here we
319
+ * centralize the parsing of `@symbol.<kind>.def` /
320
+ * `@symbol.<kind>.name` / `@edge.<kind>.target` /
321
+ * `@edge.<kind>.from`.
322
+ *
323
+ * Scope is computed by walking up the syntax tree from the
324
+ * definition node and collecting the names of enclosing class /
325
+ * function / module declarations. The dotted form matches the
326
+ * convention in `types.ts:Symbol.scope`. Cost is bounded by tree
327
+ * depth, which is bounded by source nesting; on a 5K LOC file
328
+ * scope resolution is dominated by the query pass itself.
329
+ */
330
+ function extract(
331
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
332
+ rootNode,
333
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
334
+ query, file, grammarTag) {
335
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
336
+ const matches = query.matches(rootNode);
337
+ const symbols = [];
338
+ /**
339
+ * Map from def-node identity to the index in `symbols`. The same
340
+ * def may appear in multiple matches (a class with both an extends
341
+ * and implements clause); we dedupe to keep one Symbol row per
342
+ * declaration site.
343
+ */
344
+ const symbolByDefId = new Map();
345
+ /**
346
+ * Map from caller-side definition node id to the canonical name +
347
+ * scope pair. Used when a later @edge.calls.target capture lands
348
+ * inside that definition and we need to know who originated the
349
+ * edge.
350
+ */
351
+ const defContextByNodeId = new Map();
352
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
353
+ const collectSymbol = (defNode, nameNode, kind) => {
354
+ if (symbolByDefId.has(defNode.id))
355
+ return;
356
+ const scope = computeScope(defNode, grammarTag);
357
+ const symbol = {
358
+ name: nameNode.text,
359
+ kind,
360
+ file,
361
+ line: defNode.startPosition.row + 1,
362
+ column: defNode.startPosition.column,
363
+ scope,
364
+ };
365
+ const sig = trimSignature(defNode);
366
+ if (sig)
367
+ symbol.signature = sig;
368
+ symbolByDefId.set(defNode.id, symbols.length);
369
+ symbols.push(symbol);
370
+ defContextByNodeId.set(defNode.id, {
371
+ name: symbol.name,
372
+ scope: symbol.scope,
373
+ kind: symbol.kind,
374
+ });
375
+ };
376
+ for (const m of matches) {
377
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
378
+ const defs = {};
379
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
380
+ const names = {};
381
+ for (const cap of m.captures) {
382
+ const parts = cap.name.split('.');
383
+ if (parts[0] !== 'symbol' || parts.length < 3)
384
+ continue;
385
+ const kind = parts[1];
386
+ const role = parts[2];
387
+ if (role === 'def')
388
+ defs[kind] = cap.node;
389
+ else if (role === 'name')
390
+ names[kind] = cap.node;
391
+ }
392
+ for (const kind of Object.keys(defs)) {
393
+ const def = defs[kind];
394
+ const nm = names[kind];
395
+ if (!def || !nm)
396
+ continue;
397
+ if (!isSymbolKind(kind))
398
+ continue;
399
+ collectSymbol(def, nm, kind);
400
+ }
401
+ }
402
+ const pendingEdges = [];
403
+ for (const m of matches) {
404
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
405
+ const fromCaps = {};
406
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
407
+ const targetCaps = {};
408
+ for (const cap of m.captures) {
409
+ const parts = cap.name.split('.');
410
+ if (parts[0] !== 'edge' || parts.length < 3)
411
+ continue;
412
+ const kind = parts[1];
413
+ const role = parts[2];
414
+ if (role === 'from')
415
+ fromCaps[kind] = cap.node;
416
+ else if (role === 'target')
417
+ targetCaps[kind] = cap.node;
418
+ }
419
+ for (const kind of Object.keys(targetCaps)) {
420
+ const tgt = targetCaps[kind];
421
+ if (!tgt)
422
+ continue;
423
+ if (!isEdgeKind(kind))
424
+ continue;
425
+ const fromNode = fromCaps[kind];
426
+ let fromName;
427
+ let fromScope;
428
+ if (fromNode) {
429
+ fromName = fromNode.text;
430
+ fromScope = computeScope(fromNode, grammarTag);
431
+ }
432
+ else {
433
+ const ctx = findEnclosingDef(tgt, defContextByNodeId);
434
+ if (!ctx) {
435
+ // No tracked caller in this file - skip; the orchestrator
436
+ // can't store an orphan with no fromSymbolId. We could in
437
+ // theory emit a "file-level" edge, but the db schema does
438
+ // not model that today and PR L4 PageRank does not need it.
439
+ continue;
440
+ }
441
+ fromName = ctx.name;
442
+ fromScope = ctx.scope;
443
+ }
444
+ pendingEdges.push({
445
+ fromName,
446
+ fromScope,
447
+ toName: tgt.text,
448
+ kind,
449
+ line: tgt.startPosition.row + 1,
450
+ });
451
+ }
452
+ }
453
+ return { symbols, pendingEdges };
454
+ }
455
+ /**
456
+ * Walk parents until we hit a node that owns a tracked symbol. The
457
+ * map is keyed by `SyntaxNode.id`, which is stable within a tree.
458
+ */
459
+ function findEnclosingDef(
460
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
461
+ startNode, byId) {
462
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
463
+ let n = startNode.parent;
464
+ while (n) {
465
+ const ctx = byId.get(n.id);
466
+ if (ctx)
467
+ return ctx;
468
+ n = n.parent;
469
+ }
470
+ return null;
471
+ }
472
+ /**
473
+ * Walk parents to build a dotted scope path. We collect ancestor
474
+ * names for class / interface / function / method / module
475
+ * declarations. Cross-language node-type names diverge - the picker
476
+ * uses a small grammar-tagged switch to match the right node types.
477
+ */
478
+ function computeScope(
479
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
480
+ defNode, grammarTag) {
481
+ const names = [];
482
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
483
+ let n = defNode.parent;
484
+ while (n) {
485
+ const tag = scopeNameFor(n, grammarTag);
486
+ if (tag)
487
+ names.unshift(tag);
488
+ n = n.parent;
489
+ }
490
+ return names.join(grammarTag === 'rust' ? '::' : '.');
491
+ }
492
+ /**
493
+ * Per-grammar lookup: given a syntax node, return the
494
+ * operator-facing name to contribute to scope, or null if this node
495
+ * is not a scope. Centralized here so adding a new grammar means
496
+ * appending one branch.
497
+ */
498
+ function scopeNameFor(
499
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
500
+ node, grammarTag) {
501
+ const type = node.type;
502
+ switch (grammarTag) {
503
+ case 'typescript':
504
+ case 'tsx':
505
+ case 'javascript':
506
+ if (type === 'class_declaration' ||
507
+ type === 'abstract_class_declaration' ||
508
+ type === 'interface_declaration' ||
509
+ type === 'function_declaration' ||
510
+ type === 'method_definition') {
511
+ return nodeFieldText(node, 'name');
512
+ }
513
+ return null;
514
+ case 'python':
515
+ if (type === 'class_definition' || type === 'function_definition') {
516
+ return nodeFieldText(node, 'name');
517
+ }
518
+ return null;
519
+ case 'go':
520
+ if (type === 'function_declaration' ||
521
+ type === 'method_declaration' ||
522
+ type === 'type_declaration') {
523
+ return nodeFieldText(node, 'name');
524
+ }
525
+ return null;
526
+ case 'rust':
527
+ if (type === 'mod_item' ||
528
+ type === 'function_item' ||
529
+ type === 'struct_item' ||
530
+ type === 'enum_item' ||
531
+ type === 'trait_item') {
532
+ return nodeFieldText(node, 'name');
533
+ }
534
+ return null;
535
+ default:
536
+ return null;
537
+ }
538
+ }
539
+ /**
540
+ * Extract `node.childForFieldName(field)?.text` defensively.
541
+ * Returns null if either the field is absent OR the child has no
542
+ * text. We do NOT throw; absent field names in tree-sitter happen
543
+ * frequently on partial trees and broken syntax.
544
+ */
545
+ function nodeFieldText(
546
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
547
+ node, field) {
548
+ if (typeof node.childForFieldName !== 'function')
549
+ return null;
550
+ const child = node.childForFieldName(field);
551
+ if (!child)
552
+ return null;
553
+ const txt = child.text;
554
+ return typeof txt === 'string' && txt.length > 0 ? txt : null;
555
+ }
556
+ /**
557
+ * Cap signature snippets to the first line, trimmed to 120 chars.
558
+ * The FTS5 column does not need full bodies; readers ask for the
559
+ * file and line instead. Keeps storage flat.
560
+ */
561
+ function trimSignature(
562
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
563
+ defNode) {
564
+ const text = defNode.text;
565
+ if (typeof text !== 'string' || text.length === 0)
566
+ return null;
567
+ const firstLine = text.split(/\r?\n/, 1)[0]?.trim() ?? '';
568
+ if (firstLine.length === 0)
569
+ return null;
570
+ if (firstLine.length <= 120)
571
+ return firstLine;
572
+ return `${firstLine.slice(0, 117)}...`;
573
+ }
574
+ function countLines(s) {
575
+ let n = 1;
576
+ for (let i = 0; i < s.length; i += 1) {
577
+ if (s.charCodeAt(i) === 10)
578
+ n += 1;
579
+ }
580
+ return n;
581
+ }
582
+ function isSymbolKind(s) {
583
+ return (s === 'function' ||
584
+ s === 'class' ||
585
+ s === 'method' ||
586
+ s === 'interface' ||
587
+ s === 'type' ||
588
+ s === 'variable' ||
589
+ s === 'import');
590
+ }
591
+ function isEdgeKind(s) {
592
+ return (s === 'calls' ||
593
+ s === 'extends' ||
594
+ s === 'implements' ||
595
+ s === 'imports' ||
596
+ s === 'references');
597
+ }
598
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1,57 @@
1
+ ; Go symbol + edge query - used by core/codegraph/parser.ts.
2
+ ;
3
+ ; SymbolKind coverage:
4
+ ; function - function_declaration at file top level
5
+ ; method - method_declaration (receiver-attached)
6
+ ; type - type_declaration (struct, alias, interface base)
7
+ ; interface - type_declaration whose underlying type is interface_type
8
+ ; variable - top-level var / const single-identifier binding
9
+ ; import - import_spec path string OR alias identifier
10
+ ;
11
+ ; EdgeKind coverage:
12
+ ; calls - call_expression with identifier OR selector
13
+ ; implements - Go has no `implements` keyword; satisfaction is
14
+ ; structural. We do NOT emit implements edges for Go.
15
+
16
+ (function_declaration
17
+ name: (identifier) @symbol.function.name) @symbol.function.def
18
+
19
+ (method_declaration
20
+ name: (field_identifier) @symbol.method.name) @symbol.method.def
21
+
22
+ ; `type Foo struct { ... }` / `type Foo interface { ... }` / `type Foo = X`
23
+ (type_declaration
24
+ (type_spec
25
+ name: (type_identifier) @symbol.type.name)) @symbol.type.def
26
+
27
+ (type_declaration
28
+ (type_spec
29
+ name: (type_identifier) @symbol.interface.name
30
+ type: (interface_type))) @symbol.interface.def
31
+
32
+ ; Top-level var / const - single-identifier specs only to dodge noise.
33
+ (var_declaration
34
+ (var_spec
35
+ name: (identifier) @symbol.variable.name)) @symbol.variable.def
36
+
37
+ (const_declaration
38
+ (const_spec
39
+ name: (identifier) @symbol.variable.name)) @symbol.variable.def
40
+
41
+ ; Imports: `import "fmt"` / `import f "fmt"`. We keep both the quoted
42
+ ; path and the alias identifier as the symbol name. Reviewer note: the
43
+ ; quoted form (with double quotes) matches what Go editor tooling
44
+ ; surfaces - we keep it as-is.
45
+ (import_spec
46
+ path: (interpreted_string_literal) @symbol.import.name) @symbol.import.def
47
+
48
+ (import_spec
49
+ name: (package_identifier) @symbol.import.name) @symbol.import.def
50
+
51
+ ; Calls: bare and selector.
52
+ (call_expression
53
+ function: (identifier) @edge.calls.target)
54
+
55
+ (call_expression
56
+ function: (selector_expression
57
+ field: (field_identifier) @edge.calls.target))