spidersan 0.5.0 → 0.9.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 +46 -48
- package/README.md +241 -4
- 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 +398 -0
- package/dist/commands/bot.js.map +1 -0
- package/dist/commands/conflicts.d.ts.map +1 -1
- package/dist/commands/conflicts.js +264 -313
- 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 +1 -38
- 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/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +117 -59
- package/dist/commands/doctor.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 +137 -74
- package/dist/commands/pulse.js.map +1 -1
- package/dist/commands/queen.d.ts.map +1 -1
- package/dist/commands/queen.js +36 -19
- 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 +7 -29
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/stale.d.ts +1 -9
- package/dist/commands/stale.d.ts.map +1 -1
- package/dist/commands/stale.js +1 -42
- package/dist/commands/stale.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.map +1 -1
- package/dist/commands/watch.js +13 -34
- package/dist/commands/watch.js.map +1 -1
- package/dist/lib/agent-errors.js +2 -2
- package/dist/lib/agent-errors.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/daily-bridge.d.ts.map +1 -1
- package/dist/lib/daily-bridge.js +3 -2
- package/dist/lib/daily-bridge.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/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/remote-drift.d.ts +60 -0
- package/dist/lib/remote-drift.d.ts.map +1 -0
- package/dist/lib/remote-drift.js +225 -0
- package/dist/lib/remote-drift.js.map +1 -0
- package/dist/lib/repo-scanner.d.ts +0 -4
- package/dist/lib/repo-scanner.d.ts.map +1 -1
- package/dist/lib/repo-scanner.js +2 -1
- package/dist/lib/repo-scanner.js.map +1 -1
- 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 +17 -0
- package/dist/lib/security.d.ts.map +1 -1
- package/dist/lib/security.js +34 -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/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/index.d.ts +5 -5
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +5 -6
- 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.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/mycmail-adapter.d.ts.map +1 -1
- package/dist/storage/mycmail-adapter.js +4 -6
- package/dist/storage/mycmail-adapter.js.map +1 -1
- 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
package/dist/lib/security.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { resolve, relative, isAbsolute } from 'path';
|
|
1
|
+
import { resolve, relative, isAbsolute, dirname } from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
2
3
|
/**
|
|
3
4
|
* Spidersan Security Utilities
|
|
4
5
|
*
|
|
@@ -41,6 +42,17 @@ export function validateBranchName(branch) {
|
|
|
41
42
|
}
|
|
42
43
|
return branch;
|
|
43
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Validate PR number
|
|
47
|
+
* @throws Error if invalid
|
|
48
|
+
*/
|
|
49
|
+
export function validatePRNumber(prNumber) {
|
|
50
|
+
const num = typeof prNumber === 'string' ? parseInt(prNumber, 10) : prNumber;
|
|
51
|
+
if (!Number.isInteger(num) || num <= 0) {
|
|
52
|
+
throw new Error(`Invalid PR number: ${prNumber}`);
|
|
53
|
+
}
|
|
54
|
+
return num;
|
|
55
|
+
}
|
|
44
56
|
/**
|
|
45
57
|
* Validate task ID (for torrent/task commands)
|
|
46
58
|
* @throws Error if invalid
|
|
@@ -104,6 +116,16 @@ export function escapeGitArg(arg) {
|
|
|
104
116
|
// Just basic validation, no escaping needed
|
|
105
117
|
return arg;
|
|
106
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Escapes a string so it can be safely used in a shell script.
|
|
121
|
+
* Replaces single quotes with '\'' and wraps the result in single quotes.
|
|
122
|
+
* Prevents command injection when generating bash scripts.
|
|
123
|
+
*/
|
|
124
|
+
export function escapeShellString(str) {
|
|
125
|
+
if (str === null || str === undefined)
|
|
126
|
+
return "''";
|
|
127
|
+
return `'${String(str).replace(/'/g, "'\\''")}'`;
|
|
128
|
+
}
|
|
107
129
|
// Export validation patterns for testing
|
|
108
130
|
export const patterns = {
|
|
109
131
|
VALID_AGENT_ID,
|
|
@@ -116,6 +138,7 @@ export const patterns = {
|
|
|
116
138
|
export const sanitizeAgentId = validateAgentId;
|
|
117
139
|
export const sanitizeBranchName = validateBranchName;
|
|
118
140
|
export const sanitizeFilePath = validateFilePath;
|
|
141
|
+
export const sanitizePRNumber = validatePRNumber;
|
|
119
142
|
// Message ID validation (for mycmail commands)
|
|
120
143
|
const VALID_MESSAGE_ID = /^[a-z0-9][a-z0-9_-]{0,64}$/i;
|
|
121
144
|
export function isValidMessageId(messageId) {
|
|
@@ -154,4 +177,14 @@ export function escapeBlessed(text) {
|
|
|
154
177
|
}
|
|
155
178
|
return text.replace(/[{}]/g, (char) => char === '{' ? '{open}' : '{close}');
|
|
156
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Safely resolves the CLI entry point path.
|
|
182
|
+
* Replaces insecure usage of process.argv[1] which can be manipulated.
|
|
183
|
+
*/
|
|
184
|
+
export function getCLIPath() {
|
|
185
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
186
|
+
const __dirname = dirname(__filename);
|
|
187
|
+
const ext = __filename.endsWith('.ts') ? '.ts' : '.js';
|
|
188
|
+
return resolve(__dirname, '..', 'bin', `spidersan${ext}`);
|
|
189
|
+
}
|
|
157
190
|
//# sourceMappingURL=security.js.map
|
package/dist/lib/security.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/lib/security.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/lib/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Logger — captures raw spidersan ask/advise/explain sessions for training.
|
|
3
|
+
*
|
|
4
|
+
* Writes to ~/.spidersan/sessions/YYYY-MM-DD.jsonl (one JSON object per line).
|
|
5
|
+
* Each entry is a raw session: context + result + outcome.
|
|
6
|
+
*
|
|
7
|
+
* Outcome is what makes this a gold pair. Without it we just have questions.
|
|
8
|
+
* Outcome is captured inline (TTY prompt after response) or left null.
|
|
9
|
+
*
|
|
10
|
+
* Anonymization + gold pair transformation happens at `watsan index-pair` time,
|
|
11
|
+
* not here. This logger stores raw data locally — nothing leaves the machine.
|
|
12
|
+
*
|
|
13
|
+
* Design:
|
|
14
|
+
* - Never throws — session logging must not crash spidersan ask
|
|
15
|
+
* - Append-only JSONL — safe for concurrent writes, easy to process
|
|
16
|
+
* - File per day — easy to hand to watsan for a given date range
|
|
17
|
+
*/
|
|
18
|
+
import type { Interface as ReadlineInterface } from 'readline';
|
|
19
|
+
import type { SpiderContext } from './ai/types.js';
|
|
20
|
+
import type { ReasoningResult, ReasoningMode } from './ai/index.js';
|
|
21
|
+
export type SessionOutcome = 'followed' | 'ignored' | `modified:${string}` | null;
|
|
22
|
+
export interface RawSession {
|
|
23
|
+
session_id: string;
|
|
24
|
+
logged_at: string;
|
|
25
|
+
mode: ReasoningMode;
|
|
26
|
+
question?: string;
|
|
27
|
+
branch?: string;
|
|
28
|
+
context: SpiderContext;
|
|
29
|
+
result: ReasoningResult;
|
|
30
|
+
outcome: SessionOutcome;
|
|
31
|
+
outcome_captured_at: string | null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Append a session entry to today's log file.
|
|
35
|
+
* Returns the session_id so the caller can later capture the outcome.
|
|
36
|
+
* Never throws.
|
|
37
|
+
*/
|
|
38
|
+
export declare function logSession(mode: ReasoningMode, context: SpiderContext, result: ReasoningResult, opts?: {
|
|
39
|
+
question?: string;
|
|
40
|
+
branch?: string;
|
|
41
|
+
}): string;
|
|
42
|
+
/**
|
|
43
|
+
* Update the outcome for a previously logged session.
|
|
44
|
+
* Checks today's and yesterday's log files.
|
|
45
|
+
* Never throws.
|
|
46
|
+
*/
|
|
47
|
+
export declare function captureOutcome(session_id: string, outcome: SessionOutcome): void;
|
|
48
|
+
/**
|
|
49
|
+
* Show a brief outcome prompt after a response (TTY only).
|
|
50
|
+
* Non-blocking: skips if stdin is not a TTY or SPIDERSAN_NO_OUTCOME_PROMPT=1.
|
|
51
|
+
* Returns the captured outcome (or null if skipped).
|
|
52
|
+
*/
|
|
53
|
+
export declare function promptOutcome(session_id: string, rl: ReadlineInterface): Promise<SessionOutcome>;
|
|
54
|
+
//# sourceMappingURL=session-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-logger.d.ts","sourceRoot":"","sources":["../../src/lib/session-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,SAAS,IAAI,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAIpE,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,SAAS,GACT,YAAY,MAAM,EAAE,GACpB,IAAI,CAAC;AAET,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,cAAc,CAAC;IACxB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAqBD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,eAAe,EACvB,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,MAAM,CAoBR;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAuBhF;AAID;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,iBAAiB,GACpB,OAAO,CAAC,cAAc,CAAC,CA8BzB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Logger — captures raw spidersan ask/advise/explain sessions for training.
|
|
3
|
+
*
|
|
4
|
+
* Writes to ~/.spidersan/sessions/YYYY-MM-DD.jsonl (one JSON object per line).
|
|
5
|
+
* Each entry is a raw session: context + result + outcome.
|
|
6
|
+
*
|
|
7
|
+
* Outcome is what makes this a gold pair. Without it we just have questions.
|
|
8
|
+
* Outcome is captured inline (TTY prompt after response) or left null.
|
|
9
|
+
*
|
|
10
|
+
* Anonymization + gold pair transformation happens at `watsan index-pair` time,
|
|
11
|
+
* not here. This logger stores raw data locally — nothing leaves the machine.
|
|
12
|
+
*
|
|
13
|
+
* Design:
|
|
14
|
+
* - Never throws — session logging must not crash spidersan ask
|
|
15
|
+
* - Append-only JSONL — safe for concurrent writes, easy to process
|
|
16
|
+
* - File per day — easy to hand to watsan for a given date range
|
|
17
|
+
*/
|
|
18
|
+
import { appendFileSync, readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
19
|
+
import { join } from 'path';
|
|
20
|
+
import { homedir } from 'os';
|
|
21
|
+
import { randomUUID } from 'crypto';
|
|
22
|
+
// ─── Paths ────────────────────────────────────────────────────
|
|
23
|
+
function sessionsDir() {
|
|
24
|
+
return join(homedir(), '.spidersan', 'sessions');
|
|
25
|
+
}
|
|
26
|
+
function dateFile(offsetDays = 0) {
|
|
27
|
+
const d = new Date(Date.now() - offsetDays * 86_400_000);
|
|
28
|
+
const ymd = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
29
|
+
return join(sessionsDir(), `${ymd}.jsonl`);
|
|
30
|
+
}
|
|
31
|
+
function ensureDir() {
|
|
32
|
+
const dir = sessionsDir();
|
|
33
|
+
if (!existsSync(dir))
|
|
34
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
35
|
+
}
|
|
36
|
+
// ─── Write ────────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Append a session entry to today's log file.
|
|
39
|
+
* Returns the session_id so the caller can later capture the outcome.
|
|
40
|
+
* Never throws.
|
|
41
|
+
*/
|
|
42
|
+
export function logSession(mode, context, result, opts) {
|
|
43
|
+
const session_id = randomUUID();
|
|
44
|
+
try {
|
|
45
|
+
ensureDir();
|
|
46
|
+
const entry = {
|
|
47
|
+
session_id,
|
|
48
|
+
logged_at: new Date().toISOString(),
|
|
49
|
+
mode,
|
|
50
|
+
question: opts?.question,
|
|
51
|
+
branch: opts?.branch,
|
|
52
|
+
context,
|
|
53
|
+
result,
|
|
54
|
+
outcome: null,
|
|
55
|
+
outcome_captured_at: null,
|
|
56
|
+
};
|
|
57
|
+
appendFileSync(dateFile(), JSON.stringify(entry) + '\n', { encoding: 'utf-8' });
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Silent — logging must never crash the main command
|
|
61
|
+
}
|
|
62
|
+
return session_id;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Update the outcome for a previously logged session.
|
|
66
|
+
* Checks today's and yesterday's log files.
|
|
67
|
+
* Never throws.
|
|
68
|
+
*/
|
|
69
|
+
export function captureOutcome(session_id, outcome) {
|
|
70
|
+
try {
|
|
71
|
+
const now = new Date().toISOString();
|
|
72
|
+
// Check today and yesterday (covers sessions that started near midnight)
|
|
73
|
+
for (const filePath of [dateFile(0), dateFile(1)]) {
|
|
74
|
+
if (!existsSync(filePath))
|
|
75
|
+
continue;
|
|
76
|
+
const lines = readFileSync(filePath, 'utf-8').split('\n').filter(Boolean);
|
|
77
|
+
const idx = lines.findIndex(line => {
|
|
78
|
+
try {
|
|
79
|
+
return JSON.parse(line).session_id === session_id;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
if (idx === -1)
|
|
86
|
+
continue;
|
|
87
|
+
const entry = JSON.parse(lines[idx]);
|
|
88
|
+
entry.outcome = outcome;
|
|
89
|
+
entry.outcome_captured_at = now;
|
|
90
|
+
lines[idx] = JSON.stringify(entry);
|
|
91
|
+
writeFileSync(filePath, lines.join('\n') + '\n', { encoding: 'utf-8' });
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Silent
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ─── Inline outcome prompt ────────────────────────────────────
|
|
100
|
+
/**
|
|
101
|
+
* Show a brief outcome prompt after a response (TTY only).
|
|
102
|
+
* Non-blocking: skips if stdin is not a TTY or SPIDERSAN_NO_OUTCOME_PROMPT=1.
|
|
103
|
+
* Returns the captured outcome (or null if skipped).
|
|
104
|
+
*/
|
|
105
|
+
export async function promptOutcome(session_id, rl) {
|
|
106
|
+
if (!process.stdin.isTTY || process.env['SPIDERSAN_NO_OUTCOME_PROMPT'] === '1') {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
return new Promise((resolve) => {
|
|
110
|
+
process.stdout.write('\x1b[2m Follow this advice? [y/n/m=modified, Enter to skip] \x1b[0m');
|
|
111
|
+
rl.once('line', (answer) => {
|
|
112
|
+
const a = answer.trim().toLowerCase();
|
|
113
|
+
if (a === 'y' || a === 'yes') {
|
|
114
|
+
captureOutcome(session_id, 'followed');
|
|
115
|
+
resolve('followed');
|
|
116
|
+
}
|
|
117
|
+
else if (a === 'n' || a === 'no') {
|
|
118
|
+
captureOutcome(session_id, 'ignored');
|
|
119
|
+
resolve('ignored');
|
|
120
|
+
}
|
|
121
|
+
else if (a.startsWith('m')) {
|
|
122
|
+
process.stdout.write('\x1b[2m What changed? (one line) \x1b[0m');
|
|
123
|
+
rl.once('line', (desc) => {
|
|
124
|
+
const outcome = `modified:${desc.trim().slice(0, 200)}`;
|
|
125
|
+
captureOutcome(session_id, outcome);
|
|
126
|
+
resolve(outcome);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// Enter / anything else → skip
|
|
131
|
+
resolve(null);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=session-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-logger.js","sourceRoot":"","sources":["../../src/lib/session-logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,10 @@ export interface BranchRegistry {
|
|
|
17
17
|
version: string;
|
|
18
18
|
projectId?: string;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Use BranchRegistryStore for local registry access and
|
|
22
|
+
* SupabaseRegistrySyncClient for cross-machine sync.
|
|
23
|
+
*/
|
|
20
24
|
export interface StorageAdapter {
|
|
21
25
|
/**
|
|
22
26
|
* Initialize the storage (create directories, connect to DB, etc.)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/storage/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,MAAM;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC3B;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAElC;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhE;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEvE;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE1C;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEhD;;OAEG;IACH,OAAO,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC/C"}
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/storage/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,MAAM;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAElC;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhE;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEvE;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE1C;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEhD;;OAEG;IACH,OAAO,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC/C"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Branch } from './adapter.js';
|
|
2
|
+
export interface BranchRegistryStore {
|
|
3
|
+
init(): Promise<void>;
|
|
4
|
+
isInitialized(): Promise<boolean>;
|
|
5
|
+
list(): Promise<Branch[]>;
|
|
6
|
+
register(branch: Omit<Branch, 'registeredAt'>): Promise<Branch>;
|
|
7
|
+
update(name: string, updates: Partial<Branch>): Promise<Branch | null>;
|
|
8
|
+
unregister(name: string): Promise<boolean>;
|
|
9
|
+
get(name: string): Promise<Branch | null>;
|
|
10
|
+
findByFiles(files: string[]): Promise<Branch[]>;
|
|
11
|
+
cleanup(olderThan: Date): Promise<string[]>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=branch-registry-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-registry-store.d.ts","sourceRoot":"","sources":["../../src/storage/branch-registry-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,mBAAmB;IAChC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1C,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-registry-store.js","sourceRoot":"","sources":["../../src/storage/branch-registry-store.ts"],"names":[],"mappings":""}
|
|
@@ -2,5 +2,9 @@
|
|
|
2
2
|
* Storage factory - selects the right storage backend
|
|
3
3
|
*/
|
|
4
4
|
import type { StorageAdapter } from './adapter.js';
|
|
5
|
+
import type { BranchRegistryStore } from './branch-registry-store.js';
|
|
6
|
+
import type { SupabaseRegistrySyncClient } from './supabase-registry-sync-client.js';
|
|
7
|
+
export declare function getBranchRegistryStore(basePath?: string): Promise<BranchRegistryStore>;
|
|
8
|
+
export declare function getSupabaseRegistrySyncClient(): Promise<SupabaseRegistrySyncClient | null>;
|
|
5
9
|
export declare function getStorage(): Promise<StorageAdapter>;
|
|
6
10
|
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAwBrF,wBAAsB,sBAAsB,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAE3G;AAED,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAOhG;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAQ1D"}
|
package/dist/storage/factory.js
CHANGED
|
@@ -1,22 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Storage factory - selects the right storage backend
|
|
3
3
|
*/
|
|
4
|
+
import { JsonBranchRegistryStore } from './json-branch-registry-store.js';
|
|
4
5
|
import { LocalStorage } from './local.js';
|
|
5
6
|
import { SupabaseStorage } from './supabase.js';
|
|
7
|
+
import { SupabaseRegistrySyncClientImpl } from './supabase-registry-sync-client-impl.js';
|
|
6
8
|
import { loadConfig } from '../lib/config.js';
|
|
7
|
-
|
|
9
|
+
async function getSupabaseConfig() {
|
|
8
10
|
const config = await loadConfig();
|
|
9
|
-
// Check environment variables first
|
|
10
11
|
const supabaseUrl = process.env.SUPABASE_URL || config.storage.supabaseUrl;
|
|
11
12
|
const supabaseKey = process.env.SUPABASE_KEY || config.storage.supabaseKey;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
if (!supabaseUrl || !supabaseKey) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
url: supabaseUrl,
|
|
18
|
+
key: supabaseKey,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export async function getBranchRegistryStore(basePath = process.cwd()) {
|
|
22
|
+
return new JsonBranchRegistryStore(basePath);
|
|
23
|
+
}
|
|
24
|
+
export async function getSupabaseRegistrySyncClient() {
|
|
25
|
+
const config = await getSupabaseConfig();
|
|
26
|
+
if (!config) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return new SupabaseRegistrySyncClientImpl(config);
|
|
30
|
+
}
|
|
31
|
+
export async function getStorage() {
|
|
32
|
+
const supabaseConfig = await getSupabaseConfig();
|
|
33
|
+
if (supabaseConfig) {
|
|
34
|
+
return new SupabaseStorage(supabaseConfig);
|
|
18
35
|
}
|
|
19
|
-
// Default to local storage
|
|
20
36
|
return new LocalStorage();
|
|
21
37
|
}
|
|
22
38
|
//# sourceMappingURL=factory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAIhD,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAO9C,KAAK,UAAU,iBAAiB;IAC5B,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAC3E,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAE3E,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO;QACH,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,WAAW;KACnB,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IACzE,OAAO,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B;IAC/C,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,8BAA8B,CAAC,MAAM,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAEjD,IAAI,cAAc,EAAE,CAAC;QACjB,OAAO,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,IAAI,YAAY,EAAE,CAAC;AAC9B,CAAC"}
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * from './adapter.js';
|
|
2
|
+
export * from './branch-registry-store.js';
|
|
2
3
|
export * from './local.js';
|
|
4
|
+
export * from './json-branch-registry-store.js';
|
|
5
|
+
export * from './memory-branch-registry-store.js';
|
|
3
6
|
export * from './supabase.js';
|
|
7
|
+
export * from './supabase-registry-sync-client.js';
|
|
8
|
+
export * from './supabase-registry-sync-client-impl.js';
|
|
4
9
|
export * from './factory.js';
|
|
5
|
-
export * from './message-adapter.js';
|
|
6
|
-
export * from './local-messages.js';
|
|
7
|
-
export * from './git-messages.js';
|
|
8
|
-
export * from './mycmail-adapter.js';
|
|
9
|
-
export * from './message-factory.js';
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,YAAY,CAAC;AAC3B,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAC9B,cAAc,oCAAoC,CAAC;AACnD,cAAc,yCAAyC,CAAC;AACxD,cAAc,cAAc,CAAC"}
|
package/dist/storage/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// Branch storage adapters
|
|
2
2
|
export * from './adapter.js';
|
|
3
|
+
export * from './branch-registry-store.js';
|
|
3
4
|
export * from './local.js';
|
|
5
|
+
export * from './json-branch-registry-store.js';
|
|
6
|
+
export * from './memory-branch-registry-store.js';
|
|
4
7
|
export * from './supabase.js';
|
|
8
|
+
export * from './supabase-registry-sync-client.js';
|
|
9
|
+
export * from './supabase-registry-sync-client-impl.js';
|
|
5
10
|
export * from './factory.js';
|
|
6
|
-
// Message storage adapters (tiered fallback)
|
|
7
|
-
export * from './message-adapter.js';
|
|
8
|
-
export * from './local-messages.js';
|
|
9
|
-
export * from './git-messages.js';
|
|
10
|
-
export * from './mycmail-adapter.js';
|
|
11
|
-
export * from './message-factory.js';
|
|
12
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,YAAY,CAAC;AAC3B,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAC9B,cAAc,oCAAoC,CAAC;AACnD,cAAc,yCAAyC,CAAC;AACxD,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Branch } from './adapter.js';
|
|
2
|
+
import type { BranchRegistryStore } from './branch-registry-store.js';
|
|
3
|
+
export declare class JsonBranchRegistryStore implements BranchRegistryStore {
|
|
4
|
+
private basePath;
|
|
5
|
+
private registryPath;
|
|
6
|
+
constructor(basePath?: string);
|
|
7
|
+
init(): Promise<void>;
|
|
8
|
+
isInitialized(): Promise<boolean>;
|
|
9
|
+
list(): Promise<Branch[]>;
|
|
10
|
+
register(branch: Omit<Branch, 'registeredAt'>): Promise<Branch>;
|
|
11
|
+
update(name: string, updates: Partial<Branch>): Promise<Branch | null>;
|
|
12
|
+
unregister(name: string): Promise<boolean>;
|
|
13
|
+
get(name: string): Promise<Branch | null>;
|
|
14
|
+
findByFiles(files: string[]): Promise<Branch[]>;
|
|
15
|
+
cleanup(olderThan: Date): Promise<string[]>;
|
|
16
|
+
private load;
|
|
17
|
+
private save;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=json-branch-registry-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-branch-registry-store.d.ts","sourceRoot":"","sources":["../../src/storage/json-branch-registry-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AA6BtE,qBAAa,uBAAwB,YAAW,mBAAmB;IAC/D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;gBAEjB,QAAQ,GAAE,MAAsB;IAKtC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAWrB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAKzB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAY/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAetE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW1C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKzC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAM/C,OAAO,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAkBnC,IAAI;YASJ,IAAI;CAGrB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
const SPIDERSAN_DIR = '.spidersan';
|
|
5
|
+
const REGISTRY_FILE = 'registry.json';
|
|
6
|
+
const REGISTRY_VERSION = '1.0';
|
|
7
|
+
function normalizeBranch(branch) {
|
|
8
|
+
return {
|
|
9
|
+
...branch,
|
|
10
|
+
registeredAt: branch.registeredAt instanceof Date
|
|
11
|
+
? branch.registeredAt
|
|
12
|
+
: new Date(branch.registeredAt),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function normalizeRegistry(registry) {
|
|
16
|
+
return {
|
|
17
|
+
...registry,
|
|
18
|
+
branches: Object.fromEntries(Object.entries(registry.branches).map(([name, branch]) => [name, normalizeBranch(branch)])),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export class JsonBranchRegistryStore {
|
|
22
|
+
basePath;
|
|
23
|
+
registryPath;
|
|
24
|
+
constructor(basePath = process.cwd()) {
|
|
25
|
+
this.basePath = basePath;
|
|
26
|
+
this.registryPath = join(basePath, SPIDERSAN_DIR, REGISTRY_FILE);
|
|
27
|
+
}
|
|
28
|
+
async init() {
|
|
29
|
+
const dir = join(this.basePath, SPIDERSAN_DIR);
|
|
30
|
+
if (!existsSync(dir)) {
|
|
31
|
+
await mkdir(dir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
if (!existsSync(this.registryPath)) {
|
|
34
|
+
await this.save({ branches: {}, version: REGISTRY_VERSION });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async isInitialized() {
|
|
38
|
+
return existsSync(this.registryPath);
|
|
39
|
+
}
|
|
40
|
+
async list() {
|
|
41
|
+
const registry = await this.load();
|
|
42
|
+
return Object.values(registry.branches);
|
|
43
|
+
}
|
|
44
|
+
async register(branch) {
|
|
45
|
+
const registry = await this.load();
|
|
46
|
+
const newBranch = {
|
|
47
|
+
...branch,
|
|
48
|
+
registeredAt: new Date(),
|
|
49
|
+
};
|
|
50
|
+
registry.branches[branch.name] = newBranch;
|
|
51
|
+
await this.save(registry);
|
|
52
|
+
return newBranch;
|
|
53
|
+
}
|
|
54
|
+
async update(name, updates) {
|
|
55
|
+
const registry = await this.load();
|
|
56
|
+
if (!registry.branches[name]) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
registry.branches[name] = {
|
|
60
|
+
...registry.branches[name],
|
|
61
|
+
...updates,
|
|
62
|
+
name,
|
|
63
|
+
};
|
|
64
|
+
await this.save(registry);
|
|
65
|
+
return registry.branches[name];
|
|
66
|
+
}
|
|
67
|
+
async unregister(name) {
|
|
68
|
+
const registry = await this.load();
|
|
69
|
+
if (!registry.branches[name]) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
delete registry.branches[name];
|
|
73
|
+
await this.save(registry);
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
async get(name) {
|
|
77
|
+
const registry = await this.load();
|
|
78
|
+
return registry.branches[name] || null;
|
|
79
|
+
}
|
|
80
|
+
async findByFiles(files) {
|
|
81
|
+
const branches = await this.list();
|
|
82
|
+
const fileSet = new Set(files);
|
|
83
|
+
return branches.filter((branch) => branch.files.some((file) => fileSet.has(file)));
|
|
84
|
+
}
|
|
85
|
+
async cleanup(olderThan) {
|
|
86
|
+
const registry = await this.load();
|
|
87
|
+
const removedNames = [];
|
|
88
|
+
for (const [name, branch] of Object.entries(registry.branches)) {
|
|
89
|
+
if (branch.registeredAt < olderThan) {
|
|
90
|
+
delete registry.branches[name];
|
|
91
|
+
removedNames.push(name);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (removedNames.length > 0) {
|
|
95
|
+
await this.save(registry);
|
|
96
|
+
}
|
|
97
|
+
return removedNames;
|
|
98
|
+
}
|
|
99
|
+
async load() {
|
|
100
|
+
try {
|
|
101
|
+
const data = await readFile(this.registryPath, 'utf-8');
|
|
102
|
+
return normalizeRegistry(JSON.parse(data));
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return { branches: {}, version: REGISTRY_VERSION };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async save(registry) {
|
|
109
|
+
await writeFile(this.registryPath, JSON.stringify(registry, null, 2));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=json-branch-registry-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-branch-registry-store.js","sourceRoot":"","sources":["../../src/storage/json-branch-registry-store.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/local.d.ts
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Local JSON Storage Adapter
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* This is the default free-tier storage.
|
|
4
|
+
* Thin compatibility wrapper over JsonBranchRegistryStore.
|
|
6
5
|
*/
|
|
7
6
|
import type { StorageAdapter, Branch } from './adapter.js';
|
|
8
7
|
export declare class LocalStorage implements StorageAdapter {
|
|
9
|
-
private
|
|
10
|
-
private registryPath;
|
|
8
|
+
private store;
|
|
11
9
|
constructor(basePath?: string);
|
|
12
10
|
init(): Promise<void>;
|
|
13
11
|
isInitialized(): Promise<boolean>;
|
|
14
|
-
private load;
|
|
15
|
-
private save;
|
|
16
12
|
list(): Promise<Branch[]>;
|
|
17
13
|
register(branch: Omit<Branch, 'registeredAt'>): Promise<Branch>;
|
|
18
14
|
update(name: string, updates: Partial<Branch>): Promise<Branch | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3D,qBAAa,YAAa,YAAW,cAAc;IAC/C,OAAO,CAAC,KAAK,CAA0B;gBAE3B,QAAQ,GAAE,MAAsB;IAItC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAItE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIzC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/C,OAAO,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAGpD"}
|