@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.
@@ -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 GitHub API (no clone needed).
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 raw = execSync(
147
- `gh api "repos/${repo}/contents/registry/registry.json?ref=${REGISTRY_BASE_BRANCH}" --jq .content -H "Accept: application/vnd.github.v3+json"`,
148
- { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }
149
- );
150
- const content = Buffer.from(raw.trim(), 'base64').toString('utf8');
151
- const registry = JSON.parse(content);
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
5
5
  "type": "module",
6
6
  "bin": {