@mariozechner/pi-coding-agent 0.52.2 → 0.52.4
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 +16 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +6 -0
- package/dist/core/package-manager.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +143 -40
- package/dist/utils/git.js.map +1 -1
- package/docs/packages.md +1 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
package/dist/utils/git.js
CHANGED
|
@@ -1,49 +1,152 @@
|
|
|
1
1
|
import hostedGitInfo from "hosted-git-info";
|
|
2
|
+
function splitRef(url) {
|
|
3
|
+
const scpLikeMatch = url.match(/^git@([^:]+):(.+)$/);
|
|
4
|
+
if (scpLikeMatch) {
|
|
5
|
+
const pathWithMaybeRef = scpLikeMatch[2] ?? "";
|
|
6
|
+
const refSeparator = pathWithMaybeRef.indexOf("@");
|
|
7
|
+
if (refSeparator < 0)
|
|
8
|
+
return { repo: url };
|
|
9
|
+
const repoPath = pathWithMaybeRef.slice(0, refSeparator);
|
|
10
|
+
const ref = pathWithMaybeRef.slice(refSeparator + 1);
|
|
11
|
+
if (!repoPath || !ref)
|
|
12
|
+
return { repo: url };
|
|
13
|
+
return {
|
|
14
|
+
repo: `git@${scpLikeMatch[1] ?? ""}:${repoPath}`,
|
|
15
|
+
ref,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (url.includes("://")) {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = new URL(url);
|
|
21
|
+
const pathWithMaybeRef = parsed.pathname.replace(/^\/+/, "");
|
|
22
|
+
const refSeparator = pathWithMaybeRef.indexOf("@");
|
|
23
|
+
if (refSeparator < 0)
|
|
24
|
+
return { repo: url };
|
|
25
|
+
const repoPath = pathWithMaybeRef.slice(0, refSeparator);
|
|
26
|
+
const ref = pathWithMaybeRef.slice(refSeparator + 1);
|
|
27
|
+
if (!repoPath || !ref)
|
|
28
|
+
return { repo: url };
|
|
29
|
+
parsed.pathname = `/${repoPath}`;
|
|
30
|
+
return {
|
|
31
|
+
repo: parsed.toString().replace(/\/$/, ""),
|
|
32
|
+
ref,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return { repo: url };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const slashIndex = url.indexOf("/");
|
|
40
|
+
if (slashIndex < 0) {
|
|
41
|
+
return { repo: url };
|
|
42
|
+
}
|
|
43
|
+
const host = url.slice(0, slashIndex);
|
|
44
|
+
const pathWithMaybeRef = url.slice(slashIndex + 1);
|
|
45
|
+
const refSeparator = pathWithMaybeRef.indexOf("@");
|
|
46
|
+
if (refSeparator < 0) {
|
|
47
|
+
return { repo: url };
|
|
48
|
+
}
|
|
49
|
+
const repoPath = pathWithMaybeRef.slice(0, refSeparator);
|
|
50
|
+
const ref = pathWithMaybeRef.slice(refSeparator + 1);
|
|
51
|
+
if (!repoPath || !ref) {
|
|
52
|
+
return { repo: url };
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
repo: `${host}/${repoPath}`,
|
|
56
|
+
ref,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function parseGenericGitUrl(url) {
|
|
60
|
+
const { repo: repoWithoutRef, ref } = splitRef(url);
|
|
61
|
+
let repo = repoWithoutRef;
|
|
62
|
+
let host = "";
|
|
63
|
+
let path = "";
|
|
64
|
+
const scpLikeMatch = repoWithoutRef.match(/^git@([^:]+):(.+)$/);
|
|
65
|
+
if (scpLikeMatch) {
|
|
66
|
+
host = scpLikeMatch[1] ?? "";
|
|
67
|
+
path = scpLikeMatch[2] ?? "";
|
|
68
|
+
}
|
|
69
|
+
else if (repoWithoutRef.startsWith("https://") ||
|
|
70
|
+
repoWithoutRef.startsWith("http://") ||
|
|
71
|
+
repoWithoutRef.startsWith("ssh://")) {
|
|
72
|
+
try {
|
|
73
|
+
const parsed = new URL(repoWithoutRef);
|
|
74
|
+
host = parsed.hostname;
|
|
75
|
+
path = parsed.pathname.replace(/^\/+/, "");
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const slashIndex = repoWithoutRef.indexOf("/");
|
|
83
|
+
if (slashIndex < 0) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
host = repoWithoutRef.slice(0, slashIndex);
|
|
87
|
+
path = repoWithoutRef.slice(slashIndex + 1);
|
|
88
|
+
if (!host.includes(".") && host !== "localhost") {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
repo = `https://${repoWithoutRef}`;
|
|
92
|
+
}
|
|
93
|
+
const normalizedPath = path.replace(/\.git$/, "").replace(/^\/+/, "");
|
|
94
|
+
if (!host || !normalizedPath || normalizedPath.split("/").length < 2) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
type: "git",
|
|
99
|
+
repo,
|
|
100
|
+
host,
|
|
101
|
+
path: normalizedPath,
|
|
102
|
+
ref,
|
|
103
|
+
pinned: Boolean(ref),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
2
106
|
/**
|
|
3
107
|
* Parse any git URL (SSH or HTTPS) into a GitSource.
|
|
4
108
|
*/
|
|
5
109
|
export function parseGitUrl(source) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
110
|
+
const url = source.startsWith("git:") ? source.slice(4).trim() : source;
|
|
111
|
+
const split = splitRef(url);
|
|
112
|
+
const hostedCandidates = [split.ref ? `${split.repo}#${split.ref}` : undefined, url].filter((value) => Boolean(value));
|
|
113
|
+
for (const candidate of hostedCandidates) {
|
|
114
|
+
const info = hostedGitInfo.fromUrl(candidate);
|
|
115
|
+
if (info) {
|
|
116
|
+
if (split.ref && info.project?.includes("@")) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const useHttpsPrefix = !split.repo.startsWith("http://") &&
|
|
120
|
+
!split.repo.startsWith("https://") &&
|
|
121
|
+
!split.repo.startsWith("ssh://") &&
|
|
122
|
+
!split.repo.startsWith("git@");
|
|
123
|
+
return {
|
|
124
|
+
type: "git",
|
|
125
|
+
repo: useHttpsPrefix ? `https://${split.repo}` : split.repo,
|
|
126
|
+
host: info.domain || "",
|
|
127
|
+
path: `${info.user}/${info.project}`.replace(/\.git$/, ""),
|
|
128
|
+
ref: info.committish || split.ref || undefined,
|
|
129
|
+
pinned: Boolean(info.committish || split.ref),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
29
132
|
}
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
133
|
+
const httpsCandidates = [split.ref ? `https://${split.repo}#${split.ref}` : undefined, `https://${url}`].filter((value) => Boolean(value));
|
|
134
|
+
for (const candidate of httpsCandidates) {
|
|
135
|
+
const info = hostedGitInfo.fromUrl(candidate);
|
|
136
|
+
if (info) {
|
|
137
|
+
if (split.ref && info.project?.includes("@")) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
type: "git",
|
|
142
|
+
repo: `https://${split.repo}`,
|
|
143
|
+
host: info.domain || "",
|
|
144
|
+
path: `${info.user}/${info.project}`.replace(/\.git$/, ""),
|
|
145
|
+
ref: info.committish || split.ref || undefined,
|
|
146
|
+
pinned: Boolean(info.committish || split.ref),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
46
149
|
}
|
|
47
|
-
return
|
|
150
|
+
return parseGenericGitUrl(url);
|
|
48
151
|
}
|
|
49
152
|
//# sourceMappingURL=git.js.map
|
package/dist/utils/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAoB5C;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAoB;IAC7D,IAAI,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAEtE,yDAAyD;IACzD,IAAI,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;QACzF,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,oCAAoC;IACjE,CAAC;IAED,8CAA8C;IAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;QAC/C,IAAI,IAAI;YAAE,GAAG,GAAG,WAAW,GAAG,EAAE,CAAC,CAAC,8BAA8B;IACjE,CAAC;IAED,IAAI,IAAI,EAAE,CAAC;QACV,OAAO;YACN,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;YACvB,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;YACpC,GAAG,EAAE,IAAI,CAAC,UAAU,IAAI,SAAS;YACjC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;SAChC,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,cAAc,CAAC;IACpC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,YAAY,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC/D,mCAAmC;QACnC,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,OAAO,EAAE,CAAC;QAClF,OAAO;YACN,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;YACrE,GAAG;YACH,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC;SACpB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AAAA,CACZ","sourcesContent":["import hostedGitInfo from \"hosted-git-info\";\n\n/**\n * Parsed git URL information.\n */\nexport type GitSource = {\n\t/** Always \"git\" for git sources */\n\ttype: \"git\";\n\t/** Clone URL (always valid for git clone, without ref suffix) */\n\trepo: string;\n\t/** Git host domain (e.g., \"github.com\") */\n\thost: string;\n\t/** Repository path (e.g., \"user/repo\") */\n\tpath: string;\n\t/** Git ref (branch, tag, commit) if specified */\n\tref?: string;\n\t/** True if ref was specified (package won't be auto-updated) */\n\tpinned: boolean;\n};\n\n/**\n * Parse any git URL (SSH or HTTPS) into a GitSource.\n */\nexport function parseGitUrl(source: string): GitSource | null {\n\tlet url = source.startsWith(\"git:\") ? source.slice(4).trim() : source;\n\n\t// Try hosted-git-info, converting @ref to #ref if needed\n\tlet info = hostedGitInfo.fromUrl(url);\n\tconst lastAt = url.lastIndexOf(\"@\");\n\tif ((info?.project?.includes(\"@\") || !info) && lastAt > 0) {\n\t\tinfo = hostedGitInfo.fromUrl(`${url.slice(0, lastAt)}#${url.slice(lastAt + 1)}`) ?? info;\n\t\turl = url.slice(0, lastAt); // strip ref from url for repo field\n\t}\n\n\t// Try with https:// prefix for shorthand URLs\n\tif (!info) {\n\t\tinfo = hostedGitInfo.fromUrl(`https://${url}`);\n\t\tif (info) url = `https://${url}`; // make repo a valid clone URL\n\t}\n\n\tif (info) {\n\t\treturn {\n\t\t\ttype: \"git\",\n\t\t\trepo: url,\n\t\t\thost: info.domain || \"\",\n\t\t\tpath: `${info.user}/${info.project}`,\n\t\t\tref: info.committish || undefined,\n\t\t\tpinned: Boolean(info.committish),\n\t\t};\n\t}\n\n\t// Fallback for codeberg (not in hosted-git-info)\n\tconst normalized = url.replace(/^https?:\\/\\//, \"\").replace(/@[^/]*$/, \"\");\n\tconst codebergHost = \"codeberg.org\";\n\tif (normalized.startsWith(`${codebergHost}/`)) {\n\t\tconst ref = url.match(/@([^/]+)$/)?.[1];\n\t\tconst repoUrl = ref ? url.slice(0, url.lastIndexOf(\"@\")) : url;\n\t\t// Ensure repo is a valid clone URL\n\t\tconst cloneableRepo = repoUrl.startsWith(\"http\") ? repoUrl : `https://${repoUrl}`;\n\t\treturn {\n\t\t\ttype: \"git\",\n\t\t\trepo: cloneableRepo,\n\t\t\thost: codebergHost,\n\t\t\tpath: normalized.slice(codebergHost.length + 1).replace(/\\.git$/, \"\"),\n\t\t\tref,\n\t\t\tpinned: Boolean(ref),\n\t\t};\n\t}\n\n\treturn null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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","sourcesContent":["import hostedGitInfo from \"hosted-git-info\";\n\n/**\n * Parsed git URL information.\n */\nexport type GitSource = {\n\t/** Always \"git\" for git sources */\n\ttype: \"git\";\n\t/** Clone URL (always valid for git clone, without ref suffix) */\n\trepo: string;\n\t/** Git host domain (e.g., \"github.com\") */\n\thost: string;\n\t/** Repository path (e.g., \"user/repo\") */\n\tpath: string;\n\t/** Git ref (branch, tag, commit) if specified */\n\tref?: string;\n\t/** True if ref was specified (package won't be auto-updated) */\n\tpinned: boolean;\n};\n\nfunction splitRef(url: string): { repo: string; ref?: string } {\n\tconst scpLikeMatch = url.match(/^git@([^:]+):(.+)$/);\n\tif (scpLikeMatch) {\n\t\tconst pathWithMaybeRef = scpLikeMatch[2] ?? \"\";\n\t\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\n\t\tif (refSeparator < 0) return { repo: url };\n\t\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\n\t\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\n\t\tif (!repoPath || !ref) return { repo: url };\n\t\treturn {\n\t\t\trepo: `git@${scpLikeMatch[1] ?? \"\"}:${repoPath}`,\n\t\t\tref,\n\t\t};\n\t}\n\n\tif (url.includes(\"://\")) {\n\t\ttry {\n\t\t\tconst parsed = new URL(url);\n\t\t\tconst pathWithMaybeRef = parsed.pathname.replace(/^\\/+/, \"\");\n\t\t\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\n\t\t\tif (refSeparator < 0) return { repo: url };\n\t\t\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\n\t\t\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\n\t\t\tif (!repoPath || !ref) return { repo: url };\n\t\t\tparsed.pathname = `/${repoPath}`;\n\t\t\treturn {\n\t\t\t\trepo: parsed.toString().replace(/\\/$/, \"\"),\n\t\t\t\tref,\n\t\t\t};\n\t\t} catch {\n\t\t\treturn { repo: url };\n\t\t}\n\t}\n\n\tconst slashIndex = url.indexOf(\"/\");\n\tif (slashIndex < 0) {\n\t\treturn { repo: url };\n\t}\n\tconst host = url.slice(0, slashIndex);\n\tconst pathWithMaybeRef = url.slice(slashIndex + 1);\n\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\n\tif (refSeparator < 0) {\n\t\treturn { repo: url };\n\t}\n\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\n\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\n\tif (!repoPath || !ref) {\n\t\treturn { repo: url };\n\t}\n\treturn {\n\t\trepo: `${host}/${repoPath}`,\n\t\tref,\n\t};\n}\n\nfunction parseGenericGitUrl(url: string): GitSource | null {\n\tconst { repo: repoWithoutRef, ref } = splitRef(url);\n\tlet repo = repoWithoutRef;\n\tlet host = \"\";\n\tlet path = \"\";\n\n\tconst scpLikeMatch = repoWithoutRef.match(/^git@([^:]+):(.+)$/);\n\tif (scpLikeMatch) {\n\t\thost = scpLikeMatch[1] ?? \"\";\n\t\tpath = scpLikeMatch[2] ?? \"\";\n\t} else if (\n\t\trepoWithoutRef.startsWith(\"https://\") ||\n\t\trepoWithoutRef.startsWith(\"http://\") ||\n\t\trepoWithoutRef.startsWith(\"ssh://\")\n\t) {\n\t\ttry {\n\t\t\tconst parsed = new URL(repoWithoutRef);\n\t\t\thost = parsed.hostname;\n\t\t\tpath = parsed.pathname.replace(/^\\/+/, \"\");\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t} else {\n\t\tconst slashIndex = repoWithoutRef.indexOf(\"/\");\n\t\tif (slashIndex < 0) {\n\t\t\treturn null;\n\t\t}\n\t\thost = repoWithoutRef.slice(0, slashIndex);\n\t\tpath = repoWithoutRef.slice(slashIndex + 1);\n\t\tif (!host.includes(\".\") && host !== \"localhost\") {\n\t\t\treturn null;\n\t\t}\n\t\trepo = `https://${repoWithoutRef}`;\n\t}\n\n\tconst normalizedPath = path.replace(/\\.git$/, \"\").replace(/^\\/+/, \"\");\n\tif (!host || !normalizedPath || normalizedPath.split(\"/\").length < 2) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\ttype: \"git\",\n\t\trepo,\n\t\thost,\n\t\tpath: normalizedPath,\n\t\tref,\n\t\tpinned: Boolean(ref),\n\t};\n}\n\n/**\n * Parse any git URL (SSH or HTTPS) into a GitSource.\n */\nexport function parseGitUrl(source: string): GitSource | null {\n\tconst url = source.startsWith(\"git:\") ? source.slice(4).trim() : source;\n\tconst split = splitRef(url);\n\n\tconst hostedCandidates = [split.ref ? `${split.repo}#${split.ref}` : undefined, url].filter(\n\t\t(value): value is string => Boolean(value),\n\t);\n\tfor (const candidate of hostedCandidates) {\n\t\tconst info = hostedGitInfo.fromUrl(candidate);\n\t\tif (info) {\n\t\t\tif (split.ref && info.project?.includes(\"@\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst useHttpsPrefix =\n\t\t\t\t!split.repo.startsWith(\"http://\") &&\n\t\t\t\t!split.repo.startsWith(\"https://\") &&\n\t\t\t\t!split.repo.startsWith(\"ssh://\") &&\n\t\t\t\t!split.repo.startsWith(\"git@\");\n\t\t\treturn {\n\t\t\t\ttype: \"git\",\n\t\t\t\trepo: useHttpsPrefix ? `https://${split.repo}` : split.repo,\n\t\t\t\thost: info.domain || \"\",\n\t\t\t\tpath: `${info.user}/${info.project}`.replace(/\\.git$/, \"\"),\n\t\t\t\tref: info.committish || split.ref || undefined,\n\t\t\t\tpinned: Boolean(info.committish || split.ref),\n\t\t\t};\n\t\t}\n\t}\n\n\tconst httpsCandidates = [split.ref ? `https://${split.repo}#${split.ref}` : undefined, `https://${url}`].filter(\n\t\t(value): value is string => Boolean(value),\n\t);\n\tfor (const candidate of httpsCandidates) {\n\t\tconst info = hostedGitInfo.fromUrl(candidate);\n\t\tif (info) {\n\t\t\tif (split.ref && info.project?.includes(\"@\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\ttype: \"git\",\n\t\t\t\trepo: `https://${split.repo}`,\n\t\t\t\thost: info.domain || \"\",\n\t\t\t\tpath: `${info.user}/${info.project}`.replace(/\\.git$/, \"\"),\n\t\t\t\tref: info.committish || split.ref || undefined,\n\t\t\t\tpinned: Boolean(info.committish || split.ref),\n\t\t\t};\n\t\t}\n\t}\n\n\treturn parseGenericGitUrl(url);\n}\n"]}
|
package/docs/packages.md
CHANGED
|
@@ -66,6 +66,7 @@ ssh://git@github.com/user/repo@v1
|
|
|
66
66
|
|
|
67
67
|
- HTTPS and SSH URLs are both supported.
|
|
68
68
|
- SSH URLs use your configured SSH keys automatically (respects `~/.ssh/config`).
|
|
69
|
+
- For non-interactive runs (for example CI), you can set `GIT_TERMINAL_PROMPT=0` to disable credential prompts and set `GIT_SSH_COMMAND` (for example `ssh -o BatchMode=yes -o ConnectTimeout=5`) to fail fast.
|
|
69
70
|
- Raw `https://` URLs work without the `git:` prefix.
|
|
70
71
|
- Refs pin the package and skip `pi update`.
|
|
71
72
|
- Cloned to `~/.pi/agent/git/<host>/<path>` (global) or `.pi/git/<host>/<path>` (project).
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-custom-provider",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-custom-provider",
|
|
9
|
-
"version": "1.3.
|
|
9
|
+
"version": "1.3.4",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.52.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-with-deps",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-with-deps",
|
|
9
|
-
"version": "1.16.
|
|
9
|
+
"version": "1.16.4",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ms": "^2.1.3"
|
|
12
12
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mariozechner/pi-coding-agent",
|
|
3
|
-
"version": "0.52.
|
|
3
|
+
"version": "0.52.4",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@mariozechner/jiti": "^2.6.2",
|
|
43
|
-
"@mariozechner/pi-agent-core": "^0.52.
|
|
44
|
-
"@mariozechner/pi-ai": "^0.52.
|
|
45
|
-
"@mariozechner/pi-tui": "^0.52.
|
|
43
|
+
"@mariozechner/pi-agent-core": "^0.52.4",
|
|
44
|
+
"@mariozechner/pi-ai": "^0.52.4",
|
|
45
|
+
"@mariozechner/pi-tui": "^0.52.4",
|
|
46
46
|
"@silvia-odwyer/photon-node": "^0.3.4",
|
|
47
47
|
"chalk": "^5.5.0",
|
|
48
48
|
"cli-highlight": "^2.1.11",
|