@olorehq/olore 0.3.1 → 0.4.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 +14 -11
  2. package/dist/cli.js +76 -11
  3. package/package.json +7 -3
package/README.md CHANGED
@@ -7,17 +7,17 @@
7
7
  ██║ ██║██║ ██║ ██║██╔══██╗██╔══╝
8
8
  ╚██████╔╝███████╗╚██████╔╝██║ ██║███████╗
9
9
  ╚═════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
10
- O(pen) Lore for AI Agents
10
+ Stop the hallucinations.
11
11
  ```
12
12
 
13
- Documentation package manager for AI coding agents. Local-first. Offline-ready.
13
+ Version-pinned docs for AI coding agents. Local-first. Offline-ready.
14
14
 
15
15
  ## Quick Start
16
16
 
17
17
  ```bash
18
18
  npm install -g @olorehq/olore
19
19
  olore install prisma
20
- olore inject
20
+ olore inject prisma
21
21
  ```
22
22
 
23
23
  That's it. Your agent now has Prisma docs. No hallucinations.
@@ -28,7 +28,7 @@ Your AI coding agent makes decisions about which tools to invoke. Sometimes it d
28
28
 
29
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
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.
31
+ `olore inject` writes a skill reference table into your `AGENTS.md` / `CLAUDE.md`. Agents see which docs are available and invoke skills when needed — no guessing, no network calls.
32
32
 
33
33
  - **Version-pinned** — same docs, every run, every machine
34
34
  - **Offline** — works on planes, in CI, behind firewalls
@@ -37,26 +37,29 @@ Your AI coding agent makes decisions about which tools to invoke. Sometimes it d
37
37
 
38
38
  ## Available Packages
39
39
 
40
- `prisma` · `nextjs` · `zod` · `drizzle` · `langchain` · `tanstack-query` · `claude-code` · `codex` · `opencode` · `cargo` · `agentskills`
40
+ `a2a` · `agentskills` · `astro` · `axiom` · `azure-sdk-js` · `cargo` · `checkly` · `claude-code` · `clerk` · `cloudflare` · `codex` · `convex` · `drizzle` · `github-actions` · `hono` · `langchain` · `lucia` · `neon` · `neverthrow` · `nextjs` · `openclaw` · `opencode` · `opennext` · `partykit` · `partyserver` · `posthog` · `prettier` · `prisma` · `rhf` · `sentry` · `supabase` · `t3-env` · `tanstack-query` · `trpc` · `tsf` · `turso` · `vitest` · `xstate` · `zod`
41
41
 
42
- More on the [registry](https://github.com/olorehq/olore). Contributions welcome.
42
+ Browse all with `olore search`. Contributions welcome on [GitHub](https://github.com/olorehq/olore).
43
43
 
44
44
  ## Supported Agents
45
45
 
46
- - **Claude Code** — injects into `CLAUDE.md`
47
- - **Codex** — injects into `AGENTS.md`
48
- - **OpenCode** — injects into `AGENTS.md`
46
+ - **Claude Code** — skills in `~/.claude/skills/`
47
+ - **Codex** — skills in `~/.codex/skills/`
48
+ - **OpenCode** — skills in `~/.config/opencode/skills/`
49
49
 
50
50
  ## Commands
51
51
 
52
52
  | Command | Description |
53
53
  |---|---|
54
54
  | `olore install <pkg>` | Install a documentation package |
55
- | `olore inject` | Inject doc indexes into AGENTS.md / CLAUDE.md |
55
+ | `olore inject <pkg...>` | Write skill reference table into AGENTS.md / CLAUDE.md |
56
56
  | `olore inject --remove` | Remove injected content |
57
+ | `olore init` | Auto-detect project deps and install matching docs |
58
+ | `olore search [query]` | Browse available packages |
57
59
  | `olore list` | List installed packages |
58
60
  | `olore remove <pkg>` | Remove a package |
59
- | `olore search` | Browse available packages |
61
+ | `olore link <path>` | Link a local package for development |
62
+ | `olore prune` | Clean up dangling symlinks and orphaned packages |
60
63
  | `olore doctor` | Diagnose issues |
61
64
 
62
65
  ## Links
package/dist/cli.js CHANGED
@@ -25,7 +25,8 @@ import fs from "fs-extra";
25
25
  import * as tar from "tar";
26
26
 
27
27
  // src/core/constants.ts
28
- var REGISTRY_URL = "https://olore.dev/registry";
28
+ var REGISTRY_URL = "https://github.com/olorehq/olore/releases/download/registry/registry.json";
29
+ var REGISTRY_FALLBACK_URL = "https://olore.dev/registry";
29
30
  var DOWNLOAD_TIMEOUT = 6e4;
30
31
  var USER_AGENT = "olore-cli/0.1.0";
31
32
 
@@ -925,8 +926,23 @@ async function fetchWithTimeout(url, timeout = DOWNLOAD_TIMEOUT) {
925
926
  clearTimeout(timeoutId);
926
927
  }
927
928
  }
928
- async function fetchPackageIndex() {
929
- const url = `${REGISTRY_URL}/index.json`;
929
+ var cachedRegistry = null;
930
+ async function fetchCombinedRegistry() {
931
+ if (cachedRegistry) {
932
+ return cachedRegistry;
933
+ }
934
+ try {
935
+ const response2 = await fetchWithTimeout(REGISTRY_URL);
936
+ if (response2.ok) {
937
+ const data = await response2.json();
938
+ if (data.version === 2) {
939
+ cachedRegistry = data;
940
+ return cachedRegistry;
941
+ }
942
+ }
943
+ } catch {
944
+ }
945
+ const url = `${REGISTRY_FALLBACK_URL}/index.json`;
930
946
  const response = await fetchWithTimeout(url);
931
947
  if (response.status === 404) {
932
948
  throw new RegistryError("Registry not found", "NOT_FOUND");
@@ -934,15 +950,58 @@ async function fetchPackageIndex() {
934
950
  if (!response.ok) {
935
951
  throw new RegistryError(`Failed to fetch registry: ${response.status}`, "NETWORK_ERROR");
936
952
  }
953
+ let index;
937
954
  try {
938
- const data = await response.json();
939
- return data;
955
+ index = await response.json();
940
956
  } catch {
941
957
  throw new RegistryError("Invalid registry response", "INVALID_RESPONSE");
942
958
  }
959
+ const packages = {};
960
+ for (const [name, entry] of Object.entries(index.packages)) {
961
+ packages[name] = {
962
+ description: entry.description,
963
+ latest: entry.latest,
964
+ versions: {}
965
+ // populated on demand in fetchPackageVersions
966
+ };
967
+ }
968
+ cachedRegistry = {
969
+ version: 2,
970
+ updated: index.updated,
971
+ packages
972
+ };
973
+ return cachedRegistry;
974
+ }
975
+ async function fetchPackageIndex() {
976
+ const combined = await fetchCombinedRegistry();
977
+ const packages = {};
978
+ for (const [name, entry] of Object.entries(combined.packages)) {
979
+ packages[name] = {
980
+ description: entry.description,
981
+ latest: entry.latest,
982
+ versions: Object.keys(entry.versions).length > 0 ? Object.keys(entry.versions) : [entry.latest]
983
+ };
984
+ }
985
+ return {
986
+ version: combined.version,
987
+ updated: combined.updated,
988
+ packages
989
+ };
943
990
  }
944
991
  async function fetchPackageVersions(name) {
945
- const url = `${REGISTRY_URL}/packages/${name}.json`;
992
+ const combined = await fetchCombinedRegistry();
993
+ const entry = combined.packages[name];
994
+ if (!entry) {
995
+ throw new RegistryError(`Package "${name}" not found in registry`, "NOT_FOUND");
996
+ }
997
+ if (Object.keys(entry.versions).length > 0) {
998
+ return {
999
+ name,
1000
+ description: entry.description,
1001
+ versions: entry.versions
1002
+ };
1003
+ }
1004
+ const url = `${REGISTRY_FALLBACK_URL}/packages/${name}.json`;
946
1005
  const response = await fetchWithTimeout(url);
947
1006
  if (response.status === 404) {
948
1007
  throw new RegistryError(`Package "${name}" not found in registry`, "NOT_FOUND");
@@ -952,7 +1011,9 @@ async function fetchPackageVersions(name) {
952
1011
  }
953
1012
  try {
954
1013
  const data = await response.json();
955
- return data;
1014
+ const versions = data;
1015
+ entry.versions = versions.versions;
1016
+ return versions;
956
1017
  } catch {
957
1018
  throw new RegistryError("Invalid package response", "INVALID_RESPONSE");
958
1019
  }
@@ -980,16 +1041,20 @@ import pc4 from "picocolors";
980
1041
  // package.json
981
1042
  var package_default = {
982
1043
  name: "@olorehq/olore",
983
- version: "0.3.1",
984
- description: "Universal documentation for any AI coding agent",
1044
+ version: "0.4.0",
1045
+ description: "Version-pinned docs for AI coding agents. Offline. Local-first.",
985
1046
  keywords: [
986
1047
  "ai",
987
1048
  "documentation",
988
1049
  "claude",
989
1050
  "codex",
1051
+ "opencode",
990
1052
  "coding-assistant",
991
1053
  "context",
992
- "llm"
1054
+ "llm",
1055
+ "skills",
1056
+ "agents-md",
1057
+ "claude-md"
993
1058
  ],
994
1059
  license: "MIT",
995
1060
  author: "olorehq",
@@ -1746,7 +1811,7 @@ function truncate(str, maxLen) {
1746
1811
  var require2 = createRequire(import.meta.url);
1747
1812
  var { version } = require2("../package.json");
1748
1813
  var program = new Command();
1749
- program.name("olore").description("Universal documentation for any AI coding agent").version(version).addHelpText("after", `
1814
+ program.name("olore").description("Version-pinned docs for AI coding agents").version(version).addHelpText("after", `
1750
1815
  ${pc12.gray("May the Skill be with you.")}`);
1751
1816
  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) => {
1752
1817
  try {
package/package.json CHANGED
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "name": "@olorehq/olore",
3
- "version": "0.3.1",
4
- "description": "Universal documentation for any AI coding agent",
3
+ "version": "0.4.0",
4
+ "description": "Version-pinned docs for AI coding agents. Offline. Local-first.",
5
5
  "keywords": [
6
6
  "ai",
7
7
  "documentation",
8
8
  "claude",
9
9
  "codex",
10
+ "opencode",
10
11
  "coding-assistant",
11
12
  "context",
12
- "llm"
13
+ "llm",
14
+ "skills",
15
+ "agents-md",
16
+ "claude-md"
13
17
  ],
14
18
  "license": "MIT",
15
19
  "author": "olorehq",