@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
package/README.md
CHANGED
|
@@ -46,10 +46,15 @@ const items = await listItems('/path/to/.devsteps');
|
|
|
46
46
|
- `getItem()` - Retrieve work item by ID
|
|
47
47
|
- `updateItem()` - Update existing work item
|
|
48
48
|
- `deleteItem()` - Delete work item
|
|
49
|
-
- `listItems()` - List all work items with filters
|
|
49
|
+
- `listItems()` - List all work items with filters (supports `archived: true` for archive scan)
|
|
50
50
|
- `searchItems()` - Full-text search across items
|
|
51
|
-
- `linkItems()` - Create
|
|
52
|
-
- `
|
|
51
|
+
- `linkItems()` - Create bidirectional relationship between items
|
|
52
|
+
- `unlinkItem()` - Remove a bidirectional relationship (idempotent — no-op if not present)
|
|
53
|
+
- `archiveItem()` - Archive a single completed item
|
|
54
|
+
- `purgeItems()` - Bulk archive items matching status/type filters
|
|
55
|
+
- `bulkUpdateItems()` - Update status/assignee/category/priority on multiple items
|
|
56
|
+
- `bulkAddTags()` - Add tags to multiple items at once
|
|
57
|
+
- `bulkRemoveTags()` - Remove tags from multiple items at once
|
|
53
58
|
|
|
54
59
|
### Types
|
|
55
60
|
- `ItemType` - Epic, Story, Task, Bug, etc.
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
2
5
|
* Centralized constants for type-safe comparisons.
|
|
3
6
|
* Use these instead of string literals to get autocomplete + compile-time safety.
|
|
4
7
|
*
|
|
@@ -72,6 +75,29 @@ export declare const HIERARCHY_TYPE: {
|
|
|
72
75
|
*/
|
|
73
76
|
export type ItemTypeValue = (typeof ITEM_TYPE)[keyof typeof ITEM_TYPE];
|
|
74
77
|
export type StatusValue = (typeof STATUS)[keyof typeof STATUS];
|
|
78
|
+
/**
|
|
79
|
+
* Context Budget Protocol — Loop iteration bounds
|
|
80
|
+
*
|
|
81
|
+
* Hard limits enforced at handler level (not just schema).
|
|
82
|
+
* These values define the maximum number of iterations per loop type.
|
|
83
|
+
* Changing these requires updating all Tier-2 agent files that reference them.
|
|
84
|
+
*
|
|
85
|
+
* @see EPIC-028 N-Tier Agent Hierarchy
|
|
86
|
+
*/
|
|
87
|
+
export declare const CBP_LOOP: {
|
|
88
|
+
/** Max Review-Fix iterations before escalation (Tier-2 quality gate) */
|
|
89
|
+
readonly MAX_REVIEW_FIX_ITERATIONS: 3;
|
|
90
|
+
/** Max TDD loop iterations (Tier-3 test-driven impl) */
|
|
91
|
+
readonly MAX_TDD_ITERATIONS: 3;
|
|
92
|
+
/** Max clarification rounds in Tier-2 research analyst */
|
|
93
|
+
readonly MAX_CLARIFICATION_ROUNDS: 2;
|
|
94
|
+
/** Max conflict-resolution rounds within a Tier-2 REDUCE phase */
|
|
95
|
+
readonly MAX_CONFLICT_RESOLUTION_ROUNDS: 2;
|
|
96
|
+
/** Max Tier-2 parallel T3 dispatches per turn */
|
|
97
|
+
readonly MAX_PARALLEL_T3_DISPATCHES: 10;
|
|
98
|
+
/** Max tokens for MandateResult findings field (~800 tokens) */
|
|
99
|
+
readonly MAX_MANDATE_FINDINGS_CHARS: 6000;
|
|
100
|
+
};
|
|
75
101
|
export type RelationshipTypeValue = (typeof RELATIONSHIP_TYPE)[keyof typeof RELATIONSHIP_TYPE];
|
|
76
102
|
export type MethodologyValue = (typeof METHODOLOGY)[keyof typeof METHODOLOGY];
|
|
77
103
|
export type HierarchyTypeValue = (typeof HIERARCHY_TYPE)[keyof typeof HIERARCHY_TYPE];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,eAAO,MAAM,SAAS;;;;;;;;;CASZ,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,MAAM;;;;;;;;;CAST,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;CAYpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AACvE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;AAE/D;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ;IACnB,wEAAwE;;IAExE,wDAAwD;;IAExD,0DAA0D;;IAE1D,kEAAkE;;IAElE,iDAAiD;;IAEjD,gEAAgE;;CAExD,CAAC;AACX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAC/F,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAC9E,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,OAAO,cAAc,CAAC,CAAC"}
|
package/dist/constants/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
2
5
|
* Centralized constants for type-safe comparisons.
|
|
3
6
|
* Use these instead of string literals to get autocomplete + compile-time safety.
|
|
4
7
|
*
|
|
@@ -67,4 +70,27 @@ export const HIERARCHY_TYPE = {
|
|
|
67
70
|
WATERFALL: 'waterfall',
|
|
68
71
|
BOTH: 'both',
|
|
69
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* Context Budget Protocol — Loop iteration bounds
|
|
75
|
+
*
|
|
76
|
+
* Hard limits enforced at handler level (not just schema).
|
|
77
|
+
* These values define the maximum number of iterations per loop type.
|
|
78
|
+
* Changing these requires updating all Tier-2 agent files that reference them.
|
|
79
|
+
*
|
|
80
|
+
* @see EPIC-028 N-Tier Agent Hierarchy
|
|
81
|
+
*/
|
|
82
|
+
export const CBP_LOOP = {
|
|
83
|
+
/** Max Review-Fix iterations before escalation (Tier-2 quality gate) */
|
|
84
|
+
MAX_REVIEW_FIX_ITERATIONS: 3,
|
|
85
|
+
/** Max TDD loop iterations (Tier-3 test-driven impl) */
|
|
86
|
+
MAX_TDD_ITERATIONS: 3,
|
|
87
|
+
/** Max clarification rounds in Tier-2 research analyst */
|
|
88
|
+
MAX_CLARIFICATION_ROUNDS: 2,
|
|
89
|
+
/** Max conflict-resolution rounds within a Tier-2 REDUCE phase */
|
|
90
|
+
MAX_CONFLICT_RESOLUTION_ROUNDS: 2,
|
|
91
|
+
/** Max Tier-2 parallel T3 dispatches per turn */
|
|
92
|
+
MAX_PARALLEL_T3_DISPATCHES: 10,
|
|
93
|
+
/** Max tokens for MandateResult findings field (~800 tokens) */
|
|
94
|
+
MAX_MANDATE_FINDINGS_CHARS: 6000,
|
|
95
|
+
};
|
|
70
96
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,OAAO,EAAE,SAAS;IAClB,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,aAAa;IAC1B,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;CACZ,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,UAAU,EAAE,YAAY;IACxB,cAAc,EAAE,gBAAgB;IAChC,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IACxB,aAAa,EAAE,eAAe;CACtB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;CACR,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,IAAI,EAAE,MAAM;CACJ,CAAC;AAQX;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,wEAAwE;IACxE,yBAAyB,EAAE,CAAC;IAC5B,wDAAwD;IACxD,kBAAkB,EAAE,CAAC;IACrB,0DAA0D;IAC1D,wBAAwB,EAAE,CAAC;IAC3B,kEAAkE;IAClE,8BAA8B,EAAE,CAAC;IACjC,iDAAiD;IACjD,0BAA0B,EAAE,EAAE;IAC9B,gEAAgE;IAChE,0BAA0B,EAAE,IAAI;CACxB,CAAC"}
|
package/dist/core/add.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Core add-item operation
|
|
6
|
+
* Creates metadata JSON, description Markdown, and updates distributed index.
|
|
7
|
+
*/
|
|
1
8
|
import type { DevStepsConfig, EisenhowerQuadrant, ItemMetadata, ItemType } from '../schemas/index.js';
|
|
2
9
|
export interface AddItemArgs {
|
|
3
10
|
type: ItemType;
|
|
@@ -18,5 +25,5 @@ export interface AddItemResult {
|
|
|
18
25
|
* Core business logic for adding a new item to devsteps
|
|
19
26
|
* Pure function that handles all file I/O and validation
|
|
20
27
|
*/
|
|
21
|
-
export declare function addItem(
|
|
28
|
+
export declare function addItem(devstepsDir: string, args: AddItemArgs): Promise<AddItemResult>;
|
|
22
29
|
//# sourceMappingURL=add.d.ts.map
|
package/dist/core/add.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/core/add.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/core/add.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAU7B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CA2E5F"}
|
package/dist/core/add.js
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Core add-item operation
|
|
6
|
+
* Creates metadata JSON, description Markdown, and updates distributed index.
|
|
7
|
+
*/
|
|
1
8
|
import { existsSync, writeFileSync } from 'node:fs';
|
|
2
9
|
import { join } from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
import { loadCounters, updateCounters, addItemToIndex, } from './index-refs.js';
|
|
10
|
+
import { generateItemId, getCurrentTimestamp, getTypePrefix, TYPE_TO_DIRECTORY, } from '../utils/index.js';
|
|
5
11
|
import { getConfig } from './config.js';
|
|
12
|
+
import { addItemToIndex, loadCounters, updateCounters } from './index-refs.js';
|
|
6
13
|
/**
|
|
7
14
|
* Core business logic for adding a new item to devsteps
|
|
8
15
|
* Pure function that handles all file I/O and validation
|
|
9
16
|
*/
|
|
10
|
-
export async function addItem(
|
|
17
|
+
export async function addItem(devstepsDir, args) {
|
|
11
18
|
// Check if initialized
|
|
12
|
-
if (!existsSync(
|
|
19
|
+
if (!existsSync(devstepsDir)) {
|
|
13
20
|
throw new Error('Project not initialized. Run devsteps-init first.');
|
|
14
21
|
}
|
|
15
22
|
// Read config and index
|
|
16
|
-
const config = await getConfig(
|
|
23
|
+
const config = await getConfig(devstepsDir);
|
|
17
24
|
// Get counter (auto-migration ensures refs-style index is always available)
|
|
18
25
|
const counterKey = getTypePrefix(args.type); // Use uppercase prefix for consistency
|
|
19
|
-
const counters = loadCounters(
|
|
26
|
+
const counters = loadCounters(devstepsDir);
|
|
20
27
|
const counter = (counters[counterKey] || 0) + 1;
|
|
21
28
|
// Generate ID using global counter
|
|
22
29
|
const typeFolder = TYPE_TO_DIRECTORY[args.type];
|
|
@@ -53,7 +60,7 @@ export async function addItem(devstepsir, args) {
|
|
|
53
60
|
metadata: {},
|
|
54
61
|
};
|
|
55
62
|
// Save metadata
|
|
56
|
-
const itemDir = join(
|
|
63
|
+
const itemDir = join(devstepsDir, typeFolder);
|
|
57
64
|
const metadataPath = join(itemDir, `${itemId}.json`);
|
|
58
65
|
const descriptionPath = join(itemDir, `${itemId}.md`);
|
|
59
66
|
writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
|
|
@@ -61,11 +68,11 @@ export async function addItem(devstepsir, args) {
|
|
|
61
68
|
const description = args.description || `# ${args.title}\n\n<!-- Add detailed description here -->\n`;
|
|
62
69
|
writeFileSync(descriptionPath, description);
|
|
63
70
|
// Update index (auto-migration ensures refs-style always available)
|
|
64
|
-
const currentCounters = loadCounters(
|
|
71
|
+
const currentCounters = loadCounters(devstepsDir);
|
|
65
72
|
currentCounters[counterKey] = counter;
|
|
66
|
-
updateCounters(
|
|
73
|
+
updateCounters(devstepsDir, currentCounters);
|
|
67
74
|
// Add to all relevant indexes (by-type, by-status, by-priority)
|
|
68
|
-
addItemToIndex(
|
|
75
|
+
addItemToIndex(devstepsDir, metadata);
|
|
69
76
|
return {
|
|
70
77
|
itemId,
|
|
71
78
|
metadata,
|
package/dist/core/add.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/core/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/core/add.ts"],"names":[],"mappings":"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"}
|
package/dist/core/archive.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Core archive and purge operations
|
|
6
|
+
* Moves items to .devsteps/archive/ and updates the distributed index.
|
|
7
|
+
*/
|
|
1
8
|
import type { ItemStatus } from '../schemas/index.js';
|
|
2
9
|
export interface ArchiveItemResult {
|
|
3
10
|
itemId: string;
|
|
@@ -7,7 +14,7 @@ export interface ArchiveItemResult {
|
|
|
7
14
|
/**
|
|
8
15
|
* Core business logic for archiving a single item
|
|
9
16
|
*/
|
|
10
|
-
export declare function archiveItem(
|
|
17
|
+
export declare function archiveItem(devstepsDir: string, itemId: string): Promise<ArchiveItemResult>;
|
|
11
18
|
export interface PurgeItemsArgs {
|
|
12
19
|
status?: ItemStatus[];
|
|
13
20
|
type?: string;
|
|
@@ -20,5 +27,5 @@ export interface PurgeItemsResult {
|
|
|
20
27
|
/**
|
|
21
28
|
* Core business logic for bulk archiving items
|
|
22
29
|
*/
|
|
23
|
-
export declare function purgeItems(
|
|
30
|
+
export declare function purgeItems(devstepsDir: string, args?: PurgeItemsArgs): Promise<PurgeItemsResult>;
|
|
24
31
|
//# sourceMappingURL=archive.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,qBAAqB,CAAC;AAKhE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,UAAU,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+CjG;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CA8C3B"}
|
package/dist/core/archive.js
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Core archive and purge operations
|
|
6
|
+
* Moves items to .devsteps/archive/ and updates the distributed index.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, mkdirSync, renameSync } from 'node:fs';
|
|
2
9
|
import { join } from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
import { removeItemFromIndex } from './index-refs.js';
|
|
10
|
+
import { getCurrentTimestamp, parseItemId, TYPE_TO_DIRECTORY } from '../utils/index.js';
|
|
5
11
|
import { getItem } from './get.js';
|
|
12
|
+
import { removeItemFromIndex } from './index-refs.js';
|
|
13
|
+
import { listItems } from './list.js';
|
|
6
14
|
/**
|
|
7
15
|
* Core business logic for archiving a single item
|
|
8
16
|
*/
|
|
9
|
-
export async function archiveItem(
|
|
10
|
-
if (!existsSync(
|
|
17
|
+
export async function archiveItem(devstepsDir, itemId) {
|
|
18
|
+
if (!existsSync(devstepsDir)) {
|
|
11
19
|
throw new Error('Project not initialized. Run devsteps-init first.');
|
|
12
20
|
}
|
|
13
21
|
const parsed = parseItemId(itemId);
|
|
@@ -15,16 +23,16 @@ export async function archiveItem(devstepsir, itemId) {
|
|
|
15
23
|
throw new Error(`Invalid item ID: ${itemId}`);
|
|
16
24
|
}
|
|
17
25
|
const typeFolder = TYPE_TO_DIRECTORY[parsed.type];
|
|
18
|
-
const metadataPath = join(
|
|
19
|
-
const descriptionPath = join(
|
|
26
|
+
const metadataPath = join(devstepsDir, typeFolder, `${itemId}.json`);
|
|
27
|
+
const descriptionPath = join(devstepsDir, typeFolder, `${itemId}.md`);
|
|
20
28
|
if (!existsSync(metadataPath)) {
|
|
21
29
|
throw new Error(`Item not found: ${itemId}`);
|
|
22
30
|
}
|
|
23
31
|
// Read metadata
|
|
24
|
-
const { metadata } = await getItem(
|
|
32
|
+
const { metadata } = await getItem(devstepsDir, itemId);
|
|
25
33
|
const originalStatus = metadata.status;
|
|
26
34
|
// Create archive directory if not exists
|
|
27
|
-
const archiveDir = join(
|
|
35
|
+
const archiveDir = join(devstepsDir, 'archive', typeFolder);
|
|
28
36
|
mkdirSync(archiveDir, { recursive: true });
|
|
29
37
|
// Move files to archive
|
|
30
38
|
const archiveMetadataPath = join(archiveDir, `${itemId}.json`);
|
|
@@ -35,7 +43,7 @@ export async function archiveItem(devstepsir, itemId) {
|
|
|
35
43
|
}
|
|
36
44
|
// Update index (auto-migration ensures refs-style always available)
|
|
37
45
|
// Remove from all indexes (by-type, by-status, by-priority)
|
|
38
|
-
removeItemFromIndex(
|
|
46
|
+
removeItemFromIndex(devstepsDir, itemId, metadata.type, metadata.status, metadata.eisenhower);
|
|
39
47
|
// Note: refs-style doesn't track archived_items in index
|
|
40
48
|
// Archive metadata already contains all needed info
|
|
41
49
|
return {
|
|
@@ -47,34 +55,36 @@ export async function archiveItem(devstepsir, itemId) {
|
|
|
47
55
|
/**
|
|
48
56
|
* Core business logic for bulk archiving items
|
|
49
57
|
*/
|
|
50
|
-
export async function purgeItems(
|
|
51
|
-
if (!existsSync(
|
|
58
|
+
export async function purgeItems(devstepsDir, args = {}) {
|
|
59
|
+
if (!existsSync(devstepsDir)) {
|
|
52
60
|
throw new Error('Project not initialized. Run devsteps-init first.');
|
|
53
61
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
itemsToArchive = itemsToArchive.filter((i) => i.type === args.type);
|
|
64
|
-
}
|
|
65
|
-
// Filter by date
|
|
66
|
-
if (args.olderThan) {
|
|
67
|
-
const cutoffDate = args.olderThan;
|
|
68
|
-
itemsToArchive = itemsToArchive.filter((i) => {
|
|
69
|
-
const updated = new Date(i.updated);
|
|
70
|
-
return updated < cutoffDate;
|
|
62
|
+
// Collect candidate items using the refs-style index (via listItems).
|
|
63
|
+
// listItems() handles both legacy index.json and the current directory-based index.
|
|
64
|
+
const statusFilter = args.status ?? ['done', 'cancelled'];
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
const candidates = [];
|
|
67
|
+
for (const status of statusFilter) {
|
|
68
|
+
const result = await listItems(devstepsDir, {
|
|
69
|
+
status,
|
|
70
|
+
type: args.type ? args.type : undefined,
|
|
71
71
|
});
|
|
72
|
+
for (const item of result.items) {
|
|
73
|
+
if (!seen.has(item.id)) {
|
|
74
|
+
seen.add(item.id);
|
|
75
|
+
candidates.push({ id: item.id, updated: item.updated });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
72
78
|
}
|
|
79
|
+
// Apply optional date filter
|
|
80
|
+
const itemsToArchive = args.olderThan != null
|
|
81
|
+
? candidates.filter((i) => new Date(i.updated) < args.olderThan)
|
|
82
|
+
: candidates;
|
|
73
83
|
// Archive each item
|
|
74
84
|
const archivedIds = [];
|
|
75
85
|
for (const item of itemsToArchive) {
|
|
76
86
|
try {
|
|
77
|
-
await archiveItem(
|
|
87
|
+
await archiveItem(devstepsDir, item.id);
|
|
78
88
|
archivedIds.push(item.id);
|
|
79
89
|
}
|
|
80
90
|
catch (error) {
|
package/dist/core/archive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Auto-Migration Detection
|
|
6
|
+
*
|
|
7
|
+
* Pure analysis/detection functions — no side effects, no I/O mutations.
|
|
8
|
+
* These functions only read state and return status information.
|
|
9
|
+
*
|
|
10
|
+
* @see STORY-073 External Project Migration Auto-Detection
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Migration check result
|
|
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 index migration is needed (legacy → refs-style)
|
|
51
|
+
*/
|
|
52
|
+
export declare function checkMigrationNeeded(devstepsDir: string): MigrationCheckResult;
|
|
53
|
+
/**
|
|
54
|
+
* Get user-friendly migration status message
|
|
55
|
+
*/
|
|
56
|
+
export declare function getMigrationStatusMessage(devstepsDir: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Check if items/ directory migration is needed (flat → nested structure)
|
|
59
|
+
*/
|
|
60
|
+
export declare function needsItemsDirectoryMigration(devstepsDir: string): boolean;
|
|
61
|
+
//# sourceMappingURL=auto-migrate-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-migrate-detect.d.ts","sourceRoot":"","sources":["../../src/core/auto-migrate-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kCAAkC;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,kCAAkC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,oBAAoB,CA6B9E;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAQrE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAOzE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025 Thomas Hertel (the@devsteps.dev)
|
|
3
|
+
* Licensed under the Apache License, Version 2.0
|
|
4
|
+
*
|
|
5
|
+
* Auto-Migration Detection
|
|
6
|
+
*
|
|
7
|
+
* Pure analysis/detection functions — no side effects, no I/O mutations.
|
|
8
|
+
* These functions only read state and return status information.
|
|
9
|
+
*
|
|
10
|
+
* @see STORY-073 External Project Migration Auto-Detection
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { hasLegacyIndex, hasRefsStyleIndex, loadLegacyIndex } from './index-refs.js';
|
|
15
|
+
/**
|
|
16
|
+
* Check if index migration is needed (legacy → refs-style)
|
|
17
|
+
*/
|
|
18
|
+
export function checkMigrationNeeded(devstepsDir) {
|
|
19
|
+
if (!existsSync(devstepsDir)) {
|
|
20
|
+
return { needed: false, hasLegacy: false, hasRefs: false, message: 'Not a DevSteps project (no .devsteps directory)' };
|
|
21
|
+
}
|
|
22
|
+
const hasLegacy = hasLegacyIndex(devstepsDir);
|
|
23
|
+
const hasRefs = hasRefsStyleIndex(devstepsDir);
|
|
24
|
+
if (!hasLegacy && hasRefs) {
|
|
25
|
+
return { needed: false, hasLegacy: false, hasRefs: true, message: 'Project already using refs-style index ✓' };
|
|
26
|
+
}
|
|
27
|
+
if (hasLegacy && hasRefs) {
|
|
28
|
+
return { needed: false, hasLegacy: true, hasRefs: true, message: 'Both index formats exist - manual intervention required' };
|
|
29
|
+
}
|
|
30
|
+
if (!hasLegacy && !hasRefs) {
|
|
31
|
+
return { needed: false, hasLegacy: false, hasRefs: false, message: 'No index found - new project or not initialized' };
|
|
32
|
+
}
|
|
33
|
+
let itemCount;
|
|
34
|
+
try {
|
|
35
|
+
const legacy = loadLegacyIndex(devstepsDir);
|
|
36
|
+
itemCount = legacy.items.length;
|
|
37
|
+
}
|
|
38
|
+
catch (_error) {
|
|
39
|
+
// Ignore - legacy index might be corrupted
|
|
40
|
+
}
|
|
41
|
+
return { needed: true, hasLegacy: true, hasRefs: false, itemCount, message: `Migration needed: ${itemCount ?? 'unknown'} items to migrate` };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get user-friendly migration status message
|
|
45
|
+
*/
|
|
46
|
+
export function getMigrationStatusMessage(devstepsDir) {
|
|
47
|
+
const result = checkMigrationNeeded(devstepsDir);
|
|
48
|
+
if (!existsSync(devstepsDir))
|
|
49
|
+
return '❌ Not a DevSteps project';
|
|
50
|
+
if (result.needed)
|
|
51
|
+
return `🔄 Migration available: ${result.itemCount ?? 'unknown'} items can be migrated to refs-style index`;
|
|
52
|
+
if (result.hasRefs)
|
|
53
|
+
return '✅ Project using refs-style index';
|
|
54
|
+
if (result.hasLegacy && result.hasRefs)
|
|
55
|
+
return '⚠️ Both index formats detected - manual cleanup needed';
|
|
56
|
+
return '📦 DevSteps project (no index yet)';
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if items/ directory migration is needed (flat → nested structure)
|
|
60
|
+
*/
|
|
61
|
+
export function needsItemsDirectoryMigration(devstepsDir) {
|
|
62
|
+
const hasOldStructure = existsSync(join(devstepsDir, 'epics')) ||
|
|
63
|
+
existsSync(join(devstepsDir, 'stories')) ||
|
|
64
|
+
existsSync(join(devstepsDir, 'tasks'));
|
|
65
|
+
const hasNewStructure = existsSync(join(devstepsDir, 'items'));
|
|
66
|
+
return hasOldStructure && !hasNewStructure;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=auto-migrate-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-migrate-detect.js","sourceRoot":"","sources":["../../src/core/auto-migrate-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AA0CrF;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC;IACzH,CAAC;IAED,MAAM,SAAS,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC;QAC1B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,0CAA0C,EAAE,CAAC;IACjH,CAAC;IAED,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;QACzB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,yDAAyD,EAAE,CAAC;IAC/H,CAAC;IAED,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC;IACzH,CAAC;IAED,IAAI,SAA6B,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAC5C,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;IAClC,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,2CAA2C;IAC7C,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,qBAAqB,SAAS,IAAI,SAAS,mBAAmB,EAAE,CAAC;AAC/I,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,WAAmB;IAC3D,MAAM,MAAM,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAEjD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,0BAA0B,CAAC;IAChE,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,2BAA2B,MAAM,CAAC,SAAS,IAAI,SAAS,4CAA4C,CAAC;IAC/H,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,kCAAkC,CAAC;IAC9D,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,yDAAyD,CAAC;IACzG,OAAO,oCAAoC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAAC,WAAmB;IAC9D,MAAM,eAAe,GACnB,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACxC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IACzC,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/D,OAAO,eAAe,IAAI,CAAC,eAAe,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
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 type { AutoMigrationOptions, MigrationStats } from './auto-migrate-detect.js';
|
|
13
|
+
/**
|
|
14
|
+
* Perform core index migration: legacy index.json → refs-style distributed index
|
|
15
|
+
*
|
|
16
|
+
* @param devstepsDir Path to .devsteps directory
|
|
17
|
+
* @param options Migration options
|
|
18
|
+
* @returns Migration statistics
|
|
19
|
+
* @throws Error if migration fails or preconditions not met
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export declare function performMigration(devstepsDir: string, options?: AutoMigrationOptions): Promise<MigrationStats>;
|
|
23
|
+
/**
|
|
24
|
+
* Migrate from flat directory structure to items/ subdirectory
|
|
25
|
+
*
|
|
26
|
+
* Moves: `.devsteps/epics/…` → `.devsteps/items/epics/…`
|
|
27
|
+
*/
|
|
28
|
+
export declare function migrateItemsDirectory(devstepsDir: string, options?: AutoMigrationOptions): {
|
|
29
|
+
moved: number;
|
|
30
|
+
types: Record<string, number>;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=auto-migrate-impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-migrate-impl.d.ts","sourceRoot":"","sources":["../../src/core/auto-migrate-impl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAsBH,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAErF;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,CAAC,CA6DzB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,oBAAyB,GACjC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CA2BlD"}
|