@slats/claude-assets-sync 0.1.1 → 0.1.2

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.
@@ -48,11 +48,7 @@ const BulkAddView = ({ pattern, cwd, local = false, ref, }) => {
48
48
  await asyncPool.asyncPool(3, matched, async (pkgName) => {
49
49
  setScanSteps((prev) => prev.map((s) => s.name === pkgName ? { ...s, status: 'running' } : s));
50
50
  try {
51
- const trees = await packageScanner.scanPackageAssets(pkgName, {
52
- local,
53
- ref,
54
- cwd,
55
- });
51
+ const trees = await packageScanner.scanPackageAssets(pkgName, { local, ref, cwd });
56
52
  const hasAssets = trees.length > 0;
57
53
  if (hasAssets) {
58
54
  packagesWithAssets.push(pkgName);
@@ -67,7 +63,7 @@ const BulkAddView = ({ pattern, cwd, local = false, ref, }) => {
67
63
  }
68
64
  catch (err) {
69
65
  const msg = err instanceof Error ? err.message : String(err);
70
- const isNoAssets = /no repository|asset path.*does not exist|not found in (local workspace|node_modules)/i.test(msg);
66
+ const isNoAssets = /no repository|asset path.*does not exist|not found in/i.test(msg);
71
67
  if (isNoAssets) {
72
68
  scanResults.push({ name: pkgName, status: 'skipped', assetCount: 0 });
73
69
  setScanSteps((prev) => prev.map((s) => s.name === pkgName ? { ...s, status: 'skipped' } : s));
@@ -46,11 +46,7 @@ const BulkAddView = ({ pattern, cwd, local = false, ref, }) => {
46
46
  await asyncPool(3, matched, async (pkgName) => {
47
47
  setScanSteps((prev) => prev.map((s) => s.name === pkgName ? { ...s, status: 'running' } : s));
48
48
  try {
49
- const trees = await scanPackageAssets(pkgName, {
50
- local,
51
- ref,
52
- cwd,
53
- });
49
+ const trees = await scanPackageAssets(pkgName, { local, ref, cwd });
54
50
  const hasAssets = trees.length > 0;
55
51
  if (hasAssets) {
56
52
  packagesWithAssets.push(pkgName);
@@ -65,7 +61,7 @@ const BulkAddView = ({ pattern, cwd, local = false, ref, }) => {
65
61
  }
66
62
  catch (err) {
67
63
  const msg = err instanceof Error ? err.message : String(err);
68
- const isNoAssets = /no repository|asset path.*does not exist|not found in (local workspace|node_modules)/i.test(msg);
64
+ const isNoAssets = /no repository|asset path.*does not exist|not found in/i.test(msg);
69
65
  if (isNoAssets) {
70
66
  scanResults.push({ name: pkgName, status: 'skipped', assetCount: 0 });
71
67
  setScanSteps((prev) => prev.map((s) => s.name === pkgName ? { ...s, status: 'skipped' } : s));
@@ -26,7 +26,7 @@ export declare const META_FILES: {
26
26
  * Schema versions for metadata files
27
27
  */
28
28
  export declare const SCHEMA_VERSIONS: {
29
- readonly UNIFIED_SYNC_META: "0.1.0";
29
+ readonly UNIFIED_SYNC_META: "0.1.2";
30
30
  readonly LEGACY_SYNC_META: "1.0.0";
31
31
  readonly SKILL_UNIT_FORMAT: "2";
32
32
  };
@@ -2,9 +2,17 @@
2
2
 
3
3
  var fs = require('node:fs');
4
4
  var path = require('node:path');
5
+ var _package = require('../utils/package.cjs');
5
6
 
6
7
  const canUseLocalSource = (packageName, requestedVersion, assetPath, cwd) => {
7
- const docsPath = path.join(cwd, 'node_modules', packageName, assetPath);
8
+ const packagePath = _package.resolvePackagePath(packageName, cwd);
9
+ if (!packagePath) {
10
+ return {
11
+ available: false,
12
+ reason: `Package ${packageName} not found in node_modules`,
13
+ };
14
+ }
15
+ const docsPath = path.join(packagePath, assetPath);
8
16
  if (!fs.existsSync(docsPath)) {
9
17
  return {
10
18
  available: false,
@@ -12,7 +20,7 @@ const canUseLocalSource = (packageName, requestedVersion, assetPath, cwd) => {
12
20
  };
13
21
  }
14
22
  try {
15
- const pkgJsonPath = path.join(cwd, 'node_modules', packageName, 'package.json');
23
+ const pkgJsonPath = path.join(packagePath, 'package.json');
16
24
  const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
17
25
  if (pkgJson.version !== requestedVersion) {
18
26
  return {
@@ -1,8 +1,16 @@
1
1
  import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
+ import { resolvePackagePath } from '../utils/package.mjs';
3
4
 
4
5
  const canUseLocalSource = (packageName, requestedVersion, assetPath, cwd) => {
5
- const docsPath = join(cwd, 'node_modules', packageName, assetPath);
6
+ const packagePath = resolvePackagePath(packageName, cwd);
7
+ if (!packagePath) {
8
+ return {
9
+ available: false,
10
+ reason: `Package ${packageName} not found in node_modules`,
11
+ };
12
+ }
13
+ const docsPath = join(packagePath, assetPath);
6
14
  if (!existsSync(docsPath)) {
7
15
  return {
8
16
  available: false,
@@ -10,7 +18,7 @@ const canUseLocalSource = (packageName, requestedVersion, assetPath, cwd) => {
10
18
  };
11
19
  }
12
20
  try {
13
- const pkgJsonPath = join(cwd, 'node_modules', packageName, 'package.json');
21
+ const pkgJsonPath = join(packagePath, 'package.json');
14
22
  const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
15
23
  if (pkgJson.version !== requestedVersion) {
16
24
  return {
@@ -31,7 +31,7 @@ async function scanPackageAssets(packageName, options) {
31
31
  if (options.local) {
32
32
  return scanLocalAssets(packageName, cwd);
33
33
  }
34
- return scanRemoteAssets(packageName, options.ref);
34
+ return scanRemoteAssets(packageName, cwd, options.ref);
35
35
  }
36
36
  async function scanLocalAssets(packageName, cwd) {
37
37
  const packagePath = findLocalPackage(packageName, cwd);
@@ -60,8 +60,11 @@ async function scanLocalAssets(packageName, cwd) {
60
60
  }
61
61
  return trees;
62
62
  }
63
- async function scanRemoteAssets(packageName, ref) {
64
- const nodeModulesPath = path.join(process.cwd(), 'node_modules', packageName);
63
+ async function scanRemoteAssets(packageName, cwd, ref) {
64
+ const nodeModulesPath = _package.resolvePackagePath(packageName, cwd);
65
+ if (!nodeModulesPath) {
66
+ throw new Error(`Package ${packageName} not found`);
67
+ }
65
68
  const pkgInfo = readPackageJsonFromPath(nodeModulesPath);
66
69
  if (!pkgInfo) {
67
70
  throw new Error(`Package ${packageName} not found`);
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { toFlatFileName } from '../utils/nameTransform.mjs';
4
- import { resolveClaudeConfig, parseGitHubRepo } from '../utils/package.mjs';
4
+ import { resolveClaudeConfig, resolvePackagePath, parseGitHubRepo } from '../utils/package.mjs';
5
5
  import { DEFAULT_ASSET_TYPES } from './constants.mjs';
6
6
  import { fetchDirectoryContents } from './github.mjs';
7
7
 
@@ -29,7 +29,7 @@ async function scanPackageAssets(packageName, options) {
29
29
  if (options.local) {
30
30
  return scanLocalAssets(packageName, cwd);
31
31
  }
32
- return scanRemoteAssets(packageName, options.ref);
32
+ return scanRemoteAssets(packageName, cwd, options.ref);
33
33
  }
34
34
  async function scanLocalAssets(packageName, cwd) {
35
35
  const packagePath = findLocalPackage(packageName, cwd);
@@ -58,8 +58,11 @@ async function scanLocalAssets(packageName, cwd) {
58
58
  }
59
59
  return trees;
60
60
  }
61
- async function scanRemoteAssets(packageName, ref) {
62
- const nodeModulesPath = join(process.cwd(), 'node_modules', packageName);
61
+ async function scanRemoteAssets(packageName, cwd, ref) {
62
+ const nodeModulesPath = resolvePackagePath(packageName, cwd);
63
+ if (!nodeModulesPath) {
64
+ throw new Error(`Package ${packageName} not found`);
65
+ }
63
66
  const pkgInfo = readPackageJsonFromPath(nodeModulesPath);
64
67
  if (!pkgInfo) {
65
68
  throw new Error(`Package ${packageName} not found`);
@@ -2,7 +2,7 @@ import type { PackageSyncInfo, SkillUnit, UnifiedSyncMeta } from '../utils/types
2
2
  /**
3
3
  * Schema version for the unified metadata format
4
4
  */
5
- export declare const SCHEMA_VERSION: "0.1.0";
5
+ export declare const SCHEMA_VERSION: "0.1.2";
6
6
  /**
7
7
  * Read unified sync metadata from .claude/.sync-meta.json
8
8
  *
@@ -5,10 +5,26 @@ var fs = require('node:fs');
5
5
  var path = require('node:path');
6
6
  var constants = require('../core/constants.cjs');
7
7
 
8
+ const resolvePackagePath = (packageName, cwd) => {
9
+ let dir = cwd;
10
+ while (true) {
11
+ const candidate = path.join(dir, 'node_modules', packageName);
12
+ if (fs.existsSync(path.join(candidate, 'package.json'))) {
13
+ return candidate;
14
+ }
15
+ const parent = path.dirname(dir);
16
+ if (parent === dir)
17
+ break;
18
+ dir = parent;
19
+ }
20
+ return null;
21
+ };
8
22
  const readPackageJson = (packageName, cwd = process.cwd()) => {
9
23
  try {
10
- const packageJsonPath = path.join(cwd, 'node_modules', packageName, 'package.json');
11
- const content = fs.readFileSync(packageJsonPath, 'utf-8');
24
+ const packagePath = resolvePackagePath(packageName, cwd);
25
+ if (!packagePath)
26
+ return null;
27
+ const content = fs.readFileSync(path.join(packagePath, 'package.json'), 'utf-8');
12
28
  const json = JSON.parse(content);
13
29
  if (!json.name || !json.version || !json.repository)
14
30
  return null;
@@ -151,3 +167,4 @@ exports.parseGitHubRepo = parseGitHubRepo;
151
167
  exports.readLocalPackageJson = readLocalPackageJson;
152
168
  exports.readPackageJson = readPackageJson;
153
169
  exports.resolveClaudeConfig = resolveClaudeConfig;
170
+ exports.resolvePackagePath = resolvePackagePath;
@@ -1,5 +1,14 @@
1
1
  import type { ClaudeConfig, GitHubRepoInfo, PackageInfo, WorkspaceInfo } from './types';
2
2
  export { getAssetStructure } from '../core/assetStructure';
3
+ /**
4
+ * Resolve package path in node_modules by walking up the directory tree.
5
+ * Mimics Node.js module resolution: checks cwd/node_modules, then ../node_modules, etc.
6
+ *
7
+ * @param packageName - Package name (e.g., "@canard/schema-form")
8
+ * @param cwd - Starting directory for resolution
9
+ * @returns Absolute path to the package directory, or null if not found
10
+ */
11
+ export declare const resolvePackagePath: (packageName: string, cwd: string) => string | null;
3
12
  /**
4
13
  * Read package.json from node_modules
5
14
  * @param packageName - Package name (e.g., "@canard/schema-form")
@@ -3,10 +3,26 @@ import { readFileSync, existsSync } from 'node:fs';
3
3
  import { join, dirname } from 'node:path';
4
4
  import { DEFAULT_ASSET_PATH, FS_PATTERNS, DEFAULT_ASSET_TYPES } from '../core/constants.mjs';
5
5
 
6
+ const resolvePackagePath = (packageName, cwd) => {
7
+ let dir = cwd;
8
+ while (true) {
9
+ const candidate = join(dir, 'node_modules', packageName);
10
+ if (existsSync(join(candidate, 'package.json'))) {
11
+ return candidate;
12
+ }
13
+ const parent = dirname(dir);
14
+ if (parent === dir)
15
+ break;
16
+ dir = parent;
17
+ }
18
+ return null;
19
+ };
6
20
  const readPackageJson = (packageName, cwd = process.cwd()) => {
7
21
  try {
8
- const packageJsonPath = join(cwd, 'node_modules', packageName, 'package.json');
9
- const content = readFileSync(packageJsonPath, 'utf-8');
22
+ const packagePath = resolvePackagePath(packageName, cwd);
23
+ if (!packagePath)
24
+ return null;
25
+ const content = readFileSync(join(packagePath, 'package.json'), 'utf-8');
10
26
  const json = JSON.parse(content);
11
27
  if (!json.name || !json.version || !json.repository)
12
28
  return null;
@@ -138,4 +154,4 @@ const resolveClaudeConfig = (claude) => ({
138
154
  ...(claude?.assets ? { assets: claude.assets } : {}),
139
155
  });
140
156
 
141
- export { buildAssetPath, buildVersionTag, findGitRoot, findWorkspaceLocation, findWorkspaceRoot, getAssetTypes, getWorkspaceList, parseGitHubRepo, readLocalPackageJson, readPackageJson, resolveClaudeConfig };
157
+ export { buildAssetPath, buildVersionTag, findGitRoot, findWorkspaceLocation, findWorkspaceRoot, getAssetTypes, getWorkspaceList, parseGitHubRepo, readLocalPackageJson, readPackageJson, resolveClaudeConfig, resolvePackagePath };
package/dist/version.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  'use strict';
2
2
 
3
- const VERSION = '0.1.0';
3
+ const VERSION = '0.1.2';
4
4
 
5
5
  exports.VERSION = VERSION;
package/dist/version.d.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * Current package version from package.json
3
3
  * Automatically synchronized during build process
4
4
  */
5
- export declare const VERSION = "0.1.0";
5
+ export declare const VERSION = "0.1.2";
package/dist/version.mjs CHANGED
@@ -1,3 +1,3 @@
1
- const VERSION = '0.1.0';
1
+ const VERSION = '0.1.2';
2
2
 
3
3
  export { VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slats/claude-assets-sync",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "CLI tool to sync Claude commands and skills from npm packages to your project's .claude directory",
5
5
  "keywords": [
6
6
  "claude",