@detergent-software/atk 3.0.0-dev.20 → 3.0.0-dev.21

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 (51) hide show
  1. package/build/commands/setup.d.ts.map +1 -1
  2. package/build/commands/setup.js +6 -18
  3. package/build/commands/setup.js.map +1 -1
  4. package/build/commands/sync.d.ts.map +1 -1
  5. package/build/commands/sync.js +44 -163
  6. package/build/commands/sync.js.map +1 -1
  7. package/build/components/FrozenSkippedHint.d.ts +11 -0
  8. package/build/components/FrozenSkippedHint.d.ts.map +1 -0
  9. package/build/components/FrozenSkippedHint.js +12 -0
  10. package/build/components/FrozenSkippedHint.js.map +1 -0
  11. package/build/components/SyncAllInSync.d.ts +14 -0
  12. package/build/components/SyncAllInSync.d.ts.map +1 -0
  13. package/build/components/SyncAllInSync.js +10 -0
  14. package/build/components/SyncAllInSync.js.map +1 -0
  15. package/build/components/SyncDriftedList.d.ts +24 -0
  16. package/build/components/SyncDriftedList.d.ts.map +1 -0
  17. package/build/components/SyncDriftedList.js +17 -0
  18. package/build/components/SyncDriftedList.js.map +1 -0
  19. package/build/components/SyncNoAssets.d.ts +12 -0
  20. package/build/components/SyncNoAssets.d.ts.map +1 -0
  21. package/build/components/SyncNoAssets.js +9 -0
  22. package/build/components/SyncNoAssets.js.map +1 -0
  23. package/build/components/index.d.ts +4 -0
  24. package/build/components/index.d.ts.map +1 -1
  25. package/build/components/index.js +4 -0
  26. package/build/components/index.js.map +1 -1
  27. package/build/hooks/useSetupState.d.ts +2 -4
  28. package/build/hooks/useSetupState.d.ts.map +1 -1
  29. package/build/hooks/useSetupState.js +40 -99
  30. package/build/hooks/useSetupState.js.map +1 -1
  31. package/build/lib/adapter.d.ts +21 -0
  32. package/build/lib/adapter.d.ts.map +1 -1
  33. package/build/lib/adapter.js +59 -1
  34. package/build/lib/adapter.js.map +1 -1
  35. package/build/lib/detector.d.ts +2 -11
  36. package/build/lib/detector.d.ts.map +1 -1
  37. package/build/lib/detector.js +2 -64
  38. package/build/lib/detector.js.map +1 -1
  39. package/build/lib/gitignore.d.ts +17 -0
  40. package/build/lib/gitignore.d.ts.map +1 -1
  41. package/build/lib/gitignore.js +17 -1
  42. package/build/lib/gitignore.js.map +1 -1
  43. package/build/lib/setup.d.ts +28 -0
  44. package/build/lib/setup.d.ts.map +1 -0
  45. package/build/lib/setup.js +98 -0
  46. package/build/lib/setup.js.map +1 -0
  47. package/build/lib/sync.d.ts +109 -0
  48. package/build/lib/sync.d.ts.map +1 -0
  49. package/build/lib/sync.js +221 -0
  50. package/build/lib/sync.js.map +1 -0
  51. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/lib/setup.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,eAAO,MAAM,WAAW,QAA4B,CAAC;AAMrD,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACd;AAMD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiFtG"}
@@ -0,0 +1,98 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { loadAdapter } from './adapter.js';
3
+ import { saveProjectConfig } from './config.js';
4
+ import { ensureGitignoreEntries, ensureGitignorePatterns } from './gitignore.js';
5
+ import { getLockfilePath, readLockfile, writeLockfile } from './lockfile.js';
6
+ // ---------------------------------------------------------------------------
7
+ // Constants
8
+ // ---------------------------------------------------------------------------
9
+ /**
10
+ * Regex for valid org identifiers. Must start with a letter, then letters,
11
+ * digits, or hyphens. Matches the constraint in the manifest schema.
12
+ */
13
+ export const ORG_PATTERN = /^[a-zA-Z][a-zA-Z0-9-]*$/;
14
+ // ---------------------------------------------------------------------------
15
+ // Main function
16
+ // ---------------------------------------------------------------------------
17
+ /**
18
+ * Perform the setup creation step: write project config, write/update the
19
+ * lockfile, and ensure gitignore entries are present for the selected tools.
20
+ *
21
+ * This is the extracted business logic from the `useSetupState` creating
22
+ * effect, made independently testable without React rendering overhead.
23
+ */
24
+ export async function performSetupCreation(options) {
25
+ const { orgLocked, orgValue, projectDir, selectedTools } = options;
26
+ const actions = [];
27
+ const warnings = [];
28
+ const resolvedOrg = orgLocked ? orgValue.trim() : orgValue.trim() || undefined;
29
+ // Validate org format when non-empty
30
+ if (resolvedOrg !== undefined && !ORG_PATTERN.test(resolvedOrg)) {
31
+ throw new Error(`Invalid org "${resolvedOrg}": must start with a letter and contain only letters, digits, or hyphens.`);
32
+ }
33
+ // 1. Write .atkrc.json with { tools: [...] }
34
+ await saveProjectConfig(projectDir, { tools: selectedTools });
35
+ actions.push({ detail: `tools: ${selectedTools.join(', ')}`, label: 'Wrote .atkrc.json' });
36
+ // 2. Write/update .atk-lock.json
37
+ const lockfilePath = getLockfilePath(projectDir);
38
+ if (existsSync(lockfilePath)) {
39
+ // Preserve existing assets and org
40
+ const existing = await readLockfile(projectDir);
41
+ // Only update org if it's not already set and we have a new one
42
+ const updatedLockfile = {
43
+ ...existing,
44
+ lockVersion: 1,
45
+ ...(resolvedOrg !== undefined && !existing.org ? { org: resolvedOrg } : {}),
46
+ };
47
+ await writeLockfile(projectDir, updatedLockfile);
48
+ actions.push({
49
+ detail: `${(existing.assets ?? []).length} existing asset(s) preserved`,
50
+ label: 'Updated .atk-lock.json',
51
+ });
52
+ }
53
+ else {
54
+ await writeLockfile(projectDir, {
55
+ assets: [],
56
+ lockVersion: 1,
57
+ ...(resolvedOrg !== undefined ? { org: resolvedOrg } : {}),
58
+ });
59
+ actions.push({
60
+ detail: resolvedOrg ? `org: ${resolvedOrg}` : 'no org',
61
+ label: 'Created .atk-lock.json',
62
+ });
63
+ }
64
+ // 3. Ensure .atkrc.json is in .gitignore via the adapters' gitignore entries
65
+ const allAdded = [];
66
+ let anyAdapterLoaded = false;
67
+ for (const tool of selectedTools) {
68
+ try {
69
+ const adapter = await loadAdapter(tool);
70
+ anyAdapterLoaded = true;
71
+ const { added } = await ensureGitignoreEntries(projectDir, adapter);
72
+ allAdded.push(...added);
73
+ }
74
+ catch (err) {
75
+ // Individual adapter load failure is non-fatal; record warning and continue
76
+ const message = err instanceof Error ? err.message : String(err);
77
+ warnings.push(`Failed to load adapter for "${tool}": ${message}`);
78
+ }
79
+ }
80
+ if (!anyAdapterLoaded) {
81
+ // If no adapters could be loaded, manually ensure critical files are gitignored
82
+ try {
83
+ const { added } = await ensureGitignorePatterns(projectDir, ['.atkrc.json', '.atk-lock.json.lock']);
84
+ allAdded.push(...added);
85
+ }
86
+ catch (err) {
87
+ const message = err instanceof Error ? err.message : String(err);
88
+ warnings.push(`Failed to update .gitignore: ${message}`);
89
+ }
90
+ }
91
+ if (allAdded.length > 0) {
92
+ // Deduplicate entries
93
+ const uniqueAdded = [...new Set(allAdded)];
94
+ actions.push({ detail: uniqueAdded.join(', '), label: 'Updated .gitignore' });
95
+ }
96
+ return { actions, warnings };
97
+ }
98
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/lib/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ import type { InstallResult } from './installer.js';
2
+ import type { Adapter } from './schemas/adapter.js';
3
+ import type { ProjectConfig } from './schemas/config.js';
4
+ import type { InstalledAsset } from './schemas/lockfile.js';
5
+ import type { Registry } from './schemas/registry.js';
6
+ export interface ClassifySyncEntriesOptions {
7
+ adapter: Adapter;
8
+ assets: InstalledAsset[];
9
+ force: boolean;
10
+ onProgress?: (msg: string) => void;
11
+ projectConfig: null | ProjectConfig;
12
+ projectDir: string;
13
+ }
14
+ export interface ClassifySyncEntriesResult {
15
+ frozenSkipped: number;
16
+ skipped: number;
17
+ toSync: SyncEntry[];
18
+ }
19
+ export interface DryRunSyncOptions {
20
+ force: boolean;
21
+ onProgress?: (msg: string) => void;
22
+ projectConfig: null | ProjectConfig;
23
+ projectDir: string;
24
+ tools: Array<{
25
+ adapter: Adapter;
26
+ tool: string;
27
+ }>;
28
+ }
29
+ export interface SyncAssetsOptions {
30
+ force: boolean;
31
+ onProgress?: (msg: string) => void;
32
+ projectConfig: null | ProjectConfig;
33
+ projectDir: string;
34
+ registry: Registry;
35
+ tools: Array<{
36
+ adapter: Adapter;
37
+ tool: string;
38
+ }>;
39
+ }
40
+ export interface SyncEntry {
41
+ asset: InstalledAsset;
42
+ reason: 'forced' | 'missing' | 'modified';
43
+ result?: InstallResult;
44
+ }
45
+ export interface SyncFailure {
46
+ assetName: string;
47
+ assetType: string;
48
+ error: string;
49
+ version: string;
50
+ }
51
+ export type SyncOutcome = {
52
+ outcome: 'dry-run';
53
+ toolResults: ToolDryRunResult[];
54
+ } | {
55
+ outcome: 'synced';
56
+ toolResults: ToolSyncResult[];
57
+ };
58
+ export interface ToolDryRunResult {
59
+ bootstrapHint?: string;
60
+ frozenSkipped: number;
61
+ skipped: number;
62
+ tool: string;
63
+ toSync: SyncEntry[];
64
+ }
65
+ export interface ToolSyncResult {
66
+ bootstrapHint?: string;
67
+ failures: SyncFailure[];
68
+ frozenSkipped: number;
69
+ skipped: number;
70
+ synced: SyncEntry[];
71
+ tool: string;
72
+ }
73
+ /**
74
+ * Classify installed assets into entries that need syncing vs. those that
75
+ * can be skipped. This consolidates the duplicated checksum-checking loop
76
+ * that previously appeared in both the dry-run and live sync paths.
77
+ *
78
+ * For each asset the function:
79
+ * 1. Checks if the asset is frozen — if so, increments `frozenSkipped`.
80
+ * 2. If `force` is true, marks it as `forced` without checking checksums.
81
+ * 3. Otherwise, resolves installed paths via the adapter, verifies checksums,
82
+ * and classifies as `missing` or `modified` when checksums fail, or
83
+ * increments `skipped` when all checksums pass.
84
+ */
85
+ export declare function classifySyncEntries(options: ClassifySyncEntriesOptions): Promise<ClassifySyncEntriesResult>;
86
+ /**
87
+ * Perform a dry-run sync: read the lockfile (without locking), classify each
88
+ * tool's assets, and return the results so the UI can display what *would*
89
+ * be synced.
90
+ *
91
+ * This fixes finding O10.3 by populating `bootstrapHint` when a tool has no
92
+ * installed assets, which the original inline dry-run path in sync.tsx omitted.
93
+ */
94
+ export declare function dryRunSync(options: DryRunSyncOptions): Promise<ToolDryRunResult[]>;
95
+ /**
96
+ * Perform a live sync: acquire the lockfile lock, classify each tool's assets,
97
+ * then remove and reinstall drifted entries.
98
+ *
99
+ * Uses `removeSingleAsset()` for disk-only cleanup (no lockfile I/O) and
100
+ * manages lockfile state in-memory with a single read at the start and a
101
+ * single write at the end. This follows the same pattern established by
102
+ * `executeBundleUninstall()` in `uninstaller.ts`.
103
+ *
104
+ * NOTE: Sync reinstalls only the direct asset, not its dependencies. This is
105
+ * intentional per F4.2 — dependencies are assumed to already be installed and
106
+ * are not re-fetched during a sync operation.
107
+ */
108
+ export declare function syncAssets(options: SyncAssetsOptions): Promise<ToolSyncResult[]>;
109
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,221 @@
1
+ import { join } from 'node:path';
2
+ import { resolveInstalledPaths } from './adapter.js';
3
+ import { verifyChecksums } from './checksum.js';
4
+ import { isFrozenInConfig } from './config.js';
5
+ import { executeInstallPlan, InstallerError } from './installer.js';
6
+ import { addAssetToLockfile, readLockfile, removeAssetFromLockfile, withLockfileErrorHandling, writeLockfile } from './lockfile.js';
7
+ import { resolveInstallPlan, ResolverError } from './resolver.js';
8
+ import { removeSingleAsset, UninstallerError } from './uninstaller.js';
9
+ // ---------------------------------------------------------------------------
10
+ // Dry-run orchestration
11
+ // ---------------------------------------------------------------------------
12
+ /**
13
+ * Classify installed assets into entries that need syncing vs. those that
14
+ * can be skipped. This consolidates the duplicated checksum-checking loop
15
+ * that previously appeared in both the dry-run and live sync paths.
16
+ *
17
+ * For each asset the function:
18
+ * 1. Checks if the asset is frozen — if so, increments `frozenSkipped`.
19
+ * 2. If `force` is true, marks it as `forced` without checking checksums.
20
+ * 3. Otherwise, resolves installed paths via the adapter, verifies checksums,
21
+ * and classifies as `missing` or `modified` when checksums fail, or
22
+ * increments `skipped` when all checksums pass.
23
+ */
24
+ export async function classifySyncEntries(options) {
25
+ const { adapter, assets, force, onProgress, projectConfig, projectDir } = options;
26
+ const toSync = [];
27
+ let frozenSkipped = 0;
28
+ let skipped = 0;
29
+ for (const asset of assets) {
30
+ onProgress?.(`Checking ${asset.name}...`);
31
+ if (isFrozenInConfig(projectConfig, asset.name, asset.type, asset.org)) {
32
+ frozenSkipped++;
33
+ continue;
34
+ }
35
+ if (force) {
36
+ toSync.push({ asset, reason: 'forced' });
37
+ continue;
38
+ }
39
+ const resolved = resolveInstalledPaths(asset, adapter, projectDir);
40
+ const filesToCheck = resolved.files.map((f) => ({
41
+ checksum: f.checksum,
42
+ path: join(projectDir, f.installedPath),
43
+ }));
44
+ const checksumFailures = await verifyChecksums(filesToCheck);
45
+ if (checksumFailures.length === 0) {
46
+ skipped++;
47
+ continue;
48
+ }
49
+ const hasMissing = checksumFailures.some((f) => f.actual.startsWith('FILE_NOT_FOUND'));
50
+ toSync.push({
51
+ asset,
52
+ reason: hasMissing ? 'missing' : 'modified',
53
+ });
54
+ }
55
+ return { frozenSkipped, skipped, toSync };
56
+ }
57
+ /**
58
+ * Perform a dry-run sync: read the lockfile (without locking), classify each
59
+ * tool's assets, and return the results so the UI can display what *would*
60
+ * be synced.
61
+ *
62
+ * This fixes finding O10.3 by populating `bootstrapHint` when a tool has no
63
+ * installed assets, which the original inline dry-run path in sync.tsx omitted.
64
+ */
65
+ export async function dryRunSync(options) {
66
+ const { force, onProgress, projectConfig, projectDir, tools } = options;
67
+ onProgress?.('Reading lockfile...');
68
+ const lockfile = await readLockfile(projectDir);
69
+ const toolResults = [];
70
+ for (const { adapter, tool: toolName } of tools) {
71
+ const toolAssets = lockfile.assets ?? [];
72
+ if (toolAssets.length === 0) {
73
+ toolResults.push({
74
+ bootstrapHint: `Run "atk install <asset>" to install assets for ${toolName}`,
75
+ frozenSkipped: 0,
76
+ skipped: 0,
77
+ tool: toolName,
78
+ toSync: [],
79
+ });
80
+ continue;
81
+ }
82
+ const classified = await classifySyncEntries({
83
+ adapter,
84
+ assets: toolAssets,
85
+ force,
86
+ onProgress: onProgress
87
+ ? (msg) => onProgress(`${msg} for ${toolName}`)
88
+ : undefined,
89
+ projectConfig,
90
+ projectDir,
91
+ });
92
+ toolResults.push({
93
+ frozenSkipped: classified.frozenSkipped,
94
+ skipped: classified.skipped,
95
+ tool: toolName,
96
+ toSync: classified.toSync,
97
+ });
98
+ }
99
+ return toolResults;
100
+ }
101
+ // ---------------------------------------------------------------------------
102
+ // Live sync orchestration
103
+ // ---------------------------------------------------------------------------
104
+ /**
105
+ * Perform a live sync: acquire the lockfile lock, classify each tool's assets,
106
+ * then remove and reinstall drifted entries.
107
+ *
108
+ * Uses `removeSingleAsset()` for disk-only cleanup (no lockfile I/O) and
109
+ * manages lockfile state in-memory with a single read at the start and a
110
+ * single write at the end. This follows the same pattern established by
111
+ * `executeBundleUninstall()` in `uninstaller.ts`.
112
+ *
113
+ * NOTE: Sync reinstalls only the direct asset, not its dependencies. This is
114
+ * intentional per F4.2 — dependencies are assumed to already be installed and
115
+ * are not re-fetched during a sync operation.
116
+ */
117
+ export async function syncAssets(options) {
118
+ const { force, onProgress, projectConfig, projectDir, registry, tools } = options;
119
+ return withLockfileErrorHandling(projectDir, async () => {
120
+ onProgress?.('Reading lockfile...');
121
+ let lockfile = await readLockfile(projectDir);
122
+ const toolResults = [];
123
+ for (const { adapter, tool: toolName } of tools) {
124
+ const toolAssets = lockfile.assets ?? [];
125
+ if (toolAssets.length === 0) {
126
+ toolResults.push({
127
+ bootstrapHint: 'No assets installed. Run `atk setup` to initialize.',
128
+ failures: [],
129
+ frozenSkipped: 0,
130
+ skipped: 0,
131
+ synced: [],
132
+ tool: toolName,
133
+ });
134
+ continue;
135
+ }
136
+ const classified = await classifySyncEntries({
137
+ adapter,
138
+ assets: toolAssets,
139
+ force,
140
+ onProgress: onProgress
141
+ ? (msg) => onProgress(`${msg} for ${toolName}`)
142
+ : undefined,
143
+ projectConfig,
144
+ projectDir,
145
+ });
146
+ if (classified.toSync.length === 0) {
147
+ toolResults.push({
148
+ failures: [],
149
+ frozenSkipped: classified.frozenSkipped,
150
+ skipped: classified.skipped,
151
+ synced: [],
152
+ tool: toolName,
153
+ });
154
+ continue;
155
+ }
156
+ const failures = [];
157
+ for (const entry of classified.toSync) {
158
+ onProgress?.(`Syncing ${entry.asset.name} for ${toolName}...`);
159
+ // Save the original lockfile entry so we can restore it on reinstall failure
160
+ const originalEntry = entry.asset;
161
+ // Step 1: Disk-only cleanup via removeSingleAsset (no lockfile I/O).
162
+ // Tolerate UninstallerError (e.g., files already missing) but propagate
163
+ // unexpected errors.
164
+ try {
165
+ await removeSingleAsset(originalEntry, adapter, projectDir, onProgress);
166
+ }
167
+ catch (error) {
168
+ if (!(error instanceof UninstallerError)) {
169
+ throw error;
170
+ }
171
+ }
172
+ // Step 2: Track removal in the in-memory lockfile
173
+ lockfile = removeAssetFromLockfile(lockfile, originalEntry.name, originalEntry.type, originalEntry.org);
174
+ // Step 3: Reinstall the direct asset only (not dependencies — intentional per F4.2).
175
+ // Resolve the full plan but filter to just the direct asset entry.
176
+ try {
177
+ const plan = resolveInstallPlan(registry, originalEntry.name, originalEntry.type, originalEntry.version);
178
+ const directEntries = plan.entries.filter((e) => e.asset.name === originalEntry.name);
179
+ const directPlan = { entries: directEntries, totalCount: directEntries.length };
180
+ const results = await executeInstallPlan(directPlan, {
181
+ adapter,
182
+ onProgress,
183
+ projectDir,
184
+ });
185
+ entry.result = results[0];
186
+ // Step 4: After successful reinstall, re-read the lockfile from disk
187
+ // to capture the state that executeInstallPlan wrote, and keep our
188
+ // in-memory copy in sync.
189
+ lockfile = await readLockfile(projectDir);
190
+ }
191
+ catch (error) {
192
+ if (error instanceof ResolverError || error instanceof InstallerError) {
193
+ // On reinstall failure, restore the original InstalledAsset entry
194
+ // back into the in-memory lockfile so it is not silently dropped.
195
+ lockfile = addAssetToLockfile(lockfile, originalEntry);
196
+ failures.push({
197
+ assetName: originalEntry.name,
198
+ assetType: originalEntry.type,
199
+ error: error.message,
200
+ version: originalEntry.version,
201
+ });
202
+ continue;
203
+ }
204
+ throw error;
205
+ }
206
+ }
207
+ toolResults.push({
208
+ failures,
209
+ frozenSkipped: classified.frozenSkipped,
210
+ skipped: classified.skipped,
211
+ synced: classified.toSync.filter((e) => e.result !== undefined),
212
+ tool: toolName,
213
+ });
214
+ }
215
+ // Write the lockfile once at the end to persist any in-memory mutations
216
+ // (e.g., restored entries from failed reinstalls)
217
+ await writeLockfile(projectDir, lockfile);
218
+ return toolResults;
219
+ });
220
+ }
221
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@detergent-software/atk",
3
- "version": "3.0.0-dev.20",
3
+ "version": "3.0.0-dev.21",
4
4
  "description": "Agentic Tool Kit — CLI for managing AI coding tool assets.",
5
5
  "type": "module",
6
6
  "bin": {