Skip to content

Commit dc7a0b6

Browse files
mickmickshclaude
andcommitted
chore: bump to v0.4.6 -- wire search command in TS CLI
Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent dc9ec59 commit dc7a0b6

5 files changed

Lines changed: 75 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to LAP (Lean API Platform) will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.4.6] - 2026-03-12
9+
10+
### Fixed
11+
- Wire up `search` command in TypeScript CLI (was missing from dispatcher)
12+
- TS CLI now supports: `lapsh search <query> [--tag] [--sort] [--limit] [--offset] [--json]`
13+
814
## [0.4.5] - 2026-03-12
915

1016
### Added

lap/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""LAP -- Lean API Platform. Token-efficient API specs for AI agents."""
22

3-
__version__ = "0.4.5"
3+
__version__ = "0.4.6"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "lapsh"
7-
version = "0.4.5"
7+
version = "0.4.6"
88
description = "Lean API Platform -- Token-efficient API specs for AI agents"
99
readme = "README.md"
1010
license = "Apache-2.0"

sdks/typescript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lap-platform/lapsh",
3-
"version": "0.4.5",
3+
"version": "0.4.6",
44
"description": "TypeScript SDK for LAP (Lean API Platform) -- Parse and work with LAP API specifications",
55
"main": "dist/src/index.js",
66
"types": "dist/src/index.d.ts",

sdks/typescript/src/cli.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { toLap } from './serializer';
3030
import { generateSkill } from './skill';
3131
import { enhanceSkill, hasClaudeCli } from './skill_llm';
3232
import { compile } from './compilers/index';
33+
import { LAPClient } from './client';
3334

3435
// ── Helpers ─────────────────────────────────────────────────────────
3536

@@ -69,6 +70,8 @@ Commands:
6970
skill-batch <dir> -o <outdir> Batch generate skills
7071
[--layer 1|2] [-v] Layer + verbose mode
7172
skill-install <name> [--dir <path>] Install skill from registry
73+
search <query> [--tag t] [--sort s] Search the LAP registry for APIs
74+
[--limit n] [--offset n] [--json] Pagination and JSON output
7275
7376
Environment:
7477
LAP_REGISTRY Registry URL (default: https://registry.lap.sh)`);
@@ -395,6 +398,66 @@ async function cmdSkillBatch(args: string[]): Promise<void> {
395398
info(`Generated ${success} skills, ${failed} failures`);
396399
}
397400

401+
async function cmdSearch(args: string[]): Promise<void> {
402+
const queryParts: string[] = [];
403+
let tag: string | undefined;
404+
let sort: string | undefined;
405+
let limit: number | undefined;
406+
let offset: number | undefined;
407+
let jsonOutput = false;
408+
409+
for (let i = 0; i < args.length; i++) {
410+
if (args[i] === '--tag' && i + 1 < args.length) { tag = args[++i]; }
411+
else if (args[i] === '--sort' && i + 1 < args.length) { sort = args[++i]; }
412+
else if (args[i] === '--limit' && i + 1 < args.length) { limit = parseInt(args[++i], 10); }
413+
else if (args[i] === '--offset' && i + 1 < args.length) { offset = parseInt(args[++i], 10); }
414+
else if (args[i] === '--json') { jsonOutput = true; }
415+
else if (!args[i].startsWith('-')) { queryParts.push(args[i]); }
416+
}
417+
418+
const query = queryParts.join(' ').trim();
419+
if (!query) error('Please provide a search query. Usage: lapsh search <query>');
420+
421+
const client = new LAPClient();
422+
const registryUrl = getRegistryUrl();
423+
const result = await client.search(registryUrl, query, { tag, sort, limit, offset });
424+
425+
if (jsonOutput) {
426+
console.log(JSON.stringify(result, null, 2));
427+
return;
428+
}
429+
430+
if (result.results.length === 0) {
431+
info(`No results for '${query}'.`);
432+
return;
433+
}
434+
435+
const rows = result.results.map(r => {
436+
const name = r.name || '';
437+
const desc = r.description || '';
438+
const ep = typeof r.endpoints === 'number' ? `${r.endpoints} endpoints` : '';
439+
const size = r.size;
440+
const lean = r.lean_size;
441+
const ratio = (typeof size === 'number' && typeof lean === 'number' && lean)
442+
? `${(size / lean).toFixed(1)}x compressed` : '';
443+
const skill = r.has_skill ? ' [skill]' : '';
444+
return { name, ep, ratio, desc, skill };
445+
});
446+
447+
const nameW = Math.max(...rows.map(r => r.name.length));
448+
const epW = Math.max(...rows.map(r => r.ep.length));
449+
const ratioW = Math.max(...rows.map(r => r.ratio.length));
450+
451+
for (const { name, ep, ratio, desc, skill } of rows) {
452+
console.log(` ${name.padEnd(nameW)} ${ep.padStart(epW)} ${ratio.padStart(ratioW)} ${desc}${skill}`);
453+
}
454+
455+
const shown = (result.offset || 0) + result.results.length;
456+
if (shown < result.total) {
457+
info(`Showing ${shown}/${result.total} results. Use --offset ${shown} for more.`);
458+
}
459+
}
460+
398461
async function cmdSkillInstall(args: string[]): Promise<void> {
399462
let name = '';
400463
let dir = '';
@@ -467,6 +530,9 @@ async function main(): Promise<void> {
467530
case 'skill-install':
468531
await cmdSkillInstall(args.slice(1));
469532
break;
533+
case 'search':
534+
await cmdSearch(args.slice(1));
535+
break;
470536
default:
471537
console.error(`Unknown command: ${command}`);
472538
usage();

0 commit comments

Comments
 (0)