@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,161 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Start the graph visualizer server and output connection info
|
|
3
|
+
# Usage: start-visualizer.sh [--project-dir <path>] [--host <bind-host>] [--url-host <display-host>] [--foreground] [--background]
|
|
4
|
+
#
|
|
5
|
+
# Starts server on a random high port, outputs JSON with URL.
|
|
6
|
+
# Each session gets its own directory to avoid conflicts.
|
|
7
|
+
#
|
|
8
|
+
# Options:
|
|
9
|
+
# --project-dir <path> Store session files under <path>/.sia/visualize/
|
|
10
|
+
# instead of /tmp. Files persist after server stops.
|
|
11
|
+
# --host <bind-host> Host/interface to bind (default: 127.0.0.1).
|
|
12
|
+
# Use 0.0.0.0 in remote/containerized environments.
|
|
13
|
+
# --url-host <host> Hostname shown in returned URL JSON.
|
|
14
|
+
# --foreground Run server in the current terminal (no backgrounding).
|
|
15
|
+
# --background Force background mode (overrides Codex auto-foreground).
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
18
|
+
|
|
19
|
+
# Parse arguments
|
|
20
|
+
PROJECT_DIR=""
|
|
21
|
+
FOREGROUND="false"
|
|
22
|
+
FORCE_BACKGROUND="false"
|
|
23
|
+
BIND_HOST="127.0.0.1"
|
|
24
|
+
URL_HOST=""
|
|
25
|
+
while [[ $# -gt 0 ]]; do
|
|
26
|
+
case "$1" in
|
|
27
|
+
--project-dir)
|
|
28
|
+
PROJECT_DIR="$2"
|
|
29
|
+
shift 2
|
|
30
|
+
;;
|
|
31
|
+
--host)
|
|
32
|
+
BIND_HOST="$2"
|
|
33
|
+
shift 2
|
|
34
|
+
;;
|
|
35
|
+
--url-host)
|
|
36
|
+
URL_HOST="$2"
|
|
37
|
+
shift 2
|
|
38
|
+
;;
|
|
39
|
+
--foreground|--no-daemon)
|
|
40
|
+
FOREGROUND="true"
|
|
41
|
+
shift
|
|
42
|
+
;;
|
|
43
|
+
--background|--daemon)
|
|
44
|
+
FORCE_BACKGROUND="true"
|
|
45
|
+
shift
|
|
46
|
+
;;
|
|
47
|
+
*)
|
|
48
|
+
echo "{\"error\": \"Unknown argument: $1\"}"
|
|
49
|
+
exit 1
|
|
50
|
+
;;
|
|
51
|
+
esac
|
|
52
|
+
done
|
|
53
|
+
|
|
54
|
+
if [[ -z "$URL_HOST" ]]; then
|
|
55
|
+
if [[ "$BIND_HOST" == "127.0.0.1" || "$BIND_HOST" == "localhost" ]]; then
|
|
56
|
+
URL_HOST="localhost"
|
|
57
|
+
else
|
|
58
|
+
URL_HOST="$BIND_HOST"
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Some environments reap detached/background processes. Auto-foreground when detected.
|
|
63
|
+
if [[ -n "${CODEX_CI:-}" && "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then
|
|
64
|
+
FOREGROUND="true"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Windows/Git Bash reaps nohup background processes. Auto-foreground when detected.
|
|
68
|
+
if [[ "$FOREGROUND" != "true" && "$FORCE_BACKGROUND" != "true" ]]; then
|
|
69
|
+
case "${OSTYPE:-}" in
|
|
70
|
+
msys*|cygwin*|mingw*) FOREGROUND="true" ;;
|
|
71
|
+
esac
|
|
72
|
+
if [[ -n "${MSYSTEM:-}" ]]; then
|
|
73
|
+
FOREGROUND="true"
|
|
74
|
+
fi
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Generate unique session directory
|
|
78
|
+
SESSION_ID="$$-$(date +%s)"
|
|
79
|
+
|
|
80
|
+
if [[ -n "$PROJECT_DIR" ]]; then
|
|
81
|
+
SCREEN_DIR="${PROJECT_DIR}/.sia/visualize/${SESSION_ID}"
|
|
82
|
+
else
|
|
83
|
+
SCREEN_DIR="/tmp/visualize-${SESSION_ID}"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
PID_FILE="${SCREEN_DIR}/.server.pid"
|
|
87
|
+
LOG_FILE="${SCREEN_DIR}/.server.log"
|
|
88
|
+
|
|
89
|
+
# Create fresh session directory
|
|
90
|
+
mkdir -p "$SCREEN_DIR"
|
|
91
|
+
|
|
92
|
+
# Generate graph data before starting server
|
|
93
|
+
if [[ -n "$PROJECT_DIR" ]]; then
|
|
94
|
+
GRAPH_FILE="${SCREEN_DIR}/graph.json"
|
|
95
|
+
if command -v sia &>/dev/null; then
|
|
96
|
+
sia export --format json > "$GRAPH_FILE" 2>/dev/null || echo '{"nodes":[],"edges":[]}' > "$GRAPH_FILE"
|
|
97
|
+
elif command -v bun &>/dev/null && [[ -f "${PROJECT_DIR}/src/cli/index.ts" ]]; then
|
|
98
|
+
bun run "${PROJECT_DIR}/src/cli/index.ts" export --format json > "$GRAPH_FILE" 2>/dev/null || echo '{"nodes":[],"edges":[]}' > "$GRAPH_FILE"
|
|
99
|
+
else
|
|
100
|
+
echo '{"nodes":[],"edges":[]}' > "$GRAPH_FILE"
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Kill any existing server
|
|
105
|
+
if [[ -f "$PID_FILE" ]]; then
|
|
106
|
+
old_pid=$(cat "$PID_FILE")
|
|
107
|
+
kill "$old_pid" 2>/dev/null
|
|
108
|
+
rm -f "$PID_FILE"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
cd "$SCRIPT_DIR"
|
|
112
|
+
|
|
113
|
+
# Resolve the harness PID (grandparent of this script).
|
|
114
|
+
OWNER_PID="$(ps -o ppid= -p "$PPID" 2>/dev/null | tr -d ' ')"
|
|
115
|
+
if [[ -z "$OWNER_PID" || "$OWNER_PID" == "1" ]]; then
|
|
116
|
+
OWNER_PID="$PPID"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# On Windows/MSYS2, the MSYS2 PID namespace is invisible to Node.js.
|
|
120
|
+
case "${OSTYPE:-}" in
|
|
121
|
+
msys*|cygwin*|mingw*) OWNER_PID="" ;;
|
|
122
|
+
esac
|
|
123
|
+
|
|
124
|
+
# Foreground mode for environments that reap detached/background processes.
|
|
125
|
+
if [[ "$FOREGROUND" == "true" ]]; then
|
|
126
|
+
echo "$$" > "$PID_FILE"
|
|
127
|
+
env VISUALIZER_DIR="$SCREEN_DIR" VISUALIZER_HOST="$BIND_HOST" VISUALIZER_URL_HOST="$URL_HOST" VISUALIZER_OWNER_PID="$OWNER_PID" GRAPH_DATA_FILE="${GRAPH_FILE:-${SCREEN_DIR}/graph.json}" node visualizer-server.cjs
|
|
128
|
+
exit $?
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# Start server, capturing output to log file
|
|
132
|
+
nohup env VISUALIZER_DIR="$SCREEN_DIR" VISUALIZER_HOST="$BIND_HOST" VISUALIZER_URL_HOST="$URL_HOST" VISUALIZER_OWNER_PID="$OWNER_PID" GRAPH_DATA_FILE="${GRAPH_FILE:-${SCREEN_DIR}/graph.json}" node visualizer-server.cjs > "$LOG_FILE" 2>&1 &
|
|
133
|
+
SERVER_PID=$!
|
|
134
|
+
disown "$SERVER_PID" 2>/dev/null
|
|
135
|
+
echo "$SERVER_PID" > "$PID_FILE"
|
|
136
|
+
|
|
137
|
+
# Wait for server-started message (check log file)
|
|
138
|
+
for i in {1..50}; do
|
|
139
|
+
if grep -q "server-started" "$LOG_FILE" 2>/dev/null; then
|
|
140
|
+
# Verify server is still alive after a short window (catches process reapers)
|
|
141
|
+
alive="true"
|
|
142
|
+
for _ in {1..20}; do
|
|
143
|
+
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
|
|
144
|
+
alive="false"
|
|
145
|
+
break
|
|
146
|
+
fi
|
|
147
|
+
sleep 0.1
|
|
148
|
+
done
|
|
149
|
+
if [[ "$alive" != "true" ]]; then
|
|
150
|
+
echo "{\"error\": \"Server started but was killed. Retry in a persistent terminal with: $SCRIPT_DIR/start-visualizer.sh${PROJECT_DIR:+ --project-dir $PROJECT_DIR} --host $BIND_HOST --url-host $URL_HOST --foreground\"}"
|
|
151
|
+
exit 1
|
|
152
|
+
fi
|
|
153
|
+
grep "server-started" "$LOG_FILE" | head -1
|
|
154
|
+
exit 0
|
|
155
|
+
fi
|
|
156
|
+
sleep 0.1
|
|
157
|
+
done
|
|
158
|
+
|
|
159
|
+
# Timeout - server didn't start
|
|
160
|
+
echo '{"error": "Server failed to start within 5 seconds"}'
|
|
161
|
+
exit 1
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Stop the visualizer server and clean up
|
|
3
|
+
# Usage: stop-visualizer.sh <screen_dir>
|
|
4
|
+
#
|
|
5
|
+
# Kills the server process. Only deletes session directory if it's
|
|
6
|
+
# under /tmp (ephemeral). Persistent directories (.sia/) are
|
|
7
|
+
# kept so graph snapshots can be reviewed later.
|
|
8
|
+
|
|
9
|
+
SCREEN_DIR="$1"
|
|
10
|
+
|
|
11
|
+
if [[ -z "$SCREEN_DIR" ]]; then
|
|
12
|
+
echo '{"error": "Usage: stop-visualizer.sh <screen_dir>"}'
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
PID_FILE="${SCREEN_DIR}/.server.pid"
|
|
17
|
+
|
|
18
|
+
if [[ -f "$PID_FILE" ]]; then
|
|
19
|
+
pid=$(cat "$PID_FILE")
|
|
20
|
+
|
|
21
|
+
# Try to stop gracefully, fallback to force if still alive
|
|
22
|
+
kill "$pid" 2>/dev/null || true
|
|
23
|
+
|
|
24
|
+
# Wait for graceful shutdown (up to ~2s)
|
|
25
|
+
for i in {1..20}; do
|
|
26
|
+
if ! kill -0 "$pid" 2>/dev/null; then
|
|
27
|
+
break
|
|
28
|
+
fi
|
|
29
|
+
sleep 0.1
|
|
30
|
+
done
|
|
31
|
+
|
|
32
|
+
# If still running, escalate to SIGKILL
|
|
33
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
34
|
+
kill -9 "$pid" 2>/dev/null || true
|
|
35
|
+
|
|
36
|
+
# Give SIGKILL a moment to take effect
|
|
37
|
+
sleep 0.1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
41
|
+
echo '{"status": "failed", "error": "process still running"}'
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
rm -f "$PID_FILE" "${SCREEN_DIR}/.server.log"
|
|
46
|
+
|
|
47
|
+
# Only delete ephemeral /tmp directories
|
|
48
|
+
if [[ "$SCREEN_DIR" == /tmp/* ]]; then
|
|
49
|
+
rm -rf "$SCREEN_DIR"
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
echo '{"status": "stopped"}'
|
|
53
|
+
else
|
|
54
|
+
echo '{"status": "not_running"}'
|
|
55
|
+
fi
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
const http = require('http');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
// ========== WebSocket Protocol (RFC 6455) ==========
|
|
7
|
+
|
|
8
|
+
const OPCODES = { TEXT: 0x01, CLOSE: 0x08, PING: 0x09, PONG: 0x0A };
|
|
9
|
+
const WS_MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
|
10
|
+
|
|
11
|
+
function computeAcceptKey(clientKey) {
|
|
12
|
+
return crypto.createHash('sha1').update(clientKey + WS_MAGIC).digest('base64');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function encodeFrame(opcode, payload) {
|
|
16
|
+
const fin = 0x80;
|
|
17
|
+
const len = payload.length;
|
|
18
|
+
let header;
|
|
19
|
+
|
|
20
|
+
if (len < 126) {
|
|
21
|
+
header = Buffer.alloc(2);
|
|
22
|
+
header[0] = fin | opcode;
|
|
23
|
+
header[1] = len;
|
|
24
|
+
} else if (len < 65536) {
|
|
25
|
+
header = Buffer.alloc(4);
|
|
26
|
+
header[0] = fin | opcode;
|
|
27
|
+
header[1] = 126;
|
|
28
|
+
header.writeUInt16BE(len, 2);
|
|
29
|
+
} else {
|
|
30
|
+
header = Buffer.alloc(10);
|
|
31
|
+
header[0] = fin | opcode;
|
|
32
|
+
header[1] = 127;
|
|
33
|
+
header.writeBigUInt64BE(BigInt(len), 2);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return Buffer.concat([header, payload]);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function decodeFrame(buffer) {
|
|
40
|
+
if (buffer.length < 2) return null;
|
|
41
|
+
|
|
42
|
+
const secondByte = buffer[1];
|
|
43
|
+
const opcode = buffer[0] & 0x0F;
|
|
44
|
+
const masked = (secondByte & 0x80) !== 0;
|
|
45
|
+
let payloadLen = secondByte & 0x7F;
|
|
46
|
+
let offset = 2;
|
|
47
|
+
|
|
48
|
+
if (!masked) throw new Error('Client frames must be masked');
|
|
49
|
+
|
|
50
|
+
if (payloadLen === 126) {
|
|
51
|
+
if (buffer.length < 4) return null;
|
|
52
|
+
payloadLen = buffer.readUInt16BE(2);
|
|
53
|
+
offset = 4;
|
|
54
|
+
} else if (payloadLen === 127) {
|
|
55
|
+
if (buffer.length < 10) return null;
|
|
56
|
+
payloadLen = Number(buffer.readBigUInt64BE(2));
|
|
57
|
+
offset = 10;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const maskOffset = offset;
|
|
61
|
+
const dataOffset = offset + 4;
|
|
62
|
+
const totalLen = dataOffset + payloadLen;
|
|
63
|
+
if (buffer.length < totalLen) return null;
|
|
64
|
+
|
|
65
|
+
const mask = buffer.slice(maskOffset, dataOffset);
|
|
66
|
+
const data = Buffer.alloc(payloadLen);
|
|
67
|
+
for (let i = 0; i < payloadLen; i++) {
|
|
68
|
+
data[i] = buffer[dataOffset + i] ^ mask[i % 4];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { opcode, payload: data, bytesConsumed: totalLen };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ========== Configuration ==========
|
|
75
|
+
|
|
76
|
+
const PORT = process.env.VISUALIZER_PORT || (49152 + Math.floor(Math.random() * 16383));
|
|
77
|
+
const HOST = process.env.VISUALIZER_HOST || '127.0.0.1';
|
|
78
|
+
const URL_HOST = process.env.VISUALIZER_URL_HOST || (HOST === '127.0.0.1' ? 'localhost' : HOST);
|
|
79
|
+
const SCREEN_DIR = process.env.VISUALIZER_DIR || '/tmp/visualize';
|
|
80
|
+
const OWNER_PID = process.env.VISUALIZER_OWNER_PID ? Number(process.env.VISUALIZER_OWNER_PID) : null;
|
|
81
|
+
const GRAPH_DATA_FILE = process.env.GRAPH_DATA_FILE || path.join(SCREEN_DIR, 'graph.json');
|
|
82
|
+
|
|
83
|
+
// ========== Template and Graph Data ==========
|
|
84
|
+
|
|
85
|
+
const graphTemplate = fs.readFileSync(path.join(__dirname, 'graph-template.html'), 'utf-8');
|
|
86
|
+
|
|
87
|
+
function loadGraphData() {
|
|
88
|
+
if (fs.existsSync(GRAPH_DATA_FILE)) {
|
|
89
|
+
try {
|
|
90
|
+
return fs.readFileSync(GRAPH_DATA_FILE, 'utf-8');
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.error('Failed to read graph data:', e.message);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return JSON.stringify({ nodes: [], edges: [] });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function buildPage() {
|
|
99
|
+
const graphJson = loadGraphData();
|
|
100
|
+
return graphTemplate.replace('/* GRAPH_DATA */', graphJson);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ========== HTTP Request Handler ==========
|
|
104
|
+
|
|
105
|
+
function handleRequest(req, res) {
|
|
106
|
+
touchActivity();
|
|
107
|
+
if (req.method === 'GET' && req.url === '/') {
|
|
108
|
+
const html = buildPage();
|
|
109
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
110
|
+
res.end(html);
|
|
111
|
+
} else {
|
|
112
|
+
res.writeHead(404);
|
|
113
|
+
res.end('Not found');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ========== WebSocket Connection Handling ==========
|
|
118
|
+
|
|
119
|
+
const clients = new Set();
|
|
120
|
+
|
|
121
|
+
function handleUpgrade(req, socket) {
|
|
122
|
+
const key = req.headers['sec-websocket-key'];
|
|
123
|
+
if (!key) { socket.destroy(); return; }
|
|
124
|
+
|
|
125
|
+
const accept = computeAcceptKey(key);
|
|
126
|
+
socket.write(
|
|
127
|
+
'HTTP/1.1 101 Switching Protocols\r\n' +
|
|
128
|
+
'Upgrade: websocket\r\n' +
|
|
129
|
+
'Connection: Upgrade\r\n' +
|
|
130
|
+
'Sec-WebSocket-Accept: ' + accept + '\r\n\r\n'
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
let buffer = Buffer.alloc(0);
|
|
134
|
+
clients.add(socket);
|
|
135
|
+
|
|
136
|
+
socket.on('data', (chunk) => {
|
|
137
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
138
|
+
while (buffer.length > 0) {
|
|
139
|
+
let result;
|
|
140
|
+
try {
|
|
141
|
+
result = decodeFrame(buffer);
|
|
142
|
+
} catch (e) {
|
|
143
|
+
socket.end(encodeFrame(OPCODES.CLOSE, Buffer.alloc(0)));
|
|
144
|
+
clients.delete(socket);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (!result) break;
|
|
148
|
+
buffer = buffer.slice(result.bytesConsumed);
|
|
149
|
+
|
|
150
|
+
switch (result.opcode) {
|
|
151
|
+
case OPCODES.TEXT:
|
|
152
|
+
touchActivity();
|
|
153
|
+
break;
|
|
154
|
+
case OPCODES.CLOSE:
|
|
155
|
+
socket.end(encodeFrame(OPCODES.CLOSE, Buffer.alloc(0)));
|
|
156
|
+
clients.delete(socket);
|
|
157
|
+
return;
|
|
158
|
+
case OPCODES.PING:
|
|
159
|
+
socket.write(encodeFrame(OPCODES.PONG, result.payload));
|
|
160
|
+
break;
|
|
161
|
+
case OPCODES.PONG:
|
|
162
|
+
break;
|
|
163
|
+
default: {
|
|
164
|
+
const closeBuf = Buffer.alloc(2);
|
|
165
|
+
closeBuf.writeUInt16BE(1003);
|
|
166
|
+
socket.end(encodeFrame(OPCODES.CLOSE, closeBuf));
|
|
167
|
+
clients.delete(socket);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
socket.on('close', () => clients.delete(socket));
|
|
175
|
+
socket.on('error', () => clients.delete(socket));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function broadcast(msg) {
|
|
179
|
+
const frame = encodeFrame(OPCODES.TEXT, Buffer.from(JSON.stringify(msg)));
|
|
180
|
+
for (const socket of clients) {
|
|
181
|
+
try { socket.write(frame); } catch (e) { clients.delete(socket); }
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ========== Activity Tracking ==========
|
|
186
|
+
|
|
187
|
+
const IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
|
|
188
|
+
let lastActivity = Date.now();
|
|
189
|
+
|
|
190
|
+
function touchActivity() {
|
|
191
|
+
lastActivity = Date.now();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ========== Server Startup ==========
|
|
195
|
+
|
|
196
|
+
function startServer() {
|
|
197
|
+
if (!fs.existsSync(SCREEN_DIR)) fs.mkdirSync(SCREEN_DIR, { recursive: true });
|
|
198
|
+
|
|
199
|
+
const server = http.createServer(handleRequest);
|
|
200
|
+
server.on('upgrade', handleUpgrade);
|
|
201
|
+
|
|
202
|
+
// Watch for graph data file changes and push reloads
|
|
203
|
+
const debounceTimers = new Map();
|
|
204
|
+
|
|
205
|
+
if (fs.existsSync(path.dirname(GRAPH_DATA_FILE))) {
|
|
206
|
+
try {
|
|
207
|
+
const watcher = fs.watch(path.dirname(GRAPH_DATA_FILE), (eventType, filename) => {
|
|
208
|
+
if (!filename || filename !== path.basename(GRAPH_DATA_FILE)) return;
|
|
209
|
+
|
|
210
|
+
if (debounceTimers.has(filename)) clearTimeout(debounceTimers.get(filename));
|
|
211
|
+
debounceTimers.set(filename, setTimeout(() => {
|
|
212
|
+
debounceTimers.delete(filename);
|
|
213
|
+
if (!fs.existsSync(GRAPH_DATA_FILE)) return;
|
|
214
|
+
touchActivity();
|
|
215
|
+
console.log(JSON.stringify({ type: 'graph-updated', file: GRAPH_DATA_FILE }));
|
|
216
|
+
broadcast({ type: 'reload' });
|
|
217
|
+
}, 100));
|
|
218
|
+
});
|
|
219
|
+
watcher.on('error', (err) => console.error('fs.watch error:', err.message));
|
|
220
|
+
} catch (e) {
|
|
221
|
+
console.error('Could not watch graph data directory:', e.message);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function shutdown(reason) {
|
|
226
|
+
console.log(JSON.stringify({ type: 'server-stopped', reason }));
|
|
227
|
+
const infoFile = path.join(SCREEN_DIR, '.server-info');
|
|
228
|
+
if (fs.existsSync(infoFile)) fs.unlinkSync(infoFile);
|
|
229
|
+
fs.writeFileSync(
|
|
230
|
+
path.join(SCREEN_DIR, '.server-stopped'),
|
|
231
|
+
JSON.stringify({ reason, timestamp: Date.now() }) + '\n'
|
|
232
|
+
);
|
|
233
|
+
clearInterval(lifecycleCheck);
|
|
234
|
+
server.close(() => process.exit(0));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function ownerAlive() {
|
|
238
|
+
if (!OWNER_PID) return true;
|
|
239
|
+
try { process.kill(OWNER_PID, 0); return true; } catch (e) { return false; }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Check every 60s: exit if owner process died or idle for 30 minutes
|
|
243
|
+
const lifecycleCheck = setInterval(() => {
|
|
244
|
+
if (!ownerAlive()) shutdown('owner process exited');
|
|
245
|
+
else if (Date.now() - lastActivity > IDLE_TIMEOUT_MS) shutdown('idle timeout');
|
|
246
|
+
}, 60 * 1000);
|
|
247
|
+
lifecycleCheck.unref();
|
|
248
|
+
|
|
249
|
+
server.listen(PORT, HOST, () => {
|
|
250
|
+
const info = JSON.stringify({
|
|
251
|
+
type: 'server-started', port: Number(PORT), host: HOST,
|
|
252
|
+
url_host: URL_HOST, url: 'http://' + URL_HOST + ':' + PORT,
|
|
253
|
+
screen_dir: SCREEN_DIR
|
|
254
|
+
});
|
|
255
|
+
console.log(info);
|
|
256
|
+
fs.writeFileSync(path.join(SCREEN_DIR, '.server-info'), info + '\n');
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (require.main === module) {
|
|
261
|
+
startServer();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
module.exports = { computeAcceptKey, encodeFrame, decodeFrame, OPCODES };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sia-workspace
|
|
3
|
+
description: Manages SIA workspaces for cross-repo knowledge sharing — creating workspaces, adding repos, and detecting API contracts. Use when working across multiple repositories or setting up shared knowledge.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SIA Workspace
|
|
7
|
+
|
|
8
|
+
Manage workspaces that enable cross-repo knowledge sharing.
|
|
9
|
+
|
|
10
|
+
## What Are Workspaces?
|
|
11
|
+
|
|
12
|
+
Workspaces group multiple repositories together so SIA can:
|
|
13
|
+
- Share knowledge across repos via bridge edges
|
|
14
|
+
- Detect API contracts between services
|
|
15
|
+
- Enable cross-repo search with `sia_search({ workspace: true })`
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
### Create a workspace
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bun run ${CLAUDE_PLUGIN_ROOT}/src/cli/commands/workspace.ts create "my-workspace"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### List workspaces
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun run ${CLAUDE_PLUGIN_ROOT}/src/cli/commands/workspace.ts list
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Add a repo to a workspace
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun run ${CLAUDE_PLUGIN_ROOT}/src/cli/commands/workspace.ts add "my-workspace" /path/to/repo
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Remove a repo from a workspace
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bun run ${CLAUDE_PLUGIN_ROOT}/src/cli/commands/workspace.ts remove "my-workspace" /path/to/repo
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Show workspace details
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bun run ${CLAUDE_PLUGIN_ROOT}/src/cli/commands/workspace.ts show "my-workspace"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Related: Team Sync
|
|
50
|
+
|
|
51
|
+
For team-based knowledge sharing (requires a sync server):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bun run ${CLAUDE_PLUGIN_ROOT}/src/cli/commands/team.ts join <server-url>
|
|
55
|
+
bun run ${CLAUDE_PLUGIN_ROOT}/src/cli/commands/team.ts status
|
|
56
|
+
bun run ${CLAUDE_PLUGIN_ROOT}/src/cli/commands/team.ts leave
|
|
57
|
+
```
|