@agimon-ai/po-git 0.0.0-alpha.44 → 0.0.0-alpha.46
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/dist/extensions/native.mjs +6 -3
- package/dist/extensions/native.mjs.map +1 -1
- package/dist/extensions/server.cjs +57 -53
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +56 -52
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{worktreeOperations-CU0iV2h-.cjs → worktreeOperations-C1ygq-Na.cjs} +73 -65
- package/dist/worktreeOperations-C1ygq-Na.cjs.map +1 -0
- package/dist/{worktreeOperations-BqLLypS5.mjs → worktreeOperations-CP2lYxrI.mjs} +72 -64
- package/dist/worktreeOperations-CP2lYxrI.mjs.map +1 -0
- package/package.json +8 -8
- package/dist/worktreeOperations-BqLLypS5.mjs.map +0 -1
- package/dist/worktreeOperations-CU0iV2h-.cjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as READ_TIMEOUT_MS, E as runGit, S as NETWORK_TIMEOUT_MS, T as createWorktreeGit, a as GIT_WORKTREE_LIFECYCLE_EVENT, c as isWorktreeLifecycleEvent, d as registryFile, f as readJson, g as invalidRequest, h as PoGitExpectedError, i as GIT_SESSION_CHANGED_EVENT, l as credentialsFile, m as HubUnavailableError, n as createWorktreeRegistry, o as createWorktreeMessageInbox, p as writeJsonAtomic, r as validRefName, s as isSessionChangedEvent, t as createWorktreeOperations, u as poGitRoot, w as REBASE_TIMEOUT_MS } from "../worktreeOperations-
|
|
2
|
-
import fs from "node:fs";
|
|
1
|
+
import { C as READ_TIMEOUT_MS, E as runGit, S as NETWORK_TIMEOUT_MS, T as createWorktreeGit, a as GIT_WORKTREE_LIFECYCLE_EVENT, c as isWorktreeLifecycleEvent, d as registryFile, f as readJson, g as invalidRequest, h as PoGitExpectedError, i as GIT_SESSION_CHANGED_EVENT, l as credentialsFile, m as HubUnavailableError, n as createWorktreeRegistry, o as createWorktreeMessageInbox, p as writeJsonAtomic, r as validRefName, s as isSessionChangedEvent, t as createWorktreeOperations, u as poGitRoot, w as REBASE_TIMEOUT_MS } from "../worktreeOperations-CP2lYxrI.mjs";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import { composeServerProviderOverrides, defineServerPlugin, packageResourcePath, readPackageResource } from "@agimon-ai/po-core/serverPlugin";
|
|
@@ -646,11 +646,11 @@ const NAME_STATUS = {
|
|
|
646
646
|
T: "modified"
|
|
647
647
|
};
|
|
648
648
|
/** Line count of a small regular file, or undefined when it is binary, large, or not a regular file. */
|
|
649
|
-
function untrackedLines(root, relPath) {
|
|
649
|
+
async function untrackedLines(root, relPath) {
|
|
650
650
|
const absolute = path.join(root, relPath);
|
|
651
651
|
let stat;
|
|
652
652
|
try {
|
|
653
|
-
stat = fs.
|
|
653
|
+
stat = await fs.lstat(absolute);
|
|
654
654
|
} catch {
|
|
655
655
|
return;
|
|
656
656
|
}
|
|
@@ -659,7 +659,7 @@ function untrackedLines(root, relPath) {
|
|
|
659
659
|
binary: false
|
|
660
660
|
};
|
|
661
661
|
if (!stat.isFile() || stat.size > MAX_FILE_BYTES) return void 0;
|
|
662
|
-
const content = fs.
|
|
662
|
+
const content = await fs.readFile(absolute);
|
|
663
663
|
if (content.subarray(0, BINARY_PROBE_BYTES).includes(0)) return {
|
|
664
664
|
lines: 0,
|
|
665
665
|
binary: true
|
|
@@ -782,8 +782,8 @@ function createBranchDiff() {
|
|
|
782
782
|
"--exclude-standard",
|
|
783
783
|
"-z"
|
|
784
784
|
]));
|
|
785
|
-
untracked.
|
|
786
|
-
const counted = index < MAX_UNTRACKED_COUNTED ? untrackedLines(root, relPath) : void 0;
|
|
785
|
+
for (const [index, relPath] of untracked.entries()) {
|
|
786
|
+
const counted = index < MAX_UNTRACKED_COUNTED ? await untrackedLines(root, relPath) : void 0;
|
|
787
787
|
entries.push({
|
|
788
788
|
path: relPath,
|
|
789
789
|
status: "untracked",
|
|
@@ -791,18 +791,20 @@ function createBranchDiff() {
|
|
|
791
791
|
removed: 0,
|
|
792
792
|
...counted?.binary ? { binary: true } : {}
|
|
793
793
|
});
|
|
794
|
-
}
|
|
794
|
+
}
|
|
795
795
|
entries.sort((left, right) => left.path.localeCompare(right.path));
|
|
796
796
|
const conflicts = [...unmerged];
|
|
797
|
-
const
|
|
797
|
+
const rebaseMerge = await readLine$1(root, [
|
|
798
798
|
"rev-parse",
|
|
799
799
|
"--git-path",
|
|
800
800
|
"rebase-merge"
|
|
801
|
-
])
|
|
801
|
+
]);
|
|
802
|
+
const rebaseApply = await readLine$1(root, [
|
|
802
803
|
"rev-parse",
|
|
803
804
|
"--git-path",
|
|
804
805
|
"rebase-apply"
|
|
805
|
-
])
|
|
806
|
+
]);
|
|
807
|
+
const rebasing = (await Promise.all([rebaseMerge, rebaseApply].map(async (gitPath) => gitPath === void 0 ? false : fs.access(path.resolve(root, gitPath)).then(() => true, () => false)))).some(Boolean);
|
|
806
808
|
const upstreamRef = branch === void 0 ? void 0 : await upstreamOf(root, branch);
|
|
807
809
|
let upstream;
|
|
808
810
|
if (upstreamRef !== void 0) {
|
|
@@ -847,7 +849,7 @@ function createBranchDiff() {
|
|
|
847
849
|
if (entry === void 0) throw new Error("That path is not in this review.");
|
|
848
850
|
if (entry.status === "untracked") {
|
|
849
851
|
const absolute = path.join(review.root, entry.path);
|
|
850
|
-
const stat = fs.
|
|
852
|
+
const stat = await fs.lstat(absolute);
|
|
851
853
|
if (stat.isSymbolicLink()) return {
|
|
852
854
|
path: entry.path,
|
|
853
855
|
hunks: [{
|
|
@@ -855,7 +857,7 @@ function createBranchDiff() {
|
|
|
855
857
|
rows: [{
|
|
856
858
|
marker: "+",
|
|
857
859
|
line: 1,
|
|
858
|
-
content: fs.
|
|
860
|
+
content: await fs.readlink(absolute)
|
|
859
861
|
}]
|
|
860
862
|
}]
|
|
861
863
|
};
|
|
@@ -864,7 +866,7 @@ function createBranchDiff() {
|
|
|
864
866
|
hunks: [],
|
|
865
867
|
tooLarge: true
|
|
866
868
|
};
|
|
867
|
-
const content = fs.
|
|
869
|
+
const content = await fs.readFile(absolute);
|
|
868
870
|
if (content.subarray(0, BINARY_PROBE_BYTES).includes(0)) return {
|
|
869
871
|
path: entry.path,
|
|
870
872
|
hunks: [],
|
|
@@ -981,9 +983,9 @@ function isRecord(value) {
|
|
|
981
983
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
982
984
|
}
|
|
983
985
|
/** The workspace key: the canonical root, so a symlinked path and its target share one entry. */
|
|
984
|
-
function workspaceKey(workspaceRoot) {
|
|
986
|
+
async function workspaceKey(workspaceRoot) {
|
|
985
987
|
try {
|
|
986
|
-
return fs.
|
|
988
|
+
return await fs.realpath(workspaceRoot);
|
|
987
989
|
} catch {
|
|
988
990
|
return path.resolve(workspaceRoot);
|
|
989
991
|
}
|
|
@@ -1032,7 +1034,7 @@ function publicView(config) {
|
|
|
1032
1034
|
* the saved one, and only for the same host: a token never follows a host it
|
|
1033
1035
|
* was not entered for.
|
|
1034
1036
|
*/
|
|
1035
|
-
function parseGitAuthSave(request, current, homeDir) {
|
|
1037
|
+
async function parseGitAuthSave(request, current, homeDir) {
|
|
1036
1038
|
if (!isRecord(request)) throw invalidRequest("The git auth request is not an object.", "Send method none, ssh or https.");
|
|
1037
1039
|
if (request.method === "none") return { method: "none" };
|
|
1038
1040
|
if (request.method === "ssh") {
|
|
@@ -1042,7 +1044,7 @@ function parseGitAuthSave(request, current, homeDir) {
|
|
|
1042
1044
|
if (!keyPath.startsWith("/") && !keyPath.startsWith("~/")) throw invalidRequest("The key path is not absolute.", "Give the key as an absolute path or one under ~/.");
|
|
1043
1045
|
let isFile = false;
|
|
1044
1046
|
try {
|
|
1045
|
-
isFile = fs.
|
|
1047
|
+
isFile = (await fs.stat(expandHome(keyPath, homeDir))).isFile();
|
|
1046
1048
|
} catch {
|
|
1047
1049
|
isFile = false;
|
|
1048
1050
|
}
|
|
@@ -1077,16 +1079,16 @@ function parseGitAuthSave(request, current, homeDir) {
|
|
|
1077
1079
|
throw invalidRequest("The git auth method is unknown.", "Send method none, ssh or https.");
|
|
1078
1080
|
}
|
|
1079
1081
|
/** Tightens a file or folder something left readable by group or others. */
|
|
1080
|
-
function tighten(target, mode) {
|
|
1082
|
+
async function tighten(target, mode) {
|
|
1081
1083
|
try {
|
|
1082
|
-
if ((fs.
|
|
1084
|
+
if (((await fs.stat(target)).mode & LOOSE_BITS) !== 0) await fs.chmod(target, mode);
|
|
1083
1085
|
} catch {}
|
|
1084
1086
|
}
|
|
1085
1087
|
function createGitAuthStore(homeDir = os.homedir()) {
|
|
1086
1088
|
const file = credentialsFile(homeDir);
|
|
1087
|
-
const readFile = () => {
|
|
1088
|
-
tighten(file, OWNER_ONLY_FILE);
|
|
1089
|
-
const raw = readJson(file);
|
|
1089
|
+
const readFile = async () => {
|
|
1090
|
+
await tighten(file, OWNER_ONLY_FILE);
|
|
1091
|
+
const raw = await readJson(file);
|
|
1090
1092
|
const workspaces = {};
|
|
1091
1093
|
if (isRecord(raw) && raw.version === 1 && isRecord(raw.workspaces)) for (const [key, value] of Object.entries(raw.workspaces)) {
|
|
1092
1094
|
const config = parseConfig(value);
|
|
@@ -1097,28 +1099,28 @@ function createGitAuthStore(homeDir = os.homedir()) {
|
|
|
1097
1099
|
workspaces
|
|
1098
1100
|
};
|
|
1099
1101
|
};
|
|
1100
|
-
const read = (workspaceRoot) => readFile().workspaces[workspaceKey(workspaceRoot)] ?? { method: "none" };
|
|
1102
|
+
const read = async (workspaceRoot) => (await readFile()).workspaces[await workspaceKey(workspaceRoot)] ?? { method: "none" };
|
|
1101
1103
|
return {
|
|
1102
1104
|
read,
|
|
1103
|
-
view: (workspaceRoot) => publicView(read(workspaceRoot)),
|
|
1104
|
-
save(workspaceRoot, request) {
|
|
1105
|
-
const key = workspaceKey(workspaceRoot);
|
|
1106
|
-
const current = readFile();
|
|
1107
|
-
const next = parseGitAuthSave(request, current.workspaces[key] ?? { method: "none" }, homeDir);
|
|
1105
|
+
view: async (workspaceRoot) => publicView(await read(workspaceRoot)),
|
|
1106
|
+
async save(workspaceRoot, request) {
|
|
1107
|
+
const key = await workspaceKey(workspaceRoot);
|
|
1108
|
+
const current = await readFile();
|
|
1109
|
+
const next = await parseGitAuthSave(request, current.workspaces[key] ?? { method: "none" }, homeDir);
|
|
1108
1110
|
const root = poGitRoot(homeDir);
|
|
1109
|
-
fs.
|
|
1111
|
+
await fs.mkdir(root, {
|
|
1110
1112
|
recursive: true,
|
|
1111
1113
|
mode: OWNER_ONLY_DIRECTORY
|
|
1112
1114
|
});
|
|
1113
|
-
fs.
|
|
1115
|
+
await fs.chmod(root, OWNER_ONLY_DIRECTORY);
|
|
1114
1116
|
const workspaces = { ...current.workspaces };
|
|
1115
1117
|
if (next.method === "none") delete workspaces[key];
|
|
1116
1118
|
else workspaces[key] = next;
|
|
1117
|
-
writeJsonAtomic(file, {
|
|
1119
|
+
await writeJsonAtomic(file, {
|
|
1118
1120
|
version: 1,
|
|
1119
1121
|
workspaces
|
|
1120
1122
|
});
|
|
1121
|
-
fs.
|
|
1123
|
+
await fs.chmod(file, OWNER_ONLY_FILE);
|
|
1122
1124
|
return publicView(next);
|
|
1123
1125
|
}
|
|
1124
1126
|
};
|
|
@@ -1364,9 +1366,9 @@ var route_server_default = defineRoute({
|
|
|
1364
1366
|
if (request.method !== "GET" && request.method !== "PUT") return Response.json({ error: "Use GET or PUT." }, { status: 405 });
|
|
1365
1367
|
const root = rootOf(url);
|
|
1366
1368
|
if (root instanceof Response) return root;
|
|
1367
|
-
if (request.method === "GET") return Response.json(gitAuth.view(root));
|
|
1369
|
+
if (request.method === "GET") return Response.json(await gitAuth.view(root));
|
|
1368
1370
|
try {
|
|
1369
|
-
return Response.json(gitAuth.save(root, await request.json().catch(() => void 0)));
|
|
1371
|
+
return Response.json(await gitAuth.save(root, await request.json().catch(() => void 0)));
|
|
1370
1372
|
} catch (error) {
|
|
1371
1373
|
if (error instanceof PoGitExpectedError && error.code === "invalid_request") {
|
|
1372
1374
|
const text = error.message.replace(/^\[[a-z_]+\] /u, "").replace("\nRecovery: ", " ");
|
|
@@ -1390,7 +1392,7 @@ var route_server_default = defineRoute({
|
|
|
1390
1392
|
if (request.method !== "GET") return Response.json({ error: "Use GET." }, { status: 405 });
|
|
1391
1393
|
let recordedBaseRef;
|
|
1392
1394
|
try {
|
|
1393
|
-
recordedBaseRef = createWorktreeRegistry(registryFile(cwd, homeDir)).list().find((record) => record.sessionId === context.sessionId)?.baseRef;
|
|
1395
|
+
recordedBaseRef = (await createWorktreeRegistry(await registryFile(cwd, homeDir)).list()).find((record) => record.sessionId === context.sessionId)?.baseRef;
|
|
1394
1396
|
} catch {
|
|
1395
1397
|
recordedBaseRef = void 0;
|
|
1396
1398
|
}
|
|
@@ -1590,7 +1592,7 @@ async function rebasing(root) {
|
|
|
1590
1592
|
"--git-path",
|
|
1591
1593
|
name
|
|
1592
1594
|
]);
|
|
1593
|
-
if (gitPath !== void 0 && fs.
|
|
1595
|
+
if (gitPath !== void 0 && await fs.access(path.resolve(root, gitPath)).then(() => true, () => false)) return true;
|
|
1594
1596
|
}
|
|
1595
1597
|
return false;
|
|
1596
1598
|
}
|
|
@@ -1823,9 +1825,9 @@ function createGitChangesChannel(options = {}) {
|
|
|
1823
1825
|
const rerun = /* @__PURE__ */ new Set();
|
|
1824
1826
|
const busy = /* @__PURE__ */ new Set();
|
|
1825
1827
|
/** The base the session's own worktree was created from, when it has one. */
|
|
1826
|
-
const recordedBaseRef = (scope) => {
|
|
1828
|
+
const recordedBaseRef = async (scope) => {
|
|
1827
1829
|
try {
|
|
1828
|
-
return createWorktreeRegistry(registryFile(scope.cwd, homeDir)).list().find((record) => record.sessionId === scope.sessionId)?.baseRef;
|
|
1830
|
+
return (await createWorktreeRegistry(await registryFile(scope.cwd, homeDir)).list()).find((record) => record.sessionId === scope.sessionId)?.baseRef;
|
|
1829
1831
|
} catch {
|
|
1830
1832
|
return;
|
|
1831
1833
|
}
|
|
@@ -1858,8 +1860,7 @@ function createGitChangesChannel(options = {}) {
|
|
|
1858
1860
|
return;
|
|
1859
1861
|
}
|
|
1860
1862
|
inFlight.add(sessionId);
|
|
1861
|
-
|
|
1862
|
-
diff.review(scope.cwd, base === void 0 ? {} : { recordedBaseRef: base }).then((review) => {
|
|
1863
|
+
recordedBaseRef(scope).then((base) => diff.review(scope.cwd, base === void 0 ? {} : { recordedBaseRef: base })).then((review) => {
|
|
1863
1864
|
if (scopes.has(sessionId)) update(sessionId, { changes: review?.changes });
|
|
1864
1865
|
}).catch((error) => {
|
|
1865
1866
|
host.onNotice(`git diff refresh failed for ${sessionId} (${error instanceof Error ? error.name : "unknown"})`);
|
|
@@ -1868,12 +1869,12 @@ function createGitChangesChannel(options = {}) {
|
|
|
1868
1869
|
if (rerun.delete(sessionId)) refresh(sessionId);
|
|
1869
1870
|
});
|
|
1870
1871
|
};
|
|
1871
|
-
const run = (scope, command) => {
|
|
1872
|
+
const run = async (scope, command) => {
|
|
1872
1873
|
const workspaceRoot = scope.sessionContext?.workspaceRoot ?? scope.cwd;
|
|
1873
|
-
const base = recordedBaseRef(scope);
|
|
1874
|
+
const base = await recordedBaseRef(scope);
|
|
1874
1875
|
const context = {
|
|
1875
1876
|
cwd: scope.cwd,
|
|
1876
|
-
auth: auth.read(workspaceRoot),
|
|
1877
|
+
auth: await auth.read(workspaceRoot),
|
|
1877
1878
|
...base === void 0 ? {} : { recordedBaseRef: base }
|
|
1878
1879
|
};
|
|
1879
1880
|
if (command.action === "pull") return sync.pull(context);
|
|
@@ -1971,9 +1972,9 @@ function payloadOf(state) {
|
|
|
1971
1972
|
};
|
|
1972
1973
|
}
|
|
1973
1974
|
/** Worktrees visible to this session, using the hub's live session table for ownership. */
|
|
1974
|
-
function viewsFor(scope, deps) {
|
|
1975
|
+
async function viewsFor(scope, deps) {
|
|
1975
1976
|
try {
|
|
1976
|
-
return createWorktreeRegistry(registryFile(scope.cwd, deps.homeDir)).list().flatMap((record) => {
|
|
1977
|
+
return (await createWorktreeRegistry(await registryFile(scope.cwd, deps.homeDir)).list()).flatMap((record) => {
|
|
1977
1978
|
if (record.parentSessionId === void 0 && record.sessionId !== scope.sessionId) return [];
|
|
1978
1979
|
const owned = record.parentSessionId === void 0 || record.parentSessionId === scope.sessionId;
|
|
1979
1980
|
const unowned = !owned && !deps.sessionService.isLive(record.parentSessionId);
|
|
@@ -2091,10 +2092,13 @@ function createWorktreesChannel(options = {}) {
|
|
|
2091
2092
|
return generation;
|
|
2092
2093
|
};
|
|
2093
2094
|
/** Republishes a session, skipping a frame that would say nothing new. */
|
|
2094
|
-
const publish = (scope, force) => {
|
|
2095
|
+
const publish = async (scope, force) => {
|
|
2096
|
+
const generation = generations.get(scope.sessionId);
|
|
2097
|
+
const worktreeViews = await viewsFor(scope, views);
|
|
2098
|
+
if (generation === void 0 || generations.get(scope.sessionId) !== generation) return;
|
|
2095
2099
|
const previous = latest.get(scope.sessionId);
|
|
2096
2100
|
const next = {
|
|
2097
|
-
worktrees:
|
|
2101
|
+
worktrees: worktreeViews,
|
|
2098
2102
|
pending: previous?.pending,
|
|
2099
2103
|
error: previous?.error,
|
|
2100
2104
|
errorTarget: previous?.errorTarget
|
|
@@ -2106,7 +2110,7 @@ function createWorktreesChannel(options = {}) {
|
|
|
2106
2110
|
const mark = (scope, pending, error, errorTarget) => {
|
|
2107
2111
|
const previous = latest.get(scope.sessionId);
|
|
2108
2112
|
latest.set(scope.sessionId, {
|
|
2109
|
-
worktrees: previous?.worktrees ??
|
|
2113
|
+
worktrees: previous?.worktrees ?? [],
|
|
2110
2114
|
pending,
|
|
2111
2115
|
error,
|
|
2112
2116
|
errorTarget
|
|
@@ -2146,15 +2150,15 @@ function createWorktreesChannel(options = {}) {
|
|
|
2146
2150
|
sessionAdded(scope) {
|
|
2147
2151
|
newGeneration(scope.sessionId);
|
|
2148
2152
|
publish(scope, false);
|
|
2149
|
-
const unsubscribe = host.directEvents.subscribe(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, (payload) => {
|
|
2153
|
+
const unsubscribe = host.directEvents.subscribe(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, async (payload) => {
|
|
2150
2154
|
if (!isWorktreeLifecycleEvent(payload)) return;
|
|
2151
2155
|
let sameRepository = false;
|
|
2152
2156
|
try {
|
|
2153
|
-
sameRepository = registryFile(scope.cwd, options.homeDir) === registryFile(payload.repositoryRoot, options.homeDir);
|
|
2157
|
+
sameRepository = await registryFile(scope.cwd, options.homeDir) === await registryFile(payload.repositoryRoot, options.homeDir);
|
|
2154
2158
|
} catch {
|
|
2155
2159
|
sameRepository = false;
|
|
2156
2160
|
}
|
|
2157
|
-
if (sameRepository) publish(scope, false);
|
|
2161
|
+
if (sameRepository) await publish(scope, false);
|
|
2158
2162
|
});
|
|
2159
2163
|
subscriptions.set(scope.sessionId, unsubscribe);
|
|
2160
2164
|
},
|