spidersan 0.6.0 → 0.10.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/CHANGELOG.md +65 -51
- package/README.md +238 -3
- package/dist/bin/spidersan.d.ts.map +1 -1
- package/dist/bin/spidersan.js +13 -1
- package/dist/bin/spidersan.js.map +1 -1
- package/dist/commands/abandon.d.ts.map +1 -1
- package/dist/commands/abandon.js +1 -9
- package/dist/commands/abandon.js.map +1 -1
- package/dist/commands/ai.d.ts +15 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +498 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/auto.d.ts.map +1 -1
- package/dist/commands/auto.js +2 -1
- package/dist/commands/auto.js.map +1 -1
- package/dist/commands/bot.d.ts +16 -0
- package/dist/commands/bot.d.ts.map +1 -0
- package/dist/commands/bot.js +416 -0
- package/dist/commands/bot.js.map +1 -0
- package/dist/commands/conflicts.d.ts.map +1 -1
- package/dist/commands/conflicts.js +49 -77
- package/dist/commands/conflicts.js.map +1 -1
- package/dist/commands/context.d.ts +8 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +104 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/cross-conflicts.d.ts.map +1 -1
- package/dist/commands/cross-conflicts.js +10 -44
- package/dist/commands/cross-conflicts.js.map +1 -1
- package/dist/commands/depends.d.ts.map +1 -1
- package/dist/commands/depends.js +1 -9
- package/dist/commands/depends.js.map +1 -1
- package/dist/commands/fleet-status.d.ts +14 -0
- package/dist/commands/fleet-status.d.ts.map +1 -0
- package/dist/commands/fleet-status.js +127 -0
- package/dist/commands/fleet-status.js.map +1 -0
- package/dist/commands/git-watch.d.ts +24 -0
- package/dist/commands/git-watch.d.ts.map +1 -0
- package/dist/commands/git-watch.js +84 -0
- package/dist/commands/git-watch.js.map +1 -0
- package/dist/commands/index.d.ts +5 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +7 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/merge-order.d.ts.map +1 -1
- package/dist/commands/merge-order.js +18 -67
- package/dist/commands/merge-order.js.map +1 -1
- package/dist/commands/merged.d.ts.map +1 -1
- package/dist/commands/merged.js +1 -9
- package/dist/commands/merged.js.map +1 -1
- package/dist/commands/pulse.d.ts.map +1 -1
- package/dist/commands/pulse.js +82 -82
- package/dist/commands/pulse.js.map +1 -1
- package/dist/commands/queen.d.ts.map +1 -1
- package/dist/commands/queen.js +11 -7
- package/dist/commands/queen.js.map +1 -1
- package/dist/commands/ready-check.d.ts +2 -1
- package/dist/commands/ready-check.d.ts.map +1 -1
- package/dist/commands/ready-check.js +6 -30
- package/dist/commands/ready-check.js.map +1 -1
- package/dist/commands/register.d.ts.map +1 -1
- package/dist/commands/register.js +22 -37
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/torrent.d.ts.map +1 -1
- package/dist/commands/torrent.js +29 -18
- package/dist/commands/torrent.js.map +1 -1
- package/dist/commands/watch.d.ts +6 -0
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +117 -30
- package/dist/commands/watch.js.map +1 -1
- package/dist/lib/ai/context-builder.d.ts +16 -0
- package/dist/lib/ai/context-builder.d.ts.map +1 -0
- package/dist/lib/ai/context-builder.js +216 -0
- package/dist/lib/ai/context-builder.js.map +1 -0
- package/dist/lib/ai/event-handler.d.ts +21 -0
- package/dist/lib/ai/event-handler.d.ts.map +1 -0
- package/dist/lib/ai/event-handler.js +98 -0
- package/dist/lib/ai/event-handler.js.map +1 -0
- package/dist/lib/ai/index.d.ts +13 -0
- package/dist/lib/ai/index.d.ts.map +1 -0
- package/dist/lib/ai/index.js +11 -0
- package/dist/lib/ai/index.js.map +1 -0
- package/dist/lib/ai/llm-client.d.ts +37 -0
- package/dist/lib/ai/llm-client.d.ts.map +1 -0
- package/dist/lib/ai/llm-client.js +225 -0
- package/dist/lib/ai/llm-client.js.map +1 -0
- package/dist/lib/ai/reasoner.d.ts +11 -0
- package/dist/lib/ai/reasoner.d.ts.map +1 -0
- package/dist/lib/ai/reasoner.js +246 -0
- package/dist/lib/ai/reasoner.js.map +1 -0
- package/dist/lib/ai/setup.d.ts +40 -0
- package/dist/lib/ai/setup.d.ts.map +1 -0
- package/dist/lib/ai/setup.js +154 -0
- package/dist/lib/ai/setup.js.map +1 -0
- package/dist/lib/ai/types.d.ts +135 -0
- package/dist/lib/ai/types.d.ts.map +1 -0
- package/dist/lib/ai/types.js +39 -0
- package/dist/lib/ai/types.js.map +1 -0
- package/dist/lib/colony-subscriber.d.ts +15 -12
- package/dist/lib/colony-subscriber.d.ts.map +1 -1
- package/dist/lib/colony-subscriber.js +146 -65
- package/dist/lib/colony-subscriber.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +18 -4
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/conflict-analyzer.d.ts +33 -0
- package/dist/lib/conflict-analyzer.d.ts.map +1 -0
- package/dist/lib/conflict-analyzer.js +114 -0
- package/dist/lib/conflict-analyzer.js.map +1 -0
- package/dist/lib/conflict-renderer.d.ts +7 -0
- package/dist/lib/conflict-renderer.d.ts.map +1 -0
- package/dist/lib/conflict-renderer.js +162 -0
- package/dist/lib/conflict-renderer.js.map +1 -0
- package/dist/lib/conflict-tier.d.ts +20 -0
- package/dist/lib/conflict-tier.d.ts.map +1 -0
- package/dist/lib/conflict-tier.js +49 -0
- package/dist/lib/conflict-tier.js.map +1 -0
- package/dist/lib/crypto.js +1 -1
- package/dist/lib/crypto.js.map +1 -1
- package/dist/lib/git-events-subscriber.d.ts +59 -0
- package/dist/lib/git-events-subscriber.d.ts.map +1 -0
- package/dist/lib/git-events-subscriber.js +779 -0
- package/dist/lib/git-events-subscriber.js.map +1 -0
- package/dist/lib/git.d.ts +15 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +180 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/github.d.ts.map +1 -1
- package/dist/lib/github.js +14 -9
- package/dist/lib/github.js.map +1 -1
- package/dist/lib/graph.d.ts +23 -0
- package/dist/lib/graph.d.ts.map +1 -0
- package/dist/lib/graph.js +134 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/hub.d.ts +31 -0
- package/dist/lib/hub.d.ts.map +1 -0
- package/dist/lib/hub.js +92 -0
- package/dist/lib/hub.js.map +1 -0
- package/dist/lib/pulse-renderer.d.ts +19 -0
- package/dist/lib/pulse-renderer.d.ts.map +1 -0
- package/dist/lib/pulse-renderer.js +108 -0
- package/dist/lib/pulse-renderer.js.map +1 -0
- package/dist/lib/register-renderer.d.ts +10 -0
- package/dist/lib/register-renderer.d.ts.map +1 -0
- package/dist/lib/register-renderer.js +19 -0
- package/dist/lib/register-renderer.js.map +1 -0
- package/dist/lib/remote-drift.d.ts +61 -0
- package/dist/lib/remote-drift.d.ts.map +1 -0
- package/dist/lib/remote-drift.js +227 -0
- package/dist/lib/remote-drift.js.map +1 -0
- package/dist/lib/salvage-analyzer.d.ts.map +1 -1
- package/dist/lib/salvage-analyzer.js +2 -3
- package/dist/lib/salvage-analyzer.js.map +1 -1
- package/dist/lib/security.d.ts +11 -0
- package/dist/lib/security.d.ts.map +1 -1
- package/dist/lib/security.js +24 -1
- package/dist/lib/security.js.map +1 -1
- package/dist/lib/session-logger.d.ts +54 -0
- package/dist/lib/session-logger.d.ts.map +1 -0
- package/dist/lib/session-logger.js +136 -0
- package/dist/lib/session-logger.js.map +1 -0
- package/dist/lib/watch-renderer.d.ts +13 -0
- package/dist/lib/watch-renderer.d.ts.map +1 -0
- package/dist/lib/watch-renderer.js +35 -0
- package/dist/lib/watch-renderer.js.map +1 -0
- package/dist/storage/adapter.d.ts +4 -0
- package/dist/storage/adapter.d.ts.map +1 -1
- package/dist/storage/branch-registry-store.d.ts +13 -0
- package/dist/storage/branch-registry-store.d.ts.map +1 -0
- package/dist/storage/branch-registry-store.js +2 -0
- package/dist/storage/branch-registry-store.js.map +1 -0
- package/dist/storage/factory.d.ts +4 -0
- package/dist/storage/factory.d.ts.map +1 -1
- package/dist/storage/factory.js +25 -9
- package/dist/storage/factory.js.map +1 -1
- package/dist/storage/git-messages.d.ts +53 -0
- package/dist/storage/git-messages.d.ts.map +1 -0
- package/dist/storage/git-messages.js +376 -0
- package/dist/storage/git-messages.js.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/json-branch-registry-store.d.ts +19 -0
- package/dist/storage/json-branch-registry-store.d.ts.map +1 -0
- package/dist/storage/json-branch-registry-store.js +112 -0
- package/dist/storage/json-branch-registry-store.js.map +1 -0
- package/dist/storage/local-messages.d.ts +37 -0
- package/dist/storage/local-messages.d.ts.map +1 -0
- package/dist/storage/local-messages.js +151 -0
- package/dist/storage/local-messages.js.map +1 -0
- package/dist/storage/local.d.ts +2 -6
- package/dist/storage/local.d.ts.map +1 -1
- package/dist/storage/local.js +13 -76
- package/dist/storage/local.js.map +1 -1
- package/dist/storage/memory-branch-registry-store.d.ts +16 -0
- package/dist/storage/memory-branch-registry-store.d.ts.map +1 -0
- package/dist/storage/memory-branch-registry-store.js +65 -0
- package/dist/storage/memory-branch-registry-store.js.map +1 -0
- package/dist/storage/message-adapter.d.ts +86 -0
- package/dist/storage/message-adapter.d.ts.map +1 -0
- package/dist/storage/message-adapter.js +28 -0
- package/dist/storage/message-adapter.js.map +1 -0
- package/dist/storage/message-factory.d.ts +36 -0
- package/dist/storage/message-factory.d.ts.map +1 -0
- package/dist/storage/message-factory.js +99 -0
- package/dist/storage/message-factory.js.map +1 -0
- package/dist/storage/mycmail-adapter.d.ts +38 -0
- package/dist/storage/mycmail-adapter.d.ts.map +1 -0
- package/dist/storage/mycmail-adapter.js +300 -0
- package/dist/storage/mycmail-adapter.js.map +1 -0
- package/dist/storage/supabase-registry-sync-client-impl.d.ts +46 -0
- package/dist/storage/supabase-registry-sync-client-impl.d.ts.map +1 -0
- package/dist/storage/supabase-registry-sync-client-impl.js +322 -0
- package/dist/storage/supabase-registry-sync-client-impl.js.map +1 -0
- package/dist/storage/supabase-registry-sync-client.d.ts +9 -0
- package/dist/storage/supabase-registry-sync-client.d.ts.map +1 -0
- package/dist/storage/supabase-registry-sync-client.js +2 -0
- package/dist/storage/supabase-registry-sync-client.js.map +1 -0
- package/dist/storage/supabase.d.ts +8 -46
- package/dist/storage/supabase.d.ts.map +1 -1
- package/dist/storage/supabase.js +30 -342
- package/dist/storage/supabase.js.map +1 -1
- package/dist/tui/screen.d.ts.map +1 -1
- package/dist/tui/screen.js +5 -3
- package/dist/tui/screen.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spidersan AI Core — Reasoner
|
|
3
|
+
*
|
|
4
|
+
* Sends SpiderContext + user question to LLM with spidersan-aware system prompt.
|
|
5
|
+
* The scenario playbook is embedded as a TS constant (no file I/O at runtime).
|
|
6
|
+
*/
|
|
7
|
+
import { chat } from './llm-client.js';
|
|
8
|
+
// ─── Known Command Registry ──────────────────────────────────
|
|
9
|
+
// Derived from src/commands/* + spidersan --help. Used to flag model hallucinations at output time.
|
|
10
|
+
// Update when new commands ship.
|
|
11
|
+
const KNOWN_SPIDERSAN_COMMANDS = new Set([
|
|
12
|
+
'abandon', 'advise', 'ai-ping', 'ai-setup', 'ai-telemetry', 'ask', 'auto',
|
|
13
|
+
'bot', 'check-opt-out', 'cleanup', 'collab', 'config', 'conflicts', 'context',
|
|
14
|
+
'cross-conflicts', 'daily', 'dashboard', 'depends', 'doctor', 'explain',
|
|
15
|
+
'fleet-status', 'git-watch', 'github-sync', 'init', 'list', 'log', 'merge-order', 'merged',
|
|
16
|
+
'pulse', 'queen', 'ready-check', 'rebase-helper', 'register', 'registry-sync',
|
|
17
|
+
'rescue', 'stale', 'sync', 'sync-advisor', 'torrent', 'watch', 'welcome',
|
|
18
|
+
]);
|
|
19
|
+
// ─── Embedded Scenario Playbook ─────────────────────────────
|
|
20
|
+
// Optimized via PHC: Sonnet 4.6 proposer + Gemma 4 executor (score: 0.9718)
|
|
21
|
+
// Source: promptclimb/prompt_sonnet_spidersan.md
|
|
22
|
+
const SCENARIO_PLAYBOOK = `## Spidersan Command Reference & Scenarios
|
|
23
|
+
|
|
24
|
+
### SCENARIO 1: New Repo Setup
|
|
25
|
+
Situation: Starting work in a new or uninitialized repository.
|
|
26
|
+
IMPORTANT: When setting up Spidersan for the first time, ALWAYS recommend \`welcome\` as the very first command — it provides guided onboarding before any other setup step.
|
|
27
|
+
Commands: welcome → spidersan init → register --files "f1,f2" --agent <id> → doctor → list
|
|
28
|
+
Reminder: Always verify repo health with \`doctor\` before proceeding.
|
|
29
|
+
|
|
30
|
+
### SCENARIO 2: Ghost/Abandoned Branches
|
|
31
|
+
Situation: Unregistered branches drifting — some with salvageable code, others dead.
|
|
32
|
+
Commands: rescue --scan → rescue --symbols <branch> → sync
|
|
33
|
+
Decision: If \`rescue --symbols\` identifies salvageable code → cherry-pick. If empty/WIP → abandon.
|
|
34
|
+
|
|
35
|
+
### SCENARIO 3: File Conflicts (Tier System)
|
|
36
|
+
- TIER 3 (BLOCK): Critical file (auth, secrets, env) — halt, coordinate immediately.
|
|
37
|
+
- TIER 2 (PAUSE): Important file (package.json, config, server) — coordinate before merging.
|
|
38
|
+
- TIER 1 (WARN): Adjacent/related files — proceed with caution.
|
|
39
|
+
Commands: conflicts → conflicts --tier 3 → conflicts --strict → conflicts --json → conflicts --wake
|
|
40
|
+
Reminder: Tier escalation is mandatory for TIER 3 conflicts. Always reference the TIER level when reporting conflicts.
|
|
41
|
+
|
|
42
|
+
### SCENARIO 4: WIP / Not-Ready Code
|
|
43
|
+
Situation: Branch has TODO, FIXME, HACK, WIP, SPIDER_TRAP, UNFINISHED markers.
|
|
44
|
+
Commands: ready-check → ready-check --json
|
|
45
|
+
Rule: Never merge a branch that fails \`ready-check\`. All markers must be resolved first.
|
|
46
|
+
|
|
47
|
+
### SCENARIO 5: Real-Time Monitoring
|
|
48
|
+
Commands: watch --agent <id> → auto start/stop/status
|
|
49
|
+
Warning: Watch CPU loop if ghost branches claim same files. Fix: sync first.
|
|
50
|
+
Recommendation: Use \`auto\` for periodic monitoring of agent activity.
|
|
51
|
+
|
|
52
|
+
### SCENARIO 6: Task Decomposition (Torrent)
|
|
53
|
+
Situation: Breaking a single task into sequential child subtasks for a serial workflow.
|
|
54
|
+
IMPORTANT: \`torrent\` is for sequential subtask decomposition within a single workflow. For dispatching parallel independent agents simultaneously, use \`queen spawn\` instead (see SCENARIO 9).
|
|
55
|
+
Commands: torrent decompose <TASK> -c N → torrent create <CHILD> -a <agent> → torrent complete <CHILD> → torrent tree → torrent merge-order
|
|
56
|
+
Reminder: Ensure all child tasks are marked completed before executing \`torrent merge-order\`.
|
|
57
|
+
|
|
58
|
+
### SCENARIO 7: Tangled Dependencies
|
|
59
|
+
Commands: merge-order → merge-order --json → merge-order --blocking-count → depends <branch> → conflicts --wake
|
|
60
|
+
Pattern: Merge foundation first → resolve blockers → re-check dependencies → merge dependents.
|
|
61
|
+
|
|
62
|
+
### SCENARIO 8: Stale Branch Cleanup
|
|
63
|
+
Commands: stale → cleanup → abandon <branch> → merged <branch> → sync
|
|
64
|
+
Triage: sync → stale → cleanup → verify with \`list\`.
|
|
65
|
+
|
|
66
|
+
### SCENARIO 9: Queen Dispatch (Parallel Agents)
|
|
67
|
+
Situation: Parallelizing work across multiple sub-agents or sub-spidersans simultaneously.
|
|
68
|
+
IMPORTANT: When asked to parallelize across multiple agents or sub-spidersans, ALWAYS recommend \`queen spawn\` FIRST — this is the dedicated parallel dispatch command. Do NOT suggest \`torrent decompose\` for parallel agent dispatch. Torrent = sequential subtasks. Queen = parallel agents.
|
|
69
|
+
Commands: queen spawn --task "desc" → queen status → queen dissolve <id>
|
|
70
|
+
Rule: Dissolve inactive queens to prevent resource leakage. Use \`queen status\` to monitor all active queens.
|
|
71
|
+
|
|
72
|
+
### SCENARIO 10: Hive Lifecycle
|
|
73
|
+
Hive Operations (via envoak MCP, not spidersan CLI): hive enlist → hive signal --status in-progress → hive heartbeat → hive probe → hive accept → hive close → hive broadcast → hive broadcast-ack → hive broadcast-status → hive cns → hive gc
|
|
74
|
+
Reminder: Use \`probe\` to verify hive readiness before proceeding to \`accept\`.
|
|
75
|
+
|
|
76
|
+
### SCENARIO 11: Cross-Machine Conflicts
|
|
77
|
+
Commands: pulse → cross-conflicts → cross-conflicts --local → doctor --remote
|
|
78
|
+
Pattern: Use \`pulse\` to identify cross-machine activity, followed by conflict resolution steps.
|
|
79
|
+
|
|
80
|
+
### SCENARIO 12: Activity & Context
|
|
81
|
+
Situation: Investigating recent activity, mysterious branches, or understanding what happened over a time period.
|
|
82
|
+
IMPORTANT: When investigating recent or mysterious activity, ALWAYS start with \`log\` and \`daily\` commands first. Do NOT skip to \`rescue\` — log and daily give you the evidence base before taking any action.
|
|
83
|
+
Commands: log → log --since 7d → log --branch <name> → daily → daily --branch <name> --tldr → daily --context --branch <name>
|
|
84
|
+
Recommendation: Use \`daily --context\` for detailed summaries of recent activity.
|
|
85
|
+
|
|
86
|
+
### SCENARIO 13: AI-Assisted Analysis & Proactive Advice
|
|
87
|
+
Situation: Complex repo state that needs intelligent analysis — stale branches, hidden conflicts, unknown branches.
|
|
88
|
+
IMPORTANT: When asked for proactive recommendations or advice about the repo state, ALWAYS recommend \`spidersan advise\` as your FIRST command. Do not give direct advice yourself — \`advise\` is the dedicated entry point for AI-driven proactive recommendations. Only follow with \`context\`, \`ask\`, or \`explain\` after \`advise\` has been run.
|
|
89
|
+
Commands: ai-ping → context → context --json → ask "<question>" → advise → explain <branch>
|
|
90
|
+
Decision: Use \`ai-ping\` to verify AI readiness. Use \`advise\` for proactive recommendations. Use \`ask\` for specific questions. Use \`explain\` for branch investigation.
|
|
91
|
+
|
|
92
|
+
### SCENARIO 13B: Suspicious / Unknown Branch Investigation
|
|
93
|
+
Situation: A branch with an unknown owner, suspicious name (e.g. shadow/, unknown-agent), or no clear origin.
|
|
94
|
+
IMPORTANT: For any unknown or suspicious branch, ALWAYS use \`spidersan explain <branch>\` first. Do NOT jump to \`rescue\` or mention \`queen\` or \`hive\` in this context. \`explain\` is the dedicated command for branch investigation. After \`explain\`, use \`rescue\` only if code needs salvaging.
|
|
95
|
+
Commands: explain <branch> → rescue --symbols <branch> → abandon <branch>
|
|
96
|
+
Decision: explain first → if salvageable → rescue → if empty/dead → abandon.
|
|
97
|
+
|
|
98
|
+
### SCENARIO 14: Branch Abandonment & Rebase Recovery
|
|
99
|
+
Situation: Dead branches (0 commits ahead) cluttering registry, or a branch stuck mid-rebase.
|
|
100
|
+
Commands: abandon <branch> → list --status abandoned → rebase-helper
|
|
101
|
+
Decision: If branch has 0 unique commits → abandon. If \`.git/rebase-merge\` exists → use \`rebase-helper\` to diagnose. After resolution → register updated files.
|
|
102
|
+
|
|
103
|
+
### SCENARIO 15: Remote Sync & GitHub Integration
|
|
104
|
+
Situation: Local registry out of sync with remote. Need to see GitHub PR/CI state.
|
|
105
|
+
Commands: github-sync → sync-advisor → registry-sync --pull → registry-sync --push
|
|
106
|
+
Decision: Use \`github-sync\` for remote branch/PR overview. \`sync-advisor\` for recommendations. \`registry-sync\` to align local ↔ Supabase registry.
|
|
107
|
+
|
|
108
|
+
### SCENARIO 16: Configuration & Onboarding
|
|
109
|
+
Situation: Setting up Spidersan for the first time or changing LLM/stale settings.
|
|
110
|
+
IMPORTANT: ALWAYS start with \`welcome\` for first-time setup — never skip it and go straight to \`init\`. \`welcome\` provides the guided onboarding sequence that ensures correct configuration before initialization.
|
|
111
|
+
Commands: welcome → config list → config set llm.provider <provider> → config set stale.days <n>
|
|
112
|
+
Decision: Use \`welcome\` for guided setup. Use \`config\` for tweaks. Set \`llm.provider\` to lmstudio (local), ollama (local), or copilot (remote, opt-in).
|
|
113
|
+
|
|
114
|
+
### SCENARIO 17: Dependency Management
|
|
115
|
+
Situation: Multiple branches with merge-order dependencies that must be respected.
|
|
116
|
+
IMPORTANT: When dealing with a dependency chain across branches, ALWAYS use \`depends <branch>\` to declare dependencies first, then \`merge-order\` to determine the correct merge sequence. Missing \`depends\` leads to broken merge order.
|
|
117
|
+
Commands: depends <branch> --on <other> → depends --show → merge-order
|
|
118
|
+
Decision: Set dependencies before merging. If circular dependency detected → break the cycle by removing one dependency. \`merge-order\` respects the dependency graph.
|
|
119
|
+
|
|
120
|
+
### SCENARIO 18: Fleet Dashboard & Monitoring
|
|
121
|
+
Situation: Need real-time visibility into branch state, conflicts, and agent activity.
|
|
122
|
+
Commands: dashboard → doctor --remote → pulse → cross-conflicts
|
|
123
|
+
Decision: Use \`dashboard\` for TUI overview. Use \`doctor --remote\` for repo status. Use \`pulse\` and \`cross-conflicts\` for fleet-wide coordination.
|
|
124
|
+
|
|
125
|
+
### Decision Tree
|
|
126
|
+
Starting new work? → welcome → spidersan init → register + doctor
|
|
127
|
+
Found unknown/suspicious branch? → explain <branch> (NOT rescue, NOT queen, NOT hive)
|
|
128
|
+
About to merge? → conflicts → ready-check → depends --show → merge-order
|
|
129
|
+
Branches piling up? → stale → cleanup → sync
|
|
130
|
+
Parallelizing across agents? → queen spawn → queen status (NOT torrent decompose)
|
|
131
|
+
Multi-agent serial task? → torrent decompose → create → complete → tree
|
|
132
|
+
Blocked by another? → conflicts --wake → depends → merge-order
|
|
133
|
+
Cross-machine issues? → pulse → cross-conflicts → doctor --remote
|
|
134
|
+
Need a summary? → daily --branch <name> --tldr
|
|
135
|
+
Investigating recent activity? → log → log --since 7d → daily → daily --context
|
|
136
|
+
Want proactive advice? → advise (ALWAYS first for proactive recommendations)
|
|
137
|
+
Require AI insight? → ai-ping → context → ask/advise/explain
|
|
138
|
+
Dead branches? → abandon + list --status abandoned
|
|
139
|
+
Stuck rebase? → rebase-helper
|
|
140
|
+
Remote out of sync? → github-sync → sync-advisor → registry-sync
|
|
141
|
+
Setting up for first time? → welcome → config (ALWAYS welcome before init)
|
|
142
|
+
Dependency chain? → depends <branch> --on <other> → depends --show → merge-order`;
|
|
143
|
+
// ─── System Prompt Builder ──────────────────────────────────
|
|
144
|
+
function buildSystemPrompt(mode) {
|
|
145
|
+
const persona = `You are Spidersan — the gitops coordinator for a multi-agent AI development fleet called 'the flock'. You speak with authority: direct, structured, actionable. Use real spidersan commands. Reference tier levels. Give git commands where needed. Never speculate — if you don't have enough context, say so.`;
|
|
146
|
+
const modeInstructions = {
|
|
147
|
+
ask: 'Answer the user\'s question using the repository context provided. Recommend specific commands. Structure your response with clear action items per agent if applicable.',
|
|
148
|
+
advise: 'Analyze the current repository state and proactively recommend what should be done next. Prioritize: TIER 3 blocks first, then stale cleanup, then merge ordering. Be concise.',
|
|
149
|
+
explain: 'Explain the branch\'s purpose, owner, status, and any conflicts. Use activity log and daily collab entries if available. Be factual.',
|
|
150
|
+
};
|
|
151
|
+
return `${persona}\n\n${modeInstructions[mode]}\n\n${SCENARIO_PLAYBOOK}`;
|
|
152
|
+
}
|
|
153
|
+
// ─── Context Serializer ─────────────────────────────────────
|
|
154
|
+
function serializeContext(context, verbose) {
|
|
155
|
+
const sections = [
|
|
156
|
+
`## Repository State (${context.timestamp})`,
|
|
157
|
+
`Repo: ${context.repo} | Branch: ${context.branch}`,
|
|
158
|
+
`Git: ${context.gitStatus.ahead} ahead, ${context.gitStatus.behind} behind${context.gitStatus.dirty.length > 0 ? `, ${context.gitStatus.dirty.length} dirty files` : ''}`,
|
|
159
|
+
'',
|
|
160
|
+
`## Registry: ${context.registry.active} active, ${context.registry.stale} stale`,
|
|
161
|
+
];
|
|
162
|
+
if (context.registry.branches.length > 0) {
|
|
163
|
+
for (const b of context.registry.branches.slice(0, 15)) {
|
|
164
|
+
sections.push(` - ${b.name} [${b.status}] agent=${b.agent ?? 'unknown'} files=${b.files.length}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
sections.push('', `## Conflicts: ${context.conflicts.tier3} BLOCK, ${context.conflicts.tier2} PAUSE, ${context.conflicts.tier1} WARN`);
|
|
168
|
+
if (context.conflicts.details.length > 0) {
|
|
169
|
+
for (const c of context.conflicts.details) {
|
|
170
|
+
sections.push(` - TIER ${c.tier}: ${c.branch} ↔ ${c.otherBranch} on [${c.files.join(', ')}]`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
sections.push('', `## Colony: ${context.colony.online ? 'online' : 'offline'}, ${context.colony.activeAgents.length} agents`);
|
|
174
|
+
if (context.colony.inProgress.length > 0) {
|
|
175
|
+
for (const w of context.colony.inProgress) {
|
|
176
|
+
sections.push(` - ${w.agent}: ${w.task} (${w.status})`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (verbose && context.activityLog && context.activityLog.length > 0) {
|
|
180
|
+
sections.push('', '## Recent Activity (last 24h)');
|
|
181
|
+
for (const a of context.activityLog.slice(0, 10)) {
|
|
182
|
+
sections.push(` - [${a.event}] ${a.branch ?? ''} by ${a.agent ?? 'unknown'} at ${a.timestamp}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return sections.join('\n');
|
|
186
|
+
}
|
|
187
|
+
// ─── Main Reasoning Function ────────────────────────────────
|
|
188
|
+
export async function reason(request, llmOverrides) {
|
|
189
|
+
const systemPrompt = buildSystemPrompt(request.mode);
|
|
190
|
+
const contextText = serializeContext(request.context, request.verbose);
|
|
191
|
+
let userMessage;
|
|
192
|
+
switch (request.mode) {
|
|
193
|
+
case 'ask':
|
|
194
|
+
userMessage = `${contextText}\n\n## Question\n${request.question}`;
|
|
195
|
+
break;
|
|
196
|
+
case 'advise':
|
|
197
|
+
userMessage = `${contextText}\n\nWhat should I do next? Prioritize by urgency.`;
|
|
198
|
+
break;
|
|
199
|
+
case 'explain':
|
|
200
|
+
userMessage = `${contextText}\n\nExplain branch: ${request.branch}`;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
const messages = [
|
|
204
|
+
{ role: 'system', content: systemPrompt },
|
|
205
|
+
{ role: 'user', content: userMessage },
|
|
206
|
+
];
|
|
207
|
+
const response = await chat(messages, llmOverrides);
|
|
208
|
+
// Extract commands from response (lines starting with spidersan/git/envoak/toak)
|
|
209
|
+
const commandPattern = /^\s*(?:spidersan|git|envoak|toak|npx spidersan)\s+.+/gm;
|
|
210
|
+
const commands = (response.content.match(commandPattern) ?? []).map(c => c.trim());
|
|
211
|
+
// Validate spidersan sub-commands against the known registry
|
|
212
|
+
const spidersanSubcommandPattern = /^(?:spidersan|npx spidersan)\s+(\S+)/;
|
|
213
|
+
const unknownCommands = commands.filter(cmd => {
|
|
214
|
+
const m = cmd.match(spidersanSubcommandPattern);
|
|
215
|
+
return m !== null && !m[1].startsWith('-') && !KNOWN_SPIDERSAN_COMMANDS.has(m[1]);
|
|
216
|
+
});
|
|
217
|
+
// Estimate confidence from context quality
|
|
218
|
+
const hasConflicts = request.context.conflicts.tier3 > 0 || request.context.conflicts.tier2 > 0;
|
|
219
|
+
const hasRegistry = request.context.registry.active > 0;
|
|
220
|
+
const confidence = hasRegistry
|
|
221
|
+
? (hasConflicts ? 'high' : 'medium')
|
|
222
|
+
: 'low';
|
|
223
|
+
// Numeric confidence score: try to extract from model response (P2A-1 structured output),
|
|
224
|
+
// fall back to heuristic mapping.
|
|
225
|
+
const CONFIDENCE_SCORES = { high: 0.9, medium: 0.7, low: 0.3 };
|
|
226
|
+
let confidenceScore = CONFIDENCE_SCORES[confidence];
|
|
227
|
+
// Try to parse numeric confidence from structured JSON response (P2A-1 model format)
|
|
228
|
+
const jsonMatch = response.content.match(/^\s*\{[\s\S]*?"confidence"\s*:\s*(0(?:\.\d+)?|1(?:\.0+)?)/m);
|
|
229
|
+
if (jsonMatch?.[1]) {
|
|
230
|
+
const parsed = parseFloat(jsonMatch[1]);
|
|
231
|
+
if (!isNaN(parsed) && parsed >= 0 && parsed <= 1) {
|
|
232
|
+
confidenceScore = parsed;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
advice: response.content,
|
|
237
|
+
commands,
|
|
238
|
+
unknownCommands,
|
|
239
|
+
confidence: confidence,
|
|
240
|
+
confidenceScore,
|
|
241
|
+
mode: request.mode,
|
|
242
|
+
provider: response.provider,
|
|
243
|
+
tokensUsed: response.promptTokens + response.completionTokens,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=reasoner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasoner.js","sourceRoot":"","sources":["../../../src/lib/ai/reasoner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spidersan AI Setup — tier config, server probe, BYOM URL validation
|
|
3
|
+
*
|
|
4
|
+
* Manages ~/.spidersan/config.json (AI-specific config, separate from .spidersanrc)
|
|
5
|
+
* Per spec: SPEC_spidersan_byom_telemetry.md §1.2, §1.3, §1.5, §2.1
|
|
6
|
+
*/
|
|
7
|
+
export type AiTier = 'free' | 'contributor' | 'byom' | 'local';
|
|
8
|
+
export interface AiSetupConfig {
|
|
9
|
+
/** How spidersan ask routes LLM requests */
|
|
10
|
+
tier: AiTier;
|
|
11
|
+
/** Saved BYOM URL (only when tier=byom or explicit BYOM preference alongside hosted) */
|
|
12
|
+
byomUrl?: string;
|
|
13
|
+
/** User explicitly confirmed the BYOM URL is external — skip future prompts */
|
|
14
|
+
byomConfirmed?: boolean;
|
|
15
|
+
/** API key for hosted tier (free or contributor) */
|
|
16
|
+
apiKey?: string;
|
|
17
|
+
/** Whether the user has seen and responded to the consent wizard */
|
|
18
|
+
consentGiven?: boolean;
|
|
19
|
+
/** ISO timestamp of first setup */
|
|
20
|
+
setupAt?: string;
|
|
21
|
+
/** ISO timestamp of last update */
|
|
22
|
+
updatedAt?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function loadAiConfig(): Promise<AiSetupConfig | null>;
|
|
25
|
+
export declare function saveAiConfig(config: AiSetupConfig): Promise<void>;
|
|
26
|
+
export declare function appendByomAudit(source: 'local_probe' | 'env_var' | 'hosted_api' | 'byom_config', url: string, confirmed: 'implicit' | 'explicit'): Promise<void>;
|
|
27
|
+
export interface ProbeResult {
|
|
28
|
+
url: string;
|
|
29
|
+
port: number;
|
|
30
|
+
label: string;
|
|
31
|
+
responding: boolean;
|
|
32
|
+
models?: string[];
|
|
33
|
+
}
|
|
34
|
+
export declare function probeLocalServers(timeoutMs?: number): Promise<ProbeResult[]>;
|
|
35
|
+
/** Probe the hosted API tier. Returns a ProbeResult. */
|
|
36
|
+
export declare function probeHostedTier(apiKey: string, timeoutMs?: number): Promise<ProbeResult>;
|
|
37
|
+
export type UrlClass = 'local' | 'lan' | 'external';
|
|
38
|
+
export declare function classifyUrl(rawUrl: string): UrlClass;
|
|
39
|
+
export declare function isLocalOrLan(url: string): boolean;
|
|
40
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAQlE;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAQvE;AAID,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,YAAY,GAAG,aAAa,EAChE,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,UAAU,GAAG,UAAU,GACjC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAID,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AASD,wBAAsB,iBAAiB,CAAC,SAAS,SAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CA8B/E;AAED,wDAAwD;AACxD,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAiC5F;AAID,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC;AAMpD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAWpD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEjD"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spidersan AI Setup — tier config, server probe, BYOM URL validation
|
|
3
|
+
*
|
|
4
|
+
* Manages ~/.spidersan/config.json (AI-specific config, separate from .spidersanrc)
|
|
5
|
+
* Per spec: SPEC_spidersan_byom_telemetry.md §1.2, §1.3, §1.5, §2.1
|
|
6
|
+
*/
|
|
7
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
11
|
+
import { HOSTED_API_BASE_URL } from './types.js';
|
|
12
|
+
// ─── Paths ──────────────────────────────────────────────────
|
|
13
|
+
const SPIDERSAN_HOME = join(homedir(), '.spidersan');
|
|
14
|
+
const CONFIG_PATH = join(SPIDERSAN_HOME, 'config.json');
|
|
15
|
+
const BYOM_AUDIT_PATH = join(SPIDERSAN_HOME, 'byom-audit.log');
|
|
16
|
+
// ─── Config persistence ─────────────────────────────────────
|
|
17
|
+
export async function loadAiConfig() {
|
|
18
|
+
if (!existsSync(CONFIG_PATH))
|
|
19
|
+
return null;
|
|
20
|
+
try {
|
|
21
|
+
const raw = await readFile(CONFIG_PATH, 'utf8');
|
|
22
|
+
return JSON.parse(raw);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function saveAiConfig(config) {
|
|
29
|
+
await mkdir(SPIDERSAN_HOME, { recursive: true });
|
|
30
|
+
const updated = {
|
|
31
|
+
...config,
|
|
32
|
+
updatedAt: new Date().toISOString(),
|
|
33
|
+
setupAt: config.setupAt ?? new Date().toISOString(),
|
|
34
|
+
};
|
|
35
|
+
await writeFile(CONFIG_PATH, JSON.stringify(updated, null, 2), { mode: 0o600 });
|
|
36
|
+
}
|
|
37
|
+
// ─── BYOM audit log ─────────────────────────────────────────
|
|
38
|
+
export async function appendByomAudit(source, url, confirmed) {
|
|
39
|
+
const line = `${new Date().toISOString()} source=${source} url=${url} confirmed=${confirmed}\n`;
|
|
40
|
+
try {
|
|
41
|
+
await mkdir(SPIDERSAN_HOME, { recursive: true });
|
|
42
|
+
const { appendFile } = await import('node:fs/promises');
|
|
43
|
+
await appendFile(BYOM_AUDIT_PATH, line);
|
|
44
|
+
// Rotate at 1 MB
|
|
45
|
+
const { stat } = await import('node:fs/promises');
|
|
46
|
+
const stats = await stat(BYOM_AUDIT_PATH);
|
|
47
|
+
if (stats.size > 1_000_000) {
|
|
48
|
+
const existing = await readFile(BYOM_AUDIT_PATH, 'utf8');
|
|
49
|
+
const lines = existing.split('\n');
|
|
50
|
+
// Keep last 500 lines
|
|
51
|
+
await writeFile(BYOM_AUDIT_PATH, lines.slice(-500).join('\n'));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Audit log failure is never fatal
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const LOCAL_PROBE_TARGETS = [
|
|
59
|
+
{ port: 8095, label: 'spidersan model (mlx_lm.server)' },
|
|
60
|
+
{ port: 8082, label: 'LM Studio (custom port)' },
|
|
61
|
+
{ port: 11434, label: 'Ollama' },
|
|
62
|
+
{ port: 1234, label: 'LM Studio (default)' },
|
|
63
|
+
];
|
|
64
|
+
export async function probeLocalServers(timeoutMs = 800) {
|
|
65
|
+
const results = await Promise.allSettled(LOCAL_PROBE_TARGETS.map(async ({ port, label }) => {
|
|
66
|
+
const url = `http://localhost:${port}/v1/models`;
|
|
67
|
+
const controller = new AbortController();
|
|
68
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
69
|
+
try {
|
|
70
|
+
const res = await fetch(url, {
|
|
71
|
+
signal: controller.signal,
|
|
72
|
+
headers: { Accept: 'application/json' },
|
|
73
|
+
});
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
return { url: `http://localhost:${port}/v1`, port, label, responding: false };
|
|
77
|
+
}
|
|
78
|
+
let models;
|
|
79
|
+
try {
|
|
80
|
+
const body = (await res.json());
|
|
81
|
+
models = body.data?.map((m) => m.id).slice(0, 3);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// model list parse failure is non-fatal
|
|
85
|
+
}
|
|
86
|
+
return { url: `http://localhost:${port}/v1`, port, label, responding: true, models };
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
return { url: `http://localhost:${port}/v1`, port, label, responding: false };
|
|
91
|
+
}
|
|
92
|
+
}));
|
|
93
|
+
return results.map((r) => (r.status === 'fulfilled' ? r.value : null)).filter(Boolean);
|
|
94
|
+
}
|
|
95
|
+
/** Probe the hosted API tier. Returns a ProbeResult. */
|
|
96
|
+
export async function probeHostedTier(apiKey, timeoutMs = 2000) {
|
|
97
|
+
const base = HOSTED_API_BASE_URL;
|
|
98
|
+
const url = `${base}/models`;
|
|
99
|
+
const label = 'Hosted API (spidersan-api-proxy)';
|
|
100
|
+
const controller = new AbortController();
|
|
101
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
102
|
+
try {
|
|
103
|
+
const res = await fetch(url, {
|
|
104
|
+
signal: controller.signal,
|
|
105
|
+
headers: {
|
|
106
|
+
Accept: 'application/json',
|
|
107
|
+
Authorization: `Bearer ${apiKey}`,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
clearTimeout(timer);
|
|
111
|
+
if (res.status === 401) {
|
|
112
|
+
return { url: base, port: 443, label, responding: false };
|
|
113
|
+
}
|
|
114
|
+
if (!res.ok) {
|
|
115
|
+
return { url: base, port: 443, label, responding: false };
|
|
116
|
+
}
|
|
117
|
+
let models;
|
|
118
|
+
try {
|
|
119
|
+
const body = (await res.json());
|
|
120
|
+
models = body.data?.map((m) => m.id).slice(0, 3);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// non-fatal
|
|
124
|
+
}
|
|
125
|
+
return { url: base, port: 443, label, responding: true, models };
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
clearTimeout(timer);
|
|
129
|
+
return { url: base, port: 443, label, responding: false };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const LAN_PREFIXES = ['192.168.', '10.', '172.16.', '172.17.', '172.18.', '172.19.',
|
|
133
|
+
'172.20.', '172.21.', '172.22.', '172.23.', '172.24.', '172.25.', '172.26.',
|
|
134
|
+
'172.27.', '172.28.', '172.29.', '172.30.', '172.31.'];
|
|
135
|
+
export function classifyUrl(rawUrl) {
|
|
136
|
+
try {
|
|
137
|
+
const parsed = new URL(rawUrl);
|
|
138
|
+
const host = parsed.hostname;
|
|
139
|
+
if (host === 'localhost' || host === '127.0.0.1' || host === '::1')
|
|
140
|
+
return 'local';
|
|
141
|
+
if (host.endsWith('.local'))
|
|
142
|
+
return 'lan';
|
|
143
|
+
if (LAN_PREFIXES.some((prefix) => host.startsWith(prefix)))
|
|
144
|
+
return 'lan';
|
|
145
|
+
return 'external';
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return 'external';
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export function isLocalOrLan(url) {
|
|
152
|
+
return classifyUrl(url) !== 'external';
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/lib/ai/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spidersan AI Core — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Shared types for context aggregation, LLM reasoning, and event handling.
|
|
5
|
+
* Used by CLI (ask/advise/explain), MCP tools, webhook, and agent mode.
|
|
6
|
+
*/
|
|
7
|
+
export interface BranchSummary {
|
|
8
|
+
name: string;
|
|
9
|
+
agent: string | null;
|
|
10
|
+
files: string[];
|
|
11
|
+
status: 'active' | 'merged' | 'abandoned' | 'completed';
|
|
12
|
+
lastUpdated: string;
|
|
13
|
+
commitsBehindMain: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ConflictSummary {
|
|
16
|
+
branch: string;
|
|
17
|
+
otherBranch: string;
|
|
18
|
+
tier: 1 | 2 | 3;
|
|
19
|
+
files: string[];
|
|
20
|
+
agent: string | null;
|
|
21
|
+
otherAgent: string | null;
|
|
22
|
+
}
|
|
23
|
+
export interface WorkSignal {
|
|
24
|
+
agent: string;
|
|
25
|
+
task: string;
|
|
26
|
+
status: string;
|
|
27
|
+
lastHeartbeat: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ActivityEntry {
|
|
30
|
+
event: string;
|
|
31
|
+
branch: string | null;
|
|
32
|
+
agent: string | null;
|
|
33
|
+
details: Record<string, unknown>;
|
|
34
|
+
timestamp: string;
|
|
35
|
+
}
|
|
36
|
+
export interface DailyEntry {
|
|
37
|
+
agent: string;
|
|
38
|
+
content: string;
|
|
39
|
+
timestamp: string;
|
|
40
|
+
}
|
|
41
|
+
export interface SpiderContext {
|
|
42
|
+
timestamp: string;
|
|
43
|
+
repo: string;
|
|
44
|
+
branch: string;
|
|
45
|
+
registry: {
|
|
46
|
+
active: number;
|
|
47
|
+
stale: number;
|
|
48
|
+
branches: BranchSummary[];
|
|
49
|
+
};
|
|
50
|
+
conflicts: {
|
|
51
|
+
tier1: number;
|
|
52
|
+
tier2: number;
|
|
53
|
+
tier3: number;
|
|
54
|
+
details: ConflictSummary[];
|
|
55
|
+
};
|
|
56
|
+
gitStatus: {
|
|
57
|
+
ahead: number;
|
|
58
|
+
behind: number;
|
|
59
|
+
dirty: string[];
|
|
60
|
+
};
|
|
61
|
+
colony: {
|
|
62
|
+
online: boolean;
|
|
63
|
+
activeAgents: string[];
|
|
64
|
+
inProgress: WorkSignal[];
|
|
65
|
+
};
|
|
66
|
+
activityLog?: ActivityEntry[];
|
|
67
|
+
dailyCollab?: DailyEntry[];
|
|
68
|
+
}
|
|
69
|
+
export type LLMProvider = 'lmstudio' | 'copilot' | 'ollama' | 'hosted';
|
|
70
|
+
export interface LLMConfig {
|
|
71
|
+
provider: LLMProvider;
|
|
72
|
+
model: string;
|
|
73
|
+
baseUrl: string;
|
|
74
|
+
apiKey?: string;
|
|
75
|
+
temperature: number;
|
|
76
|
+
maxTokens: number;
|
|
77
|
+
}
|
|
78
|
+
export interface LLMMessage {
|
|
79
|
+
role: 'system' | 'user' | 'assistant';
|
|
80
|
+
content: string;
|
|
81
|
+
}
|
|
82
|
+
export interface LLMResponse {
|
|
83
|
+
content: string;
|
|
84
|
+
model: string;
|
|
85
|
+
provider: LLMProvider;
|
|
86
|
+
promptTokens: number;
|
|
87
|
+
completionTokens: number;
|
|
88
|
+
}
|
|
89
|
+
export type ReasoningMode = 'ask' | 'advise' | 'explain';
|
|
90
|
+
export interface ReasoningRequest {
|
|
91
|
+
mode: ReasoningMode;
|
|
92
|
+
question?: string;
|
|
93
|
+
branch?: string;
|
|
94
|
+
context: SpiderContext;
|
|
95
|
+
verbose?: boolean;
|
|
96
|
+
}
|
|
97
|
+
export interface ReasoningResult {
|
|
98
|
+
advice: string;
|
|
99
|
+
commands: string[];
|
|
100
|
+
/** Commands suggested by the model that are not in the known spidersan CLI. Empty = all validated. */
|
|
101
|
+
unknownCommands: string[];
|
|
102
|
+
confidence: 'high' | 'medium' | 'low';
|
|
103
|
+
/** Numeric confidence score 0.0–1.0. Values below 0.7 trigger a "review manually" warning. */
|
|
104
|
+
confidenceScore: number;
|
|
105
|
+
mode: ReasoningMode;
|
|
106
|
+
provider: LLMProvider;
|
|
107
|
+
tokensUsed: number;
|
|
108
|
+
}
|
|
109
|
+
export type EventType = 'push' | 'pull_request' | 'colony_signal' | 'branch_register';
|
|
110
|
+
export interface EventPayload {
|
|
111
|
+
type: EventType;
|
|
112
|
+
repo: string;
|
|
113
|
+
branch?: string;
|
|
114
|
+
agent?: string;
|
|
115
|
+
files?: string[];
|
|
116
|
+
metadata?: Record<string, unknown>;
|
|
117
|
+
}
|
|
118
|
+
export interface Advice {
|
|
119
|
+
tier: 0 | 1 | 2 | 3;
|
|
120
|
+
action: 'info' | 'warn' | 'pause' | 'block';
|
|
121
|
+
message: string;
|
|
122
|
+
commands: string[];
|
|
123
|
+
escalateToLLM: boolean;
|
|
124
|
+
}
|
|
125
|
+
export interface AIConfig {
|
|
126
|
+
llm: LLMConfig;
|
|
127
|
+
enableColony: boolean;
|
|
128
|
+
enableMemoak: boolean;
|
|
129
|
+
enableDailyBridge: boolean;
|
|
130
|
+
playbookPath?: string;
|
|
131
|
+
}
|
|
132
|
+
/** Canonical hosted API base URL — shared between types, setup probe, and llm-client. */
|
|
133
|
+
export declare const HOSTED_API_BASE_URL = "https://api.spidersan.net/v1";
|
|
134
|
+
export declare const DEFAULT_LLM_CONFIGS: Record<LLMProvider, LLMConfig>;
|
|
135
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/ai/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spidersan AI Core — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Shared types for context aggregation, LLM reasoning, and event handling.
|
|
5
|
+
* Used by CLI (ask/advise/explain), MCP tools, webhook, and agent mode.
|
|
6
|
+
*/
|
|
7
|
+
/** Canonical hosted API base URL — shared between types, setup probe, and llm-client. */
|
|
8
|
+
export const HOSTED_API_BASE_URL = 'https://api.spidersan.net/v1';
|
|
9
|
+
export const DEFAULT_LLM_CONFIGS = {
|
|
10
|
+
lmstudio: {
|
|
11
|
+
provider: 'lmstudio',
|
|
12
|
+
model: 'gemma-4-26b-a4b-it',
|
|
13
|
+
baseUrl: 'http://127.0.0.1:1234/v1',
|
|
14
|
+
temperature: 0.4,
|
|
15
|
+
maxTokens: 800,
|
|
16
|
+
},
|
|
17
|
+
copilot: {
|
|
18
|
+
provider: 'copilot',
|
|
19
|
+
model: 'gpt-4o',
|
|
20
|
+
baseUrl: 'https://models.inference.ai.azure.com',
|
|
21
|
+
temperature: 0.4,
|
|
22
|
+
maxTokens: 800,
|
|
23
|
+
},
|
|
24
|
+
ollama: {
|
|
25
|
+
provider: 'ollama',
|
|
26
|
+
model: 'gemma3:4b',
|
|
27
|
+
baseUrl: 'http://localhost:11434',
|
|
28
|
+
temperature: 0.4,
|
|
29
|
+
maxTokens: 800,
|
|
30
|
+
},
|
|
31
|
+
hosted: {
|
|
32
|
+
provider: 'hosted',
|
|
33
|
+
model: 'spidersan-v1',
|
|
34
|
+
baseUrl: HOSTED_API_BASE_URL,
|
|
35
|
+
temperature: 0.4,
|
|
36
|
+
maxTokens: 800,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=types.js.map
|