oh-my-customcode 0.83.0 → 0.85.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.
package/README.md CHANGED
@@ -21,19 +21,6 @@ npm install -g oh-my-customcode && cd your-project && omcustom init
21
21
 
22
22
  ---
23
23
 
24
- ## What's New in v0.74.0
25
-
26
- | Feature | Description |
27
- |---------|-------------|
28
- | **`omcustom sync`** | Drift detection for `.claude/` configuration — compare against lockfile, export team snapshots |
29
- | **`omcustom init --from-snapshot`** | Team reproducibility — install from pre-configured snapshot directory |
30
- | **`analysis --interview`** | Interactive AI architecture interview before file-based project detection |
31
- | **skill-extractor** | 100th skill — analyze task trajectories to propose reusable SKILL.md candidates |
32
- | **User Model** | Structured tracking of correction patterns, skill preferences, expertise profile |
33
- | **Release Cleanup** | Auto-close linked issues and delete release branches on PR merge |
34
-
35
- ---
36
-
37
24
  ## Philosophy
38
25
 
39
26
  oh-my-customcode is built on two ideas:
package/dist/cli/index.js CHANGED
@@ -2301,7 +2301,7 @@ var init_package = __esm(() => {
2301
2301
  workspaces: [
2302
2302
  "packages/*"
2303
2303
  ],
2304
- version: "0.83.0",
2304
+ version: "0.85.0",
2305
2305
  description: "Batteries-included agent harness for Claude Code",
2306
2306
  type: "module",
2307
2307
  bin: {
@@ -9608,6 +9608,23 @@ async function getTemplateVersion() {
9608
9608
  }
9609
9609
  return package_default.version;
9610
9610
  }
9611
+ function matchesSearchPaths(projectPath, searchPaths) {
9612
+ if (!searchPaths || searchPaths.length === 0)
9613
+ return true;
9614
+ return searchPaths.some((searchPath) => projectPath === searchPath || projectPath.startsWith(searchPath + sep2));
9615
+ }
9616
+ function isUnderHome(projectPath, home) {
9617
+ return projectPath.startsWith(home + sep2) || projectPath === home;
9618
+ }
9619
+ function sortProjects(projects) {
9620
+ return projects.sort((a, b) => {
9621
+ if (a.status === "latest" && b.status !== "latest")
9622
+ return -1;
9623
+ if (a.status !== "latest" && b.status === "latest")
9624
+ return 1;
9625
+ return a.name.localeCompare(b.name);
9626
+ });
9627
+ }
9611
9628
  async function findProjects(options = {}) {
9612
9629
  const currentVersion = await getTemplateVersion();
9613
9630
  const registry = await readRegistry();
@@ -9619,12 +9636,12 @@ async function findProjects(options = {}) {
9619
9636
  return fallbackResults;
9620
9637
  }
9621
9638
  const results = [];
9639
+ const home = process.env.HOME ?? homedir3();
9622
9640
  for (const [projectPath, entry] of Object.entries(registry.projects)) {
9623
- if (options.paths && options.paths.length > 0) {
9624
- const matchesPath = options.paths.some((searchPath) => projectPath === searchPath || projectPath.startsWith(searchPath + sep2));
9625
- if (!matchesPath)
9626
- continue;
9627
- }
9641
+ if (!matchesSearchPaths(projectPath, options.paths))
9642
+ continue;
9643
+ if (!isUnderHome(projectPath, home))
9644
+ continue;
9628
9645
  results.push({
9629
9646
  name: basename4(projectPath),
9630
9647
  path: projectPath,
@@ -9635,31 +9652,21 @@ async function findProjects(options = {}) {
9635
9652
  detectionMethod: "registry"
9636
9653
  });
9637
9654
  }
9638
- return results.sort((a, b) => {
9639
- if (a.status === "latest" && b.status !== "latest")
9640
- return -1;
9641
- if (a.status !== "latest" && b.status === "latest")
9642
- return 1;
9643
- return a.name.localeCompare(b.name);
9644
- });
9655
+ return sortProjects(results);
9645
9656
  }
9646
- async function _findProjectsFromLockfiles(options, currentVersion) {
9647
- const { dirname: dirname3 } = await import("node:path");
9648
- const fs2 = await import("node:fs/promises");
9649
- const seen = new Set;
9650
- const results = [];
9651
- async function scanDir(dir2, depth) {
9652
- if (depth > 3 || seen.has(dir2))
9653
- return;
9654
- seen.add(dir2);
9655
- let entries;
9656
- try {
9657
- entries = await fs2.readdir(dir2, { withFileTypes: true });
9658
- } catch {
9659
- return;
9660
- }
9661
- const lockFile = await readLockFile(dir2);
9662
- if (lockFile) {
9657
+ async function _scanDirForLockfiles(dir2, depth, seen, results, home, currentVersion, fs2) {
9658
+ if (depth > 3 || seen.has(dir2))
9659
+ return;
9660
+ seen.add(dir2);
9661
+ let entries;
9662
+ try {
9663
+ entries = await fs2.readdir(dir2, { withFileTypes: true });
9664
+ } catch {
9665
+ return;
9666
+ }
9667
+ const lockFile = await readLockFile(dir2);
9668
+ if (lockFile) {
9669
+ if (isUnderHome(dir2, home)) {
9663
9670
  const version = lockFile.version || lockFile.templateVersion || null;
9664
9671
  results.push({
9665
9672
  name: basename4(dir2),
@@ -9670,13 +9677,20 @@ async function _findProjectsFromLockfiles(options, currentVersion) {
9670
9677
  status: computeStatus(version, currentVersion),
9671
9678
  detectionMethod: "lockfile"
9672
9679
  });
9673
- return;
9674
- }
9675
- if (depth < 3) {
9676
- const subdirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules" && e.name !== "dist" && e.name !== "build" && e.name !== ".git");
9677
- await Promise.all(subdirs.map((sub) => scanDir(join10(dir2, sub.name), depth + 1).catch(() => {})));
9678
9680
  }
9681
+ return;
9679
9682
  }
9683
+ if (depth < 3) {
9684
+ const subdirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && !SCAN_SKIP_DIRS2.has(e.name));
9685
+ await Promise.all(subdirs.map((sub) => _scanDirForLockfiles(join10(dir2, sub.name), depth + 1, seen, results, home, currentVersion, fs2).catch(() => {})));
9686
+ }
9687
+ }
9688
+ async function _findProjectsFromLockfiles(options, currentVersion) {
9689
+ const { dirname: dirname3 } = await import("node:path");
9690
+ const fs2 = await import("node:fs/promises");
9691
+ const seen = new Set;
9692
+ const results = [];
9693
+ const home = process.env.HOME ?? homedir3();
9680
9694
  const searchPaths = options.paths ? [...options.paths] : [];
9681
9695
  if (!options.paths) {
9682
9696
  const cwd = process.cwd();
@@ -9686,14 +9700,8 @@ async function _findProjectsFromLockfiles(options, currentVersion) {
9686
9700
  if (parent !== cwd && !searchPaths.includes(parent))
9687
9701
  searchPaths.push(parent);
9688
9702
  }
9689
- await Promise.all(searchPaths.map((p) => scanDir(p, 0).catch(() => {})));
9690
- return results.sort((a, b) => {
9691
- if (a.status === "latest" && b.status !== "latest")
9692
- return -1;
9693
- if (a.status !== "latest" && b.status === "latest")
9694
- return 1;
9695
- return a.name.localeCompare(b.name);
9696
- });
9703
+ await Promise.all(searchPaths.map((p) => _scanDirForLockfiles(p, 0, seen, results, home, currentVersion, fs2).catch(() => {})));
9704
+ return sortProjects(results);
9697
9705
  }
9698
9706
  async function writeLockFile(projectDir, version, existing) {
9699
9707
  const fs2 = await import("node:fs/promises");
@@ -9814,11 +9822,12 @@ async function projectsCommand(options = {}) {
9814
9822
  return { success: false, projects: [], currentVersion, errors: [errorMessage] };
9815
9823
  }
9816
9824
  }
9817
- var projects_default;
9825
+ var SCAN_SKIP_DIRS2, projects_default;
9818
9826
  var init_projects = __esm(() => {
9819
9827
  init_package();
9820
9828
  init_registry();
9821
9829
  init_fs();
9830
+ SCAN_SKIP_DIRS2 = new Set(["node_modules", "dist", "build", ".git"]);
9822
9831
  projects_default = projectsCommand;
9823
9832
  });
9824
9833
 
package/dist/index.js CHANGED
@@ -1974,7 +1974,7 @@ var package_default = {
1974
1974
  workspaces: [
1975
1975
  "packages/*"
1976
1976
  ],
1977
- version: "0.83.0",
1977
+ version: "0.85.0",
1978
1978
  description: "Batteries-included agent harness for Claude Code",
1979
1979
  type: "module",
1980
1980
  bin: {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "workspaces": [
4
4
  "packages/*"
5
5
  ],
6
- "version": "0.83.0",
6
+ "version": "0.85.0",
7
7
  "description": "Batteries-included agent harness for Claude Code",
8
8
  "type": "module",
9
9
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.83.0",
3
- "lastUpdated": "2026-04-12T00:00:00.000Z",
2
+ "version": "0.85.0",
3
+ "lastUpdated": "2026-04-13T00:00:00.000Z",
4
4
  "components": [
5
5
  {
6
6
  "name": "rules",