@olorehq/olore 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +85 -37
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -712,33 +712,61 @@ 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(" ");
727
+ }
728
+ function resolvePackages(requested, installed) {
729
+ const matched = [];
730
+ const notFound = [];
731
+ for (const req of requested) {
732
+ const normalized = req.replace(/^olore-/, "");
733
+ let found = installed.find((pkg) => pkg.name === normalized);
734
+ if (!found && normalized.includes("@")) {
735
+ const [name, version2] = normalized.split("@");
736
+ found = installed.find((pkg) => pkg.name === name && pkg.version === version2);
737
+ }
738
+ if (!found) {
739
+ found = installed.find((pkg) => `${pkg.name}-${pkg.version}` === normalized);
740
+ }
741
+ if (found) {
742
+ if (!matched.includes(found)) {
743
+ matched.push(found);
744
+ }
745
+ } else {
746
+ notFound.push(req);
747
+ }
748
+ }
749
+ return { matched, notFound };
721
750
  }
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 };
751
+ function buildInjectedContent(packages) {
752
+ const rows = packages.map((pkg) => {
753
+ const library = formatLibraryName(pkg.name);
754
+ const version2 = pkg.version !== "latest" ? ` ${pkg.version}` : "";
755
+ const skillCommand = `olore-${pkg.name}-${pkg.version}`;
756
+ return `| ${library}${version2} | \`${skillCommand}\` |`;
757
+ });
758
+ const lines = [
759
+ MARKER_START,
760
+ "## Documentation Reference",
761
+ "",
762
+ "Use these skills to access up-to-date documentation. Your training data may be outdated.",
763
+ "",
764
+ "| Library | Skill |",
765
+ "|---------|-------|",
766
+ ...rows,
767
+ MARKER_END
768
+ ];
769
+ return lines.join("\n");
742
770
  }
743
771
  function smartMerge(filePath, injectedContent) {
744
772
  if (!fs6.existsSync(filePath)) {
@@ -773,7 +801,7 @@ function removeSection(filePath) {
773
801
  }
774
802
  return true;
775
803
  }
776
- async function inject(options) {
804
+ async function inject(packages, options) {
777
805
  const cwd = process.cwd();
778
806
  if (options.remove) {
779
807
  const filesRemoved = [];
@@ -800,8 +828,7 @@ async function inject(options) {
800
828
  }
801
829
  return;
802
830
  }
803
- const { content, count } = await buildInjectedContent();
804
- if (count === 0) {
831
+ if (packages.length === 0) {
805
832
  if (options.json) {
806
833
  const result = {
807
834
  packagesFound: 0,
@@ -812,10 +839,31 @@ async function inject(options) {
812
839
  console.log(JSON.stringify(result, null, 2));
813
840
  return;
814
841
  }
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."));
842
+ console.log(pc3.yellow("No packages specified."));
843
+ console.log(pc3.gray("Usage: olore inject <package1> <package2> ..."));
844
+ console.log(pc3.gray("Example: olore inject nextjs prisma zod"));
845
+ return;
846
+ }
847
+ const installed = await getInstalledPackages();
848
+ const { matched, notFound } = resolvePackages(packages, installed);
849
+ if (notFound.length > 0) {
850
+ console.log(pc3.yellow(`Not installed: ${notFound.join(", ")}`));
851
+ console.log(pc3.gray("Run olore install <package> first."));
852
+ if (matched.length === 0) return;
853
+ }
854
+ if (matched.length === 0) {
855
+ if (options.json) {
856
+ const result = {
857
+ packagesFound: 0,
858
+ packagesInjected: 0,
859
+ filesWritten: [],
860
+ removed: false
861
+ };
862
+ console.log(JSON.stringify(result, null, 2));
863
+ }
817
864
  return;
818
865
  }
866
+ const content = buildInjectedContent(matched);
819
867
  const filesWritten = [];
820
868
  for (const fileName of TARGET_FILES) {
821
869
  const filePath = path6.join(cwd, fileName);
@@ -824,8 +872,8 @@ async function inject(options) {
824
872
  }
825
873
  if (options.json) {
826
874
  const result = {
827
- packagesFound: count,
828
- packagesInjected: count,
875
+ packagesFound: installed.length,
876
+ packagesInjected: matched.length,
829
877
  filesWritten,
830
878
  removed: false
831
879
  };
@@ -834,7 +882,7 @@ async function inject(options) {
834
882
  }
835
883
  console.log(
836
884
  pc3.green(
837
- `Injected ${count} package${count === 1 ? "" : "s"} into: ${filesWritten.join(", ")}`
885
+ `Injected ${matched.length} package${matched.length === 1 ? "" : "s"} into: ${filesWritten.join(", ")}`
838
886
  )
839
887
  );
840
888
  console.log(pc3.gray("Run olore inject --remove to clean up."));
@@ -932,7 +980,7 @@ import pc4 from "picocolors";
932
980
  // package.json
933
981
  var package_default = {
934
982
  name: "@olorehq/olore",
935
- version: "0.2.1",
983
+ version: "0.3.1",
936
984
  description: "Universal documentation for any AI coding agent",
937
985
  keywords: [
938
986
  "ai",
@@ -1764,9 +1812,9 @@ program.command("prune").description("Remove dangling symlinks, orphaned package
1764
1812
  process.exit(1);
1765
1813
  }
1766
1814
  });
1767
- 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) => {
1815
+ program.command("inject [packages...]").description("Inject documentation reference into AGENTS.md and CLAUDE.md").option("--remove", "Remove injected content from project files").option("--json", "Output as JSON").action(async (packages, options) => {
1768
1816
  try {
1769
- await inject(options);
1817
+ await inject(packages, options);
1770
1818
  } catch (error) {
1771
1819
  console.error(pc12.red(`Error: ${error.message}`));
1772
1820
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olorehq/olore",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "Universal documentation for any AI coding agent",
5
5
  "keywords": [
6
6
  "ai",