@olorehq/olore 0.2.0 → 0.3.0

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