@rkarim08/sia 1.0.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/.claude-plugin/marketplace.json +35 -0
- package/.claude-plugin/plugin.json +27 -0
- package/.mcp.json +13 -0
- package/CLAUDE.md +226 -0
- package/LICENSE +202 -0
- package/PLUGIN_README.md +253 -0
- package/README.md +1013 -0
- package/agents/sia-changelog-writer.md +89 -0
- package/agents/sia-code-reviewer.md +86 -0
- package/agents/sia-conflict-resolver.md +100 -0
- package/agents/sia-convention-enforcer.md +69 -0
- package/agents/sia-debug.md +106 -0
- package/agents/sia-decision-reviewer.md +101 -0
- package/agents/sia-dependency-tracker.md +80 -0
- package/agents/sia-explain.md +126 -0
- package/agents/sia-feature.md +116 -0
- package/agents/sia-knowledge-capture.md +117 -0
- package/agents/sia-lead-architecture-advisor.md +93 -0
- package/agents/sia-lead-team-health.md +107 -0
- package/agents/sia-migration.md +100 -0
- package/agents/sia-onboarding.md +115 -0
- package/agents/sia-orientation.md +99 -0
- package/agents/sia-pm-briefing.md +106 -0
- package/agents/sia-pm-risk-advisor.md +82 -0
- package/agents/sia-qa-analyst.md +116 -0
- package/agents/sia-qa-regression-map.md +94 -0
- package/agents/sia-refactor.md +115 -0
- package/agents/sia-regression.md +112 -0
- package/agents/sia-security-audit.md +125 -0
- package/agents/sia-test-advisor.md +91 -0
- package/hooks/hooks.json +98 -0
- package/migrations/bridge/001_initial.sql +34 -0
- package/migrations/episodic/001_initial.sql +35 -0
- package/migrations/meta/001_initial.sql +68 -0
- package/migrations/semantic/001_initial.sql +292 -0
- package/migrations/semantic/002_ontology.sql +89 -0
- package/migrations/semantic/003_freshness.sql +63 -0
- package/migrations/semantic/004_v5_unified_schema.sql +194 -0
- package/migrations/semantic/005_backfill_event_kinds.sql +8 -0
- package/migrations/semantic/006_tree_sitter.sql +6 -0
- package/migrations/semantic/007_branch_snapshots.sql +22 -0
- package/package.json +110 -0
- package/scripts/branch-switch.sh +13 -0
- package/scripts/build-wasm-grammars.sh +81 -0
- package/scripts/post-compact.sh +8 -0
- package/scripts/post-tool-use.sh +10 -0
- package/scripts/pre-compact.sh +8 -0
- package/scripts/session-end.sh +8 -0
- package/scripts/session-start.sh +8 -0
- package/scripts/start-mcp.ts +45 -0
- package/scripts/stop-hook.sh +8 -0
- package/scripts/user-prompt-submit.sh +8 -0
- package/scripts/viz-server.ts +152 -0
- package/skills/sia-brainstorm/SKILL.md +156 -0
- package/skills/sia-brainstorm/scripts/frame-template.html +214 -0
- package/skills/sia-brainstorm/scripts/helper.js +95 -0
- package/skills/sia-brainstorm/scripts/server.cjs +338 -0
- package/skills/sia-brainstorm/scripts/start-server.sh +153 -0
- package/skills/sia-brainstorm/scripts/stop-server.sh +55 -0
- package/skills/sia-brainstorm/spec-document-reviewer-prompt.md +49 -0
- package/skills/sia-brainstorm/visual-companion.md +286 -0
- package/skills/sia-capture/SKILL.md +64 -0
- package/skills/sia-compare/SKILL.md +33 -0
- package/skills/sia-conflicts/SKILL.md +38 -0
- package/skills/sia-debug-workflow/SKILL.md +120 -0
- package/skills/sia-debug-workflow/root-cause-tracing.md +70 -0
- package/skills/sia-debug-workflow/scripts/find-polluter.sh +64 -0
- package/skills/sia-debug-workflow/temporal-investigation.md +72 -0
- package/skills/sia-digest/SKILL.md +23 -0
- package/skills/sia-dispatch/SKILL.md +69 -0
- package/skills/sia-dispatch/agent-task-template.md +99 -0
- package/skills/sia-doctor/SKILL.md +39 -0
- package/skills/sia-execute/SKILL.md +70 -0
- package/skills/sia-execute-plan/SKILL.md +85 -0
- package/skills/sia-export-import/SKILL.md +49 -0
- package/skills/sia-export-knowledge/SKILL.md +46 -0
- package/skills/sia-finish/SKILL.md +100 -0
- package/skills/sia-finish/pr-summary-template.md +54 -0
- package/skills/sia-freshness/SKILL.md +38 -0
- package/skills/sia-history/SKILL.md +42 -0
- package/skills/sia-impact/SKILL.md +70 -0
- package/skills/sia-index/SKILL.md +54 -0
- package/skills/sia-install/SKILL.md +39 -0
- package/skills/sia-lead-compliance/SKILL.md +16 -0
- package/skills/sia-lead-drift-report/SKILL.md +16 -0
- package/skills/sia-lead-knowledge-map/SKILL.md +16 -0
- package/skills/sia-learn/SKILL.md +58 -0
- package/skills/sia-plan/SKILL.md +68 -0
- package/skills/sia-plan/plan-reviewer-prompt.md +63 -0
- package/skills/sia-playbooks/SKILL.md +29 -0
- package/skills/sia-playbooks/reference-feature.md +100 -0
- package/skills/sia-playbooks/reference-flagging.md +50 -0
- package/skills/sia-playbooks/reference-orientation.md +92 -0
- package/skills/sia-playbooks/reference-regression.md +115 -0
- package/skills/sia-playbooks/reference-review.md +64 -0
- package/skills/sia-playbooks/reference-tools.md +239 -0
- package/skills/sia-pm-decision-log/SKILL.md +28 -0
- package/skills/sia-pm-risk-dashboard/SKILL.md +24 -0
- package/skills/sia-pm-sprint-summary/SKILL.md +27 -0
- package/skills/sia-prune/SKILL.md +45 -0
- package/skills/sia-qa-coverage/SKILL.md +28 -0
- package/skills/sia-qa-flaky/SKILL.md +20 -0
- package/skills/sia-qa-report/SKILL.md +26 -0
- package/skills/sia-reindex/SKILL.md +30 -0
- package/skills/sia-review-respond/SKILL.md +88 -0
- package/skills/sia-review-respond/pushback-patterns.md +90 -0
- package/skills/sia-search/SKILL.md +47 -0
- package/skills/sia-setup/SKILL.md +82 -0
- package/skills/sia-setup/setup-checklist.md +97 -0
- package/skills/sia-stats/SKILL.md +36 -0
- package/skills/sia-status/SKILL.md +44 -0
- package/skills/sia-sync/SKILL.md +46 -0
- package/skills/sia-team/SKILL.md +64 -0
- package/skills/sia-test/SKILL.md +92 -0
- package/skills/sia-test/testing-anti-patterns.md +104 -0
- package/skills/sia-tour/SKILL.md +29 -0
- package/skills/sia-upgrade/SKILL.md +43 -0
- package/skills/sia-verify/SKILL.md +81 -0
- package/skills/sia-visualize/SKILL.md +28 -0
- package/skills/sia-visualize-live/SKILL.md +55 -0
- package/skills/sia-visualize-live/scripts/graph-template.html +389 -0
- package/skills/sia-visualize-live/scripts/start-visualizer.sh +161 -0
- package/skills/sia-visualize-live/scripts/stop-visualizer.sh +55 -0
- package/skills/sia-visualize-live/scripts/visualizer-server.cjs +264 -0
- package/skills/sia-workspace/SKILL.md +57 -0
- package/src/agent/claude-md-template-flagging.md +219 -0
- package/src/agent/claude-md-template.md +213 -0
- package/src/agent/modules/sia-feature.md +100 -0
- package/src/agent/modules/sia-flagging.md +50 -0
- package/src/agent/modules/sia-orientation.md +92 -0
- package/src/agent/modules/sia-regression.md +115 -0
- package/src/agent/modules/sia-review.md +64 -0
- package/src/agent/modules/sia-tools.md +239 -0
- package/src/ast/extractors/c-include.ts +189 -0
- package/src/ast/extractors/csharp-project.ts +260 -0
- package/src/ast/extractors/prisma-schema.ts +44 -0
- package/src/ast/extractors/project-manifest.ts +111 -0
- package/src/ast/extractors/sql-schema.ts +67 -0
- package/src/ast/extractors/tier-a.ts +423 -0
- package/src/ast/extractors/tier-b.ts +289 -0
- package/src/ast/extractors/tier-dispatch.ts +247 -0
- package/src/ast/index-worker.ts +108 -0
- package/src/ast/indexer.ts +484 -0
- package/src/ast/languages.ts +408 -0
- package/src/ast/pagerank-builder.ts +125 -0
- package/src/ast/path-utils.ts +137 -0
- package/src/ast/tree-sitter/backends/native.ts +57 -0
- package/src/ast/tree-sitter/backends/wasm.ts +39 -0
- package/src/ast/tree-sitter/call-walker.ts +44 -0
- package/src/ast/tree-sitter/edit-computer.ts +55 -0
- package/src/ast/tree-sitter/query-runner.ts +46 -0
- package/src/ast/tree-sitter/service.ts +174 -0
- package/src/ast/tree-sitter/tree-cache.ts +39 -0
- package/src/ast/tree-sitter/types.ts +79 -0
- package/src/ast/watcher.ts +322 -0
- package/src/capture/chunker.ts +169 -0
- package/src/capture/consolidate.ts +127 -0
- package/src/capture/edge-inferrer.ts +161 -0
- package/src/capture/embedder.ts +166 -0
- package/src/capture/embedding-cache.ts +73 -0
- package/src/capture/flag-processor.ts +64 -0
- package/src/capture/hook.ts +67 -0
- package/src/capture/pipeline.ts +450 -0
- package/src/capture/prompts/consolidate.ts +25 -0
- package/src/capture/prompts/edge-infer.ts +29 -0
- package/src/capture/prompts/extract-flagged.ts +36 -0
- package/src/capture/prompts/extract.ts +42 -0
- package/src/capture/tokenizer.ts +147 -0
- package/src/capture/track-a-ast.ts +93 -0
- package/src/capture/track-b-llm.ts +149 -0
- package/src/capture/types.ts +64 -0
- package/src/cli/commands/community.ts +137 -0
- package/src/cli/commands/compare.ts +123 -0
- package/src/cli/commands/conflicts.ts +41 -0
- package/src/cli/commands/digest.ts +197 -0
- package/src/cli/commands/disable-flagging.ts +34 -0
- package/src/cli/commands/doctor.ts +240 -0
- package/src/cli/commands/download-model.ts +161 -0
- package/src/cli/commands/enable-flagging.ts +34 -0
- package/src/cli/commands/export-knowledge.ts +208 -0
- package/src/cli/commands/export.ts +85 -0
- package/src/cli/commands/freshness.ts +164 -0
- package/src/cli/commands/graph.ts +51 -0
- package/src/cli/commands/history.ts +139 -0
- package/src/cli/commands/import.ts +335 -0
- package/src/cli/commands/install.ts +156 -0
- package/src/cli/commands/lead-report.ts +241 -0
- package/src/cli/commands/learn.ts +321 -0
- package/src/cli/commands/pm-report.ts +413 -0
- package/src/cli/commands/prune.ts +75 -0
- package/src/cli/commands/qa-report.ts +278 -0
- package/src/cli/commands/reindex.ts +104 -0
- package/src/cli/commands/rollback.ts +70 -0
- package/src/cli/commands/search.ts +103 -0
- package/src/cli/commands/server.ts +91 -0
- package/src/cli/commands/share.ts +33 -0
- package/src/cli/commands/stats.ts +79 -0
- package/src/cli/commands/status.ts +176 -0
- package/src/cli/commands/sync.ts +96 -0
- package/src/cli/commands/team.ts +118 -0
- package/src/cli/commands/tour.ts +157 -0
- package/src/cli/commands/visualize-live.ts +162 -0
- package/src/cli/commands/workspace.ts +117 -0
- package/src/cli/index.ts +424 -0
- package/src/cli/learn-progress.ts +87 -0
- package/src/community/detection-bridge.ts +344 -0
- package/src/community/leiden.ts +462 -0
- package/src/community/raptor.ts +210 -0
- package/src/community/scheduler.ts +74 -0
- package/src/community/summarize.ts +115 -0
- package/src/decay/archiver.ts +73 -0
- package/src/decay/bridge-orphan-cleanup.ts +212 -0
- package/src/decay/consolidation-sweep.ts +112 -0
- package/src/decay/decay.ts +116 -0
- package/src/decay/deep-validator.ts +62 -0
- package/src/decay/episodic-promoter.ts +132 -0
- package/src/decay/maintenance-scheduler.ts +326 -0
- package/src/decay/scheduler.ts +6 -0
- package/src/decay/session-sweeper.ts +79 -0
- package/src/decay/types.ts +17 -0
- package/src/freshness/confidence-decay.ts +122 -0
- package/src/freshness/cuckoo-filter.ts +176 -0
- package/src/freshness/deep-validation.ts +345 -0
- package/src/freshness/dirty-tracker.ts +237 -0
- package/src/freshness/file-watcher-layer.ts +119 -0
- package/src/freshness/firewall.ts +64 -0
- package/src/freshness/git-reconcile-layer.ts +161 -0
- package/src/freshness/inverted-index.ts +158 -0
- package/src/freshness/stale-read-layer.ts +222 -0
- package/src/graph/audit.ts +69 -0
- package/src/graph/bridge-db.ts +141 -0
- package/src/graph/communities.ts +195 -0
- package/src/graph/db-interface.ts +259 -0
- package/src/graph/edges.ts +163 -0
- package/src/graph/entities.ts +327 -0
- package/src/graph/episodic-db.ts +113 -0
- package/src/graph/flags.ts +31 -0
- package/src/graph/meta-db.ts +200 -0
- package/src/graph/semantic-db.ts +101 -0
- package/src/graph/session-resume.ts +56 -0
- package/src/graph/snapshots.ts +342 -0
- package/src/graph/staging.ts +151 -0
- package/src/graph/types.ts +128 -0
- package/src/hooks/adapters/claude-code.ts +21 -0
- package/src/hooks/adapters/cline.ts +43 -0
- package/src/hooks/adapters/cursor.ts +65 -0
- package/src/hooks/adapters/generic.ts +12 -0
- package/src/hooks/agent-detect.ts +34 -0
- package/src/hooks/claude-md-directives.ts +32 -0
- package/src/hooks/event-router.ts +182 -0
- package/src/hooks/extractors/pattern-detector.ts +111 -0
- package/src/hooks/handlers/post-compact.ts +30 -0
- package/src/hooks/handlers/post-tool-use.ts +403 -0
- package/src/hooks/handlers/pre-compact.ts +100 -0
- package/src/hooks/handlers/session-end.ts +47 -0
- package/src/hooks/handlers/session-start.ts +154 -0
- package/src/hooks/handlers/stop.ts +128 -0
- package/src/hooks/handlers/user-prompt-submit.ts +68 -0
- package/src/hooks/plugin-branch-switch.ts +68 -0
- package/src/hooks/plugin-common.ts +47 -0
- package/src/hooks/plugin-post-compact.ts +28 -0
- package/src/hooks/plugin-post-tool-use.ts +38 -0
- package/src/hooks/plugin-pre-compact.ts +37 -0
- package/src/hooks/plugin-session-end.ts +37 -0
- package/src/hooks/plugin-session-start.ts +75 -0
- package/src/hooks/plugin-stop.ts +61 -0
- package/src/hooks/plugin-user-prompt-submit.ts +47 -0
- package/src/hooks/types.ts +43 -0
- package/src/knowledge/discovery.ts +238 -0
- package/src/knowledge/external-refs.ts +98 -0
- package/src/knowledge/freshness.ts +221 -0
- package/src/knowledge/ingest.ts +330 -0
- package/src/knowledge/markdown-export.ts +229 -0
- package/src/knowledge/markdown-import.ts +359 -0
- package/src/knowledge/patterns.ts +74 -0
- package/src/knowledge/templates.ts +307 -0
- package/src/llm/ai-sdk-adapter.ts +46 -0
- package/src/llm/config.ts +88 -0
- package/src/llm/cost-tracker.ts +110 -0
- package/src/llm/prompts/extraction.ts +55 -0
- package/src/llm/prompts/summarization.ts +36 -0
- package/src/llm/prompts/validation.ts +37 -0
- package/src/llm/provider-registry.ts +68 -0
- package/src/llm/reliability.ts +179 -0
- package/src/llm/schemas.ts +52 -0
- package/src/mcp/freshness-annotator.ts +69 -0
- package/src/mcp/server.ts +949 -0
- package/src/mcp/tools/sia-ast-query.ts +225 -0
- package/src/mcp/tools/sia-at-time.ts +151 -0
- package/src/mcp/tools/sia-backlinks.ts +87 -0
- package/src/mcp/tools/sia-batch-execute.ts +169 -0
- package/src/mcp/tools/sia-by-file.ts +89 -0
- package/src/mcp/tools/sia-community.ts +113 -0
- package/src/mcp/tools/sia-doctor.ts +73 -0
- package/src/mcp/tools/sia-execute-file.ts +122 -0
- package/src/mcp/tools/sia-execute.ts +104 -0
- package/src/mcp/tools/sia-expand.ts +158 -0
- package/src/mcp/tools/sia-fetch-and-index.ts +241 -0
- package/src/mcp/tools/sia-flag.ts +65 -0
- package/src/mcp/tools/sia-index.ts +111 -0
- package/src/mcp/tools/sia-note.ts +134 -0
- package/src/mcp/tools/sia-search.ts +105 -0
- package/src/mcp/tools/sia-stats.ts +63 -0
- package/src/mcp/tools/sia-sync-status.ts +44 -0
- package/src/mcp/tools/sia-upgrade.ts +247 -0
- package/src/mcp/truncate.ts +231 -0
- package/src/native/bridge.ts +167 -0
- package/src/native/fallback-ast-diff.ts +144 -0
- package/src/native/fallback-graph.ts +325 -0
- package/src/ontology/constraints.ts +56 -0
- package/src/ontology/errors.ts +8 -0
- package/src/ontology/middleware.ts +266 -0
- package/src/retrieval/bm25-search.ts +151 -0
- package/src/retrieval/context-assembly.ts +76 -0
- package/src/retrieval/graph-traversal.ts +168 -0
- package/src/retrieval/pagerank.ts +40 -0
- package/src/retrieval/query-classifier.ts +106 -0
- package/src/retrieval/reranker.ts +156 -0
- package/src/retrieval/search.ts +236 -0
- package/src/retrieval/throttle.ts +102 -0
- package/src/retrieval/vector-search.ts +203 -0
- package/src/retrieval/workspace-search.ts +130 -0
- package/src/sandbox/context-mode.ts +285 -0
- package/src/sandbox/credential-pass.ts +55 -0
- package/src/sandbox/executor.ts +235 -0
- package/src/security/pattern-detector.ts +127 -0
- package/src/security/rule-of-two.ts +50 -0
- package/src/security/sanitize.ts +46 -0
- package/src/security/semantic-consistency.ts +93 -0
- package/src/security/staging-promoter.ts +154 -0
- package/src/shared/config.ts +302 -0
- package/src/shared/diagnostics.ts +210 -0
- package/src/shared/errors.ts +48 -0
- package/src/shared/git-utils.ts +143 -0
- package/src/shared/llm-client.ts +120 -0
- package/src/shared/logger.ts +99 -0
- package/src/shared/types.ts +79 -0
- package/src/sync/client.ts +43 -0
- package/src/sync/conflict.ts +106 -0
- package/src/sync/dedup.ts +183 -0
- package/src/sync/hlc.ts +117 -0
- package/src/sync/keychain.ts +144 -0
- package/src/sync/pull.ts +232 -0
- package/src/sync/push.ts +131 -0
- package/src/types/chokidar.d.ts +23 -0
- package/src/visualization/graph-renderer.ts +312 -0
- package/src/visualization/subgraph-extract.ts +208 -0
- package/src/visualization/views/community-clusters.ts +246 -0
- package/src/visualization/views/dependency-map.ts +189 -0
- package/src/visualization/views/graph-explorer.ts +364 -0
- package/src/visualization/views/timeline.ts +247 -0
- package/src/workspace/api-contracts.ts +226 -0
- package/src/workspace/cross-repo.ts +61 -0
- package/src/workspace/detector.ts +190 -0
- package/src/workspace/manifest.ts +141 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Sia — Regression Investigation Playbook
|
|
2
|
+
|
|
3
|
+
*Loaded by the base CLAUDE.md when `task_type = 'bug-fix'` (regression signal detected).*
|
|
4
|
+
*Follow these steps in order. They replace the condensed Step 1 in the base module.*
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Regression Investigation
|
|
9
|
+
|
|
10
|
+
A regression is any situation where something worked before and is now broken. The key
|
|
11
|
+
capability that distinguishes Sia's regression support from generic memory retrieval is
|
|
12
|
+
`sia_at_time`: it lets you query the graph as it existed at a point in the past, surfacing
|
|
13
|
+
exactly what facts changed between then and now.
|
|
14
|
+
|
|
15
|
+
**Step 1 — Initial search (current state)**
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
sia_search(symptom_description,
|
|
19
|
+
task_type='bug-fix',
|
|
20
|
+
node_types=['Bug', 'Solution', 'Decision'],
|
|
21
|
+
limit=10)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Scan results for entities matching the symptom, affected files, or known related
|
|
25
|
+
components. Look for a prior instance of this bug, a Decision that was recently changed,
|
|
26
|
+
or a Solution that should have prevented this.
|
|
27
|
+
|
|
28
|
+
**Step 2 — Causal chain traversal (conditional)**
|
|
29
|
+
|
|
30
|
+
If a relevant entity is found in Step 1, call:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
sia_expand(entity_id, depth=1, edge_types=['supersedes', 'caused_by', 'solves'])
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This surfaces what superseded the old fact, what caused the bug, and what solutions were
|
|
37
|
+
previously applied. This call is optional — use it only when the Step 1 result points to
|
|
38
|
+
a likely causal chain. It counts against the 2-call sia_expand session budget.
|
|
39
|
+
|
|
40
|
+
**Step 3 — Temporal investigation (MANDATORY — never skip)**
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
// Initial call — use the default limit
|
|
44
|
+
sia_at_time(
|
|
45
|
+
as_of='<estimated date regression began>',
|
|
46
|
+
tags=[<relevant tags>],
|
|
47
|
+
limit=20
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Important: `limit` applies to **both** `entities[]` and `invalidated_entities[]` simultaneously. Bumping `limit` to 50 on a re-call returns 50 current entities alongside 50 invalidated entities — the extra current entities are usually irrelevant to regression work and add response payload that may hit the `maxResponseTokens` cap. Prefer narrowed re-calls over blindly increasing `limit`.
|
|
52
|
+
|
|
53
|
+
If the initial call returns `invalidated_count > invalidated_entities.length` (result is truncated), make a **narrowed follow-up** targeting causally relevant entity types rather than raising `limit` alone:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
// Truncation follow-up — narrow by type to reduce current-entity noise
|
|
57
|
+
sia_at_time(
|
|
58
|
+
as_of='<same date>',
|
|
59
|
+
entity_types=['Decision', 'Solution', 'Bug'], // causally relevant types
|
|
60
|
+
tags=[<relevant tags>],
|
|
61
|
+
limit=50
|
|
62
|
+
)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Without this call, the temporal investigation capability is completely unused. `sia_at_time`
|
|
66
|
+
returns two arrays — read them in this order:
|
|
67
|
+
|
|
68
|
+
`invalidated_entities[]` is the primary diagnostic signal. These are facts that ENDED on
|
|
69
|
+
or before `as_of`. Each entry's `t_valid_until` is exactly when that fact stopped being
|
|
70
|
+
true. **Entries with `t_valid_until` closest to `as_of` are the most temporally
|
|
71
|
+
relevant** — they represent what changed most recently before the regression and are
|
|
72
|
+
therefore the highest-priority root cause candidates. The array is sorted by
|
|
73
|
+
`t_valid_until DESC` so the most relevant entries appear first.
|
|
74
|
+
|
|
75
|
+
`entities[]` contains facts still valid at `as_of`. Compare these against the current
|
|
76
|
+
`sia_search` output to see what has changed since that date.
|
|
77
|
+
|
|
78
|
+
If `invalidated_count > invalidated_entities.length`, the result is truncated. Make
|
|
79
|
+
additional narrowed calls using `entity_types` or `tags` to retrieve the remaining
|
|
80
|
+
entries. Do not treat a truncated result as the complete picture.
|
|
81
|
+
|
|
82
|
+
**Step 4 — Explain the delta**
|
|
83
|
+
|
|
84
|
+
Present the findings to the developer with specific entity citations. The answer to
|
|
85
|
+
"what caused the regression" should be grounded in one or more specific invalidated
|
|
86
|
+
entities, not general speculation.
|
|
87
|
+
|
|
88
|
+
**Step 5 — Flag if applicable**
|
|
89
|
+
|
|
90
|
+
If flagging is enabled (`enableFlagging: true`) and the root cause is non-obvious:
|
|
91
|
+
`sia_flag("Root cause: [description]")`. If flagging is disabled, skip this step.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Edge Types for Regression Investigation
|
|
96
|
+
|
|
97
|
+
When calling `sia_expand` during regression work, these edge types are most diagnostic:
|
|
98
|
+
|
|
99
|
+
`supersedes` — what replaced the old Decision or Solution
|
|
100
|
+
`caused_by` — what entity directly caused this Bug
|
|
101
|
+
`solves` — what Solution was supposed to address this Bug
|
|
102
|
+
`invalidates` — what action marked the old fact as no longer true
|
|
103
|
+
|
|
104
|
+
Use `edge_types=['supersedes','caused_by','solves']` as the default filter for regression
|
|
105
|
+
traversal. This keeps the neighborhood focused on causal relationships rather than
|
|
106
|
+
structural dependencies, which tend to be less diagnostic for regression work.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Tool Budget for This Playbook
|
|
111
|
+
|
|
112
|
+
This playbook uses up to 4 tool calls, which is the permitted exception to the 3-tool
|
|
113
|
+
invariant. The sequence is: `sia_search` (1) + conditional `sia_expand` (2) +
|
|
114
|
+
`sia_at_time` (3) + one additional narrowed `sia_at_time` if truncated (4). If no
|
|
115
|
+
causal entity is found in Step 1, skip `sia_expand` and stay within 3 calls.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Sia — PR / Code Review Playbook
|
|
2
|
+
|
|
3
|
+
*Loaded by the base CLAUDE.md when `task_type = 'review'`.*
|
|
4
|
+
*Follow these steps in order. They replace the condensed Step 1 in the base module.*
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## PR / Code Review
|
|
9
|
+
|
|
10
|
+
Code review with Sia is convention-first: retrieve the full set of project-specific
|
|
11
|
+
conventions before looking at a single line of code. Generic best-practice rules are
|
|
12
|
+
secondary. What matters is whether the change conforms to the patterns this team has
|
|
13
|
+
established in this project.
|
|
14
|
+
|
|
15
|
+
**Step 1 — Convention retrieval**
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
sia_search("conventions standards style patterns",
|
|
19
|
+
task_type='review',
|
|
20
|
+
node_types=['Convention'],
|
|
21
|
+
limit=15)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Use `limit=15` here — this is one of the few contexts where maximum coverage matters
|
|
25
|
+
more than latency. You need the full convention set before evaluating the code.
|
|
26
|
+
|
|
27
|
+
**Step 2 — File-scoped retrieval**
|
|
28
|
+
|
|
29
|
+
For each file in the PR:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
sia_by_file(file_path)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This surfaces decisions, patterns, and prior bug history for each changed file. A file
|
|
36
|
+
that has had recurring bugs around a specific pattern is worth scrutinising more closely.
|
|
37
|
+
|
|
38
|
+
**Step 3 — Evaluate each change**
|
|
39
|
+
|
|
40
|
+
Compare each change against the retrieved conventions and file-specific context. The
|
|
41
|
+
evaluation question is: does this change conform to the conventions the team has
|
|
42
|
+
established, and does it respect the decisions that constrain this file?
|
|
43
|
+
|
|
44
|
+
**Step 4 — Report violations by entity ID**
|
|
45
|
+
|
|
46
|
+
For each violation, cite the specific Convention entity that is breached. Do not
|
|
47
|
+
paraphrase the convention — reference it by ID so the developer can look it up:
|
|
48
|
+
|
|
49
|
+
> "Violation of Convention #conv-44: direct database query in service layer —
|
|
50
|
+
> all DB access must go through the Repository layer per this convention."
|
|
51
|
+
|
|
52
|
+
Never apply only general best-practice conventions. Project-specific conventions
|
|
53
|
+
stored in Sia take precedence and are the primary review criteria.
|
|
54
|
+
|
|
55
|
+
**Step 5 — Summarise**
|
|
56
|
+
|
|
57
|
+
Provide a summary that distinguishes: convention violations (must fix), Sia-unaware
|
|
58
|
+
patterns (worth noting), and items where no convention applies (developer discretion).
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Tool Budget for This Playbook
|
|
63
|
+
|
|
64
|
+
This playbook uses 1 + N tool calls: `sia_search` (1) + `sia_by_file` once per changed file (N calls, one each). The per-file `sia_by_file` calls are permitted by the review exception in Invariant 1 of the base module — they do not count against the 3-tool limit. This exception applies exclusively to `task_type='review'` sessions. Review is inherently multi-file and this budget is appropriate.
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Sia — Full Tool Parameter Reference
|
|
2
|
+
|
|
3
|
+
*Read this module when you need complete parameter documentation for any Sia tool,*
|
|
4
|
+
*or when the base module's condensed guidance is insufficient for the task at hand.*
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## `sia_search` — General Memory Retrieval
|
|
9
|
+
|
|
10
|
+
Your primary tool. Call at the start of every non-trivial task.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
sia_search({
|
|
14
|
+
query: string,
|
|
15
|
+
// Conversational language works well: "session timeout expiry behavior"
|
|
16
|
+
// rather than keyword fragments: "timeout session".
|
|
17
|
+
|
|
18
|
+
task_type?: 'bug-fix' | 'feature' | 'review',
|
|
19
|
+
// Boosts entity types relevant to the task:
|
|
20
|
+
// bug-fix → Bug, Solution, Decision entities ranked higher
|
|
21
|
+
// feature → Concept, Decision entities ranked higher
|
|
22
|
+
// review → Convention entities ranked higher
|
|
23
|
+
|
|
24
|
+
node_types?: string[],
|
|
25
|
+
// Further narrow by type: ['Decision','Convention'], ['Bug','Solution'], etc.
|
|
26
|
+
// Use when you know the category of what you're looking for.
|
|
27
|
+
|
|
28
|
+
package_path?: string,
|
|
29
|
+
// Monorepo: scope to a specific package path. Reduces cross-package noise
|
|
30
|
+
// when working in a single package of a large monorepo.
|
|
31
|
+
|
|
32
|
+
workspace?: boolean,
|
|
33
|
+
// Default false. Set true ONLY for cross-repo tasks: API contracts between
|
|
34
|
+
// linked repositories, shared types, cross-service calls.
|
|
35
|
+
// Never use for single-repo tasks — adds 400ms latency and cross-repo noise.
|
|
36
|
+
|
|
37
|
+
paranoid?: boolean,
|
|
38
|
+
// Default false. Set true when auditing external dependencies or when you want
|
|
39
|
+
// to query the graph without surface-level exposure to Tier 4 content.
|
|
40
|
+
// Filters Tier 4 entities from retrieval results only — does NOT prevent Tier 4
|
|
41
|
+
// content from being captured into the graph, and does NOT guarantee memory
|
|
42
|
+
// integrity.
|
|
43
|
+
//
|
|
44
|
+
// If the developer expresses concern about memory poisoning or graph integrity,
|
|
45
|
+
// paranoid: true on queries is insufficient. Direct them to:
|
|
46
|
+
// paranoidCapture: true in ~/.sia/config.json
|
|
47
|
+
// which quarantines Tier 4 at the chunker stage (the hard guarantee). For past
|
|
48
|
+
// captures, suggest: npx sia rollback to inspect and revert if needed.
|
|
49
|
+
|
|
50
|
+
limit?: number,
|
|
51
|
+
// Default 5. Use 10 for architectural queries. Use 15 ONLY for PR review
|
|
52
|
+
// (full convention coverage required). Never use 15 as a default.
|
|
53
|
+
|
|
54
|
+
include_provenance?: boolean,
|
|
55
|
+
// Default false. When true, adds extraction_method to entity results.
|
|
56
|
+
// WHEN TO USE — set true only when:
|
|
57
|
+
// (a) two Tier 3 results contradict each other (spacy is more reliable
|
|
58
|
+
// than llm-haiku — provenance lets you choose the more reliable one)
|
|
59
|
+
// (b) the developer asks how a fact was captured
|
|
60
|
+
// (c) you are about to use a Tier 3 entity as a hard constraint on a
|
|
61
|
+
// security-critical or data-migration task
|
|
62
|
+
// DO NOT use by default — adds payload for no benefit on routine queries.
|
|
63
|
+
//
|
|
64
|
+
// Values when true:
|
|
65
|
+
// 'tree-sitter' = deterministic AST extraction (Tier 2, fully reliable)
|
|
66
|
+
// 'spacy' = deterministic NLP (Tier 3, highly reliable)
|
|
67
|
+
// 'llm-haiku' = probabilistic LLM extraction (Tier 3, can hallucinate)
|
|
68
|
+
// 'user-direct' = developer stated this explicitly (Tier 1)
|
|
69
|
+
// 'manifest' = declared in .sia-manifest.yaml (Tier 1)
|
|
70
|
+
// Conflict rule: prefer 'spacy' over 'llm-haiku' for Tier 3 disambiguation.
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## `sia_by_file` — File-Scoped Memory Retrieval
|
|
77
|
+
|
|
78
|
+
Call before modifying any file you have not worked on recently. Returns everything
|
|
79
|
+
Sia knows about that file: decisions made about it, bugs found in it, patterns it
|
|
80
|
+
implements, conventions that apply to it. This is a complement to `sia_search`,
|
|
81
|
+
not an alternative — use both.
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
sia_by_file({
|
|
85
|
+
file_path: string, // relative path from project root
|
|
86
|
+
workspace?: boolean, // default false — include cross-repo edges for this file
|
|
87
|
+
limit?: number, // default 10
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## `sia_expand` — Graph Relationship Traversal
|
|
94
|
+
|
|
95
|
+
Call when a search result is relevant but you need to understand how it connects to
|
|
96
|
+
the rest of the graph. Use sparingly — the session budget is 2 calls.
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
sia_expand({
|
|
100
|
+
entity_id: string, // the ID from a sia_search or sia_by_file result
|
|
101
|
+
depth?: 1 | 2 | 3, // default 1; see depth guide below
|
|
102
|
+
edge_types?: string[], // see edge type guide below
|
|
103
|
+
include_cross_repo?: boolean, // default false
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Depth guide:**
|
|
108
|
+
`depth=1` — immediate neighbors only. Use for 90% of cases.
|
|
109
|
+
`depth=2` — multi-step causal chains. Use for regression tracing and dependency audits.
|
|
110
|
+
`depth=3` — full dependency impact. The 50-entity neighbor cap will usually bind here;
|
|
111
|
+
use only when a complete impact analysis is explicitly needed.
|
|
112
|
+
|
|
113
|
+
**Edge type guide:**
|
|
114
|
+
Regression investigation: `edge_types=['supersedes', 'caused_by', 'solves']`
|
|
115
|
+
Dependency analysis: `edge_types=['calls', 'imports', 'depends_on']`
|
|
116
|
+
Decision history: `edge_types=['supersedes', 'elaborates', 'contradicts']`
|
|
117
|
+
Bug-to-solution: `edge_types=['solves', 'caused_by']`
|
|
118
|
+
|
|
119
|
+
**Hard constraints:**
|
|
120
|
+
Never expand all results from a `sia_search` — context overflow is guaranteed.
|
|
121
|
+
Never call `sia_expand` on Community entities — they already contain synthesised summaries.
|
|
122
|
+
Budget: 2 calls per session maximum.
|
|
123
|
+
|
|
124
|
+
**Edge truncation:** `SiaExpandResult.edge_count` is the total active edges in the
|
|
125
|
+
neighborhood. `edges[]` is capped at 200. If `edge_count > edges.length`, the traversal
|
|
126
|
+
is incomplete. Narrow with an `edge_types` filter or reduce `depth` and re-call.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## `sia_community` — Architectural Summaries
|
|
131
|
+
|
|
132
|
+
Use for broad structural questions, architectural orientation, and module-level
|
|
133
|
+
understanding. Not for specific entity lookups — use `sia_search` for those.
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
sia_community({
|
|
137
|
+
query?: string, // topic description for community selection
|
|
138
|
+
entity_id?: string, // OR: get the community containing this specific entity
|
|
139
|
+
level?: 0 | 1 | 2, // default 1; see level guide below
|
|
140
|
+
package_path?: string, // monorepo: scope to a specific package
|
|
141
|
+
})
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Level guide:**
|
|
145
|
+
`level=2` — Coarse architectural overview. Use for: new developer orientation,
|
|
146
|
+
system-wide design questions, "how does this system work?" queries.
|
|
147
|
+
`level=1` — Subsystem / module level. Use for: "how does the auth module work?",
|
|
148
|
+
before implementing a feature that spans a module.
|
|
149
|
+
`level=0` — Fine-grained cluster view. Rarely needed by the agent; more useful
|
|
150
|
+
from the CLI. Avoid in agent workflows.
|
|
151
|
+
|
|
152
|
+
Never use `sia_search("architecture")` as a substitute for `sia_community` — it
|
|
153
|
+
returns raw entity snippets (a list of class names) rather than synthesised summaries.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## `sia_at_time` — Temporal Graph Query
|
|
158
|
+
|
|
159
|
+
Use for historical investigation: regressions, architecture evolution, "what changed
|
|
160
|
+
about X?", "what was true before this broke?"
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
sia_at_time({
|
|
164
|
+
as_of: string, // ISO 8601 OR relative: "7 days ago", "3 months ago", "January"
|
|
165
|
+
entity_types?: string[], // narrow by entity type
|
|
166
|
+
tags?: string[], // narrow by tag
|
|
167
|
+
limit?: number, // default 20, max 50. Applies to BOTH entities[] and
|
|
168
|
+
// invalidated_entities[]. Increase for large regressions
|
|
169
|
+
// (many entities changed at once).
|
|
170
|
+
})
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Output:** A `SiaTemporalResult` with two entity arrays and an edge array:
|
|
174
|
+
- `invalidated_entities[]` — facts that ENDED on or before `as_of`. The change history.
|
|
175
|
+
Sorted by `t_valid_until DESC` (most recently ended first — highest priority for
|
|
176
|
+
regression diagnosis). Each entry's `t_valid_until` is exactly when that fact ended.
|
|
177
|
+
- `entities[]` — facts still valid at `as_of`. Compare against current `sia_search`
|
|
178
|
+
output to see what has changed since.
|
|
179
|
+
- `edges[]` — edges valid at `as_of`, capped at 50.
|
|
180
|
+
- `edge_count` — total edges valid at `as_of` before the 50-cap truncation. If
|
|
181
|
+
`edge_count > edges.length`, the edge set is incomplete — narrow with `entity_types`
|
|
182
|
+
or `tags` to retrieve remaining edge context.
|
|
183
|
+
|
|
184
|
+
When `invalidated_count > invalidated_entities.length`, entity results are truncated.
|
|
185
|
+
Make additional narrowed calls with `entity_types` or `tags` filters to retrieve
|
|
186
|
+
remaining entries. Do not assume you have the complete picture until
|
|
187
|
+
`invalidated_count == invalidated_entities.length`.
|
|
188
|
+
|
|
189
|
+
`sia_at_time` has no meaning in isolation. Always compare its output against the current
|
|
190
|
+
graph (a current `sia_search` call) to identify what changed and what superseded each
|
|
191
|
+
invalidated fact.
|
|
192
|
+
|
|
193
|
+
**When `t_valid_from` is null in a result:** the entity was recorded but Sia could not
|
|
194
|
+
determine when it became true in the world. Say "this was the state at some point before
|
|
195
|
+
[as_of], but the exact start date is unknown."
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## `sia_flag` — Mid-Session Capture Signal (If Enabled)
|
|
200
|
+
|
|
201
|
+
Available only when `npx sia enable-flagging` has been run. See
|
|
202
|
+
`src/agent/modules/sia-flagging.md` for full guidance.
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
sia_flag({ reason: string }) // max 100 characters after sanitization
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The `reason` is sanitized before storage. Characters stripped: `<`, `>`, `{`, `}`,
|
|
209
|
+
`[`, `]`, `\`, quotes, and control characters. Permitted: colons, backticks,
|
|
210
|
+
underscores, forward slashes, `@`, and all standard punctuation. Natural root-cause
|
|
211
|
+
descriptions pass through correctly.
|
|
212
|
+
|
|
213
|
+
If the tool returns a disabled error, tell the developer: "This moment seems worth
|
|
214
|
+
capturing. Run `npx sia enable-flagging` if you want in-session capture — otherwise
|
|
215
|
+
Sia will attempt to capture it at session end via the Stop hook, with lower precision."
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Three Paranoid Modes — They Are Not Equivalent
|
|
220
|
+
|
|
221
|
+
These are three distinct mechanisms that are frequently confused:
|
|
222
|
+
|
|
223
|
+
**`paranoid: true` on `sia_search`** (or `npx sia search --paranoid` from CLI): filters
|
|
224
|
+
Tier 4 facts from query results only. It does not prevent external content from being
|
|
225
|
+
captured into the graph. A developer who uses this flag expecting "no external content
|
|
226
|
+
will enter my graph" is mistaken — they have only filtered what they see, not what
|
|
227
|
+
is stored.
|
|
228
|
+
|
|
229
|
+
**`paranoidCapture: true` in `~/.sia/config.json`**: quarantines all Tier 4 content at
|
|
230
|
+
the capture pipeline's chunker stage. This is the hard guarantee. External content never
|
|
231
|
+
reaches staging, never reaches the main graph, and appears only as a `QUARANTINE` entry
|
|
232
|
+
in the audit log.
|
|
233
|
+
|
|
234
|
+
**`--paranoid` CLI flag**: equivalent to `paranoid: true` on `sia_search` — retrieval
|
|
235
|
+
filtering only, not capture-side isolation.
|
|
236
|
+
|
|
237
|
+
If a developer asks for the strongest isolation from external content, direct them to
|
|
238
|
+
`paranoidCapture: true` in config, not the query-time flag. Both can be used together
|
|
239
|
+
for defence in depth.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// Module: c-include — C/C++ #include resolution with compile_commands.json support
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, extname, join } from "node:path";
|
|
5
|
+
import type { CandidateFact } from "@/capture/types";
|
|
6
|
+
|
|
7
|
+
/** A single entry in compile_commands.json */
|
|
8
|
+
interface CompileCommand {
|
|
9
|
+
file: string;
|
|
10
|
+
command?: string;
|
|
11
|
+
arguments?: string[];
|
|
12
|
+
directory?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Parse `-I<path>` and `-I <path>` flags from a compilation command string.
|
|
17
|
+
*/
|
|
18
|
+
function extractIncludePathsFromCommand(command: string): string[] {
|
|
19
|
+
const paths: string[] = [];
|
|
20
|
+
const re = /-I\s*([^\s]+)/g;
|
|
21
|
+
let match = re.exec(command);
|
|
22
|
+
while (match !== null) {
|
|
23
|
+
paths.push(match[1]);
|
|
24
|
+
match = re.exec(command);
|
|
25
|
+
}
|
|
26
|
+
return paths;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Load compile_commands.json from repoRoot and find include paths for the
|
|
31
|
+
* given filePath. Returns null if the file does not exist, [] if found but
|
|
32
|
+
* no matching entry or no -I flags.
|
|
33
|
+
*/
|
|
34
|
+
function loadIncludePaths(repoRoot: string, filePath: string): string[] | null {
|
|
35
|
+
const ccPath = join(repoRoot, "compile_commands.json");
|
|
36
|
+
if (!existsSync(ccPath)) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const raw = readFileSync(ccPath, "utf8") as string;
|
|
42
|
+
const commands: CompileCommand[] = JSON.parse(raw) as CompileCommand[];
|
|
43
|
+
|
|
44
|
+
const entry = commands.find((cmd) => {
|
|
45
|
+
const dir = cmd.directory ?? "";
|
|
46
|
+
const resolvedFile = dir ? join(dir, cmd.file) : cmd.file;
|
|
47
|
+
return resolvedFile === filePath || cmd.file === filePath;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (!entry) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (entry.arguments && entry.arguments.length > 0) {
|
|
55
|
+
const paths: string[] = [];
|
|
56
|
+
for (let i = 0; i < entry.arguments.length; i++) {
|
|
57
|
+
const arg = entry.arguments[i];
|
|
58
|
+
if (arg === "-I" && i + 1 < entry.arguments.length) {
|
|
59
|
+
paths.push(entry.arguments[i + 1]);
|
|
60
|
+
i++;
|
|
61
|
+
} else if (arg.startsWith("-I") && arg.length > 2) {
|
|
62
|
+
paths.push(arg.slice(2));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return paths;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (entry.command) {
|
|
69
|
+
return extractIncludePathsFromCommand(entry.command);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return [];
|
|
73
|
+
} catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Determine language tag based on file extension. */
|
|
79
|
+
function langFromPath(filePath: string): string {
|
|
80
|
+
const ext = extname(filePath).toLowerCase();
|
|
81
|
+
if (ext === ".c" || ext === ".h") return "c";
|
|
82
|
+
return "cpp";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Extract `#include` directives from C/C++ source content.
|
|
87
|
+
*
|
|
88
|
+
* System includes (`<...>`) → confidence 0.80, tag `system-include`.
|
|
89
|
+
* Local includes (`"..."`) → resolved via compile_commands -I paths, then
|
|
90
|
+
* same-directory, then repo-root fallback.
|
|
91
|
+
* Resolved → confidence 0.85; unresolved → confidence 0.70.
|
|
92
|
+
*/
|
|
93
|
+
export function extractCIncludes(
|
|
94
|
+
content: string,
|
|
95
|
+
filePath: string,
|
|
96
|
+
repoRoot?: string,
|
|
97
|
+
): CandidateFact[] {
|
|
98
|
+
if (!content) return [];
|
|
99
|
+
|
|
100
|
+
const includeRe = /^\s*#\s*include\s*(?:<([^>]+)>|"([^"]+)")/gm;
|
|
101
|
+
const directives: Array<{ name: string; isSystem: boolean; raw: string }> = [];
|
|
102
|
+
let m = includeRe.exec(content);
|
|
103
|
+
while (m !== null) {
|
|
104
|
+
if (m[1] !== undefined) {
|
|
105
|
+
directives.push({ name: m[1], isSystem: true, raw: m[0].trim() });
|
|
106
|
+
} else if (m[2] !== undefined) {
|
|
107
|
+
directives.push({ name: m[2], isSystem: false, raw: m[0].trim() });
|
|
108
|
+
}
|
|
109
|
+
m = includeRe.exec(content);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (directives.length === 0) return [];
|
|
113
|
+
|
|
114
|
+
const lang = langFromPath(filePath);
|
|
115
|
+
|
|
116
|
+
let includePaths: string[] = [];
|
|
117
|
+
|
|
118
|
+
if (repoRoot) {
|
|
119
|
+
const loaded = loadIncludePaths(repoRoot, filePath);
|
|
120
|
+
if (loaded === null) {
|
|
121
|
+
console.warn(
|
|
122
|
+
`[c-include] compile_commands.json not found in ${repoRoot}; falling back to directory-based resolution`,
|
|
123
|
+
);
|
|
124
|
+
} else {
|
|
125
|
+
includePaths = loaded;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const facts: CandidateFact[] = [];
|
|
130
|
+
|
|
131
|
+
for (const directive of directives) {
|
|
132
|
+
if (directive.isSystem) {
|
|
133
|
+
facts.push({
|
|
134
|
+
type: "CodeEntity",
|
|
135
|
+
name: directive.name,
|
|
136
|
+
content: directive.raw,
|
|
137
|
+
summary: `System include: ${directive.name} in ${filePath}`,
|
|
138
|
+
tags: ["include", "system-include", lang],
|
|
139
|
+
file_paths: [filePath],
|
|
140
|
+
trust_tier: 2,
|
|
141
|
+
confidence: 0.8,
|
|
142
|
+
extraction_method: "c-include",
|
|
143
|
+
});
|
|
144
|
+
} else {
|
|
145
|
+
let resolvedPath: string | undefined;
|
|
146
|
+
|
|
147
|
+
for (const ip of includePaths) {
|
|
148
|
+
const candidate = join(ip, directive.name);
|
|
149
|
+
if (existsSync(candidate)) {
|
|
150
|
+
resolvedPath = candidate;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (!resolvedPath) {
|
|
156
|
+
const candidate = join(dirname(filePath), directive.name);
|
|
157
|
+
if (existsSync(candidate)) {
|
|
158
|
+
resolvedPath = candidate;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!resolvedPath && repoRoot) {
|
|
163
|
+
const candidate = join(repoRoot, directive.name);
|
|
164
|
+
if (existsSync(candidate)) {
|
|
165
|
+
resolvedPath = candidate;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const confidence = resolvedPath ? 0.85 : 0.7;
|
|
170
|
+
const filePaths = resolvedPath ? [filePath, resolvedPath] : [filePath];
|
|
171
|
+
|
|
172
|
+
facts.push({
|
|
173
|
+
type: "CodeEntity",
|
|
174
|
+
name: directive.name,
|
|
175
|
+
content: directive.raw,
|
|
176
|
+
summary: resolvedPath
|
|
177
|
+
? `Local include: ${directive.name} -> ${resolvedPath}`
|
|
178
|
+
: `Local include: ${directive.name} (unresolved) in ${filePath}`,
|
|
179
|
+
tags: ["include", lang],
|
|
180
|
+
file_paths: filePaths,
|
|
181
|
+
trust_tier: 2,
|
|
182
|
+
confidence,
|
|
183
|
+
extraction_method: "c-include",
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return facts;
|
|
189
|
+
}
|