cgraphx 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +243 -0
- package/dist/.claude-template/commands/my-commit.md +9 -0
- package/dist/.claude-template/commands/my-query.md +4 -0
- package/dist/.claude-template/hooks/context-monitor/context-monitor.cjs +216 -0
- package/dist/.claude-template/plugins/claude-hud/dist/claude-config-dir.d.ts +4 -0
- package/dist/.claude-template/plugins/claude-hud/dist/claude-config-dir.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/claude-config-dir.js +24 -0
- package/dist/.claude-template/plugins/claude-hud/dist/claude-config-dir.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/config-reader.d.ts +8 -0
- package/dist/.claude-template/plugins/claude-hud/dist/config-reader.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/config-reader.js +204 -0
- package/dist/.claude-template/plugins/claude-hud/dist/config-reader.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/config.d.ts +46 -0
- package/dist/.claude-template/plugins/claude-hud/dist/config.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/config.js +220 -0
- package/dist/.claude-template/plugins/claude-hud/dist/config.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/constants.d.ts +10 -0
- package/dist/.claude-template/plugins/claude-hud/dist/constants.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/constants.js +10 -0
- package/dist/.claude-template/plugins/claude-hud/dist/constants.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/debug.d.ts +6 -0
- package/dist/.claude-template/plugins/claude-hud/dist/debug.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/debug.js +15 -0
- package/dist/.claude-template/plugins/claude-hud/dist/debug.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/extra-cmd.d.ts +23 -0
- package/dist/.claude-template/plugins/claude-hud/dist/extra-cmd.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/extra-cmd.js +103 -0
- package/dist/.claude-template/plugins/claude-hud/dist/extra-cmd.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/git.d.ts +16 -0
- package/dist/.claude-template/plugins/claude-hud/dist/git.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/git.js +86 -0
- package/dist/.claude-template/plugins/claude-hud/dist/git.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/index.d.ts +24 -0
- package/dist/.claude-template/plugins/claude-hud/dist/index.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/index.js +97 -0
- package/dist/.claude-template/plugins/claude-hud/dist/index.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/agents-line.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/agents-line.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/agents-line.js +44 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/agents-line.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/colors.d.ts +12 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/colors.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/colors.js +58 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/colors.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/index.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/index.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/index.js +379 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/index.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/environment.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/environment.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/environment.js +30 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/environment.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/identity.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/identity.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/identity.js +52 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/identity.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/index.d.ts +5 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/index.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/index.js +5 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/index.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/project.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/project.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/project.js +74 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/project.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/usage.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/usage.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/usage.js +92 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/lines/usage.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/session-line.d.ts +7 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/session-line.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/session-line.js +247 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/session-line.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/todos-line.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/todos-line.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/todos-line.js +25 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/todos-line.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/tools-line.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/tools-line.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/tools-line.js +43 -0
- package/dist/.claude-template/plugins/claude-hud/dist/render/tools-line.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/speed-tracker.d.ts +7 -0
- package/dist/.claude-template/plugins/claude-hud/dist/speed-tracker.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/speed-tracker.js +62 -0
- package/dist/.claude-template/plugins/claude-hud/dist/speed-tracker.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/stdin.d.ts +9 -0
- package/dist/.claude-template/plugins/claude-hud/dist/stdin.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/stdin.js +136 -0
- package/dist/.claude-template/plugins/claude-hud/dist/stdin.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/transcript.d.ts +3 -0
- package/dist/.claude-template/plugins/claude-hud/dist/transcript.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/transcript.js +189 -0
- package/dist/.claude-template/plugins/claude-hud/dist/transcript.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/types.d.ts +79 -0
- package/dist/.claude-template/plugins/claude-hud/dist/types.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/types.js +5 -0
- package/dist/.claude-template/plugins/claude-hud/dist/types.js.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/usage-api.d.ts +59 -0
- package/dist/.claude-template/plugins/claude-hud/dist/usage-api.d.ts.map +1 -0
- package/dist/.claude-template/plugins/claude-hud/dist/usage-api.js +733 -0
- package/dist/.claude-template/plugins/claude-hud/dist/usage-api.js.map +1 -0
- package/dist/.claude-template/skills/cgraphx/SKILL.md +143 -0
- package/dist/.claude-template/skills/cgraphx/agent-prompt.md +56 -0
- package/dist/.claude-template/skills/clarify-requirements/SKILL.md +425 -0
- package/dist/.claude-template/skills/code-impact-api/SKILL.md +143 -0
- package/dist/.claude-template/skills/code-impact-api/agent-prompt.md +51 -0
- package/dist/.claude-template/skills/code-impact-docgen/SKILL.md +366 -0
- package/dist/.claude-template/skills/code-impact-docgen/template-business-html.md +242 -0
- package/dist/.claude-template/skills/code-impact-docgen/template-business-md.md +107 -0
- package/dist/.claude-template/skills/code-impact-docgen/template-technical-html.md +205 -0
- package/dist/.claude-template/skills/code-impact-docgen/template-technical-md.md +155 -0
- package/dist/.claude-template/skills/code-impact-init/SKILL.md +800 -0
- package/dist/.claude-template/skills/code-impact-markdown/SKILL.md +345 -0
- package/dist/.claude-template/skills/code-impact-markdown/template-guide.md +68 -0
- package/dist/.claude-template/skills/code-impact-markdown/template-memory.md +82 -0
- package/dist/.claude-template/skills/code-impact-markdown/template-runbook.md +58 -0
- package/dist/.claude-template/skills/db-query/SKILL.md +166 -0
- package/dist/.claude-template/skills/db-query/agent-prompt.md +55 -0
- package/dist/.claude-template/skills/developer-timeline/SKILL.md +302 -0
- package/dist/.claude-template/skills/developer-timeline/demo-single-page-report.html +657 -0
- package/dist/.claude-template/skills/implementation/SKILL.md +136 -0
- package/dist/.claude-template/skills/subagent-implement/SKILL.md +225 -0
- package/dist/.claude-template/skills/subagent-implement/implementer-prompt.md +127 -0
- package/dist/.claude-template/skills/subagent-implement/quality-reviewer-prompt.md +130 -0
- package/dist/.claude-template/skills/subagent-implement/spec-reviewer-prompt.md +112 -0
- package/dist/.claude-template/skills/write-plan/SKILL.md +322 -0
- package/dist/.claude-template/skills/write-plan/plan-document-reviewer-prompt.md +134 -0
- package/dist/.claude-template/skills/write-prd/SKILL.md +242 -0
- package/dist/.claude-template/skills/write-spec/SKILL.md +278 -0
- package/dist/bin/codegraph.d.ts +26 -0
- package/dist/bin/codegraph.d.ts.map +1 -0
- package/dist/bin/codegraph.js +2014 -0
- package/dist/bin/codegraph.js.map +1 -0
- package/dist/bin/fatal-handler.d.ts +20 -0
- package/dist/bin/fatal-handler.d.ts.map +1 -0
- package/dist/bin/fatal-handler.js +118 -0
- package/dist/bin/fatal-handler.js.map +1 -0
- package/dist/bin/node-version-check.d.ts +51 -0
- package/dist/bin/node-version-check.d.ts.map +1 -0
- package/dist/bin/node-version-check.js +114 -0
- package/dist/bin/node-version-check.js.map +1 -0
- package/dist/bin/uninstall.d.ts +14 -0
- package/dist/bin/uninstall.d.ts.map +1 -0
- package/dist/bin/uninstall.js +36 -0
- package/dist/bin/uninstall.js.map +1 -0
- package/dist/context/formatter.d.ts +30 -0
- package/dist/context/formatter.d.ts.map +1 -0
- package/dist/context/formatter.js +263 -0
- package/dist/context/formatter.js.map +1 -0
- package/dist/context/index.d.ts +119 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +1296 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/markers.d.ts +19 -0
- package/dist/context/markers.d.ts.map +1 -0
- package/dist/context/markers.js +22 -0
- package/dist/context/markers.js.map +1 -0
- package/dist/db/index.d.ts +122 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +296 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +44 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +140 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/queries.d.ts +401 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +1591 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.sql +152 -0
- package/dist/db/sqlite-adapter.d.ts +53 -0
- package/dist/db/sqlite-adapter.d.ts.map +1 -0
- package/dist/db/sqlite-adapter.js +117 -0
- package/dist/db/sqlite-adapter.js.map +1 -0
- package/dist/dbquery/cli.d.ts +17 -0
- package/dist/dbquery/cli.d.ts.map +1 -0
- package/dist/dbquery/cli.js +229 -0
- package/dist/dbquery/cli.js.map +1 -0
- package/dist/dbquery/config.d.ts +38 -0
- package/dist/dbquery/config.d.ts.map +1 -0
- package/dist/dbquery/config.js +244 -0
- package/dist/dbquery/config.js.map +1 -0
- package/dist/dbquery/constants.d.ts +40 -0
- package/dist/dbquery/constants.d.ts.map +1 -0
- package/dist/dbquery/constants.js +65 -0
- package/dist/dbquery/constants.js.map +1 -0
- package/dist/dbquery/drivers/mysql.d.ts +15 -0
- package/dist/dbquery/drivers/mysql.d.ts.map +1 -0
- package/dist/dbquery/drivers/mysql.js +102 -0
- package/dist/dbquery/drivers/mysql.js.map +1 -0
- package/dist/dbquery/drivers/postgres.d.ts +16 -0
- package/dist/dbquery/drivers/postgres.d.ts.map +1 -0
- package/dist/dbquery/drivers/postgres.js +105 -0
- package/dist/dbquery/drivers/postgres.js.map +1 -0
- package/dist/dbquery/errors.d.ts +40 -0
- package/dist/dbquery/errors.d.ts.map +1 -0
- package/dist/dbquery/errors.js +85 -0
- package/dist/dbquery/errors.js.map +1 -0
- package/dist/dbquery/executor.d.ts +30 -0
- package/dist/dbquery/executor.d.ts.map +1 -0
- package/dist/dbquery/executor.js +243 -0
- package/dist/dbquery/executor.js.map +1 -0
- package/dist/dbquery/format.d.ts +18 -0
- package/dist/dbquery/format.d.ts.map +1 -0
- package/dist/dbquery/format.js +174 -0
- package/dist/dbquery/format.js.map +1 -0
- package/dist/dbquery/index.d.ts +10 -0
- package/dist/dbquery/index.d.ts.map +1 -0
- package/dist/dbquery/index.js +23 -0
- package/dist/dbquery/index.js.map +1 -0
- package/dist/dbquery/init.d.ts +33 -0
- package/dist/dbquery/init.d.ts.map +1 -0
- package/dist/dbquery/init.js +125 -0
- package/dist/dbquery/init.js.map +1 -0
- package/dist/dbquery/logging.d.ts +22 -0
- package/dist/dbquery/logging.d.ts.map +1 -0
- package/dist/dbquery/logging.js +140 -0
- package/dist/dbquery/logging.js.map +1 -0
- package/dist/dbquery/mcp-tools.d.ts +29 -0
- package/dist/dbquery/mcp-tools.d.ts.map +1 -0
- package/dist/dbquery/mcp-tools.js +206 -0
- package/dist/dbquery/mcp-tools.js.map +1 -0
- package/dist/dbquery/queries.d.ts +31 -0
- package/dist/dbquery/queries.d.ts.map +1 -0
- package/dist/dbquery/queries.js +160 -0
- package/dist/dbquery/queries.js.map +1 -0
- package/dist/dbquery/safety.d.ts +35 -0
- package/dist/dbquery/safety.d.ts.map +1 -0
- package/dist/dbquery/safety.js +306 -0
- package/dist/dbquery/safety.js.map +1 -0
- package/dist/dbquery/types.d.ts +152 -0
- package/dist/dbquery/types.d.ts.map +1 -0
- package/dist/dbquery/types.js +10 -0
- package/dist/dbquery/types.js.map +1 -0
- package/dist/directory.d.ts +147 -0
- package/dist/directory.d.ts.map +1 -0
- package/dist/directory.js +523 -0
- package/dist/directory.js.map +1 -0
- package/dist/errors.d.ts +136 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +219 -0
- package/dist/errors.js.map +1 -0
- package/dist/extraction/astro-extractor.d.ts +79 -0
- package/dist/extraction/astro-extractor.d.ts.map +1 -0
- package/dist/extraction/astro-extractor.js +320 -0
- package/dist/extraction/astro-extractor.js.map +1 -0
- package/dist/extraction/dfm-extractor.d.ts +31 -0
- package/dist/extraction/dfm-extractor.d.ts.map +1 -0
- package/dist/extraction/dfm-extractor.js +151 -0
- package/dist/extraction/dfm-extractor.js.map +1 -0
- package/dist/extraction/extraction-version.d.ts +25 -0
- package/dist/extraction/extraction-version.d.ts.map +1 -0
- package/dist/extraction/extraction-version.js +28 -0
- package/dist/extraction/extraction-version.js.map +1 -0
- package/dist/extraction/function-ref.d.ts +118 -0
- package/dist/extraction/function-ref.d.ts.map +1 -0
- package/dist/extraction/function-ref.js +727 -0
- package/dist/extraction/function-ref.js.map +1 -0
- package/dist/extraction/generated-detection.d.ts +30 -0
- package/dist/extraction/generated-detection.d.ts.map +1 -0
- package/dist/extraction/generated-detection.js +83 -0
- package/dist/extraction/generated-detection.js.map +1 -0
- package/dist/extraction/grammars.d.ts +114 -0
- package/dist/extraction/grammars.d.ts.map +1 -0
- package/dist/extraction/grammars.js +477 -0
- package/dist/extraction/grammars.js.map +1 -0
- package/dist/extraction/index.d.ts +175 -0
- package/dist/extraction/index.d.ts.map +1 -0
- package/dist/extraction/index.js +1887 -0
- package/dist/extraction/index.js.map +1 -0
- package/dist/extraction/languages/c-cpp.d.ts +12 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -0
- package/dist/extraction/languages/c-cpp.js +275 -0
- package/dist/extraction/languages/c-cpp.js.map +1 -0
- package/dist/extraction/languages/csharp.d.ts +25 -0
- package/dist/extraction/languages/csharp.d.ts.map +1 -0
- package/dist/extraction/languages/csharp.js +175 -0
- package/dist/extraction/languages/csharp.js.map +1 -0
- package/dist/extraction/languages/dart.d.ts +3 -0
- package/dist/extraction/languages/dart.d.ts.map +1 -0
- package/dist/extraction/languages/dart.js +374 -0
- package/dist/extraction/languages/dart.js.map +1 -0
- package/dist/extraction/languages/go.d.ts +3 -0
- package/dist/extraction/languages/go.d.ts.map +1 -0
- package/dist/extraction/languages/go.js +111 -0
- package/dist/extraction/languages/go.js.map +1 -0
- package/dist/extraction/languages/index.d.ts +10 -0
- package/dist/extraction/languages/index.d.ts.map +1 -0
- package/dist/extraction/languages/index.js +53 -0
- package/dist/extraction/languages/index.js.map +1 -0
- package/dist/extraction/languages/java.d.ts +3 -0
- package/dist/extraction/languages/java.d.ts.map +1 -0
- package/dist/extraction/languages/java.js +315 -0
- package/dist/extraction/languages/java.js.map +1 -0
- package/dist/extraction/languages/javascript.d.ts +3 -0
- package/dist/extraction/languages/javascript.d.ts.map +1 -0
- package/dist/extraction/languages/javascript.js +106 -0
- package/dist/extraction/languages/javascript.js.map +1 -0
- package/dist/extraction/languages/kotlin.d.ts +3 -0
- package/dist/extraction/languages/kotlin.d.ts.map +1 -0
- package/dist/extraction/languages/kotlin.js +379 -0
- package/dist/extraction/languages/kotlin.js.map +1 -0
- package/dist/extraction/languages/lua.d.ts +3 -0
- package/dist/extraction/languages/lua.d.ts.map +1 -0
- package/dist/extraction/languages/lua.js +150 -0
- package/dist/extraction/languages/lua.js.map +1 -0
- package/dist/extraction/languages/luau.d.ts +3 -0
- package/dist/extraction/languages/luau.d.ts.map +1 -0
- package/dist/extraction/languages/luau.js +37 -0
- package/dist/extraction/languages/luau.js.map +1 -0
- package/dist/extraction/languages/objc.d.ts +3 -0
- package/dist/extraction/languages/objc.d.ts.map +1 -0
- package/dist/extraction/languages/objc.js +175 -0
- package/dist/extraction/languages/objc.js.map +1 -0
- package/dist/extraction/languages/pascal.d.ts +3 -0
- package/dist/extraction/languages/pascal.d.ts.map +1 -0
- package/dist/extraction/languages/pascal.js +77 -0
- package/dist/extraction/languages/pascal.js.map +1 -0
- package/dist/extraction/languages/php.d.ts +3 -0
- package/dist/extraction/languages/php.d.ts.map +1 -0
- package/dist/extraction/languages/php.js +196 -0
- package/dist/extraction/languages/php.js.map +1 -0
- package/dist/extraction/languages/python.d.ts +3 -0
- package/dist/extraction/languages/python.d.ts.map +1 -0
- package/dist/extraction/languages/python.js +56 -0
- package/dist/extraction/languages/python.js.map +1 -0
- package/dist/extraction/languages/r.d.ts +3 -0
- package/dist/extraction/languages/r.d.ts.map +1 -0
- package/dist/extraction/languages/r.js +314 -0
- package/dist/extraction/languages/r.js.map +1 -0
- package/dist/extraction/languages/ruby.d.ts +3 -0
- package/dist/extraction/languages/ruby.d.ts.map +1 -0
- package/dist/extraction/languages/ruby.js +149 -0
- package/dist/extraction/languages/ruby.js.map +1 -0
- package/dist/extraction/languages/rust.d.ts +3 -0
- package/dist/extraction/languages/rust.d.ts.map +1 -0
- package/dist/extraction/languages/rust.js +142 -0
- package/dist/extraction/languages/rust.js.map +1 -0
- package/dist/extraction/languages/scala.d.ts +3 -0
- package/dist/extraction/languages/scala.d.ts.map +1 -0
- package/dist/extraction/languages/scala.js +209 -0
- package/dist/extraction/languages/scala.js.map +1 -0
- package/dist/extraction/languages/swift.d.ts +3 -0
- package/dist/extraction/languages/swift.d.ts.map +1 -0
- package/dist/extraction/languages/swift.js +152 -0
- package/dist/extraction/languages/swift.js.map +1 -0
- package/dist/extraction/languages/typescript.d.ts +16 -0
- package/dist/extraction/languages/typescript.d.ts.map +1 -0
- package/dist/extraction/languages/typescript.js +167 -0
- package/dist/extraction/languages/typescript.js.map +1 -0
- package/dist/extraction/liquid-extractor.d.ts +59 -0
- package/dist/extraction/liquid-extractor.d.ts.map +1 -0
- package/dist/extraction/liquid-extractor.js +357 -0
- package/dist/extraction/liquid-extractor.js.map +1 -0
- package/dist/extraction/mybatis-extractor.d.ts +48 -0
- package/dist/extraction/mybatis-extractor.d.ts.map +1 -0
- package/dist/extraction/mybatis-extractor.js +198 -0
- package/dist/extraction/mybatis-extractor.js.map +1 -0
- package/dist/extraction/parse-worker.d.ts +8 -0
- package/dist/extraction/parse-worker.d.ts.map +1 -0
- package/dist/extraction/parse-worker.js +97 -0
- package/dist/extraction/parse-worker.js.map +1 -0
- package/dist/extraction/razor-extractor.d.ts +42 -0
- package/dist/extraction/razor-extractor.d.ts.map +1 -0
- package/dist/extraction/razor-extractor.js +285 -0
- package/dist/extraction/razor-extractor.js.map +1 -0
- package/dist/extraction/svelte-extractor.d.ts +56 -0
- package/dist/extraction/svelte-extractor.d.ts.map +1 -0
- package/dist/extraction/svelte-extractor.js +275 -0
- package/dist/extraction/svelte-extractor.js.map +1 -0
- package/dist/extraction/tree-sitter-helpers.d.ts +28 -0
- package/dist/extraction/tree-sitter-helpers.d.ts.map +1 -0
- package/dist/extraction/tree-sitter-helpers.js +152 -0
- package/dist/extraction/tree-sitter-helpers.js.map +1 -0
- package/dist/extraction/tree-sitter-types.d.ts +239 -0
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -0
- package/dist/extraction/tree-sitter-types.js +10 -0
- package/dist/extraction/tree-sitter-types.js.map +1 -0
- package/dist/extraction/tree-sitter.d.ts +647 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -0
- package/dist/extraction/tree-sitter.js +5592 -0
- package/dist/extraction/tree-sitter.js.map +1 -0
- package/dist/extraction/vue-extractor.d.ts +51 -0
- package/dist/extraction/vue-extractor.d.ts.map +1 -0
- package/dist/extraction/vue-extractor.js +254 -0
- package/dist/extraction/vue-extractor.js.map +1 -0
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-luau.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/dist/extraction/wasm-runtime-flags.d.ts +38 -0
- package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -0
- package/dist/extraction/wasm-runtime-flags.js +106 -0
- package/dist/extraction/wasm-runtime-flags.js.map +1 -0
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +13 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/queries.d.ts +106 -0
- package/dist/graph/queries.d.ts.map +1 -0
- package/dist/graph/queries.js +339 -0
- package/dist/graph/queries.js.map +1 -0
- package/dist/graph/traversal.d.ts +127 -0
- package/dist/graph/traversal.d.ts.map +1 -0
- package/dist/graph/traversal.js +540 -0
- package/dist/graph/traversal.js.map +1 -0
- package/dist/index.d.ts +563 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1041 -0
- package/dist/index.js.map +1 -0
- package/dist/installer/claude-assets.d.ts +45 -0
- package/dist/installer/claude-assets.d.ts.map +1 -0
- package/dist/installer/claude-assets.js +144 -0
- package/dist/installer/claude-assets.js.map +1 -0
- package/dist/installer/config-writer.d.ts +28 -0
- package/dist/installer/config-writer.d.ts.map +1 -0
- package/dist/installer/config-writer.js +91 -0
- package/dist/installer/config-writer.js.map +1 -0
- package/dist/installer/index.d.ts +101 -0
- package/dist/installer/index.d.ts.map +1 -0
- package/dist/installer/index.js +692 -0
- package/dist/installer/index.js.map +1 -0
- package/dist/installer/instructions-template.d.ts +41 -0
- package/dist/installer/instructions-template.d.ts.map +1 -0
- package/dist/installer/instructions-template.js +53 -0
- package/dist/installer/instructions-template.js.map +1 -0
- package/dist/installer/targets/antigravity.d.ts +57 -0
- package/dist/installer/targets/antigravity.d.ts.map +1 -0
- package/dist/installer/targets/antigravity.js +308 -0
- package/dist/installer/targets/antigravity.js.map +1 -0
- package/dist/installer/targets/claude.d.ts +66 -0
- package/dist/installer/targets/claude.d.ts.map +1 -0
- package/dist/installer/targets/claude.js +564 -0
- package/dist/installer/targets/claude.js.map +1 -0
- package/dist/installer/targets/codex.d.ts +18 -0
- package/dist/installer/targets/codex.d.ts.map +1 -0
- package/dist/installer/targets/codex.js +185 -0
- package/dist/installer/targets/codex.js.map +1 -0
- package/dist/installer/targets/cursor.d.ts +35 -0
- package/dist/installer/targets/cursor.d.ts.map +1 -0
- package/dist/installer/targets/cursor.js +254 -0
- package/dist/installer/targets/cursor.js.map +1 -0
- package/dist/installer/targets/gemini.d.ts +26 -0
- package/dist/installer/targets/gemini.d.ts.map +1 -0
- package/dist/installer/targets/gemini.js +165 -0
- package/dist/installer/targets/gemini.js.map +1 -0
- package/dist/installer/targets/hermes.d.ts +18 -0
- package/dist/installer/targets/hermes.d.ts.map +1 -0
- package/dist/installer/targets/hermes.js +359 -0
- package/dist/installer/targets/hermes.js.map +1 -0
- package/dist/installer/targets/kiro.d.ts +27 -0
- package/dist/installer/targets/kiro.d.ts.map +1 -0
- package/dist/installer/targets/kiro.js +178 -0
- package/dist/installer/targets/kiro.js.map +1 -0
- package/dist/installer/targets/opencode.d.ts +38 -0
- package/dist/installer/targets/opencode.d.ts.map +1 -0
- package/dist/installer/targets/opencode.js +288 -0
- package/dist/installer/targets/opencode.js.map +1 -0
- package/dist/installer/targets/registry.d.ts +35 -0
- package/dist/installer/targets/registry.d.ts.map +1 -0
- package/dist/installer/targets/registry.js +91 -0
- package/dist/installer/targets/registry.js.map +1 -0
- package/dist/installer/targets/shared.d.ts +101 -0
- package/dist/installer/targets/shared.d.ts.map +1 -0
- package/dist/installer/targets/shared.js +264 -0
- package/dist/installer/targets/shared.js.map +1 -0
- package/dist/installer/targets/toml.d.ts +52 -0
- package/dist/installer/targets/toml.d.ts.map +1 -0
- package/dist/installer/targets/toml.js +147 -0
- package/dist/installer/targets/toml.js.map +1 -0
- package/dist/installer/targets/types.d.ts +108 -0
- package/dist/installer/targets/types.d.ts.map +1 -0
- package/dist/installer/targets/types.js +16 -0
- package/dist/installer/targets/types.js.map +1 -0
- package/dist/markdown/cli.d.ts +16 -0
- package/dist/markdown/cli.d.ts.map +1 -0
- package/dist/markdown/cli.js +533 -0
- package/dist/markdown/cli.js.map +1 -0
- package/dist/markdown/constants.d.ts +22 -0
- package/dist/markdown/constants.d.ts.map +1 -0
- package/dist/markdown/constants.js +71 -0
- package/dist/markdown/constants.js.map +1 -0
- package/dist/markdown/dedup.d.ts +20 -0
- package/dist/markdown/dedup.d.ts.map +1 -0
- package/dist/markdown/dedup.js +64 -0
- package/dist/markdown/dedup.js.map +1 -0
- package/dist/markdown/errors.d.ts +22 -0
- package/dist/markdown/errors.d.ts.map +1 -0
- package/dist/markdown/errors.js +45 -0
- package/dist/markdown/errors.js.map +1 -0
- package/dist/markdown/extractor.d.ts +43 -0
- package/dist/markdown/extractor.d.ts.map +1 -0
- package/dist/markdown/extractor.js +152 -0
- package/dist/markdown/extractor.js.map +1 -0
- package/dist/markdown/frontmatter-parser.d.ts +47 -0
- package/dist/markdown/frontmatter-parser.d.ts.map +1 -0
- package/dist/markdown/frontmatter-parser.js +199 -0
- package/dist/markdown/frontmatter-parser.js.map +1 -0
- package/dist/markdown/indexer.d.ts +34 -0
- package/dist/markdown/indexer.d.ts.map +1 -0
- package/dist/markdown/indexer.js +256 -0
- package/dist/markdown/indexer.js.map +1 -0
- package/dist/markdown/mcp-tools.d.ts +33 -0
- package/dist/markdown/mcp-tools.d.ts.map +1 -0
- package/dist/markdown/mcp-tools.js +300 -0
- package/dist/markdown/mcp-tools.js.map +1 -0
- package/dist/markdown/query.d.ts +108 -0
- package/dist/markdown/query.d.ts.map +1 -0
- package/dist/markdown/query.js +570 -0
- package/dist/markdown/query.js.map +1 -0
- package/dist/markdown/schema-bootstrap.d.ts +40 -0
- package/dist/markdown/schema-bootstrap.d.ts.map +1 -0
- package/dist/markdown/schema-bootstrap.js +85 -0
- package/dist/markdown/schema-bootstrap.js.map +1 -0
- package/dist/markdown/schema.sql +124 -0
- package/dist/markdown/store.d.ts +77 -0
- package/dist/markdown/store.d.ts.map +1 -0
- package/dist/markdown/store.js +194 -0
- package/dist/markdown/store.js.map +1 -0
- package/dist/markdown/summary-extractor.d.ts +22 -0
- package/dist/markdown/summary-extractor.d.ts.map +1 -0
- package/dist/markdown/summary-extractor.js +66 -0
- package/dist/markdown/summary-extractor.js.map +1 -0
- package/dist/markdown/types.d.ts +159 -0
- package/dist/markdown/types.d.ts.map +1 -0
- package/dist/markdown/types.js +9 -0
- package/dist/markdown/types.js.map +1 -0
- package/dist/markdown/validator.d.ts +44 -0
- package/dist/markdown/validator.d.ts.map +1 -0
- package/dist/markdown/validator.js +95 -0
- package/dist/markdown/validator.js.map +1 -0
- package/dist/mcp/daemon-manager.d.ts +42 -0
- package/dist/mcp/daemon-manager.d.ts.map +1 -0
- package/dist/mcp/daemon-manager.js +129 -0
- package/dist/mcp/daemon-manager.js.map +1 -0
- package/dist/mcp/daemon-paths.d.ts +46 -0
- package/dist/mcp/daemon-paths.d.ts.map +1 -0
- package/dist/mcp/daemon-paths.js +125 -0
- package/dist/mcp/daemon-paths.js.map +1 -0
- package/dist/mcp/daemon-registry.d.ts +47 -0
- package/dist/mcp/daemon-registry.d.ts.map +1 -0
- package/dist/mcp/daemon-registry.js +229 -0
- package/dist/mcp/daemon-registry.js.map +1 -0
- package/dist/mcp/daemon.d.ts +220 -0
- package/dist/mcp/daemon.d.ts.map +1 -0
- package/dist/mcp/daemon.js +637 -0
- package/dist/mcp/daemon.js.map +1 -0
- package/dist/mcp/dynamic-boundaries.d.ts +41 -0
- package/dist/mcp/dynamic-boundaries.d.ts.map +1 -0
- package/dist/mcp/dynamic-boundaries.js +359 -0
- package/dist/mcp/dynamic-boundaries.js.map +1 -0
- package/dist/mcp/engine.d.ts +105 -0
- package/dist/mcp/engine.d.ts.map +1 -0
- package/dist/mcp/engine.js +278 -0
- package/dist/mcp/engine.js.map +1 -0
- package/dist/mcp/index.d.ts +113 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +499 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/liveness-watchdog.d.ts +18 -0
- package/dist/mcp/liveness-watchdog.d.ts.map +1 -0
- package/dist/mcp/liveness-watchdog.js +207 -0
- package/dist/mcp/liveness-watchdog.js.map +1 -0
- package/dist/mcp/ppid-watchdog.d.ts +44 -0
- package/dist/mcp/ppid-watchdog.d.ts.map +1 -0
- package/dist/mcp/ppid-watchdog.js +27 -0
- package/dist/mcp/ppid-watchdog.js.map +1 -0
- package/dist/mcp/proxy.d.ts +87 -0
- package/dist/mcp/proxy.d.ts.map +1 -0
- package/dist/mcp/proxy.js +641 -0
- package/dist/mcp/proxy.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +34 -0
- package/dist/mcp/server-instructions.d.ts.map +1 -0
- package/dist/mcp/server-instructions.js +106 -0
- package/dist/mcp/server-instructions.js.map +1 -0
- package/dist/mcp/session.d.ts +79 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +330 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/stdin-teardown.d.ts +27 -0
- package/dist/mcp/stdin-teardown.d.ts.map +1 -0
- package/dist/mcp/stdin-teardown.js +49 -0
- package/dist/mcp/stdin-teardown.js.map +1 -0
- package/dist/mcp/tools.d.ts +547 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +4122 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/transport.d.ts +188 -0
- package/dist/mcp/transport.d.ts.map +1 -0
- package/dist/mcp/transport.js +359 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/mcp/version.d.ts +19 -0
- package/dist/mcp/version.d.ts.map +1 -0
- package/dist/mcp/version.js +71 -0
- package/dist/mcp/version.js.map +1 -0
- package/dist/project-config.d.ts +36 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +235 -0
- package/dist/project-config.js.map +1 -0
- package/dist/reasoning/config.d.ts +45 -0
- package/dist/reasoning/config.d.ts.map +1 -0
- package/dist/reasoning/config.js +171 -0
- package/dist/reasoning/config.js.map +1 -0
- package/dist/reasoning/credentials.d.ts +5 -0
- package/dist/reasoning/credentials.d.ts.map +1 -0
- package/dist/reasoning/credentials.js +83 -0
- package/dist/reasoning/credentials.js.map +1 -0
- package/dist/reasoning/login.d.ts +21 -0
- package/dist/reasoning/login.d.ts.map +1 -0
- package/dist/reasoning/login.js +85 -0
- package/dist/reasoning/login.js.map +1 -0
- package/dist/reasoning/reasoner.d.ts +43 -0
- package/dist/reasoning/reasoner.d.ts.map +1 -0
- package/dist/reasoning/reasoner.js +308 -0
- package/dist/reasoning/reasoner.js.map +1 -0
- package/dist/resolution/c-fnptr-synthesizer.d.ts +33 -0
- package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -0
- package/dist/resolution/c-fnptr-synthesizer.js +352 -0
- package/dist/resolution/c-fnptr-synthesizer.js.map +1 -0
- package/dist/resolution/callback-synthesizer.d.ts +15 -0
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -0
- package/dist/resolution/callback-synthesizer.js +2926 -0
- package/dist/resolution/callback-synthesizer.js.map +1 -0
- package/dist/resolution/frameworks/astro.d.ts +9 -0
- package/dist/resolution/frameworks/astro.d.ts.map +1 -0
- package/dist/resolution/frameworks/astro.js +169 -0
- package/dist/resolution/frameworks/astro.js.map +1 -0
- package/dist/resolution/frameworks/cargo-workspace.d.ts +18 -0
- package/dist/resolution/frameworks/cargo-workspace.d.ts.map +1 -0
- package/dist/resolution/frameworks/cargo-workspace.js +225 -0
- package/dist/resolution/frameworks/cargo-workspace.js.map +1 -0
- package/dist/resolution/frameworks/csharp.d.ts +8 -0
- package/dist/resolution/frameworks/csharp.d.ts.map +1 -0
- package/dist/resolution/frameworks/csharp.js +241 -0
- package/dist/resolution/frameworks/csharp.js.map +1 -0
- package/dist/resolution/frameworks/drupal.d.ts +51 -0
- package/dist/resolution/frameworks/drupal.d.ts.map +1 -0
- package/dist/resolution/frameworks/drupal.js +367 -0
- package/dist/resolution/frameworks/drupal.js.map +1 -0
- package/dist/resolution/frameworks/expo-modules.d.ts +3 -0
- package/dist/resolution/frameworks/expo-modules.d.ts.map +1 -0
- package/dist/resolution/frameworks/expo-modules.js +148 -0
- package/dist/resolution/frameworks/expo-modules.js.map +1 -0
- package/dist/resolution/frameworks/express.d.ts +8 -0
- package/dist/resolution/frameworks/express.d.ts.map +1 -0
- package/dist/resolution/frameworks/express.js +308 -0
- package/dist/resolution/frameworks/express.js.map +1 -0
- package/dist/resolution/frameworks/fabric.d.ts +3 -0
- package/dist/resolution/frameworks/fabric.d.ts.map +1 -0
- package/dist/resolution/frameworks/fabric.js +354 -0
- package/dist/resolution/frameworks/fabric.js.map +1 -0
- package/dist/resolution/frameworks/go.d.ts +8 -0
- package/dist/resolution/frameworks/go.d.ts.map +1 -0
- package/dist/resolution/frameworks/go.js +161 -0
- package/dist/resolution/frameworks/go.js.map +1 -0
- package/dist/resolution/frameworks/goframe.d.ts +41 -0
- package/dist/resolution/frameworks/goframe.d.ts.map +1 -0
- package/dist/resolution/frameworks/goframe.js +112 -0
- package/dist/resolution/frameworks/goframe.js.map +1 -0
- package/dist/resolution/frameworks/index.d.ts +50 -0
- package/dist/resolution/frameworks/index.d.ts.map +1 -0
- package/dist/resolution/frameworks/index.js +169 -0
- package/dist/resolution/frameworks/index.js.map +1 -0
- package/dist/resolution/frameworks/java.d.ts +8 -0
- package/dist/resolution/frameworks/java.d.ts.map +1 -0
- package/dist/resolution/frameworks/java.js +509 -0
- package/dist/resolution/frameworks/java.js.map +1 -0
- package/dist/resolution/frameworks/laravel.d.ts +13 -0
- package/dist/resolution/frameworks/laravel.d.ts.map +1 -0
- package/dist/resolution/frameworks/laravel.js +257 -0
- package/dist/resolution/frameworks/laravel.js.map +1 -0
- package/dist/resolution/frameworks/nestjs.d.ts +26 -0
- package/dist/resolution/frameworks/nestjs.d.ts.map +1 -0
- package/dist/resolution/frameworks/nestjs.js +698 -0
- package/dist/resolution/frameworks/nestjs.js.map +1 -0
- package/dist/resolution/frameworks/play.d.ts +19 -0
- package/dist/resolution/frameworks/play.d.ts.map +1 -0
- package/dist/resolution/frameworks/play.js +111 -0
- package/dist/resolution/frameworks/play.js.map +1 -0
- package/dist/resolution/frameworks/python.d.ts +10 -0
- package/dist/resolution/frameworks/python.d.ts.map +1 -0
- package/dist/resolution/frameworks/python.js +400 -0
- package/dist/resolution/frameworks/python.js.map +1 -0
- package/dist/resolution/frameworks/react-native.d.ts +3 -0
- package/dist/resolution/frameworks/react-native.d.ts.map +1 -0
- package/dist/resolution/frameworks/react-native.js +410 -0
- package/dist/resolution/frameworks/react-native.js.map +1 -0
- package/dist/resolution/frameworks/react.d.ts +8 -0
- package/dist/resolution/frameworks/react.d.ts.map +1 -0
- package/dist/resolution/frameworks/react.js +334 -0
- package/dist/resolution/frameworks/react.js.map +1 -0
- package/dist/resolution/frameworks/ruby.d.ts +8 -0
- package/dist/resolution/frameworks/ruby.d.ts.map +1 -0
- package/dist/resolution/frameworks/ruby.js +302 -0
- package/dist/resolution/frameworks/ruby.js.map +1 -0
- package/dist/resolution/frameworks/rust.d.ts +8 -0
- package/dist/resolution/frameworks/rust.d.ts.map +1 -0
- package/dist/resolution/frameworks/rust.js +304 -0
- package/dist/resolution/frameworks/rust.js.map +1 -0
- package/dist/resolution/frameworks/svelte.d.ts +9 -0
- package/dist/resolution/frameworks/svelte.d.ts.map +1 -0
- package/dist/resolution/frameworks/svelte.js +253 -0
- package/dist/resolution/frameworks/svelte.js.map +1 -0
- package/dist/resolution/frameworks/swift-objc.d.ts +37 -0
- package/dist/resolution/frameworks/swift-objc.d.ts.map +1 -0
- package/dist/resolution/frameworks/swift-objc.js +252 -0
- package/dist/resolution/frameworks/swift-objc.js.map +1 -0
- package/dist/resolution/frameworks/swift.d.ts +10 -0
- package/dist/resolution/frameworks/swift.d.ts.map +1 -0
- package/dist/resolution/frameworks/swift.js +400 -0
- package/dist/resolution/frameworks/swift.js.map +1 -0
- package/dist/resolution/frameworks/vue.d.ts +9 -0
- package/dist/resolution/frameworks/vue.d.ts.map +1 -0
- package/dist/resolution/frameworks/vue.js +303 -0
- package/dist/resolution/frameworks/vue.js.map +1 -0
- package/dist/resolution/go-module.d.ts +26 -0
- package/dist/resolution/go-module.d.ts.map +1 -0
- package/dist/resolution/go-module.js +78 -0
- package/dist/resolution/go-module.js.map +1 -0
- package/dist/resolution/goframe-synthesizer.d.ts +28 -0
- package/dist/resolution/goframe-synthesizer.d.ts.map +1 -0
- package/dist/resolution/goframe-synthesizer.js +158 -0
- package/dist/resolution/goframe-synthesizer.js.map +1 -0
- package/dist/resolution/import-resolver.d.ts +78 -0
- package/dist/resolution/import-resolver.d.ts.map +1 -0
- package/dist/resolution/import-resolver.js +1849 -0
- package/dist/resolution/import-resolver.js.map +1 -0
- package/dist/resolution/index.d.ts +196 -0
- package/dist/resolution/index.d.ts.map +1 -0
- package/dist/resolution/index.js +1328 -0
- package/dist/resolution/index.js.map +1 -0
- package/dist/resolution/lru-cache.d.ts +24 -0
- package/dist/resolution/lru-cache.d.ts.map +1 -0
- package/dist/resolution/lru-cache.js +62 -0
- package/dist/resolution/lru-cache.js.map +1 -0
- package/dist/resolution/name-matcher.d.ts +93 -0
- package/dist/resolution/name-matcher.d.ts.map +1 -0
- package/dist/resolution/name-matcher.js +1212 -0
- package/dist/resolution/name-matcher.js.map +1 -0
- package/dist/resolution/path-aliases.d.ts +68 -0
- package/dist/resolution/path-aliases.d.ts.map +1 -0
- package/dist/resolution/path-aliases.js +238 -0
- package/dist/resolution/path-aliases.js.map +1 -0
- package/dist/resolution/strip-comments.d.ts +27 -0
- package/dist/resolution/strip-comments.d.ts.map +1 -0
- package/dist/resolution/strip-comments.js +443 -0
- package/dist/resolution/strip-comments.js.map +1 -0
- package/dist/resolution/swift-objc-bridge.d.ts +134 -0
- package/dist/resolution/swift-objc-bridge.d.ts.map +1 -0
- package/dist/resolution/swift-objc-bridge.js +256 -0
- package/dist/resolution/swift-objc-bridge.js.map +1 -0
- package/dist/resolution/types.d.ts +233 -0
- package/dist/resolution/types.d.ts.map +1 -0
- package/dist/resolution/types.js +8 -0
- package/dist/resolution/types.js.map +1 -0
- package/dist/resolution/workspace-packages.d.ts +48 -0
- package/dist/resolution/workspace-packages.d.ts.map +1 -0
- package/dist/resolution/workspace-packages.js +208 -0
- package/dist/resolution/workspace-packages.js.map +1 -0
- package/dist/search/query-parser.d.ts +57 -0
- package/dist/search/query-parser.d.ts.map +1 -0
- package/dist/search/query-parser.js +177 -0
- package/dist/search/query-parser.js.map +1 -0
- package/dist/search/query-utils.d.ts +87 -0
- package/dist/search/query-utils.d.ts.map +1 -0
- package/dist/search/query-utils.js +449 -0
- package/dist/search/query-utils.js.map +1 -0
- package/dist/sync/git-hooks.d.ts +45 -0
- package/dist/sync/git-hooks.d.ts.map +1 -0
- package/dist/sync/git-hooks.js +225 -0
- package/dist/sync/git-hooks.js.map +1 -0
- package/dist/sync/index.d.ts +19 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +35 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/watch-policy.d.ts +48 -0
- package/dist/sync/watch-policy.d.ts.map +1 -0
- package/dist/sync/watch-policy.js +124 -0
- package/dist/sync/watch-policy.js.map +1 -0
- package/dist/sync/watcher.d.ts +350 -0
- package/dist/sync/watcher.d.ts.map +1 -0
- package/dist/sync/watcher.js +811 -0
- package/dist/sync/watcher.js.map +1 -0
- package/dist/sync/worktree.d.ts +54 -0
- package/dist/sync/worktree.d.ts.map +1 -0
- package/dist/sync/worktree.js +137 -0
- package/dist/sync/worktree.js.map +1 -0
- package/dist/telemetry/index.d.ts +143 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +541 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/timeline/bash-semantics.d.ts +52 -0
- package/dist/timeline/bash-semantics.d.ts.map +1 -0
- package/dist/timeline/bash-semantics.js +376 -0
- package/dist/timeline/bash-semantics.js.map +1 -0
- package/dist/timeline/cli.d.ts +50 -0
- package/dist/timeline/cli.d.ts.map +1 -0
- package/dist/timeline/cli.js +367 -0
- package/dist/timeline/cli.js.map +1 -0
- package/dist/timeline/constants.d.ts +62 -0
- package/dist/timeline/constants.d.ts.map +1 -0
- package/dist/timeline/constants.js +73 -0
- package/dist/timeline/constants.js.map +1 -0
- package/dist/timeline/errors.d.ts +27 -0
- package/dist/timeline/errors.d.ts.map +1 -0
- package/dist/timeline/errors.js +51 -0
- package/dist/timeline/errors.js.map +1 -0
- package/dist/timeline/hook-runner.d.ts +36 -0
- package/dist/timeline/hook-runner.d.ts.map +1 -0
- package/dist/timeline/hook-runner.js +61 -0
- package/dist/timeline/hook-runner.js.map +1 -0
- package/dist/timeline/hooks.d.ts +45 -0
- package/dist/timeline/hooks.d.ts.map +1 -0
- package/dist/timeline/hooks.js +364 -0
- package/dist/timeline/hooks.js.map +1 -0
- package/dist/timeline/index.d.ts +12 -0
- package/dist/timeline/index.d.ts.map +1 -0
- package/dist/timeline/index.js +28 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/timeline/indexer.d.ts +37 -0
- package/dist/timeline/indexer.d.ts.map +1 -0
- package/dist/timeline/indexer.js +76 -0
- package/dist/timeline/indexer.js.map +1 -0
- package/dist/timeline/installer.d.ts +33 -0
- package/dist/timeline/installer.d.ts.map +1 -0
- package/dist/timeline/installer.js +255 -0
- package/dist/timeline/installer.js.map +1 -0
- package/dist/timeline/payload.d.ts +31 -0
- package/dist/timeline/payload.d.ts.map +1 -0
- package/dist/timeline/payload.js +58 -0
- package/dist/timeline/payload.js.map +1 -0
- package/dist/timeline/post-tool-summary.d.ts +29 -0
- package/dist/timeline/post-tool-summary.d.ts.map +1 -0
- package/dist/timeline/post-tool-summary.js +190 -0
- package/dist/timeline/post-tool-summary.js.map +1 -0
- package/dist/timeline/recorder.d.ts +36 -0
- package/dist/timeline/recorder.d.ts.map +1 -0
- package/dist/timeline/recorder.js +42 -0
- package/dist/timeline/recorder.js.map +1 -0
- package/dist/timeline/schema-bootstrap.d.ts +42 -0
- package/dist/timeline/schema-bootstrap.d.ts.map +1 -0
- package/dist/timeline/schema-bootstrap.js +81 -0
- package/dist/timeline/schema-bootstrap.js.map +1 -0
- package/dist/timeline/schema.sql +37 -0
- package/dist/timeline/store.d.ts +69 -0
- package/dist/timeline/store.d.ts.map +1 -0
- package/dist/timeline/store.js +429 -0
- package/dist/timeline/store.js.map +1 -0
- package/dist/timeline/types.d.ts +78 -0
- package/dist/timeline/types.d.ts.map +1 -0
- package/dist/timeline/types.js +9 -0
- package/dist/timeline/types.js.map +1 -0
- package/dist/types.d.ts +392 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +81 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/glyphs.d.ts +42 -0
- package/dist/ui/glyphs.d.ts.map +1 -0
- package/dist/ui/glyphs.js +78 -0
- package/dist/ui/glyphs.js.map +1 -0
- package/dist/ui/shimmer-progress.d.ts +11 -0
- package/dist/ui/shimmer-progress.d.ts.map +1 -0
- package/dist/ui/shimmer-progress.js +90 -0
- package/dist/ui/shimmer-progress.js.map +1 -0
- package/dist/ui/shimmer-worker.d.ts +2 -0
- package/dist/ui/shimmer-worker.d.ts.map +1 -0
- package/dist/ui/shimmer-worker.js +118 -0
- package/dist/ui/shimmer-worker.js.map +1 -0
- package/dist/ui/types.d.ts +17 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +3 -0
- package/dist/ui/types.js.map +1 -0
- package/dist/upgrade/index.d.ts +132 -0
- package/dist/upgrade/index.d.ts.map +1 -0
- package/dist/upgrade/index.js +498 -0
- package/dist/upgrade/index.js.map +1 -0
- package/dist/utils.d.ts +224 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +583 -0
- package/dist/utils.js.map +1 -0
- package/package.json +60 -0
- package/scripts/add-lang/bench.sh +60 -0
- package/scripts/add-lang/check-grammar.mjs +75 -0
- package/scripts/add-lang/dump-ast.mjs +103 -0
- package/scripts/add-lang/verify-extraction.mjs +70 -0
- package/scripts/agent-eval/ab-adoption.sh +91 -0
- package/scripts/agent-eval/ab-hook.sh +86 -0
- package/scripts/agent-eval/ab-impl.sh +78 -0
- package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -0
- package/scripts/agent-eval/ab-sufficiency.sh +78 -0
- package/scripts/agent-eval/arms-F.sh +21 -0
- package/scripts/agent-eval/arms-matrix.sh +37 -0
- package/scripts/agent-eval/audit.sh +68 -0
- package/scripts/agent-eval/bench-readme.sh +28 -0
- package/scripts/agent-eval/bench-why-repo.sh +22 -0
- package/scripts/agent-eval/block-read-hook.sh +19 -0
- package/scripts/agent-eval/hook-settings.json +15 -0
- package/scripts/agent-eval/itrun.sh +120 -0
- package/scripts/agent-eval/offload-eval-3arm.sh +72 -0
- package/scripts/agent-eval/offload-eval-cost.mjs +133 -0
- package/scripts/agent-eval/offload-eval-effort.mjs +108 -0
- package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -0
- package/scripts/agent-eval/offload-eval-frontload.sh +47 -0
- package/scripts/agent-eval/offload-eval-ground-truth.json +18 -0
- package/scripts/agent-eval/offload-eval-hook.mjs +84 -0
- package/scripts/agent-eval/offload-eval-judge.mjs +103 -0
- package/scripts/agent-eval/offload-eval-matrix.sh +20 -0
- package/scripts/agent-eval/offload-eval-metrics.mjs +94 -0
- package/scripts/agent-eval/offload-eval-refs1.sh +50 -0
- package/scripts/agent-eval/offload-eval-setup.sh +24 -0
- package/scripts/agent-eval/offload-eval-styles.sh +72 -0
- package/scripts/agent-eval/offload-eval-summarize.mjs +68 -0
- package/scripts/agent-eval/offload-eval.md +76 -0
- package/scripts/agent-eval/parse-arms.mjs +116 -0
- package/scripts/agent-eval/parse-bench-readme.mjs +84 -0
- package/scripts/agent-eval/parse-run.mjs +45 -0
- package/scripts/agent-eval/parse-session.mjs +93 -0
- package/scripts/agent-eval/probe-context.mjs +21 -0
- package/scripts/agent-eval/probe-explore.mjs +40 -0
- package/scripts/agent-eval/probe-node.mjs +20 -0
- package/scripts/agent-eval/probe-sweep.mjs +119 -0
- package/scripts/agent-eval/probe-trace.mjs +20 -0
- package/scripts/agent-eval/redirect-read-hook.sh +38 -0
- package/scripts/agent-eval/run-agent.sh +34 -0
- package/scripts/agent-eval/run-all.sh +69 -0
- package/scripts/agent-eval/run-arms.sh +56 -0
- package/scripts/agent-eval/seq-matrix.mjs +137 -0
- package/scripts/build-bundle.sh +118 -0
- package/scripts/extract-release-notes.mjs +130 -0
- package/scripts/local-install.sh +41 -0
- package/scripts/npm-sdk.js +75 -0
- package/scripts/npm-shim.js +246 -0
- package/scripts/pack-npm.sh +118 -0
- package/scripts/prepare-release.mjs +270 -0
|
@@ -0,0 +1,811 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* File Watcher
|
|
4
|
+
*
|
|
5
|
+
* Watches the project directory for file changes and triggers debounced sync
|
|
6
|
+
* operations to keep the code graph up-to-date.
|
|
7
|
+
*
|
|
8
|
+
* Uses Node's built-in `fs.watch` directly (no third-party watcher, no native
|
|
9
|
+
* addon) with a per-platform strategy chosen to keep the open-descriptor /
|
|
10
|
+
* kernel-watch cost BOUNDED rather than growing with the number of files:
|
|
11
|
+
*
|
|
12
|
+
* - macOS / Windows: a SINGLE recursive `fs.watch(root, {recursive:true})`.
|
|
13
|
+
* libuv maps this to one FSEvents stream (macOS) / one
|
|
14
|
+
* ReadDirectoryChangesW handle (Windows), so it costs O(1) descriptors no
|
|
15
|
+
* matter how large the tree. This is the fix for the macOS file-table
|
|
16
|
+
* exhaustion (#644 / #496 / #555 / #628): the previous watcher held one
|
|
17
|
+
* open fd PER WATCHED FILE on macOS (tens of thousands of REG fds), which
|
|
18
|
+
* exhausted `kern.maxfiles` and crashed unrelated processes system-wide.
|
|
19
|
+
*
|
|
20
|
+
* - Linux: recursive `fs.watch` is unsupported, so we watch each (non-ignored)
|
|
21
|
+
* DIRECTORY with one inotify watch — O(directories), NOT O(files). New
|
|
22
|
+
* directories are picked up dynamically and an overall watch cap bounds
|
|
23
|
+
* inotify usage on pathological monorepos (#579). A single inotify watch on
|
|
24
|
+
* a directory already reports create/modify/delete for its children, so
|
|
25
|
+
* per-file watches are never needed.
|
|
26
|
+
*
|
|
27
|
+
* Excluded trees (node_modules/, dist/, .git/, …) are filtered via the
|
|
28
|
+
* indexer's `buildScopeIgnore` (built-in default-ignore dirs + the project's
|
|
29
|
+
* .gitignore) — on Linux they're never descended into (so they cost no watch),
|
|
30
|
+
* and on macOS/Windows the single recursive stream still covers them but their
|
|
31
|
+
* events are dropped before any sync is scheduled. Either way the watcher's
|
|
32
|
+
* scope matches the indexer's (#276 / #407).
|
|
33
|
+
*/
|
|
34
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
35
|
+
if (k2 === undefined) k2 = k;
|
|
36
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
37
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
38
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
39
|
+
}
|
|
40
|
+
Object.defineProperty(o, k2, desc);
|
|
41
|
+
}) : (function(o, m, k, k2) {
|
|
42
|
+
if (k2 === undefined) k2 = k;
|
|
43
|
+
o[k2] = m[k];
|
|
44
|
+
}));
|
|
45
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
46
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
47
|
+
}) : function(o, v) {
|
|
48
|
+
o["default"] = v;
|
|
49
|
+
});
|
|
50
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
51
|
+
var ownKeys = function(o) {
|
|
52
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
53
|
+
var ar = [];
|
|
54
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
55
|
+
return ar;
|
|
56
|
+
};
|
|
57
|
+
return ownKeys(o);
|
|
58
|
+
};
|
|
59
|
+
return function (mod) {
|
|
60
|
+
if (mod && mod.__esModule) return mod;
|
|
61
|
+
var result = {};
|
|
62
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
63
|
+
__setModuleDefault(result, mod);
|
|
64
|
+
return result;
|
|
65
|
+
};
|
|
66
|
+
})();
|
|
67
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
68
|
+
exports.FileWatcher = exports.LockUnavailableError = void 0;
|
|
69
|
+
exports.__setFsWatchForTests = __setFsWatchForTests;
|
|
70
|
+
exports.__emitWatchEventForTests = __emitWatchEventForTests;
|
|
71
|
+
const fs = __importStar(require("fs"));
|
|
72
|
+
const path = __importStar(require("path"));
|
|
73
|
+
const extraction_1 = require("../extraction");
|
|
74
|
+
const project_config_1 = require("../project-config");
|
|
75
|
+
const errors_1 = require("../errors");
|
|
76
|
+
const utils_1 = require("../utils");
|
|
77
|
+
const directory_1 = require("../directory");
|
|
78
|
+
const watch_policy_1 = require("./watch-policy");
|
|
79
|
+
/**
|
|
80
|
+
* Number of consecutive lock-contention retries the watcher tolerates before
|
|
81
|
+
* it gives up and degrades auto-sync. Brief contention (another writer for a
|
|
82
|
+
* few cycles) stays under this; a long-lived external writer crosses it.
|
|
83
|
+
*/
|
|
84
|
+
const MAX_LOCK_RETRIES = 5;
|
|
85
|
+
/** Cap on the exponential lock-retry backoff so it never sleeps absurdly long. */
|
|
86
|
+
const MAX_LOCK_RETRY_DELAY_MS = 30_000;
|
|
87
|
+
/** Actionable degrade message; both exhaustion paths share it verbatim. */
|
|
88
|
+
const EXHAUSTION_REASON = 'OS watch/file limit exhausted; auto-sync disabled. Run `cgraphx sync` ' +
|
|
89
|
+
'(or install git sync hooks) to refresh the graph after changes.';
|
|
90
|
+
/**
|
|
91
|
+
* Actionable, NON-fatal warning for Linux inotify watch-count exhaustion.
|
|
92
|
+
* Unlike {@link EXHAUSTION_REASON} this does not disable the watcher — the
|
|
93
|
+
* watches already installed keep working — so it names the exact kernel knob to
|
|
94
|
+
* raise instead.
|
|
95
|
+
*/
|
|
96
|
+
const INOTIFY_LIMIT_REASON = 'Linux inotify watch limit reached (fs.inotify.max_user_watches); live ' +
|
|
97
|
+
'watching now covers only part of the project, so edits in unwatched ' +
|
|
98
|
+
'directories will not auto-sync. Raise the limit (e.g. `sudo sysctl ' +
|
|
99
|
+
'fs.inotify.max_user_watches=1048576`, persisted in /etc/sysctl.d) and ' +
|
|
100
|
+
'restart, or run `cgraphx sync` (or install git sync hooks) to refresh.';
|
|
101
|
+
/**
|
|
102
|
+
* True when an error is OS watch/file-descriptor exhaustion (EMFILE/ENFILE).
|
|
103
|
+
* Prefers the structured `err.code`; falls back to message matching ONLY when
|
|
104
|
+
* no code is present (some platforms surface a bare Error from `fs.watch`).
|
|
105
|
+
*/
|
|
106
|
+
function isWatchResourceExhaustion(err) {
|
|
107
|
+
const e = err;
|
|
108
|
+
if (e?.code === 'EMFILE' || e?.code === 'ENFILE')
|
|
109
|
+
return true;
|
|
110
|
+
if (!e?.code && e?.message) {
|
|
111
|
+
return /EMFILE|ENFILE|too many open files/i.test(e.message);
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* True when an error is Linux inotify *watch-count* exhaustion. `fs.watch`
|
|
117
|
+
* surfaces a hit `fs.inotify.max_user_watches` as ENOSPC ("no space" = no watch
|
|
118
|
+
* descriptors left, NOT disk space). This only arises on the Linux
|
|
119
|
+
* per-directory path; it is non-fatal (raise the limit and partial watching
|
|
120
|
+
* keeps working), so it warns rather than degrading.
|
|
121
|
+
*/
|
|
122
|
+
function isInotifyWatchExhaustion(err) {
|
|
123
|
+
return err?.code === 'ENOSPC';
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Native recursive `fs.watch` is only reliable on macOS and Windows; on Linux
|
|
127
|
+
* (and AIX) it throws `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`. We branch on this
|
|
128
|
+
* to pick the recursive vs per-directory strategy.
|
|
129
|
+
*/
|
|
130
|
+
function supportsRecursiveWatch() {
|
|
131
|
+
return process.platform === 'darwin' || process.platform === 'win32';
|
|
132
|
+
}
|
|
133
|
+
let watchImpl = fs.watch;
|
|
134
|
+
/** @internal Test-only seam to inject a fake fs.watch implementation. */
|
|
135
|
+
function __setFsWatchForTests(fn) {
|
|
136
|
+
watchImpl = fn ?? fs.watch;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Upper bound on simultaneously-watched directories on the Linux per-directory
|
|
140
|
+
* path. Each is one inotify watch; the kernel's `fs.inotify.max_user_watches`
|
|
141
|
+
* is the hard limit (commonly 8k–128k). We stop adding watches past this and
|
|
142
|
+
* log once — partial live-watch (with `cgraphx sync` as the backstop) is far
|
|
143
|
+
* better than exhausting the user's inotify budget and breaking watching
|
|
144
|
+
* system-wide (#579). Tunable via CGRAPHX_MAX_DIR_WATCHES.
|
|
145
|
+
*/
|
|
146
|
+
const DEFAULT_MAX_DIR_WATCHES = 50_000;
|
|
147
|
+
function maxDirWatches() {
|
|
148
|
+
const raw = process.env.CGRAPHX_MAX_DIR_WATCHES;
|
|
149
|
+
if (raw && /^\d+$/.test(raw)) {
|
|
150
|
+
const n = Number(raw);
|
|
151
|
+
if (n > 0)
|
|
152
|
+
return n;
|
|
153
|
+
}
|
|
154
|
+
return DEFAULT_MAX_DIR_WATCHES;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Test seam (see {@link __emitWatchEventForTests}). Maps a watcher's project
|
|
158
|
+
* root to its live instance so tests can synthesize a change event
|
|
159
|
+
* deterministically — real fs.watch delivery latency races under parallel
|
|
160
|
+
* vitest (the reason the previous chokidar mock existed). Only populated under
|
|
161
|
+
* a test runner, so production carries no bookkeeping or retained references.
|
|
162
|
+
*/
|
|
163
|
+
const liveWatchersForTests = new Map();
|
|
164
|
+
const IS_TEST_RUNTIME = !!(process.env.VITEST || process.env.NODE_ENV === 'test');
|
|
165
|
+
/**
|
|
166
|
+
* Thrown by a `syncFn` to signal that the underlying sync couldn't acquire
|
|
167
|
+
* the cross-process write lock (#449). The watcher treats this as "no
|
|
168
|
+
* progress" — preserves `pendingFiles`, skips `onSyncComplete`, and the
|
|
169
|
+
* `finally` block reschedules. Quiet (debug-only) because a long-running
|
|
170
|
+
* external indexer can hit this every debounce cycle.
|
|
171
|
+
*/
|
|
172
|
+
class LockUnavailableError extends Error {
|
|
173
|
+
constructor(message = 'cgraphx file lock unavailable; another process is writing') {
|
|
174
|
+
super(message);
|
|
175
|
+
this.name = 'LockUnavailableError';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.LockUnavailableError = LockUnavailableError;
|
|
179
|
+
/**
|
|
180
|
+
* FileWatcher monitors a project directory for changes and triggers
|
|
181
|
+
* debounced sync operations via a provided callback.
|
|
182
|
+
*
|
|
183
|
+
* Design goals:
|
|
184
|
+
* - Bounded resource usage: O(1) descriptors on macOS/Windows (one recursive
|
|
185
|
+
* watch), O(directories) inotify watches on Linux — never O(files), which
|
|
186
|
+
* was the system-crashing fd leak on macOS (#644/#496/#555/#628).
|
|
187
|
+
* - Debounced to avoid thrashing on rapid saves
|
|
188
|
+
* - Filters to supported source files by extension
|
|
189
|
+
* - Ignores .cgraphx/ and .git/ regardless of .gitignore
|
|
190
|
+
* - Tracks per-file pending state so MCP tools can flag stale results
|
|
191
|
+
* without blocking on a sync (issue #403)
|
|
192
|
+
*/
|
|
193
|
+
class FileWatcher {
|
|
194
|
+
/** macOS/Windows: the single recursive watcher. Null on Linux. */
|
|
195
|
+
recursiveWatcher = null;
|
|
196
|
+
/** Linux: one watcher per watched directory (keyed by absolute path). */
|
|
197
|
+
dirWatchers = new Map();
|
|
198
|
+
/** Set once the per-directory watch cap is hit, so we log only once. */
|
|
199
|
+
dirCapWarned = false;
|
|
200
|
+
/**
|
|
201
|
+
* Set once the Linux inotify watch limit (ENOSPC) is hit. Double duty: we
|
|
202
|
+
* warn only once, AND we stop attempting new directory watches for the rest
|
|
203
|
+
* of the session — once the kernel budget is exhausted every further
|
|
204
|
+
* `inotify_add_watch` fails too, so trying the rest of the tree is pure
|
|
205
|
+
* waste. NON-fatal (does not degrade): installed watches keep working.
|
|
206
|
+
*/
|
|
207
|
+
inotifyLimitWarned = false;
|
|
208
|
+
/**
|
|
209
|
+
* One-way latch: the reason live watching was permanently disabled at runtime
|
|
210
|
+
* (watch-resource exhaustion, or lock contention past the retry budget), or
|
|
211
|
+
* null while healthy. Set by {@link degrade}; cleared only by a fresh start().
|
|
212
|
+
*/
|
|
213
|
+
degradedReason = null;
|
|
214
|
+
/** Consecutive lock-contention retries for watcher-triggered syncs. */
|
|
215
|
+
lockRetryCount = 0;
|
|
216
|
+
/** Test-only inert mode: started, but with no OS watcher installed. */
|
|
217
|
+
inert = false;
|
|
218
|
+
debounceTimer = null;
|
|
219
|
+
/**
|
|
220
|
+
* Files seen by the watcher since the last successful sync — populated on
|
|
221
|
+
* every change event, cleared at the start of a sync, and re-populated by
|
|
222
|
+
* events that arrive mid-sync (or restored on sync failure). Keyed by the
|
|
223
|
+
* same project-relative POSIX path the rest of the codebase uses, so a
|
|
224
|
+
* caller can intersect tool-response file paths against this map cheaply.
|
|
225
|
+
*/
|
|
226
|
+
pendingFiles = new Map();
|
|
227
|
+
/**
|
|
228
|
+
* Wall-clock ms at which the in-flight sync began. Combined with
|
|
229
|
+
* {@link pendingFiles}'s `lastSeenMs`, this distinguishes "still in the
|
|
230
|
+
* debounce window" (lastSeen > syncStarted, sync hasn't started yet for
|
|
231
|
+
* this edit) from "currently being indexed" (lastSeen <= syncStarted).
|
|
232
|
+
*/
|
|
233
|
+
syncStartedMs = 0;
|
|
234
|
+
syncing = false;
|
|
235
|
+
stopped = false;
|
|
236
|
+
/**
|
|
237
|
+
* True once the initial watch set is established. Unlike the previous
|
|
238
|
+
* chokidar implementation there is no asynchronous initial "crawl" emitting
|
|
239
|
+
* an `add` per existing file — `fs.watch` only reports changes from the
|
|
240
|
+
* moment it's installed — so this flips to true synchronously at the end of
|
|
241
|
+
* `start()`. The startup reconcile against on-disk state is handled
|
|
242
|
+
* separately by the engine's catch-up sync, not by the watcher.
|
|
243
|
+
*/
|
|
244
|
+
ready = false;
|
|
245
|
+
/**
|
|
246
|
+
* Callbacks that resolve when the watch set is established. Used by tests
|
|
247
|
+
* (and any production caller that cares about a clean baseline) to
|
|
248
|
+
* deterministically gate on watcher readiness.
|
|
249
|
+
*/
|
|
250
|
+
readyWaiters = [];
|
|
251
|
+
// The shared scope matcher (built-in defaults + project .gitignore, with
|
|
252
|
+
// embedded child repos matched by their OWN rules — #514), built once at
|
|
253
|
+
// start(). Same source of truth the indexer uses, so watcher scope can
|
|
254
|
+
// never diverge from index scope. An embedded repo created after start()
|
|
255
|
+
// joins the scope on the next watcher restart / re-index.
|
|
256
|
+
ignoreMatcher = null;
|
|
257
|
+
projectRoot;
|
|
258
|
+
debounceMs;
|
|
259
|
+
syncFn;
|
|
260
|
+
onSyncComplete;
|
|
261
|
+
onSyncError;
|
|
262
|
+
onDegraded;
|
|
263
|
+
inertForTests;
|
|
264
|
+
constructor(projectRoot, syncFn, options = {}) {
|
|
265
|
+
this.projectRoot = projectRoot;
|
|
266
|
+
this.syncFn = syncFn;
|
|
267
|
+
this.debounceMs = options.debounceMs ?? 2000;
|
|
268
|
+
this.onSyncComplete = options.onSyncComplete;
|
|
269
|
+
this.onSyncError = options.onSyncError;
|
|
270
|
+
this.onDegraded = options.onDegraded;
|
|
271
|
+
this.inertForTests = options.inertForTests ?? false;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Start watching for file changes.
|
|
275
|
+
* Returns true if watching started successfully, false otherwise.
|
|
276
|
+
*/
|
|
277
|
+
start() {
|
|
278
|
+
if (this.recursiveWatcher || this.dirWatchers.size > 0 || this.inert)
|
|
279
|
+
return true; // Already watching
|
|
280
|
+
this.stopped = false;
|
|
281
|
+
this.degradedReason = null;
|
|
282
|
+
this.lockRetryCount = 0;
|
|
283
|
+
// Some environments make filesystem watching unusable — most notably
|
|
284
|
+
// WSL2 /mnt/ drives, where the underlying fs.watch calls block long
|
|
285
|
+
// enough to break MCP startup handshakes (issue #199). Skip watching
|
|
286
|
+
// there; callers fall back to manual `cgraphx sync` or git sync hooks.
|
|
287
|
+
const disabledReason = (0, watch_policy_1.watchDisabledReason)(this.projectRoot);
|
|
288
|
+
if (disabledReason) {
|
|
289
|
+
(0, errors_1.logDebug)('File watcher disabled', { reason: disabledReason, projectRoot: this.projectRoot });
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
// Reuse the indexer's ignore set so the watcher and indexer agree on scope.
|
|
293
|
+
this.ignoreMatcher = (0, extraction_1.buildScopeIgnore)(this.projectRoot);
|
|
294
|
+
try {
|
|
295
|
+
if (this.inertForTests) {
|
|
296
|
+
// Test-only: install no OS watcher; the seam drives events instead.
|
|
297
|
+
this.inert = true;
|
|
298
|
+
}
|
|
299
|
+
else if (supportsRecursiveWatch()) {
|
|
300
|
+
this.startRecursive();
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
this.startPerDirectory();
|
|
304
|
+
}
|
|
305
|
+
// The per-directory (Linux) path catches watch-resource exhaustion inside
|
|
306
|
+
// watchTree and degrades synchronously rather than throwing, so it never
|
|
307
|
+
// reaches the catch below. Surface that as a failed start here so both
|
|
308
|
+
// strategies report exhaustion identically (start() === false).
|
|
309
|
+
if (this.degradedReason)
|
|
310
|
+
return false;
|
|
311
|
+
// No async crawl to wait on: as soon as the watch set is installed we
|
|
312
|
+
// have a clean baseline (pendingFiles is only populated by post-start
|
|
313
|
+
// events). Clear defensively and flip ready.
|
|
314
|
+
this.pendingFiles.clear();
|
|
315
|
+
this.ready = true;
|
|
316
|
+
for (const cb of this.readyWaiters)
|
|
317
|
+
cb();
|
|
318
|
+
this.readyWaiters.length = 0;
|
|
319
|
+
if (IS_TEST_RUNTIME)
|
|
320
|
+
liveWatchersForTests.set(this.projectRoot, this);
|
|
321
|
+
(0, errors_1.logDebug)('File watcher started', {
|
|
322
|
+
projectRoot: this.projectRoot,
|
|
323
|
+
debounceMs: this.debounceMs,
|
|
324
|
+
mode: this.inertForTests ? 'inert' : supportsRecursiveWatch() ? 'recursive' : 'per-directory',
|
|
325
|
+
watchedDirs: this.dirWatchers.size || undefined,
|
|
326
|
+
});
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
// Watcher setup failed. Watch-resource exhaustion (EMFILE/ENFILE on the
|
|
331
|
+
// recursive path) is terminal — degrade cleanly with one actionable
|
|
332
|
+
// warning instead of leaving a half-broken watcher. Everything else
|
|
333
|
+
// (permission denied, missing directory) keeps the prior quiet-stop.
|
|
334
|
+
if (isWatchResourceExhaustion(err)) {
|
|
335
|
+
this.degrade(EXHAUSTION_REASON, { error: String(err) });
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
(0, errors_1.logWarn)('Could not start file watcher', { error: String(err) });
|
|
339
|
+
this.stop();
|
|
340
|
+
}
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* macOS/Windows: one recursive watcher for the whole tree. O(1) descriptors.
|
|
346
|
+
* `filename` arrives relative to the project root (with subdirectories), so
|
|
347
|
+
* it maps straight to a project-relative path.
|
|
348
|
+
*/
|
|
349
|
+
startRecursive() {
|
|
350
|
+
this.recursiveWatcher = watchImpl(this.projectRoot, { recursive: true, persistent: true }, (_event, filename) => {
|
|
351
|
+
if (this.stopped || filename == null)
|
|
352
|
+
return;
|
|
353
|
+
this.handleChange((0, utils_1.normalizePath)(String(filename)));
|
|
354
|
+
});
|
|
355
|
+
this.recursiveWatcher.on('error', (err) => {
|
|
356
|
+
if (isWatchResourceExhaustion(err)) {
|
|
357
|
+
this.degrade(EXHAUSTION_REASON, { error: String(err) });
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
(0, errors_1.logWarn)('File watcher error', { error: String(err) });
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Linux: walk the (non-ignored) tree and watch each directory. One inotify
|
|
365
|
+
* watch per directory reports create/modify/delete for that directory's
|
|
366
|
+
* direct children, so we never watch individual files.
|
|
367
|
+
*/
|
|
368
|
+
startPerDirectory() {
|
|
369
|
+
this.watchTree(this.projectRoot, /* markExisting */ false);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Add an inotify watch for `dir` and recurse into its non-ignored
|
|
373
|
+
* subdirectories. When `markExisting` is true (a directory that appeared
|
|
374
|
+
* AFTER startup), the source files already inside it are recorded as pending
|
|
375
|
+
* — this closes the `mkdir + write` race where files created before the new
|
|
376
|
+
* directory's watch is installed would otherwise be missed until the next
|
|
377
|
+
* full sync. The initial startup walk passes false (the engine's catch-up
|
|
378
|
+
* sync owns the baseline).
|
|
379
|
+
*/
|
|
380
|
+
watchTree(dir, markExisting) {
|
|
381
|
+
// A degrade() mid-walk (exhaustion on an earlier directory) calls stop(),
|
|
382
|
+
// which sets `stopped`; bail so the recursion unwinds without adding more
|
|
383
|
+
// watches to a watcher that is shutting down. `inotifyLimitWarned` does the
|
|
384
|
+
// same after ENOSPC — the kernel budget is gone, so stop trying the rest of
|
|
385
|
+
// the tree (every add would fail) while keeping the watches already set.
|
|
386
|
+
if (this.stopped || this.degradedReason || this.inotifyLimitWarned)
|
|
387
|
+
return;
|
|
388
|
+
if (this.dirWatchers.has(dir))
|
|
389
|
+
return;
|
|
390
|
+
if (this.dirWatchers.size >= maxDirWatches()) {
|
|
391
|
+
if (!this.dirCapWarned) {
|
|
392
|
+
this.dirCapWarned = true;
|
|
393
|
+
(0, errors_1.logWarn)('File watcher hit directory-watch cap; remaining subtrees rely on manual/periodic sync', {
|
|
394
|
+
cap: maxDirWatches(),
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
let w;
|
|
400
|
+
try {
|
|
401
|
+
w = watchImpl(dir, { persistent: true }, (_event, filename) => this.handleDirEvent(dir, filename));
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
// EMFILE/ENFILE means the PROCESS is out of descriptors — every further
|
|
405
|
+
// directory would fail too, so degrade the whole watcher rather than
|
|
406
|
+
// limping along with a partial watch set.
|
|
407
|
+
if (isWatchResourceExhaustion(err)) {
|
|
408
|
+
this.degrade(EXHAUSTION_REASON, { error: String(err), dir });
|
|
409
|
+
}
|
|
410
|
+
else if (isInotifyWatchExhaustion(err)) {
|
|
411
|
+
// ENOSPC = inotify watch budget exhausted. NON-fatal: keep the watches
|
|
412
|
+
// we have and tell the user the knob to raise (warn once).
|
|
413
|
+
this.warnInotifyLimit({ error: String(err), dir });
|
|
414
|
+
}
|
|
415
|
+
// ENOENT / EACCES on a single directory stays non-fatal: skip it quietly.
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
w.on('error', (err) => {
|
|
419
|
+
if (isWatchResourceExhaustion(err)) {
|
|
420
|
+
this.degrade(EXHAUSTION_REASON, { error: String(err), dir });
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (isInotifyWatchExhaustion(err)) {
|
|
424
|
+
this.warnInotifyLimit({ error: String(err), dir });
|
|
425
|
+
}
|
|
426
|
+
this.unwatchDir(dir);
|
|
427
|
+
});
|
|
428
|
+
this.dirWatchers.set(dir, w);
|
|
429
|
+
let entries;
|
|
430
|
+
try {
|
|
431
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
432
|
+
}
|
|
433
|
+
catch {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
for (const entry of entries) {
|
|
437
|
+
const child = path.join(dir, entry.name);
|
|
438
|
+
if (entry.isDirectory()) {
|
|
439
|
+
if (this.shouldIgnoreDir(child))
|
|
440
|
+
continue;
|
|
441
|
+
this.watchTree(child, markExisting);
|
|
442
|
+
}
|
|
443
|
+
else if (markExisting && entry.isFile()) {
|
|
444
|
+
this.handleChange((0, utils_1.normalizePath)(path.relative(this.projectRoot, child)));
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Linux per-directory event handler. `filename` is relative to `dir`. A new
|
|
450
|
+
* sub-directory is picked up by extending the watch tree; everything else is
|
|
451
|
+
* routed through the shared change handler.
|
|
452
|
+
*/
|
|
453
|
+
handleDirEvent(dir, filename) {
|
|
454
|
+
if (this.stopped || filename == null)
|
|
455
|
+
return;
|
|
456
|
+
const full = path.join(dir, String(filename));
|
|
457
|
+
// A newly-created directory needs its own watch (recursive isn't available
|
|
458
|
+
// on Linux). statSync is cheap and these events are rare relative to file
|
|
459
|
+
// edits. If the path vanished (rapid create/delete) the stat throws and we
|
|
460
|
+
// fall through to the change handler, which no-ops on a non-source path.
|
|
461
|
+
try {
|
|
462
|
+
if (fs.statSync(full).isDirectory()) {
|
|
463
|
+
if (!this.shouldIgnoreDir(full))
|
|
464
|
+
this.watchTree(full, /* markExisting */ true);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
catch {
|
|
469
|
+
// deleted/inaccessible — treat as a normal change below
|
|
470
|
+
}
|
|
471
|
+
this.handleChange((0, utils_1.normalizePath)(path.relative(this.projectRoot, full)));
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Shared change handler for both watch strategies. `rel` is a
|
|
475
|
+
* project-relative POSIX path. Applies the ignore + source-file filters and,
|
|
476
|
+
* for a real source change, records it as pending (#403) and schedules a
|
|
477
|
+
* debounced sync.
|
|
478
|
+
*
|
|
479
|
+
* The recursive (macOS/Windows) watcher reports events for ignored trees too
|
|
480
|
+
* (one stream covers the whole repo), so the ignore check here is load-bearing
|
|
481
|
+
* — it drops node_modules/dist/.git churn before any sync is scheduled.
|
|
482
|
+
*/
|
|
483
|
+
handleChange(rel) {
|
|
484
|
+
if (!rel || rel === '.' || rel.startsWith('..'))
|
|
485
|
+
return;
|
|
486
|
+
if (this.isAlwaysIgnored(rel))
|
|
487
|
+
return;
|
|
488
|
+
if (this.ignoreMatcher && this.ignoreMatcher.ignores(rel))
|
|
489
|
+
return;
|
|
490
|
+
if (!(0, extraction_1.isSourceFile)(rel, (0, project_config_1.loadExtensionOverrides)(this.projectRoot)))
|
|
491
|
+
return;
|
|
492
|
+
(0, errors_1.logDebug)('File change detected', { file: rel });
|
|
493
|
+
if (this.ready) {
|
|
494
|
+
const now = Date.now();
|
|
495
|
+
const existing = this.pendingFiles.get(rel);
|
|
496
|
+
this.pendingFiles.set(rel, {
|
|
497
|
+
firstSeenMs: existing?.firstSeenMs ?? now,
|
|
498
|
+
lastSeenMs: now,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
this.scheduleSync();
|
|
502
|
+
}
|
|
503
|
+
/** Close and forget the watch for a directory that errored/was removed. */
|
|
504
|
+
unwatchDir(dir) {
|
|
505
|
+
const w = this.dirWatchers.get(dir);
|
|
506
|
+
if (w) {
|
|
507
|
+
try {
|
|
508
|
+
w.close();
|
|
509
|
+
}
|
|
510
|
+
catch {
|
|
511
|
+
/* already closed */
|
|
512
|
+
}
|
|
513
|
+
this.dirWatchers.delete(dir);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
/** Our own dirs are always ignored, regardless of .gitignore. */
|
|
517
|
+
isAlwaysIgnored(rel) {
|
|
518
|
+
// First path segment. Ignore any CodeGraph data dir — the active one AND a
|
|
519
|
+
// sibling like `.cgraphx-win` a second environment (Windows/WSL) created
|
|
520
|
+
// in the same tree, so neither side watches the other's index (#636).
|
|
521
|
+
const top = rel.split('/')[0] ?? rel;
|
|
522
|
+
return ((0, directory_1.isCodeGraphDataDir)(top) ||
|
|
523
|
+
rel === '.git' || rel.startsWith('.git/'));
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* True for any directory that should NOT be watched (used while building the
|
|
527
|
+
* Linux per-directory watch tree). Tests the directory form of the path so a
|
|
528
|
+
* dir-only ignore rule like `build/` matches.
|
|
529
|
+
*/
|
|
530
|
+
shouldIgnoreDir(dirPath) {
|
|
531
|
+
const rel = (0, utils_1.normalizePath)(path.relative(this.projectRoot, dirPath));
|
|
532
|
+
if (!rel || rel === '.' || rel.startsWith('..'))
|
|
533
|
+
return false; // root / outside
|
|
534
|
+
if (this.isAlwaysIgnored(rel))
|
|
535
|
+
return true;
|
|
536
|
+
if (!this.ignoreMatcher)
|
|
537
|
+
return false;
|
|
538
|
+
return this.ignoreMatcher.ignores(rel + '/');
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Permanently disable live watching after a terminal runtime failure
|
|
542
|
+
* (watch-resource exhaustion, or lock contention past the retry budget).
|
|
543
|
+
* Idempotent: logs one actionable warning, fires {@link WatchOptions.onDegraded}
|
|
544
|
+
* once, and stops the watcher. A subsequent start() clears the latch.
|
|
545
|
+
*/
|
|
546
|
+
degrade(reason, context = {}) {
|
|
547
|
+
if (this.degradedReason)
|
|
548
|
+
return;
|
|
549
|
+
this.degradedReason = reason;
|
|
550
|
+
(0, errors_1.logWarn)('File watcher disabled', { projectRoot: this.projectRoot, reason, ...context });
|
|
551
|
+
this.onDegraded?.(reason);
|
|
552
|
+
this.stop();
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Warn ONCE that the Linux inotify watch budget is exhausted (ENOSPC), and
|
|
556
|
+
* stop adding new watches for the rest of this session — every further
|
|
557
|
+
* `inotify_add_watch` would fail too, so walking the rest of the tree is
|
|
558
|
+
* waste. Unlike {@link degrade} this is NON-fatal: the watches already
|
|
559
|
+
* installed keep firing, and `cgraphx sync` covers the unwatched remainder.
|
|
560
|
+
* The message names the kernel knob to raise (`fs.inotify.max_user_watches`).
|
|
561
|
+
*/
|
|
562
|
+
warnInotifyLimit(context = {}) {
|
|
563
|
+
if (this.inotifyLimitWarned)
|
|
564
|
+
return;
|
|
565
|
+
this.inotifyLimitWarned = true;
|
|
566
|
+
(0, errors_1.logWarn)(INOTIFY_LIMIT_REASON, { watchedDirs: this.dirWatchers.size, ...context });
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Whether live watching has degraded permanently (until the next start()).
|
|
570
|
+
* Distinct from {@link isActive}: a degraded watcher is inactive, but an
|
|
571
|
+
* inactive watcher is not necessarily degraded (it may simply be stopped or
|
|
572
|
+
* never started). Hosts use this to tell the user auto-sync is off.
|
|
573
|
+
*/
|
|
574
|
+
isDegraded() {
|
|
575
|
+
return this.degradedReason !== null;
|
|
576
|
+
}
|
|
577
|
+
/** The reason live watching degraded, or null if it is healthy. */
|
|
578
|
+
getDegradedReason() {
|
|
579
|
+
return this.degradedReason;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Stop watching for file changes.
|
|
583
|
+
*/
|
|
584
|
+
stop() {
|
|
585
|
+
this.stopped = true;
|
|
586
|
+
if (this.debounceTimer) {
|
|
587
|
+
clearTimeout(this.debounceTimer);
|
|
588
|
+
this.debounceTimer = null;
|
|
589
|
+
}
|
|
590
|
+
if (this.recursiveWatcher) {
|
|
591
|
+
try {
|
|
592
|
+
this.recursiveWatcher.close();
|
|
593
|
+
}
|
|
594
|
+
catch {
|
|
595
|
+
/* already closed */
|
|
596
|
+
}
|
|
597
|
+
this.recursiveWatcher = null;
|
|
598
|
+
}
|
|
599
|
+
for (const w of this.dirWatchers.values()) {
|
|
600
|
+
try {
|
|
601
|
+
w.close();
|
|
602
|
+
}
|
|
603
|
+
catch {
|
|
604
|
+
/* already closed */
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
this.dirWatchers.clear();
|
|
608
|
+
this.dirCapWarned = false;
|
|
609
|
+
this.inotifyLimitWarned = false;
|
|
610
|
+
this.lockRetryCount = 0;
|
|
611
|
+
// NB: degradedReason is intentionally NOT reset here — it must survive the
|
|
612
|
+
// stop() that degrade() triggers so isDegraded() stays true. start() clears it.
|
|
613
|
+
this.inert = false;
|
|
614
|
+
this.pendingFiles.clear();
|
|
615
|
+
this.ready = false;
|
|
616
|
+
this.ignoreMatcher = null;
|
|
617
|
+
if (IS_TEST_RUNTIME)
|
|
618
|
+
liveWatchersForTests.delete(this.projectRoot);
|
|
619
|
+
(0, errors_1.logDebug)('File watcher stopped');
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* @internal Test-only: feed a synthetic project-relative change through the
|
|
623
|
+
* same filter → pendingFiles → debounced-sync path a real fs.watch event
|
|
624
|
+
* takes. Lets the watcher / staleness-banner suites stay deterministic
|
|
625
|
+
* instead of racing on OS watch-delivery latency. See
|
|
626
|
+
* {@link __emitWatchEventForTests}.
|
|
627
|
+
*/
|
|
628
|
+
ingestEventForTests(relPath) {
|
|
629
|
+
this.handleChange((0, utils_1.normalizePath)(relPath));
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Whether the watcher is currently active.
|
|
633
|
+
*/
|
|
634
|
+
isActive() {
|
|
635
|
+
return (this.recursiveWatcher !== null || this.dirWatchers.size > 0 || this.inert) && !this.stopped;
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Resolves once the watch set has been installed (or immediately if it
|
|
639
|
+
* already has). Useful for tests that need a deterministic boundary before
|
|
640
|
+
* asserting on `pendingFiles`.
|
|
641
|
+
*
|
|
642
|
+
* Production callers don't need this: `pendingFiles` is read continuously,
|
|
643
|
+
* the staleness banner is always correct (empty or populated), and there is
|
|
644
|
+
* no asynchronous initial-scan window with `fs.watch`.
|
|
645
|
+
*/
|
|
646
|
+
waitUntilReady(timeoutMs = 10000) {
|
|
647
|
+
if (this.ready)
|
|
648
|
+
return Promise.resolve();
|
|
649
|
+
return new Promise((resolve, reject) => {
|
|
650
|
+
const t = setTimeout(() => {
|
|
651
|
+
const idx = this.readyWaiters.indexOf(handler);
|
|
652
|
+
if (idx >= 0)
|
|
653
|
+
this.readyWaiters.splice(idx, 1);
|
|
654
|
+
reject(new Error(`FileWatcher.waitUntilReady timed out after ${timeoutMs}ms`));
|
|
655
|
+
}, timeoutMs);
|
|
656
|
+
const handler = () => { clearTimeout(t); resolve(); };
|
|
657
|
+
this.readyWaiters.push(handler);
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Schedule a normal debounced sync after a source edit.
|
|
662
|
+
*/
|
|
663
|
+
scheduleSync() {
|
|
664
|
+
if (this.debounceTimer) {
|
|
665
|
+
clearTimeout(this.debounceTimer);
|
|
666
|
+
}
|
|
667
|
+
this.debounceTimer = setTimeout(() => {
|
|
668
|
+
this.debounceTimer = null;
|
|
669
|
+
this.flush();
|
|
670
|
+
}, this.debounceMs);
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Schedule a retry after a recoverable sync failure (lock contention). Kept
|
|
674
|
+
* separate from {@link scheduleSync} so prolonged contention backs off
|
|
675
|
+
* exponentially instead of hammering the lock every debounce cycle.
|
|
676
|
+
*/
|
|
677
|
+
scheduleRetrySync(delayMs) {
|
|
678
|
+
if (this.debounceTimer) {
|
|
679
|
+
clearTimeout(this.debounceTimer);
|
|
680
|
+
}
|
|
681
|
+
this.debounceTimer = setTimeout(() => {
|
|
682
|
+
this.debounceTimer = null;
|
|
683
|
+
this.flush();
|
|
684
|
+
}, delayMs);
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Flush pending changes by running sync.
|
|
688
|
+
*
|
|
689
|
+
* pendingFiles is NOT cleared at the start of sync — entries are removed
|
|
690
|
+
* only after sync commits successfully, and only for entries whose
|
|
691
|
+
* lastSeenMs <= syncStartedMs. That way, a query that arrives mid-sync
|
|
692
|
+
* still sees the affected files marked stale (the DB hasn't been updated
|
|
693
|
+
* yet), and an event that lands mid-sync persists into the follow-up.
|
|
694
|
+
*
|
|
695
|
+
* On sync failure pendingFiles is left untouched — every edit is still
|
|
696
|
+
* unindexed, and the rescheduled sync will absorb the same set next time.
|
|
697
|
+
*/
|
|
698
|
+
async flush() {
|
|
699
|
+
// If already syncing, the post-sync check will re-trigger
|
|
700
|
+
if (this.syncing || this.stopped)
|
|
701
|
+
return;
|
|
702
|
+
this.syncStartedMs = Date.now();
|
|
703
|
+
this.syncing = true;
|
|
704
|
+
try {
|
|
705
|
+
const result = await this.syncFn();
|
|
706
|
+
this.lockRetryCount = 0; // a clean sync clears any contention backoff
|
|
707
|
+
// Remove entries whose most recent event predates this sync — those
|
|
708
|
+
// edits are now in the DB. Entries with lastSeenMs > syncStartedMs
|
|
709
|
+
// arrived mid-sync; whether the in-flight sync captured them depends
|
|
710
|
+
// on when sync read that file, so we keep them as pending and let
|
|
711
|
+
// the follow-up sync handle them. We prefer false positives ("shown
|
|
712
|
+
// stale, actually fresh" → at worst one extra Read) over false
|
|
713
|
+
// negatives ("shown fresh, actually stale" → misleads the agent).
|
|
714
|
+
for (const [filePath, info] of this.pendingFiles) {
|
|
715
|
+
if (info.lastSeenMs <= this.syncStartedMs) {
|
|
716
|
+
this.pendingFiles.delete(filePath);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
this.onSyncComplete?.(result);
|
|
720
|
+
}
|
|
721
|
+
catch (err) {
|
|
722
|
+
if (err instanceof LockUnavailableError) {
|
|
723
|
+
this.lockRetryCount += 1;
|
|
724
|
+
// Lock-failure no-op (another writer holds the lock). pendingFiles
|
|
725
|
+
// stays intact and the `finally` block reschedules with backoff. Keep
|
|
726
|
+
// brief contention quiet (debug-only — a long external index would
|
|
727
|
+
// otherwise spam stderr every cycle), but stop retrying forever: once a
|
|
728
|
+
// writer holds the lock past the budget, degrade auto-sync explicitly.
|
|
729
|
+
(0, errors_1.logDebug)('Watch sync skipped: file lock unavailable', {
|
|
730
|
+
pendingFiles: this.pendingFiles.size,
|
|
731
|
+
retryCount: this.lockRetryCount,
|
|
732
|
+
});
|
|
733
|
+
if (this.lockRetryCount > MAX_LOCK_RETRIES) {
|
|
734
|
+
this.degrade('cgraphx file lock held by another process past the retry budget; ' +
|
|
735
|
+
'auto-sync disabled. Run `cgraphx sync` once the other writer finishes ' +
|
|
736
|
+
'(or install git sync hooks) to refresh the graph.', { pendingFiles: this.pendingFiles.size, retryCount: this.lockRetryCount });
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
this.lockRetryCount = 0; // a non-lock failure isn't contention; reset backoff
|
|
741
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
742
|
+
(0, errors_1.logWarn)('Watch sync failed', { error: error.message });
|
|
743
|
+
this.onSyncError?.(error);
|
|
744
|
+
}
|
|
745
|
+
// Failure: leave pendingFiles untouched. Every edit it tracks is
|
|
746
|
+
// still unindexed; the rescheduled sync sees the same set.
|
|
747
|
+
}
|
|
748
|
+
finally {
|
|
749
|
+
this.syncing = false;
|
|
750
|
+
// If pending files remain (mid-sync events, or this sync failed),
|
|
751
|
+
// schedule another pass. After lock contention, back off exponentially
|
|
752
|
+
// (debounceMs · 2^(n-1), capped) instead of retrying at the normal
|
|
753
|
+
// debounce cadence; a clean sync resets lockRetryCount so normal edits
|
|
754
|
+
// keep the fast debounce. A degrade() above already set `stopped`, so
|
|
755
|
+
// this won't reschedule a watcher that has given up.
|
|
756
|
+
if (this.pendingFiles.size > 0 && !this.stopped) {
|
|
757
|
+
if (this.lockRetryCount > 0) {
|
|
758
|
+
const retryDelayMs = Math.min(this.debounceMs * 2 ** Math.max(0, this.lockRetryCount - 1), MAX_LOCK_RETRY_DELAY_MS);
|
|
759
|
+
this.scheduleRetrySync(retryDelayMs);
|
|
760
|
+
}
|
|
761
|
+
else {
|
|
762
|
+
this.scheduleSync();
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Snapshot of files seen by the watcher since the last successful sync.
|
|
769
|
+
*
|
|
770
|
+
* Used by MCP tool responses to mark stale results without blocking on a
|
|
771
|
+
* sync: a tool that returns a hit in `src/foo.ts` while `src/foo.ts` is in
|
|
772
|
+
* this list tells the agent "Read this file directly, the index lags."
|
|
773
|
+
*
|
|
774
|
+
* `indexing` is true when a sync is currently in flight whose start time is
|
|
775
|
+
* AFTER this file's most recent event — i.e. that sync will absorb the
|
|
776
|
+
* edit. False means the file is still inside the debounce window and no
|
|
777
|
+
* sync has started yet (a follow-up call a few hundred ms later may show
|
|
778
|
+
* `indexing: true` or the file may have left the list entirely).
|
|
779
|
+
*
|
|
780
|
+
* Cheap: O(pendingFiles.size), no I/O, no locks.
|
|
781
|
+
*/
|
|
782
|
+
getPendingFiles() {
|
|
783
|
+
const result = [];
|
|
784
|
+
for (const [filePath, info] of this.pendingFiles) {
|
|
785
|
+
result.push({
|
|
786
|
+
path: filePath,
|
|
787
|
+
firstSeenMs: info.firstSeenMs,
|
|
788
|
+
lastSeenMs: info.lastSeenMs,
|
|
789
|
+
indexing: this.syncing && this.syncStartedMs >= info.lastSeenMs,
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
return result;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
exports.FileWatcher = FileWatcher;
|
|
796
|
+
/**
|
|
797
|
+
* Test-only: synthesize a source-file change for the live watcher running at
|
|
798
|
+
* `projectRoot`, exercising the real filter → pendingFiles → debounced-sync
|
|
799
|
+
* logic without depending on fs.watch delivery timing (which races under
|
|
800
|
+
* parallel vitest). `relPath` is project-relative POSIX (e.g. "src/foo.ts").
|
|
801
|
+
* Returns false if no live watcher is registered for that root (e.g. outside a
|
|
802
|
+
* test runtime, where the registry is intentionally not populated).
|
|
803
|
+
*/
|
|
804
|
+
function __emitWatchEventForTests(projectRoot, relPath) {
|
|
805
|
+
const w = liveWatchersForTests.get(projectRoot);
|
|
806
|
+
if (!w)
|
|
807
|
+
return false;
|
|
808
|
+
w.ingestEventForTests(relPath);
|
|
809
|
+
return true;
|
|
810
|
+
}
|
|
811
|
+
//# sourceMappingURL=watcher.js.map
|