@olorehq/olore 0.1.3 → 0.1.5
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/dist/cli.js +165 -10
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { createRequire } from "module";
|
|
5
5
|
import { Command } from "commander";
|
|
6
|
-
import
|
|
6
|
+
import pc10 from "picocolors";
|
|
7
7
|
|
|
8
8
|
// src/commands/doctor.ts
|
|
9
9
|
import pc from "picocolors";
|
|
@@ -742,6 +742,22 @@ async function fetchWithTimeout(url, timeout = DOWNLOAD_TIMEOUT) {
|
|
|
742
742
|
clearTimeout(timeoutId);
|
|
743
743
|
}
|
|
744
744
|
}
|
|
745
|
+
async function fetchPackageIndex() {
|
|
746
|
+
const url = `${REGISTRY_URL}/index.json`;
|
|
747
|
+
const response = await fetchWithTimeout(url);
|
|
748
|
+
if (response.status === 404) {
|
|
749
|
+
throw new RegistryError("Registry not found", "NOT_FOUND");
|
|
750
|
+
}
|
|
751
|
+
if (!response.ok) {
|
|
752
|
+
throw new RegistryError(`Failed to fetch registry: ${response.status}`, "NETWORK_ERROR");
|
|
753
|
+
}
|
|
754
|
+
try {
|
|
755
|
+
const data = await response.json();
|
|
756
|
+
return data;
|
|
757
|
+
} catch {
|
|
758
|
+
throw new RegistryError("Invalid registry response", "INVALID_RESPONSE");
|
|
759
|
+
}
|
|
760
|
+
}
|
|
745
761
|
async function fetchPackageVersions(name) {
|
|
746
762
|
const url = `${REGISTRY_URL}/packages/${name}.json`;
|
|
747
763
|
const response = await fetchWithTimeout(url);
|
|
@@ -868,6 +884,31 @@ function parsePackageSpec(spec) {
|
|
|
868
884
|
}
|
|
869
885
|
return { name: spec };
|
|
870
886
|
}
|
|
887
|
+
function levenshtein(a, b) {
|
|
888
|
+
const m = a.length;
|
|
889
|
+
const n = b.length;
|
|
890
|
+
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
891
|
+
for (let i = 0; i <= m; i++) dp[i][0] = i;
|
|
892
|
+
for (let j = 0; j <= n; j++) dp[0][j] = j;
|
|
893
|
+
for (let i = 1; i <= m; i++) {
|
|
894
|
+
for (let j = 1; j <= n; j++) {
|
|
895
|
+
dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
return dp[m][n];
|
|
899
|
+
}
|
|
900
|
+
function findSimilarPackages(input, packages, maxResults = 3) {
|
|
901
|
+
const results = [];
|
|
902
|
+
for (const [name, entry] of Object.entries(packages)) {
|
|
903
|
+
const distance = levenshtein(input.toLowerCase(), name.toLowerCase());
|
|
904
|
+
const isSubstring = name.toLowerCase().includes(input.toLowerCase()) || input.toLowerCase().includes(name.toLowerCase());
|
|
905
|
+
if (distance <= 3 || isSubstring) {
|
|
906
|
+
results.push({ name, description: entry.description, distance });
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
results.sort((a, b) => a.distance - b.distance);
|
|
910
|
+
return results.slice(0, maxResults).map(({ name, description }) => ({ name, description }));
|
|
911
|
+
}
|
|
871
912
|
async function installFromRemote(pkg, optionsVersion) {
|
|
872
913
|
const { name, version: specVersion } = parsePackageSpec(pkg);
|
|
873
914
|
const requestedVersion = optionsVersion || specVersion || "latest";
|
|
@@ -885,6 +926,20 @@ Installing ${name}@${requestedVersion} from registry...
|
|
|
885
926
|
if (error.code === "NOT_FOUND") {
|
|
886
927
|
console.log(pc3.yellow(`
|
|
887
928
|
Package "${name}" not found in registry.`));
|
|
929
|
+
try {
|
|
930
|
+
const index = await fetchPackageIndex();
|
|
931
|
+
const similar = findSimilarPackages(name, index.packages);
|
|
932
|
+
if (similar.length > 0) {
|
|
933
|
+
console.log(pc3.bold("\nDid you mean?"));
|
|
934
|
+
for (const pkg2 of similar) {
|
|
935
|
+
console.log(` ${pc3.cyan(pkg2.name)} ${pc3.gray("-")} ${pc3.gray(pkg2.description)}`);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
} catch {
|
|
939
|
+
}
|
|
940
|
+
console.log(
|
|
941
|
+
pc3.gray("\nRun ") + pc3.cyan("olore search") + pc3.gray(" to see all available packages.")
|
|
942
|
+
);
|
|
888
943
|
console.log(pc3.gray("\nFor local packages, use a path:"));
|
|
889
944
|
console.log(pc3.cyan(` olore install ./vault/packages/${name}/<version>`));
|
|
890
945
|
console.log("");
|
|
@@ -1260,17 +1315,109 @@ Specify version: ${pc8.cyan(`olore remove ${name}@<version>`)}`);
|
|
|
1260
1315
|
}
|
|
1261
1316
|
}
|
|
1262
1317
|
|
|
1318
|
+
// src/commands/search.ts
|
|
1319
|
+
import ora5 from "ora";
|
|
1320
|
+
import pc9 from "picocolors";
|
|
1321
|
+
async function search(query, options) {
|
|
1322
|
+
const spinner = ora5("Fetching package registry...").start();
|
|
1323
|
+
let packages;
|
|
1324
|
+
try {
|
|
1325
|
+
const index = await fetchPackageIndex();
|
|
1326
|
+
packages = index.packages;
|
|
1327
|
+
spinner.stop();
|
|
1328
|
+
} catch (error) {
|
|
1329
|
+
spinner.fail("Failed to fetch registry");
|
|
1330
|
+
if (error instanceof RegistryError) {
|
|
1331
|
+
if (error.code === "NETWORK_ERROR" || error.code === "TIMEOUT") {
|
|
1332
|
+
console.log(pc9.red(`
|
|
1333
|
+
Network error: ${error.message}`));
|
|
1334
|
+
console.log(pc9.gray("Please check your internet connection and try again."));
|
|
1335
|
+
} else {
|
|
1336
|
+
console.log(pc9.red(`
|
|
1337
|
+
Error: ${error.message}`));
|
|
1338
|
+
}
|
|
1339
|
+
} else {
|
|
1340
|
+
console.log(pc9.red(`
|
|
1341
|
+
Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1342
|
+
}
|
|
1343
|
+
process.exit(1);
|
|
1344
|
+
}
|
|
1345
|
+
let entries = Object.entries(packages);
|
|
1346
|
+
if (query) {
|
|
1347
|
+
const q = query.toLowerCase();
|
|
1348
|
+
entries = entries.filter(
|
|
1349
|
+
([name, info]) => name.toLowerCase().includes(q) || info.description.toLowerCase().includes(q)
|
|
1350
|
+
);
|
|
1351
|
+
}
|
|
1352
|
+
if (entries.length === 0) {
|
|
1353
|
+
if (query) {
|
|
1354
|
+
console.log(pc9.yellow(`
|
|
1355
|
+
No packages matching '${query}'`));
|
|
1356
|
+
} else {
|
|
1357
|
+
console.log(pc9.yellow("\nNo packages available in the registry"));
|
|
1358
|
+
}
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
const installed = await getInstalledPackages();
|
|
1362
|
+
const installedNames = new Set(installed.map((p) => p.name));
|
|
1363
|
+
const installedVersions = /* @__PURE__ */ new Map();
|
|
1364
|
+
for (const pkg of installed) {
|
|
1365
|
+
installedVersions.set(pkg.name, pkg.version);
|
|
1366
|
+
}
|
|
1367
|
+
if (options.json) {
|
|
1368
|
+
const result = {
|
|
1369
|
+
packages: entries.map(([name, info]) => ({
|
|
1370
|
+
name,
|
|
1371
|
+
description: info.description,
|
|
1372
|
+
versions: info.versions,
|
|
1373
|
+
installed: installedNames.has(name),
|
|
1374
|
+
installedVersion: installedVersions.get(name) || null
|
|
1375
|
+
})),
|
|
1376
|
+
...query ? { query } : {}
|
|
1377
|
+
};
|
|
1378
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
const colName = 20;
|
|
1382
|
+
const colDesc = 44;
|
|
1383
|
+
const colVersions = 12;
|
|
1384
|
+
console.log(pc9.bold("\nAvailable packages:\n"));
|
|
1385
|
+
console.log(
|
|
1386
|
+
pc9.gray(
|
|
1387
|
+
"PACKAGE".padEnd(colName) + "DESCRIPTION".padEnd(colDesc) + "VERSIONS".padEnd(colVersions) + "INSTALLED"
|
|
1388
|
+
)
|
|
1389
|
+
);
|
|
1390
|
+
console.log(pc9.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
|
|
1391
|
+
for (const [name, info] of entries.sort(([a], [b]) => a.localeCompare(b))) {
|
|
1392
|
+
const desc = truncate(info.description, colDesc - 2);
|
|
1393
|
+
const versions = info.versions.join(", ");
|
|
1394
|
+
const installedVersion = installedVersions.get(name);
|
|
1395
|
+
const status = installedVersion ? pc9.green(`\u2713 ${installedVersion}`) : "";
|
|
1396
|
+
console.log(
|
|
1397
|
+
name.padEnd(colName) + desc.padEnd(colDesc) + versions.padEnd(colVersions) + status
|
|
1398
|
+
);
|
|
1399
|
+
}
|
|
1400
|
+
console.log(pc9.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
|
|
1401
|
+
console.log(pc9.gray(`${entries.length} package${entries.length === 1 ? "" : "s"} available`));
|
|
1402
|
+
console.log(`
|
|
1403
|
+
Install with: ${pc9.cyan("olore install <package>")}`);
|
|
1404
|
+
}
|
|
1405
|
+
function truncate(str, maxLen) {
|
|
1406
|
+
if (str.length <= maxLen) return str;
|
|
1407
|
+
return str.slice(0, maxLen - 1) + "\u2026";
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1263
1410
|
// src/cli.ts
|
|
1264
1411
|
var require2 = createRequire(import.meta.url);
|
|
1265
1412
|
var { version } = require2("../package.json");
|
|
1266
1413
|
var program = new Command();
|
|
1267
1414
|
program.name("olore").description("Universal documentation for any AI coding agent").version(version).addHelpText("after", `
|
|
1268
|
-
${
|
|
1415
|
+
${pc10.gray("May the Skill be with you.")}`);
|
|
1269
1416
|
program.command("init").description("Initialize a documentation package in the current directory").option("-n, --name <name>", "Package name (default: folder name)").option("-v, --version <version>", "Package version (default: latest)").option("-y, --yes", "Skip prompts, use defaults").action(async (options) => {
|
|
1270
1417
|
try {
|
|
1271
1418
|
await init(options);
|
|
1272
1419
|
} catch (error) {
|
|
1273
|
-
console.error(
|
|
1420
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1274
1421
|
process.exit(1);
|
|
1275
1422
|
}
|
|
1276
1423
|
});
|
|
@@ -1278,7 +1425,7 @@ program.command("install <package>").alias("i").description("Install a documenta
|
|
|
1278
1425
|
try {
|
|
1279
1426
|
await install(pkg, options);
|
|
1280
1427
|
} catch (error) {
|
|
1281
|
-
console.error(
|
|
1428
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1282
1429
|
process.exit(1);
|
|
1283
1430
|
}
|
|
1284
1431
|
});
|
|
@@ -1286,7 +1433,7 @@ program.command("link <path>").description("Link a local package for development
|
|
|
1286
1433
|
try {
|
|
1287
1434
|
await link(localPath);
|
|
1288
1435
|
} catch (error) {
|
|
1289
|
-
console.error(
|
|
1436
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1290
1437
|
process.exit(1);
|
|
1291
1438
|
}
|
|
1292
1439
|
});
|
|
@@ -1294,7 +1441,15 @@ program.command("list").alias("ls").description("List installed documentation pa
|
|
|
1294
1441
|
try {
|
|
1295
1442
|
await list(options);
|
|
1296
1443
|
} catch (error) {
|
|
1297
|
-
console.error(
|
|
1444
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1445
|
+
process.exit(1);
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
program.command("search [query]").description("Search available packages in the registry").option("--json", "Output as JSON").action(async (query, options) => {
|
|
1449
|
+
try {
|
|
1450
|
+
await search(query, options);
|
|
1451
|
+
} catch (error) {
|
|
1452
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1298
1453
|
process.exit(1);
|
|
1299
1454
|
}
|
|
1300
1455
|
});
|
|
@@ -1302,7 +1457,7 @@ program.command("remove <package>").alias("rm").description("Remove an installed
|
|
|
1302
1457
|
try {
|
|
1303
1458
|
await remove(pkg);
|
|
1304
1459
|
} catch (error) {
|
|
1305
|
-
console.error(
|
|
1460
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1306
1461
|
process.exit(1);
|
|
1307
1462
|
}
|
|
1308
1463
|
});
|
|
@@ -1310,7 +1465,7 @@ program.command("doctor").description("Check for issues with installed packages"
|
|
|
1310
1465
|
try {
|
|
1311
1466
|
await doctor(options);
|
|
1312
1467
|
} catch (error) {
|
|
1313
|
-
console.error(
|
|
1468
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1314
1469
|
process.exit(1);
|
|
1315
1470
|
}
|
|
1316
1471
|
});
|
|
@@ -1318,7 +1473,7 @@ program.command("prune").description("Remove dangling symlinks, orphaned package
|
|
|
1318
1473
|
try {
|
|
1319
1474
|
await prune(options);
|
|
1320
1475
|
} catch (error) {
|
|
1321
|
-
console.error(
|
|
1476
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1322
1477
|
process.exit(1);
|
|
1323
1478
|
}
|
|
1324
1479
|
});
|
|
@@ -1326,7 +1481,7 @@ program.command("order66").description(false).action(async () => {
|
|
|
1326
1481
|
try {
|
|
1327
1482
|
await order66();
|
|
1328
1483
|
} catch (error) {
|
|
1329
|
-
console.error(
|
|
1484
|
+
console.error(pc10.red(`Error: ${error.message}`));
|
|
1330
1485
|
process.exit(1);
|
|
1331
1486
|
}
|
|
1332
1487
|
});
|