@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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { applyAction } from '../../core/injectDocs/utils/applyAction.mjs';
|
|
2
|
+
import { summarize } from '../../core/injectDocs/utils/summarize.mjs';
|
|
3
|
+
import { asyncPool } from '../../utils/asyncPool.mjs';
|
|
4
|
+
|
|
5
|
+
const CONCURRENCY = 8;
|
|
6
|
+
async function applyAllPlans({ plans, dryRun, dispatch, }) {
|
|
7
|
+
const total = plans.reduce((acc, tp) => acc + tp.plan.actions.length, 0);
|
|
8
|
+
let done = 0;
|
|
9
|
+
dispatch({ type: 'apply-start', total });
|
|
10
|
+
if (dryRun) {
|
|
11
|
+
const reports = plans.map((tp) => summarize(tp.plan, 0));
|
|
12
|
+
dispatch({ type: 'done', reports, exitCode: 0, dryRun: true });
|
|
13
|
+
return { reports, exitCode: 0 };
|
|
14
|
+
}
|
|
15
|
+
const reports = [];
|
|
16
|
+
for (const tp of plans) {
|
|
17
|
+
await asyncPool(CONCURRENCY, tp.plan.actions, async (action) => {
|
|
18
|
+
await applyAction(action, tp.target.assetRoot);
|
|
19
|
+
done += 1;
|
|
20
|
+
dispatch({ type: 'apply-progress', done, current: action.relPath });
|
|
21
|
+
});
|
|
22
|
+
reports.push(summarize(tp.plan, 0));
|
|
23
|
+
}
|
|
24
|
+
const hasFailure = reports.some((r) => r.exitCode !== 0);
|
|
25
|
+
const exitCode = hasFailure ? 1 : 0;
|
|
26
|
+
dispatch({ type: 'done', reports, exitCode, dryRun: false });
|
|
27
|
+
return { reports, exitCode };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { applyAllPlans };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface UseExitAppOptions {
|
|
2
|
+
readonly enabled: boolean;
|
|
3
|
+
readonly exitCode: 0 | 1 | 2;
|
|
4
|
+
readonly onExit: (code: 0 | 1 | 2) => void;
|
|
5
|
+
readonly delayMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function useExitApp({ enabled, exitCode, onExit, delayMs, }: UseExitAppOptions): void;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useApp } from 'ink';
|
|
3
|
+
|
|
4
|
+
function useExitApp({ enabled, exitCode, onExit, delayMs = 0, }) {
|
|
5
|
+
const { exit } = useApp();
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!enabled)
|
|
8
|
+
return;
|
|
9
|
+
const handle = setTimeout(() => {
|
|
10
|
+
onExit(exitCode);
|
|
11
|
+
exit();
|
|
12
|
+
}, delayMs);
|
|
13
|
+
return () => {
|
|
14
|
+
clearTimeout(handle);
|
|
15
|
+
};
|
|
16
|
+
}, [enabled, exitCode, delayMs, exit, onExit]);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { useExitApp };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { InjectEvent, TargetPlan, Warning } from '../types/index.js';
|
|
2
|
+
interface RequestForceConfirmInput {
|
|
3
|
+
readonly plans: readonly TargetPlan[];
|
|
4
|
+
readonly warnings: readonly Warning[];
|
|
5
|
+
readonly force: boolean;
|
|
6
|
+
readonly dispatch: (event: InjectEvent) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function requestForceConfirm({ plans, warnings, force, dispatch, }: RequestForceConfirmInput): Promise<boolean>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
async function requestForceConfirm({ plans, warnings, force, dispatch, }) {
|
|
2
|
+
const hasWarnings = plans.some((p) => p.plan.requiresForce);
|
|
3
|
+
if (!hasWarnings)
|
|
4
|
+
return true;
|
|
5
|
+
if (!force) {
|
|
6
|
+
dispatch({
|
|
7
|
+
type: 'fail',
|
|
8
|
+
error: new Error('Re-run with --force to proceed, or inspect with --dry-run.'),
|
|
9
|
+
});
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
dispatch({
|
|
14
|
+
type: 'force-confirm-required',
|
|
15
|
+
warnings,
|
|
16
|
+
pending: (ok) => {
|
|
17
|
+
dispatch({ type: 'force-answer', ok });
|
|
18
|
+
resolve(ok);
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { requestForceConfirm };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ConsumerPackage, DefaultFlags } from '../../commands/runCli/type.js';
|
|
2
|
+
import type { InjectEvent } from '../types/index.js';
|
|
3
|
+
interface UseInjectSessionOptions {
|
|
4
|
+
readonly targets: readonly ConsumerPackage[];
|
|
5
|
+
readonly flags: DefaultFlags;
|
|
6
|
+
readonly originCwd: string;
|
|
7
|
+
readonly dispatch: (event: InjectEvent) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function useInjectSession({ targets, flags, originCwd, dispatch, }: UseInjectSessionOptions): void;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
2
|
+
import { applyAllPlans } from './useApplyStep.mjs';
|
|
3
|
+
import { requestForceConfirm } from './useForceConfirmStep.mjs';
|
|
4
|
+
import { usePlanStep } from './usePlanStep.mjs';
|
|
5
|
+
import { useResolveStep } from './useResolveStep.mjs';
|
|
6
|
+
|
|
7
|
+
function useInjectSession({ targets, flags, originCwd, dispatch, }) {
|
|
8
|
+
const [scope, setScope] = useState(null);
|
|
9
|
+
const [plansReady, setPlansReady] = useState(null);
|
|
10
|
+
const pipelineStarted = useRef(false);
|
|
11
|
+
const onScopeResolved = useCallback((resolved) => {
|
|
12
|
+
setScope(resolved);
|
|
13
|
+
}, []);
|
|
14
|
+
const onPlansReady = useCallback((plans, warnings) => {
|
|
15
|
+
setPlansReady({ plans, warnings });
|
|
16
|
+
}, []);
|
|
17
|
+
useResolveStep({ targets, flags, dispatch, onScopeResolved });
|
|
18
|
+
usePlanStep({
|
|
19
|
+
targets,
|
|
20
|
+
scope,
|
|
21
|
+
originCwd,
|
|
22
|
+
force: Boolean(flags.force),
|
|
23
|
+
dispatch,
|
|
24
|
+
onPlansReady,
|
|
25
|
+
});
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!plansReady || pipelineStarted.current)
|
|
28
|
+
return;
|
|
29
|
+
pipelineStarted.current = true;
|
|
30
|
+
(async () => {
|
|
31
|
+
const { plans, warnings } = plansReady;
|
|
32
|
+
if (plans.length === 0) {
|
|
33
|
+
dispatch({
|
|
34
|
+
type: 'done',
|
|
35
|
+
reports: [],
|
|
36
|
+
exitCode: 2,
|
|
37
|
+
dryRun: Boolean(flags.dryRun),
|
|
38
|
+
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const ok = await requestForceConfirm({
|
|
42
|
+
plans,
|
|
43
|
+
warnings,
|
|
44
|
+
force: Boolean(flags.force),
|
|
45
|
+
dispatch,
|
|
46
|
+
});
|
|
47
|
+
if (!ok)
|
|
48
|
+
return;
|
|
49
|
+
await applyAllPlans({
|
|
50
|
+
plans,
|
|
51
|
+
dryRun: Boolean(flags.dryRun),
|
|
52
|
+
dispatch,
|
|
53
|
+
});
|
|
54
|
+
})().catch((error) => {
|
|
55
|
+
dispatch({
|
|
56
|
+
type: 'fail',
|
|
57
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}, [plansReady, flags.force, flags.dryRun, dispatch]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { useInjectSession };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useInterval(callback: () => void, delayMs: number | null): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ConsumerPackage } from '../../commands/runCli/type.js';
|
|
2
|
+
import { type Scope } from '../../core/index.js';
|
|
3
|
+
import type { InjectEvent, TargetPlan, Warning } from '../types/index.js';
|
|
4
|
+
interface UsePlanStepOptions {
|
|
5
|
+
readonly targets: readonly ConsumerPackage[];
|
|
6
|
+
readonly scope: Scope | null;
|
|
7
|
+
readonly originCwd: string;
|
|
8
|
+
readonly force: boolean;
|
|
9
|
+
readonly dispatch: (event: InjectEvent) => void;
|
|
10
|
+
readonly onPlansReady: (plans: readonly TargetPlan[], warnings: readonly Warning[]) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function usePlanStep({ targets, scope, originCwd, force, dispatch, onPlansReady, }: UsePlanStepOptions): void;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
import 'node:crypto';
|
|
3
|
+
import 'node:fs/promises';
|
|
4
|
+
import { readHashManifest, computeNamespacePrefixes } from '../../core/hashManifest/hashManifest.mjs';
|
|
5
|
+
import 'node:path';
|
|
6
|
+
import 'picocolors';
|
|
7
|
+
import { buildPlan } from '../../core/buildPlan/buildPlan.mjs';
|
|
8
|
+
import { resolveScope } from '../../core/scope/scope.mjs';
|
|
9
|
+
|
|
10
|
+
function usePlanStep({ targets, scope, originCwd, force, dispatch, onPlansReady, }) {
|
|
11
|
+
const startedRef = useRef(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (!scope || startedRef.current)
|
|
14
|
+
return;
|
|
15
|
+
startedRef.current = true;
|
|
16
|
+
let cancelled = false;
|
|
17
|
+
(async () => {
|
|
18
|
+
const results = [];
|
|
19
|
+
const warnings = [];
|
|
20
|
+
for (const target of targets) {
|
|
21
|
+
if (cancelled)
|
|
22
|
+
return;
|
|
23
|
+
dispatch({
|
|
24
|
+
type: 'plan-step',
|
|
25
|
+
step: { packageName: target.name, status: 'running' },
|
|
26
|
+
});
|
|
27
|
+
try {
|
|
28
|
+
if (!target.hashesPresent) {
|
|
29
|
+
dispatch({
|
|
30
|
+
type: 'plan-step',
|
|
31
|
+
step: {
|
|
32
|
+
packageName: target.name,
|
|
33
|
+
status: 'failed',
|
|
34
|
+
error: 'dist/claude-hashes.json missing',
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const manifest = await readHashManifest(target.packageRoot);
|
|
40
|
+
const scopeResolution = resolveScope(scope, originCwd);
|
|
41
|
+
const plan = await buildPlan({
|
|
42
|
+
sourceHashes: manifest.files,
|
|
43
|
+
targetRoot: scopeResolution.targetRoot,
|
|
44
|
+
namespacePrefixes: computeNamespacePrefixes(manifest),
|
|
45
|
+
force,
|
|
46
|
+
});
|
|
47
|
+
results.push({ target, scope: scopeResolution, plan });
|
|
48
|
+
for (const action of plan.actions) {
|
|
49
|
+
if (action.kind === 'warn-diverged' || action.kind === 'warn-orphan') {
|
|
50
|
+
warnings.push({
|
|
51
|
+
packageName: target.name,
|
|
52
|
+
kind: action.kind,
|
|
53
|
+
relPath: action.relPath,
|
|
54
|
+
description: action.kind === 'warn-diverged'
|
|
55
|
+
? 'local differs from source (user edit or version change)'
|
|
56
|
+
: 'exists locally but not in manifest',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
dispatch({
|
|
61
|
+
type: 'plan-step',
|
|
62
|
+
step: { packageName: target.name, status: 'done' },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
dispatch({
|
|
67
|
+
type: 'plan-step',
|
|
68
|
+
step: {
|
|
69
|
+
packageName: target.name,
|
|
70
|
+
status: 'failed',
|
|
71
|
+
error: error instanceof Error ? error.message : String(error),
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (cancelled)
|
|
77
|
+
return;
|
|
78
|
+
dispatch({ type: 'plans-ready', plans: results });
|
|
79
|
+
onPlansReady(results, warnings);
|
|
80
|
+
})().catch((error) => {
|
|
81
|
+
if (!cancelled) {
|
|
82
|
+
dispatch({
|
|
83
|
+
type: 'fail',
|
|
84
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return () => {
|
|
89
|
+
cancelled = true;
|
|
90
|
+
};
|
|
91
|
+
}, [targets, scope, originCwd, force, dispatch, onPlansReady]);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { usePlanStep };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ConsumerPackage } from '../../commands/runCli/type.js';
|
|
2
|
+
import type { Scope } from '../../core/index.js';
|
|
3
|
+
import type { InjectEvent } from '../types/index.js';
|
|
4
|
+
interface UseResolveStepOptions {
|
|
5
|
+
readonly targets: readonly ConsumerPackage[];
|
|
6
|
+
readonly flags: {
|
|
7
|
+
readonly scope?: string;
|
|
8
|
+
};
|
|
9
|
+
readonly dispatch: (event: InjectEvent) => void;
|
|
10
|
+
readonly onScopeResolved: (scope: Scope) => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Ink path is guaranteed TTY by `renderOrFallback`, so interactive
|
|
14
|
+
* scope selection is always safe. Non-TTY invocations go through
|
|
15
|
+
* `renderPlain` + `resolveScopeFlag` which exits 2 on missing scope.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useResolveStep({ targets, flags, dispatch, onScopeResolved, }: UseResolveStepOptions): void;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useResolveStep({ targets, flags, dispatch, onScopeResolved, }) {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (flags.scope === 'user' || flags.scope === 'project') {
|
|
6
|
+
const resolved = flags.scope;
|
|
7
|
+
dispatch({ type: 'scope-selected', scope: resolved });
|
|
8
|
+
dispatch({ type: 'planning-started', targets, scope: resolved });
|
|
9
|
+
onScopeResolved(resolved);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const pending = (scope) => {
|
|
13
|
+
dispatch({ type: 'scope-selected', scope });
|
|
14
|
+
dispatch({ type: 'planning-started', targets, scope });
|
|
15
|
+
onScopeResolved(scope);
|
|
16
|
+
};
|
|
17
|
+
dispatch({ type: 'scope-needed', pending });
|
|
18
|
+
}, [targets, flags.scope, dispatch, onScopeResolved]);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { useResolveStep };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useTerminalWidth(): number;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { renderInjectApp } from './InjectApp/utils/renderInjectApp.mjs';
|
|
2
|
+
import 'react/jsx-runtime';
|
|
3
|
+
import 'react';
|
|
4
|
+
import 'ink';
|
|
5
|
+
import 'ink-select-input';
|
|
6
|
+
import 'ink-spinner';
|
|
7
|
+
import 'node:fs/promises';
|
|
8
|
+
import 'node:path';
|
|
9
|
+
import 'picocolors';
|
|
10
|
+
import 'node:crypto';
|
|
11
|
+
import 'node:os';
|
|
12
|
+
import 'node:fs';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
export { renderInjectApp };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const colors: {
|
|
2
|
+
readonly primary: "cyan";
|
|
3
|
+
readonly success: "green";
|
|
4
|
+
readonly warn: "yellow";
|
|
5
|
+
readonly danger: "red";
|
|
6
|
+
readonly muted: "gray";
|
|
7
|
+
readonly accent: "magenta";
|
|
8
|
+
readonly info: "blue";
|
|
9
|
+
readonly dim: "gray";
|
|
10
|
+
};
|
|
11
|
+
export declare const gradientStops: readonly ["#22d3ee", "#a78bfa", "#f59e0b"];
|
|
12
|
+
export type ColorName = (typeof colors)[keyof typeof colors];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const icons: {
|
|
2
|
+
readonly bulletDone: "●";
|
|
3
|
+
readonly bulletActive: "◐";
|
|
4
|
+
readonly bulletPending: "○";
|
|
5
|
+
readonly triangleRight: "▸";
|
|
6
|
+
readonly check: "✓";
|
|
7
|
+
readonly cross: "✗";
|
|
8
|
+
readonly warning: "⚠";
|
|
9
|
+
readonly question: "?";
|
|
10
|
+
readonly plus: "+";
|
|
11
|
+
readonly equals: "=";
|
|
12
|
+
readonly minus: "−";
|
|
13
|
+
readonly tilde: "~";
|
|
14
|
+
readonly blockFull: "█";
|
|
15
|
+
readonly blockEmpty: "░";
|
|
16
|
+
readonly dash: "─";
|
|
17
|
+
readonly divider: "───";
|
|
18
|
+
readonly boxTopLeft: "╭";
|
|
19
|
+
readonly boxTopRight: "╮";
|
|
20
|
+
readonly boxBottomLeft: "╰";
|
|
21
|
+
readonly boxBottomRight: "╯";
|
|
22
|
+
readonly boxHorizontal: "─";
|
|
23
|
+
readonly boxVertical: "│";
|
|
24
|
+
readonly boxDoubleTopLeft: "┌";
|
|
25
|
+
readonly boxDoubleTopRight: "┐";
|
|
26
|
+
readonly boxDoubleBottomLeft: "└";
|
|
27
|
+
readonly boxDoubleBottomRight: "┘";
|
|
28
|
+
};
|
|
29
|
+
export type IconName = keyof typeof icons;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const icons = {
|
|
2
|
+
bulletDone: '●',
|
|
3
|
+
bulletActive: '◐',
|
|
4
|
+
bulletPending: '○',
|
|
5
|
+
triangleRight: '▸',
|
|
6
|
+
check: '✓',
|
|
7
|
+
cross: '✗',
|
|
8
|
+
warning: '⚠',
|
|
9
|
+
question: '?',
|
|
10
|
+
plus: '+',
|
|
11
|
+
equals: '=',
|
|
12
|
+
minus: '−',
|
|
13
|
+
blockFull: '█',
|
|
14
|
+
blockEmpty: '░',
|
|
15
|
+
divider: '───'};
|
|
16
|
+
|
|
17
|
+
export { icons };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const spacing: {
|
|
2
|
+
readonly xs: 0;
|
|
3
|
+
readonly sm: 1;
|
|
4
|
+
readonly md: 2;
|
|
5
|
+
readonly lg: 3;
|
|
6
|
+
readonly xl: 4;
|
|
7
|
+
};
|
|
8
|
+
export declare const widths: {
|
|
9
|
+
readonly statusBadge: 10;
|
|
10
|
+
readonly pathColumn: 60;
|
|
11
|
+
readonly progressBarDefault: 28;
|
|
12
|
+
readonly targetCardCount: 18;
|
|
13
|
+
readonly minTerminalWidth: 60;
|
|
14
|
+
readonly idealTerminalWidth: 120;
|
|
15
|
+
};
|
|
16
|
+
export declare const limits: {
|
|
17
|
+
readonly maxWarningsBeforeCollapse: 10;
|
|
18
|
+
readonly maxPlanRowsBeforeTruncate: 40;
|
|
19
|
+
readonly planTruncatedReveal: 15;
|
|
20
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ConsumerPackage } from '../../commands/runCli/type.js';
|
|
2
|
+
import type { InjectReport, Scope } from '../../core/index.js';
|
|
3
|
+
import type { PlanStepState, TargetPlan, Warning } from './target.js';
|
|
4
|
+
export type InjectEvent = {
|
|
5
|
+
readonly type: 'scope-needed';
|
|
6
|
+
readonly pending: (scope: Scope) => void;
|
|
7
|
+
} | {
|
|
8
|
+
readonly type: 'scope-selected';
|
|
9
|
+
readonly scope: Scope;
|
|
10
|
+
} | {
|
|
11
|
+
readonly type: 'planning-started';
|
|
12
|
+
readonly targets: readonly ConsumerPackage[];
|
|
13
|
+
readonly scope: Scope;
|
|
14
|
+
} | {
|
|
15
|
+
readonly type: 'plan-step';
|
|
16
|
+
readonly step: PlanStepState;
|
|
17
|
+
} | {
|
|
18
|
+
readonly type: 'plans-ready';
|
|
19
|
+
readonly plans: readonly TargetPlan[];
|
|
20
|
+
} | {
|
|
21
|
+
readonly type: 'force-confirm-required';
|
|
22
|
+
readonly warnings: readonly Warning[];
|
|
23
|
+
readonly pending: (ok: boolean) => void;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: 'force-answer';
|
|
26
|
+
readonly ok: boolean;
|
|
27
|
+
} | {
|
|
28
|
+
readonly type: 'apply-start';
|
|
29
|
+
readonly total: number;
|
|
30
|
+
} | {
|
|
31
|
+
readonly type: 'apply-progress';
|
|
32
|
+
readonly done: number;
|
|
33
|
+
readonly current?: string;
|
|
34
|
+
} | {
|
|
35
|
+
readonly type: 'done';
|
|
36
|
+
readonly reports: readonly InjectReport[];
|
|
37
|
+
readonly exitCode: 0 | 1 | 2;
|
|
38
|
+
readonly dryRun: boolean;
|
|
39
|
+
} | {
|
|
40
|
+
readonly type: 'fail';
|
|
41
|
+
readonly error: Error;
|
|
42
|
+
} | {
|
|
43
|
+
readonly type: 'focus-target';
|
|
44
|
+
readonly index: number;
|
|
45
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ConsumerPackage } from '../../commands/runCli/type.js';
|
|
2
|
+
import type { InjectReport, Scope } from '../../core/index.js';
|
|
3
|
+
import type { ApplyProgress, PlanStepState, TargetPlan, Warning } from './target.js';
|
|
4
|
+
export type Phase = {
|
|
5
|
+
readonly kind: 'booting';
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: 'resolving';
|
|
8
|
+
readonly targets: readonly ConsumerPackage[];
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'scope-select';
|
|
11
|
+
readonly targets: readonly ConsumerPackage[];
|
|
12
|
+
readonly pending: (scope: Scope) => void;
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: 'planning';
|
|
15
|
+
readonly targets: readonly ConsumerPackage[];
|
|
16
|
+
readonly scope: Scope;
|
|
17
|
+
readonly progress: ReadonlyMap<string, PlanStepState>;
|
|
18
|
+
} | {
|
|
19
|
+
readonly kind: 'diff-review';
|
|
20
|
+
readonly plans: readonly TargetPlan[];
|
|
21
|
+
readonly focusedIndex: number;
|
|
22
|
+
readonly scope: Scope;
|
|
23
|
+
} | {
|
|
24
|
+
readonly kind: 'force-confirm';
|
|
25
|
+
readonly plans: readonly TargetPlan[];
|
|
26
|
+
readonly warnings: readonly Warning[];
|
|
27
|
+
readonly pending: (ok: boolean) => void;
|
|
28
|
+
readonly scope: Scope;
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: 'applying';
|
|
31
|
+
readonly plans: readonly TargetPlan[];
|
|
32
|
+
readonly progress: ApplyProgress;
|
|
33
|
+
readonly scope: Scope;
|
|
34
|
+
} | {
|
|
35
|
+
readonly kind: 'summary';
|
|
36
|
+
readonly reports: readonly InjectReport[];
|
|
37
|
+
readonly plans: readonly TargetPlan[];
|
|
38
|
+
readonly exitCode: 0 | 1 | 2;
|
|
39
|
+
readonly scope: Scope;
|
|
40
|
+
readonly dryRun: boolean;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: 'error';
|
|
43
|
+
readonly error: Error;
|
|
44
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { InjectPlan } from '../../core/buildPlan/index.js';
|
|
2
|
+
import type { ScopeResolution } from '../../core/index.js';
|
|
3
|
+
import type { ConsumerPackage } from '../../commands/runCli/type.js';
|
|
4
|
+
export interface PlanStepState {
|
|
5
|
+
readonly packageName: string;
|
|
6
|
+
readonly status: 'pending' | 'running' | 'done' | 'failed';
|
|
7
|
+
readonly error?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface TargetPlan {
|
|
10
|
+
readonly target: ConsumerPackage;
|
|
11
|
+
readonly scope: ScopeResolution;
|
|
12
|
+
readonly plan: InjectPlan;
|
|
13
|
+
}
|
|
14
|
+
export interface Warning {
|
|
15
|
+
readonly packageName: string;
|
|
16
|
+
readonly kind: 'warn-diverged' | 'warn-orphan';
|
|
17
|
+
readonly relPath: string;
|
|
18
|
+
readonly description: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ApplyProgress {
|
|
21
|
+
readonly total: number;
|
|
22
|
+
readonly done: number;
|
|
23
|
+
readonly current?: string;
|
|
24
|
+
readonly startedAt: number;
|
|
25
|
+
}
|
package/dist/utils/version.d.ts
CHANGED
package/dist/utils/version.mjs
CHANGED
|
@@ -78,7 +78,7 @@ See `knowledge/package-json-patches.md` for the complete patch list:
|
|
|
78
78
|
- `scripts.build` — ensure the chain ends with `&& yarn build:hashes`.
|
|
79
79
|
- `scripts.build:hashes` — set to `claude-build-hashes` (the engine's bin).
|
|
80
80
|
- `scripts.prepublishOnly` — `yarn build` if not already present.
|
|
81
|
-
- `
|
|
81
|
+
- `devDependencies."@slats/claude-assets-sync"` — add (NOT `dependencies`, NOT `peerDependencies`). The engine is CLI-only and must not leak into end-user production installs.
|
|
82
82
|
- `files` — ensure `"dist"`, `"docs"`, `"README.md"` are listed. Never include `"bin"` or `"scripts"`.
|
|
83
83
|
|
|
84
84
|
Do NOT add any `bin` entry. Do NOT add `./bin/*` or `./docs/*` to `exports`.
|