akm-cli 0.7.5 → 0.8.0-rc.3
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/.github/CHANGELOG.md +1 -1
- package/dist/cli/parse-args.js +86 -0
- package/dist/cli.js +1023 -521
- package/dist/commands/agent-dispatch.js +107 -0
- package/dist/commands/agent-support.js +62 -0
- package/dist/commands/config-cli.js +68 -84
- package/dist/commands/consolidate.js +812 -0
- package/dist/commands/distill-promotion-policy.js +658 -0
- package/dist/commands/distill.js +218 -43
- package/dist/commands/eval-cases.js +40 -0
- package/dist/commands/events.js +2 -23
- package/dist/commands/graph.js +222 -0
- package/dist/commands/health.js +376 -0
- package/dist/commands/help/help-accept.md +9 -0
- package/dist/commands/help/help-improve.md +53 -0
- package/dist/commands/help/help-proposals.md +15 -0
- package/dist/commands/help/help-propose.md +17 -0
- package/dist/commands/help/help-reject.md +8 -0
- package/dist/commands/history.js +3 -30
- package/dist/commands/improve.js +1161 -0
- package/dist/commands/info.js +2 -2
- package/dist/commands/init.js +2 -2
- package/dist/commands/install-audit.js +5 -1
- package/dist/commands/installed-stashes.js +118 -138
- package/dist/commands/knowledge.js +133 -0
- package/dist/commands/lint/agent-linter.js +46 -0
- package/dist/commands/lint/base-linter.js +291 -0
- package/dist/commands/lint/command-linter.js +46 -0
- package/dist/commands/lint/default-linter.js +13 -0
- package/dist/commands/lint/index.js +145 -0
- package/dist/commands/lint/knowledge-linter.js +13 -0
- package/dist/commands/lint/memory-linter.js +58 -0
- package/dist/commands/lint/registry.js +33 -0
- package/dist/commands/lint/skill-linter.js +42 -0
- package/dist/commands/lint/task-linter.js +47 -0
- package/dist/commands/lint/types.js +1 -0
- package/dist/commands/lint/vault-key-rules.js +67 -0
- package/dist/commands/lint/workflow-linter.js +53 -0
- package/dist/commands/lint.js +1 -0
- package/dist/commands/proposal.js +8 -7
- package/dist/commands/propose.js +71 -28
- package/dist/commands/reflect.js +135 -35
- package/dist/commands/registry-search.js +2 -2
- package/dist/commands/remember.js +54 -0
- package/dist/commands/schema-repair.js +130 -0
- package/dist/commands/search.js +21 -5
- package/dist/commands/show.js +125 -20
- package/dist/commands/source-add.js +10 -10
- package/dist/commands/source-manage.js +11 -19
- package/dist/commands/tasks.js +385 -0
- package/dist/commands/url-checker.js +39 -0
- package/dist/commands/vault.js +168 -77
- package/dist/core/action-contributors.js +25 -0
- package/dist/core/asset-ref.js +4 -0
- package/dist/core/asset-registry.js +4 -16
- package/dist/core/asset-spec.js +10 -0
- package/dist/core/common.js +100 -0
- package/dist/core/concurrent.js +22 -0
- package/dist/core/config.js +233 -133
- package/dist/core/events.js +73 -126
- package/dist/core/frontmatter.js +0 -6
- package/dist/core/markdown.js +17 -0
- package/dist/core/memory-improve.js +678 -0
- package/dist/core/parse.js +155 -0
- package/dist/core/paths.js +101 -3
- package/dist/core/proposal-validators.js +61 -0
- package/dist/core/proposals.js +49 -38
- package/dist/core/state-db.js +731 -0
- package/dist/core/time.js +51 -0
- package/dist/core/warn.js +59 -1
- package/dist/indexer/db-search.js +52 -238
- package/dist/indexer/db.js +403 -54
- package/dist/indexer/ensure-index.js +61 -0
- package/dist/indexer/graph-boost.js +247 -94
- package/dist/indexer/graph-db.js +201 -0
- package/dist/indexer/graph-dedup.js +99 -0
- package/dist/indexer/graph-extraction.js +409 -76
- package/dist/indexer/index-context.js +10 -0
- package/dist/indexer/indexer.js +456 -290
- package/dist/indexer/llm-cache.js +47 -0
- package/dist/indexer/matchers.js +124 -160
- package/dist/indexer/memory-inference.js +63 -29
- package/dist/indexer/metadata-contributors.js +26 -0
- package/dist/indexer/metadata.js +196 -197
- package/dist/indexer/path-resolver.js +89 -0
- package/dist/indexer/ranking-contributors.js +204 -0
- package/dist/indexer/ranking.js +74 -0
- package/dist/indexer/search-hit-enrichers.js +22 -0
- package/dist/indexer/search-source.js +24 -9
- package/dist/indexer/semantic-status.js +2 -16
- package/dist/indexer/walker.js +25 -0
- package/dist/integrations/agent/builders.js +109 -0
- package/dist/integrations/agent/config.js +203 -3
- package/dist/integrations/agent/index.js +5 -2
- package/dist/integrations/agent/model-aliases.js +63 -0
- package/dist/integrations/agent/profiles.js +67 -5
- package/dist/integrations/agent/prompts.js +77 -72
- package/dist/integrations/agent/sdk-runner.js +120 -0
- package/dist/integrations/agent/spawn.js +93 -22
- package/dist/integrations/lockfile.js +10 -18
- package/dist/integrations/session-logs/index.js +65 -0
- package/dist/integrations/session-logs/providers/claude-code.js +56 -0
- package/dist/integrations/session-logs/providers/opencode.js +52 -0
- package/dist/integrations/session-logs/types.js +1 -0
- package/dist/llm/call-ai.js +74 -0
- package/dist/llm/client.js +61 -122
- package/dist/llm/feature-gate.js +27 -16
- package/dist/llm/graph-extract.js +297 -62
- package/dist/llm/memory-infer.js +49 -71
- package/dist/llm/metadata-enhance.js +39 -22
- package/dist/llm/prompts/graph-extract-user-prompt.md +12 -0
- package/dist/output/cli-hints-full.md +277 -0
- package/dist/output/cli-hints-short.md +65 -0
- package/dist/output/cli-hints.js +2 -318
- package/dist/output/renderers.js +220 -256
- package/dist/output/shapes.js +101 -93
- package/dist/output/text.js +256 -17
- package/dist/registry/providers/skills-sh.js +61 -49
- package/dist/registry/providers/static-index.js +44 -48
- package/dist/registry/resolve.js +8 -16
- package/dist/setup/setup.js +510 -11
- package/dist/sources/provider-factory.js +2 -1
- package/dist/sources/providers/filesystem.js +16 -23
- package/dist/sources/providers/git.js +4 -5
- package/dist/sources/providers/website.js +15 -22
- package/dist/sources/website-ingest.js +4 -0
- package/dist/tasks/backends/cron.js +200 -0
- package/dist/tasks/backends/exec-utils.js +25 -0
- package/dist/tasks/backends/index.js +32 -0
- package/dist/tasks/backends/launchd-template.xml +19 -0
- package/dist/tasks/backends/launchd.js +184 -0
- package/dist/tasks/backends/schtasks-template.xml +29 -0
- package/dist/tasks/backends/schtasks.js +212 -0
- package/dist/tasks/parser.js +198 -0
- package/dist/tasks/resolveAkmBin.js +84 -0
- package/dist/tasks/runner.js +432 -0
- package/dist/tasks/schedule.js +208 -0
- package/dist/tasks/schema.js +13 -0
- package/dist/tasks/validator.js +59 -0
- package/dist/wiki/index-template.md +12 -0
- package/dist/wiki/ingest-workflow-template.md +54 -0
- package/dist/wiki/log-template.md +8 -0
- package/dist/wiki/schema-template.md +61 -0
- package/dist/wiki/wiki-templates.js +12 -0
- package/dist/wiki/wiki.js +10 -61
- package/dist/workflows/authoring.js +5 -25
- package/dist/workflows/renderer.js +8 -3
- package/dist/workflows/runs.js +59 -91
- package/dist/workflows/validator.js +1 -1
- package/dist/workflows/workflow-template.md +24 -0
- package/docs/README.md +5 -2
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.8.0.md +43 -0
- package/package.json +3 -2
- package/dist/templates/wiki-templates.js +0 -100
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
1
|
import { fetchWithRetry } from "../../core/common";
|
|
4
|
-
import {
|
|
2
|
+
import { closeDatabase, getRegistryIndexCache, openDatabase, upsertRegistryIndexCache } from "../../indexer/db";
|
|
5
3
|
import { registerProvider } from "../factory";
|
|
6
4
|
// ── Constants ───────────────────────────────────────────────────────────────
|
|
7
5
|
/** Per-query cache TTL in milliseconds (15 minutes). */
|
|
8
6
|
const QUERY_CACHE_TTL_MS = 15 * 60 * 1000;
|
|
9
|
-
/** Maximum age before query cache is considered stale but still usable (1 day). */
|
|
10
|
-
const QUERY_CACHE_STALE_MS = 24 * 60 * 60 * 1000;
|
|
11
7
|
// ── Provider class ──────────────────────────────────────────────────────────
|
|
12
8
|
class SkillsShProvider {
|
|
13
9
|
type = "skills-sh";
|
|
@@ -89,13 +85,33 @@ class SkillsShProvider {
|
|
|
89
85
|
return ref.source === "github";
|
|
90
86
|
}
|
|
91
87
|
async fetchSkills(query, limit) {
|
|
92
|
-
//
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
// Build a stable DB cache key for this query
|
|
89
|
+
const dbCacheKey = this.queryDbCacheKey(query, limit);
|
|
90
|
+
// ── Step 1: Try DB cache (index.db) ───────────────────────────────────
|
|
91
|
+
let db;
|
|
92
|
+
let dbCacheResult;
|
|
93
|
+
try {
|
|
94
|
+
db = openDatabase();
|
|
95
|
+
dbCacheResult = getRegistryIndexCache(db, dbCacheKey, QUERY_CACHE_TTL_MS);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// index.db not available yet (pre-migration install or test env) — fall through
|
|
99
|
+
}
|
|
100
|
+
if (dbCacheResult) {
|
|
101
|
+
try {
|
|
102
|
+
const parsed = JSON.parse(dbCacheResult.indexJson);
|
|
103
|
+
if (Array.isArray(parsed)) {
|
|
104
|
+
const entries = parsed.filter(isValidSkillsEntry);
|
|
105
|
+
if (db)
|
|
106
|
+
closeDatabase(db);
|
|
107
|
+
return entries;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
/* corrupt DB entry — fall through */
|
|
112
|
+
}
|
|
97
113
|
}
|
|
98
|
-
// Fetch from API
|
|
114
|
+
// ── Step 2: Fetch from API ─────────────────────────────────────────────
|
|
99
115
|
const baseUrl = this.config.url.replace(/\/+$/, "");
|
|
100
116
|
const url = `${baseUrl}/api/search?q=${encodeURIComponent(query)}&limit=${limit}`;
|
|
101
117
|
try {
|
|
@@ -105,13 +121,40 @@ class SkillsShProvider {
|
|
|
105
121
|
}
|
|
106
122
|
const data = (await response.json());
|
|
107
123
|
const entries = parseSkillsResponse(data);
|
|
108
|
-
|
|
124
|
+
// Write to DB cache (primary)
|
|
125
|
+
if (db) {
|
|
126
|
+
try {
|
|
127
|
+
upsertRegistryIndexCache(db, dbCacheKey, JSON.stringify(entries));
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
/* best-effort */
|
|
131
|
+
}
|
|
132
|
+
closeDatabase(db);
|
|
133
|
+
}
|
|
109
134
|
return entries;
|
|
110
135
|
}
|
|
111
136
|
catch (err) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
137
|
+
if (db) {
|
|
138
|
+
try {
|
|
139
|
+
closeDatabase(db);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
/* ignore */
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Fetch failed — use stale DB cache if available
|
|
146
|
+
if (dbCacheResult) {
|
|
147
|
+
try {
|
|
148
|
+
const parsed = JSON.parse(dbCacheResult.indexJson);
|
|
149
|
+
if (Array.isArray(parsed)) {
|
|
150
|
+
const entries = parsed.filter(isValidSkillsEntry);
|
|
151
|
+
if (entries.length > 0)
|
|
152
|
+
return entries;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
/* ignore */
|
|
157
|
+
}
|
|
115
158
|
}
|
|
116
159
|
throw err;
|
|
117
160
|
}
|
|
@@ -167,9 +210,8 @@ class SkillsShProvider {
|
|
|
167
210
|
});
|
|
168
211
|
return hits.length > 0 ? hits : undefined;
|
|
169
212
|
}
|
|
170
|
-
// ──
|
|
171
|
-
|
|
172
|
-
const cacheDir = getRegistryIndexCacheDir();
|
|
213
|
+
// ── DB cache key ────────────────────────────────────────────────────────
|
|
214
|
+
queryDbCacheKey(query, limit) {
|
|
173
215
|
const hasher = new Bun.CryptoHasher("md5");
|
|
174
216
|
hasher.update(this.config.url);
|
|
175
217
|
hasher.update("\0");
|
|
@@ -177,33 +219,7 @@ class SkillsShProvider {
|
|
|
177
219
|
hasher.update("\0");
|
|
178
220
|
hasher.update(String(limit));
|
|
179
221
|
const hash = hasher.digest("hex");
|
|
180
|
-
return
|
|
181
|
-
}
|
|
182
|
-
readQueryCache(cachePath) {
|
|
183
|
-
try {
|
|
184
|
-
const stat = fs.statSync(cachePath);
|
|
185
|
-
const raw = JSON.parse(fs.readFileSync(cachePath, "utf8"));
|
|
186
|
-
if (!Array.isArray(raw))
|
|
187
|
-
return null;
|
|
188
|
-
const entries = raw.filter(isValidSkillsEntry);
|
|
189
|
-
return { entries, mtime: stat.mtimeMs };
|
|
190
|
-
}
|
|
191
|
-
catch {
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
writeQueryCache(cachePath, entries) {
|
|
196
|
-
try {
|
|
197
|
-
const dir = path.dirname(cachePath);
|
|
198
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
199
|
-
const tmpPath = `${cachePath}.tmp.${process.pid}`;
|
|
200
|
-
// 0o600: owner read/write only — cache may contain search terms tied to API keys
|
|
201
|
-
fs.writeFileSync(tmpPath, JSON.stringify(entries), { encoding: "utf8", mode: 0o600 });
|
|
202
|
-
fs.renameSync(tmpPath, cachePath);
|
|
203
|
-
}
|
|
204
|
-
catch {
|
|
205
|
-
// Best-effort caching
|
|
206
|
-
}
|
|
222
|
+
return `skills-sh:${hash}`;
|
|
207
223
|
}
|
|
208
224
|
}
|
|
209
225
|
// ── Self-register ───────────────────────────────────────────────────────────
|
|
@@ -226,7 +242,3 @@ function isValidSkillsEntry(entry) {
|
|
|
226
242
|
typeof obj.installs === "number" &&
|
|
227
243
|
typeof obj.source === "string");
|
|
228
244
|
}
|
|
229
|
-
// ── Utilities ───────────────────────────────────────────────────────────────
|
|
230
|
-
function isExpired(mtimeMs, ttlMs) {
|
|
231
|
-
return Date.now() - mtimeMs > ttlMs;
|
|
232
|
-
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
1
|
import { fetchWithRetry, jsonWithByteCap, toErrorMessage } from "../../core/common";
|
|
4
|
-
import {
|
|
2
|
+
import { closeDatabase, getRegistryIndexCache, openDatabase, upsertRegistryIndexCache } from "../../indexer/db";
|
|
5
3
|
import { asString } from "../../integrations/github";
|
|
6
4
|
import { registerProvider } from "../factory";
|
|
7
5
|
// ── Constants ───────────────────────────────────────────────────────────────
|
|
@@ -114,13 +112,25 @@ function assetHitToPreview(hit) {
|
|
|
114
112
|
registerProvider("static-index", (config) => new StaticIndexProvider(config));
|
|
115
113
|
// ── Index loading with cache ────────────────────────────────────────────────
|
|
116
114
|
async function loadIndex(entry) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
115
|
+
// ── Step 1: Try DB cache (index.db) ─────────────────────────────────────
|
|
116
|
+
let db;
|
|
117
|
+
let dbCacheResult;
|
|
118
|
+
try {
|
|
119
|
+
db = openDatabase();
|
|
120
|
+
dbCacheResult = getRegistryIndexCache(db, entry.url, CACHE_TTL_MS);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// index.db not available yet (pre-migration install or test env) — fall through
|
|
124
|
+
}
|
|
125
|
+
if (dbCacheResult) {
|
|
126
|
+
const index = parseRegistryIndex(JSON.parse(dbCacheResult.indexJson));
|
|
127
|
+
if (index) {
|
|
128
|
+
if (db)
|
|
129
|
+
closeDatabase(db);
|
|
130
|
+
return index;
|
|
131
|
+
}
|
|
122
132
|
}
|
|
123
|
-
//
|
|
133
|
+
// ── Step 2: Fetch fresh index from remote ────────────────────────────────
|
|
124
134
|
try {
|
|
125
135
|
const response = await fetchWithRetry(entry.url, undefined, { timeout: 10_000 });
|
|
126
136
|
if (!response.ok) {
|
|
@@ -131,54 +141,40 @@ async function loadIndex(entry) {
|
|
|
131
141
|
const data = await jsonWithByteCap(response, 50 * 1024 * 1024);
|
|
132
142
|
const index = parseRegistryIndex(data);
|
|
133
143
|
if (index) {
|
|
134
|
-
|
|
144
|
+
// Write to DB cache (primary)
|
|
145
|
+
if (db) {
|
|
146
|
+
try {
|
|
147
|
+
const etag = response.headers.get("etag") ?? undefined;
|
|
148
|
+
const lastModified = response.headers.get("last-modified") ?? undefined;
|
|
149
|
+
upsertRegistryIndexCache(db, entry.url, JSON.stringify(index), { etag, lastModified });
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
/* best-effort */
|
|
153
|
+
}
|
|
154
|
+
closeDatabase(db);
|
|
155
|
+
}
|
|
135
156
|
return index;
|
|
136
157
|
}
|
|
137
158
|
throw new Error("Invalid registry index format");
|
|
138
159
|
}
|
|
139
160
|
catch (err) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
161
|
+
if (db) {
|
|
162
|
+
try {
|
|
163
|
+
closeDatabase(db);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
/* ignore */
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Fetch failed — use stale DB cache if available
|
|
170
|
+
if (dbCacheResult) {
|
|
171
|
+
const index = parseRegistryIndex(JSON.parse(dbCacheResult.indexJson));
|
|
172
|
+
if (index)
|
|
173
|
+
return index;
|
|
143
174
|
}
|
|
144
175
|
throw err;
|
|
145
176
|
}
|
|
146
177
|
}
|
|
147
|
-
// ── Cache helpers (exported for reuse by other providers) ───────────────────
|
|
148
|
-
export function indexCachePath(url) {
|
|
149
|
-
const indexDir = getRegistryIndexCacheDir();
|
|
150
|
-
// Deterministic filename from URL
|
|
151
|
-
const slug = url
|
|
152
|
-
.replace(/[^a-zA-Z0-9]+/g, "-")
|
|
153
|
-
.replace(/^-+|-+$/g, "")
|
|
154
|
-
.slice(0, 120);
|
|
155
|
-
return path.join(indexDir, `${slug}.json`);
|
|
156
|
-
}
|
|
157
|
-
export function readCachedIndex(cachePath) {
|
|
158
|
-
try {
|
|
159
|
-
const stat = fs.statSync(cachePath);
|
|
160
|
-
const raw = JSON.parse(fs.readFileSync(cachePath, "utf8"));
|
|
161
|
-
const index = parseRegistryIndex(raw);
|
|
162
|
-
if (!index)
|
|
163
|
-
return null;
|
|
164
|
-
return { index, mtime: stat.mtimeMs };
|
|
165
|
-
}
|
|
166
|
-
catch {
|
|
167
|
-
return null;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
export function writeCachedIndex(cachePath, index) {
|
|
171
|
-
try {
|
|
172
|
-
const dir = path.dirname(cachePath);
|
|
173
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
174
|
-
const tmpPath = `${cachePath}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`;
|
|
175
|
-
fs.writeFileSync(tmpPath, JSON.stringify(index), "utf8");
|
|
176
|
-
fs.renameSync(tmpPath, cachePath);
|
|
177
|
-
}
|
|
178
|
-
catch {
|
|
179
|
-
// Best-effort caching — don't fail the search if we can't write
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
178
|
export function isCacheExpired(mtimeMs) {
|
|
183
179
|
return Date.now() - mtimeMs > CACHE_TTL_MS;
|
|
184
180
|
}
|
package/dist/registry/resolve.js
CHANGED
|
@@ -340,6 +340,7 @@ async function resolveNpmArtifact(parsed) {
|
|
|
340
340
|
}
|
|
341
341
|
async function resolveGithubArtifact(parsed) {
|
|
342
342
|
const gitUrl = `https://github.com/${encodeURIComponent(parsed.owner)}/${encodeURIComponent(parsed.repo)}.git`;
|
|
343
|
+
const repoBase = `${GITHUB_API_BASE}/repos/${encodeURIComponent(parsed.owner)}/${encodeURIComponent(parsed.repo)}`;
|
|
343
344
|
// Prefer git-backed installs so private GitHub repos work with the user's
|
|
344
345
|
// normal git credential helper rather than requiring API-specific auth.
|
|
345
346
|
const gitResolvedRevision = resolveGitRevisionFromRemote(gitUrl, parsed.requestedRef);
|
|
@@ -355,18 +356,18 @@ async function resolveGithubArtifact(parsed) {
|
|
|
355
356
|
}
|
|
356
357
|
const headers = githubHeaders();
|
|
357
358
|
if (parsed.requestedRef) {
|
|
358
|
-
const commit = await tryFetchJson(`${
|
|
359
|
+
const commit = await tryFetchJson(`${repoBase}/commits/${encodeURIComponent(parsed.requestedRef)}`, headers);
|
|
359
360
|
const resolvedRevision = asString(commit?.sha) ?? parsed.requestedRef;
|
|
360
361
|
return {
|
|
361
362
|
id: parsed.id,
|
|
362
363
|
source: parsed.source,
|
|
363
364
|
ref: parsed.ref,
|
|
364
|
-
artifactUrl: `${
|
|
365
|
+
artifactUrl: `${repoBase}/tarball/${encodeURIComponent(parsed.requestedRef)}`,
|
|
365
366
|
resolvedRevision,
|
|
366
367
|
resolvedVersion: parsed.requestedRef,
|
|
367
368
|
};
|
|
368
369
|
}
|
|
369
|
-
const latestRelease = await tryFetchJson(`${
|
|
370
|
+
const latestRelease = await tryFetchJson(`${repoBase}/releases/latest`, headers);
|
|
370
371
|
if (latestRelease) {
|
|
371
372
|
const tarballUrl = asString(latestRelease.tarball_url);
|
|
372
373
|
if (tarballUrl) {
|
|
@@ -380,17 +381,17 @@ async function resolveGithubArtifact(parsed) {
|
|
|
380
381
|
};
|
|
381
382
|
}
|
|
382
383
|
}
|
|
383
|
-
const repoMeta = await fetchJson(
|
|
384
|
+
const repoMeta = await fetchJson(repoBase, headers);
|
|
384
385
|
const defaultBranch = asString(repoMeta.default_branch);
|
|
385
386
|
if (!defaultBranch) {
|
|
386
387
|
throw new Error(`Unable to resolve default branch for ${parsed.owner}/${parsed.repo}.`);
|
|
387
388
|
}
|
|
388
|
-
const commit = await tryFetchJson(`${
|
|
389
|
+
const commit = await tryFetchJson(`${repoBase}/commits/${encodeURIComponent(defaultBranch)}`, headers);
|
|
389
390
|
return {
|
|
390
391
|
id: parsed.id,
|
|
391
392
|
source: parsed.source,
|
|
392
393
|
ref: parsed.ref,
|
|
393
|
-
artifactUrl: `${
|
|
394
|
+
artifactUrl: `${repoBase}/tarball/${encodeURIComponent(defaultBranch)}`,
|
|
394
395
|
resolvedVersion: defaultBranch,
|
|
395
396
|
resolvedRevision: asString(commit?.sha) ?? defaultBranch,
|
|
396
397
|
};
|
|
@@ -407,16 +408,7 @@ function resolveGitRevisionFromRemote(url, requestedRef) {
|
|
|
407
408
|
return firstLine?.split(/\s/)[0] || undefined;
|
|
408
409
|
}
|
|
409
410
|
async function resolveGitArtifact(parsed) {
|
|
410
|
-
|
|
411
|
-
const ref = parsed.requestedRef ?? "HEAD";
|
|
412
|
-
if (parsed.requestedRef)
|
|
413
|
-
validateGitRef(parsed.requestedRef);
|
|
414
|
-
const result = spawnSync("git", ["ls-remote", parsed.url, ref], { encoding: "utf8", timeout: 30_000 });
|
|
415
|
-
let resolvedRevision;
|
|
416
|
-
if (result.status === 0) {
|
|
417
|
-
const firstLine = result.stdout.trim().split(/\r?\n/)[0];
|
|
418
|
-
resolvedRevision = firstLine?.split(/\s/)[0] || undefined;
|
|
419
|
-
}
|
|
411
|
+
const resolvedRevision = resolveGitRevisionFromRemote(parsed.url, parsed.requestedRef);
|
|
420
412
|
return {
|
|
421
413
|
id: parsed.id,
|
|
422
414
|
source: parsed.source,
|