@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,162 @@
|
|
|
1
|
+
// Module: visualize-live — CLI command to start interactive browser visualizer
|
|
2
|
+
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
6
|
+
import type { SiaDb } from "@/graph/db-interface";
|
|
7
|
+
import { type ExtractOpts, extractSubgraph } from "@/visualization/subgraph-extract";
|
|
8
|
+
import {
|
|
9
|
+
type CommunityData,
|
|
10
|
+
generateCommunityClusterHtml,
|
|
11
|
+
} from "@/visualization/views/community-clusters";
|
|
12
|
+
import { generateDependencyMapHtml } from "@/visualization/views/dependency-map";
|
|
13
|
+
import { generateGraphExplorerHtml } from "@/visualization/views/graph-explorer";
|
|
14
|
+
import { generateTimelineHtml } from "@/visualization/views/timeline";
|
|
15
|
+
|
|
16
|
+
export type ViewType = "graph" | "timeline" | "deps" | "communities";
|
|
17
|
+
|
|
18
|
+
export interface VisualizeLiveOpts {
|
|
19
|
+
view?: ViewType;
|
|
20
|
+
port?: number;
|
|
21
|
+
scope?: string;
|
|
22
|
+
maxNodes?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Parse CLI args into VisualizeLiveOpts.
|
|
27
|
+
*/
|
|
28
|
+
export function parseVisualizeLiveArgs(args: string[]): VisualizeLiveOpts {
|
|
29
|
+
const opts: VisualizeLiveOpts = {};
|
|
30
|
+
for (let i = 0; i < args.length; i++) {
|
|
31
|
+
if (args[i] === "--view" && args[i + 1]) {
|
|
32
|
+
opts.view = args[++i] as ViewType;
|
|
33
|
+
} else if (args[i] === "--port" && args[i + 1]) {
|
|
34
|
+
opts.port = parseInt(args[++i], 10);
|
|
35
|
+
} else if (args[i] === "--scope" && args[i + 1]) {
|
|
36
|
+
opts.scope = args[++i];
|
|
37
|
+
} else if (args[i] === "--max-nodes" && args[i + 1]) {
|
|
38
|
+
opts.maxNodes = parseInt(args[++i], 10);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return opts;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Generate the appropriate view HTML based on the selected view type.
|
|
46
|
+
*/
|
|
47
|
+
export async function generateViewHtml(
|
|
48
|
+
db: SiaDb,
|
|
49
|
+
view: ViewType,
|
|
50
|
+
extractOpts: ExtractOpts,
|
|
51
|
+
): Promise<string> {
|
|
52
|
+
switch (view) {
|
|
53
|
+
case "graph": {
|
|
54
|
+
const data = await extractSubgraph(db, extractOpts);
|
|
55
|
+
return generateGraphExplorerHtml(data);
|
|
56
|
+
}
|
|
57
|
+
case "timeline": {
|
|
58
|
+
const data = await extractSubgraph(db, extractOpts);
|
|
59
|
+
const events = data.nodes.map((n) => ({
|
|
60
|
+
id: n.id,
|
|
61
|
+
type: n.type,
|
|
62
|
+
name: n.name,
|
|
63
|
+
created_at: Date.now() - Math.random() * 86400_000 * 30, // placeholder
|
|
64
|
+
kind: n.type,
|
|
65
|
+
}));
|
|
66
|
+
return generateTimelineHtml(events);
|
|
67
|
+
}
|
|
68
|
+
case "deps": {
|
|
69
|
+
const data = await extractSubgraph(db, {
|
|
70
|
+
...extractOpts,
|
|
71
|
+
nodeType: extractOpts.nodeType ?? "FileNode",
|
|
72
|
+
});
|
|
73
|
+
return generateDependencyMapHtml(data, { rootFile: extractOpts.scope });
|
|
74
|
+
}
|
|
75
|
+
case "communities": {
|
|
76
|
+
// Fetch community data from the graph
|
|
77
|
+
const { rows: commRows } = await db.execute(
|
|
78
|
+
`SELECT id, name, level, summary, member_count FROM communities
|
|
79
|
+
WHERE t_valid_until IS NULL
|
|
80
|
+
ORDER BY level ASC, member_count DESC
|
|
81
|
+
LIMIT 50`,
|
|
82
|
+
);
|
|
83
|
+
const { rows: memberRows } = await db.execute(
|
|
84
|
+
`SELECT entity_id, community_id, entity_name, entity_type FROM community_members
|
|
85
|
+
WHERE t_valid_until IS NULL
|
|
86
|
+
LIMIT 500`,
|
|
87
|
+
);
|
|
88
|
+
const communityData: CommunityData = {
|
|
89
|
+
communities: commRows.map((r) => ({
|
|
90
|
+
id: r.id as string,
|
|
91
|
+
name: r.name as string,
|
|
92
|
+
level: (r.level as number) ?? 1,
|
|
93
|
+
summary: (r.summary as string) ?? "",
|
|
94
|
+
memberCount: (r.member_count as number) ?? 0,
|
|
95
|
+
})),
|
|
96
|
+
members: memberRows.map((r) => ({
|
|
97
|
+
entityId: r.entity_id as string,
|
|
98
|
+
communityId: r.community_id as string,
|
|
99
|
+
entityName: r.entity_name as string,
|
|
100
|
+
entityType: r.entity_type as string,
|
|
101
|
+
})),
|
|
102
|
+
};
|
|
103
|
+
return generateCommunityClusterHtml(communityData);
|
|
104
|
+
}
|
|
105
|
+
default:
|
|
106
|
+
throw new Error(`Unknown view type: ${view}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Run the visualize-live command: start server, generate view, output URL.
|
|
112
|
+
*/
|
|
113
|
+
export async function runVisualizeLive(db: SiaDb, args: string[]): Promise<void> {
|
|
114
|
+
const opts = parseVisualizeLiveArgs(args);
|
|
115
|
+
const view = opts.view ?? "graph";
|
|
116
|
+
const port = opts.port ?? 52742;
|
|
117
|
+
|
|
118
|
+
// Create screen directory
|
|
119
|
+
const screenDir = resolve(".sia-graph/viz");
|
|
120
|
+
mkdirSync(screenDir, { recursive: true });
|
|
121
|
+
|
|
122
|
+
// Generate HTML view
|
|
123
|
+
const extractOpts: ExtractOpts = {
|
|
124
|
+
scope: opts.scope,
|
|
125
|
+
maxNodes: opts.maxNodes,
|
|
126
|
+
};
|
|
127
|
+
const html = await generateViewHtml(db, view, extractOpts);
|
|
128
|
+
|
|
129
|
+
// Write to screen dir with timestamp
|
|
130
|
+
const filename = `${view}-${Date.now()}.html`;
|
|
131
|
+
writeFileSync(join(screenDir, filename), html, "utf-8");
|
|
132
|
+
|
|
133
|
+
// Start the viz server
|
|
134
|
+
const serverScript = resolve(__dirname, "../../scripts/viz-server.ts");
|
|
135
|
+
const child = spawn(
|
|
136
|
+
"bun",
|
|
137
|
+
["run", serverScript, "--screen-dir", screenDir, "--port", String(port)],
|
|
138
|
+
{
|
|
139
|
+
stdio: "pipe",
|
|
140
|
+
detached: true,
|
|
141
|
+
},
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
child.stdout?.on("data", (data: Buffer) => {
|
|
145
|
+
const msg = data.toString().trim();
|
|
146
|
+
try {
|
|
147
|
+
const info = JSON.parse(msg);
|
|
148
|
+
if (info.type === "server-started") {
|
|
149
|
+
console.log(`SIA Graph Visualizer running at: ${info.url}`);
|
|
150
|
+
console.log(`View: ${view} | Screen dir: ${screenDir}`);
|
|
151
|
+
}
|
|
152
|
+
} catch {
|
|
153
|
+
console.log(msg);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
child.stderr?.on("data", (data: Buffer) => {
|
|
158
|
+
console.error(data.toString().trim());
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
child.unref();
|
|
162
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Module: workspace — Workspace CLI subcommands (create, list, add, remove, show)
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import type { SiaDb } from "@/graph/db-interface";
|
|
5
|
+
import {
|
|
6
|
+
addRepoToWorkspace,
|
|
7
|
+
createWorkspace,
|
|
8
|
+
getWorkspaceContractCount,
|
|
9
|
+
getWorkspaceRepos,
|
|
10
|
+
listWorkspaces,
|
|
11
|
+
registerRepo,
|
|
12
|
+
removeRepoFromWorkspace,
|
|
13
|
+
resolveWorkspaceName,
|
|
14
|
+
type WorkspaceListItem,
|
|
15
|
+
} from "@/graph/meta-db";
|
|
16
|
+
import { detectApiContracts, writeDetectedContracts } from "@/workspace/api-contracts";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create a workspace.
|
|
20
|
+
*/
|
|
21
|
+
export async function workspaceCreate(db: SiaDb, name: string): Promise<string> {
|
|
22
|
+
return createWorkspace(db, name);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* List all workspaces with member counts.
|
|
27
|
+
*/
|
|
28
|
+
export async function workspaceList(db: SiaDb): Promise<WorkspaceListItem[]> {
|
|
29
|
+
return listWorkspaces(db);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Add a repo to a workspace. Triggers API contract auto-detection.
|
|
34
|
+
*/
|
|
35
|
+
export async function workspaceAdd(
|
|
36
|
+
db: SiaDb,
|
|
37
|
+
workspaceName: string,
|
|
38
|
+
repoPath: string,
|
|
39
|
+
): Promise<void> {
|
|
40
|
+
const wsId = await resolveWorkspaceName(db, workspaceName);
|
|
41
|
+
if (!wsId) throw new Error(`Workspace '${workspaceName}' not found`);
|
|
42
|
+
|
|
43
|
+
const repoId = await registerRepo(db, repoPath);
|
|
44
|
+
await addRepoToWorkspace(db, wsId, repoId);
|
|
45
|
+
|
|
46
|
+
// Auto-detect API contracts
|
|
47
|
+
const contracts = await detectApiContracts(resolve(repoPath));
|
|
48
|
+
if (contracts.length > 0) {
|
|
49
|
+
await writeDetectedContracts(db, repoId, contracts);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Remove a repo from a workspace.
|
|
55
|
+
*/
|
|
56
|
+
export async function workspaceRemove(
|
|
57
|
+
db: SiaDb,
|
|
58
|
+
workspaceName: string,
|
|
59
|
+
repoPath: string,
|
|
60
|
+
): Promise<void> {
|
|
61
|
+
const wsId = await resolveWorkspaceName(db, workspaceName);
|
|
62
|
+
if (!wsId) throw new Error(`Workspace '${workspaceName}' not found`);
|
|
63
|
+
|
|
64
|
+
const resolved = resolve(repoPath);
|
|
65
|
+
const repoId = createHash("sha256").update(resolved).digest("hex");
|
|
66
|
+
await removeRepoFromWorkspace(db, wsId, repoId);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Shape returned by workspaceShow. */
|
|
70
|
+
export interface WorkspaceShowInfo {
|
|
71
|
+
name: string;
|
|
72
|
+
id: string;
|
|
73
|
+
members: Array<{ id: string; path: string; name: string | null }>;
|
|
74
|
+
contractCount: number;
|
|
75
|
+
crossRepoEdgeCount: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Show workspace details: members, contracts, cross-repo edge count.
|
|
80
|
+
*/
|
|
81
|
+
export async function workspaceShow(
|
|
82
|
+
metaDb: SiaDb,
|
|
83
|
+
bridgeDb: SiaDb,
|
|
84
|
+
workspaceName: string,
|
|
85
|
+
): Promise<WorkspaceShowInfo> {
|
|
86
|
+
const wsId = await resolveWorkspaceName(metaDb, workspaceName);
|
|
87
|
+
if (!wsId) throw new Error(`Workspace '${workspaceName}' not found`);
|
|
88
|
+
|
|
89
|
+
const repos = await getWorkspaceRepos(metaDb, wsId);
|
|
90
|
+
const contractCount = await getWorkspaceContractCount(metaDb, wsId);
|
|
91
|
+
|
|
92
|
+
// Count cross-repo edges for workspace repos
|
|
93
|
+
let crossRepoEdgeCount = 0;
|
|
94
|
+
if (repos.length > 0) {
|
|
95
|
+
const repoIds = repos.map((r) => r.id as string);
|
|
96
|
+
const placeholders = repoIds.map(() => "?").join(", ");
|
|
97
|
+
const edgeResult = await bridgeDb.execute(
|
|
98
|
+
`SELECT COUNT(*) as cnt FROM cross_repo_edges
|
|
99
|
+
WHERE (source_repo_id IN (${placeholders}) OR target_repo_id IN (${placeholders}))
|
|
100
|
+
AND t_valid_until IS NULL`,
|
|
101
|
+
[...repoIds, ...repoIds],
|
|
102
|
+
);
|
|
103
|
+
crossRepoEdgeCount = (edgeResult.rows[0]?.cnt as number) ?? 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
name: workspaceName,
|
|
108
|
+
id: wsId,
|
|
109
|
+
members: repos.map((r) => ({
|
|
110
|
+
id: r.id as string,
|
|
111
|
+
path: r.path as string,
|
|
112
|
+
name: (r.name as string | null) ?? null,
|
|
113
|
+
})),
|
|
114
|
+
contractCount,
|
|
115
|
+
crossRepoEdgeCount,
|
|
116
|
+
};
|
|
117
|
+
}
|
package/src/cli/index.ts
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { runCommunityCommand } from "@/cli/commands/community";
|
|
4
|
+
|
|
5
|
+
const VERSION = "1.0.0";
|
|
6
|
+
|
|
7
|
+
function printHelp(): void {
|
|
8
|
+
console.log(`sia v${VERSION} — Persistent graph memory for AI coding agents
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
sia <command> [options]
|
|
12
|
+
|
|
13
|
+
Commands:
|
|
14
|
+
install Install Sia in the current project
|
|
15
|
+
workspace Manage workspaces (create, list, add, remove, show)
|
|
16
|
+
team Team sync (join, leave, status)
|
|
17
|
+
sync Manual push/pull (sync push, sync pull)
|
|
18
|
+
search Search the knowledge graph
|
|
19
|
+
stats Show graph statistics
|
|
20
|
+
status Show knowledge graph health dashboard
|
|
21
|
+
reindex Re-index the repository
|
|
22
|
+
learn Build the complete knowledge graph (code + docs + communities)
|
|
23
|
+
community Show community structure
|
|
24
|
+
doctor Run diagnostic checks
|
|
25
|
+
digest Generate session digest
|
|
26
|
+
graph Visualize the knowledge graph
|
|
27
|
+
visualize-live Launch interactive browser graph visualizer
|
|
28
|
+
prune Remove archived entities
|
|
29
|
+
export Export graph to JSON
|
|
30
|
+
export-knowledge Generate human-readable KNOWLEDGE.md
|
|
31
|
+
import Import graph from JSON
|
|
32
|
+
rollback Restore graph from snapshot
|
|
33
|
+
conflicts List or resolve entity conflicts
|
|
34
|
+
freshness Generate freshness report
|
|
35
|
+
share Share an entity
|
|
36
|
+
history Show temporal knowledge history
|
|
37
|
+
compare Compare graph state between time points
|
|
38
|
+
download-model Download ONNX embedding model
|
|
39
|
+
enable-flagging Enable mid-session flagging
|
|
40
|
+
disable-flagging Disable mid-session flagging
|
|
41
|
+
tour Guided walkthrough of the knowledge graph
|
|
42
|
+
qa-report Generate QA testing intelligence report
|
|
43
|
+
pm-report Generate PM reports (sprint, decisions, risks)
|
|
44
|
+
lead-report Tech lead reports (drift, knowledge-map, compliance)
|
|
45
|
+
server Manage MCP server (start, stop, status)
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
--version, -v Show version
|
|
49
|
+
--help, -h Show this help
|
|
50
|
+
`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Open the graph database for the current working directory.
|
|
55
|
+
* Shared by commands that need SiaDb access.
|
|
56
|
+
*/
|
|
57
|
+
async function openDb() {
|
|
58
|
+
const { resolveRepoHash } = await import("@/capture/hook");
|
|
59
|
+
const { openGraphDb } = await import("@/graph/semantic-db");
|
|
60
|
+
const repoHash = resolveRepoHash(process.cwd());
|
|
61
|
+
return openGraphDb(repoHash);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function main(): Promise<void> {
|
|
65
|
+
const args = process.argv.slice(2);
|
|
66
|
+
|
|
67
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
68
|
+
console.log(`sia v${VERSION}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
73
|
+
printHelp();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const command = args[0];
|
|
78
|
+
const rest = args.slice(1);
|
|
79
|
+
|
|
80
|
+
switch (command) {
|
|
81
|
+
// --- Self-contained commands (no DB needed) ---
|
|
82
|
+
case "install": {
|
|
83
|
+
const { siaInstall } = await import("@/cli/commands/install");
|
|
84
|
+
const result = await siaInstall();
|
|
85
|
+
console.log(JSON.stringify(result, null, 2));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
case "reindex": {
|
|
89
|
+
const { siaReindex } = await import("@/cli/commands/reindex");
|
|
90
|
+
const result = await siaReindex();
|
|
91
|
+
console.log(JSON.stringify(result, null, 2));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
case "learn": {
|
|
95
|
+
const { siaLearn } = await import("@/cli/commands/learn");
|
|
96
|
+
const options: Record<string, unknown> = {};
|
|
97
|
+
if (rest.includes("--incremental")) options.incremental = true;
|
|
98
|
+
if (rest.includes("--force")) options.force = true;
|
|
99
|
+
if (rest.includes("--quiet")) options.verbosity = "quiet";
|
|
100
|
+
if (rest.includes("--interactive")) options.verbosity = "interactive";
|
|
101
|
+
if (rest.includes("--verbose")) options.verbosity = "verbose";
|
|
102
|
+
await siaLearn(options as any);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
case "download-model": {
|
|
106
|
+
const { downloadModel } = await import("@/cli/commands/download-model");
|
|
107
|
+
const path = await downloadModel();
|
|
108
|
+
console.log(`Model downloaded to: ${path}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
case "enable-flagging": {
|
|
112
|
+
const { enableFlagging } = await import("@/cli/commands/enable-flagging");
|
|
113
|
+
await enableFlagging();
|
|
114
|
+
console.log("Flagging enabled.");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
case "disable-flagging": {
|
|
118
|
+
const { disableFlagging } = await import("@/cli/commands/disable-flagging");
|
|
119
|
+
await disableFlagging();
|
|
120
|
+
console.log("Flagging disabled.");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// --- Commands with their own CLI dispatchers ---
|
|
125
|
+
case "community":
|
|
126
|
+
await runCommunityCommand(rest);
|
|
127
|
+
return;
|
|
128
|
+
case "sync": {
|
|
129
|
+
const { runSync } = await import("@/cli/commands/sync");
|
|
130
|
+
await runSync(rest);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
case "team": {
|
|
134
|
+
const { teamJoin, teamLeave, teamStatus } = await import("@/cli/commands/team");
|
|
135
|
+
const sub = rest[0];
|
|
136
|
+
if (sub === "join" && rest.length >= 3) {
|
|
137
|
+
await teamJoin(rest[1], rest[2]);
|
|
138
|
+
} else if (sub === "leave") {
|
|
139
|
+
await teamLeave();
|
|
140
|
+
} else if (sub === "status") {
|
|
141
|
+
const status = await teamStatus();
|
|
142
|
+
console.log(JSON.stringify(status, null, 2));
|
|
143
|
+
} else {
|
|
144
|
+
console.error("Usage: sia team <join|leave|status>");
|
|
145
|
+
}
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// --- Commands that need DB ---
|
|
150
|
+
case "search": {
|
|
151
|
+
const { searchGraph } = await import("@/cli/commands/search");
|
|
152
|
+
const query = rest.join(" ");
|
|
153
|
+
if (!query) {
|
|
154
|
+
console.error("Usage: sia search <query>");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const db = await openDb();
|
|
158
|
+
try {
|
|
159
|
+
const results = await searchGraph(db, query);
|
|
160
|
+
console.log(JSON.stringify(results, null, 2));
|
|
161
|
+
} finally {
|
|
162
|
+
await db.close();
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
case "status": {
|
|
167
|
+
const { runStatus } = await import("@/cli/commands/status");
|
|
168
|
+
const db = await openDb();
|
|
169
|
+
try {
|
|
170
|
+
await runStatus(db);
|
|
171
|
+
} finally {
|
|
172
|
+
await db.close();
|
|
173
|
+
}
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
case "stats": {
|
|
177
|
+
const { getStats } = await import("@/cli/commands/stats");
|
|
178
|
+
const db = await openDb();
|
|
179
|
+
try {
|
|
180
|
+
const result = await getStats(db);
|
|
181
|
+
console.log(JSON.stringify(result, null, 2));
|
|
182
|
+
} finally {
|
|
183
|
+
await db.close();
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
case "doctor": {
|
|
188
|
+
const { runDoctor } = await import("@/cli/commands/doctor");
|
|
189
|
+
const db = await openDb();
|
|
190
|
+
try {
|
|
191
|
+
const report = await runDoctor(db, process.cwd());
|
|
192
|
+
console.log(JSON.stringify(report, null, 2));
|
|
193
|
+
} finally {
|
|
194
|
+
await db.close();
|
|
195
|
+
}
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
case "digest": {
|
|
199
|
+
const { generateDigest } = await import("@/cli/commands/digest");
|
|
200
|
+
const db = await openDb();
|
|
201
|
+
try {
|
|
202
|
+
const result = await generateDigest(db);
|
|
203
|
+
console.log(JSON.stringify(result, null, 2));
|
|
204
|
+
} finally {
|
|
205
|
+
await db.close();
|
|
206
|
+
}
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
case "graph": {
|
|
210
|
+
const { generateGraphVisualization } = await import("@/cli/commands/graph");
|
|
211
|
+
const db = await openDb();
|
|
212
|
+
try {
|
|
213
|
+
const output = await generateGraphVisualization(db);
|
|
214
|
+
console.log(output);
|
|
215
|
+
} finally {
|
|
216
|
+
await db.close();
|
|
217
|
+
}
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
case "visualize-live": {
|
|
221
|
+
const { runVisualizeLive } = await import("@/cli/commands/visualize-live");
|
|
222
|
+
const db = await openDb();
|
|
223
|
+
try {
|
|
224
|
+
await runVisualizeLive(db, rest);
|
|
225
|
+
} finally {
|
|
226
|
+
await db.close();
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
case "prune": {
|
|
231
|
+
const { pruneDryRun, pruneConfirm } = await import("@/cli/commands/prune");
|
|
232
|
+
const db = await openDb();
|
|
233
|
+
try {
|
|
234
|
+
if (rest.includes("--confirm")) {
|
|
235
|
+
const removed = await pruneConfirm(db);
|
|
236
|
+
console.log(`Pruned ${removed} entities.`);
|
|
237
|
+
} else {
|
|
238
|
+
const candidates = await pruneDryRun(db);
|
|
239
|
+
console.log(JSON.stringify(candidates, null, 2));
|
|
240
|
+
if (candidates.length > 0) {
|
|
241
|
+
console.log(`\nRun 'sia prune --confirm' to remove ${candidates.length} entities.`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
} finally {
|
|
245
|
+
await db.close();
|
|
246
|
+
}
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
case "export-knowledge": {
|
|
250
|
+
const { runExportKnowledge } = await import("@/cli/commands/export-knowledge");
|
|
251
|
+
await runExportKnowledge(rest);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
case "export": {
|
|
255
|
+
const { exportToFile, exportGraph } = await import("@/cli/commands/export");
|
|
256
|
+
const db = await openDb();
|
|
257
|
+
try {
|
|
258
|
+
const outputPath = rest[0];
|
|
259
|
+
if (outputPath) {
|
|
260
|
+
const path = await exportToFile(db, outputPath);
|
|
261
|
+
console.log(`Exported to: ${path}`);
|
|
262
|
+
} else {
|
|
263
|
+
const data = await exportGraph(db);
|
|
264
|
+
console.log(JSON.stringify(data, null, 2));
|
|
265
|
+
}
|
|
266
|
+
} finally {
|
|
267
|
+
await db.close();
|
|
268
|
+
}
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
case "import": {
|
|
272
|
+
const { importFromFile } = await import("@/cli/commands/import");
|
|
273
|
+
const filePath = rest[0];
|
|
274
|
+
const mode = rest.includes("--replace") ? ("replace" as const) : ("merge" as const);
|
|
275
|
+
if (!filePath) {
|
|
276
|
+
console.error("Usage: sia import <file> [--replace]");
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const db = await openDb();
|
|
280
|
+
try {
|
|
281
|
+
const result = await importFromFile(db, filePath, mode);
|
|
282
|
+
console.log(JSON.stringify(result, null, 2));
|
|
283
|
+
} finally {
|
|
284
|
+
await db.close();
|
|
285
|
+
}
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
case "rollback": {
|
|
289
|
+
const { rollbackGraph } = await import("@/cli/commands/rollback");
|
|
290
|
+
const { resolveRepoHash } = await import("@/capture/hook");
|
|
291
|
+
const repoHash = resolveRepoHash(process.cwd());
|
|
292
|
+
const db = await openDb();
|
|
293
|
+
try {
|
|
294
|
+
const result = await rollbackGraph(db, repoHash);
|
|
295
|
+
console.log(JSON.stringify(result, null, 2));
|
|
296
|
+
} finally {
|
|
297
|
+
await db.close();
|
|
298
|
+
}
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
case "conflicts": {
|
|
302
|
+
const { listConflicts, resolveConflict } = await import("@/cli/commands/conflicts");
|
|
303
|
+
const db = await openDb();
|
|
304
|
+
try {
|
|
305
|
+
if (rest[0] === "resolve" && rest[1] && rest[2]) {
|
|
306
|
+
await resolveConflict(db, rest[1], rest[2]);
|
|
307
|
+
console.log("Conflict resolved.");
|
|
308
|
+
} else {
|
|
309
|
+
const conflicts = await listConflicts(db);
|
|
310
|
+
console.log(JSON.stringify(conflicts, null, 2));
|
|
311
|
+
}
|
|
312
|
+
} finally {
|
|
313
|
+
await db.close();
|
|
314
|
+
}
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
case "freshness": {
|
|
318
|
+
const { generateFreshnessReport } = await import("@/cli/commands/freshness");
|
|
319
|
+
const db = await openDb();
|
|
320
|
+
try {
|
|
321
|
+
const report = await generateFreshnessReport(db);
|
|
322
|
+
console.log(JSON.stringify(report, null, 2));
|
|
323
|
+
} finally {
|
|
324
|
+
await db.close();
|
|
325
|
+
}
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
case "share": {
|
|
329
|
+
const { shareEntity } = await import("@/cli/commands/share");
|
|
330
|
+
const entityId = rest[0];
|
|
331
|
+
if (!entityId) {
|
|
332
|
+
console.error("Usage: sia share <entity-id>");
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const db = await openDb();
|
|
336
|
+
try {
|
|
337
|
+
await shareEntity(db, entityId);
|
|
338
|
+
console.log(`Entity ${entityId} shared.`);
|
|
339
|
+
} finally {
|
|
340
|
+
await db.close();
|
|
341
|
+
}
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
case "workspace": {
|
|
345
|
+
const mod = await import("@/cli/commands/workspace");
|
|
346
|
+
const db = await openDb();
|
|
347
|
+
try {
|
|
348
|
+
const sub = rest[0];
|
|
349
|
+
if (sub === "create" && rest[1]) {
|
|
350
|
+
const id = await mod.workspaceCreate(db, rest[1]);
|
|
351
|
+
console.log(`Workspace created: ${id}`);
|
|
352
|
+
} else if (sub === "list") {
|
|
353
|
+
const items = await mod.workspaceList(db);
|
|
354
|
+
console.log(JSON.stringify(items, null, 2));
|
|
355
|
+
} else if (sub === "add" && rest[1] && rest[2]) {
|
|
356
|
+
await mod.workspaceAdd(db, rest[1], rest[2]);
|
|
357
|
+
console.log("Repository added to workspace.");
|
|
358
|
+
} else if (sub === "remove" && rest[1] && rest[2]) {
|
|
359
|
+
await mod.workspaceRemove(db, rest[1], rest[2]);
|
|
360
|
+
console.log("Repository removed from workspace.");
|
|
361
|
+
} else {
|
|
362
|
+
console.error("Usage: sia workspace <create|list|add|remove> [args]");
|
|
363
|
+
}
|
|
364
|
+
} finally {
|
|
365
|
+
await db.close();
|
|
366
|
+
}
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
case "history": {
|
|
370
|
+
const { runHistory } = await import("@/cli/commands/history");
|
|
371
|
+
await runHistory(rest);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
case "compare": {
|
|
375
|
+
const { runCompare } = await import("@/cli/commands/compare");
|
|
376
|
+
await runCompare(rest);
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
case "tour": {
|
|
380
|
+
const { runTour } = await import("@/cli/commands/tour");
|
|
381
|
+
await runTour(rest);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
case "qa-report": {
|
|
385
|
+
const { runQaReport } = await import("@/cli/commands/qa-report");
|
|
386
|
+
await runQaReport(rest);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
case "pm-report": {
|
|
390
|
+
const { runPmReport } = await import("@/cli/commands/pm-report");
|
|
391
|
+
await runPmReport(rest);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
case "lead-report": {
|
|
395
|
+
const { runLeadReport } = await import("@/cli/commands/lead-report");
|
|
396
|
+
await runLeadReport(rest);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
case "server": {
|
|
400
|
+
const { serverStart, serverStop, serverStatus } = await import("@/cli/commands/server");
|
|
401
|
+
const sub = rest[0];
|
|
402
|
+
if (sub === "start") {
|
|
403
|
+
const config = serverStart();
|
|
404
|
+
console.log(JSON.stringify(config, null, 2));
|
|
405
|
+
} else if (sub === "stop") {
|
|
406
|
+
const config = serverStop();
|
|
407
|
+
console.log(JSON.stringify(config, null, 2));
|
|
408
|
+
} else if (sub === "status") {
|
|
409
|
+
const config = serverStatus();
|
|
410
|
+
console.log(JSON.stringify(config, null, 2));
|
|
411
|
+
} else {
|
|
412
|
+
console.error("Usage: sia server <start|stop|status>");
|
|
413
|
+
}
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
default:
|
|
417
|
+
console.error(`Unknown command: ${command}. Run 'sia --help' for usage.`);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
main().catch((err) => {
|
|
422
|
+
console.error(err);
|
|
423
|
+
process.exit(1);
|
|
424
|
+
});
|