@slats/claude-assets-sync 0.1.0 → 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.
Files changed (67) hide show
  1. package/dist/commands/add.cjs +24 -0
  2. package/dist/commands/add.d.ts +2 -6
  3. package/dist/commands/add.mjs +24 -0
  4. package/dist/commands/index.d.ts +1 -2
  5. package/dist/commands/list.cjs +12 -1
  6. package/dist/commands/list.d.ts +10 -1
  7. package/dist/commands/list.mjs +12 -2
  8. package/dist/commands/remove.cjs +49 -31
  9. package/dist/commands/remove.mjs +49 -30
  10. package/dist/commands/types.d.ts +9 -0
  11. package/dist/commands/update.cjs +27 -0
  12. package/dist/commands/update.d.ts +16 -0
  13. package/dist/commands/update.mjs +27 -1
  14. package/dist/components/add/BulkAddView.cjs +165 -0
  15. package/dist/components/add/BulkAddView.d.ts +11 -0
  16. package/dist/components/add/BulkAddView.mjs +163 -0
  17. package/dist/components/list/ListCommand.cjs +585 -392
  18. package/dist/components/list/ListCommand.d.ts +0 -3
  19. package/dist/components/list/ListCommand.mjs +590 -377
  20. package/dist/components/list/index.d.ts +1 -0
  21. package/dist/components/list/types.d.ts +14 -0
  22. package/dist/components/remove/RemoveConfirm.cjs +18 -0
  23. package/dist/components/remove/RemoveConfirm.d.ts +11 -0
  24. package/dist/components/remove/RemoveConfirm.mjs +16 -0
  25. package/dist/components/shared/Confirm.cjs +30 -0
  26. package/dist/components/shared/Confirm.d.ts +8 -0
  27. package/dist/components/shared/Confirm.mjs +28 -0
  28. package/dist/components/shared/MenuItem.cjs +18 -0
  29. package/dist/components/shared/MenuItem.d.ts +7 -0
  30. package/dist/components/shared/MenuItem.mjs +16 -0
  31. package/dist/components/shared/ProgressBar.d.ts +7 -0
  32. package/dist/components/shared/StepRunner.cjs +58 -0
  33. package/dist/components/shared/StepRunner.d.ts +15 -0
  34. package/dist/components/shared/StepRunner.mjs +56 -0
  35. package/dist/components/shared/Table.cjs +19 -0
  36. package/dist/components/shared/Table.d.ts +8 -0
  37. package/dist/components/shared/Table.mjs +17 -0
  38. package/dist/components/shared/index.d.ts +6 -0
  39. package/dist/core/cli.cjs +4 -8
  40. package/dist/core/cli.mjs +5 -9
  41. package/dist/core/constants.cjs +2 -0
  42. package/dist/core/constants.d.ts +5 -1
  43. package/dist/core/constants.mjs +2 -1
  44. package/dist/core/io.mjs +1 -1
  45. package/dist/core/listOperations.cjs +228 -0
  46. package/dist/core/listOperations.d.ts +43 -0
  47. package/dist/core/listOperations.mjs +205 -0
  48. package/dist/core/localSource.cjs +10 -2
  49. package/dist/core/localSource.mjs +10 -2
  50. package/dist/core/packageScanner.cjs +14 -9
  51. package/dist/core/packageScanner.mjs +15 -10
  52. package/dist/core/sync.cjs +9 -15
  53. package/dist/core/sync.mjs +10 -16
  54. package/dist/core/syncMeta.d.ts +1 -1
  55. package/dist/utils/asyncPool.cjs +26 -0
  56. package/dist/utils/asyncPool.d.ts +5 -0
  57. package/dist/utils/asyncPool.mjs +24 -0
  58. package/dist/utils/dependencies.cjs +57 -0
  59. package/dist/utils/dependencies.d.ts +10 -0
  60. package/dist/utils/dependencies.mjs +34 -0
  61. package/dist/utils/package.cjs +24 -2
  62. package/dist/utils/package.d.ts +15 -1
  63. package/dist/utils/package.mjs +24 -4
  64. package/dist/version.cjs +1 -1
  65. package/dist/version.d.ts +1 -1
  66. package/dist/version.mjs +1 -1
  67. package/package.json +2 -1
@@ -7,3 +7,4 @@ export { ListCommand } from './ListCommand.js';
7
7
  export type { EditableTreeItemProps } from './EditableTreeItem.js';
8
8
  export type { SyncedPackageTreeProps } from './SyncedPackageTree.js';
9
9
  export type { ListCommandProps } from './ListCommand.js';
10
+ export type { ListPhase, SelectItem, PackageDetailInfo } from './types.js';
@@ -0,0 +1,14 @@
1
+ export type ListPhase = 'loading' | 'main-menu' | 'package-list' | 'package-detail' | 'sync-action' | 'remove-action' | 'update-action' | 'edit-assets' | 'status-view' | 'confirming' | 'done' | 'error';
2
+ export interface SelectItem {
3
+ label: string;
4
+ value: string;
5
+ }
6
+ export interface PackageDetailInfo {
7
+ prefix: string;
8
+ originalName: string;
9
+ version: string;
10
+ local: boolean;
11
+ syncedAt?: string;
12
+ files: Record<string, any[]>;
13
+ totalAssets: number;
14
+ }
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var ink = require('ink');
5
+ var React = require('react');
6
+ var Confirm = require('../shared/Confirm.cjs');
7
+ require('ink-spinner');
8
+
9
+ const RemoveConfirm = ({ packageName, filesToRemove, onConfirm, }) => {
10
+ const { exit } = ink.useApp();
11
+ const handleConfirm = React.useCallback((yes) => {
12
+ onConfirm(yes);
13
+ exit();
14
+ }, [onConfirm, exit]);
15
+ return (jsxRuntime.jsx(Confirm.Confirm, { message: `Remove ${filesToRemove.length} file(s) from ${packageName}?`, onConfirm: handleConfirm, defaultYes: false }));
16
+ };
17
+
18
+ exports.RemoveConfirm = RemoveConfirm;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ interface RemoveConfirmProps {
3
+ packageName: string;
4
+ filesToRemove: Array<{
5
+ assetType: string;
6
+ path: string;
7
+ }>;
8
+ onConfirm: (yes: boolean) => void;
9
+ }
10
+ export declare const RemoveConfirm: React.FC<RemoveConfirmProps>;
11
+ export {};
@@ -0,0 +1,16 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useApp } from 'ink';
3
+ import { useCallback } from 'react';
4
+ import { Confirm } from '../shared/Confirm.mjs';
5
+ import 'ink-spinner';
6
+
7
+ const RemoveConfirm = ({ packageName, filesToRemove, onConfirm, }) => {
8
+ const { exit } = useApp();
9
+ const handleConfirm = useCallback((yes) => {
10
+ onConfirm(yes);
11
+ exit();
12
+ }, [onConfirm, exit]);
13
+ return (jsx(Confirm, { message: `Remove ${filesToRemove.length} file(s) from ${packageName}?`, onConfirm: handleConfirm, defaultYes: false }));
14
+ };
15
+
16
+ export { RemoveConfirm };
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var ink = require('ink');
5
+ var React = require('react');
6
+
7
+ const Confirm = ({ message, onConfirm, defaultYes = true, }) => {
8
+ const [answered, setAnswered] = React.useState(false);
9
+ ink.useInput((input, key) => {
10
+ if (answered)
11
+ return;
12
+ if (input === 'y' || input === 'Y') {
13
+ setAnswered(true);
14
+ onConfirm(true);
15
+ }
16
+ else if (input === 'n' || input === 'N') {
17
+ setAnswered(true);
18
+ onConfirm(false);
19
+ }
20
+ else if (key.return) {
21
+ setAnswered(true);
22
+ onConfirm(defaultYes);
23
+ }
24
+ });
25
+ const yText = defaultYes ? jsxRuntime.jsx(ink.Text, { bold: true, children: "Y" }) : jsxRuntime.jsx(ink.Text, { dimColor: true, children: "y" });
26
+ const nText = defaultYes ? jsxRuntime.jsx(ink.Text, { dimColor: true, children: "n" }) : jsxRuntime.jsx(ink.Text, { bold: true, children: "N" });
27
+ return (jsxRuntime.jsxs(ink.Text, { children: [jsxRuntime.jsx(ink.Text, { color: "cyan", children: "? " }), message, " ", jsxRuntime.jsx(ink.Text, { color: "gray", children: "[" }), yText, jsxRuntime.jsx(ink.Text, { color: "gray", children: "/" }), nText, jsxRuntime.jsx(ink.Text, { color: "gray", children: "]" })] }));
28
+ };
29
+
30
+ exports.Confirm = Confirm;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ interface ConfirmProps {
3
+ message: string;
4
+ onConfirm: (yes: boolean) => void;
5
+ defaultYes?: boolean;
6
+ }
7
+ export declare const Confirm: React.FC<ConfirmProps>;
8
+ export {};
@@ -0,0 +1,28 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useInput, Text } from 'ink';
3
+ import { useState } from 'react';
4
+
5
+ const Confirm = ({ message, onConfirm, defaultYes = true, }) => {
6
+ const [answered, setAnswered] = useState(false);
7
+ useInput((input, key) => {
8
+ if (answered)
9
+ return;
10
+ if (input === 'y' || input === 'Y') {
11
+ setAnswered(true);
12
+ onConfirm(true);
13
+ }
14
+ else if (input === 'n' || input === 'N') {
15
+ setAnswered(true);
16
+ onConfirm(false);
17
+ }
18
+ else if (key.return) {
19
+ setAnswered(true);
20
+ onConfirm(defaultYes);
21
+ }
22
+ });
23
+ const yText = defaultYes ? jsx(Text, { bold: true, children: "Y" }) : jsx(Text, { dimColor: true, children: "y" });
24
+ const nText = defaultYes ? jsx(Text, { dimColor: true, children: "n" }) : jsx(Text, { bold: true, children: "N" });
25
+ return (jsxs(Text, { children: [jsx(Text, { color: "cyan", children: "? " }), message, " ", jsx(Text, { color: "gray", children: "[" }), yText, jsx(Text, { color: "gray", children: "/" }), nText, jsx(Text, { color: "gray", children: "]" })] }));
26
+ };
27
+
28
+ export { Confirm };
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var ink = require('ink');
5
+
6
+ const MenuItem = ({ isSelected = false, label, }) => {
7
+ if (label === 'Delete' || label === 'Remove') {
8
+ return (jsxRuntime.jsx(ink.Text, { bold: isSelected, color: "red", children: label }));
9
+ }
10
+ const match = label.match(/^(.+?)\s+\((\d+)\)$/);
11
+ if (match) {
12
+ const [, name, count] = match;
13
+ return (jsxRuntime.jsxs(ink.Text, { children: [jsxRuntime.jsx(ink.Text, { bold: isSelected, children: name }), " ", jsxRuntime.jsxs(ink.Text, { dimColor: true, children: ["(", count, ")"] })] }));
14
+ }
15
+ return jsxRuntime.jsx(ink.Text, { bold: isSelected, children: label });
16
+ };
17
+
18
+ exports.MenuItem = MenuItem;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface MenuItemProps {
3
+ isSelected?: boolean;
4
+ label: string;
5
+ }
6
+ export declare const MenuItem: React.FC<MenuItemProps>;
7
+ export {};
@@ -0,0 +1,16 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { Text } from 'ink';
3
+
4
+ const MenuItem = ({ isSelected = false, label, }) => {
5
+ if (label === 'Delete' || label === 'Remove') {
6
+ return (jsx(Text, { bold: isSelected, color: "red", children: label }));
7
+ }
8
+ const match = label.match(/^(.+?)\s+\((\d+)\)$/);
9
+ if (match) {
10
+ const [, name, count] = match;
11
+ return (jsxs(Text, { children: [jsx(Text, { bold: isSelected, children: name }), " ", jsxs(Text, { dimColor: true, children: ["(", count, ")"] })] }));
12
+ }
13
+ return jsx(Text, { bold: isSelected, children: label });
14
+ };
15
+
16
+ export { MenuItem };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface ProgressBarProps {
3
+ percent: number;
4
+ width?: number;
5
+ }
6
+ export declare const ProgressBar: React.FC<ProgressBarProps>;
7
+ export {};
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var ink = require('ink');
5
+ var Spinner = require('ink-spinner');
6
+
7
+ const StepIcon = ({ status }) => {
8
+ switch (status) {
9
+ case 'success':
10
+ return jsxRuntime.jsx(ink.Text, { color: "green", children: "\u2713" });
11
+ case 'running':
12
+ return (jsxRuntime.jsx(ink.Text, { color: "yellow", children: jsxRuntime.jsx(Spinner, { type: "dots" }) }));
13
+ case 'skipped':
14
+ return jsxRuntime.jsx(ink.Text, { color: "blue", children: "\u23ED" });
15
+ case 'failed':
16
+ return jsxRuntime.jsx(ink.Text, { color: "red", children: "\u2717" });
17
+ case 'pending':
18
+ default:
19
+ return jsxRuntime.jsx(ink.Text, { color: "gray", children: "\u25CB" });
20
+ }
21
+ };
22
+ const StepStatusText = ({ step }) => {
23
+ switch (step.status) {
24
+ case 'success':
25
+ return (jsxRuntime.jsxs(ink.Text, { color: "green", children: ["Done", step.duration != null
26
+ ? ` (${Math.round(step.duration / 1000)}s)`
27
+ : ''] }));
28
+ case 'running':
29
+ return jsxRuntime.jsx(ink.Text, { color: "yellow", children: "Running..." });
30
+ case 'skipped':
31
+ return jsxRuntime.jsx(ink.Text, { color: "blue", children: "Skipped" });
32
+ case 'failed':
33
+ return (jsxRuntime.jsxs(ink.Text, { color: "red", children: ["Failed", step.error ? `: ${step.error}` : ''] }));
34
+ case 'pending':
35
+ default:
36
+ return null;
37
+ }
38
+ };
39
+ const StepItemView = ({ step, index, total, isLast, }) => (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", marginBottom: isLast ? 0 : 1, children: [jsxRuntime.jsxs(ink.Text, { children: [' ', jsxRuntime.jsx(StepIcon, { status: step.status }), jsxRuntime.jsxs(ink.Text, { children: [' ', jsxRuntime.jsxs(ink.Text, { bold: true, children: ["Step ", index + 1, "/", total] }), ' ', step.name] })] }), step.output && step.status !== 'pending' && (jsxRuntime.jsxs(ink.Text, { color: "gray", children: [' ', step.output] })), jsxRuntime.jsxs(ink.Text, { children: [' ', jsxRuntime.jsx(StepStatusText, { step: step })] })] }));
40
+ const StepRunner = ({ steps, total }) => {
41
+ const completedSteps = [];
42
+ const activeSteps = [];
43
+ steps.forEach((step, idx) => {
44
+ const indexed = { ...step, idx };
45
+ if (step.status === 'success' ||
46
+ step.status === 'failed' ||
47
+ step.status === 'skipped') {
48
+ completedSteps.push(indexed);
49
+ }
50
+ else {
51
+ activeSteps.push(indexed);
52
+ }
53
+ });
54
+ const lastIdx = steps.length - 1;
55
+ return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Static, { items: completedSteps, children: (item) => (jsxRuntime.jsx(StepItemView, { step: item, index: item.idx, total: total, isLast: item.idx === lastIdx && activeSteps.length === 0 }, item.idx)) }), activeSteps.map((item) => (jsxRuntime.jsx(StepItemView, { step: item, index: item.idx, total: total, isLast: item.idx === lastIdx }, item.idx)))] }));
56
+ };
57
+
58
+ exports.StepRunner = StepRunner;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export interface StepResult {
3
+ name: string;
4
+ status: 'pending' | 'running' | 'success' | 'failed' | 'skipped';
5
+ error?: string;
6
+ duration?: number;
7
+ output?: string;
8
+ }
9
+ interface StepRunnerProps {
10
+ steps: StepResult[];
11
+ currentStep: number;
12
+ total: number;
13
+ }
14
+ export declare const StepRunner: React.FC<StepRunnerProps>;
15
+ export {};
@@ -0,0 +1,56 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Box, Static, Text } from 'ink';
3
+ import Spinner from 'ink-spinner';
4
+
5
+ const StepIcon = ({ status }) => {
6
+ switch (status) {
7
+ case 'success':
8
+ return jsx(Text, { color: "green", children: "\u2713" });
9
+ case 'running':
10
+ return (jsx(Text, { color: "yellow", children: jsx(Spinner, { type: "dots" }) }));
11
+ case 'skipped':
12
+ return jsx(Text, { color: "blue", children: "\u23ED" });
13
+ case 'failed':
14
+ return jsx(Text, { color: "red", children: "\u2717" });
15
+ case 'pending':
16
+ default:
17
+ return jsx(Text, { color: "gray", children: "\u25CB" });
18
+ }
19
+ };
20
+ const StepStatusText = ({ step }) => {
21
+ switch (step.status) {
22
+ case 'success':
23
+ return (jsxs(Text, { color: "green", children: ["Done", step.duration != null
24
+ ? ` (${Math.round(step.duration / 1000)}s)`
25
+ : ''] }));
26
+ case 'running':
27
+ return jsx(Text, { color: "yellow", children: "Running..." });
28
+ case 'skipped':
29
+ return jsx(Text, { color: "blue", children: "Skipped" });
30
+ case 'failed':
31
+ return (jsxs(Text, { color: "red", children: ["Failed", step.error ? `: ${step.error}` : ''] }));
32
+ case 'pending':
33
+ default:
34
+ return null;
35
+ }
36
+ };
37
+ const StepItemView = ({ step, index, total, isLast, }) => (jsxs(Box, { flexDirection: "column", marginBottom: isLast ? 0 : 1, children: [jsxs(Text, { children: [' ', jsx(StepIcon, { status: step.status }), jsxs(Text, { children: [' ', jsxs(Text, { bold: true, children: ["Step ", index + 1, "/", total] }), ' ', step.name] })] }), step.output && step.status !== 'pending' && (jsxs(Text, { color: "gray", children: [' ', step.output] })), jsxs(Text, { children: [' ', jsx(StepStatusText, { step: step })] })] }));
38
+ const StepRunner = ({ steps, total }) => {
39
+ const completedSteps = [];
40
+ const activeSteps = [];
41
+ steps.forEach((step, idx) => {
42
+ const indexed = { ...step, idx };
43
+ if (step.status === 'success' ||
44
+ step.status === 'failed' ||
45
+ step.status === 'skipped') {
46
+ completedSteps.push(indexed);
47
+ }
48
+ else {
49
+ activeSteps.push(indexed);
50
+ }
51
+ });
52
+ const lastIdx = steps.length - 1;
53
+ return (jsxs(Box, { flexDirection: "column", children: [jsx(Static, { items: completedSteps, children: (item) => (jsx(StepItemView, { step: item, index: item.idx, total: total, isLast: item.idx === lastIdx && activeSteps.length === 0 }, item.idx)) }), activeSteps.map((item) => (jsx(StepItemView, { step: item, index: item.idx, total: total, isLast: item.idx === lastIdx }, item.idx)))] }));
54
+ };
55
+
56
+ export { StepRunner };
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var ink = require('ink');
5
+
6
+ const Table = ({ headers, rows, columnWidths, }) => {
7
+ const widths = columnWidths ??
8
+ headers.map((header, colIdx) => {
9
+ const dataMax = rows.reduce((max, row) => Math.max(max, (row[colIdx] ?? '').length), 0);
10
+ return Math.max(header.length, dataMax) + 2;
11
+ });
12
+ const padCell = (text, width) => {
13
+ return text.padEnd(width);
14
+ };
15
+ const separator = widths.map((w) => '─'.repeat(w)).join(' ');
16
+ return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Text, { children: headers.map((h, i) => (jsxRuntime.jsxs(ink.Text, { bold: true, children: [padCell(h, widths[i]), i < headers.length - 1 ? ' ' : ''] }, i))) }), jsxRuntime.jsx(ink.Text, { color: "gray", children: separator }), rows.map((row, rowIdx) => (jsxRuntime.jsx(ink.Text, { children: row.map((cell, colIdx) => (jsxRuntime.jsxs(ink.Text, { children: [padCell(cell, widths[colIdx]), colIdx < row.length - 1 ? ' ' : ''] }, colIdx))) }, rowIdx)))] }));
17
+ };
18
+
19
+ exports.Table = Table;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ interface TableProps {
3
+ headers: string[];
4
+ rows: string[][];
5
+ columnWidths?: number[];
6
+ }
7
+ export declare const Table: React.FC<TableProps>;
8
+ export {};
@@ -0,0 +1,17 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Box, Text } from 'ink';
3
+
4
+ const Table = ({ headers, rows, columnWidths, }) => {
5
+ const widths = columnWidths ??
6
+ headers.map((header, colIdx) => {
7
+ const dataMax = rows.reduce((max, row) => Math.max(max, (row[colIdx] ?? '').length), 0);
8
+ return Math.max(header.length, dataMax) + 2;
9
+ });
10
+ const padCell = (text, width) => {
11
+ return text.padEnd(width);
12
+ };
13
+ const separator = widths.map((w) => '─'.repeat(w)).join(' ');
14
+ return (jsxs(Box, { flexDirection: "column", children: [jsx(Text, { children: headers.map((h, i) => (jsxs(Text, { bold: true, children: [padCell(h, widths[i]), i < headers.length - 1 ? ' ' : ''] }, i))) }), jsx(Text, { color: "gray", children: separator }), rows.map((row, rowIdx) => (jsx(Text, { children: row.map((cell, colIdx) => (jsxs(Text, { children: [padCell(cell, widths[colIdx]), colIdx < row.length - 1 ? ' ' : ''] }, colIdx))) }, rowIdx)))] }));
15
+ };
16
+
17
+ export { Table };
@@ -0,0 +1,6 @@
1
+ export { Confirm } from './Confirm.js';
2
+ export { MenuItem } from './MenuItem.js';
3
+ export { ProgressBar } from './ProgressBar.js';
4
+ export { StepRunner } from './StepRunner.js';
5
+ export type { StepResult } from './StepRunner.js';
6
+ export { Table } from './Table.js';
package/dist/core/cli.cjs CHANGED
@@ -38,23 +38,19 @@ const createProgram = () => {
38
38
  program
39
39
  .command('add')
40
40
  .description('Add a package with interactive asset selection')
41
- .requiredOption('-p, --package <name>', 'Package name to add')
41
+ .option('-p, --package <name>', 'Package name to add')
42
+ .option('--pattern <regex>', 'Regex pattern to bulk add matching packages')
42
43
  .option('-l, --local', 'Read packages from local workspace instead of node_modules', false)
43
44
  .option('-r, --ref <ref>', 'Git ref (branch, tag, or commit) to fetch from')
44
45
  .action(async (opts) => {
45
46
  await add.runAddCommand({
46
47
  package: opts.package,
48
+ pattern: opts.pattern,
47
49
  local: opts.local,
48
50
  ref: opts.ref,
49
51
  });
50
52
  });
51
- program
52
- .command('list')
53
- .description('List all synced packages')
54
- .option('--json', 'Output as JSON')
55
- .action(async (opts) => {
56
- await list.runListCommand({ json: opts.json });
57
- });
53
+ list.registerListCommand(program);
58
54
  program
59
55
  .command('remove')
60
56
  .description('Remove a synced package')
package/dist/core/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Command } from 'commander';
2
2
  import { runSyncCommand } from '../commands/sync.mjs';
3
- import { runListCommand } from '../commands/list.mjs';
3
+ import { registerListCommand } from '../commands/list.mjs';
4
4
  import { runRemoveCommand } from '../commands/remove.mjs';
5
5
  import { runStatusCommand } from '../commands/status.mjs';
6
6
  import { runMigrateCommand } from '../commands/migrate.mjs';
@@ -36,23 +36,19 @@ const createProgram = () => {
36
36
  program
37
37
  .command('add')
38
38
  .description('Add a package with interactive asset selection')
39
- .requiredOption('-p, --package <name>', 'Package name to add')
39
+ .option('-p, --package <name>', 'Package name to add')
40
+ .option('--pattern <regex>', 'Regex pattern to bulk add matching packages')
40
41
  .option('-l, --local', 'Read packages from local workspace instead of node_modules', false)
41
42
  .option('-r, --ref <ref>', 'Git ref (branch, tag, or commit) to fetch from')
42
43
  .action(async (opts) => {
43
44
  await runAddCommand({
44
45
  package: opts.package,
46
+ pattern: opts.pattern,
45
47
  local: opts.local,
46
48
  ref: opts.ref,
47
49
  });
48
50
  });
49
- program
50
- .command('list')
51
- .description('List all synced packages')
52
- .option('--json', 'Output as JSON')
53
- .action(async (opts) => {
54
- await runListCommand({ json: opts.json });
55
- });
51
+ registerListCommand(program);
56
52
  program
57
53
  .command('remove')
58
54
  .description('Remove a synced package')
@@ -3,6 +3,7 @@
3
3
  var version = require('../version.cjs');
4
4
 
5
5
  const CLAUDE_BASE_DIR = '.claude';
6
+ const DEFAULT_ASSET_PATH = 'docs/claude';
6
7
  const META_FILES = {
7
8
  SYNC_META: '.sync-meta.json',
8
9
  UNIFIED_SYNC_META: '.claude/.sync-meta.json',
@@ -20,6 +21,7 @@ const FS_PATTERNS = {
20
21
  };
21
22
 
22
23
  exports.CLAUDE_BASE_DIR = CLAUDE_BASE_DIR;
24
+ exports.DEFAULT_ASSET_PATH = DEFAULT_ASSET_PATH;
23
25
  exports.DEFAULT_ASSET_TYPES = DEFAULT_ASSET_TYPES;
24
26
  exports.FS_PATTERNS = FS_PATTERNS;
25
27
  exports.META_FILES = META_FILES;
@@ -2,6 +2,10 @@
2
2
  * Base directory for Claude assets
3
3
  */
4
4
  export declare const CLAUDE_BASE_DIR: ".claude";
5
+ /**
6
+ * Default asset path when claude.assetPath is not configured
7
+ */
8
+ export declare const DEFAULT_ASSET_PATH: "docs/claude";
5
9
  /**
6
10
  * Asset directory names
7
11
  */
@@ -22,7 +26,7 @@ export declare const META_FILES: {
22
26
  * Schema versions for metadata files
23
27
  */
24
28
  export declare const SCHEMA_VERSIONS: {
25
- readonly UNIFIED_SYNC_META: "0.1.0";
29
+ readonly UNIFIED_SYNC_META: "0.1.2";
26
30
  readonly LEGACY_SYNC_META: "1.0.0";
27
31
  readonly SKILL_UNIT_FORMAT: "2";
28
32
  };
@@ -1,6 +1,7 @@
1
1
  import { VERSION } from '../version.mjs';
2
2
 
3
3
  const CLAUDE_BASE_DIR = '.claude';
4
+ const DEFAULT_ASSET_PATH = 'docs/claude';
4
5
  const META_FILES = {
5
6
  SYNC_META: '.sync-meta.json',
6
7
  UNIFIED_SYNC_META: '.claude/.sync-meta.json',
@@ -17,4 +18,4 @@ const FS_PATTERNS = {
17
18
  GITHUB_SHORTHAND: /^github:([^/]+)\/([^/]+)$/,
18
19
  };
19
20
 
20
- export { CLAUDE_BASE_DIR, DEFAULT_ASSET_TYPES, FS_PATTERNS, META_FILES, SCHEMA_VERSIONS };
21
+ export { CLAUDE_BASE_DIR, DEFAULT_ASSET_PATH, DEFAULT_ASSET_TYPES, FS_PATTERNS, META_FILES, SCHEMA_VERSIONS };
package/dist/core/io.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'node:fs';
1
+ import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync } from 'node:fs';
2
2
  import { dirname } from 'node:path';
3
3
 
4
4
  function readJsonFile(path) {