sphica 0.6.20 → 0.6.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/THIRD_PARTY_NOTICES.md +4 -4
- package/db/migrations/0008.check.sql +33 -0
- package/db/migrations/0008.sql +53 -0
- package/db/schema.sql +16 -1
- package/dist/capture.js +57 -22
- package/dist/cli.js +636 -596
- package/dist/deliver.js +55 -22
- package/dist/mcp-record.js +62 -28
- package/dist/mcp.js +25 -12
- package/package.json +1 -1
package/dist/deliver.js
CHANGED
|
@@ -11135,7 +11135,7 @@ var HOST_MARKS = new Set([".orphaned_at", ".in_use"]);
|
|
|
11135
11135
|
|
|
11136
11136
|
// server/src/sqlite.ts
|
|
11137
11137
|
var SCHEMA_GENERATION = 2;
|
|
11138
|
-
var SCHEMA_REVISION =
|
|
11138
|
+
var SCHEMA_REVISION = 8;
|
|
11139
11139
|
var sphicaHome = () => process.env.SPHICA_HOME || path3.join(os.homedir(), ".sphica");
|
|
11140
11140
|
var dbFile = () => process.env.SPHICA_DB || path3.join(sphicaHome(), "sphica.db");
|
|
11141
11141
|
function requireRuntime() {
|
|
@@ -11512,7 +11512,7 @@ import fs3 from "node:fs";
|
|
|
11512
11512
|
import path4 from "node:path";
|
|
11513
11513
|
var localFile = () => path4.join(sphicaHome(), "projects.json");
|
|
11514
11514
|
var LOCAL_KEY = /^[a-z0-9][a-z0-9._-]*$/;
|
|
11515
|
-
function
|
|
11515
|
+
function legacyRemote(url) {
|
|
11516
11516
|
const raw = String(url ?? "").trim();
|
|
11517
11517
|
if (!raw)
|
|
11518
11518
|
return null;
|
|
@@ -11529,6 +11529,15 @@ function normalizeRemote(url) {
|
|
|
11529
11529
|
return null;
|
|
11530
11530
|
}
|
|
11531
11531
|
}
|
|
11532
|
+
var fold = (s) => s.replace(/[A-Z]+/g, (m) => m.toLowerCase());
|
|
11533
|
+
function normalizeKey(key) {
|
|
11534
|
+
if (!key.startsWith("git:"))
|
|
11535
|
+
return key;
|
|
11536
|
+
const rest = key.slice(4);
|
|
11537
|
+
const cut = rest.indexOf("/");
|
|
11538
|
+
const host = fold(cut < 0 ? rest : rest.slice(0, cut));
|
|
11539
|
+
return host === "github.com" ? fold(key) : `git:${host}${cut < 0 ? "" : rest.slice(cut)}`;
|
|
11540
|
+
}
|
|
11532
11541
|
var git = (dir, ...args) => {
|
|
11533
11542
|
try {
|
|
11534
11543
|
return execFileSync("git", ["-C", dir, ...args], {
|
|
@@ -11563,14 +11572,17 @@ function identify(dir) {
|
|
|
11563
11572
|
const given = path4.resolve(dir);
|
|
11564
11573
|
const top = git(given, "rev-parse", "--show-toplevel");
|
|
11565
11574
|
const root = top || given;
|
|
11566
|
-
const
|
|
11567
|
-
if (
|
|
11568
|
-
|
|
11575
|
+
const legacy = top ? legacyRemote(git(root, "remote", "get-url", "origin")) : null;
|
|
11576
|
+
if (legacy) {
|
|
11577
|
+
const key = normalizeKey(`git:${legacy}`);
|
|
11578
|
+
const remote = key.slice(4);
|
|
11579
|
+
return { key, legacyKey: `git:${legacy}`, root, name: remote.split("/").slice(1).join("/") || remote };
|
|
11580
|
+
}
|
|
11569
11581
|
const map = localMap();
|
|
11570
11582
|
for (let d = root;; d = path4.dirname(d)) {
|
|
11571
11583
|
const local = map[d];
|
|
11572
11584
|
if (local && LOCAL_KEY.test(local))
|
|
11573
|
-
return { key: `local:${local}`, root: d, name: local };
|
|
11585
|
+
return { key: `local:${local}`, legacyKey: `local:${local}`, root: d, name: local };
|
|
11574
11586
|
if (top || path4.dirname(d) === d)
|
|
11575
11587
|
return null;
|
|
11576
11588
|
}
|
|
@@ -11666,6 +11678,8 @@ var HOLD_MAX = 1000;
|
|
|
11666
11678
|
var baselineDir = () => path6.join(sphicaHome(), "worktree");
|
|
11667
11679
|
function current(raw) {
|
|
11668
11680
|
const r = raw;
|
|
11681
|
+
if (typeof r.project !== "string")
|
|
11682
|
+
throw new Error("queue record without a project key");
|
|
11669
11683
|
if (r.v === 2)
|
|
11670
11684
|
return raw;
|
|
11671
11685
|
if (r.v !== 1)
|
|
@@ -11846,7 +11860,7 @@ function onHook(host, input) {
|
|
|
11846
11860
|
v: 2,
|
|
11847
11861
|
host,
|
|
11848
11862
|
session: String(input.session_id),
|
|
11849
|
-
project: place.
|
|
11863
|
+
project: place.legacyKey,
|
|
11850
11864
|
branch: branchOf(place.root),
|
|
11851
11865
|
turn,
|
|
11852
11866
|
at
|
|
@@ -11978,17 +11992,33 @@ var BATCH = 500;
|
|
|
11978
11992
|
var FLUSH_BUDGET_MS = 30000;
|
|
11979
11993
|
var ROWS = 1000;
|
|
11980
11994
|
var chunks = (xs, n = ROWS) => Array.from({ length: Math.ceil(xs.length / n) }, (_, i) => xs.slice(i * n, (i + 1) * n));
|
|
11981
|
-
async function
|
|
11995
|
+
async function projectsOf(trx, keys) {
|
|
11996
|
+
if (!keys.length)
|
|
11997
|
+
return new Map;
|
|
11998
|
+
const all = await trx.selectFrom("project").select(["id", "key"]).execute();
|
|
11999
|
+
const exact = new Map(all.map((p) => [p.key, p.id]));
|
|
12000
|
+
const normal = Map.groupBy(all, (p) => normalizeKey(p.key));
|
|
12001
|
+
const found = new Map;
|
|
12002
|
+
for (const k of keys) {
|
|
12003
|
+
const same = normal.get(normalizeKey(k));
|
|
12004
|
+
const id = exact.get(k) ?? (same?.length === 1 ? same[0]?.id : undefined);
|
|
12005
|
+
if (id !== undefined)
|
|
12006
|
+
found.set(k, id);
|
|
12007
|
+
}
|
|
12008
|
+
return found;
|
|
12009
|
+
}
|
|
12010
|
+
async function write(db, batch) {
|
|
11982
12011
|
return inTransaction(db, async (trx) => {
|
|
12012
|
+
const projects = await projectsOf(trx, batch.map((r) => r.project));
|
|
11983
12013
|
const sessions = new Map;
|
|
11984
12014
|
for (const r of batch) {
|
|
11985
12015
|
const p = projects.get(r.project);
|
|
11986
|
-
if (
|
|
12016
|
+
if (p === undefined)
|
|
11987
12017
|
continue;
|
|
11988
|
-
const id = sessionId(p
|
|
12018
|
+
const id = sessionId(p, r.host, r.session);
|
|
11989
12019
|
const prev = sessions.get(id);
|
|
11990
12020
|
if (!prev || Date.parse(r.at) < Date.parse(prev.at))
|
|
11991
|
-
sessions.set(id, { project: p
|
|
12021
|
+
sessions.set(id, { project: p, host: r.host, session: r.session, branch: r.branch, at: r.at });
|
|
11992
12022
|
}
|
|
11993
12023
|
for (const part of chunks([...sessions]))
|
|
11994
12024
|
await trx.insertInto("capture_session").values(part.map(([id, v]) => ({
|
|
@@ -12001,9 +12031,9 @@ async function write(db, batch, projects) {
|
|
|
12001
12031
|
}))).execute();
|
|
12002
12032
|
const messages = batch.flatMap((m) => {
|
|
12003
12033
|
const p = m.kind === "message" ? projects.get(m.project) : undefined;
|
|
12004
|
-
if (m.kind !== "message" ||
|
|
12034
|
+
if (m.kind !== "message" || p === undefined)
|
|
12005
12035
|
return [];
|
|
12006
|
-
return [{ m, session: sessionId(p
|
|
12036
|
+
return [{ m, session: sessionId(p, m.host, m.session) }];
|
|
12007
12037
|
});
|
|
12008
12038
|
const present = async () => {
|
|
12009
12039
|
let n = 0;
|
|
@@ -12031,11 +12061,11 @@ async function write(db, batch, projects) {
|
|
|
12031
12061
|
const after = await present();
|
|
12032
12062
|
const edits = batch.flatMap((r) => {
|
|
12033
12063
|
const p = r.kind === "edit" ? projects.get(r.project) : undefined;
|
|
12034
|
-
if (r.kind !== "edit" ||
|
|
12064
|
+
if (r.kind !== "edit" || p === undefined)
|
|
12035
12065
|
return [];
|
|
12036
12066
|
return [
|
|
12037
12067
|
{
|
|
12038
|
-
session_id: sessionId(p
|
|
12068
|
+
session_id: sessionId(p, r.host, r.session),
|
|
12039
12069
|
turn_id: r.turn,
|
|
12040
12070
|
tool_event_id: r.event,
|
|
12041
12071
|
path: r.path,
|
|
@@ -12046,7 +12076,7 @@ async function write(db, batch, projects) {
|
|
|
12046
12076
|
});
|
|
12047
12077
|
for (const part of chunks(edits))
|
|
12048
12078
|
await trx.insertInto("capture_edit").values(part).execute();
|
|
12049
|
-
return after - before;
|
|
12079
|
+
return { sent: after - before, strayed: new Set(batch.filter((r) => !projects.has(r.project))) };
|
|
12050
12080
|
});
|
|
12051
12081
|
}
|
|
12052
12082
|
var REJECTED = new Set([18, 19, 20, 25]);
|
|
@@ -12075,19 +12105,22 @@ async function sendBatch(db, names) {
|
|
|
12075
12105
|
else
|
|
12076
12106
|
fs5.rmSync(path6.join(from, name), { force: true });
|
|
12077
12107
|
}
|
|
12078
|
-
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
12079
|
-
const known = records.filter((x) => projects.has(x.r.project));
|
|
12080
|
-
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
12081
12108
|
let sent = 0;
|
|
12109
|
+
let strayed = [];
|
|
12082
12110
|
const bad = [];
|
|
12083
12111
|
try {
|
|
12084
|
-
|
|
12112
|
+
const out = await write(db, records.map((x) => x.r));
|
|
12113
|
+
sent = out.sent;
|
|
12114
|
+
strayed = records.filter((x) => out.strayed.has(x.r));
|
|
12085
12115
|
} catch (e) {
|
|
12086
12116
|
if (!rejected(e))
|
|
12087
12117
|
throw e;
|
|
12088
|
-
for (const x of
|
|
12118
|
+
for (const x of records) {
|
|
12089
12119
|
try {
|
|
12090
|
-
|
|
12120
|
+
const out = await write(db, [x.r]);
|
|
12121
|
+
sent += out.sent;
|
|
12122
|
+
if (out.strayed.size)
|
|
12123
|
+
strayed.push(x);
|
|
12091
12124
|
} catch (e2) {
|
|
12092
12125
|
if (!rejected(e2))
|
|
12093
12126
|
throw e2;
|
package/dist/mcp-record.js
CHANGED
|
@@ -4070,13 +4070,14 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
4070
4070
|
if (!malformedIPLiteral) {
|
|
4071
4071
|
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
4072
4072
|
}
|
|
4073
|
-
if (
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4078
|
-
}
|
|
4073
|
+
if (uri.indexOf("%") !== -1 && parsed.host !== undefined && !malformedIPLiteral) {
|
|
4074
|
+
let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4075
|
+
if (!isIP) {
|
|
4076
|
+
host = normalizePercentEncoding(host.toLowerCase());
|
|
4079
4077
|
}
|
|
4078
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4079
|
+
}
|
|
4080
|
+
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
4080
4081
|
if (parsed.path) {
|
|
4081
4082
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
4082
4083
|
}
|
|
@@ -45870,7 +45871,7 @@ var HOST_MARKS = new Set([".orphaned_at", ".in_use"]);
|
|
|
45870
45871
|
|
|
45871
45872
|
// server/src/sqlite.ts
|
|
45872
45873
|
var SCHEMA_GENERATION = 2;
|
|
45873
|
-
var SCHEMA_REVISION =
|
|
45874
|
+
var SCHEMA_REVISION = 8;
|
|
45874
45875
|
var sphicaHome = () => process.env.SPHICA_HOME || path2.join(os.homedir(), ".sphica");
|
|
45875
45876
|
var dbFile = () => process.env.SPHICA_DB || path2.join(sphicaHome(), "sphica.db");
|
|
45876
45877
|
function requireRuntime() {
|
|
@@ -46343,7 +46344,7 @@ ${l}`).join("");
|
|
|
46343
46344
|
// server/src/project.ts
|
|
46344
46345
|
var localFile = () => path4.join(sphicaHome(), "projects.json");
|
|
46345
46346
|
var LOCAL_KEY = /^[a-z0-9][a-z0-9._-]*$/;
|
|
46346
|
-
function
|
|
46347
|
+
function legacyRemote(url2) {
|
|
46347
46348
|
const raw = String(url2 ?? "").trim();
|
|
46348
46349
|
if (!raw)
|
|
46349
46350
|
return null;
|
|
@@ -46360,6 +46361,15 @@ function normalizeRemote(url2) {
|
|
|
46360
46361
|
return null;
|
|
46361
46362
|
}
|
|
46362
46363
|
}
|
|
46364
|
+
var fold = (s) => s.replace(/[A-Z]+/g, (m) => m.toLowerCase());
|
|
46365
|
+
function normalizeKey(key) {
|
|
46366
|
+
if (!key.startsWith("git:"))
|
|
46367
|
+
return key;
|
|
46368
|
+
const rest = key.slice(4);
|
|
46369
|
+
const cut = rest.indexOf("/");
|
|
46370
|
+
const host = fold(cut < 0 ? rest : rest.slice(0, cut));
|
|
46371
|
+
return host === "github.com" ? fold(key) : `git:${host}${cut < 0 ? "" : rest.slice(cut)}`;
|
|
46372
|
+
}
|
|
46363
46373
|
var git = (dir, ...args) => {
|
|
46364
46374
|
try {
|
|
46365
46375
|
return execFileSync("git", ["-C", dir, ...args], {
|
|
@@ -46394,14 +46404,17 @@ function identify(dir) {
|
|
|
46394
46404
|
const given = path4.resolve(dir);
|
|
46395
46405
|
const top = git(given, "rev-parse", "--show-toplevel");
|
|
46396
46406
|
const root = top || given;
|
|
46397
|
-
const
|
|
46398
|
-
if (
|
|
46399
|
-
|
|
46407
|
+
const legacy = top ? legacyRemote(git(root, "remote", "get-url", "origin")) : null;
|
|
46408
|
+
if (legacy) {
|
|
46409
|
+
const key = normalizeKey(`git:${legacy}`);
|
|
46410
|
+
const remote = key.slice(4);
|
|
46411
|
+
return { key, legacyKey: `git:${legacy}`, root, name: remote.split("/").slice(1).join("/") || remote };
|
|
46412
|
+
}
|
|
46400
46413
|
const map3 = localMap();
|
|
46401
46414
|
for (let d = root;; d = path4.dirname(d)) {
|
|
46402
46415
|
const local = map3[d];
|
|
46403
46416
|
if (local && LOCAL_KEY.test(local))
|
|
46404
|
-
return { key: `local:${local}`, root: d, name: local };
|
|
46417
|
+
return { key: `local:${local}`, legacyKey: `local:${local}`, root: d, name: local };
|
|
46405
46418
|
if (top || path4.dirname(d) === d)
|
|
46406
46419
|
return null;
|
|
46407
46420
|
}
|
|
@@ -46517,6 +46530,8 @@ var HOLD_MAX = 1000;
|
|
|
46517
46530
|
var baselineDir = () => path6.join(sphicaHome(), "worktree");
|
|
46518
46531
|
function current(raw) {
|
|
46519
46532
|
const r = raw;
|
|
46533
|
+
if (typeof r.project !== "string")
|
|
46534
|
+
throw new Error("queue record without a project key");
|
|
46520
46535
|
if (r.v === 2)
|
|
46521
46536
|
return raw;
|
|
46522
46537
|
if (r.v !== 1)
|
|
@@ -46697,7 +46712,7 @@ function onHook(host, input2) {
|
|
|
46697
46712
|
v: 2,
|
|
46698
46713
|
host,
|
|
46699
46714
|
session: String(input2.session_id),
|
|
46700
|
-
project: place.
|
|
46715
|
+
project: place.legacyKey,
|
|
46701
46716
|
branch: branchOf(place.root),
|
|
46702
46717
|
turn,
|
|
46703
46718
|
at
|
|
@@ -46830,17 +46845,33 @@ var FLUSH_BUDGET_MS = 30000;
|
|
|
46830
46845
|
var TOOL_FLUSH_BUDGET_MS = 2000;
|
|
46831
46846
|
var ROWS = 1000;
|
|
46832
46847
|
var chunks = (xs, n = ROWS) => Array.from({ length: Math.ceil(xs.length / n) }, (_, i) => xs.slice(i * n, (i + 1) * n));
|
|
46833
|
-
async function
|
|
46848
|
+
async function projectsOf(trx, keys) {
|
|
46849
|
+
if (!keys.length)
|
|
46850
|
+
return new Map;
|
|
46851
|
+
const all = await trx.selectFrom("project").select(["id", "key"]).execute();
|
|
46852
|
+
const exact = new Map(all.map((p) => [p.key, p.id]));
|
|
46853
|
+
const normal = Map.groupBy(all, (p) => normalizeKey(p.key));
|
|
46854
|
+
const found = new Map;
|
|
46855
|
+
for (const k of keys) {
|
|
46856
|
+
const same = normal.get(normalizeKey(k));
|
|
46857
|
+
const id = exact.get(k) ?? (same?.length === 1 ? same[0]?.id : undefined);
|
|
46858
|
+
if (id !== undefined)
|
|
46859
|
+
found.set(k, id);
|
|
46860
|
+
}
|
|
46861
|
+
return found;
|
|
46862
|
+
}
|
|
46863
|
+
async function write(db, batch) {
|
|
46834
46864
|
return inTransaction(db, async (trx) => {
|
|
46865
|
+
const projects = await projectsOf(trx, batch.map((r) => r.project));
|
|
46835
46866
|
const sessions = new Map;
|
|
46836
46867
|
for (const r of batch) {
|
|
46837
46868
|
const p = projects.get(r.project);
|
|
46838
|
-
if (
|
|
46869
|
+
if (p === undefined)
|
|
46839
46870
|
continue;
|
|
46840
|
-
const id = sessionId(p
|
|
46871
|
+
const id = sessionId(p, r.host, r.session);
|
|
46841
46872
|
const prev = sessions.get(id);
|
|
46842
46873
|
if (!prev || Date.parse(r.at) < Date.parse(prev.at))
|
|
46843
|
-
sessions.set(id, { project: p
|
|
46874
|
+
sessions.set(id, { project: p, host: r.host, session: r.session, branch: r.branch, at: r.at });
|
|
46844
46875
|
}
|
|
46845
46876
|
for (const part of chunks([...sessions]))
|
|
46846
46877
|
await trx.insertInto("capture_session").values(part.map(([id, v]) => ({
|
|
@@ -46853,9 +46884,9 @@ async function write(db, batch, projects) {
|
|
|
46853
46884
|
}))).execute();
|
|
46854
46885
|
const messages = batch.flatMap((m) => {
|
|
46855
46886
|
const p = m.kind === "message" ? projects.get(m.project) : undefined;
|
|
46856
|
-
if (m.kind !== "message" ||
|
|
46887
|
+
if (m.kind !== "message" || p === undefined)
|
|
46857
46888
|
return [];
|
|
46858
|
-
return [{ m, session: sessionId(p
|
|
46889
|
+
return [{ m, session: sessionId(p, m.host, m.session) }];
|
|
46859
46890
|
});
|
|
46860
46891
|
const present = async () => {
|
|
46861
46892
|
let n = 0;
|
|
@@ -46883,11 +46914,11 @@ async function write(db, batch, projects) {
|
|
|
46883
46914
|
const after = await present();
|
|
46884
46915
|
const edits = batch.flatMap((r) => {
|
|
46885
46916
|
const p = r.kind === "edit" ? projects.get(r.project) : undefined;
|
|
46886
|
-
if (r.kind !== "edit" ||
|
|
46917
|
+
if (r.kind !== "edit" || p === undefined)
|
|
46887
46918
|
return [];
|
|
46888
46919
|
return [
|
|
46889
46920
|
{
|
|
46890
|
-
session_id: sessionId(p
|
|
46921
|
+
session_id: sessionId(p, r.host, r.session),
|
|
46891
46922
|
turn_id: r.turn,
|
|
46892
46923
|
tool_event_id: r.event,
|
|
46893
46924
|
path: r.path,
|
|
@@ -46898,7 +46929,7 @@ async function write(db, batch, projects) {
|
|
|
46898
46929
|
});
|
|
46899
46930
|
for (const part of chunks(edits))
|
|
46900
46931
|
await trx.insertInto("capture_edit").values(part).execute();
|
|
46901
|
-
return after - before;
|
|
46932
|
+
return { sent: after - before, strayed: new Set(batch.filter((r) => !projects.has(r.project))) };
|
|
46902
46933
|
});
|
|
46903
46934
|
}
|
|
46904
46935
|
var REJECTED = new Set([18, 19, 20, 25]);
|
|
@@ -46927,19 +46958,22 @@ async function sendBatch(db, names) {
|
|
|
46927
46958
|
else
|
|
46928
46959
|
fs6.rmSync(path6.join(from, name), { force: true });
|
|
46929
46960
|
}
|
|
46930
|
-
const projects = new Map((await db.selectFrom("project").select(["id", "key", "name"]).where("key", "in", [...new Set(records.map((x) => x.r.project))]).execute()).map((p) => [p.key, { id: p.id, name: p.name }]));
|
|
46931
|
-
const known = records.filter((x) => projects.has(x.r.project));
|
|
46932
|
-
const strayed = records.filter((x) => !projects.has(x.r.project));
|
|
46933
46961
|
let sent = 0;
|
|
46962
|
+
let strayed = [];
|
|
46934
46963
|
const bad = [];
|
|
46935
46964
|
try {
|
|
46936
|
-
|
|
46965
|
+
const out = await write(db, records.map((x) => x.r));
|
|
46966
|
+
sent = out.sent;
|
|
46967
|
+
strayed = records.filter((x) => out.strayed.has(x.r));
|
|
46937
46968
|
} catch (e) {
|
|
46938
46969
|
if (!rejected(e))
|
|
46939
46970
|
throw e;
|
|
46940
|
-
for (const x of
|
|
46971
|
+
for (const x of records) {
|
|
46941
46972
|
try {
|
|
46942
|
-
|
|
46973
|
+
const out = await write(db, [x.r]);
|
|
46974
|
+
sent += out.sent;
|
|
46975
|
+
if (out.strayed.size)
|
|
46976
|
+
strayed.push(x);
|
|
46943
46977
|
} catch (e2) {
|
|
46944
46978
|
if (!rejected(e2))
|
|
46945
46979
|
throw e2;
|
package/dist/mcp.js
CHANGED
|
@@ -4070,13 +4070,14 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
4070
4070
|
if (!malformedIPLiteral) {
|
|
4071
4071
|
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
4072
4072
|
}
|
|
4073
|
-
if (
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4078
|
-
}
|
|
4073
|
+
if (uri.indexOf("%") !== -1 && parsed.host !== undefined && !malformedIPLiteral) {
|
|
4074
|
+
let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4075
|
+
if (!isIP) {
|
|
4076
|
+
host = normalizePercentEncoding(host.toLowerCase());
|
|
4079
4077
|
}
|
|
4078
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4079
|
+
}
|
|
4080
|
+
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
4080
4081
|
if (parsed.path) {
|
|
4081
4082
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
4082
4083
|
}
|
|
@@ -45691,7 +45692,7 @@ var HOST_MARKS = new Set([".orphaned_at", ".in_use"]);
|
|
|
45691
45692
|
|
|
45692
45693
|
// server/src/sqlite.ts
|
|
45693
45694
|
var SCHEMA_GENERATION = 2;
|
|
45694
|
-
var SCHEMA_REVISION =
|
|
45695
|
+
var SCHEMA_REVISION = 8;
|
|
45695
45696
|
var sphicaHome = () => process.env.SPHICA_HOME || path2.join(os.homedir(), ".sphica");
|
|
45696
45697
|
var dbFile = () => process.env.SPHICA_DB || path2.join(sphicaHome(), "sphica.db");
|
|
45697
45698
|
function requireRuntime() {
|
|
@@ -47111,7 +47112,7 @@ import fs6 from "node:fs";
|
|
|
47111
47112
|
import path7 from "node:path";
|
|
47112
47113
|
var localFile = () => path7.join(sphicaHome(), "projects.json");
|
|
47113
47114
|
var LOCAL_KEY = /^[a-z0-9][a-z0-9._-]*$/;
|
|
47114
|
-
function
|
|
47115
|
+
function legacyRemote(url2) {
|
|
47115
47116
|
const raw = String(url2 ?? "").trim();
|
|
47116
47117
|
if (!raw)
|
|
47117
47118
|
return null;
|
|
@@ -47128,6 +47129,15 @@ function normalizeRemote(url2) {
|
|
|
47128
47129
|
return null;
|
|
47129
47130
|
}
|
|
47130
47131
|
}
|
|
47132
|
+
var fold = (s) => s.replace(/[A-Z]+/g, (m) => m.toLowerCase());
|
|
47133
|
+
function normalizeKey(key) {
|
|
47134
|
+
if (!key.startsWith("git:"))
|
|
47135
|
+
return key;
|
|
47136
|
+
const rest = key.slice(4);
|
|
47137
|
+
const cut2 = rest.indexOf("/");
|
|
47138
|
+
const host = fold(cut2 < 0 ? rest : rest.slice(0, cut2));
|
|
47139
|
+
return host === "github.com" ? fold(key) : `git:${host}${cut2 < 0 ? "" : rest.slice(cut2)}`;
|
|
47140
|
+
}
|
|
47131
47141
|
var git = (dir, ...args) => {
|
|
47132
47142
|
try {
|
|
47133
47143
|
return execFileSync2("git", ["-C", dir, ...args], {
|
|
@@ -47162,14 +47172,17 @@ function identify(dir) {
|
|
|
47162
47172
|
const given = path7.resolve(dir);
|
|
47163
47173
|
const top = git(given, "rev-parse", "--show-toplevel");
|
|
47164
47174
|
const root = top || given;
|
|
47165
|
-
const
|
|
47166
|
-
if (
|
|
47167
|
-
|
|
47175
|
+
const legacy = top ? legacyRemote(git(root, "remote", "get-url", "origin")) : null;
|
|
47176
|
+
if (legacy) {
|
|
47177
|
+
const key = normalizeKey(`git:${legacy}`);
|
|
47178
|
+
const remote = key.slice(4);
|
|
47179
|
+
return { key, legacyKey: `git:${legacy}`, root, name: remote.split("/").slice(1).join("/") || remote };
|
|
47180
|
+
}
|
|
47168
47181
|
const map3 = localMap();
|
|
47169
47182
|
for (let d = root;; d = path7.dirname(d)) {
|
|
47170
47183
|
const local = map3[d];
|
|
47171
47184
|
if (local && LOCAL_KEY.test(local))
|
|
47172
|
-
return { key: `local:${local}`, root: d, name: local };
|
|
47185
|
+
return { key: `local:${local}`, legacyKey: `local:${local}`, root: d, name: local };
|
|
47173
47186
|
if (top || path7.dirname(d) === d)
|
|
47174
47187
|
return null;
|
|
47175
47188
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sphica",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.22",
|
|
4
4
|
"description": "Records Claude Code and Codex sessions on your machine and keeps past implementation and decisions, with their sources, for your agent to find.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|