@detergent-software/atk 3.0.0 → 4.0.0
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 +361 -0
- package/build/commands/_app.d.ts.map +1 -1
- package/build/commands/_app.js +23 -3
- package/build/commands/_app.js.map +1 -1
- package/build/commands/audit.d.ts.map +1 -1
- package/build/commands/audit.js +76 -37
- package/build/commands/audit.js.map +1 -1
- package/build/commands/browse.d.ts.map +1 -1
- package/build/commands/browse.js +126 -154
- package/build/commands/browse.js.map +1 -1
- package/build/commands/cache.d.ts.map +1 -1
- package/build/commands/cache.js +13 -15
- package/build/commands/cache.js.map +1 -1
- package/build/commands/config.d.ts +1 -1
- package/build/commands/config.d.ts.map +1 -1
- package/build/commands/config.js +7 -3
- package/build/commands/config.js.map +1 -1
- package/build/commands/diff.d.ts.map +1 -1
- package/build/commands/diff.js +4 -117
- package/build/commands/diff.js.map +1 -1
- package/build/commands/freeze.d.ts +1 -2
- package/build/commands/freeze.d.ts.map +1 -1
- package/build/commands/freeze.js +17 -37
- package/build/commands/freeze.js.map +1 -1
- package/build/commands/info.d.ts +1 -2
- package/build/commands/info.d.ts.map +1 -1
- package/build/commands/info.js +43 -38
- package/build/commands/info.js.map +1 -1
- package/build/commands/init.d.ts.map +1 -1
- package/build/commands/init.js +41 -414
- package/build/commands/init.js.map +1 -1
- package/build/commands/install.d.ts.map +1 -1
- package/build/commands/install.js +79 -72
- package/build/commands/install.js.map +1 -1
- package/build/commands/list.d.ts +2 -2
- package/build/commands/list.d.ts.map +1 -1
- package/build/commands/list.js +138 -27
- package/build/commands/list.js.map +1 -1
- package/build/commands/outdated.d.ts.map +1 -1
- package/build/commands/outdated.js +20 -10
- package/build/commands/outdated.js.map +1 -1
- package/build/commands/pin.d.ts +1 -2
- package/build/commands/pin.d.ts.map +1 -1
- package/build/commands/pin.js +44 -47
- package/build/commands/pin.js.map +1 -1
- package/build/commands/prune.d.ts.map +1 -1
- package/build/commands/prune.js +76 -151
- package/build/commands/prune.js.map +1 -1
- package/build/commands/publish.d.ts +4 -1
- package/build/commands/publish.d.ts.map +1 -1
- package/build/commands/publish.js +139 -388
- package/build/commands/publish.js.map +1 -1
- package/build/commands/search.d.ts.map +1 -1
- package/build/commands/search.js +14 -19
- package/build/commands/search.js.map +1 -1
- package/build/commands/setup.d.ts +1 -1
- package/build/commands/setup.d.ts.map +1 -1
- package/build/commands/setup.js +48 -253
- package/build/commands/setup.js.map +1 -1
- package/build/commands/sync.d.ts.map +1 -1
- package/build/commands/sync.js +43 -169
- package/build/commands/sync.js.map +1 -1
- package/build/commands/thaw.d.ts +1 -2
- package/build/commands/thaw.d.ts.map +1 -1
- package/build/commands/thaw.js +19 -37
- package/build/commands/thaw.js.map +1 -1
- package/build/commands/uninstall.d.ts.map +1 -1
- package/build/commands/uninstall.js +106 -221
- package/build/commands/uninstall.js.map +1 -1
- package/build/commands/unpin.d.ts +1 -2
- package/build/commands/unpin.d.ts.map +1 -1
- package/build/commands/unpin.js +23 -38
- package/build/commands/unpin.js.map +1 -1
- package/build/commands/update.d.ts.map +1 -1
- package/build/commands/update.js +57 -54
- package/build/commands/update.js.map +1 -1
- package/build/commands/why.d.ts +1 -1
- package/build/commands/why.d.ts.map +1 -1
- package/build/commands/why.js +14 -6
- package/build/commands/why.js.map +1 -1
- package/build/components/AssetDetail.d.ts +1 -3
- package/build/components/AssetDetail.d.ts.map +1 -1
- package/build/components/AssetDetail.js +22 -21
- package/build/components/AssetDetail.js.map +1 -1
- package/build/components/AssetTable.d.ts +5 -2
- package/build/components/AssetTable.d.ts.map +1 -1
- package/build/components/AssetTable.js +37 -40
- package/build/components/AssetTable.js.map +1 -1
- package/build/components/AssetVersionLine.d.ts +27 -0
- package/build/components/AssetVersionLine.d.ts.map +1 -0
- package/build/components/AssetVersionLine.js +10 -0
- package/build/components/AssetVersionLine.js.map +1 -0
- package/build/components/BrowseExpandedBundle.d.ts +10 -1
- package/build/components/BrowseExpandedBundle.d.ts.map +1 -1
- package/build/components/BrowseExpandedBundle.js +25 -2
- package/build/components/BrowseExpandedBundle.js.map +1 -1
- package/build/components/BrowseExpandedRow.d.ts +4 -1
- package/build/components/BrowseExpandedRow.d.ts.map +1 -1
- package/build/components/BrowseExpandedRow.js +24 -3
- package/build/components/BrowseExpandedRow.js.map +1 -1
- package/build/components/BrowseList.d.ts +5 -1
- package/build/components/BrowseList.d.ts.map +1 -1
- package/build/components/BrowseList.js +57 -47
- package/build/components/BrowseList.js.map +1 -1
- package/build/components/BundleDetail.d.ts +2 -1
- package/build/components/BundleDetail.d.ts.map +1 -1
- package/build/components/BundleDetail.js +3 -2
- package/build/components/BundleDetail.js.map +1 -1
- package/build/components/DiffView.d.ts +0 -2
- package/build/components/DiffView.d.ts.map +1 -1
- package/build/components/DiffView.js +11 -5
- package/build/components/DiffView.js.map +1 -1
- package/build/components/DryRunBanner.d.ts +3 -3
- package/build/components/DryRunBanner.d.ts.map +1 -1
- package/build/components/DryRunBanner.js +2 -2
- package/build/components/DryRunBanner.js.map +1 -1
- package/build/components/FilterBar.d.ts +10 -3
- package/build/components/FilterBar.d.ts.map +1 -1
- package/build/components/FilterBar.js +4 -4
- package/build/components/FilterBar.js.map +1 -1
- package/build/components/FrozenSkippedHint.d.ts +11 -0
- package/build/components/FrozenSkippedHint.d.ts.map +1 -0
- package/build/components/FrozenSkippedHint.js +12 -0
- package/build/components/FrozenSkippedHint.js.map +1 -0
- package/build/components/HelpBar.d.ts.map +1 -1
- package/build/components/HelpBar.js +3 -3
- package/build/components/HelpBar.js.map +1 -1
- package/build/components/InitSuccess.d.ts +5 -0
- package/build/components/InitSuccess.d.ts.map +1 -0
- package/build/components/InitSuccess.js +20 -0
- package/build/components/InitSuccess.js.map +1 -0
- package/build/components/InstallSummary.d.ts +3 -3
- package/build/components/InstallSummary.d.ts.map +1 -1
- package/build/components/InstallSummary.js +2 -2
- package/build/components/InstallSummary.js.map +1 -1
- package/build/components/Link.d.ts +7 -0
- package/build/components/Link.d.ts.map +1 -0
- package/build/components/Link.js +6 -0
- package/build/components/Link.js.map +1 -0
- package/build/components/ListActionBar.d.ts +11 -0
- package/build/components/ListActionBar.d.ts.map +1 -0
- package/build/components/ListActionBar.js +30 -0
- package/build/components/ListActionBar.js.map +1 -0
- package/build/components/ListBrowseList.d.ts +27 -0
- package/build/components/ListBrowseList.d.ts.map +1 -0
- package/build/components/ListBrowseList.js +57 -0
- package/build/components/ListBrowseList.js.map +1 -0
- package/build/components/ListExpandedRow.d.ts +38 -0
- package/build/components/ListExpandedRow.d.ts.map +1 -0
- package/build/components/ListExpandedRow.js +46 -0
- package/build/components/ListExpandedRow.js.map +1 -0
- package/build/components/ListHelpBar.d.ts +19 -0
- package/build/components/ListHelpBar.d.ts.map +1 -0
- package/build/components/ListHelpBar.js +11 -0
- package/build/components/ListHelpBar.js.map +1 -0
- package/build/components/OrphanListItem.d.ts +15 -0
- package/build/components/OrphanListItem.d.ts.map +1 -0
- package/build/components/OrphanListItem.js +6 -0
- package/build/components/OrphanListItem.js.map +1 -0
- package/build/components/PromptField.d.ts +19 -0
- package/build/components/PromptField.d.ts.map +1 -0
- package/build/components/PromptField.js +7 -0
- package/build/components/PromptField.js.map +1 -0
- package/build/components/SkippedAssetSection.d.ts +35 -0
- package/build/components/SkippedAssetSection.d.ts.map +1 -0
- package/build/components/SkippedAssetSection.js +15 -0
- package/build/components/SkippedAssetSection.js.map +1 -0
- package/build/components/StatusBadge.d.ts +1 -1
- package/build/components/StatusBadge.d.ts.map +1 -1
- package/build/components/StatusBadge.js +4 -0
- package/build/components/StatusBadge.js.map +1 -1
- package/build/components/SyncAllInSync.d.ts +14 -0
- package/build/components/SyncAllInSync.d.ts.map +1 -0
- package/build/components/SyncAllInSync.js +10 -0
- package/build/components/SyncAllInSync.js.map +1 -0
- package/build/components/SyncDriftedList.d.ts +24 -0
- package/build/components/SyncDriftedList.d.ts.map +1 -0
- package/build/components/SyncDriftedList.js +17 -0
- package/build/components/SyncDriftedList.js.map +1 -0
- package/build/components/SyncNoAssets.d.ts +12 -0
- package/build/components/SyncNoAssets.d.ts.map +1 -0
- package/build/components/SyncNoAssets.js +9 -0
- package/build/components/SyncNoAssets.js.map +1 -0
- package/build/components/index.d.ts +16 -2
- package/build/components/index.d.ts.map +1 -1
- package/build/components/index.js +16 -2
- package/build/components/index.js.map +1 -1
- package/build/hooks/useBrowseState.d.ts +44 -1
- package/build/hooks/useBrowseState.d.ts.map +1 -1
- package/build/hooks/useBrowseState.js +148 -13
- package/build/hooks/useBrowseState.js.map +1 -1
- package/build/hooks/useConfirmation.d.ts +18 -0
- package/build/hooks/useConfirmation.d.ts.map +1 -0
- package/build/hooks/useConfirmation.js +56 -0
- package/build/hooks/useConfirmation.js.map +1 -0
- package/build/hooks/useInitState.d.ts +109 -0
- package/build/hooks/useInitState.d.ts.map +1 -0
- package/build/hooks/useInitState.js +474 -0
- package/build/hooks/useInitState.js.map +1 -0
- package/build/hooks/useListActions.d.ts +15 -0
- package/build/hooks/useListActions.d.ts.map +1 -0
- package/build/hooks/useListActions.js +155 -0
- package/build/hooks/useListActions.js.map +1 -0
- package/build/hooks/useListState.d.ts +151 -0
- package/build/hooks/useListState.d.ts.map +1 -0
- package/build/hooks/useListState.js +448 -0
- package/build/hooks/useListState.js.map +1 -0
- package/build/hooks/usePruneState.d.ts +76 -0
- package/build/hooks/usePruneState.d.ts.map +1 -0
- package/build/hooks/usePruneState.js +252 -0
- package/build/hooks/usePruneState.js.map +1 -0
- package/build/hooks/usePublishState.d.ts +147 -0
- package/build/hooks/usePublishState.d.ts.map +1 -0
- package/build/hooks/usePublishState.js +916 -0
- package/build/hooks/usePublishState.js.map +1 -0
- package/build/hooks/useSetupState.d.ts +57 -0
- package/build/hooks/useSetupState.d.ts.map +1 -0
- package/build/hooks/useSetupState.js +236 -0
- package/build/hooks/useSetupState.js.map +1 -0
- package/build/hooks/useUninstallState.d.ts +102 -0
- package/build/hooks/useUninstallState.d.ts.map +1 -0
- package/build/hooks/useUninstallState.js +342 -0
- package/build/hooks/useUninstallState.js.map +1 -0
- package/build/lib/adapter.d.ts +21 -0
- package/build/lib/adapter.d.ts.map +1 -1
- package/build/lib/adapter.js +59 -1
- package/build/lib/adapter.js.map +1 -1
- package/build/lib/checksum.d.ts +39 -0
- package/build/lib/checksum.d.ts.map +1 -1
- package/build/lib/checksum.js +98 -13
- package/build/lib/checksum.js.map +1 -1
- package/build/lib/config.d.ts +38 -18
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +103 -55
- package/build/lib/config.js.map +1 -1
- package/build/lib/detector.d.ts +2 -11
- package/build/lib/detector.d.ts.map +1 -1
- package/build/lib/detector.js +2 -64
- package/build/lib/detector.js.map +1 -1
- package/build/lib/diagnostics.d.ts +7 -0
- package/build/lib/diagnostics.d.ts.map +1 -1
- package/build/lib/diagnostics.js +54 -34
- package/build/lib/diagnostics.js.map +1 -1
- package/build/lib/diff-command.d.ts +40 -0
- package/build/lib/diff-command.d.ts.map +1 -0
- package/build/lib/diff-command.js +145 -0
- package/build/lib/diff-command.js.map +1 -0
- package/build/lib/diff.d.ts +7 -0
- package/build/lib/diff.d.ts.map +1 -1
- package/build/lib/diff.js +15 -10
- package/build/lib/diff.js.map +1 -1
- package/build/lib/format.d.ts +6 -0
- package/build/lib/format.d.ts.map +1 -0
- package/build/lib/format.js +18 -0
- package/build/lib/format.js.map +1 -0
- package/build/lib/github.d.ts +35 -0
- package/build/lib/github.d.ts.map +1 -1
- package/build/lib/github.js +44 -0
- package/build/lib/github.js.map +1 -1
- package/build/lib/gitignore.d.ts +17 -0
- package/build/lib/gitignore.d.ts.map +1 -1
- package/build/lib/gitignore.js +17 -1
- package/build/lib/gitignore.js.map +1 -1
- package/build/lib/init.d.ts +22 -0
- package/build/lib/init.d.ts.map +1 -1
- package/build/lib/init.js +163 -18
- package/build/lib/init.js.map +1 -1
- package/build/lib/installer.d.ts +1 -0
- package/build/lib/installer.d.ts.map +1 -1
- package/build/lib/installer.js +7 -7
- package/build/lib/installer.js.map +1 -1
- package/build/lib/lockfile.d.ts +19 -17
- package/build/lib/lockfile.d.ts.map +1 -1
- package/build/lib/lockfile.js +43 -67
- package/build/lib/lockfile.js.map +1 -1
- package/build/lib/publisher.d.ts +41 -12
- package/build/lib/publisher.d.ts.map +1 -1
- package/build/lib/publisher.js +226 -64
- package/build/lib/publisher.js.map +1 -1
- package/build/lib/registry.d.ts +20 -5
- package/build/lib/registry.d.ts.map +1 -1
- package/build/lib/registry.js +41 -30
- package/build/lib/registry.js.map +1 -1
- package/build/lib/schemas/config.d.ts +31 -3
- package/build/lib/schemas/config.d.ts.map +1 -1
- package/build/lib/schemas/config.js +21 -2
- package/build/lib/schemas/config.js.map +1 -1
- package/build/lib/schemas/index.d.ts +1 -1
- package/build/lib/schemas/index.d.ts.map +1 -1
- package/build/lib/schemas/index.js +1 -1
- package/build/lib/schemas/index.js.map +1 -1
- package/build/lib/schemas/lockfile.d.ts +18 -2
- package/build/lib/schemas/lockfile.d.ts.map +1 -1
- package/build/lib/schemas/lockfile.js +7 -1
- package/build/lib/schemas/lockfile.js.map +1 -1
- package/build/lib/schemas/manifest.d.ts +1 -1
- package/build/lib/schemas/manifest.d.ts.map +1 -1
- package/build/lib/schemas/manifest.js +7 -2
- package/build/lib/schemas/manifest.js.map +1 -1
- package/build/lib/schemas/registry.d.ts +2 -4
- package/build/lib/schemas/registry.d.ts.map +1 -1
- package/build/lib/schemas/registry.js +1 -1
- package/build/lib/schemas/registry.js.map +1 -1
- package/build/lib/search.d.ts +15 -1
- package/build/lib/search.d.ts.map +1 -1
- package/build/lib/search.js +65 -65
- package/build/lib/search.js.map +1 -1
- package/build/lib/setup.d.ts +28 -0
- package/build/lib/setup.d.ts.map +1 -0
- package/build/lib/setup.js +98 -0
- package/build/lib/setup.js.map +1 -0
- package/build/lib/sync.d.ts +109 -0
- package/build/lib/sync.d.ts.map +1 -0
- package/build/lib/sync.js +217 -0
- package/build/lib/sync.js.map +1 -0
- package/build/lib/tool-resolver.d.ts +29 -6
- package/build/lib/tool-resolver.d.ts.map +1 -1
- package/build/lib/tool-resolver.js +54 -15
- package/build/lib/tool-resolver.js.map +1 -1
- package/build/lib/updater.d.ts +7 -4
- package/build/lib/updater.d.ts.map +1 -1
- package/build/lib/updater.js +10 -6
- package/build/lib/updater.js.map +1 -1
- package/build/lib/version.js +1 -1
- package/build/lib/version.js.map +1 -1
- package/package.json +79 -65
- package/tool-adapters/claude-code.json +1 -1
- package/tool-adapters/copilot-cli.json +1 -1
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text, useApp } from 'ink';
|
|
2
|
+
import { Box, Text, useApp, useInput, useStdin } from 'ink';
|
|
3
3
|
import TextInput from 'ink-text-input';
|
|
4
|
-
import { cp, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
5
|
-
import { tmpdir } from 'node:os';
|
|
6
|
-
import { dirname, join, resolve } from 'node:path';
|
|
7
4
|
import { option } from 'pastel';
|
|
8
|
-
import {
|
|
5
|
+
import { useEffect } from 'react';
|
|
9
6
|
import { z } from 'zod';
|
|
10
7
|
import { DryRunBanner, Spinner } from '../components/index.js';
|
|
11
8
|
import { CheckIcon } from '../components/StatusBadge.js';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { hashFile } from '../lib/checksum.js';
|
|
15
|
-
import { DEFAULT_REGISTRY_BRANCH } from '../lib/github.js';
|
|
16
|
-
import { addAssetToLockfile, findInstalledAsset, readLockfile, withLockfileLock, writeLockfile, } from '../lib/lockfile.js';
|
|
17
|
-
import { parseOrgFromName } from '../lib/org.js';
|
|
18
|
-
import { findProjectRoot } from '../lib/paths.js';
|
|
19
|
-
import { buildPublishPlan, bumpVersion, checkRegistryVersion, detectPublishType, executeDirectPublish, executePublish, isOrgAsset, mapPublishError, updateManifestVersion, validatePublishTarget, } from '../lib/publisher.js';
|
|
20
|
-
import { clearCache, fetchRegistry } from '../lib/registry.js';
|
|
21
|
-
import { resolveTool } from '../lib/tool-resolver.js';
|
|
9
|
+
import { usePublishState } from '../hooks/usePublishState.js';
|
|
10
|
+
import { bumpVersion } from '../lib/publisher.js';
|
|
22
11
|
export const description = 'Publish an asset or bundle to the registry';
|
|
23
12
|
export const options = z.object({
|
|
13
|
+
description: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe(option({
|
|
17
|
+
description: 'Asset description (skips interactive prompt)',
|
|
18
|
+
})),
|
|
24
19
|
dryRun: z
|
|
25
20
|
.boolean()
|
|
26
21
|
.default(false)
|
|
@@ -42,365 +37,71 @@ export const options = z.object({
|
|
|
42
37
|
alias: 'm',
|
|
43
38
|
description: 'Custom message appended to the auto-generated PR description or commit',
|
|
44
39
|
})),
|
|
40
|
+
tags: z
|
|
41
|
+
.string()
|
|
42
|
+
.optional()
|
|
43
|
+
.describe(option({
|
|
44
|
+
description: 'Comma-separated tags (skips interactive prompt)',
|
|
45
|
+
})),
|
|
46
|
+
update: z
|
|
47
|
+
.boolean()
|
|
48
|
+
.default(false)
|
|
49
|
+
.describe(option({
|
|
50
|
+
alias: 'u',
|
|
51
|
+
description: 'Publish an update using locally modified installed files',
|
|
52
|
+
})),
|
|
45
53
|
});
|
|
46
54
|
export const args = z.tuple([
|
|
47
|
-
z
|
|
55
|
+
z
|
|
56
|
+
.string()
|
|
57
|
+
.describe('Path to asset/bundle directory (with manifest), or path to a raw file/directory to publish without scaffolding. When --update is used, this is an installed asset name'),
|
|
48
58
|
]);
|
|
49
|
-
export default function Publish({ args: [rawPath], options: { dryRun, fromInstalled, message } }) {
|
|
59
|
+
export default function Publish({ args: [rawPath], options: { description: descriptionFlag, dryRun, fromInstalled, message, tags: tagsFlag, update }, }) {
|
|
50
60
|
const { exit } = useApp();
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const [errorMessage, setErrorMessage] = useState('');
|
|
69
|
-
// Temp directory ref for --from-installed cleanup
|
|
70
|
-
const tempDirRef = useRef(null);
|
|
71
|
-
// When --from-installed is used, resolvedPath is set after resolving the installed asset
|
|
72
|
-
const [resolvedPath, setResolvedPath] = useState(fromInstalled ? '' : resolve(rawPath));
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// Cleanup helper for temp directory
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
const cleanupTempDir = useCallback(async () => {
|
|
77
|
-
if (tempDirRef.current) {
|
|
78
|
-
try {
|
|
79
|
-
await rm(tempDirRef.current, { force: true, recursive: true });
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
// Best-effort cleanup — ignore errors
|
|
83
|
-
}
|
|
84
|
-
tempDirRef.current = null;
|
|
61
|
+
const { isRawModeSupported: isTTY } = useStdin();
|
|
62
|
+
const flags = {
|
|
63
|
+
descriptionFlag,
|
|
64
|
+
dryRun,
|
|
65
|
+
fromInstalled,
|
|
66
|
+
message,
|
|
67
|
+
rawPath,
|
|
68
|
+
tagsFlag,
|
|
69
|
+
update,
|
|
70
|
+
};
|
|
71
|
+
const [state, dispatch] = usePublishState(flags);
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// Tool selection — keyboard handling (multi-select checkboxes)
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
useInput((input, key) => {
|
|
76
|
+
if (key.upArrow) {
|
|
77
|
+
dispatch({ type: 'TOOL_CURSOR_UP' });
|
|
85
78
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// Phase: Resolving installed asset (--from-installed)
|
|
89
|
-
// ---------------------------------------------------------------------------
|
|
90
|
-
useEffect(() => {
|
|
91
|
-
if (phase !== 'resolving-installed')
|
|
92
|
-
return;
|
|
93
|
-
let cancelled = false;
|
|
94
|
-
const resolveInstalled = async () => {
|
|
95
|
-
const assetName = rawPath;
|
|
96
|
-
const { name, org } = parseOrgFromName(assetName);
|
|
97
|
-
const projectRoot = findProjectRoot();
|
|
98
|
-
const { adapter } = await resolveTool(undefined);
|
|
99
|
-
const lockfile = await readLockfile(projectRoot);
|
|
100
|
-
const installed = findInstalledAsset(lockfile, name, undefined, org);
|
|
101
|
-
if (!installed) {
|
|
102
|
-
if (!cancelled) {
|
|
103
|
-
setErrorMessage(`Asset '${assetName}' is not installed.`);
|
|
104
|
-
setPhase('error');
|
|
105
|
-
}
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
// Create temp directory and copy installed files
|
|
109
|
-
const tempDir = await mkdir(join(tmpdir(), 'atk-publish-'), { recursive: true })
|
|
110
|
-
.then(() => join(tmpdir(), `atk-publish-${Date.now()}-${Math.random().toString(36).slice(2)}`))
|
|
111
|
-
.then(async (dir) => {
|
|
112
|
-
await mkdir(dir, { recursive: true });
|
|
113
|
-
return dir;
|
|
114
|
-
});
|
|
115
|
-
if (cancelled) {
|
|
116
|
-
await rm(tempDir, { force: true, recursive: true });
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
tempDirRef.current = tempDir;
|
|
120
|
-
// Resolve installed paths via the adapter
|
|
121
|
-
const resolved = resolveInstalledPaths(installed, adapter, projectRoot);
|
|
122
|
-
// Copy each installed file preserving sourcePath directory structure
|
|
123
|
-
for (const file of resolved.files) {
|
|
124
|
-
const sourceAbsolute = join(projectRoot, file.installedPath);
|
|
125
|
-
const destPath = join(tempDir, file.sourcePath);
|
|
126
|
-
const destDir = dirname(destPath);
|
|
127
|
-
await mkdir(destDir, { recursive: true });
|
|
128
|
-
await cp(sourceAbsolute, destPath);
|
|
129
|
-
}
|
|
130
|
-
// Generate manifest.json in the temp dir
|
|
131
|
-
const manifest = {
|
|
132
|
-
author: 'unknown',
|
|
133
|
-
description: `Published from installed asset ${installed.name}`,
|
|
134
|
-
entrypoint: installed.files[0]?.sourcePath ?? 'index.md',
|
|
135
|
-
name: installed.name,
|
|
136
|
-
...(installed.org ? { org: installed.org } : {}),
|
|
137
|
-
type: installed.type,
|
|
138
|
-
version: installed.version,
|
|
139
|
-
};
|
|
140
|
-
await writeFile(join(tempDir, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
|
|
141
|
-
if (!cancelled) {
|
|
142
|
-
setResolvedPath(tempDir);
|
|
143
|
-
setPhase('detecting');
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
resolveInstalled().catch((err) => {
|
|
147
|
-
if (!cancelled) {
|
|
148
|
-
setErrorMessage(err instanceof Error ? err.message : String(err));
|
|
149
|
-
setPhase('error');
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
return () => {
|
|
153
|
-
cancelled = true;
|
|
154
|
-
};
|
|
155
|
-
}, [phase, rawPath]);
|
|
156
|
-
// ---------------------------------------------------------------------------
|
|
157
|
-
// Phase: Detecting asset vs bundle
|
|
158
|
-
// ---------------------------------------------------------------------------
|
|
159
|
-
useEffect(() => {
|
|
160
|
-
if (phase !== 'detecting')
|
|
161
|
-
return;
|
|
162
|
-
let cancelled = false;
|
|
163
|
-
const detect = async () => {
|
|
164
|
-
const detected = await detectPublishType(resolvedPath);
|
|
165
|
-
if (cancelled)
|
|
166
|
-
return;
|
|
167
|
-
setTarget(detected);
|
|
168
|
-
setPhase('validating');
|
|
169
|
-
};
|
|
170
|
-
detect().catch((err) => {
|
|
171
|
-
if (!cancelled) {
|
|
172
|
-
setErrorMessage(err instanceof Error ? err.message : String(err));
|
|
173
|
-
setPhase('error');
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
return () => {
|
|
177
|
-
cancelled = true;
|
|
178
|
-
};
|
|
179
|
-
}, [phase, resolvedPath]);
|
|
180
|
-
// ---------------------------------------------------------------------------
|
|
181
|
-
// Phase: Validating manifest/bundle
|
|
182
|
-
// ---------------------------------------------------------------------------
|
|
183
|
-
useEffect(() => {
|
|
184
|
-
if (phase !== 'validating')
|
|
185
|
-
return;
|
|
186
|
-
if (!target)
|
|
187
|
-
return;
|
|
188
|
-
let cancelled = false;
|
|
189
|
-
const validate = async () => {
|
|
190
|
-
const result = await validatePublishTarget(target);
|
|
191
|
-
if (cancelled)
|
|
192
|
-
return;
|
|
193
|
-
setValidation(result);
|
|
194
|
-
if (!result.valid) {
|
|
195
|
-
setErrorMessage(`Validation failed:\n${result.errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
196
|
-
setPhase('error');
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
setPhase('checking-registry');
|
|
200
|
-
};
|
|
201
|
-
validate().catch((err) => {
|
|
202
|
-
if (!cancelled) {
|
|
203
|
-
setErrorMessage(err instanceof Error ? err.message : String(err));
|
|
204
|
-
setPhase('error');
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
return () => {
|
|
208
|
-
cancelled = true;
|
|
209
|
-
};
|
|
210
|
-
}, [phase, target]);
|
|
211
|
-
// ---------------------------------------------------------------------------
|
|
212
|
-
// Phase: Checking registry for existing asset
|
|
213
|
-
// ---------------------------------------------------------------------------
|
|
214
|
-
useEffect(() => {
|
|
215
|
-
if (phase !== 'checking-registry')
|
|
216
|
-
return;
|
|
217
|
-
if (!target)
|
|
218
|
-
return;
|
|
219
|
-
let cancelled = false;
|
|
220
|
-
const check = async () => {
|
|
221
|
-
const authToken = await getGitHubToken();
|
|
222
|
-
if (cancelled)
|
|
223
|
-
return;
|
|
224
|
-
setToken(authToken);
|
|
225
|
-
const reg = await fetchRegistry();
|
|
226
|
-
if (cancelled)
|
|
227
|
-
return;
|
|
228
|
-
setRegistry(reg);
|
|
229
|
-
const versionResult = checkRegistryVersion(target, reg);
|
|
230
|
-
if (cancelled)
|
|
231
|
-
return;
|
|
232
|
-
setVersionCheck(versionResult);
|
|
233
|
-
if (versionResult.status === 'new-asset') {
|
|
234
|
-
setIsUpdate(false);
|
|
235
|
-
setResolvedVersion(target.data.version);
|
|
236
|
-
setPhase('building-plan');
|
|
237
|
-
}
|
|
238
|
-
else if (versionResult.status === 'version-already-bumped') {
|
|
239
|
-
setIsUpdate(true);
|
|
240
|
-
setResolvedVersion(target.data.version);
|
|
241
|
-
setPhase('confirm-update');
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
// needs-bump
|
|
245
|
-
setIsUpdate(true);
|
|
246
|
-
setPhase('bump-prompt');
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
check().catch((err) => {
|
|
250
|
-
if (!cancelled) {
|
|
251
|
-
setErrorMessage(mapPublishError(err));
|
|
252
|
-
setPhase('error');
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
return () => {
|
|
256
|
-
cancelled = true;
|
|
257
|
-
};
|
|
258
|
-
}, [phase, target]);
|
|
259
|
-
// ---------------------------------------------------------------------------
|
|
260
|
-
// Phase: Building publish plan
|
|
261
|
-
// ---------------------------------------------------------------------------
|
|
262
|
-
useEffect(() => {
|
|
263
|
-
if (phase !== 'building-plan')
|
|
264
|
-
return;
|
|
265
|
-
if (!target)
|
|
266
|
-
return;
|
|
267
|
-
let cancelled = false;
|
|
268
|
-
const build = async () => {
|
|
269
|
-
const publishPlan = await buildPublishPlan(target, resolvedVersion, isUpdate, message);
|
|
270
|
-
if (cancelled)
|
|
271
|
-
return;
|
|
272
|
-
setPlan(publishPlan);
|
|
273
|
-
if (dryRun) {
|
|
274
|
-
setPhase('dry-run-result');
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
setPhase('publishing');
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
build().catch((err) => {
|
|
281
|
-
if (!cancelled) {
|
|
282
|
-
setErrorMessage(err instanceof Error ? err.message : String(err));
|
|
283
|
-
setPhase('error');
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
return () => {
|
|
287
|
-
cancelled = true;
|
|
288
|
-
};
|
|
289
|
-
}, [phase, target, resolvedVersion, isUpdate, dryRun, message]);
|
|
290
|
-
// ---------------------------------------------------------------------------
|
|
291
|
-
// Phase: Publishing (executing git operations)
|
|
292
|
-
// ---------------------------------------------------------------------------
|
|
293
|
-
useEffect(() => {
|
|
294
|
-
if (phase !== 'publishing')
|
|
295
|
-
return;
|
|
296
|
-
if (!plan || !token)
|
|
297
|
-
return;
|
|
298
|
-
let cancelled = false;
|
|
299
|
-
const publish = async () => {
|
|
300
|
-
const progressCallback = (msg) => {
|
|
301
|
-
if (!cancelled) {
|
|
302
|
-
setProgressMessage(msg);
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
const result = isOrgAsset(plan)
|
|
306
|
-
? await executeDirectPublish(plan, token, progressCallback)
|
|
307
|
-
: await executePublish(plan, token, progressCallback);
|
|
308
|
-
if (cancelled)
|
|
309
|
-
return;
|
|
310
|
-
setPublishResult(result);
|
|
311
|
-
// Clear registry cache so subsequent commands see the new version
|
|
312
|
-
try {
|
|
313
|
-
await clearCache();
|
|
314
|
-
}
|
|
315
|
-
catch {
|
|
316
|
-
// Best-effort — don't fail publish over cache
|
|
317
|
-
}
|
|
318
|
-
// Update lockfile in-place when publishing from an installed asset
|
|
319
|
-
if (fromInstalled) {
|
|
320
|
-
try {
|
|
321
|
-
const projectRoot = findProjectRoot();
|
|
322
|
-
const { adapter: pubAdapter } = await resolveTool(undefined);
|
|
323
|
-
await withLockfileLock(projectRoot, async () => {
|
|
324
|
-
const lockfile = await readLockfile(projectRoot);
|
|
325
|
-
const { name, org } = parseOrgFromName(rawPath);
|
|
326
|
-
const installed = findInstalledAsset(lockfile, name, undefined, org);
|
|
327
|
-
if (installed) {
|
|
328
|
-
const resolved = resolveInstalledPaths(installed, pubAdapter, projectRoot);
|
|
329
|
-
const updatedFiles = await Promise.all(resolved.files.map(async (file) => ({
|
|
330
|
-
checksum: await hashFile(join(projectRoot, file.installedPath)),
|
|
331
|
-
sourcePath: file.sourcePath,
|
|
332
|
-
})));
|
|
333
|
-
const updatedLockfile = addAssetToLockfile(lockfile, {
|
|
334
|
-
...installed,
|
|
335
|
-
files: updatedFiles,
|
|
336
|
-
version: resolvedVersion,
|
|
337
|
-
});
|
|
338
|
-
await writeLockfile(projectRoot, updatedLockfile);
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
catch {
|
|
343
|
-
// Best-effort — don't fail publish over lockfile update
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
setPhase('done');
|
|
347
|
-
};
|
|
348
|
-
publish().catch((err) => {
|
|
349
|
-
if (!cancelled) {
|
|
350
|
-
setErrorMessage(mapPublishError(err));
|
|
351
|
-
setPhase('error');
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
return () => {
|
|
355
|
-
cancelled = true;
|
|
356
|
-
};
|
|
357
|
-
}, [phase, plan, token, fromInstalled, rawPath, resolvedVersion]);
|
|
358
|
-
// ---------------------------------------------------------------------------
|
|
359
|
-
// Prompt handlers
|
|
360
|
-
// ---------------------------------------------------------------------------
|
|
361
|
-
const handleConfirmSubmit = useCallback((value) => {
|
|
362
|
-
const trimmed = value.trim().toLowerCase();
|
|
363
|
-
if (trimmed === 'y' || trimmed === 'yes') {
|
|
364
|
-
setPhase('building-plan');
|
|
79
|
+
else if (key.downArrow) {
|
|
80
|
+
dispatch({ type: 'TOOL_CURSOR_DOWN' });
|
|
365
81
|
}
|
|
366
|
-
else if (
|
|
367
|
-
|
|
368
|
-
|
|
82
|
+
else if (input === ' ') {
|
|
83
|
+
const tool = state.toolAdapters[state.toolCursorIndex]?.tool;
|
|
84
|
+
if (tool) {
|
|
85
|
+
dispatch({ tool, type: 'TOGGLE_PROMPT_TOOL' });
|
|
86
|
+
}
|
|
369
87
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
return;
|
|
375
|
-
const trimmed = value.trim().toLowerCase();
|
|
376
|
-
if (trimmed !== 'patch' && trimmed !== 'minor' && trimmed !== 'major') {
|
|
377
|
-
return; // Ignore invalid input
|
|
88
|
+
else if (key.return) {
|
|
89
|
+
if (state.selectedPromptTools.length > 0) {
|
|
90
|
+
dispatch({ type: 'CONFIRM_PROMPT_TOOLS' });
|
|
91
|
+
}
|
|
378
92
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
// Re-read the target so it has the updated version
|
|
387
|
-
return detectPublishType(target.sourceDir);
|
|
388
|
-
})
|
|
389
|
-
.then((updatedTarget) => {
|
|
390
|
-
setTarget(updatedTarget);
|
|
391
|
-
setPhase('building-plan');
|
|
392
|
-
})
|
|
393
|
-
.catch((err) => {
|
|
394
|
-
setErrorMessage(`Failed to update version: ${err instanceof Error ? err.message : String(err)}`);
|
|
395
|
-
setPhase('error');
|
|
396
|
-
});
|
|
397
|
-
}, [target, versionCheck]);
|
|
93
|
+
}, { isActive: state.phase === 'prompting-tools' && isTTY });
|
|
94
|
+
/** Format asset name with org prefix when available (e.g. "@org/name") */
|
|
95
|
+
const displayName = state.target
|
|
96
|
+
? 'org' in state.target.data && state.target.data.org
|
|
97
|
+
? `@${state.target.data.org}/${state.target.data.name}`
|
|
98
|
+
: state.target.data.name
|
|
99
|
+
: '';
|
|
398
100
|
// ---------------------------------------------------------------------------
|
|
399
101
|
// Exit on error
|
|
400
102
|
// ---------------------------------------------------------------------------
|
|
401
103
|
useEffect(() => {
|
|
402
|
-
if (phase === 'error') {
|
|
403
|
-
void cleanupTempDir();
|
|
104
|
+
if (state.phase === 'error') {
|
|
404
105
|
const timer = setTimeout(() => {
|
|
405
106
|
process.exitCode = 1;
|
|
406
107
|
exit();
|
|
@@ -409,13 +110,12 @@ export default function Publish({ args: [rawPath], options: { dryRun, fromInstal
|
|
|
409
110
|
clearTimeout(timer);
|
|
410
111
|
};
|
|
411
112
|
}
|
|
412
|
-
}, [phase, exit
|
|
113
|
+
}, [state.phase, exit]);
|
|
413
114
|
// ---------------------------------------------------------------------------
|
|
414
115
|
// Exit on done
|
|
415
116
|
// ---------------------------------------------------------------------------
|
|
416
117
|
useEffect(() => {
|
|
417
|
-
if (phase === 'done') {
|
|
418
|
-
void cleanupTempDir();
|
|
118
|
+
if (state.phase === 'done') {
|
|
419
119
|
const timer = setTimeout(() => {
|
|
420
120
|
exit();
|
|
421
121
|
}, 100);
|
|
@@ -423,13 +123,12 @@ export default function Publish({ args: [rawPath], options: { dryRun, fromInstal
|
|
|
423
123
|
clearTimeout(timer);
|
|
424
124
|
};
|
|
425
125
|
}
|
|
426
|
-
}, [phase, exit
|
|
126
|
+
}, [state.phase, exit]);
|
|
427
127
|
// ---------------------------------------------------------------------------
|
|
428
128
|
// Exit on dry-run-result
|
|
429
129
|
// ---------------------------------------------------------------------------
|
|
430
130
|
useEffect(() => {
|
|
431
|
-
if (phase === 'dry-run-result') {
|
|
432
|
-
void cleanupTempDir();
|
|
131
|
+
if (state.phase === 'dry-run-result') {
|
|
433
132
|
const timer = setTimeout(() => {
|
|
434
133
|
exit();
|
|
435
134
|
}, 100);
|
|
@@ -437,56 +136,108 @@ export default function Publish({ args: [rawPath], options: { dryRun, fromInstal
|
|
|
437
136
|
clearTimeout(timer);
|
|
438
137
|
};
|
|
439
138
|
}
|
|
440
|
-
}, [phase, exit
|
|
139
|
+
}, [state.phase, exit]);
|
|
441
140
|
// ---------------------------------------------------------------------------
|
|
442
141
|
// Render
|
|
443
142
|
// ---------------------------------------------------------------------------
|
|
444
143
|
// Error state
|
|
445
|
-
if (phase === 'error') {
|
|
446
|
-
return _jsxs(Text, { color: 'red', children: ["Error: ", errorMessage] });
|
|
144
|
+
if (state.phase === 'error') {
|
|
145
|
+
return _jsxs(Text, { color: 'red', children: ["Error: ", state.errorMessage] });
|
|
447
146
|
}
|
|
448
147
|
// Resolving installed asset
|
|
449
|
-
if (phase === 'resolving-installed') {
|
|
148
|
+
if (state.phase === 'resolving-installed') {
|
|
450
149
|
return _jsx(Spinner, { message: 'Resolving installed asset...' });
|
|
451
150
|
}
|
|
151
|
+
// Resolving update from installed asset
|
|
152
|
+
if (state.phase === 'resolving-update') {
|
|
153
|
+
return _jsx(Spinner, { message: 'Resolving update from installed asset...' });
|
|
154
|
+
}
|
|
452
155
|
// Detecting
|
|
453
|
-
if (phase === 'detecting') {
|
|
156
|
+
if (state.phase === 'detecting') {
|
|
454
157
|
return _jsx(Spinner, { message: 'Detecting asset type...' });
|
|
455
158
|
}
|
|
159
|
+
// Gathering metadata (raw publish)
|
|
160
|
+
if (state.phase === 'gathering-metadata' && state.rawDetection) {
|
|
161
|
+
return (_jsxs(Box, { flexDirection: 'column', children: [_jsxs(Text, { children: ["Detected: ", state.rawDetection.assetType, " \"", _jsx(Text, { bold: true, children: state.rawDetection.name }), "\" (", state.rawDetection.files.length, " file", state.rawDetection.files.length !== 1 ? 's' : '', ")"] }), _jsxs(Text, { children: ["Author: ", state.authorValue, " (from git config)"] }), state.orgValue && _jsxs(Text, { children: ["Org: ", state.orgValue, " (from lockfile)"] }), _jsx(Text, { children: " " }), state.metadataSubPhase === 'description' && (_jsxs(Box, { children: [_jsx(Text, { children: "Description: " }), _jsx(TextInput, { focus: true, onChange: (v) => dispatch({ type: 'SET_DESCRIPTION', value: v }), onSubmit: () => dispatch({ type: 'SUBMIT_DESCRIPTION' }), value: state.descriptionValue })] })), state.metadataSubPhase === 'tags' && (_jsxs(Box, { flexDirection: 'column', children: [_jsxs(Text, { children: ["Description: ", state.descriptionValue] }), _jsxs(Box, { children: [_jsx(Text, { children: "Tags (comma-separated, optional): " }), _jsx(TextInput, { focus: true, onChange: (v) => dispatch({ type: 'SET_TAGS', value: v }), onSubmit: () => dispatch({ type: 'SUBMIT_TAGS' }), value: state.tagsValue })] })] })), state.metadataSubPhase === 'building-staging' && _jsx(Spinner, { message: 'Building staging area...' })] }));
|
|
162
|
+
}
|
|
456
163
|
// Validating
|
|
457
|
-
if (phase === 'validating') {
|
|
164
|
+
if (state.phase === 'validating') {
|
|
458
165
|
return _jsx(Spinner, { message: 'Validating manifest...' });
|
|
459
166
|
}
|
|
167
|
+
// Prompting for tags (after validation, when manifest is missing tags)
|
|
168
|
+
if (state.phase === 'prompting-tags') {
|
|
169
|
+
return (_jsxs(Box, { flexDirection: 'column', children: [state.validation && (_jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsx(Text, { bold: true, children: "Validation:" }), state.validation.errors.length === 0 && (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'pass' }), " All checks passed"] })), state.validation.warnings.map((w, i) => (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'warn' }), " ", w] }, i)))] })), _jsxs(Box, { children: [_jsx(Text, { color: 'cyan', children: '> ' }), _jsx(Text, { children: "Tags (comma-separated, e.g. \"testing, react, utilities\"): " }), _jsx(TextInput, { focus: true, onChange: (v) => dispatch({ type: 'SET_PROMPT_TAGS', value: v }), onSubmit: () => dispatch({ type: 'SUBMIT_PROMPT_TAGS' }), value: state.promptTagsValue })] })] }));
|
|
170
|
+
}
|
|
171
|
+
// Loading tool adapters
|
|
172
|
+
if (state.phase === 'loading-tools') {
|
|
173
|
+
return _jsx(Spinner, { message: 'Loading tool adapters...' });
|
|
174
|
+
}
|
|
175
|
+
// Prompting for tools (after loading adapters, when manifest is missing tools)
|
|
176
|
+
if (state.phase === 'prompting-tools') {
|
|
177
|
+
const selectedSet = new Set(state.selectedPromptTools);
|
|
178
|
+
return (_jsxs(Box, { flexDirection: 'column', children: [state.validation && (_jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsx(Text, { bold: true, children: "Validation:" }), state.validation.errors.length === 0 && (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'pass' }), " All checks passed"] })), state.validation.warnings.map((w, i) => (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'warn' }), " ", w] }, i)))] })), _jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, children: "Select compatible tools" }), _jsx(Text, { dimColor: true, children: " (space to toggle, enter to confirm)" })] }), state.toolAdapters.map((adapter, index) => {
|
|
179
|
+
const isCursor = index === state.toolCursorIndex;
|
|
180
|
+
const isSelected = selectedSet.has(adapter.tool);
|
|
181
|
+
const checkbox = isSelected ? '[x]' : '[ ]';
|
|
182
|
+
return (_jsx(Box, { children: _jsxs(Text, { color: isCursor ? 'cyan' : undefined, children: [isCursor ? '>' : ' ', " ", checkbox, " ", adapter.displayName, _jsxs(Text, { dimColor: true, children: [" (", adapter.tool, ")"] })] }) }, adapter.tool));
|
|
183
|
+
}), selectedSet.size === 0 && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Select at least one tool to continue" }) }))] }));
|
|
184
|
+
}
|
|
460
185
|
// Checking registry
|
|
461
|
-
if (phase === 'checking-registry') {
|
|
186
|
+
if (state.phase === 'checking-registry') {
|
|
462
187
|
return _jsx(Spinner, { message: 'Checking registry...' });
|
|
463
188
|
}
|
|
464
189
|
// Confirm update prompt
|
|
465
|
-
if (phase === 'confirm-update' &&
|
|
466
|
-
|
|
190
|
+
if (state.phase === 'confirm-update' &&
|
|
191
|
+
state.target &&
|
|
192
|
+
state.versionCheck &&
|
|
193
|
+
state.versionCheck.status === 'version-already-bumped') {
|
|
194
|
+
return (_jsxs(Box, { flexDirection: 'column', children: [state.validation && (_jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsx(Text, { bold: true, children: "Validation:" }), state.validation.errors.length === 0 && (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'pass' }), " All checks passed"] })), state.validation.warnings.map((w, i) => (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'warn' }), " ", w] }, i)))] })), _jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsxs(Text, { children: ["Asset ", _jsx(Text, { bold: true, children: displayName }), " already exists in the registry at v", state.versionCheck.latestVersion, "."] }), _jsxs(Text, { children: ["Publishing v", _jsx(Text, { bold: true, children: state.target.data.version }), " as an update."] })] }), _jsxs(Box, { children: [_jsx(Text, { color: 'cyan', children: '> ' }), _jsx(Text, { children: "Continue? (y/n): " }), _jsx(TextInput, { focus: true, onChange: (v) => dispatch({ type: 'SET_CONFIRM_VALUE', value: v }), onSubmit: () => dispatch({ type: 'SUBMIT_CONFIRM' }), value: state.confirmValue })] })] }));
|
|
467
195
|
}
|
|
468
196
|
// Bump prompt
|
|
469
|
-
if (phase === 'bump-prompt' &&
|
|
470
|
-
|
|
197
|
+
if (state.phase === 'bump-prompt' &&
|
|
198
|
+
state.target &&
|
|
199
|
+
state.versionCheck &&
|
|
200
|
+
state.versionCheck.status === 'needs-bump') {
|
|
201
|
+
const currentVersion = state.versionCheck.latestVersion;
|
|
202
|
+
const patchPreview = bumpVersion(currentVersion, 'patch');
|
|
203
|
+
const minorPreview = bumpVersion(currentVersion, 'minor');
|
|
204
|
+
const majorPreview = bumpVersion(currentVersion, 'major');
|
|
205
|
+
return (_jsxs(Box, { flexDirection: 'column', children: [state.validation && (_jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsx(Text, { bold: true, children: "Validation:" }), state.validation.errors.length === 0 && (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'pass' }), " All checks passed"] })), state.validation.warnings.map((w, i) => (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'warn' }), " ", w] }, i)))] })), _jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsxs(Text, { children: ["Asset ", _jsx(Text, { bold: true, children: displayName }), " exists in the registry at v", currentVersion, "."] }), _jsxs(Text, { children: ["Current manifest version (v", state.target.data.version, ") is not newer."] })] }), _jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsxs(Text, { children: [' ', _jsx(Text, { bold: true, children: "patch" }), _jsx(Text, { dimColor: true, children: " (bug fixes):" }), " ", currentVersion, " \u2192 ", patchPreview] }), _jsxs(Text, { children: [' ', _jsx(Text, { bold: true, children: "minor" }), _jsx(Text, { dimColor: true, children: " (new features):" }), " ", currentVersion, " \u2192 ", minorPreview] }), _jsxs(Text, { children: [' ', _jsx(Text, { bold: true, children: "major" }), _jsx(Text, { dimColor: true, children: " (breaking changes):" }), " ", currentVersion, " \u2192 ", majorPreview] })] }), _jsxs(Box, { children: [_jsx(Text, { color: 'cyan', children: '> ' }), _jsx(Text, { children: "Bump type (patch/minor/major): " }), _jsx(TextInput, { focus: true, onChange: (v) => dispatch({ type: 'SET_BUMP_SELECTION', value: v }), onSubmit: () => dispatch({ type: 'SUBMIT_BUMP' }), value: state.bumpSelection })] })] }));
|
|
471
206
|
}
|
|
472
207
|
// Building plan
|
|
473
|
-
if (phase === 'building-plan') {
|
|
208
|
+
if (state.phase === 'building-plan') {
|
|
474
209
|
return _jsx(Spinner, { message: 'Building publish plan...' });
|
|
475
210
|
}
|
|
211
|
+
// Confirm publish
|
|
212
|
+
if (state.phase === 'confirm-publish' && state.plan && state.target) {
|
|
213
|
+
const confirmDisplayName = 'org' in state.target.data && state.target.data.org
|
|
214
|
+
? `@${state.target.data.org}/${state.target.data.name}`
|
|
215
|
+
: state.target.data.name;
|
|
216
|
+
const oldVersion = state.versionCheck && state.versionCheck.status !== 'new-asset' ? state.versionCheck.latestVersion : undefined;
|
|
217
|
+
const newVersion = state.plan.resolvedVersion;
|
|
218
|
+
const versionDisplay = oldVersion ? `${oldVersion} → ${newVersion}` : newVersion;
|
|
219
|
+
const hasOrg = 'org' in state.target.data && Boolean(state.target.data.org);
|
|
220
|
+
const reviewer = hasOrg ? 'none' : 'jasonpaff';
|
|
221
|
+
return (_jsxs(Box, { flexDirection: 'column', children: [_jsx(Box, { flexDirection: 'column', marginBottom: 1, children: _jsx(Text, { bold: true, children: "Publish Summary" }) }), _jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Asset: " }), _jsx(Text, { bold: true, children: confirmDisplayName })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Version: " }), versionDisplay] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Files: " }), state.plan.files.length] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Action: " }), "Create PR"] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Reviewer: " }), reviewer] })] }), _jsxs(Box, { children: [_jsx(Text, { color: 'cyan', children: '> ' }), _jsx(Text, { children: "Proceed? (y/n): " }), _jsx(TextInput, { focus: true, onChange: (v) => dispatch({ type: 'SET_PUBLISH_CONFIRM_VALUE', value: v }), onSubmit: () => dispatch({ type: 'SUBMIT_PUBLISH_CONFIRM' }), value: state.publishConfirmValue })] })] }));
|
|
222
|
+
}
|
|
476
223
|
// Dry run result
|
|
477
|
-
if (phase === 'dry-run-result' && plan && target) {
|
|
478
|
-
const statusLabel = plan.isUpdate
|
|
479
|
-
? `Update from v${versionCheck && versionCheck.status !== 'new-asset' ? versionCheck.latestVersion : '?'}`
|
|
224
|
+
if (state.phase === 'dry-run-result' && state.plan && state.target) {
|
|
225
|
+
const statusLabel = state.plan.isUpdate
|
|
226
|
+
? `Update from v${state.versionCheck && state.versionCheck.status !== 'new-asset' ? state.versionCheck.latestVersion : '?'}`
|
|
480
227
|
: 'New asset';
|
|
481
|
-
return (_jsxs(Box, { flexDirection: 'column', children: [_jsx(DryRunBanner, { action: 'publish', count: plan.files.length,
|
|
228
|
+
return (_jsxs(Box, { flexDirection: 'column', children: [_jsx(DryRunBanner, { action: 'publish', count: state.plan.files.length, tools: ['registry'] }), _jsx(Text, { children: " " }), state.validation && (_jsxs(Box, { flexDirection: 'column', marginBottom: 1, children: [_jsx(Text, { bold: true, children: "Validation:" }), state.validation.errors.length === 0 && (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'pass' }), " All checks passed"] })), state.validation.warnings.map((w, i) => (_jsxs(Text, { children: [' ', _jsx(CheckIcon, { status: 'warn' }), " ", w] }, i)))] })), _jsxs(Box, { flexDirection: 'column', children: [_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Asset: " }), _jsx(Text, { bold: true, children: displayName })] }), state.target.type === 'asset' && state.target.assetType && (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Type: " }), state.target.assetType] })), state.target.type === 'bundle' && (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Type: " }), "bundle"] })), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Version: " }), state.plan.resolvedVersion] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Status: " }), statusLabel] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Checksum: " }), state.plan.checksum] })] }), _jsx(Text, { children: " " }), _jsx(Text, { bold: true, children: "Files to publish:" }), state.plan.files.map((file) => (_jsxs(Text, { children: [" ", file] }, file))), _jsx(Text, { children: " " }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Target: " }), state.plan.registryPath] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Branch: " }), state.plan.branchName] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Action: " }), "Create PR"] })] }));
|
|
482
229
|
}
|
|
483
230
|
// Publishing
|
|
484
|
-
if (phase === 'publishing') {
|
|
485
|
-
return _jsx(Spinner, { message: progressMessage || 'Publishing...' });
|
|
231
|
+
if (state.phase === 'publishing') {
|
|
232
|
+
return _jsx(Spinner, { message: state.progressMessage || 'Publishing...' });
|
|
233
|
+
}
|
|
234
|
+
// Installing (auto-install raw publish to lockfile)
|
|
235
|
+
if (state.phase === 'installing') {
|
|
236
|
+
return _jsx(Spinner, { message: 'Adding to lockfile...' });
|
|
486
237
|
}
|
|
487
238
|
// Done
|
|
488
|
-
if (phase === 'done' && publishResult && target) {
|
|
489
|
-
return (_jsxs(Box, { flexDirection: 'column', children: [_jsxs(Text, { color: 'green', children: ["Published ", _jsx(Text, { bold: true, children:
|
|
239
|
+
if (state.phase === 'done' && state.publishResult && state.target) {
|
|
240
|
+
return (_jsxs(Box, { flexDirection: 'column', children: [_jsxs(Text, { color: 'green', children: ["Published ", _jsx(Text, { bold: true, children: displayName }), " v", state.resolvedVersion] }), state.isRawPublish && (_jsxs(Text, { color: 'green', children: ["Installed ", state.rawDetection?.name, "@", state.resolvedVersion || state.target.data.version || '1.0.0', " to lockfile"] })), _jsx(Text, { children: " " }), _jsxs(Text, { children: ["PR: ", _jsx(Text, { color: 'cyan', children: state.publishResult.prUrl })] }), _jsxs(Text, { children: ["Branch: ", _jsx(Text, { dimColor: true, children: state.publishResult.branchName })] })] }));
|
|
490
241
|
}
|
|
491
242
|
return null;
|
|
492
243
|
}
|