@ghl-ai/aw 0.1.17 → 0.1.19
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/commands/search.mjs +35 -9
- package/package.json +1 -1
package/commands/search.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// commands/search.mjs — Search local workspace + remote registry
|
|
2
2
|
|
|
3
|
-
import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
3
|
+
import { readFileSync, existsSync, readdirSync, statSync, mkdtempSync } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
5
6
|
import { execSync } from 'node:child_process';
|
|
6
7
|
import * as config from '../config.mjs';
|
|
7
8
|
import * as fmt from '../fmt.mjs';
|
|
@@ -139,24 +140,49 @@ function searchLocal(workspaceDir, query) {
|
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
/**
|
|
142
|
-
* Search remote registry.json via
|
|
143
|
+
* Search remote registry.json via git archive (single-file fetch, no clone).
|
|
144
|
+
* Falls back to gh API if git archive is not available.
|
|
143
145
|
*/
|
|
144
146
|
function searchRemote(repo, query) {
|
|
145
147
|
try {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
const repoUrl = repo.startsWith('http') ? repo : `https://github.com/${repo}.git`;
|
|
149
|
+
let content;
|
|
150
|
+
try {
|
|
151
|
+
// git archive fetches a single file from remote — no clone needed
|
|
152
|
+
content = execSync(
|
|
153
|
+
`git archive --remote="${repoUrl}" ${REGISTRY_BASE_BRANCH} registry/registry.json | tar -xO registry/registry.json`,
|
|
154
|
+
{ encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }
|
|
155
|
+
);
|
|
156
|
+
} catch {
|
|
157
|
+
// GitHub doesn't support git archive — fallback to gh API
|
|
158
|
+
try {
|
|
159
|
+
const raw = execSync(
|
|
160
|
+
`gh api "repos/${repo}/contents/registry/registry.json?ref=${REGISTRY_BASE_BRANCH}" --jq .content -H "Accept: application/vnd.github.v3+json"`,
|
|
161
|
+
{ encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }
|
|
162
|
+
);
|
|
163
|
+
content = Buffer.from(raw.trim(), 'base64').toString('utf8');
|
|
164
|
+
} catch {
|
|
165
|
+
// Last resort: sparse clone just registry.json
|
|
166
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'aw-search-'));
|
|
167
|
+
try {
|
|
168
|
+
execSync(`git clone --filter=blob:none --no-checkout "${repoUrl}" "${tempDir}"`, { stdio: 'pipe' });
|
|
169
|
+
execSync('git sparse-checkout init --cone', { cwd: tempDir, stdio: 'pipe' });
|
|
170
|
+
execSync('git sparse-checkout set --skip-checks "registry/registry.json"', { cwd: tempDir, stdio: 'pipe' });
|
|
171
|
+
execSync(`git checkout ${REGISTRY_BASE_BRANCH}`, { cwd: tempDir, stdio: 'pipe' });
|
|
172
|
+
content = readFileSync(join(tempDir, 'registry', 'registry.json'), 'utf8');
|
|
173
|
+
} finally {
|
|
174
|
+
try { execSync(`rm -rf "${tempDir}"`, { stdio: 'pipe' }); } catch {}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
152
178
|
|
|
179
|
+
const registry = JSON.parse(content);
|
|
153
180
|
const queryTerms = query.split(' ');
|
|
154
181
|
return (registry.entries || []).filter(e => {
|
|
155
182
|
const haystack = `${e.name || ''} ${e.slug || ''} ${e.description || ''} ${e.type || ''} ${e.scope || ''} ${e.scopeName || ''} ${e.path || ''}`.toLowerCase();
|
|
156
183
|
return queryTerms.every(q => haystack.includes(q));
|
|
157
184
|
});
|
|
158
185
|
} catch {
|
|
159
|
-
// gh not available, not authenticated, or registry.json doesn't exist
|
|
160
186
|
return [];
|
|
161
187
|
}
|
|
162
188
|
}
|