@socrates-ai/cli 0.1.8 → 0.1.10

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/runtime.mjs +60 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@socrates-ai/cli",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "type": "module",
5
5
  "description": "Launch Socrates as a local-first AI workspace from npm.",
6
6
  "bin": {
package/src/runtime.mjs CHANGED
@@ -66,6 +66,30 @@ export const runtimeCacheDir = (home) => path.join(home, "cache");
66
66
 
67
67
  export const runtimeDirFor = (home, version, platformArch) => path.join(runtimeRoot(home), version, platformArch);
68
68
 
69
+ export const releaseDownloadUrl = (repo, tag, assetName) => {
70
+ const [owner, name] = repo.split("/");
71
+ if (!owner || !name) {
72
+ throw new Error(`Invalid Socrates release repository: ${repo}. Expected owner/name.`);
73
+ }
74
+ return `https://github.com/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/releases/download/${encodeURIComponent(tag)}/${encodeURIComponent(assetName)}`;
75
+ };
76
+
77
+ export const releaseTagFromDownloadLocation = (location) => {
78
+ const match = String(location).match(/\/releases\/download\/([^/]+)\//);
79
+ return match ? decodeURIComponent(match[1]) : undefined;
80
+ };
81
+
82
+ export const directDownloadRelease = (repo, tag) => ({
83
+ tagName: tag,
84
+ assets: ["darwin-arm64", "darwin-x64", "win32-x64"]
85
+ .map((platformArch) => runtimeAssetName(platformArch))
86
+ .concat("SHA256SUMS")
87
+ .map((name) => ({
88
+ name,
89
+ url: releaseDownloadUrl(repo, tag, name),
90
+ })),
91
+ });
92
+
69
93
  export const availablePort = () =>
70
94
  new Promise((resolve, reject) => {
71
95
  const server = http.createServer();
@@ -226,6 +250,39 @@ export const selectAsset = (assets, name) => {
226
250
 
227
251
  const fetchRelease = async (version) => {
228
252
  const repo = process.env.SOCRATES_RELEASE_REPO ?? defaultRepo;
253
+ if (version) {
254
+ return directDownloadRelease(repo, version);
255
+ }
256
+
257
+ try {
258
+ const tagName = await fetchLatestReleaseTag(repo);
259
+ return directDownloadRelease(repo, tagName);
260
+ } catch (directError) {
261
+ return fetchReleaseFromApi(repo, undefined, directError);
262
+ }
263
+ };
264
+
265
+ const fetchLatestReleaseTag = async (repo) => {
266
+ const [owner, name] = repo.split("/");
267
+ if (!owner || !name) {
268
+ throw new Error(`Invalid Socrates release repository: ${repo}. Expected owner/name.`);
269
+ }
270
+ const response = await fetch(`https://github.com/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/releases/latest/download/SHA256SUMS`, {
271
+ method: "HEAD",
272
+ redirect: "manual",
273
+ headers: {
274
+ "user-agent": "@socrates-ai/cli",
275
+ },
276
+ });
277
+ const location = response.headers.get("location");
278
+ const tagName = location ? releaseTagFromDownloadLocation(location) : undefined;
279
+ if (tagName) {
280
+ return tagName;
281
+ }
282
+ throw new Error(`Could not resolve latest Socrates release tag: HTTP ${response.status}.`);
283
+ };
284
+
285
+ const fetchReleaseFromApi = async (repo, version, cause) => {
229
286
  const pathPart = version ? `releases/tags/${encodeURIComponent(version)}` : "releases/latest";
230
287
  const response = await fetch(`https://api.github.com/repos/${repo}/${pathPart}`, {
231
288
  headers: {
@@ -234,7 +291,9 @@ const fetchRelease = async (version) => {
234
291
  },
235
292
  });
236
293
  if (!response.ok) {
237
- throw new Error(`Could not fetch Socrates release metadata: HTTP ${response.status}.`);
294
+ throw new Error(
295
+ `Could not fetch Socrates release metadata: HTTP ${response.status}.${cause ? ` Direct release lookup also failed: ${cause.message}` : ""}`,
296
+ );
238
297
  }
239
298
  const json = await response.json();
240
299
  return {