@schnick371/devsteps-shared 0.8.4 → 1.0.0-next.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.
- package/README.md +8 -3
- package/dist/constants/index.d.ts +26 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +26 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/core/add.d.ts +8 -1
- package/dist/core/add.d.ts.map +1 -1
- package/dist/core/add.js +17 -10
- package/dist/core/add.js.map +1 -1
- package/dist/core/archive.d.ts +9 -2
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +40 -30
- package/dist/core/archive.js.map +1 -1
- package/dist/core/auto-migrate-detect.d.ts +61 -0
- package/dist/core/auto-migrate-detect.d.ts.map +1 -0
- package/dist/core/auto-migrate-detect.js +68 -0
- package/dist/core/auto-migrate-detect.js.map +1 -0
- package/dist/core/auto-migrate-impl.d.ts +32 -0
- package/dist/core/auto-migrate-impl.d.ts.map +1 -0
- package/dist/core/auto-migrate-impl.js +120 -0
- package/dist/core/auto-migrate-impl.js.map +1 -0
- package/dist/core/auto-migrate.d.ts +16 -131
- package/dist/core/auto-migrate.d.ts.map +1 -1
- package/dist/core/auto-migrate.js +25 -318
- package/dist/core/auto-migrate.js.map +1 -1
- package/dist/core/auto-migrate.test.js +11 -7
- package/dist/core/auto-migrate.test.js.map +1 -1
- package/dist/core/bulk-update.d.ts +13 -6
- package/dist/core/bulk-update.d.ts.map +1 -1
- package/dist/core/bulk-update.js +19 -12
- package/dist/core/bulk-update.js.map +1 -1
- package/dist/core/config.d.ts +7 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +7 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/context.d.ts +13 -4
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +22 -13
- package/dist/core/context.js.map +1 -1
- package/dist/core/get.d.ts +8 -1
- package/dist/core/get.d.ts.map +1 -1
- package/dist/core/get.js +12 -5
- package/dist/core/get.js.map +1 -1
- package/dist/core/index-rebuild.d.ts +3 -0
- package/dist/core/index-rebuild.d.ts.map +1 -1
- package/dist/core/index-rebuild.js +11 -8
- package/dist/core/index-rebuild.js.map +1 -1
- package/dist/core/index-rebuild.test.js +6 -15
- package/dist/core/index-rebuild.test.js.map +1 -1
- package/dist/core/index-refs-core.d.ts +114 -0
- package/dist/core/index-refs-core.d.ts.map +1 -0
- package/dist/core/index-refs-core.js +306 -0
- package/dist/core/index-refs-core.js.map +1 -0
- package/dist/core/index-refs.d.ts +9 -124
- package/dist/core/index-refs.d.ts.map +1 -1
- package/dist/core/index-refs.js +19 -345
- package/dist/core/index-refs.js.map +1 -1
- package/dist/core/index-refs.test.js +3 -3
- package/dist/core/index-refs.test.js.map +1 -1
- package/dist/core/index.d.ts +19 -10
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +19 -10
- package/dist/core/index.js.map +1 -1
- package/dist/core/link.d.ts +33 -0
- package/dist/core/link.d.ts.map +1 -0
- package/dist/core/link.js +102 -0
- package/dist/core/link.js.map +1 -0
- package/dist/core/list.d.ts +9 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +92 -15
- package/dist/core/list.js.map +1 -1
- package/dist/core/unlink.d.ts +26 -0
- package/dist/core/unlink.d.ts.map +1 -0
- package/dist/core/unlink.js +78 -0
- package/dist/core/unlink.js.map +1 -0
- package/dist/core/update.d.ts +8 -1
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +23 -15
- package/dist/core/update.js.map +1 -1
- package/dist/core/validation.d.ts +26 -1
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +65 -4
- package/dist/core/validation.js.map +1 -1
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/schemas/analysis.d.ts +206 -0
- package/dist/schemas/analysis.d.ts.map +1 -0
- package/dist/schemas/analysis.js +138 -0
- package/dist/schemas/analysis.js.map +1 -0
- package/dist/schemas/cbp-loops.d.ts +154 -0
- package/dist/schemas/cbp-loops.d.ts.map +1 -0
- package/dist/schemas/cbp-loops.js +160 -0
- package/dist/schemas/cbp-loops.js.map +1 -0
- package/dist/schemas/cbp-loops.test.d.ts +10 -0
- package/dist/schemas/cbp-loops.test.d.ts.map +1 -0
- package/dist/schemas/cbp-loops.test.js +268 -0
- package/dist/schemas/cbp-loops.test.js.map +1 -0
- package/dist/schemas/cbp-mandate.d.ts +107 -0
- package/dist/schemas/cbp-mandate.d.ts.map +1 -0
- package/dist/schemas/cbp-mandate.js +107 -0
- package/dist/schemas/cbp-mandate.js.map +1 -0
- package/dist/schemas/cbp-mandate.test.d.ts +10 -0
- package/dist/schemas/cbp-mandate.test.d.ts.map +1 -0
- package/dist/schemas/cbp-mandate.test.js +188 -0
- package/dist/schemas/cbp-mandate.test.js.map +1 -0
- package/dist/schemas/index-refs.schema.d.ts +4 -1
- package/dist/schemas/index-refs.schema.d.ts.map +1 -1
- package/dist/schemas/index-refs.schema.js +24 -3
- package/dist/schemas/index-refs.schema.js.map +1 -1
- package/dist/schemas/index.d.ts +17 -7
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +14 -1
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/project.d.ts +7 -0
- package/dist/schemas/project.d.ts.map +1 -1
- package/dist/schemas/project.js +7 -0
- package/dist/schemas/project.js.map +1 -1
- package/dist/schemas/relationships.d.ts +3 -0
- package/dist/schemas/relationships.d.ts.map +1 -1
- package/dist/schemas/relationships.js +3 -0
- package/dist/schemas/relationships.js.map +1 -1
- package/dist/types/commands.d.ts +7 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/commands.js +7 -0
- package/dist/types/commands.js.map +1 -1
- package/dist/types/index-refs.types.d.ts +3 -0
- package/dist/types/index-refs.types.d.ts.map +1 -1
- package/dist/types/index-refs.types.js +3 -0
- package/dist/types/index-refs.types.js.map +1 -1
- package/dist/types/index.d.ts +9 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/cache.d.ts +7 -0
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/cache.js +7 -0
- package/dist/utils/cache.js.map +1 -1
- package/dist/utils/index.d.ts +9 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +26 -3
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/init-helpers.d.ts +30 -0
- package/dist/utils/init-helpers.d.ts.map +1 -0
- package/dist/utils/init-helpers.js +134 -0
- package/dist/utils/init-helpers.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Auto-Migration Implementation
|
|
6
|
+
*
|
|
7
|
+
* Stateful migration operations: performs actual index and directory migrations.
|
|
8
|
+
* Contains all I/O-heavy transformation logic.
|
|
9
|
+
*
|
|
10
|
+
* @see STORY-073 External Project Migration Auto-Detection
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmdirSync, writeFileSync, } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { TYPE_TO_DIRECTORY } from '../utils/index.js';
|
|
15
|
+
import { addItemToIndex, getIndexPaths, hasLegacyIndex, hasRefsStyleIndex, initializeRefsStyleIndex, loadAllIndexes, } from './index-refs.js';
|
|
16
|
+
/**
|
|
17
|
+
* Perform core index migration: legacy index.json → refs-style distributed index
|
|
18
|
+
*
|
|
19
|
+
* @param devstepsDir Path to .devsteps directory
|
|
20
|
+
* @param options Migration options
|
|
21
|
+
* @returns Migration statistics
|
|
22
|
+
* @throws Error if migration fails or preconditions not met
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export async function performMigration(devstepsDir, options = {}) {
|
|
26
|
+
const { skipBackup = false } = options;
|
|
27
|
+
const paths = getIndexPaths(devstepsDir);
|
|
28
|
+
if (!existsSync(devstepsDir))
|
|
29
|
+
throw new Error('.devsteps directory not found. Is this a DevSteps project?');
|
|
30
|
+
if (!hasLegacyIndex(devstepsDir))
|
|
31
|
+
throw new Error('No index.json found. Nothing to migrate.');
|
|
32
|
+
if (hasRefsStyleIndex(devstepsDir))
|
|
33
|
+
throw new Error('Refs-style index already exists. Aborting to prevent data loss.');
|
|
34
|
+
const stats = { totalItems: 0, byType: {}, byStatus: {}, byPriority: {} };
|
|
35
|
+
// Backup old index
|
|
36
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
37
|
+
if (!skipBackup) {
|
|
38
|
+
const backupPath = `${paths.legacy}.backup-${timestamp}`;
|
|
39
|
+
writeFileSync(backupPath, readFileSync(paths.legacy, 'utf-8'));
|
|
40
|
+
stats.backupPath = backupPath;
|
|
41
|
+
}
|
|
42
|
+
// Load legacy index + initialize new structure
|
|
43
|
+
const legacyIndex = JSON.parse(readFileSync(paths.legacy, 'utf-8'));
|
|
44
|
+
initializeRefsStyleIndex(devstepsDir, legacyIndex.counters || {});
|
|
45
|
+
// Migrate each item into new index
|
|
46
|
+
for (const item of legacyIndex.items) {
|
|
47
|
+
const typeFolder = TYPE_TO_DIRECTORY[item.type];
|
|
48
|
+
const metadataPath = join(devstepsDir, typeFolder, `${item.id}.json`);
|
|
49
|
+
if (!existsSync(metadataPath))
|
|
50
|
+
continue;
|
|
51
|
+
const metadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
|
|
52
|
+
if (!metadata.eisenhower)
|
|
53
|
+
metadata.eisenhower = 'not-urgent-important'; // Default Q2
|
|
54
|
+
addItemToIndex(devstepsDir, metadata);
|
|
55
|
+
stats.totalItems++;
|
|
56
|
+
stats.byType[item.type] = (stats.byType[item.type] || 0) + 1;
|
|
57
|
+
stats.byStatus[item.status] = (stats.byStatus[item.status] || 0) + 1;
|
|
58
|
+
stats.byPriority[metadata.eisenhower] = (stats.byPriority[metadata.eisenhower] || 0) + 1;
|
|
59
|
+
}
|
|
60
|
+
// Verify migration: count + deduplicate
|
|
61
|
+
const newIndexes = loadAllIndexes(devstepsDir);
|
|
62
|
+
let newItemCount = 0;
|
|
63
|
+
for (const items of newIndexes.byType.values()) {
|
|
64
|
+
newItemCount += items.length;
|
|
65
|
+
}
|
|
66
|
+
if (newItemCount !== stats.totalItems) {
|
|
67
|
+
throw new Error(`Item count mismatch! Migrated: ${stats.totalItems}, Verified: ${newItemCount}`);
|
|
68
|
+
}
|
|
69
|
+
const allIds = new Set();
|
|
70
|
+
for (const items of newIndexes.byType.values()) {
|
|
71
|
+
for (const id of items) {
|
|
72
|
+
if (allIds.has(id))
|
|
73
|
+
throw new Error(`Duplicate item detected: ${id}`);
|
|
74
|
+
allIds.add(id);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Archive old index and return stats
|
|
78
|
+
const archivePath = `${paths.legacy}.archived-${timestamp}`;
|
|
79
|
+
renameSync(paths.legacy, archivePath);
|
|
80
|
+
stats.archivePath = archivePath;
|
|
81
|
+
return stats;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Migrate from flat directory structure to items/ subdirectory
|
|
85
|
+
*
|
|
86
|
+
* Moves: `.devsteps/epics/…` → `.devsteps/items/epics/…`
|
|
87
|
+
*/
|
|
88
|
+
export function migrateItemsDirectory(devstepsDir, options = {}) {
|
|
89
|
+
const { silent = false } = options;
|
|
90
|
+
if (!silent)
|
|
91
|
+
console.log('📂 Migrating to items/ directory structure...');
|
|
92
|
+
const oldDirs = ['epics', 'stories', 'tasks', 'bugs', 'spikes', 'tests', 'requirements', 'features'];
|
|
93
|
+
const stats = { moved: 0, types: {} };
|
|
94
|
+
const itemsDir = join(devstepsDir, 'items');
|
|
95
|
+
if (!existsSync(itemsDir))
|
|
96
|
+
mkdirSync(itemsDir, { recursive: true });
|
|
97
|
+
for (const dirName of oldDirs) {
|
|
98
|
+
const oldPath = join(devstepsDir, dirName);
|
|
99
|
+
const newPath = join(itemsDir, dirName);
|
|
100
|
+
if (!existsSync(oldPath))
|
|
101
|
+
continue;
|
|
102
|
+
mkdirSync(newPath, { recursive: true });
|
|
103
|
+
const files = readdirSync(oldPath);
|
|
104
|
+
let count = 0;
|
|
105
|
+
for (const file of files) {
|
|
106
|
+
renameSync(join(oldPath, file), join(newPath, file));
|
|
107
|
+
count++;
|
|
108
|
+
}
|
|
109
|
+
stats.types[dirName] = count;
|
|
110
|
+
stats.moved += count;
|
|
111
|
+
try {
|
|
112
|
+
rmdirSync(oldPath);
|
|
113
|
+
}
|
|
114
|
+
catch { /* ignore — not empty or other error */ }
|
|
115
|
+
}
|
|
116
|
+
if (!silent)
|
|
117
|
+
console.log(` ✅ Moved ${stats.moved} files to items/ subdirectories`);
|
|
118
|
+
return stats;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=auto-migrate-impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-migrate-impl.js","sourceRoot":"","sources":["../../src/core/auto-migrate-impl.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,155 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
+
* Auto-Migration Module — Orchestrator
|
|
6
|
+
*
|
|
7
|
+
* Provides auto-detection and migration for DevSteps projects.
|
|
5
8
|
* Safely migrates from legacy index.json to refs-style distributed index.
|
|
6
9
|
*
|
|
7
|
-
* Safe to call repeatedly
|
|
10
|
+
* Safe to call repeatedly — only migrates once.
|
|
8
11
|
*
|
|
9
12
|
* @see STORY-073 External Project Migration Auto-Detection
|
|
10
13
|
* @see EPIC-018 Index Architecture Refactoring
|
|
11
14
|
*/
|
|
15
|
+
import { type AutoMigrationOptions, type MigrationCheckResult, type MigrationStats, checkMigrationNeeded, getMigrationStatusMessage, needsItemsDirectoryMigration } from './auto-migrate-detect.js';
|
|
16
|
+
import { migrateItemsDirectory, performMigration } from './auto-migrate-impl.js';
|
|
17
|
+
export type { AutoMigrationOptions, MigrationCheckResult, MigrationStats };
|
|
18
|
+
export { checkMigrationNeeded, getMigrationStatusMessage, needsItemsDirectoryMigration };
|
|
19
|
+
export { performMigration, migrateItemsDirectory };
|
|
12
20
|
/**
|
|
13
|
-
*
|
|
14
|
-
*/
|
|
15
|
-
export interface MigrationCheckResult {
|
|
16
|
-
/** Whether migration is needed */
|
|
17
|
-
needed: boolean;
|
|
18
|
-
/** Whether legacy index exists */
|
|
19
|
-
hasLegacy: boolean;
|
|
20
|
-
/** Whether refs-style index exists */
|
|
21
|
-
hasRefs: boolean;
|
|
22
|
-
/** Number of items in legacy index (if exists) */
|
|
23
|
-
itemCount?: number;
|
|
24
|
-
/** Human-readable status message */
|
|
25
|
-
message: string;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Auto-migration options
|
|
29
|
-
*/
|
|
30
|
-
export interface AutoMigrationOptions {
|
|
31
|
-
/** Skip backup creation (advanced users only) */
|
|
32
|
-
skipBackup?: boolean;
|
|
33
|
-
/** Silent mode - suppress console output */
|
|
34
|
-
silent?: boolean;
|
|
35
|
-
/** Dry-run mode - check only, don't migrate */
|
|
36
|
-
dryRun?: boolean;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Migration statistics
|
|
40
|
-
*/
|
|
41
|
-
export interface MigrationStats {
|
|
42
|
-
totalItems: number;
|
|
43
|
-
byType: Record<string, number>;
|
|
44
|
-
byStatus: Record<string, number>;
|
|
45
|
-
byPriority: Record<string, number>;
|
|
46
|
-
backupPath?: string;
|
|
47
|
-
archivePath?: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Check if migration is needed
|
|
51
|
-
*
|
|
52
|
-
* Migration is needed when:
|
|
53
|
-
* - Legacy index.json exists
|
|
54
|
-
* - Refs-style index/ doesn't exist
|
|
55
|
-
*
|
|
56
|
-
* @param devstepsDir Path to .devsteps directory
|
|
57
|
-
* @returns Migration check result with details
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```typescript
|
|
61
|
-
* const result = checkMigrationNeeded('/path/to/.devsteps');
|
|
62
|
-
* if (result.needed) {
|
|
63
|
-
* console.log(result.message);
|
|
64
|
-
* await ensureIndexMigrated('/path/to/.devsteps');
|
|
65
|
-
* }
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
export declare function checkMigrationNeeded(devstepsDir: string): MigrationCheckResult;
|
|
69
|
-
/**
|
|
70
|
-
* Perform index migration (internal implementation)
|
|
71
|
-
*
|
|
72
|
-
* This is the core migration logic without console output.
|
|
73
|
-
* Use ensureIndexMigrated() for auto-migration with user feedback.
|
|
74
|
-
*
|
|
75
|
-
* @param devstepsDir Path to .devsteps directory
|
|
76
|
-
* @param options Migration options
|
|
77
|
-
* @returns Migration statistics
|
|
78
|
-
* @throws Error if migration fails or preconditions not met
|
|
79
|
-
* @internal
|
|
80
|
-
*/
|
|
81
|
-
export declare function performMigration(devstepsDir: string, options?: AutoMigrationOptions): Promise<MigrationStats>;
|
|
82
|
-
/**
|
|
83
|
-
* Get user-friendly status message
|
|
84
|
-
*
|
|
85
|
-
* @param devstepsDir Path to .devsteps directory
|
|
86
|
-
* @returns Human-readable status message
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```typescript
|
|
90
|
-
* console.log(getMigrationStatusMessage('/path/to/.devsteps'));
|
|
91
|
-
* // Output: "📦 DevSteps project using refs-style index ✓"
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
export declare function getMigrationStatusMessage(devstepsDir: string): string;
|
|
95
|
-
/**
|
|
96
|
-
* Automatically migrate if needed
|
|
97
|
-
*
|
|
98
|
-
* Safe to call repeatedly - only migrates once.
|
|
99
|
-
* Checks if migration is needed and runs it if necessary.
|
|
21
|
+
* Automatically migrate if needed — safe to call repeatedly.
|
|
100
22
|
*
|
|
101
23
|
* @param devstepsDir Path to .devsteps directory
|
|
102
24
|
* @param options Migration options
|
|
103
25
|
* @returns True if migration was performed, false if not needed
|
|
104
26
|
* @throws Error if migration fails
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* ```typescript
|
|
108
|
-
* // Auto-migrate with user feedback
|
|
109
|
-
* const migrated = await ensureIndexMigrated('/path/to/.devsteps');
|
|
110
|
-
* if (migrated) {
|
|
111
|
-
* console.log('✨ Migration complete!');
|
|
112
|
-
* }
|
|
113
|
-
*
|
|
114
|
-
* // Silent auto-migration (for background tasks)
|
|
115
|
-
* await ensureIndexMigrated('/path/to/.devsteps', { silent: true });
|
|
116
|
-
*
|
|
117
|
-
* // Dry-run (check only)
|
|
118
|
-
* const needed = await ensureIndexMigrated('/path/to/.devsteps', { dryRun: true });
|
|
119
|
-
* ```
|
|
120
27
|
*/
|
|
121
28
|
export declare function ensureIndexMigrated(devstepsDir: string, options?: AutoMigrationOptions): Promise<boolean>;
|
|
122
29
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* Returns true if using flat structure (epics/, stories/)
|
|
126
|
-
* instead of nested structure (items/epics/, items/stories/)
|
|
127
|
-
*/
|
|
128
|
-
export declare function needsItemsDirectoryMigration(devstepsDir: string): boolean;
|
|
129
|
-
/**
|
|
130
|
-
* Migrate from flat directory structure to items/ subdirectory
|
|
131
|
-
*
|
|
132
|
-
* Moves files from:
|
|
133
|
-
* .devsteps/epics/EPIC-001.json → .devsteps/items/epics/EPIC-001.json
|
|
134
|
-
* .devsteps/stories/... → .devsteps/items/stories/...
|
|
135
|
-
*
|
|
136
|
-
* @param devstepsDir Path to .devsteps directory
|
|
137
|
-
* @param options Migration options
|
|
138
|
-
* @returns Migration statistics
|
|
139
|
-
*/
|
|
140
|
-
export declare function migrateItemsDirectory(devstepsDir: string, options?: AutoMigrationOptions): {
|
|
141
|
-
moved: number;
|
|
142
|
-
types: Record<string, number>;
|
|
143
|
-
};
|
|
144
|
-
/**
|
|
145
|
-
* Ensure index is migrated AND items are in correct directory structure
|
|
30
|
+
* Ensure index is migrated AND items are in correct directory structure.
|
|
146
31
|
*
|
|
147
|
-
* Combines
|
|
32
|
+
* Combines:
|
|
148
33
|
* 1. Legacy index.json → refs-style index/ (if needed)
|
|
149
34
|
* 2. Flat structure → items/ subdirectory (if needed)
|
|
150
|
-
* 3. Cleanup
|
|
35
|
+
* 3. Cleanup orphaned legacy index.json if refs-style is valid
|
|
151
36
|
*
|
|
152
|
-
* Safe to call on every operation
|
|
37
|
+
* Safe to call on every operation — only migrates when needed.
|
|
153
38
|
*/
|
|
154
39
|
export declare function ensureFullMigration(devstepsDir: string, options?: AutoMigrationOptions): Promise<void>;
|
|
155
40
|
//# sourceMappingURL=auto-migrate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-migrate.d.ts","sourceRoot":"","sources":["../../src/core/auto-migrate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auto-migrate.d.ts","sourceRoot":"","sources":["../../src/core/auto-migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,4BAA4B,EAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAGjF,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,cAAc,EAAE,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,CAAC;AAEzF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,OAAO,CAAC,CAuClB;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAwBf"}
|