@olorehq/olore 0.1.5 → 0.2.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 (3) hide show
  1. package/README.md +74 -0
  2. package/dist/cli.js +312 -169
  3. package/package.json +3 -3
package/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # olore
2
+
3
+ ```
4
+ ██████╗ ██╗ ██████╗ ██████╗ ███████╗
5
+ ██╔═══██╗██║ ██╔═══██╗██╔══██╗██╔════╝
6
+ ██║ ██║██║ ██║ ██║██████╔╝█████╗
7
+ ██║ ██║██║ ██║ ██║██╔══██╗██╔══╝
8
+ ╚██████╔╝███████╗╚██████╔╝██║ ██║███████╗
9
+ ╚═════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
10
+ O(pen) Lore for AI Agents
11
+ ```
12
+
13
+ Documentation package manager for AI coding agents. Local-first. Offline-ready.
14
+
15
+ ## Quick Start
16
+
17
+ ```bash
18
+ npm install -g @olorehq/olore
19
+ olore install prisma
20
+ olore inject
21
+ ```
22
+
23
+ That's it. Your agent now has Prisma docs. No hallucinations.
24
+
25
+ ## Why olore?
26
+
27
+ Your AI coding agent makes decisions about which tools to invoke. Sometimes it decides wrong — it skips the tool, hallucinates an API, or calls it with bad arguments.
28
+
29
+ **Passive context beats skills.** Vercel's agentic coding eval showed agents with passive documentation context scored **100%** vs **53%** with tool-based retrieval. The difference: passive context is always there. The agent doesn't have to decide to look it up.
30
+
31
+ `olore inject` embeds a compact documentation index directly into your `AGENTS.md` / `CLAUDE.md`. The agent reads it automatically on every session — no invocation decision needed. No network. No retrieval pipeline.
32
+
33
+ - **Version-pinned** — same docs, every run, every machine
34
+ - **Offline** — works on planes, in CI, behind firewalls
35
+ - **Local-first** — docs live in your project, not on someone's server
36
+ - **Any agent** — Claude Code, Codex, OpenCode, anything that reads markdown
37
+
38
+ ## Available Packages
39
+
40
+ `prisma` · `nextjs` · `zod` · `drizzle` · `langchain` · `tanstack-query` · `claude-code` · `codex` · `opencode` · `cargo` · `agentskills`
41
+
42
+ More on the [registry](https://github.com/olorehq/olore). Contributions welcome.
43
+
44
+ ## Supported Agents
45
+
46
+ - **Claude Code** — injects into `CLAUDE.md`
47
+ - **Codex** — injects into `AGENTS.md`
48
+ - **OpenCode** — injects into `AGENTS.md`
49
+
50
+ ## Commands
51
+
52
+ | Command | Description |
53
+ |---|---|
54
+ | `olore install <pkg>` | Install a documentation package |
55
+ | `olore inject` | Inject doc indexes into AGENTS.md / CLAUDE.md |
56
+ | `olore inject --remove` | Remove injected content |
57
+ | `olore list` | List installed packages |
58
+ | `olore remove <pkg>` | Remove a package |
59
+ | `olore search` | Browse available packages |
60
+ | `olore doctor` | Diagnose issues |
61
+
62
+ ## Links
63
+
64
+ - [GitHub](https://github.com/olorehq/olore)
65
+ - [Website](https://www.olore.dev)
66
+ - [Contributing](https://github.com/olorehq/olore/blob/main/CONTRIBUTING.md)
67
+
68
+ ## License
69
+
70
+ MIT
71
+
72
+ ---
73
+
74
+ > *"May the Skill be with you."*
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 pc10 from "picocolors";
6
+ import pc11 from "picocolors";
7
7
 
8
8
  // src/commands/doctor.ts
9
9
  import pc from "picocolors";
@@ -705,11 +705,146 @@ Initialized olore package: `) + pc2.cyan(fullName));
705
705
  console.log("");
706
706
  }
707
707
 
708
- // src/commands/install.ts
708
+ // src/commands/inject.ts
709
+ import fs6 from "fs";
709
710
  import path6 from "path";
710
- import fs6 from "fs-extra";
711
- import ora from "ora";
712
711
  import pc3 from "picocolors";
712
+ var MARKER_START = "<!-- olore:start -->";
713
+ var MARKER_END = "<!-- olore:end -->";
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("")}`;
721
+ }
722
+ async function buildInjectedContent() {
723
+ 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) {
738
+ return { content: "", count: 0 };
739
+ }
740
+ const combined = [MARKER_START, COMPACT_HEADER, ...packageLines, MARKER_END].join("\n");
741
+ return { content: combined, count };
742
+ }
743
+ function smartMerge(filePath, injectedContent) {
744
+ if (!fs6.existsSync(filePath)) {
745
+ fs6.writeFileSync(filePath, injectedContent + "\n", "utf-8");
746
+ return;
747
+ }
748
+ const existing = fs6.readFileSync(filePath, "utf-8");
749
+ const startIdx = existing.indexOf(MARKER_START);
750
+ const endIdx = existing.indexOf(MARKER_END);
751
+ if (startIdx !== -1 && endIdx !== -1) {
752
+ const before = existing.slice(0, startIdx);
753
+ const after = existing.slice(endIdx + MARKER_END.length);
754
+ fs6.writeFileSync(filePath, before + injectedContent + after, "utf-8");
755
+ } else {
756
+ const separator = existing.endsWith("\n") ? "\n" : "\n\n";
757
+ fs6.writeFileSync(filePath, existing + separator + injectedContent + "\n", "utf-8");
758
+ }
759
+ }
760
+ function removeSection(filePath) {
761
+ if (!fs6.existsSync(filePath)) return false;
762
+ const content = fs6.readFileSync(filePath, "utf-8");
763
+ const startIdx = content.indexOf(MARKER_START);
764
+ const endIdx = content.indexOf(MARKER_END);
765
+ if (startIdx === -1 || endIdx === -1) return false;
766
+ const before = content.slice(0, startIdx);
767
+ const after = content.slice(endIdx + MARKER_END.length);
768
+ const result = (before + after).replace(/\n{3,}/g, "\n\n").trim();
769
+ if (result.length === 0) {
770
+ fs6.unlinkSync(filePath);
771
+ } else {
772
+ fs6.writeFileSync(filePath, result + "\n", "utf-8");
773
+ }
774
+ return true;
775
+ }
776
+ async function inject(options) {
777
+ const cwd = process.cwd();
778
+ if (options.remove) {
779
+ const filesRemoved = [];
780
+ for (const fileName of TARGET_FILES) {
781
+ const filePath = path6.join(cwd, fileName);
782
+ if (removeSection(filePath)) {
783
+ filesRemoved.push(fileName);
784
+ }
785
+ }
786
+ if (options.json) {
787
+ const result = {
788
+ packagesFound: 0,
789
+ packagesInjected: 0,
790
+ filesWritten: filesRemoved,
791
+ removed: true
792
+ };
793
+ console.log(JSON.stringify(result, null, 2));
794
+ return;
795
+ }
796
+ if (filesRemoved.length === 0) {
797
+ console.log(pc3.yellow("No olore sections found in project files."));
798
+ } else {
799
+ console.log(pc3.green(`Removed olore sections from: ${filesRemoved.join(", ")}`));
800
+ }
801
+ return;
802
+ }
803
+ const { content, count } = await buildInjectedContent();
804
+ if (count === 0) {
805
+ if (options.json) {
806
+ const result = {
807
+ packagesFound: 0,
808
+ packagesInjected: 0,
809
+ filesWritten: [],
810
+ removed: false
811
+ };
812
+ console.log(JSON.stringify(result, null, 2));
813
+ return;
814
+ }
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."));
817
+ return;
818
+ }
819
+ const filesWritten = [];
820
+ for (const fileName of TARGET_FILES) {
821
+ const filePath = path6.join(cwd, fileName);
822
+ smartMerge(filePath, content);
823
+ filesWritten.push(fileName);
824
+ }
825
+ if (options.json) {
826
+ const result = {
827
+ packagesFound: count,
828
+ packagesInjected: count,
829
+ filesWritten,
830
+ removed: false
831
+ };
832
+ console.log(JSON.stringify(result, null, 2));
833
+ return;
834
+ }
835
+ console.log(
836
+ pc3.green(
837
+ `Injected ${count} package${count === 1 ? "" : "s"} into: ${filesWritten.join(", ")}`
838
+ )
839
+ );
840
+ console.log(pc3.gray("Run olore inject --remove to clean up."));
841
+ }
842
+
843
+ // src/commands/install.ts
844
+ import path7 from "path";
845
+ import fs7 from "fs-extra";
846
+ import ora from "ora";
847
+ import pc4 from "picocolors";
713
848
 
714
849
  // src/core/registry.ts
715
850
  var RegistryError = class extends Error {
@@ -791,22 +926,22 @@ async function resolveVersion(name, version2) {
791
926
  // src/commands/install.ts
792
927
  async function installFromLocal(localPath) {
793
928
  const fullPath = expandPath(localPath);
794
- if (!await fs6.pathExists(fullPath)) {
929
+ if (!await fs7.pathExists(fullPath)) {
795
930
  throw new Error(`Path not found: ${fullPath}`);
796
931
  }
797
- const stat = await fs6.stat(fullPath);
932
+ const stat = await fs7.stat(fullPath);
798
933
  if (!stat.isDirectory()) {
799
934
  throw new Error(`Not a directory: ${fullPath}`);
800
935
  }
801
- const lockPath = path6.join(fullPath, "olore-lock.json");
802
- if (!await fs6.pathExists(lockPath)) {
936
+ const lockPath = path7.join(fullPath, "olore-lock.json");
937
+ if (!await fs7.pathExists(lockPath)) {
803
938
  throw new Error(`Missing olore-lock.json in ${fullPath}`);
804
939
  }
805
- const skillPath = path6.join(fullPath, "SKILL.md");
806
- if (!await fs6.pathExists(skillPath)) {
940
+ const skillPath = path7.join(fullPath, "SKILL.md");
941
+ if (!await fs7.pathExists(skillPath)) {
807
942
  throw new Error(`Missing SKILL.md in ${fullPath}. Run /generate-agent-skills first.`);
808
943
  }
809
- const lock = await fs6.readJson(lockPath);
944
+ const lock = await fs7.readJson(lockPath);
810
945
  const packageName = lock.name;
811
946
  const packageVersion = lock.version;
812
947
  if (!packageName) {
@@ -816,57 +951,57 @@ async function installFromLocal(localPath) {
816
951
  throw new Error(`Invalid olore-lock.json: missing "version" field`);
817
952
  }
818
953
  const skillName = `olore-${packageName}-${packageVersion}`;
819
- const skillContent = await fs6.readFile(skillPath, "utf-8");
954
+ const skillContent = await fs7.readFile(skillPath, "utf-8");
820
955
  const nameMatch = skillContent.match(/^name:\s*(.+)$/m);
821
956
  const skillMdName = nameMatch ? nameMatch[1].trim() : null;
822
957
  if (skillMdName !== skillName) {
823
- console.log(pc3.yellow(`
958
+ console.log(pc4.yellow(`
824
959
  Warning: SKILL.md name mismatch`));
825
- console.log(pc3.gray(` Expected: ${skillName}`));
826
- console.log(pc3.gray(` Found: ${skillMdName || "(none)"}`));
827
- console.log(pc3.yellow(` Updating SKILL.md to fix...`));
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...`));
828
963
  const updatedContent = skillMdName ? skillContent.replace(/^name:\s*.+$/m, `name: ${skillName}`) : skillContent.replace(/^---\n/, `---
829
964
  name: ${skillName}
830
965
  `);
831
- await fs6.writeFile(skillPath, updatedContent);
966
+ await fs7.writeFile(skillPath, updatedContent);
832
967
  }
833
- console.log(pc3.bold(`
968
+ console.log(pc4.bold(`
834
969
  Installing ${packageName}@${packageVersion} from local path...
835
970
  `));
836
971
  const agents = detectAgents();
837
972
  if (agents.length === 0) {
838
- console.log(pc3.yellow("No agents detected. Creating directories anyway."));
973
+ console.log(pc4.yellow("No agents detected. Creating directories anyway."));
839
974
  }
840
975
  const agentPaths = getAgentPaths();
841
976
  const olorePath = getOlorePackagePath(packageName, packageVersion);
842
977
  const spinner = ora("Copying to ~/.olore...").start();
843
- await fs6.ensureDir(path6.dirname(olorePath));
844
- await fs6.remove(olorePath);
845
- await fs6.copy(fullPath, olorePath);
846
- spinner.succeed(`Copied to ${pc3.gray(olorePath)}`);
978
+ await fs7.ensureDir(path7.dirname(olorePath));
979
+ await fs7.remove(olorePath);
980
+ await fs7.copy(fullPath, olorePath);
981
+ spinner.succeed(`Copied to ${pc4.gray(olorePath)}`);
847
982
  const linkSpinner = ora("Linking to agent directories...").start();
848
983
  const linked = [];
849
984
  for (const [agent, skillsDir] of Object.entries(agentPaths)) {
850
- const targetDir = path6.join(skillsDir, skillName);
851
- await fs6.ensureDir(skillsDir);
852
- await fs6.remove(targetDir);
985
+ const targetDir = path7.join(skillsDir, skillName);
986
+ await fs7.ensureDir(skillsDir);
987
+ await fs7.remove(targetDir);
853
988
  await linkOrCopy(olorePath, targetDir);
854
- linked.push(`${pc3.green("\u2713")} ${agent} ${pc3.gray("\u2192")} ${pc3.gray(targetDir)}`);
989
+ linked.push(`${pc4.green("\u2713")} ${agent} ${pc4.gray("\u2192")} ${pc4.gray(targetDir)}`);
855
990
  }
856
991
  linkSpinner.stop();
857
992
  linked.forEach((line) => console.log(` ${line}`));
858
- console.log(pc3.gray(` \u2514\u2500 all linked to ${olorePath}`));
993
+ console.log(pc4.gray(` \u2514\u2500 all linked to ${olorePath}`));
859
994
  console.log("");
860
- console.log(pc3.green("Installation complete!"));
995
+ console.log(pc4.green("Installation complete!"));
861
996
  console.log("");
862
- console.log(pc3.gray("Skill is now available as:"));
863
- console.log(pc3.cyan(` /${skillName}`) + pc3.gray(" (Claude Code)"));
864
- console.log(pc3.cyan(` $${skillName}`) + pc3.gray(" (Codex)"));
865
- console.log(pc3.cyan(` ${skillName}`) + pc3.gray(" (OpenCode)"));
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)"));
866
1001
  }
867
1002
  async function install(pkg, options) {
868
1003
  if (options.force) {
869
- console.log(pc3.cyan("\n\u2728 May the Skill be with you.\n"));
1004
+ console.log(pc4.cyan("\n\u2728 May the Skill be with you.\n"));
870
1005
  }
871
1006
  if (isLocalPath(pkg)) {
872
1007
  await installFromLocal(pkg);
@@ -912,7 +1047,7 @@ function findSimilarPackages(input, packages, maxResults = 3) {
912
1047
  async function installFromRemote(pkg, optionsVersion) {
913
1048
  const { name, version: specVersion } = parsePackageSpec(pkg);
914
1049
  const requestedVersion = optionsVersion || specVersion || "latest";
915
- console.log(pc3.bold(`
1050
+ console.log(pc4.bold(`
916
1051
  Installing ${name}@${requestedVersion} from registry...
917
1052
  `));
918
1053
  const spinner = ora("Fetching package info...").start();
@@ -924,32 +1059,32 @@ Installing ${name}@${requestedVersion} from registry...
924
1059
  spinner.fail("Failed to resolve package");
925
1060
  if (error instanceof RegistryError) {
926
1061
  if (error.code === "NOT_FOUND") {
927
- console.log(pc3.yellow(`
1062
+ console.log(pc4.yellow(`
928
1063
  Package "${name}" not found in registry.`));
929
1064
  try {
930
1065
  const index = await fetchPackageIndex();
931
1066
  const similar = findSimilarPackages(name, index.packages);
932
1067
  if (similar.length > 0) {
933
- console.log(pc3.bold("\nDid you mean?"));
1068
+ console.log(pc4.bold("\nDid you mean?"));
934
1069
  for (const pkg2 of similar) {
935
- console.log(` ${pc3.cyan(pkg2.name)} ${pc3.gray("-")} ${pc3.gray(pkg2.description)}`);
1070
+ console.log(` ${pc4.cyan(pkg2.name)} ${pc4.gray("-")} ${pc4.gray(pkg2.description)}`);
936
1071
  }
937
1072
  }
938
1073
  } catch {
939
1074
  }
940
1075
  console.log(
941
- pc3.gray("\nRun ") + pc3.cyan("olore search") + pc3.gray(" to see all available packages.")
1076
+ pc4.gray("\nRun ") + pc4.cyan("olore search") + pc4.gray(" to see all available packages.")
942
1077
  );
943
- console.log(pc3.gray("\nFor local packages, use a path:"));
944
- console.log(pc3.cyan(` olore install ./vault/packages/${name}/<version>`));
1078
+ console.log(pc4.gray("\nFor local packages, use a path:"));
1079
+ console.log(pc4.cyan(` olore install ./vault/packages/${name}/<version>`));
945
1080
  console.log("");
946
1081
  } else if (error.code === "NETWORK_ERROR" || error.code === "TIMEOUT") {
947
- console.log(pc3.red(`
1082
+ console.log(pc4.red(`
948
1083
  Network error: ${error.message}`));
949
- console.log(pc3.gray("Please check your internet connection and try again."));
1084
+ console.log(pc4.gray("Please check your internet connection and try again."));
950
1085
  }
951
1086
  } else {
952
- console.log(pc3.red(`
1087
+ console.log(pc4.red(`
953
1088
  Error: ${error instanceof Error ? error.message : "Unknown error"}`));
954
1089
  }
955
1090
  process.exit(1);
@@ -957,26 +1092,26 @@ Error: ${error instanceof Error ? error.message : "Unknown error"}`));
957
1092
  const skillName = `olore-${name}-${versionInfo.version}`;
958
1093
  const agents = detectAgents();
959
1094
  if (agents.length === 0) {
960
- console.log(pc3.yellow("No agents detected. Creating directories anyway."));
1095
+ console.log(pc4.yellow("No agents detected. Creating directories anyway."));
961
1096
  }
962
1097
  const agentPaths = getAgentPaths();
963
1098
  const olorePath = getOlorePackagePath(name, versionInfo.version);
964
1099
  const downloadSpinner = ora("Downloading package...").start();
965
1100
  try {
966
1101
  await downloadAndInstall(versionInfo.downloadUrl, olorePath, versionInfo.integrity);
967
- downloadSpinner.succeed(`Downloaded to ${pc3.gray(olorePath)}`);
1102
+ downloadSpinner.succeed(`Downloaded to ${pc4.gray(olorePath)}`);
968
1103
  } catch (error) {
969
1104
  downloadSpinner.fail("Download failed");
970
1105
  if (error instanceof DownloadError) {
971
1106
  if (error.code === "CHECKSUM_MISMATCH") {
972
- console.log(pc3.red("\nChecksum verification failed!"));
973
- console.log(pc3.gray("The downloaded package may be corrupted or tampered with."));
1107
+ console.log(pc4.red("\nChecksum verification failed!"));
1108
+ console.log(pc4.gray("The downloaded package may be corrupted or tampered with."));
974
1109
  } else {
975
- console.log(pc3.red(`
1110
+ console.log(pc4.red(`
976
1111
  Download error: ${error.message}`));
977
1112
  }
978
1113
  } else {
979
- console.log(pc3.red(`
1114
+ console.log(pc4.red(`
980
1115
  Error: ${error instanceof Error ? error.message : "Unknown error"}`));
981
1116
  }
982
1117
  process.exit(1);
@@ -984,47 +1119,47 @@ Error: ${error instanceof Error ? error.message : "Unknown error"}`));
984
1119
  const linkSpinner = ora("Linking to agent directories...").start();
985
1120
  const linked = [];
986
1121
  for (const [agent, skillsDir] of Object.entries(agentPaths)) {
987
- const targetDir = path6.join(skillsDir, skillName);
988
- await fs6.ensureDir(skillsDir);
989
- await fs6.remove(targetDir);
1122
+ const targetDir = path7.join(skillsDir, skillName);
1123
+ await fs7.ensureDir(skillsDir);
1124
+ await fs7.remove(targetDir);
990
1125
  await linkOrCopy(olorePath, targetDir);
991
- linked.push(`${pc3.green("\u2713")} ${agent} ${pc3.gray("\u2192")} ${pc3.gray(targetDir)}`);
1126
+ linked.push(`${pc4.green("\u2713")} ${agent} ${pc4.gray("\u2192")} ${pc4.gray(targetDir)}`);
992
1127
  }
993
1128
  linkSpinner.stop();
994
1129
  linked.forEach((line) => console.log(` ${line}`));
995
- console.log(pc3.gray(` \u2514\u2500 all linked to ${olorePath}`));
1130
+ console.log(pc4.gray(` \u2514\u2500 all linked to ${olorePath}`));
996
1131
  console.log("");
997
- console.log(pc3.green("Installation complete!"));
1132
+ console.log(pc4.green("Installation complete!"));
998
1133
  console.log("");
999
- console.log(pc3.gray("Skill is now available as:"));
1000
- console.log(pc3.cyan(` /${skillName}`) + pc3.gray(" (Claude Code)"));
1001
- console.log(pc3.cyan(` $${skillName}`) + pc3.gray(" (Codex)"));
1002
- console.log(pc3.cyan(` ${skillName}`) + pc3.gray(" (OpenCode)"));
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)"));
1003
1138
  }
1004
1139
 
1005
1140
  // src/commands/link.ts
1006
- import path7 from "path";
1007
- import fs7 from "fs-extra";
1141
+ import path8 from "path";
1142
+ import fs8 from "fs-extra";
1008
1143
  import ora2 from "ora";
1009
- import pc4 from "picocolors";
1144
+ import pc5 from "picocolors";
1010
1145
  async function link(localPath) {
1011
1146
  const fullPath = expandPath(localPath);
1012
- if (!await fs7.pathExists(fullPath)) {
1147
+ if (!await fs8.pathExists(fullPath)) {
1013
1148
  throw new Error(`Path not found: ${fullPath}`);
1014
1149
  }
1015
- const stat = await fs7.stat(fullPath);
1150
+ const stat = await fs8.stat(fullPath);
1016
1151
  if (!stat.isDirectory()) {
1017
1152
  throw new Error(`Not a directory: ${fullPath}`);
1018
1153
  }
1019
- const lockPath = path7.join(fullPath, "olore-lock.json");
1020
- if (!await fs7.pathExists(lockPath)) {
1154
+ const lockPath = path8.join(fullPath, "olore-lock.json");
1155
+ if (!await fs8.pathExists(lockPath)) {
1021
1156
  throw new Error(`Missing olore-lock.json in ${fullPath}`);
1022
1157
  }
1023
- const skillPath = path7.join(fullPath, "SKILL.md");
1024
- if (!await fs7.pathExists(skillPath)) {
1158
+ const skillPath = path8.join(fullPath, "SKILL.md");
1159
+ if (!await fs8.pathExists(skillPath)) {
1025
1160
  throw new Error(`Missing SKILL.md in ${fullPath}. Run /build-docs first.`);
1026
1161
  }
1027
- const lock = await fs7.readJson(lockPath);
1162
+ const lock = await fs8.readJson(lockPath);
1028
1163
  const packageName = lock.name;
1029
1164
  const packageVersion = lock.version;
1030
1165
  if (!packageName) {
@@ -1034,63 +1169,63 @@ async function link(localPath) {
1034
1169
  throw new Error(`Invalid olore-lock.json: missing "version" field`);
1035
1170
  }
1036
1171
  const skillName = `olore-${packageName}-${packageVersion}`;
1037
- const skillContent = await fs7.readFile(skillPath, "utf-8");
1172
+ const skillContent = await fs8.readFile(skillPath, "utf-8");
1038
1173
  const nameMatch = skillContent.match(/^name:\s*(.+)$/m);
1039
1174
  const skillMdName = nameMatch ? nameMatch[1].trim() : null;
1040
1175
  if (skillMdName !== skillName) {
1041
- console.log(pc4.yellow(`
1176
+ console.log(pc5.yellow(`
1042
1177
  Warning: SKILL.md name mismatch`));
1043
- console.log(pc4.gray(` Expected: ${skillName}`));
1044
- console.log(pc4.gray(` Found: ${skillMdName || "(none)"}`));
1045
- console.log(pc4.yellow(` Updating SKILL.md to fix...`));
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...`));
1046
1181
  const updatedContent = skillMdName ? skillContent.replace(/^name:\s*.+$/m, `name: ${skillName}`) : skillContent.replace(/^---\n/, `---
1047
1182
  name: ${skillName}
1048
1183
  `);
1049
- await fs7.writeFile(skillPath, updatedContent);
1184
+ await fs8.writeFile(skillPath, updatedContent);
1050
1185
  }
1051
- console.log(pc4.bold(`
1186
+ console.log(pc5.bold(`
1052
1187
  Linking ${packageName}@${packageVersion}...
1053
1188
  `));
1054
1189
  const agents = detectAgents();
1055
1190
  if (agents.length === 0) {
1056
- console.log(pc4.yellow("No agents detected. Creating directories anyway."));
1191
+ console.log(pc5.yellow("No agents detected. Creating directories anyway."));
1057
1192
  }
1058
1193
  const agentPaths = getAgentPaths();
1059
1194
  const spinner = ora2(`${getLinkActionText()}...`).start();
1060
1195
  const linked = [];
1061
1196
  for (const [agent, skillsDir] of Object.entries(agentPaths)) {
1062
- const targetDir = path7.join(skillsDir, skillName);
1063
- await fs7.ensureDir(skillsDir);
1064
- await fs7.remove(targetDir);
1197
+ const targetDir = path8.join(skillsDir, skillName);
1198
+ await fs8.ensureDir(skillsDir);
1199
+ await fs8.remove(targetDir);
1065
1200
  await linkOrCopy(fullPath, targetDir);
1066
- linked.push(`${pc4.blue("\u26D3")} ${agent} ${pc4.gray("\u2192")} ${pc4.gray(targetDir)}`);
1201
+ linked.push(`${pc5.blue("\u26D3")} ${agent} ${pc5.gray("\u2192")} ${pc5.gray(targetDir)}`);
1067
1202
  }
1068
1203
  spinner.stop();
1069
1204
  linked.forEach((line) => console.log(` ${line}`));
1070
- console.log(pc4.gray(` \u2514\u2500 ${getLinkTypeText()} ${fullPath}`));
1205
+ console.log(pc5.gray(` \u2514\u2500 ${getLinkTypeText()} ${fullPath}`));
1071
1206
  console.log("");
1072
- console.log(pc4.blue("Link complete!"));
1207
+ console.log(pc5.blue("Link complete!"));
1073
1208
  console.log("");
1074
- console.log(pc4.gray("Skill is now available as:"));
1075
- console.log(pc4.cyan(` /${skillName}`) + pc4.gray(" (Claude Code)"));
1076
- console.log(pc4.cyan(` $${skillName}`) + pc4.gray(" (Codex)"));
1077
- console.log(pc4.cyan(` ${skillName}`) + pc4.gray(" (OpenCode)"));
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)"));
1078
1213
  console.log("");
1079
- console.log(pc4.gray(`Development mode: ${getLinkTypeText()} source (bypasses ~/.olore).`));
1080
- console.log(pc4.gray("Changes to source are immediately visible."));
1214
+ console.log(pc5.gray(`Development mode: ${getLinkTypeText()} source (bypasses ~/.olore).`));
1215
+ console.log(pc5.gray("Changes to source are immediately visible."));
1081
1216
  console.log(
1082
- pc4.gray("Use ") + pc4.cyan("olore install") + pc4.gray(" for a stable copy in ~/.olore.")
1217
+ pc5.gray("Use ") + pc5.cyan("olore install") + pc5.gray(" for a stable copy in ~/.olore.")
1083
1218
  );
1084
1219
  }
1085
1220
 
1086
1221
  // src/commands/list.ts
1087
- import pc5 from "picocolors";
1222
+ import pc6 from "picocolors";
1088
1223
  async function list(options) {
1089
1224
  const packages = await getInstalledPackages();
1090
1225
  if (packages.length === 0) {
1091
- console.log(pc5.yellow("\nI find your lack of skills disturbing.\n"));
1092
- console.log(pc5.gray("No packages installed."));
1093
- console.log(`Run ${pc5.cyan("olore install <package>")} to install documentation.`);
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.`);
1094
1229
  return;
1095
1230
  }
1096
1231
  if (options.json) {
@@ -1098,29 +1233,29 @@ async function list(options) {
1098
1233
  console.log(JSON.stringify({ packages, issueCount: issues2.length }, null, 2));
1099
1234
  return;
1100
1235
  }
1101
- console.log(pc5.bold("\nInstalled packages:\n"));
1236
+ console.log(pc6.bold("\nInstalled packages:\n"));
1102
1237
  console.log(
1103
- pc5.gray(
1238
+ pc6.gray(
1104
1239
  "PACKAGE".padEnd(25) + "VERSION".padEnd(12) + "TYPE".padEnd(10) + "FILES".padStart(8) + "SIZE".padStart(12)
1105
1240
  )
1106
1241
  );
1107
- console.log(pc5.gray("-".repeat(67)));
1242
+ console.log(pc6.gray("-".repeat(67)));
1108
1243
  for (const pkg of packages) {
1109
- const typeLabel = pkg.installType === "linked" ? pc5.blue("linked") : pkg.installType;
1244
+ const typeLabel = pkg.installType === "linked" ? pc6.blue("linked") : pkg.installType;
1110
1245
  console.log(
1111
1246
  pkg.name.padEnd(25) + pkg.version.padEnd(12) + typeLabel.padEnd(10) + String(pkg.files).padStart(8) + formatSize(pkg.size).padStart(12)
1112
1247
  );
1113
1248
  }
1114
- console.log(pc5.gray("-".repeat(67)));
1115
- console.log(pc5.gray(`Total: ${packages.length} packages`));
1249
+ console.log(pc6.gray("-".repeat(67)));
1250
+ console.log(pc6.gray(`Total: ${packages.length} packages`));
1116
1251
  console.log("");
1117
- console.log(pc5.gray("Types: installed = in ~/.olore, linked = dev symlink, copied = legacy"));
1252
+ console.log(pc6.gray("Types: installed = in ~/.olore, linked = dev symlink, copied = legacy"));
1118
1253
  const { issues } = await diagnose();
1119
1254
  if (issues.length > 0) {
1120
1255
  console.log("");
1121
1256
  console.log(
1122
- pc5.yellow(
1123
- `\u26A0 ${issues.length} issue${issues.length === 1 ? "" : "s"} detected. Run ${pc5.cyan("olore doctor")} for details.`
1257
+ pc6.yellow(
1258
+ `\u26A0 ${issues.length} issue${issues.length === 1 ? "" : "s"} detected. Run ${pc6.cyan("olore doctor")} for details.`
1124
1259
  )
1125
1260
  );
1126
1261
  }
@@ -1132,59 +1267,59 @@ function formatSize(bytes) {
1132
1267
  }
1133
1268
 
1134
1269
  // src/commands/order66.ts
1135
- import path8 from "path";
1136
- import fs8 from "fs-extra";
1270
+ import path9 from "path";
1271
+ import fs9 from "fs-extra";
1137
1272
  import ora3 from "ora";
1138
- import pc6 from "picocolors";
1273
+ import pc7 from "picocolors";
1139
1274
  async function order66() {
1140
- console.log(pc6.red("\n\u26A0\uFE0F Execute Order 66?\n"));
1141
- console.log(pc6.yellow("This will remove ALL installed documentation packages."));
1275
+ console.log(pc7.red("\n\u26A0\uFE0F Execute Order 66?\n"));
1276
+ console.log(pc7.yellow("This will remove ALL installed documentation packages."));
1142
1277
  const packages = await getInstalledPackages();
1143
1278
  if (packages.length === 0) {
1144
- console.log(pc6.gray("\nNo packages to remove. The Jedi are already gone."));
1279
+ console.log(pc7.gray("\nNo packages to remove. The Jedi are already gone."));
1145
1280
  return;
1146
1281
  }
1147
- console.log(pc6.gray(`
1282
+ console.log(pc7.gray(`
1148
1283
  Packages to be removed: ${packages.length}`));
1149
1284
  for (const pkg of packages) {
1150
- console.log(pc6.gray(` - ${pkg.name}@${pkg.version}`));
1285
+ console.log(pc7.gray(` - ${pkg.name}@${pkg.version}`));
1151
1286
  }
1152
- console.log(pc6.red('\n"It will be done, my lord."\n'));
1287
+ console.log(pc7.red('\n"It will be done, my lord."\n'));
1153
1288
  const spinner = ora3("Executing Order 66...").start();
1154
1289
  let removedCount = 0;
1155
1290
  const agentPaths = getAgentPaths();
1156
1291
  for (const pkg of packages) {
1157
1292
  const skillName = `olore-${pkg.name}-${pkg.version}`;
1158
1293
  for (const [, basePath] of Object.entries(agentPaths)) {
1159
- const skillPath = path8.join(basePath, skillName);
1160
- if (await fs8.pathExists(skillPath)) {
1161
- await fs8.remove(skillPath);
1294
+ const skillPath = path9.join(basePath, skillName);
1295
+ if (await fs9.pathExists(skillPath)) {
1296
+ await fs9.remove(skillPath);
1162
1297
  }
1163
1298
  }
1164
1299
  if (pkg.installType === "installed") {
1165
1300
  const olorePath = getOlorePackagePath(pkg.name, pkg.version);
1166
- if (await fs8.pathExists(olorePath)) {
1167
- await fs8.remove(olorePath);
1301
+ if (await fs9.pathExists(olorePath)) {
1302
+ await fs9.remove(olorePath);
1168
1303
  }
1169
1304
  }
1170
1305
  removedCount++;
1171
1306
  }
1172
1307
  spinner.succeed(`Removed ${removedCount} packages`);
1173
- console.log(pc6.gray("\nThe Jedi have been eliminated."));
1308
+ console.log(pc7.gray("\nThe Jedi have been eliminated."));
1174
1309
  }
1175
1310
 
1176
1311
  // src/commands/prune.ts
1177
- import pc7 from "picocolors";
1312
+ import pc8 from "picocolors";
1178
1313
  async function prune(options) {
1179
1314
  if (!options.json) {
1180
- console.log(pc7.bold("\nScanning for issues...\n"));
1315
+ console.log(pc8.bold("\nScanning for issues...\n"));
1181
1316
  }
1182
1317
  const { issues } = await diagnose();
1183
1318
  if (issues.length === 0) {
1184
1319
  if (options.json) {
1185
1320
  console.log(JSON.stringify({ removed: [], failed: [] }, null, 2));
1186
1321
  } else {
1187
- console.log(pc7.green("Nothing to prune. Everything is clean."));
1322
+ console.log(pc8.green("Nothing to prune. Everything is clean."));
1188
1323
  }
1189
1324
  return;
1190
1325
  }
@@ -1194,14 +1329,14 @@ async function prune(options) {
1194
1329
  return;
1195
1330
  }
1196
1331
  console.log(
1197
- pc7.yellow(`Would remove ${issues.length} item${issues.length === 1 ? "" : "s"}:
1332
+ pc8.yellow(`Would remove ${issues.length} item${issues.length === 1 ? "" : "s"}:
1198
1333
  `)
1199
1334
  );
1200
1335
  for (const issue of issues) {
1201
1336
  console.log(` ${issueLabel(issue.type)} ${displayPath(issue.path)}`);
1202
1337
  }
1203
1338
  console.log(`
1204
- Run ${pc7.cyan("olore prune")} (without --dry-run) to remove them.`);
1339
+ Run ${pc8.cyan("olore prune")} (without --dry-run) to remove them.`);
1205
1340
  return;
1206
1341
  }
1207
1342
  const result = await pruneIssues(issues);
@@ -1215,7 +1350,7 @@ Run ${pc7.cyan("olore prune")} (without --dry-run) to remove them.`);
1215
1350
  for (const entry of result.removed) {
1216
1351
  totalFreed += entry.freedBytes;
1217
1352
  console.log(
1218
- ` ${pc7.green("\u2713")} ${displayPath(entry.issue.path)} (${issueLabel(entry.issue.type)})`
1353
+ ` ${pc8.green("\u2713")} ${displayPath(entry.issue.path)} (${issueLabel(entry.issue.type)})`
1219
1354
  );
1220
1355
  }
1221
1356
  if (totalFreed > 0) {
@@ -1226,12 +1361,12 @@ ${formatBytes(totalFreed)} freed.`);
1226
1361
  if (result.failed.length > 0) {
1227
1362
  console.log("");
1228
1363
  console.log(
1229
- pc7.red(
1364
+ pc8.red(
1230
1365
  `Failed to remove ${result.failed.length} item${result.failed.length === 1 ? "" : "s"}:`
1231
1366
  )
1232
1367
  );
1233
1368
  for (const entry of result.failed) {
1234
- console.log(` ${pc7.red("\u2717")} ${displayPath(entry.issue.path)}: ${entry.error}`);
1369
+ console.log(` ${pc8.red("\u2717")} ${displayPath(entry.issue.path)}: ${entry.error}`);
1235
1370
  }
1236
1371
  }
1237
1372
  }
@@ -1249,12 +1384,12 @@ function issueLabel(type) {
1249
1384
  }
1250
1385
 
1251
1386
  // src/commands/remove.ts
1252
- import path9 from "path";
1253
- import fs9 from "fs-extra";
1387
+ import path10 from "path";
1388
+ import fs10 from "fs-extra";
1254
1389
  import ora4 from "ora";
1255
- import pc8 from "picocolors";
1390
+ import pc9 from "picocolors";
1256
1391
  async function remove(pkg) {
1257
- console.log(pc8.bold(`
1392
+ console.log(pc9.bold(`
1258
1393
  Removing ${pkg}...
1259
1394
  `));
1260
1395
  const packages = await getInstalledPackages();
@@ -1270,20 +1405,20 @@ Removing ${pkg}...
1270
1405
  return p.name === name;
1271
1406
  });
1272
1407
  if (matches.length === 0) {
1273
- console.error(pc8.red(`Package not found: ${pkg}`));
1408
+ console.error(pc9.red(`Package not found: ${pkg}`));
1274
1409
  console.log("\nInstalled packages:");
1275
1410
  for (const p of packages) {
1276
- console.log(` ${pc8.cyan(p.name)}@${p.version}`);
1411
+ console.log(` ${pc9.cyan(p.name)}@${p.version}`);
1277
1412
  }
1278
1413
  process.exit(1);
1279
1414
  }
1280
1415
  if (matches.length > 1 && !version2) {
1281
- console.error(pc8.red(`Multiple versions found for ${name}:`));
1416
+ console.error(pc9.red(`Multiple versions found for ${name}:`));
1282
1417
  for (const p of matches) {
1283
- console.log(` ${pc8.cyan(p.name)}@${p.version} (${p.installType})`);
1418
+ console.log(` ${pc9.cyan(p.name)}@${p.version} (${p.installType})`);
1284
1419
  }
1285
1420
  console.log(`
1286
- Specify version: ${pc8.cyan(`olore remove ${name}@<version>`)}`);
1421
+ Specify version: ${pc9.cyan(`olore remove ${name}@<version>`)}`);
1287
1422
  process.exit(1);
1288
1423
  }
1289
1424
  const found = matches[0];
@@ -1292,32 +1427,32 @@ Specify version: ${pc8.cyan(`olore remove ${name}@<version>`)}`);
1292
1427
  const removed = [];
1293
1428
  const agentPaths = getAgentPaths();
1294
1429
  for (const [agent, basePath] of Object.entries(agentPaths)) {
1295
- const skillPath = path9.join(basePath, skillName);
1296
- if (await fs9.pathExists(skillPath)) {
1297
- await fs9.remove(skillPath);
1298
- removed.push(`${pc8.green("\u2713")} ${agent}`);
1430
+ const skillPath = path10.join(basePath, skillName);
1431
+ if (await fs10.pathExists(skillPath)) {
1432
+ await fs10.remove(skillPath);
1433
+ removed.push(`${pc9.green("\u2713")} ${agent}`);
1299
1434
  }
1300
1435
  }
1301
1436
  if (found.installType === "installed") {
1302
1437
  const olorePath = getOlorePackagePath(found.name, found.version);
1303
- if (await fs9.pathExists(olorePath)) {
1304
- await fs9.remove(olorePath);
1305
- removed.push(`${pc8.green("\u2713")} ~/.olore`);
1438
+ if (await fs10.pathExists(olorePath)) {
1439
+ await fs10.remove(olorePath);
1440
+ removed.push(`${pc9.green("\u2713")} ~/.olore`);
1306
1441
  }
1307
1442
  }
1308
1443
  spinner.stop();
1309
1444
  if (removed.length === 0) {
1310
- console.log(pc8.yellow("No files found to remove."));
1445
+ console.log(pc9.yellow("No files found to remove."));
1311
1446
  } else {
1312
1447
  removed.forEach((line) => console.log(` ${line}`));
1313
1448
  console.log("");
1314
- console.log(pc8.green(`Removed ${found.name}@${found.version}`));
1449
+ console.log(pc9.green(`Removed ${found.name}@${found.version}`));
1315
1450
  }
1316
1451
  }
1317
1452
 
1318
1453
  // src/commands/search.ts
1319
1454
  import ora5 from "ora";
1320
- import pc9 from "picocolors";
1455
+ import pc10 from "picocolors";
1321
1456
  async function search(query, options) {
1322
1457
  const spinner = ora5("Fetching package registry...").start();
1323
1458
  let packages;
@@ -1329,15 +1464,15 @@ async function search(query, options) {
1329
1464
  spinner.fail("Failed to fetch registry");
1330
1465
  if (error instanceof RegistryError) {
1331
1466
  if (error.code === "NETWORK_ERROR" || error.code === "TIMEOUT") {
1332
- console.log(pc9.red(`
1467
+ console.log(pc10.red(`
1333
1468
  Network error: ${error.message}`));
1334
- console.log(pc9.gray("Please check your internet connection and try again."));
1469
+ console.log(pc10.gray("Please check your internet connection and try again."));
1335
1470
  } else {
1336
- console.log(pc9.red(`
1471
+ console.log(pc10.red(`
1337
1472
  Error: ${error.message}`));
1338
1473
  }
1339
1474
  } else {
1340
- console.log(pc9.red(`
1475
+ console.log(pc10.red(`
1341
1476
  Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1342
1477
  }
1343
1478
  process.exit(1);
@@ -1351,10 +1486,10 @@ Error: ${error instanceof Error ? error.message : "Unknown error"}`));
1351
1486
  }
1352
1487
  if (entries.length === 0) {
1353
1488
  if (query) {
1354
- console.log(pc9.yellow(`
1489
+ console.log(pc10.yellow(`
1355
1490
  No packages matching '${query}'`));
1356
1491
  } else {
1357
- console.log(pc9.yellow("\nNo packages available in the registry"));
1492
+ console.log(pc10.yellow("\nNo packages available in the registry"));
1358
1493
  }
1359
1494
  return;
1360
1495
  }
@@ -1381,26 +1516,26 @@ No packages matching '${query}'`));
1381
1516
  const colName = 20;
1382
1517
  const colDesc = 44;
1383
1518
  const colVersions = 12;
1384
- console.log(pc9.bold("\nAvailable packages:\n"));
1519
+ console.log(pc10.bold("\nAvailable packages:\n"));
1385
1520
  console.log(
1386
- pc9.gray(
1521
+ pc10.gray(
1387
1522
  "PACKAGE".padEnd(colName) + "DESCRIPTION".padEnd(colDesc) + "VERSIONS".padEnd(colVersions) + "INSTALLED"
1388
1523
  )
1389
1524
  );
1390
- console.log(pc9.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
1525
+ console.log(pc10.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
1391
1526
  for (const [name, info] of entries.sort(([a], [b]) => a.localeCompare(b))) {
1392
1527
  const desc = truncate(info.description, colDesc - 2);
1393
1528
  const versions = info.versions.join(", ");
1394
1529
  const installedVersion = installedVersions.get(name);
1395
- const status = installedVersion ? pc9.green(`\u2713 ${installedVersion}`) : "";
1530
+ const status = installedVersion ? pc10.green(`\u2713 ${installedVersion}`) : "";
1396
1531
  console.log(
1397
1532
  name.padEnd(colName) + desc.padEnd(colDesc) + versions.padEnd(colVersions) + status
1398
1533
  );
1399
1534
  }
1400
- console.log(pc9.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
1401
- console.log(pc9.gray(`${entries.length} package${entries.length === 1 ? "" : "s"} available`));
1535
+ console.log(pc10.gray("\u2500".repeat(colName + colDesc + colVersions + 12)));
1536
+ console.log(pc10.gray(`${entries.length} package${entries.length === 1 ? "" : "s"} available`));
1402
1537
  console.log(`
1403
- Install with: ${pc9.cyan("olore install <package>")}`);
1538
+ Install with: ${pc10.cyan("olore install <package>")}`);
1404
1539
  }
1405
1540
  function truncate(str, maxLen) {
1406
1541
  if (str.length <= maxLen) return str;
@@ -1412,12 +1547,12 @@ var require2 = createRequire(import.meta.url);
1412
1547
  var { version } = require2("../package.json");
1413
1548
  var program = new Command();
1414
1549
  program.name("olore").description("Universal documentation for any AI coding agent").version(version).addHelpText("after", `
1415
- ${pc10.gray("May the Skill be with you.")}`);
1550
+ ${pc11.gray("May the Skill be with you.")}`);
1416
1551
  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) => {
1417
1552
  try {
1418
1553
  await init(options);
1419
1554
  } catch (error) {
1420
- console.error(pc10.red(`Error: ${error.message}`));
1555
+ console.error(pc11.red(`Error: ${error.message}`));
1421
1556
  process.exit(1);
1422
1557
  }
1423
1558
  });
@@ -1425,7 +1560,7 @@ program.command("install <package>").alias("i").description("Install a documenta
1425
1560
  try {
1426
1561
  await install(pkg, options);
1427
1562
  } catch (error) {
1428
- console.error(pc10.red(`Error: ${error.message}`));
1563
+ console.error(pc11.red(`Error: ${error.message}`));
1429
1564
  process.exit(1);
1430
1565
  }
1431
1566
  });
@@ -1433,7 +1568,7 @@ program.command("link <path>").description("Link a local package for development
1433
1568
  try {
1434
1569
  await link(localPath);
1435
1570
  } catch (error) {
1436
- console.error(pc10.red(`Error: ${error.message}`));
1571
+ console.error(pc11.red(`Error: ${error.message}`));
1437
1572
  process.exit(1);
1438
1573
  }
1439
1574
  });
@@ -1441,7 +1576,7 @@ program.command("list").alias("ls").description("List installed documentation pa
1441
1576
  try {
1442
1577
  await list(options);
1443
1578
  } catch (error) {
1444
- console.error(pc10.red(`Error: ${error.message}`));
1579
+ console.error(pc11.red(`Error: ${error.message}`));
1445
1580
  process.exit(1);
1446
1581
  }
1447
1582
  });
@@ -1449,7 +1584,7 @@ program.command("search [query]").description("Search available packages in the
1449
1584
  try {
1450
1585
  await search(query, options);
1451
1586
  } catch (error) {
1452
- console.error(pc10.red(`Error: ${error.message}`));
1587
+ console.error(pc11.red(`Error: ${error.message}`));
1453
1588
  process.exit(1);
1454
1589
  }
1455
1590
  });
@@ -1457,7 +1592,7 @@ program.command("remove <package>").alias("rm").description("Remove an installed
1457
1592
  try {
1458
1593
  await remove(pkg);
1459
1594
  } catch (error) {
1460
- console.error(pc10.red(`Error: ${error.message}`));
1595
+ console.error(pc11.red(`Error: ${error.message}`));
1461
1596
  process.exit(1);
1462
1597
  }
1463
1598
  });
@@ -1465,7 +1600,7 @@ program.command("doctor").description("Check for issues with installed packages"
1465
1600
  try {
1466
1601
  await doctor(options);
1467
1602
  } catch (error) {
1468
- console.error(pc10.red(`Error: ${error.message}`));
1603
+ console.error(pc11.red(`Error: ${error.message}`));
1469
1604
  process.exit(1);
1470
1605
  }
1471
1606
  });
@@ -1473,7 +1608,15 @@ program.command("prune").description("Remove dangling symlinks, orphaned package
1473
1608
  try {
1474
1609
  await prune(options);
1475
1610
  } catch (error) {
1476
- console.error(pc10.red(`Error: ${error.message}`));
1611
+ console.error(pc11.red(`Error: ${error.message}`));
1612
+ process.exit(1);
1613
+ }
1614
+ });
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) => {
1616
+ try {
1617
+ await inject(options);
1618
+ } catch (error) {
1619
+ console.error(pc11.red(`Error: ${error.message}`));
1477
1620
  process.exit(1);
1478
1621
  }
1479
1622
  });
@@ -1481,7 +1624,7 @@ program.command("order66").description(false).action(async () => {
1481
1624
  try {
1482
1625
  await order66();
1483
1626
  } catch (error) {
1484
- console.error(pc10.red(`Error: ${error.message}`));
1627
+ console.error(pc11.red(`Error: ${error.message}`));
1485
1628
  process.exit(1);
1486
1629
  }
1487
1630
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olorehq/olore",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "Universal documentation for any AI coding agent",
5
5
  "keywords": [
6
6
  "ai",
@@ -11,14 +11,14 @@
11
11
  "context",
12
12
  "llm"
13
13
  ],
14
- "license": "AGPL-3.0",
14
+ "license": "MIT",
15
15
  "author": "olorehq",
16
16
  "repository": {
17
17
  "type": "git",
18
18
  "url": "git+https://github.com/olorehq/olore.git",
19
19
  "directory": "cli"
20
20
  },
21
- "homepage": "https://github.com/olorehq/olore",
21
+ "homepage": "https://www.olore.dev",
22
22
  "type": "module",
23
23
  "files": [
24
24
  "dist"