ccprofiles-core 0.7.0 → 0.7.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.
package/dist/assets.js CHANGED
@@ -4,7 +4,13 @@ import { join, relative } from 'node:path';
4
4
  import { renderPath } from './platform.js';
5
5
  import { atomicWrite, backupFiles } from './fsutil.js';
6
6
  import { physicalLinkEntry } from './links.js';
7
- const HUB_DIRS = ['skills', 'commands', 'plugins'];
7
+ // Deliberately NOT 'plugins': plugin state syncs via the manifest's declarative
8
+ // `plugins[]`/`marketplaces{}` fields (already inside manifestYaml) plus a `claude plugin
9
+ // install` reconcile after sync/import — never by copying the plugins/ directory tree.
10
+ // That tree is marketplace git clones + installed plugin caches, routinely multi-GB; walking
11
+ // and JSON.stringify-ing it here blew past V8's max string length in sealJson on a real user's
12
+ // machine (their ~/.claude-oauth/plugins/ alone was 3.9 GB).
13
+ const HUB_DIRS = ['skills', 'commands'];
8
14
  function safeParts(rel) {
9
15
  if (rel.includes('\\') || rel.includes('\0'))
10
16
  throw new Error(`unsafe asset path: ${JSON.stringify(rel)}`);
@@ -10,6 +10,10 @@ export interface LiveProfile {
10
10
  links: Record<string, string>;
11
11
  settingsEnv: Record<string, string>;
12
12
  enabledPlugins: Record<string, boolean>;
13
+ /** Plugin ids actually installed (keys of plugins/installed_plugins.json) — the ground truth
14
+ * for "present". enabledPlugins alone can be stale: an enabled-but-never-installed entry
15
+ * (e.g. written by the retired union-sharing feature) must still trigger an install. */
16
+ installedPlugins: string[];
13
17
  marketplaces: Record<string, {
14
18
  source: string;
15
19
  }>;
package/dist/discovery.js CHANGED
@@ -85,6 +85,14 @@ export async function discoverProfiles(home) {
85
85
  }
86
86
  }
87
87
  catch { /* no plugins/known_marketplaces.json */ }
88
+ const installedPlugins = [];
89
+ if (agent === 'claude')
90
+ try {
91
+ const ip = JSON.parse(await readFile(join(dir, 'plugins', 'installed_plugins.json'), 'utf8'));
92
+ if (ip && typeof ip.plugins === 'object' && ip.plugins !== null)
93
+ installedPlugins.push(...Object.keys(ip.plugins));
94
+ }
95
+ catch { /* no plugins/installed_plugins.json */ }
88
96
  out.push({
89
97
  agent,
90
98
  dirName: e.name,
@@ -96,6 +104,7 @@ export async function discoverProfiles(home) {
96
104
  links,
97
105
  settingsEnv,
98
106
  enabledPlugins,
107
+ installedPlugins,
99
108
  marketplaces,
100
109
  });
101
110
  }
@@ -95,8 +95,11 @@ export async function startSyncServer(deps) {
95
95
  }
96
96
  return send(res, 404, { error: 'not found' });
97
97
  }
98
- catch {
99
- // never leak internal error detail (paths, parse internals) to callers
98
+ catch (e) {
99
+ // never leak internal error detail (paths, parse internals) to callers — but log it
100
+ // locally (this process's own stderr, never sent over the wire) so whoever runs
101
+ // `ccprofiles serve` can actually diagnose the failure instead of a bare 500.
102
+ process.stderr.write(`ccprofiles serve error: ${e.stack ?? e}\n`);
100
103
  return send(res, 500, { error: 'internal error' });
101
104
  }
102
105
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccprofiles-core",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Core library for ccprofiles — discovery, manifest, secrets, apply, and LAN sync for Claude Code multi-account setups",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",