@slats/claude-assets-sync 0.3.0 → 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.
- package/README.md +9 -9
- package/dist/claude-hashes.json +7 -7
- package/dist/commands/runCli/runCli.mjs +7 -2
- package/dist/commands/runCli/type.d.ts +1 -0
- package/dist/commands/runCli/utils/renderOrFallback.d.ts +6 -0
- package/dist/commands/runCli/utils/renderOrFallback.mjs +12 -0
- package/dist/commands/runCli/utils/renderPlain.d.ts +11 -0
- package/dist/commands/runCli/utils/renderPlain.mjs +89 -0
- package/dist/commands/runCli/utils/resolveScopeFlag.d.ts +9 -1
- package/dist/commands/runCli/utils/resolveScopeFlag.mjs +5 -11
- package/dist/commands/runCli/utils/toConsumerPackages.d.ts +9 -0
- package/dist/commands/runCli/utils/toConsumerPackages.mjs +26 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/injectDocs/index.d.ts +3 -2
- package/dist/core/injectDocs/type.d.ts +0 -19
- package/dist/core/scope/index.d.ts +1 -1
- package/dist/core/scope/scope.d.ts +0 -1
- package/dist/core/scope/scope.mjs +1 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/ui/InjectApp/InjectApp.d.ts +2 -0
- package/dist/ui/InjectApp/InjectApp.mjs +82 -0
- package/dist/ui/InjectApp/index.d.ts +2 -0
- package/dist/ui/InjectApp/utils/eventSelectors.d.ts +5 -0
- package/dist/ui/InjectApp/utils/eventSelectors.mjs +24 -0
- package/dist/ui/InjectApp/utils/phaseReducer.d.ts +2 -0
- package/dist/ui/InjectApp/utils/phaseReducer.mjs +130 -0
- package/dist/ui/InjectApp/utils/renderInjectApp.d.ts +2 -0
- package/dist/ui/InjectApp/utils/renderInjectApp.mjs +19 -0
- package/dist/ui/InjectApp/utils/type.d.ts +5 -0
- package/dist/ui/components/ActionRow.d.ts +7 -0
- package/dist/ui/components/ActionRow.mjs +45 -0
- package/dist/ui/components/Banner.d.ts +7 -0
- package/dist/ui/components/Banner.mjs +9 -0
- package/dist/ui/components/ConfirmForce.d.ts +8 -0
- package/dist/ui/components/ConfirmForce.mjs +35 -0
- package/dist/ui/components/ErrorPanel.d.ts +6 -0
- package/dist/ui/components/ErrorPanel.mjs +14 -0
- package/dist/ui/components/Footer.d.ts +8 -0
- package/dist/ui/components/Footer.mjs +27 -0
- package/dist/ui/components/PlanTable.d.ts +8 -0
- package/dist/ui/components/PlanTable.mjs +15 -0
- package/dist/ui/components/ProgressBar.d.ts +10 -0
- package/dist/ui/components/ProgressBar.mjs +28 -0
- package/dist/ui/components/ScopePicker.d.ts +7 -0
- package/dist/ui/components/ScopePicker.mjs +26 -0
- package/dist/ui/components/Spinner.d.ts +8 -0
- package/dist/ui/components/Spinner.mjs +10 -0
- package/dist/ui/components/StatusBadge.d.ts +8 -0
- package/dist/ui/components/StepTracker.d.ts +9 -0
- package/dist/ui/components/StepTracker.mjs +43 -0
- package/dist/ui/components/Summary.d.ts +9 -0
- package/dist/ui/components/Summary.mjs +30 -0
- package/dist/ui/components/TargetCard.d.ts +11 -0
- package/dist/ui/components/TargetCard.mjs +29 -0
- package/dist/ui/hooks/useApplyStep.d.ts +12 -0
- package/dist/ui/hooks/useApplyStep.mjs +30 -0
- package/dist/ui/hooks/useExitApp.d.ts +8 -0
- package/dist/ui/hooks/useExitApp.mjs +19 -0
- package/dist/ui/hooks/useForceConfirmStep.d.ts +9 -0
- package/dist/ui/hooks/useForceConfirmStep.mjs +24 -0
- package/dist/ui/hooks/useInjectSession.d.ts +10 -0
- package/dist/ui/hooks/useInjectSession.mjs +63 -0
- package/dist/ui/hooks/useInterval.d.ts +1 -0
- package/dist/ui/hooks/usePhase.d.ts +2 -0
- package/dist/ui/hooks/usePhase.mjs +9 -0
- package/dist/ui/hooks/usePlanStep.d.ts +13 -0
- package/dist/ui/hooks/usePlanStep.mjs +94 -0
- package/dist/ui/hooks/useResolveStep.d.ts +18 -0
- package/dist/ui/hooks/useResolveStep.mjs +21 -0
- package/dist/ui/hooks/useTerminalWidth.d.ts +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.mjs +16 -0
- package/dist/ui/theme/colors.d.ts +12 -0
- package/dist/ui/theme/colors.mjs +9 -0
- package/dist/ui/theme/icons.d.ts +29 -0
- package/dist/ui/theme/icons.mjs +17 -0
- package/dist/ui/theme/layout.d.ts +20 -0
- package/dist/ui/theme/layout.mjs +9 -0
- package/dist/ui/types/event.d.ts +45 -0
- package/dist/ui/types/index.d.ts +4 -0
- package/dist/ui/types/phase.d.ts +44 -0
- package/dist/ui/types/render.d.ts +6 -0
- package/dist/ui/types/target.d.ts +25 -0
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/version.mjs +1 -1
- package/docs/claude/skills/claude-docs-asset-wiring/SKILL.md +1 -1
- package/docs/claude/skills/claude-docs-asset-wiring/knowledge/claude-md-template.md +4 -12
- package/docs/claude/skills/claude-docs-asset-wiring/knowledge/gotchas.md +17 -14
- package/docs/claude/skills/claude-docs-asset-wiring/knowledge/package-json-patches.md +18 -13
- package/docs/claude/skills/claude-docs-asset-wiring/knowledge/reference-files.md +4 -4
- package/docs/consumer-integration.md +9 -8
- package/package.json +12 -7
- package/scripts/dev-ui-fixtures.ts +288 -0
- package/scripts/dev-ui.tsx +289 -0
- package/dist/commands/runCli/runCli.cjs +0 -53
- package/dist/commands/runCli/utils/classifyTarget.cjs +0 -48
- package/dist/commands/runCli/utils/injectOne.cjs +0 -47
- package/dist/commands/runCli/utils/injectOne.d.ts +0 -3
- package/dist/commands/runCli/utils/injectOne.mjs +0 -45
- package/dist/commands/runCli/utils/resolvePackage.cjs +0 -77
- package/dist/commands/runCli/utils/resolveScopeAlias.cjs +0 -69
- package/dist/commands/runCli/utils/resolveScopeFlag.cjs +0 -28
- package/dist/commands/runCli/utils/resolveTargets.cjs +0 -40
- package/dist/commands/runCli/utils/runInject.cjs +0 -52
- package/dist/commands/runCli/utils/runInject.d.ts +0 -3
- package/dist/commands/runCli/utils/runInject.mjs +0 -50
- package/dist/core/buildPlan/buildPlan.cjs +0 -42
- package/dist/core/buildPlan/utils/toPosix.cjs +0 -9
- package/dist/core/buildPlan/utils/walkFiles.cjs +0 -25
- package/dist/core/hash/hash.cjs +0 -30
- package/dist/core/hashManifest/hashManifest.cjs +0 -27
- package/dist/core/injectDocs/injectDocs.cjs +0 -43
- package/dist/core/injectDocs/injectDocs.d.ts +0 -2
- package/dist/core/injectDocs/injectDocs.mjs +0 -41
- package/dist/core/injectDocs/utils/applyAction.cjs +0 -21
- package/dist/core/injectDocs/utils/emitCiForceList.cjs +0 -10
- package/dist/core/injectDocs/utils/emitCiForceList.d.ts +0 -2
- package/dist/core/injectDocs/utils/emitCiForceList.mjs +0 -8
- package/dist/core/injectDocs/utils/printPlan.cjs +0 -20
- package/dist/core/injectDocs/utils/printPlan.d.ts +0 -2
- package/dist/core/injectDocs/utils/printPlan.mjs +0 -18
- package/dist/core/injectDocs/utils/summarize.cjs +0 -27
- package/dist/core/scope/scope.cjs +0 -46
- package/dist/core/scope/utils/isDirectory.cjs +0 -14
- package/dist/index.cjs +0 -20
- package/dist/prompts/confirmForce.cjs +0 -27
- package/dist/prompts/confirmForce.d.ts +0 -1
- package/dist/prompts/confirmForce.mjs +0 -25
- package/dist/prompts/index.d.ts +0 -2
- package/dist/prompts/selectScope.cjs +0 -30
- package/dist/prompts/selectScope.d.ts +0 -2
- package/dist/prompts/selectScope.mjs +0 -28
- package/dist/utils/asyncPool.cjs +0 -26
- package/dist/utils/heartbeat.cjs +0 -25
- package/dist/utils/heartbeat.d.ts +0 -16
- package/dist/utils/heartbeat.mjs +0 -23
- package/dist/utils/logger.cjs +0 -74
- package/dist/utils/version.cjs +0 -5
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var logger = require('../../../utils/logger.cjs');
|
|
4
|
-
var classifyTarget = require('./classifyTarget.cjs');
|
|
5
|
-
var resolvePackage = require('./resolvePackage.cjs');
|
|
6
|
-
var resolveScopeAlias = require('./resolveScopeAlias.cjs');
|
|
7
|
-
|
|
8
|
-
async function resolveTargets(targets, rootCwd) {
|
|
9
|
-
if (targets.length === 0)
|
|
10
|
-
return [];
|
|
11
|
-
const isSingleTarget = targets.length === 1;
|
|
12
|
-
const seen = new Set();
|
|
13
|
-
const results = [];
|
|
14
|
-
for (const target of targets) {
|
|
15
|
-
const classification = classifyTarget.classifyTarget(target);
|
|
16
|
-
if (classification.kind === 'invalid') {
|
|
17
|
-
logger.logger.error(classification.reason);
|
|
18
|
-
process.exit(2);
|
|
19
|
-
}
|
|
20
|
-
let candidates;
|
|
21
|
-
if (classification.kind === 'scope') {
|
|
22
|
-
candidates = await resolveScopeAlias.resolveScopeAlias(classification.scope, rootCwd);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
const meta = await resolvePackage.resolvePackage(classification.name, {
|
|
26
|
-
skipMissingAsset: !isSingleTarget,
|
|
27
|
-
});
|
|
28
|
-
candidates = meta ? [meta] : [];
|
|
29
|
-
}
|
|
30
|
-
for (const meta of candidates) {
|
|
31
|
-
if (!seen.has(meta.packageName)) {
|
|
32
|
-
seen.add(meta.packageName);
|
|
33
|
-
results.push(meta);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return results;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
exports.resolveTargets = resolveTargets;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var promises = require('node:fs/promises');
|
|
4
|
-
var node_path = require('node:path');
|
|
5
|
-
var logger = require('../../../utils/logger.cjs');
|
|
6
|
-
var injectOne = require('./injectOne.cjs');
|
|
7
|
-
var resolveScopeFlag = require('./resolveScopeFlag.cjs');
|
|
8
|
-
|
|
9
|
-
async function runInject(flags, metadataList) {
|
|
10
|
-
if (metadataList.length === 0)
|
|
11
|
-
return;
|
|
12
|
-
for (const metadata of metadataList) {
|
|
13
|
-
if (!node_path.isAbsolute(metadata.packageRoot)) {
|
|
14
|
-
logger.logger.error(`packageRoot must be an absolute path; received: ${metadata.packageRoot}`);
|
|
15
|
-
process.exit(2);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
const originCwd = flags.root ?? process.cwd();
|
|
19
|
-
const scope = await resolveScopeFlag.resolveScopeFlag(flags.scope);
|
|
20
|
-
const fatalOnError = metadataList.length === 1;
|
|
21
|
-
let failureCount = 0;
|
|
22
|
-
for (const metadata of metadataList) {
|
|
23
|
-
const assetRoot = node_path.resolve(metadata.packageRoot, metadata.assetPath);
|
|
24
|
-
const hashesPath = node_path.join(metadata.packageRoot, 'dist', 'claude-hashes.json');
|
|
25
|
-
const hashesPresent = await promises.stat(hashesPath).then(() => true, () => false);
|
|
26
|
-
const target = {
|
|
27
|
-
name: metadata.packageName,
|
|
28
|
-
version: metadata.packageVersion,
|
|
29
|
-
packageRoot: metadata.packageRoot,
|
|
30
|
-
assetRoot,
|
|
31
|
-
hashesPresent,
|
|
32
|
-
};
|
|
33
|
-
let exitCode;
|
|
34
|
-
try {
|
|
35
|
-
exitCode = await injectOne.injectOne(target, scope, flags, originCwd);
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
39
|
-
logger.logger.error(`${target.name}: ${msg}`);
|
|
40
|
-
exitCode = 1;
|
|
41
|
-
}
|
|
42
|
-
if (exitCode !== 0) {
|
|
43
|
-
if (fatalOnError)
|
|
44
|
-
process.exit(exitCode);
|
|
45
|
-
failureCount += 1;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (failureCount > 0)
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
exports.runInject = runInject;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { stat } from 'node:fs/promises';
|
|
2
|
-
import { isAbsolute, resolve, join } from 'node:path';
|
|
3
|
-
import { logger } from '../../../utils/logger.mjs';
|
|
4
|
-
import { injectOne } from './injectOne.mjs';
|
|
5
|
-
import { resolveScopeFlag } from './resolveScopeFlag.mjs';
|
|
6
|
-
|
|
7
|
-
async function runInject(flags, metadataList) {
|
|
8
|
-
if (metadataList.length === 0)
|
|
9
|
-
return;
|
|
10
|
-
for (const metadata of metadataList) {
|
|
11
|
-
if (!isAbsolute(metadata.packageRoot)) {
|
|
12
|
-
logger.error(`packageRoot must be an absolute path; received: ${metadata.packageRoot}`);
|
|
13
|
-
process.exit(2);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
const originCwd = flags.root ?? process.cwd();
|
|
17
|
-
const scope = await resolveScopeFlag(flags.scope);
|
|
18
|
-
const fatalOnError = metadataList.length === 1;
|
|
19
|
-
let failureCount = 0;
|
|
20
|
-
for (const metadata of metadataList) {
|
|
21
|
-
const assetRoot = resolve(metadata.packageRoot, metadata.assetPath);
|
|
22
|
-
const hashesPath = join(metadata.packageRoot, 'dist', 'claude-hashes.json');
|
|
23
|
-
const hashesPresent = await stat(hashesPath).then(() => true, () => false);
|
|
24
|
-
const target = {
|
|
25
|
-
name: metadata.packageName,
|
|
26
|
-
version: metadata.packageVersion,
|
|
27
|
-
packageRoot: metadata.packageRoot,
|
|
28
|
-
assetRoot,
|
|
29
|
-
hashesPresent,
|
|
30
|
-
};
|
|
31
|
-
let exitCode;
|
|
32
|
-
try {
|
|
33
|
-
exitCode = await injectOne(target, scope, flags, originCwd);
|
|
34
|
-
}
|
|
35
|
-
catch (err) {
|
|
36
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
37
|
-
logger.error(`${target.name}: ${msg}`);
|
|
38
|
-
exitCode = 1;
|
|
39
|
-
}
|
|
40
|
-
if (exitCode !== 0) {
|
|
41
|
-
if (fatalOnError)
|
|
42
|
-
process.exit(exitCode);
|
|
43
|
-
failureCount += 1;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
if (failureCount > 0)
|
|
47
|
-
process.exit(1);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export { runInject };
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var node_path = require('node:path');
|
|
4
|
-
var hash = require('../hash/hash.cjs');
|
|
5
|
-
var toPosix = require('./utils/toPosix.cjs');
|
|
6
|
-
var walkFiles = require('./utils/walkFiles.cjs');
|
|
7
|
-
|
|
8
|
-
async function buildPlan(input) {
|
|
9
|
-
const { sourceHashes, targetRoot, namespacePrefixes, force } = input;
|
|
10
|
-
const actions = [];
|
|
11
|
-
let requiresForce = false;
|
|
12
|
-
for (const [relPath, srcHash] of Object.entries(sourceHashes)) {
|
|
13
|
-
const dstAbs = node_path.join(targetRoot, relPath);
|
|
14
|
-
const dstHash = await hash.hashFile(dstAbs);
|
|
15
|
-
if (dstHash === null)
|
|
16
|
-
actions.push({ kind: 'copy', relPath, dstAbs });
|
|
17
|
-
else if (hash.hashEquals(dstHash, srcHash))
|
|
18
|
-
actions.push({ kind: 'skip-uptodate', relPath, dstAbs });
|
|
19
|
-
else {
|
|
20
|
-
actions.push({ kind: 'warn-diverged', relPath, dstAbs });
|
|
21
|
-
requiresForce = true;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
const known = new Set(Object.keys(sourceHashes));
|
|
25
|
-
for (const prefix of namespacePrefixes) {
|
|
26
|
-
const prefixRoot = node_path.join(targetRoot, prefix);
|
|
27
|
-
for await (const abs of walkFiles.walkFiles(prefixRoot)) {
|
|
28
|
-
const relPath = toPosix.toPosix(node_path.relative(targetRoot, abs));
|
|
29
|
-
if (known.has(relPath))
|
|
30
|
-
continue;
|
|
31
|
-
if (force)
|
|
32
|
-
actions.push({ kind: 'delete', relPath, dstAbs: abs });
|
|
33
|
-
else {
|
|
34
|
-
actions.push({ kind: 'warn-orphan', relPath, dstAbs: abs });
|
|
35
|
-
requiresForce = true;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return { actions, requiresForce };
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
exports.buildPlan = buildPlan;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var promises = require('node:fs/promises');
|
|
4
|
-
var node_path = require('node:path');
|
|
5
|
-
|
|
6
|
-
async function* walkFiles(root) {
|
|
7
|
-
let entries;
|
|
8
|
-
try {
|
|
9
|
-
entries = await promises.readdir(root, { withFileTypes: true });
|
|
10
|
-
}
|
|
11
|
-
catch (err) {
|
|
12
|
-
if (err.code === 'ENOENT')
|
|
13
|
-
return;
|
|
14
|
-
throw err;
|
|
15
|
-
}
|
|
16
|
-
for (const entry of entries) {
|
|
17
|
-
const abs = node_path.join(root, entry.name);
|
|
18
|
-
if (entry.isDirectory())
|
|
19
|
-
yield* walkFiles(abs);
|
|
20
|
-
else if (entry.isFile())
|
|
21
|
-
yield abs;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
exports.walkFiles = walkFiles;
|
package/dist/core/hash/hash.cjs
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var node_crypto = require('node:crypto');
|
|
4
|
-
var promises = require('node:fs/promises');
|
|
5
|
-
|
|
6
|
-
function hashContent(buffer) {
|
|
7
|
-
return node_crypto.createHash('sha256').update(buffer).digest('hex');
|
|
8
|
-
}
|
|
9
|
-
async function hashFile(absPath) {
|
|
10
|
-
try {
|
|
11
|
-
const buf = await promises.readFile(absPath);
|
|
12
|
-
return hashContent(buf);
|
|
13
|
-
}
|
|
14
|
-
catch (err) {
|
|
15
|
-
if (err.code === 'ENOENT')
|
|
16
|
-
return null;
|
|
17
|
-
throw err;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function hashEquals(a, b) {
|
|
21
|
-
if (a === null || b === null)
|
|
22
|
-
return false;
|
|
23
|
-
if (a.length !== b.length)
|
|
24
|
-
return false;
|
|
25
|
-
return a.toLowerCase() === b.toLowerCase();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
exports.hashContent = hashContent;
|
|
29
|
-
exports.hashEquals = hashEquals;
|
|
30
|
-
exports.hashFile = hashFile;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var promises = require('node:fs/promises');
|
|
4
|
-
var node_path = require('node:path');
|
|
5
|
-
|
|
6
|
-
const HASH_MANIFEST_FILENAME = 'claude-hashes.json';
|
|
7
|
-
async function readHashManifest(packageRoot) {
|
|
8
|
-
const primary = node_path.join(packageRoot, 'dist', HASH_MANIFEST_FILENAME);
|
|
9
|
-
const raw = await promises.readFile(primary, 'utf-8');
|
|
10
|
-
const parsed = JSON.parse(raw);
|
|
11
|
-
if (parsed.schemaVersion !== 1)
|
|
12
|
-
throw new Error(`[claude-assets-sync] Unsupported manifest schemaVersion: ${parsed.schemaVersion}`);
|
|
13
|
-
return parsed;
|
|
14
|
-
}
|
|
15
|
-
function computeNamespacePrefixes(manifest) {
|
|
16
|
-
const prefixes = new Set();
|
|
17
|
-
for (const relPath of Object.keys(manifest.files)) {
|
|
18
|
-
const parts = relPath.split('/');
|
|
19
|
-
if (parts.length >= 3 && parts[0] === 'skills')
|
|
20
|
-
prefixes.add(`${parts[0]}/${parts[1]}/`);
|
|
21
|
-
}
|
|
22
|
-
return [...prefixes];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
exports.HASH_MANIFEST_FILENAME = HASH_MANIFEST_FILENAME;
|
|
26
|
-
exports.computeNamespacePrefixes = computeNamespacePrefixes;
|
|
27
|
-
exports.readHashManifest = readHashManifest;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var asyncPool = require('../../utils/asyncPool.cjs');
|
|
4
|
-
var logger = require('../../utils/logger.cjs');
|
|
5
|
-
var buildPlan = require('../buildPlan/buildPlan.cjs');
|
|
6
|
-
var hashManifest = require('../hashManifest/hashManifest.cjs');
|
|
7
|
-
var scope = require('../scope/scope.cjs');
|
|
8
|
-
var applyAction = require('./utils/applyAction.cjs');
|
|
9
|
-
var emitCiForceList = require('./utils/emitCiForceList.cjs');
|
|
10
|
-
var printPlan = require('./utils/printPlan.cjs');
|
|
11
|
-
var summarize = require('./utils/summarize.cjs');
|
|
12
|
-
|
|
13
|
-
async function injectDocs(opts) {
|
|
14
|
-
const manifest = await hashManifest.readHashManifest(opts.packageRoot);
|
|
15
|
-
const resolution = scope.resolveScope(opts.scope, opts.originCwd ?? process.cwd());
|
|
16
|
-
const plan = await buildPlan.buildPlan({
|
|
17
|
-
sourceHashes: manifest.files,
|
|
18
|
-
targetRoot: resolution.targetRoot,
|
|
19
|
-
namespacePrefixes: hashManifest.computeNamespacePrefixes(manifest),
|
|
20
|
-
force: opts.force,
|
|
21
|
-
});
|
|
22
|
-
logger.logger.info(`${opts.packageName}@${opts.packageVersion} → ${resolution.description}`);
|
|
23
|
-
printPlan.printPlan(plan);
|
|
24
|
-
if (plan.requiresForce && !opts.force) {
|
|
25
|
-
logger.logger.error('Re-run with --force to proceed, or inspect with --dry-run.');
|
|
26
|
-
return summarize.summarize(plan, 2);
|
|
27
|
-
}
|
|
28
|
-
if (opts.force &&
|
|
29
|
-
plan.actions.some((a) => a.kind === 'warn-diverged' || a.kind === 'warn-orphan')) {
|
|
30
|
-
if (!scope.isInteractive())
|
|
31
|
-
emitCiForceList.emitCiForceList(plan);
|
|
32
|
-
else if (opts.confirmForce && !(await opts.confirmForce(plan)))
|
|
33
|
-
return summarize.summarize(plan, 2);
|
|
34
|
-
}
|
|
35
|
-
if (opts.dryRun) {
|
|
36
|
-
logger.logger.warn('[DRY RUN] No files will be created, overwritten, or deleted.');
|
|
37
|
-
return summarize.summarize(plan, 0);
|
|
38
|
-
}
|
|
39
|
-
await asyncPool.asyncPool(8, plan.actions, (action) => applyAction.applyAction(action, opts.assetRoot));
|
|
40
|
-
return summarize.summarize(plan, 0);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
exports.injectDocs = injectDocs;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { asyncPool } from '../../utils/asyncPool.mjs';
|
|
2
|
-
import { logger } from '../../utils/logger.mjs';
|
|
3
|
-
import { buildPlan } from '../buildPlan/buildPlan.mjs';
|
|
4
|
-
import { readHashManifest, computeNamespacePrefixes } from '../hashManifest/hashManifest.mjs';
|
|
5
|
-
import { resolveScope, isInteractive } from '../scope/scope.mjs';
|
|
6
|
-
import { applyAction } from './utils/applyAction.mjs';
|
|
7
|
-
import { emitCiForceList } from './utils/emitCiForceList.mjs';
|
|
8
|
-
import { printPlan } from './utils/printPlan.mjs';
|
|
9
|
-
import { summarize } from './utils/summarize.mjs';
|
|
10
|
-
|
|
11
|
-
async function injectDocs(opts) {
|
|
12
|
-
const manifest = await readHashManifest(opts.packageRoot);
|
|
13
|
-
const resolution = resolveScope(opts.scope, opts.originCwd ?? process.cwd());
|
|
14
|
-
const plan = await buildPlan({
|
|
15
|
-
sourceHashes: manifest.files,
|
|
16
|
-
targetRoot: resolution.targetRoot,
|
|
17
|
-
namespacePrefixes: computeNamespacePrefixes(manifest),
|
|
18
|
-
force: opts.force,
|
|
19
|
-
});
|
|
20
|
-
logger.info(`${opts.packageName}@${opts.packageVersion} → ${resolution.description}`);
|
|
21
|
-
printPlan(plan);
|
|
22
|
-
if (plan.requiresForce && !opts.force) {
|
|
23
|
-
logger.error('Re-run with --force to proceed, or inspect with --dry-run.');
|
|
24
|
-
return summarize(plan, 2);
|
|
25
|
-
}
|
|
26
|
-
if (opts.force &&
|
|
27
|
-
plan.actions.some((a) => a.kind === 'warn-diverged' || a.kind === 'warn-orphan')) {
|
|
28
|
-
if (!isInteractive())
|
|
29
|
-
emitCiForceList(plan);
|
|
30
|
-
else if (opts.confirmForce && !(await opts.confirmForce(plan)))
|
|
31
|
-
return summarize(plan, 2);
|
|
32
|
-
}
|
|
33
|
-
if (opts.dryRun) {
|
|
34
|
-
logger.warn('[DRY RUN] No files will be created, overwritten, or deleted.');
|
|
35
|
-
return summarize(plan, 0);
|
|
36
|
-
}
|
|
37
|
-
await asyncPool(8, plan.actions, (action) => applyAction(action, opts.assetRoot));
|
|
38
|
-
return summarize(plan, 0);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export { injectDocs };
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var promises = require('node:fs/promises');
|
|
4
|
-
var node_path = require('node:path');
|
|
5
|
-
var logger = require('../../../utils/logger.cjs');
|
|
6
|
-
|
|
7
|
-
async function applyAction(action, assetRoot) {
|
|
8
|
-
if (action.kind === 'copy') {
|
|
9
|
-
const srcAbs = node_path.join(assetRoot, action.relPath);
|
|
10
|
-
await promises.mkdir(node_path.dirname(action.dstAbs), { recursive: true });
|
|
11
|
-
await promises.copyFile(srcAbs, action.dstAbs);
|
|
12
|
-
}
|
|
13
|
-
else if (action.kind === 'delete')
|
|
14
|
-
await promises.unlink(action.dstAbs).catch((error) => {
|
|
15
|
-
if (error?.code !== 'ENOENT') {
|
|
16
|
-
logger.logger.warn(`[claude-assets-sync] unlink failed: ${action.dstAbs} (${error?.code ?? error})`);
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
exports.applyAction = applyAction;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function emitCiForceList(plan) {
|
|
4
|
-
const divergent = plan.actions.filter((a) => a.kind === 'warn-diverged' || a.kind === 'warn-orphan');
|
|
5
|
-
process.stderr.write(`[claude-assets-sync] --force overwriting ${divergent.length} file(s) in non-TTY mode:\n`);
|
|
6
|
-
for (const a of divergent)
|
|
7
|
-
process.stderr.write(` ${a.relPath}\n`);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
exports.emitCiForceList = emitCiForceList;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
function emitCiForceList(plan) {
|
|
2
|
-
const divergent = plan.actions.filter((a) => a.kind === 'warn-diverged' || a.kind === 'warn-orphan');
|
|
3
|
-
process.stderr.write(`[claude-assets-sync] --force overwriting ${divergent.length} file(s) in non-TTY mode:\n`);
|
|
4
|
-
for (const a of divergent)
|
|
5
|
-
process.stderr.write(` ${a.relPath}\n`);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export { emitCiForceList };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var logger = require('../../../utils/logger.cjs');
|
|
4
|
-
|
|
5
|
-
function printPlan(plan) {
|
|
6
|
-
for (const a of plan.actions) {
|
|
7
|
-
if (a.kind === 'copy')
|
|
8
|
-
logger.logger.file('create', a.relPath);
|
|
9
|
-
else if (a.kind === 'skip-uptodate')
|
|
10
|
-
logger.logger.file('skip', `${a.relPath} (up-to-date)`);
|
|
11
|
-
else if (a.kind === 'warn-diverged')
|
|
12
|
-
logger.logger.warn(`${a.relPath} — local differs from source (user edit or version change)`);
|
|
13
|
-
else if (a.kind === 'warn-orphan')
|
|
14
|
-
logger.logger.warn(`${a.relPath} — present locally, absent in source`);
|
|
15
|
-
else if (a.kind === 'delete')
|
|
16
|
-
logger.logger.file('update', `${a.relPath} (deleting)`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
exports.printPlan = printPlan;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { logger } from '../../../utils/logger.mjs';
|
|
2
|
-
|
|
3
|
-
function printPlan(plan) {
|
|
4
|
-
for (const a of plan.actions) {
|
|
5
|
-
if (a.kind === 'copy')
|
|
6
|
-
logger.file('create', a.relPath);
|
|
7
|
-
else if (a.kind === 'skip-uptodate')
|
|
8
|
-
logger.file('skip', `${a.relPath} (up-to-date)`);
|
|
9
|
-
else if (a.kind === 'warn-diverged')
|
|
10
|
-
logger.warn(`${a.relPath} — local differs from source (user edit or version change)`);
|
|
11
|
-
else if (a.kind === 'warn-orphan')
|
|
12
|
-
logger.warn(`${a.relPath} — present locally, absent in source`);
|
|
13
|
-
else if (a.kind === 'delete')
|
|
14
|
-
logger.file('update', `${a.relPath} (deleting)`);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { printPlan };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function summarize(plan, exitCode) {
|
|
4
|
-
const report = {
|
|
5
|
-
created: [],
|
|
6
|
-
updated: [],
|
|
7
|
-
skipped: [],
|
|
8
|
-
warnings: [],
|
|
9
|
-
deleted: [],
|
|
10
|
-
exitCode,
|
|
11
|
-
};
|
|
12
|
-
for (const a of plan.actions) {
|
|
13
|
-
if (a.kind === 'copy')
|
|
14
|
-
report.created.push(a.relPath);
|
|
15
|
-
else if (a.kind === 'skip-uptodate')
|
|
16
|
-
report.skipped.push(a.relPath);
|
|
17
|
-
else if (a.kind === 'warn-diverged')
|
|
18
|
-
report.warnings.push({ relPath: a.relPath, reason: 'diverged' });
|
|
19
|
-
else if (a.kind === 'warn-orphan')
|
|
20
|
-
report.warnings.push({ relPath: a.relPath, reason: 'orphan' });
|
|
21
|
-
else if (a.kind === 'delete')
|
|
22
|
-
report.deleted.push(a.relPath);
|
|
23
|
-
}
|
|
24
|
-
return report;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
exports.summarize = summarize;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var node_os = require('node:os');
|
|
4
|
-
var node_path = require('node:path');
|
|
5
|
-
var isDirectory = require('./utils/isDirectory.cjs');
|
|
6
|
-
|
|
7
|
-
function isValidScope(value) {
|
|
8
|
-
return value === 'user' || value === 'project';
|
|
9
|
-
}
|
|
10
|
-
function findNearestDotClaudeAncestor(start) {
|
|
11
|
-
let current = start;
|
|
12
|
-
while (true) {
|
|
13
|
-
if (isDirectory.isDirectory(node_path.join(current, '.claude')))
|
|
14
|
-
return current;
|
|
15
|
-
const parent = node_path.dirname(current);
|
|
16
|
-
if (parent === current)
|
|
17
|
-
return null;
|
|
18
|
-
current = parent;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function resolveScope(scope, cwd = process.cwd()) {
|
|
22
|
-
if (scope === 'user') {
|
|
23
|
-
return {
|
|
24
|
-
scope,
|
|
25
|
-
targetRoot: node_path.join(node_os.homedir(), '.claude'),
|
|
26
|
-
description: '~/.claude (user)',
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
const ancestor = findNearestDotClaudeAncestor(cwd);
|
|
30
|
-
const base = ancestor ?? cwd;
|
|
31
|
-
return {
|
|
32
|
-
scope,
|
|
33
|
-
targetRoot: node_path.join(base, '.claude'),
|
|
34
|
-
description: ancestor !== null
|
|
35
|
-
? `${base}/.claude (project, auto-located)`
|
|
36
|
-
: `${base}/.claude (project)`,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function isInteractive() {
|
|
40
|
-
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
exports.findNearestDotClaudeAncestor = findNearestDotClaudeAncestor;
|
|
44
|
-
exports.isInteractive = isInteractive;
|
|
45
|
-
exports.isValidScope = isValidScope;
|
|
46
|
-
exports.resolveScope = resolveScope;
|
package/dist/index.cjs
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var runCli = require('./commands/runCli/runCli.cjs');
|
|
4
|
-
require('node:crypto');
|
|
5
|
-
require('node:fs/promises');
|
|
6
|
-
var hashManifest = require('./core/hashManifest/hashManifest.cjs');
|
|
7
|
-
var injectDocs = require('./core/injectDocs/injectDocs.cjs');
|
|
8
|
-
require('node:path');
|
|
9
|
-
var scope = require('./core/scope/scope.cjs');
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
exports.runCli = runCli.runCli;
|
|
14
|
-
exports.HASH_MANIFEST_FILENAME = hashManifest.HASH_MANIFEST_FILENAME;
|
|
15
|
-
exports.computeNamespacePrefixes = hashManifest.computeNamespacePrefixes;
|
|
16
|
-
exports.readHashManifest = hashManifest.readHashManifest;
|
|
17
|
-
exports.injectDocs = injectDocs.injectDocs;
|
|
18
|
-
exports.isInteractive = scope.isInteractive;
|
|
19
|
-
exports.isValidScope = scope.isValidScope;
|
|
20
|
-
exports.resolveScope = scope.resolveScope;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var prompts = require('@inquirer/prompts');
|
|
4
|
-
var pc = require('picocolors');
|
|
5
|
-
|
|
6
|
-
async function confirmForceAsync(divergedCount, orphanCount, relPaths) {
|
|
7
|
-
const extra = Math.max(0, divergedCount + orphanCount - relPaths.length);
|
|
8
|
-
const divergedPart = pc.red(pc.bold(`${divergedCount} diverged file(s)`));
|
|
9
|
-
const orphanPart = orphanCount > 0
|
|
10
|
-
? ` and ${pc.red(pc.bold(`delete ${orphanCount} orphan(s)`))}`
|
|
11
|
-
: '';
|
|
12
|
-
process.stderr.write(`${pc.yellow(pc.bold('!'))} This will overwrite ${divergedPart}${orphanPart}:\n`);
|
|
13
|
-
for (const p of relPaths) {
|
|
14
|
-
process.stderr.write(` ${pc.dim('-')} ${p}\n`);
|
|
15
|
-
}
|
|
16
|
-
if (extra > 0) {
|
|
17
|
-
process.stderr.write(` ${pc.dim(`... and ${extra} more`)}\n`);
|
|
18
|
-
}
|
|
19
|
-
process.stderr.write('\n');
|
|
20
|
-
const answer = await prompts.confirm({
|
|
21
|
-
message: pc.bold('Do you have these in git? Proceed?'),
|
|
22
|
-
default: false,
|
|
23
|
-
});
|
|
24
|
-
return answer;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
exports.confirmForceAsync = confirmForceAsync;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function confirmForceAsync(divergedCount: number, orphanCount: number, relPaths: string[]): Promise<boolean>;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { confirm } from '@inquirer/prompts';
|
|
2
|
-
import pc from 'picocolors';
|
|
3
|
-
|
|
4
|
-
async function confirmForceAsync(divergedCount, orphanCount, relPaths) {
|
|
5
|
-
const extra = Math.max(0, divergedCount + orphanCount - relPaths.length);
|
|
6
|
-
const divergedPart = pc.red(pc.bold(`${divergedCount} diverged file(s)`));
|
|
7
|
-
const orphanPart = orphanCount > 0
|
|
8
|
-
? ` and ${pc.red(pc.bold(`delete ${orphanCount} orphan(s)`))}`
|
|
9
|
-
: '';
|
|
10
|
-
process.stderr.write(`${pc.yellow(pc.bold('!'))} This will overwrite ${divergedPart}${orphanPart}:\n`);
|
|
11
|
-
for (const p of relPaths) {
|
|
12
|
-
process.stderr.write(` ${pc.dim('-')} ${p}\n`);
|
|
13
|
-
}
|
|
14
|
-
if (extra > 0) {
|
|
15
|
-
process.stderr.write(` ${pc.dim(`... and ${extra} more`)}\n`);
|
|
16
|
-
}
|
|
17
|
-
process.stderr.write('\n');
|
|
18
|
-
const answer = await confirm({
|
|
19
|
-
message: pc.bold('Do you have these in git? Proceed?'),
|
|
20
|
-
default: false,
|
|
21
|
-
});
|
|
22
|
-
return answer;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export { confirmForceAsync };
|
package/dist/prompts/index.d.ts
DELETED