@olorehq/olore 0.2.0 → 0.2.1

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.
Files changed (2) hide show
  1. package/dist/cli.js +274 -122
  2. 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 pc11 from "picocolors";
6
+ import pc12 from "picocolors";
7
7
 
8
8
  // src/commands/doctor.ts
9
9
  import pc from "picocolors";
@@ -844,7 +844,7 @@ async function inject(options) {
844
844
  import path7 from "path";
845
845
  import fs7 from "fs-extra";
846
846
  import ora from "ora";
847
- import pc4 from "picocolors";
847
+ import pc5 from "picocolors";
848
848
 
849
849
  // src/core/registry.ts
850
850
  var RegistryError = class extends Error {
@@ -923,6 +923,155 @@ async function resolveVersion(name, version2) {
923
923
  return versionInfo;
924
924
  }
925
925
 
926
+ // src/core/version-check.ts
927
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
928
+ import { homedir } from "os";
929
+ import { join } from "path";
930
+ import pc4 from "picocolors";
931
+
932
+ // package.json
933
+ var package_default = {
934
+ name: "@olorehq/olore",
935
+ version: "0.2.1",
936
+ description: "Universal documentation for any AI coding agent",
937
+ keywords: [
938
+ "ai",
939
+ "documentation",
940
+ "claude",
941
+ "codex",
942
+ "coding-assistant",
943
+ "context",
944
+ "llm"
945
+ ],
946
+ license: "MIT",
947
+ author: "olorehq",
948
+ repository: {
949
+ type: "git",
950
+ url: "git+https://github.com/olorehq/olore.git",
951
+ directory: "cli"
952
+ },
953
+ homepage: "https://www.olore.dev",
954
+ type: "module",
955
+ files: [
956
+ "dist"
957
+ ],
958
+ bin: {
959
+ olore: "dist/cli.js"
960
+ },
961
+ scripts: {
962
+ build: "tsup",
963
+ "build:bin": "bun build src/cli.ts --compile --outfile dist/olore",
964
+ "build:bin:all": "npm run build:bin:darwin-arm64 && npm run build:bin:darwin-x64 && npm run build:bin:linux-x64 && npm run build:bin:linux-arm64",
965
+ "build:bin:darwin-arm64": "bun build src/cli.ts --compile --target=bun-darwin-arm64 --outfile dist/olore-darwin-arm64",
966
+ "build:bin:darwin-x64": "bun build src/cli.ts --compile --target=bun-darwin-x64 --outfile dist/olore-darwin-x64",
967
+ "build:bin:linux-arm64": "bun build src/cli.ts --compile --target=bun-linux-arm64 --outfile dist/olore-linux-arm64",
968
+ "build:bin:linux-x64": "bun build src/cli.ts --compile --target=bun-linux-x64 --outfile dist/olore-linux-x64",
969
+ dev: "tsup --watch",
970
+ format: "prettier --write src/",
971
+ "format:check": "prettier --check src/",
972
+ lint: "eslint src/",
973
+ test: "vitest",
974
+ typecheck: "tsc --noEmit",
975
+ "generate-registry": "npx tsx scripts/generate-registry.ts"
976
+ },
977
+ dependencies: {
978
+ commander: "^12.1.0",
979
+ "fs-extra": "^11.3.3",
980
+ ora: "^9.0.0",
981
+ picocolors: "^1.1.1",
982
+ tar: "^7.4.3"
983
+ },
984
+ devDependencies: {
985
+ "@ianvs/prettier-plugin-sort-imports": "^4.7.0",
986
+ "@types/fs-extra": "^11.0.4",
987
+ "@types/node": "^22.10.7",
988
+ prettier: "^3.8.0",
989
+ "prettier-plugin-packagejson": "^2.5.22",
990
+ tsup: "^8.3.5",
991
+ typescript: "^5.7.3",
992
+ vitest: "^2.1.8"
993
+ },
994
+ engines: {
995
+ node: ">=18"
996
+ }
997
+ };
998
+
999
+ // src/core/version-check.ts
1000
+ var currentVersion = package_default.version;
1001
+ var NPM_REGISTRY = "https://registry.npmjs.org/@olorehq/olore";
1002
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
1003
+ var CACHE_DIR = join(homedir(), ".olore");
1004
+ var CACHE_FILE = join(CACHE_DIR, "version-check.json");
1005
+ var FETCH_TIMEOUT = 3e3;
1006
+ function readCache() {
1007
+ try {
1008
+ if (existsSync(CACHE_FILE)) {
1009
+ return JSON.parse(readFileSync(CACHE_FILE, "utf-8"));
1010
+ }
1011
+ } catch {
1012
+ }
1013
+ return null;
1014
+ }
1015
+ function writeCache(cache) {
1016
+ try {
1017
+ if (!existsSync(CACHE_DIR)) {
1018
+ mkdirSync(CACHE_DIR, { recursive: true });
1019
+ }
1020
+ writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
1021
+ } catch {
1022
+ }
1023
+ }
1024
+ async function fetchLatestVersion() {
1025
+ try {
1026
+ const controller = new AbortController();
1027
+ const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT);
1028
+ const response = await fetch(NPM_REGISTRY, {
1029
+ signal: controller.signal,
1030
+ headers: { Accept: "application/json" }
1031
+ });
1032
+ clearTimeout(timeoutId);
1033
+ if (!response.ok) return null;
1034
+ const data = await response.json();
1035
+ return data["dist-tags"]?.latest || null;
1036
+ } catch {
1037
+ return null;
1038
+ }
1039
+ }
1040
+ function compareVersions(current, latest) {
1041
+ const parseVersion = (v) => v.replace(/^v/, "").split(".").map((n) => parseInt(n, 10) || 0);
1042
+ const curr = parseVersion(current);
1043
+ const lat = parseVersion(latest);
1044
+ for (let i = 0; i < 3; i++) {
1045
+ if ((curr[i] || 0) < (lat[i] || 0)) return -1;
1046
+ if ((curr[i] || 0) > (lat[i] || 0)) return 1;
1047
+ }
1048
+ return 0;
1049
+ }
1050
+ async function checkForUpdates() {
1051
+ const cache = readCache();
1052
+ const now = Date.now();
1053
+ if (cache && now - cache.lastCheck < CHECK_INTERVAL_MS) {
1054
+ if (cache.latestVersion && compareVersions(currentVersion, cache.latestVersion) < 0) {
1055
+ printUpdateNotice(cache.latestVersion);
1056
+ }
1057
+ return;
1058
+ }
1059
+ const latestVersion = await fetchLatestVersion();
1060
+ writeCache({
1061
+ lastCheck: now,
1062
+ latestVersion
1063
+ });
1064
+ if (latestVersion && compareVersions(currentVersion, latestVersion) < 0) {
1065
+ printUpdateNotice(latestVersion);
1066
+ }
1067
+ }
1068
+ function printUpdateNotice(latestVersion) {
1069
+ console.log();
1070
+ console.log(
1071
+ pc4.yellow(`\u26A0\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}`) + pc4.gray(` \u2014 Run `) + pc4.cyan(`npm update -g @olorehq/olore`) + pc4.gray(` to update`)
1072
+ );
1073
+ }
1074
+
926
1075
  // src/commands/install.ts
927
1076
  async function installFromLocal(localPath) {
928
1077
  const fullPath = expandPath(localPath);
@@ -955,22 +1104,22 @@ async function installFromLocal(localPath) {
955
1104
  const nameMatch = skillContent.match(/^name:\s*(.+)$/m);
956
1105
  const skillMdName = nameMatch ? nameMatch[1].trim() : null;
957
1106
  if (skillMdName !== skillName) {
958
- console.log(pc4.yellow(`
1107
+ console.log(pc5.yellow(`
959
1108
  Warning: SKILL.md name mismatch`));
960
- console.log(pc4.gray(` Expected: ${skillName}`));
961
- console.log(pc4.gray(` Found: ${skillMdName || "(none)"}`));
962
- console.log(pc4.yellow(` Updating SKILL.md to fix...`));
1109
+ console.log(pc5.gray(` Expected: ${skillName}`));
1110
+ console.log(pc5.gray(` Found: ${skillMdName || "(none)"}`));
1111
+ console.log(pc5.yellow(` Updating SKILL.md to fix...`));
963
1112
  const updatedContent = skillMdName ? skillContent.replace(/^name:\s*.+$/m, `name: ${skillName}`) : skillContent.replace(/^---\n/, `---
964
1113
  name: ${skillName}
965
1114
  `);
966
1115
  await fs7.writeFile(skillPath, updatedContent);
967
1116
  }
968
- console.log(pc4.bold(`
1117
+ console.log(pc5.bold(`
969
1118
  Installing ${packageName}@${packageVersion} from local path...
970
1119
  `));
971
1120
  const agents = detectAgents();
972
1121
  if (agents.length === 0) {
973
- console.log(pc4.yellow("No agents detected. Creating directories anyway."));
1122
+ console.log(pc5.yellow("No agents detected. Creating directories anyway."));
974
1123
  }
975
1124
  const agentPaths = getAgentPaths();
976
1125
  const olorePath = getOlorePackagePath(packageName, packageVersion);
@@ -978,7 +1127,7 @@ Installing ${packageName}@${packageVersion} from local path...
978
1127
  await fs7.ensureDir(path7.dirname(olorePath));
979
1128
  await fs7.remove(olorePath);
980
1129
  await fs7.copy(fullPath, olorePath);
981
- spinner.succeed(`Copied to ${pc4.gray(olorePath)}`);
1130
+ spinner.succeed(`Copied to ${pc5.gray(olorePath)}`);
982
1131
  const linkSpinner = ora("Linking to agent directories...").start();
983
1132
  const linked = [];
984
1133
  for (const [agent, skillsDir] of Object.entries(agentPaths)) {
@@ -986,22 +1135,23 @@ Installing ${packageName}@${packageVersion} from local path...
986
1135
  await fs7.ensureDir(skillsDir);
987
1136
  await fs7.remove(targetDir);
988
1137
  await linkOrCopy(olorePath, targetDir);
989
- linked.push(`${pc4.green("\u2713")} ${agent} ${pc4.gray("\u2192")} ${pc4.gray(targetDir)}`);
1138
+ linked.push(`${pc5.green("\u2713")} ${agent} ${pc5.gray("\u2192")} ${pc5.gray(targetDir)}`);
990
1139
  }
991
1140
  linkSpinner.stop();
992
1141
  linked.forEach((line) => console.log(` ${line}`));
993
- console.log(pc4.gray(` \u2514\u2500 all linked to ${olorePath}`));
1142
+ console.log(pc5.gray(` \u2514\u2500 all linked to ${olorePath}`));
994
1143
  console.log("");
995
- console.log(pc4.green("Installation complete!"));
1144
+ console.log(pc5.green("Installation complete!"));
996
1145
  console.log("");
997
- console.log(pc4.gray("Skill is now available as:"));
998
- console.log(pc4.cyan(` /${skillName}`) + pc4.gray(" (Claude Code)"));
999
- console.log(pc4.cyan(` $${skillName}`) + pc4.gray(" (Codex)"));
1000
- console.log(pc4.cyan(` ${skillName}`) + pc4.gray(" (OpenCode)"));
1146
+ console.log(pc5.gray("Skill is now available as:"));
1147
+ console.log(pc5.cyan(` /${skillName}`) + pc5.gray(" (Claude Code)"));
1148
+ console.log(pc5.cyan(` $${skillName}`) + pc5.gray(" (Codex)"));
1149
+ console.log(pc5.cyan(` ${skillName}`) + pc5.gray(" (OpenCode)"));
1150
+ await checkForUpdates();
1001
1151
  }
1002
1152
  async function install(pkg, options) {
1003
1153
  if (options.force) {
1004
- console.log(pc4.cyan("\n\u2728 May the Skill be with you.\n"));
1154
+ console.log(pc5.cyan("\n\u2728 May the Skill be with you.\n"));
1005
1155
  }
1006
1156
  if (isLocalPath(pkg)) {
1007
1157
  await installFromLocal(pkg);
@@ -1047,7 +1197,7 @@ function findSimilarPackages(input, packages, maxResults = 3) {
1047
1197
  async function installFromRemote(pkg, optionsVersion) {
1048
1198
  const { name, version: specVersion } = parsePackageSpec(pkg);
1049
1199
  const requestedVersion = optionsVersion || specVersion || "latest";
1050
- console.log(pc4.bold(`
1200
+ console.log(pc5.bold(`
1051
1201
  Installing ${name}@${requestedVersion} from registry...
1052
1202
  `));
1053
1203
  const spinner = ora("Fetching package info...").start();
@@ -1059,32 +1209,32 @@ Installing ${name}@${requestedVersion} from registry...
1059
1209
  spinner.fail("Failed to resolve package");
1060
1210
  if (error instanceof RegistryError) {
1061
1211
  if (error.code === "NOT_FOUND") {
1062
- console.log(pc4.yellow(`
1212
+ console.log(pc5.yellow(`
1063
1213
  Package "${name}" not found in registry.`));
1064
1214
  try {
1065
1215
  const index = await fetchPackageIndex();
1066
1216
  const similar = findSimilarPackages(name, index.packages);
1067
1217
  if (similar.length > 0) {
1068
- console.log(pc4.bold("\nDid you mean?"));
1218
+ console.log(pc5.bold("\nDid you mean?"));
1069
1219
  for (const pkg2 of similar) {
1070
- console.log(` ${pc4.cyan(pkg2.name)} ${pc4.gray("-")} ${pc4.gray(pkg2.description)}`);
1220
+ console.log(` ${pc5.cyan(pkg2.name)} ${pc5.gray("-")} ${pc5.gray(pkg2.description)}`);
1071
1221
  }
1072
1222
  }
1073
1223
  } catch {
1074
1224
  }
1075
1225
  console.log(
1076
- pc4.gray("\nRun ") + pc4.cyan("olore search") + pc4.gray(" to see all available packages.")
1226
+ pc5.gray("\nRun ") + pc5.cyan("olore search") + pc5.gray(" to see all available packages.")
1077
1227
  );
1078
- console.log(pc4.gray("\nFor local packages, use a path:"));
1079
- console.log(pc4.cyan(` olore install ./vault/packages/${name}/<version>`));
1228
+ console.log(pc5.gray("\nFor local packages, use a path:"));
1229
+ console.log(pc5.cyan(` olore install ./vault/packages/${name}/<version>`));
1080
1230
  console.log("");
1081
1231
  } else if (error.code === "NETWORK_ERROR" || error.code === "TIMEOUT") {
1082
- console.log(pc4.red(`
1232
+ console.log(pc5.red(`
1083
1233
  Network error: ${error.message}`));
1084
- console.log(pc4.gray("Please check your internet connection and try again."));
1234
+ console.log(pc5.gray("Please check your internet connection and try again."));
1085
1235
  }
1086
1236
  } else {
1087
- console.log(pc4.red(`
1237
+ console.log(pc5.red(`
1088
1238
  Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1089
1239
  }
1090
1240
  process.exit(1);
@@ -1092,26 +1242,26 @@ Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1092
1242
  const skillName = `olore-${name}-${versionInfo.version}`;
1093
1243
  const agents = detectAgents();
1094
1244
  if (agents.length === 0) {
1095
- console.log(pc4.yellow("No agents detected. Creating directories anyway."));
1245
+ console.log(pc5.yellow("No agents detected. Creating directories anyway."));
1096
1246
  }
1097
1247
  const agentPaths = getAgentPaths();
1098
1248
  const olorePath = getOlorePackagePath(name, versionInfo.version);
1099
1249
  const downloadSpinner = ora("Downloading package...").start();
1100
1250
  try {
1101
1251
  await downloadAndInstall(versionInfo.downloadUrl, olorePath, versionInfo.integrity);
1102
- downloadSpinner.succeed(`Downloaded to ${pc4.gray(olorePath)}`);
1252
+ downloadSpinner.succeed(`Downloaded to ${pc5.gray(olorePath)}`);
1103
1253
  } catch (error) {
1104
1254
  downloadSpinner.fail("Download failed");
1105
1255
  if (error instanceof DownloadError) {
1106
1256
  if (error.code === "CHECKSUM_MISMATCH") {
1107
- console.log(pc4.red("\nChecksum verification failed!"));
1108
- console.log(pc4.gray("The downloaded package may be corrupted or tampered with."));
1257
+ console.log(pc5.red("\nChecksum verification failed!"));
1258
+ console.log(pc5.gray("The downloaded package may be corrupted or tampered with."));
1109
1259
  } else {
1110
- console.log(pc4.red(`
1260
+ console.log(pc5.red(`
1111
1261
  Download error: ${error.message}`));
1112
1262
  }
1113
1263
  } else {
1114
- console.log(pc4.red(`
1264
+ console.log(pc5.red(`
1115
1265
  Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1116
1266
  }
1117
1267
  process.exit(1);
@@ -1123,25 +1273,26 @@ Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1123
1273
  await fs7.ensureDir(skillsDir);
1124
1274
  await fs7.remove(targetDir);
1125
1275
  await linkOrCopy(olorePath, targetDir);
1126
- linked.push(`${pc4.green("\u2713")} ${agent} ${pc4.gray("\u2192")} ${pc4.gray(targetDir)}`);
1276
+ linked.push(`${pc5.green("\u2713")} ${agent} ${pc5.gray("\u2192")} ${pc5.gray(targetDir)}`);
1127
1277
  }
1128
1278
  linkSpinner.stop();
1129
1279
  linked.forEach((line) => console.log(` ${line}`));
1130
- console.log(pc4.gray(` \u2514\u2500 all linked to ${olorePath}`));
1280
+ console.log(pc5.gray(` \u2514\u2500 all linked to ${olorePath}`));
1131
1281
  console.log("");
1132
- console.log(pc4.green("Installation complete!"));
1282
+ console.log(pc5.green("Installation complete!"));
1133
1283
  console.log("");
1134
- console.log(pc4.gray("Skill is now available as:"));
1135
- console.log(pc4.cyan(` /${skillName}`) + pc4.gray(" (Claude Code)"));
1136
- console.log(pc4.cyan(` $${skillName}`) + pc4.gray(" (Codex)"));
1137
- console.log(pc4.cyan(` ${skillName}`) + pc4.gray(" (OpenCode)"));
1284
+ console.log(pc5.gray("Skill is now available as:"));
1285
+ console.log(pc5.cyan(` /${skillName}`) + pc5.gray(" (Claude Code)"));
1286
+ console.log(pc5.cyan(` $${skillName}`) + pc5.gray(" (Codex)"));
1287
+ console.log(pc5.cyan(` ${skillName}`) + pc5.gray(" (OpenCode)"));
1288
+ await checkForUpdates();
1138
1289
  }
1139
1290
 
1140
1291
  // src/commands/link.ts
1141
1292
  import path8 from "path";
1142
1293
  import fs8 from "fs-extra";
1143
1294
  import ora2 from "ora";
1144
- import pc5 from "picocolors";
1295
+ import pc6 from "picocolors";
1145
1296
  async function link(localPath) {
1146
1297
  const fullPath = expandPath(localPath);
1147
1298
  if (!await fs8.pathExists(fullPath)) {
@@ -1173,22 +1324,22 @@ async function link(localPath) {
1173
1324
  const nameMatch = skillContent.match(/^name:\s*(.+)$/m);
1174
1325
  const skillMdName = nameMatch ? nameMatch[1].trim() : null;
1175
1326
  if (skillMdName !== skillName) {
1176
- console.log(pc5.yellow(`
1327
+ console.log(pc6.yellow(`
1177
1328
  Warning: SKILL.md name mismatch`));
1178
- console.log(pc5.gray(` Expected: ${skillName}`));
1179
- console.log(pc5.gray(` Found: ${skillMdName || "(none)"}`));
1180
- console.log(pc5.yellow(` Updating SKILL.md to fix...`));
1329
+ console.log(pc6.gray(` Expected: ${skillName}`));
1330
+ console.log(pc6.gray(` Found: ${skillMdName || "(none)"}`));
1331
+ console.log(pc6.yellow(` Updating SKILL.md to fix...`));
1181
1332
  const updatedContent = skillMdName ? skillContent.replace(/^name:\s*.+$/m, `name: ${skillName}`) : skillContent.replace(/^---\n/, `---
1182
1333
  name: ${skillName}
1183
1334
  `);
1184
1335
  await fs8.writeFile(skillPath, updatedContent);
1185
1336
  }
1186
- console.log(pc5.bold(`
1337
+ console.log(pc6.bold(`
1187
1338
  Linking ${packageName}@${packageVersion}...
1188
1339
  `));
1189
1340
  const agents = detectAgents();
1190
1341
  if (agents.length === 0) {
1191
- console.log(pc5.yellow("No agents detected. Creating directories anyway."));
1342
+ console.log(pc6.yellow("No agents detected. Creating directories anyway."));
1192
1343
  }
1193
1344
  const agentPaths = getAgentPaths();
1194
1345
  const spinner = ora2(`${getLinkActionText()}...`).start();
@@ -1198,34 +1349,34 @@ Linking ${packageName}@${packageVersion}...
1198
1349
  await fs8.ensureDir(skillsDir);
1199
1350
  await fs8.remove(targetDir);
1200
1351
  await linkOrCopy(fullPath, targetDir);
1201
- linked.push(`${pc5.blue("\u26D3")} ${agent} ${pc5.gray("\u2192")} ${pc5.gray(targetDir)}`);
1352
+ linked.push(`${pc6.blue("\u26D3")} ${agent} ${pc6.gray("\u2192")} ${pc6.gray(targetDir)}`);
1202
1353
  }
1203
1354
  spinner.stop();
1204
1355
  linked.forEach((line) => console.log(` ${line}`));
1205
- console.log(pc5.gray(` \u2514\u2500 ${getLinkTypeText()} ${fullPath}`));
1356
+ console.log(pc6.gray(` \u2514\u2500 ${getLinkTypeText()} ${fullPath}`));
1206
1357
  console.log("");
1207
- console.log(pc5.blue("Link complete!"));
1358
+ console.log(pc6.blue("Link complete!"));
1208
1359
  console.log("");
1209
- console.log(pc5.gray("Skill is now available as:"));
1210
- console.log(pc5.cyan(` /${skillName}`) + pc5.gray(" (Claude Code)"));
1211
- console.log(pc5.cyan(` $${skillName}`) + pc5.gray(" (Codex)"));
1212
- console.log(pc5.cyan(` ${skillName}`) + pc5.gray(" (OpenCode)"));
1360
+ console.log(pc6.gray("Skill is now available as:"));
1361
+ console.log(pc6.cyan(` /${skillName}`) + pc6.gray(" (Claude Code)"));
1362
+ console.log(pc6.cyan(` $${skillName}`) + pc6.gray(" (Codex)"));
1363
+ console.log(pc6.cyan(` ${skillName}`) + pc6.gray(" (OpenCode)"));
1213
1364
  console.log("");
1214
- console.log(pc5.gray(`Development mode: ${getLinkTypeText()} source (bypasses ~/.olore).`));
1215
- console.log(pc5.gray("Changes to source are immediately visible."));
1365
+ console.log(pc6.gray(`Development mode: ${getLinkTypeText()} source (bypasses ~/.olore).`));
1366
+ console.log(pc6.gray("Changes to source are immediately visible."));
1216
1367
  console.log(
1217
- pc5.gray("Use ") + pc5.cyan("olore install") + pc5.gray(" for a stable copy in ~/.olore.")
1368
+ pc6.gray("Use ") + pc6.cyan("olore install") + pc6.gray(" for a stable copy in ~/.olore.")
1218
1369
  );
1219
1370
  }
1220
1371
 
1221
1372
  // src/commands/list.ts
1222
- import pc6 from "picocolors";
1373
+ import pc7 from "picocolors";
1223
1374
  async function list(options) {
1224
1375
  const packages = await getInstalledPackages();
1225
1376
  if (packages.length === 0) {
1226
- console.log(pc6.yellow("\nI find your lack of skills disturbing.\n"));
1227
- console.log(pc6.gray("No packages installed."));
1228
- console.log(`Run ${pc6.cyan("olore install <package>")} to install documentation.`);
1377
+ console.log(pc7.yellow("\nI find your lack of skills disturbing.\n"));
1378
+ console.log(pc7.gray("No packages installed."));
1379
+ console.log(`Run ${pc7.cyan("olore install <package>")} to install documentation.`);
1229
1380
  return;
1230
1381
  }
1231
1382
  if (options.json) {
@@ -1233,29 +1384,29 @@ async function list(options) {
1233
1384
  console.log(JSON.stringify({ packages, issueCount: issues2.length }, null, 2));
1234
1385
  return;
1235
1386
  }
1236
- console.log(pc6.bold("\nInstalled packages:\n"));
1387
+ console.log(pc7.bold("\nInstalled packages:\n"));
1237
1388
  console.log(
1238
- pc6.gray(
1389
+ pc7.gray(
1239
1390
  "PACKAGE".padEnd(25) + "VERSION".padEnd(12) + "TYPE".padEnd(10) + "FILES".padStart(8) + "SIZE".padStart(12)
1240
1391
  )
1241
1392
  );
1242
- console.log(pc6.gray("-".repeat(67)));
1393
+ console.log(pc7.gray("-".repeat(67)));
1243
1394
  for (const pkg of packages) {
1244
- const typeLabel = pkg.installType === "linked" ? pc6.blue("linked") : pkg.installType;
1395
+ const typeLabel = pkg.installType === "linked" ? pc7.blue("linked") : pkg.installType;
1245
1396
  console.log(
1246
1397
  pkg.name.padEnd(25) + pkg.version.padEnd(12) + typeLabel.padEnd(10) + String(pkg.files).padStart(8) + formatSize(pkg.size).padStart(12)
1247
1398
  );
1248
1399
  }
1249
- console.log(pc6.gray("-".repeat(67)));
1250
- console.log(pc6.gray(`Total: ${packages.length} packages`));
1400
+ console.log(pc7.gray("-".repeat(67)));
1401
+ console.log(pc7.gray(`Total: ${packages.length} packages`));
1251
1402
  console.log("");
1252
- console.log(pc6.gray("Types: installed = in ~/.olore, linked = dev symlink, copied = legacy"));
1403
+ console.log(pc7.gray("Types: installed = in ~/.olore, linked = dev symlink, copied = legacy"));
1253
1404
  const { issues } = await diagnose();
1254
1405
  if (issues.length > 0) {
1255
1406
  console.log("");
1256
1407
  console.log(
1257
- pc6.yellow(
1258
- `\u26A0 ${issues.length} issue${issues.length === 1 ? "" : "s"} detected. Run ${pc6.cyan("olore doctor")} for details.`
1408
+ pc7.yellow(
1409
+ `\u26A0 ${issues.length} issue${issues.length === 1 ? "" : "s"} detected. Run ${pc7.cyan("olore doctor")} for details.`
1259
1410
  )
1260
1411
  );
1261
1412
  }
@@ -1270,21 +1421,21 @@ function formatSize(bytes) {
1270
1421
  import path9 from "path";
1271
1422
  import fs9 from "fs-extra";
1272
1423
  import ora3 from "ora";
1273
- import pc7 from "picocolors";
1424
+ import pc8 from "picocolors";
1274
1425
  async function order66() {
1275
- console.log(pc7.red("\n\u26A0\uFE0F Execute Order 66?\n"));
1276
- console.log(pc7.yellow("This will remove ALL installed documentation packages."));
1426
+ console.log(pc8.red("\n\u26A0\uFE0F Execute Order 66?\n"));
1427
+ console.log(pc8.yellow("This will remove ALL installed documentation packages."));
1277
1428
  const packages = await getInstalledPackages();
1278
1429
  if (packages.length === 0) {
1279
- console.log(pc7.gray("\nNo packages to remove. The Jedi are already gone."));
1430
+ console.log(pc8.gray("\nNo packages to remove. The Jedi are already gone."));
1280
1431
  return;
1281
1432
  }
1282
- console.log(pc7.gray(`
1433
+ console.log(pc8.gray(`
1283
1434
  Packages to be removed: ${packages.length}`));
1284
1435
  for (const pkg of packages) {
1285
- console.log(pc7.gray(` - ${pkg.name}@${pkg.version}`));
1436
+ console.log(pc8.gray(` - ${pkg.name}@${pkg.version}`));
1286
1437
  }
1287
- console.log(pc7.red('\n"It will be done, my lord."\n'));
1438
+ console.log(pc8.red('\n"It will be done, my lord."\n'));
1288
1439
  const spinner = ora3("Executing Order 66...").start();
1289
1440
  let removedCount = 0;
1290
1441
  const agentPaths = getAgentPaths();
@@ -1305,21 +1456,21 @@ Packages to be removed: ${packages.length}`));
1305
1456
  removedCount++;
1306
1457
  }
1307
1458
  spinner.succeed(`Removed ${removedCount} packages`);
1308
- console.log(pc7.gray("\nThe Jedi have been eliminated."));
1459
+ console.log(pc8.gray("\nThe Jedi have been eliminated."));
1309
1460
  }
1310
1461
 
1311
1462
  // src/commands/prune.ts
1312
- import pc8 from "picocolors";
1463
+ import pc9 from "picocolors";
1313
1464
  async function prune(options) {
1314
1465
  if (!options.json) {
1315
- console.log(pc8.bold("\nScanning for issues...\n"));
1466
+ console.log(pc9.bold("\nScanning for issues...\n"));
1316
1467
  }
1317
1468
  const { issues } = await diagnose();
1318
1469
  if (issues.length === 0) {
1319
1470
  if (options.json) {
1320
1471
  console.log(JSON.stringify({ removed: [], failed: [] }, null, 2));
1321
1472
  } else {
1322
- console.log(pc8.green("Nothing to prune. Everything is clean."));
1473
+ console.log(pc9.green("Nothing to prune. Everything is clean."));
1323
1474
  }
1324
1475
  return;
1325
1476
  }
@@ -1329,14 +1480,14 @@ async function prune(options) {
1329
1480
  return;
1330
1481
  }
1331
1482
  console.log(
1332
- pc8.yellow(`Would remove ${issues.length} item${issues.length === 1 ? "" : "s"}:
1483
+ pc9.yellow(`Would remove ${issues.length} item${issues.length === 1 ? "" : "s"}:
1333
1484
  `)
1334
1485
  );
1335
1486
  for (const issue of issues) {
1336
1487
  console.log(` ${issueLabel(issue.type)} ${displayPath(issue.path)}`);
1337
1488
  }
1338
1489
  console.log(`
1339
- Run ${pc8.cyan("olore prune")} (without --dry-run) to remove them.`);
1490
+ Run ${pc9.cyan("olore prune")} (without --dry-run) to remove them.`);
1340
1491
  return;
1341
1492
  }
1342
1493
  const result = await pruneIssues(issues);
@@ -1350,7 +1501,7 @@ Run ${pc8.cyan("olore prune")} (without --dry-run) to remove them.`);
1350
1501
  for (const entry of result.removed) {
1351
1502
  totalFreed += entry.freedBytes;
1352
1503
  console.log(
1353
- ` ${pc8.green("\u2713")} ${displayPath(entry.issue.path)} (${issueLabel(entry.issue.type)})`
1504
+ ` ${pc9.green("\u2713")} ${displayPath(entry.issue.path)} (${issueLabel(entry.issue.type)})`
1354
1505
  );
1355
1506
  }
1356
1507
  if (totalFreed > 0) {
@@ -1361,12 +1512,12 @@ ${formatBytes(totalFreed)} freed.`);
1361
1512
  if (result.failed.length > 0) {
1362
1513
  console.log("");
1363
1514
  console.log(
1364
- pc8.red(
1515
+ pc9.red(
1365
1516
  `Failed to remove ${result.failed.length} item${result.failed.length === 1 ? "" : "s"}:`
1366
1517
  )
1367
1518
  );
1368
1519
  for (const entry of result.failed) {
1369
- console.log(` ${pc8.red("\u2717")} ${displayPath(entry.issue.path)}: ${entry.error}`);
1520
+ console.log(` ${pc9.red("\u2717")} ${displayPath(entry.issue.path)}: ${entry.error}`);
1370
1521
  }
1371
1522
  }
1372
1523
  }
@@ -1387,9 +1538,9 @@ function issueLabel(type) {
1387
1538
  import path10 from "path";
1388
1539
  import fs10 from "fs-extra";
1389
1540
  import ora4 from "ora";
1390
- import pc9 from "picocolors";
1541
+ import pc10 from "picocolors";
1391
1542
  async function remove(pkg) {
1392
- console.log(pc9.bold(`
1543
+ console.log(pc10.bold(`
1393
1544
  Removing ${pkg}...
1394
1545
  `));
1395
1546
  const packages = await getInstalledPackages();
@@ -1405,20 +1556,20 @@ Removing ${pkg}...
1405
1556
  return p.name === name;
1406
1557
  });
1407
1558
  if (matches.length === 0) {
1408
- console.error(pc9.red(`Package not found: ${pkg}`));
1559
+ console.error(pc10.red(`Package not found: ${pkg}`));
1409
1560
  console.log("\nInstalled packages:");
1410
1561
  for (const p of packages) {
1411
- console.log(` ${pc9.cyan(p.name)}@${p.version}`);
1562
+ console.log(` ${pc10.cyan(p.name)}@${p.version}`);
1412
1563
  }
1413
1564
  process.exit(1);
1414
1565
  }
1415
1566
  if (matches.length > 1 && !version2) {
1416
- console.error(pc9.red(`Multiple versions found for ${name}:`));
1567
+ console.error(pc10.red(`Multiple versions found for ${name}:`));
1417
1568
  for (const p of matches) {
1418
- console.log(` ${pc9.cyan(p.name)}@${p.version} (${p.installType})`);
1569
+ console.log(` ${pc10.cyan(p.name)}@${p.version} (${p.installType})`);
1419
1570
  }
1420
1571
  console.log(`
1421
- Specify version: ${pc9.cyan(`olore remove ${name}@<version>`)}`);
1572
+ Specify version: ${pc10.cyan(`olore remove ${name}@<version>`)}`);
1422
1573
  process.exit(1);
1423
1574
  }
1424
1575
  const found = matches[0];
@@ -1430,29 +1581,29 @@ Specify version: ${pc9.cyan(`olore remove ${name}@<version>`)}`);
1430
1581
  const skillPath = path10.join(basePath, skillName);
1431
1582
  if (await fs10.pathExists(skillPath)) {
1432
1583
  await fs10.remove(skillPath);
1433
- removed.push(`${pc9.green("\u2713")} ${agent}`);
1584
+ removed.push(`${pc10.green("\u2713")} ${agent}`);
1434
1585
  }
1435
1586
  }
1436
1587
  if (found.installType === "installed") {
1437
1588
  const olorePath = getOlorePackagePath(found.name, found.version);
1438
1589
  if (await fs10.pathExists(olorePath)) {
1439
1590
  await fs10.remove(olorePath);
1440
- removed.push(`${pc9.green("\u2713")} ~/.olore`);
1591
+ removed.push(`${pc10.green("\u2713")} ~/.olore`);
1441
1592
  }
1442
1593
  }
1443
1594
  spinner.stop();
1444
1595
  if (removed.length === 0) {
1445
- console.log(pc9.yellow("No files found to remove."));
1596
+ console.log(pc10.yellow("No files found to remove."));
1446
1597
  } else {
1447
1598
  removed.forEach((line) => console.log(` ${line}`));
1448
1599
  console.log("");
1449
- console.log(pc9.green(`Removed ${found.name}@${found.version}`));
1600
+ console.log(pc10.green(`Removed ${found.name}@${found.version}`));
1450
1601
  }
1451
1602
  }
1452
1603
 
1453
1604
  // src/commands/search.ts
1454
1605
  import ora5 from "ora";
1455
- import pc10 from "picocolors";
1606
+ import pc11 from "picocolors";
1456
1607
  async function search(query, options) {
1457
1608
  const spinner = ora5("Fetching package registry...").start();
1458
1609
  let packages;
@@ -1464,15 +1615,15 @@ async function search(query, options) {
1464
1615
  spinner.fail("Failed to fetch registry");
1465
1616
  if (error instanceof RegistryError) {
1466
1617
  if (error.code === "NETWORK_ERROR" || error.code === "TIMEOUT") {
1467
- console.log(pc10.red(`
1618
+ console.log(pc11.red(`
1468
1619
  Network error: ${error.message}`));
1469
- console.log(pc10.gray("Please check your internet connection and try again."));
1620
+ console.log(pc11.gray("Please check your internet connection and try again."));
1470
1621
  } else {
1471
- console.log(pc10.red(`
1622
+ console.log(pc11.red(`
1472
1623
  Error: ${error.message}`));
1473
1624
  }
1474
1625
  } else {
1475
- console.log(pc10.red(`
1626
+ console.log(pc11.red(`
1476
1627
  Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1477
1628
  }
1478
1629
  process.exit(1);
@@ -1486,10 +1637,10 @@ Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1486
1637
  }
1487
1638
  if (entries.length === 0) {
1488
1639
  if (query) {
1489
- console.log(pc10.yellow(`
1640
+ console.log(pc11.yellow(`
1490
1641
  No packages matching '${query}'`));
1491
1642
  } else {
1492
- console.log(pc10.yellow("\nNo packages available in the registry"));
1643
+ console.log(pc11.yellow("\nNo packages available in the registry"));
1493
1644
  }
1494
1645
  return;
1495
1646
  }
@@ -1516,26 +1667,27 @@ No packages matching '${query}'`));
1516
1667
  const colName = 20;
1517
1668
  const colDesc = 44;
1518
1669
  const colVersions = 12;
1519
- console.log(pc10.bold("\nAvailable packages:\n"));
1670
+ console.log(pc11.bold("\nAvailable packages:\n"));
1520
1671
  console.log(
1521
- pc10.gray(
1672
+ pc11.gray(
1522
1673
  "PACKAGE".padEnd(colName) + "DESCRIPTION".padEnd(colDesc) + "VERSIONS".padEnd(colVersions) + "INSTALLED"
1523
1674
  )
1524
1675
  );
1525
- console.log(pc10.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
1676
+ console.log(pc11.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
1526
1677
  for (const [name, info] of entries.sort(([a], [b]) => a.localeCompare(b))) {
1527
1678
  const desc = truncate(info.description, colDesc - 2);
1528
1679
  const versions = info.versions.join(", ");
1529
1680
  const installedVersion = installedVersions.get(name);
1530
- const status = installedVersion ? pc10.green(`\u2713 ${installedVersion}`) : "";
1681
+ const status = installedVersion ? pc11.green(`\u2713 ${installedVersion}`) : "";
1531
1682
  console.log(
1532
1683
  name.padEnd(colName) + desc.padEnd(colDesc) + versions.padEnd(colVersions) + status
1533
1684
  );
1534
1685
  }
1535
- console.log(pc10.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
1536
- console.log(pc10.gray(`${entries.length} package${entries.length === 1 ? "" : "s"} available`));
1686
+ console.log(pc11.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
1687
+ console.log(pc11.gray(`${entries.length} package${entries.length === 1 ? "" : "s"} available`));
1537
1688
  console.log(`
1538
- Install with: ${pc10.cyan("olore install <package>")}`);
1689
+ Install with: ${pc11.cyan("olore install <package>")}`);
1690
+ await checkForUpdates();
1539
1691
  }
1540
1692
  function truncate(str, maxLen) {
1541
1693
  if (str.length <= maxLen) return str;
@@ -1547,12 +1699,12 @@ var require2 = createRequire(import.meta.url);
1547
1699
  var { version } = require2("../package.json");
1548
1700
  var program = new Command();
1549
1701
  program.name("olore").description("Universal documentation for any AI coding agent").version(version).addHelpText("after", `
1550
- ${pc11.gray("May the Skill be with you.")}`);
1702
+ ${pc12.gray("May the Skill be with you.")}`);
1551
1703
  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) => {
1552
1704
  try {
1553
1705
  await init(options);
1554
1706
  } catch (error) {
1555
- console.error(pc11.red(`Error: ${error.message}`));
1707
+ console.error(pc12.red(`Error: ${error.message}`));
1556
1708
  process.exit(1);
1557
1709
  }
1558
1710
  });
@@ -1560,7 +1712,7 @@ program.command("install <package>").alias("i").description("Install a documenta
1560
1712
  try {
1561
1713
  await install(pkg, options);
1562
1714
  } catch (error) {
1563
- console.error(pc11.red(`Error: ${error.message}`));
1715
+ console.error(pc12.red(`Error: ${error.message}`));
1564
1716
  process.exit(1);
1565
1717
  }
1566
1718
  });
@@ -1568,7 +1720,7 @@ program.command("link <path>").description("Link a local package for development
1568
1720
  try {
1569
1721
  await link(localPath);
1570
1722
  } catch (error) {
1571
- console.error(pc11.red(`Error: ${error.message}`));
1723
+ console.error(pc12.red(`Error: ${error.message}`));
1572
1724
  process.exit(1);
1573
1725
  }
1574
1726
  });
@@ -1576,7 +1728,7 @@ program.command("list").alias("ls").description("List installed documentation pa
1576
1728
  try {
1577
1729
  await list(options);
1578
1730
  } catch (error) {
1579
- console.error(pc11.red(`Error: ${error.message}`));
1731
+ console.error(pc12.red(`Error: ${error.message}`));
1580
1732
  process.exit(1);
1581
1733
  }
1582
1734
  });
@@ -1584,7 +1736,7 @@ program.command("search [query]").description("Search available packages in the
1584
1736
  try {
1585
1737
  await search(query, options);
1586
1738
  } catch (error) {
1587
- console.error(pc11.red(`Error: ${error.message}`));
1739
+ console.error(pc12.red(`Error: ${error.message}`));
1588
1740
  process.exit(1);
1589
1741
  }
1590
1742
  });
@@ -1592,7 +1744,7 @@ program.command("remove <package>").alias("rm").description("Remove an installed
1592
1744
  try {
1593
1745
  await remove(pkg);
1594
1746
  } catch (error) {
1595
- console.error(pc11.red(`Error: ${error.message}`));
1747
+ console.error(pc12.red(`Error: ${error.message}`));
1596
1748
  process.exit(1);
1597
1749
  }
1598
1750
  });
@@ -1600,7 +1752,7 @@ program.command("doctor").description("Check for issues with installed packages"
1600
1752
  try {
1601
1753
  await doctor(options);
1602
1754
  } catch (error) {
1603
- console.error(pc11.red(`Error: ${error.message}`));
1755
+ console.error(pc12.red(`Error: ${error.message}`));
1604
1756
  process.exit(1);
1605
1757
  }
1606
1758
  });
@@ -1608,7 +1760,7 @@ program.command("prune").description("Remove dangling symlinks, orphaned package
1608
1760
  try {
1609
1761
  await prune(options);
1610
1762
  } catch (error) {
1611
- console.error(pc11.red(`Error: ${error.message}`));
1763
+ console.error(pc12.red(`Error: ${error.message}`));
1612
1764
  process.exit(1);
1613
1765
  }
1614
1766
  });
@@ -1616,7 +1768,7 @@ program.command("inject").description("Inject compressed doc indexes into AGENTS
1616
1768
  try {
1617
1769
  await inject(options);
1618
1770
  } catch (error) {
1619
- console.error(pc11.red(`Error: ${error.message}`));
1771
+ console.error(pc12.red(`Error: ${error.message}`));
1620
1772
  process.exit(1);
1621
1773
  }
1622
1774
  });
@@ -1624,7 +1776,7 @@ program.command("order66").description(false).action(async () => {
1624
1776
  try {
1625
1777
  await order66();
1626
1778
  } catch (error) {
1627
- console.error(pc11.red(`Error: ${error.message}`));
1779
+ console.error(pc12.red(`Error: ${error.message}`));
1628
1780
  process.exit(1);
1629
1781
  }
1630
1782
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olorehq/olore",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Universal documentation for any AI coding agent",
5
5
  "keywords": [
6
6
  "ai",