spidersan 0.20.1 → 0.20.2
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 +8 -0
- package/dist/bin/command-registry.d.ts +25 -0
- package/dist/bin/command-registry.d.ts.map +1 -0
- package/dist/bin/command-registry.js +29 -0
- package/dist/bin/command-registry.js.map +1 -0
- package/dist/bin/spidersan.d.ts +16 -0
- package/dist/bin/spidersan.d.ts.map +1 -0
- package/dist/bin/spidersan.js +98 -0
- package/dist/bin/spidersan.js.map +1 -0
- package/dist/commands/abandon.d.ts +8 -0
- package/dist/commands/abandon.d.ts.map +1 -0
- package/dist/commands/abandon.js +43 -0
- package/dist/commands/abandon.js.map +1 -0
- package/dist/commands/cleanup.d.ts +8 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +50 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/config.d.ts +15 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +309 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/conflicts.d.ts +34 -0
- package/dist/commands/conflicts.d.ts.map +1 -0
- package/dist/commands/conflicts.js +773 -0
- package/dist/commands/conflicts.js.map +1 -0
- 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 +17 -0
- package/dist/commands/cross-conflicts.d.ts.map +1 -0
- package/dist/commands/cross-conflicts.js +273 -0
- package/dist/commands/cross-conflicts.js.map +1 -0
- package/dist/commands/depends.d.ts +11 -0
- package/dist/commands/depends.d.ts.map +1 -0
- package/dist/commands/depends.js +63 -0
- package/dist/commands/depends.js.map +1 -0
- package/dist/commands/doctor.d.ts +30 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +558 -0
- package/dist/commands/doctor.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/github-sync.d.ts +42 -0
- package/dist/commands/github-sync.d.ts.map +1 -0
- package/dist/commands/github-sync.js +191 -0
- package/dist/commands/github-sync.js.map +1 -0
- package/dist/commands/index.d.ts +25 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +29 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +23 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +45 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/log.d.ts +7 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +110 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/merge-order.d.ts +9 -0
- package/dist/commands/merge-order.d.ts.map +1 -0
- package/dist/commands/merge-order.js +100 -0
- package/dist/commands/merge-order.js.map +1 -0
- package/dist/commands/merged.d.ts +8 -0
- package/dist/commands/merged.d.ts.map +1 -0
- package/dist/commands/merged.js +37 -0
- package/dist/commands/merged.js.map +1 -0
- package/dist/commands/pr-check.d.ts +24 -0
- package/dist/commands/pr-check.d.ts.map +1 -0
- package/dist/commands/pr-check.js +85 -0
- package/dist/commands/pr-check.js.map +1 -0
- package/dist/commands/ready-check.d.ts +11 -0
- package/dist/commands/ready-check.d.ts.map +1 -0
- package/dist/commands/ready-check.js +150 -0
- package/dist/commands/ready-check.js.map +1 -0
- package/dist/commands/rebase-helper.d.ts +3 -0
- package/dist/commands/rebase-helper.d.ts.map +1 -0
- package/dist/commands/rebase-helper.js +52 -0
- package/dist/commands/rebase-helper.js.map +1 -0
- package/dist/commands/register.d.ts +10 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +176 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/registry-sync.d.ts +9 -0
- package/dist/commands/registry-sync.d.ts.map +1 -0
- package/dist/commands/registry-sync.js +129 -0
- package/dist/commands/registry-sync.js.map +1 -0
- package/dist/commands/stale.d.ts +17 -0
- package/dist/commands/stale.d.ts.map +1 -0
- package/dist/commands/stale.js +136 -0
- package/dist/commands/stale.js.map +1 -0
- package/dist/commands/sync.d.ts +21 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +78 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/verify-trunk.d.ts +18 -0
- package/dist/commands/verify-trunk.d.ts.map +1 -0
- package/dist/commands/verify-trunk.js +77 -0
- package/dist/commands/verify-trunk.js.map +1 -0
- package/dist/commands/watch.d.ts +8 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +509 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/activity.d.ts +53 -0
- package/dist/lib/activity.d.ts.map +1 -0
- package/dist/lib/activity.js +271 -0
- package/dist/lib/activity.js.map +1 -0
- package/dist/lib/agent-errors.d.ts +41 -0
- package/dist/lib/agent-errors.d.ts.map +1 -0
- package/dist/lib/agent-errors.js +145 -0
- package/dist/lib/agent-errors.js.map +1 -0
- 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 +229 -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 +111 -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 +227 -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 +42 -0
- package/dist/lib/ai/types.js.map +1 -0
- package/dist/lib/ast.d.ts +44 -0
- package/dist/lib/ast.d.ts.map +1 -0
- package/dist/lib/ast.js +160 -0
- package/dist/lib/ast.js.map +1 -0
- package/dist/lib/carries.d.ts +22 -0
- package/dist/lib/carries.d.ts.map +1 -0
- package/dist/lib/carries.js +56 -0
- package/dist/lib/carries.js.map +1 -0
- package/dist/lib/colony-subscriber.d.ts +56 -0
- package/dist/lib/colony-subscriber.d.ts.map +1 -0
- package/dist/lib/colony-subscriber.js +265 -0
- package/dist/lib/colony-subscriber.js.map +1 -0
- package/dist/lib/config.d.ts +62 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +235 -0
- package/dist/lib/config.js.map +1 -0
- 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 +145 -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.d.ts +71 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +176 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/ecosystem-env.d.ts +33 -0
- package/dist/lib/ecosystem-env.d.ts.map +1 -0
- package/dist/lib/ecosystem-env.js +62 -0
- package/dist/lib/ecosystem-env.js.map +1 -0
- package/dist/lib/errors.d.ts +35 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +71 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/git-events-subscriber.d.ts +86 -0
- package/dist/lib/git-events-subscriber.d.ts.map +1 -0
- package/dist/lib/git-events-subscriber.js +870 -0
- package/dist/lib/git-events-subscriber.js.map +1 -0
- package/dist/lib/git-merge-analyzer.d.ts +38 -0
- package/dist/lib/git-merge-analyzer.d.ts.map +1 -0
- package/dist/lib/git-merge-analyzer.js +23 -0
- package/dist/lib/git-merge-analyzer.js.map +1 -0
- package/dist/lib/git.d.ts +103 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +670 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/github.d.ts +151 -0
- package/dist/lib/github.d.ts.map +1 -0
- package/dist/lib/github.js +425 -0
- package/dist/lib/github.js.map +1 -0
- package/dist/lib/graph.d.ts +38 -0
- package/dist/lib/graph.d.ts.map +1 -0
- package/dist/lib/graph.js +165 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/machine.d.ts +14 -0
- package/dist/lib/machine.d.ts.map +1 -0
- package/dist/lib/machine.js +38 -0
- package/dist/lib/machine.js.map +1 -0
- package/dist/lib/notify.d.ts +68 -0
- package/dist/lib/notify.d.ts.map +1 -0
- package/dist/lib/notify.js +111 -0
- package/dist/lib/notify.js.map +1 -0
- package/dist/lib/outline.d.ts +6 -0
- package/dist/lib/outline.d.ts.map +1 -0
- package/dist/lib/outline.js +60 -0
- package/dist/lib/outline.js.map +1 -0
- package/dist/lib/push-registry.d.ts +22 -0
- package/dist/lib/push-registry.d.ts.map +1 -0
- package/dist/lib/push-registry.js +21 -0
- package/dist/lib/push-registry.js.map +1 -0
- package/dist/lib/reconcile.d.ts +100 -0
- package/dist/lib/reconcile.d.ts.map +1 -0
- package/dist/lib/reconcile.js +121 -0
- package/dist/lib/reconcile.js.map +1 -0
- package/dist/lib/regex-utils.d.ts +6 -0
- package/dist/lib/regex-utils.d.ts.map +1 -0
- package/dist/lib/regex-utils.js +24 -0
- package/dist/lib/regex-utils.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/security.d.ts +72 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +180 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/semantic-analysis.d.ts +31 -0
- package/dist/lib/semantic-analysis.d.ts.map +1 -0
- package/dist/lib/semantic-analysis.js +120 -0
- package/dist/lib/semantic-analysis.js.map +1 -0
- package/dist/lib/supabase-credentials.d.ts +36 -0
- package/dist/lib/supabase-credentials.d.ts.map +1 -0
- package/dist/lib/supabase-credentials.js +43 -0
- package/dist/lib/supabase-credentials.js.map +1 -0
- package/dist/lib/trunk.d.ts +39 -0
- package/dist/lib/trunk.d.ts.map +1 -0
- package/dist/lib/trunk.js +116 -0
- package/dist/lib/trunk.js.map +1 -0
- package/dist/lib/update-check.d.ts +11 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +113 -0
- package/dist/lib/update-check.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 +81 -0
- package/dist/storage/adapter.d.ts.map +1 -0
- package/dist/storage/adapter.js +8 -0
- package/dist/storage/adapter.js.map +1 -0
- 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 +6 -0
- package/dist/storage/factory.d.ts.map +1 -0
- package/dist/storage/factory.js +14 -0
- package/dist/storage/factory.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +11 -0
- package/dist/storage/index.js.map +1 -0
- 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 +138 -0
- package/dist/storage/json-branch-registry-store.js.map +1 -0
- package/dist/storage/local.d.ts +20 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +40 -0
- package/dist/storage/local.js.map +1 -0
- 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 +68 -0
- package/dist/storage/memory-branch-registry-store.js.map +1 -0
- package/dist/storage/supabase-registry-sync-client-impl.d.ts +40 -0
- package/dist/storage/supabase-registry-sync-client-impl.d.ts.map +1 -0
- package/dist/storage/supabase-registry-sync-client-impl.js +278 -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 +28 -0
- package/dist/storage/supabase.d.ts.map +1 -0
- package/dist/storage/supabase.js +56 -0
- package/dist/storage/supabase.js.map +1 -0
- package/dist/types/cloud.d.ts +102 -0
- package/dist/types/cloud.d.ts.map +1 -0
- package/dist/types/cloud.js +13 -0
- package/dist/types/cloud.js.map +1 -0
- package/package.json +1 -1
|
@@ -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,42 @@
|
|
|
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
|
+
// A4B general-purpose backend on :8082 (mlx_lm.server). The model id must be
|
|
13
|
+
// the exact HF-cache id — mlx_lm.server resolves it from the local cache.
|
|
14
|
+
// gitOps routing is unaffected: event-handler.ts hardcodes its own :1234 default.
|
|
15
|
+
model: 'mlx-community/gemma-4-26b-a4b-it-4bit',
|
|
16
|
+
baseUrl: 'http://127.0.0.1:8082/v1',
|
|
17
|
+
temperature: 0.4,
|
|
18
|
+
maxTokens: 800,
|
|
19
|
+
},
|
|
20
|
+
copilot: {
|
|
21
|
+
provider: 'copilot',
|
|
22
|
+
model: 'gpt-4o',
|
|
23
|
+
baseUrl: 'https://models.inference.ai.azure.com',
|
|
24
|
+
temperature: 0.4,
|
|
25
|
+
maxTokens: 800,
|
|
26
|
+
},
|
|
27
|
+
ollama: {
|
|
28
|
+
provider: 'ollama',
|
|
29
|
+
model: 'gemma3:4b',
|
|
30
|
+
baseUrl: 'http://localhost:11434',
|
|
31
|
+
temperature: 0.4,
|
|
32
|
+
maxTokens: 800,
|
|
33
|
+
},
|
|
34
|
+
hosted: {
|
|
35
|
+
provider: 'hosted',
|
|
36
|
+
model: 'spidersan-v1',
|
|
37
|
+
baseUrl: HOSTED_API_BASE_URL,
|
|
38
|
+
temperature: 0.4,
|
|
39
|
+
maxTokens: 800,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/ai/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0JH,yFAAyF;AACzF,MAAM,CAAC,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAElE,MAAM,CAAC,MAAM,mBAAmB,GAAmC;IACjE,QAAQ,EAAE;QACR,QAAQ,EAAE,UAAU;QACpB,6EAA6E;QAC7E,0EAA0E;QAC1E,kFAAkF;QAClF,KAAK,EAAE,uCAAuC;QAC9C,OAAO,EAAE,0BAA0B;QACnC,WAAW,EAAE,GAAG;QAChB,SAAS,EAAE,GAAG;KACf;IACD,OAAO,EAAE;QACP,QAAQ,EAAE,SAAS;QACnB,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,uCAAuC;QAChD,WAAW,EAAE,GAAG;QAChB,SAAS,EAAE,GAAG;KACf;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,QAAQ;QAClB,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,wBAAwB;QACjC,WAAW,EAAE,GAAG;QAChB,SAAS,EAAE,GAAG;KACf;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,QAAQ;QAClB,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,mBAAmB;QAC5B,WAAW,EAAE,GAAG;QAChB,SAAS,EAAE,GAAG;KACf;CACF,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import Parser from 'tree-sitter';
|
|
2
|
+
export interface SymbolInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
type: 'function' | 'class' | 'method';
|
|
5
|
+
startLine: number;
|
|
6
|
+
endLine: number;
|
|
7
|
+
/** Enclosing class name for methods, so `A.render` and `B.render` don't collide. */
|
|
8
|
+
parent?: string;
|
|
9
|
+
content?: string;
|
|
10
|
+
hash?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class ASTParser {
|
|
13
|
+
private parser;
|
|
14
|
+
constructor();
|
|
15
|
+
parse(code: string): Parser.Tree;
|
|
16
|
+
/**
|
|
17
|
+
* Parse a file and return all defined symbols (functions, classes, methods)
|
|
18
|
+
*/
|
|
19
|
+
getSymbols(filePath: string): SymbolInfo[];
|
|
20
|
+
/**
|
|
21
|
+
* Compute SHA-256 hash of code content
|
|
22
|
+
*/
|
|
23
|
+
computeHash(content: string): string;
|
|
24
|
+
private extractSymbols;
|
|
25
|
+
/**
|
|
26
|
+
* Compare two versions of code and find symbols that differ in content.
|
|
27
|
+
* With `baseContent` (the merge-base version) this is a three-way check: a
|
|
28
|
+
* symbol only conflicts if BOTH sides changed it from base. Without it the
|
|
29
|
+
* check is two-way and over-reports one-sided edits.
|
|
30
|
+
*/
|
|
31
|
+
findSymbolConflicts(contentA: string, labelA: string, contentB: string, labelB: string, baseContent?: string): SymbolConflict[];
|
|
32
|
+
}
|
|
33
|
+
/** Language-agnostic core: two symbol lists (+ optional merge-base list) → conflicts. */
|
|
34
|
+
export declare function compareSymbols(symbolsA: SymbolInfo[], labelA: string, symbolsB: SymbolInfo[], labelB: string, symbolsBase?: SymbolInfo[]): SymbolConflict[];
|
|
35
|
+
export declare const qualify: (s: SymbolInfo) => string;
|
|
36
|
+
export interface SymbolConflict {
|
|
37
|
+
symbolName: string;
|
|
38
|
+
symbolType: string;
|
|
39
|
+
locations: {
|
|
40
|
+
file: string;
|
|
41
|
+
range: [number, number];
|
|
42
|
+
}[];
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/lib/ast.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAKjC,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,SAAS;IAClB,OAAO,CAAC,MAAM,CAAS;;IAQvB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI;IAKhC;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAS1C;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAIpC,OAAO,CAAC,cAAc;IA6FtB;;;;;OAKG;IACH,mBAAmB,CACf,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAChC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAChC,WAAW,CAAC,EAAE,MAAM,GACrB,cAAc,EAAE;CAOtB;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EACtC,QAAQ,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EACtC,WAAW,CAAC,EAAE,UAAU,EAAE,GAC3B,cAAc,EAAE,CAkClB;AAED,eAAO,MAAM,OAAO,GAAI,GAAG,UAAU,KAAG,MAAuD,CAAC;AAEhG,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAAE,CAAC;CAC1D"}
|
package/dist/lib/ast.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import Parser from 'tree-sitter';
|
|
2
|
+
import TypeScript from 'tree-sitter-typescript';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { createHash } from 'crypto';
|
|
5
|
+
export class ASTParser {
|
|
6
|
+
parser;
|
|
7
|
+
constructor() {
|
|
8
|
+
this.parser = new Parser();
|
|
9
|
+
// TypeScript binding quirk
|
|
10
|
+
this.parser.setLanguage(TypeScript.typescript);
|
|
11
|
+
}
|
|
12
|
+
parse(code) {
|
|
13
|
+
// node-tree-sitter throws "Invalid argument" past its default ~32KB buffer
|
|
14
|
+
return this.parser.parse(code, undefined, { bufferSize: Math.max(code.length + 1, 32 * 1024) });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parse a file and return all defined symbols (functions, classes, methods)
|
|
18
|
+
*/
|
|
19
|
+
getSymbols(filePath) {
|
|
20
|
+
if (!fs.existsSync(filePath)) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
const code = fs.readFileSync(filePath, 'utf-8');
|
|
24
|
+
const tree = this.parse(code);
|
|
25
|
+
return this.extractSymbols(tree);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Compute SHA-256 hash of code content
|
|
29
|
+
*/
|
|
30
|
+
computeHash(content) {
|
|
31
|
+
return createHash('sha256').update(content).digest('hex');
|
|
32
|
+
}
|
|
33
|
+
extractSymbols(tree) {
|
|
34
|
+
const symbols = [];
|
|
35
|
+
const cursor = tree.walk();
|
|
36
|
+
// Stack of symbols we are currently inside
|
|
37
|
+
const stack = [];
|
|
38
|
+
let visitedChildren = false;
|
|
39
|
+
let depth = 0;
|
|
40
|
+
while (true) {
|
|
41
|
+
if (visitedChildren) {
|
|
42
|
+
// Post-visit: Check if we are leaving a symbol node
|
|
43
|
+
if (stack.length > 0) {
|
|
44
|
+
const top = stack[stack.length - 1];
|
|
45
|
+
// Check if the current node (which we are done with) matches the stack top
|
|
46
|
+
if (top.depth === depth &&
|
|
47
|
+
top.startLine === cursor.startPosition.row + 1 &&
|
|
48
|
+
top.endLine === cursor.endPosition.row + 1) {
|
|
49
|
+
stack.pop();
|
|
50
|
+
if (top.name) {
|
|
51
|
+
const content = cursor.nodeText;
|
|
52
|
+
symbols.push({
|
|
53
|
+
name: top.name,
|
|
54
|
+
type: top.type,
|
|
55
|
+
startLine: top.startLine,
|
|
56
|
+
endLine: top.endLine,
|
|
57
|
+
...(top.parent ? { parent: top.parent } : {}),
|
|
58
|
+
content: content,
|
|
59
|
+
hash: this.computeHash(content)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (cursor.gotoNextSibling()) {
|
|
65
|
+
visitedChildren = false;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
if (!cursor.gotoParent())
|
|
69
|
+
break;
|
|
70
|
+
depth--;
|
|
71
|
+
// After returning to parent, we are done with its children
|
|
72
|
+
visitedChildren = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Pre-visit
|
|
77
|
+
const type = cursor.nodeType;
|
|
78
|
+
// 1. Check if it is a symbol definition
|
|
79
|
+
const valueType = type === 'variable_declarator'
|
|
80
|
+
? cursor.currentNode.childForFieldName('value')?.type
|
|
81
|
+
: undefined;
|
|
82
|
+
// `const f = () => {}` / `const f = function () {}` are functions too
|
|
83
|
+
const isFnConst = valueType === 'arrow_function' || valueType === 'function_expression' || valueType === 'function';
|
|
84
|
+
if (type === 'function_declaration' || type === 'class_declaration' || type === 'method_definition' || isFnConst) {
|
|
85
|
+
const parentClass = type === 'method_definition'
|
|
86
|
+
? [...stack].reverse().find(e => e.type === 'class')?.name ?? undefined
|
|
87
|
+
: undefined;
|
|
88
|
+
stack.push({
|
|
89
|
+
type: isFnConst ? 'function' : type.replace('_declaration', '').replace('_definition', ''),
|
|
90
|
+
startLine: cursor.startPosition.row + 1,
|
|
91
|
+
endLine: cursor.endPosition.row + 1,
|
|
92
|
+
name: null,
|
|
93
|
+
parent: parentClass,
|
|
94
|
+
depth: depth
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// 2. Check if it is the 'name' field of the parent symbol
|
|
98
|
+
else if (stack.length > 0 && cursor.currentFieldName === 'name') {
|
|
99
|
+
const top = stack[stack.length - 1];
|
|
100
|
+
// Name must be a direct child of the symbol
|
|
101
|
+
if (top.depth === depth - 1) {
|
|
102
|
+
top.name = cursor.nodeText;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (cursor.gotoFirstChild()) {
|
|
106
|
+
visitedChildren = false;
|
|
107
|
+
depth++;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
visitedChildren = true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return symbols;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Compare two versions of code and find symbols that differ in content.
|
|
118
|
+
* With `baseContent` (the merge-base version) this is a three-way check: a
|
|
119
|
+
* symbol only conflicts if BOTH sides changed it from base. Without it the
|
|
120
|
+
* check is two-way and over-reports one-sided edits.
|
|
121
|
+
*/
|
|
122
|
+
findSymbolConflicts(contentA, labelA, contentB, labelB, baseContent) {
|
|
123
|
+
return compareSymbols(this.extractSymbols(this.parse(contentA)), labelA, this.extractSymbols(this.parse(contentB)), labelB, baseContent === undefined ? undefined : this.extractSymbols(this.parse(baseContent)));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Language-agnostic core: two symbol lists (+ optional merge-base list) → conflicts. */
|
|
127
|
+
export function compareSymbols(symbolsA, labelA, symbolsB, labelB, symbolsBase) {
|
|
128
|
+
const baseContentByName = new Map();
|
|
129
|
+
symbolsBase?.forEach(s => baseContentByName.set(qualify(s), s.content));
|
|
130
|
+
const baseContent = symbolsBase;
|
|
131
|
+
const conflicts = [];
|
|
132
|
+
// Map for fast lookup
|
|
133
|
+
const mapB = new Map();
|
|
134
|
+
symbolsB.forEach(s => mapB.set(qualify(s), s));
|
|
135
|
+
for (const symA of symbolsA) {
|
|
136
|
+
const symB = mapB.get(qualify(symA));
|
|
137
|
+
// If symbol exists in both and content differs
|
|
138
|
+
if (symB && symA.content !== symB.content) {
|
|
139
|
+
if (baseContent !== undefined) {
|
|
140
|
+
const base = baseContentByName.get(qualify(symA));
|
|
141
|
+
// one-sided edit: the other side still equals base, git merges it cleanly
|
|
142
|
+
if (symA.content === base || symB.content === base)
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
conflicts.push({
|
|
146
|
+
symbolName: qualify(symA),
|
|
147
|
+
symbolType: symA.type,
|
|
148
|
+
locations: [
|
|
149
|
+
{ file: labelA, range: [symA.startLine, symA.endLine] },
|
|
150
|
+
{ file: labelB, range: [symB.startLine, symB.endLine] }
|
|
151
|
+
]
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// A class always "changes" when one of its methods does; report the method, not both.
|
|
156
|
+
return conflicts.filter(c => c.symbolType !== 'class' ||
|
|
157
|
+
!conflicts.some(m => m.symbolType === 'method' && m.symbolName.startsWith(`${c.symbolName}.`)));
|
|
158
|
+
}
|
|
159
|
+
export const qualify = (s) => (s.parent ? `${s.parent}.${s.name}` : s.name);
|
|
160
|
+
//# sourceMappingURL=ast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/lib/ast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface CarriedCommit {
|
|
2
|
+
sha: string;
|
|
3
|
+
subject: string;
|
|
4
|
+
}
|
|
5
|
+
export interface InheritedCommit extends CarriedCommit {
|
|
6
|
+
/** Other open remote branches that also contain this commit (self/base excluded). */
|
|
7
|
+
branches: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface CarriesReport {
|
|
10
|
+
own: CarriedCommit[];
|
|
11
|
+
inherited: InheritedCommit[];
|
|
12
|
+
/** carries ∩ another-open-branch ≠ ∅ */
|
|
13
|
+
flagged: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @param base ref the PR merges into (e.g. `origin/main`).
|
|
17
|
+
* @param prRef the PR head ref (e.g. `refs/spidersan/pr-81`).
|
|
18
|
+
* @param selfBranches remote refs that ARE this PR or the base — excluded from the
|
|
19
|
+
* "other branch" set (e.g. [`origin/<headBranch>`, base]).
|
|
20
|
+
*/
|
|
21
|
+
export declare function analyzeCarries(base: string, prRef: string, selfBranches?: string[]): CarriesReport;
|
|
22
|
+
//# sourceMappingURL=carries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"carries.d.ts","sourceRoot":"","sources":["../../src/lib/carries.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,aAAa;IAClD,qFAAqF;IACrF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,aAAa,EAAE,CAAC;IACrB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,GAAE,MAAM,EAAO,GAAG,aAAa,CAkCtG"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* carries(pr) — provenance predicate.
|
|
3
|
+
*
|
|
4
|
+
* carries(pr) = commits reachable from the PR head but not from the base, split into
|
|
5
|
+
* the author's OWN commits vs commits also reachable from another OPEN branch
|
|
6
|
+
* (INHERITED). Flag when the intersection with any other branch is non-empty.
|
|
7
|
+
*
|
|
8
|
+
* Why intersection, not superset (spidersan #257 / birdsan review): `carries(A) ⊃
|
|
9
|
+
* commits_of(B)` under-fires — a PR can share commits with B while B holds further
|
|
10
|
+
* commits the PR never inherited (the real #78/sherlock2 case). Any shared commit is
|
|
11
|
+
* the entanglement signal, so the condition is `∩ ≠ ∅`, computed per-commit here.
|
|
12
|
+
*
|
|
13
|
+
* Pure-ish: only reads git, never mutates. Spec: docs/DESIGN_pr_grammar_predicates.md.
|
|
14
|
+
*/
|
|
15
|
+
import { execFileSync } from 'child_process';
|
|
16
|
+
/**
|
|
17
|
+
* @param base ref the PR merges into (e.g. `origin/main`).
|
|
18
|
+
* @param prRef the PR head ref (e.g. `refs/spidersan/pr-81`).
|
|
19
|
+
* @param selfBranches remote refs that ARE this PR or the base — excluded from the
|
|
20
|
+
* "other branch" set (e.g. [`origin/<headBranch>`, base]).
|
|
21
|
+
*/
|
|
22
|
+
export function analyzeCarries(base, prRef, selfBranches = []) {
|
|
23
|
+
let log;
|
|
24
|
+
try {
|
|
25
|
+
log = execFileSync('git', ['log', '--format=%H%x09%s', `${base}..${prRef}`], { encoding: 'utf-8' });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return { own: [], inherited: [], flagged: false };
|
|
29
|
+
}
|
|
30
|
+
const self = new Set(selfBranches);
|
|
31
|
+
const own = [];
|
|
32
|
+
const inherited = [];
|
|
33
|
+
for (const line of log.split('\n').filter(Boolean)) {
|
|
34
|
+
const tab = line.indexOf('\t');
|
|
35
|
+
const sha = tab >= 0 ? line.slice(0, tab) : line;
|
|
36
|
+
const subject = tab >= 0 ? line.slice(tab + 1) : '';
|
|
37
|
+
let branches = [];
|
|
38
|
+
try {
|
|
39
|
+
branches = execFileSync('git', ['branch', '-r', '--contains', sha], { encoding: 'utf-8' })
|
|
40
|
+
.split('\n')
|
|
41
|
+
.map((b) => b.replace(/^[*+]?\s*/, '').trim())
|
|
42
|
+
.filter(Boolean)
|
|
43
|
+
.filter((b) => !b.includes(' -> ')) // drop symbolic refs (origin/HEAD -> origin/main)
|
|
44
|
+
.filter((b) => !self.has(b));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// detached / unknown ref → treat as own (no other branch claims it)
|
|
48
|
+
}
|
|
49
|
+
if (branches.length > 0)
|
|
50
|
+
inherited.push({ sha, subject, branches });
|
|
51
|
+
else
|
|
52
|
+
own.push({ sha, subject });
|
|
53
|
+
}
|
|
54
|
+
return { own, inherited, flagged: inherited.length > 0 };
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=carries.js.map
|