@nan0web/release 3.2.0 → 3.4.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.
Files changed (69) hide show
  1. package/bin/nan0release.js +33 -2
  2. package/bin/serve.js +73 -0
  3. package/package.json +45 -17
  4. package/src/Release/Document.js +1 -0
  5. package/src/Release/Scanner.js +3 -2
  6. package/src/Release.js +7 -7
  7. package/src/domain/App.js +31 -2
  8. package/src/domain/BumpCommand.js +10 -3
  9. package/src/domain/CheckCommand.js +504 -146
  10. package/src/domain/CheckCommand.story.js +92 -0
  11. package/src/domain/CloseCommand.js +13 -9
  12. package/src/domain/Dashboard/Dashboard.story.js +155 -0
  13. package/src/domain/Dashboard/DashboardModel.js +308 -0
  14. package/src/domain/Dashboard/ReleaseDiscovery.js +132 -0
  15. package/src/domain/Dashboard/ReleaseParser.js +226 -0
  16. package/src/domain/Dashboard/index.js +19 -0
  17. package/src/domain/DepsCommand.js +5 -2
  18. package/src/domain/InitCommand.js +18 -16
  19. package/src/domain/ListCommand.js +45 -0
  20. package/src/domain/PreviewCommand.js +39 -0
  21. package/src/domain/PublishCommand.js +7 -3
  22. package/src/domain/Registry/Registry.story.js +82 -0
  23. package/src/domain/Registry/RegistryModel.js +124 -0
  24. package/src/domain/ServeCommand.js +165 -0
  25. package/src/domain/ServeCommand.story.js +88 -0
  26. package/src/domain/SpecCommand.js +3 -1
  27. package/src/domain/StatusCommand.js +249 -3
  28. package/src/domain/ViewCommand.js +99 -0
  29. package/src/domain/WebCommand.js +140 -0
  30. package/src/domain/inspect/ReleaseAuditor.js +508 -0
  31. package/src/domain/inspect/ReleaseAuditor.story.js +136 -0
  32. package/src/domain/templates/release.html +34 -0
  33. package/src/domain/templates/release.html.template.js +34 -0
  34. package/src/index.js +6 -0
  35. package/src/inspectors/inspect-js.js +32 -0
  36. package/src/releases/1/0/v1.0.3/task.test.js +1 -1
  37. package/src/utils/nodejs/GitTelemetry.js +154 -0
  38. package/types/Release/Document.d.ts +4 -0
  39. package/types/Release/Scanner.d.ts +2 -2
  40. package/types/domain/App.d.ts +19 -3
  41. package/types/domain/BumpCommand.d.ts +9 -3
  42. package/types/domain/CheckCommand.d.ts +127 -15
  43. package/types/domain/CheckCommand.story.d.ts +1 -0
  44. package/types/domain/CloseCommand.d.ts +2 -1
  45. package/types/domain/Dashboard/Dashboard.story.d.ts +1 -0
  46. package/types/domain/Dashboard/DashboardModel.d.ts +273 -0
  47. package/types/domain/Dashboard/GitTelemetry.d.ts +23 -0
  48. package/types/domain/Dashboard/ReleaseDiscovery.d.ts +47 -0
  49. package/types/domain/Dashboard/ReleaseParser.d.ts +79 -0
  50. package/types/domain/Dashboard/index.d.ts +3 -0
  51. package/types/domain/DepsCommand.d.ts +4 -2
  52. package/types/domain/InitCommand.d.ts +2 -1
  53. package/types/domain/ListCommand.d.ts +18 -0
  54. package/types/domain/PreviewCommand.d.ts +6 -0
  55. package/types/domain/PublishCommand.d.ts +6 -3
  56. package/types/domain/Registry/Registry.story.d.ts +1 -0
  57. package/types/domain/Registry/RegistryModel.d.ts +61 -0
  58. package/types/domain/ServeCommand.d.ts +59 -0
  59. package/types/domain/ServeCommand.story.d.ts +1 -0
  60. package/types/domain/SpecCommand.d.ts +2 -1
  61. package/types/domain/StatusCommand.d.ts +39 -0
  62. package/types/domain/ViewCommand.d.ts +27 -0
  63. package/types/domain/WebCommand.d.ts +47 -0
  64. package/types/domain/inspect/ReleaseAuditor.d.ts +134 -0
  65. package/types/domain/inspect/ReleaseAuditor.story.d.ts +1 -0
  66. package/types/domain/templates/release.html.template.d.ts +2 -0
  67. package/types/index.d.ts +5 -0
  68. package/types/inspectors/inspect-js.d.ts +2 -0
  69. package/types/utils/nodejs/GitTelemetry.d.ts +23 -0
@@ -0,0 +1,273 @@
1
+ /**
2
+ * @typedef {import('./ReleaseParser.js').TaskItem} TaskItem
3
+ * @typedef {Object} ProjectDashboardEntry
4
+ * @property {string} path - Relative project path
5
+ * @property {string} name - Project name
6
+ * @property {string} version - Current release version
7
+ * @property {number} hours - Development hours spent
8
+ * @property {number} iterations - Test runs / refactor iterations
9
+ * @property {number} rrs - Release Readiness Score
10
+ * @property {'wip' | 'closed' | 'unknown'} status - Release state
11
+ * @property {TaskItem[]} tasks - Parsed tasks from release.md
12
+ * @property {string} branch - Git branch name
13
+ * @property {'clean' | 'dirty'} gitStatus - Git workspace status
14
+ * @property {string} userContent - Raw user.md content
15
+ * @property {string} releaseContent - Raw release.md content
16
+ * @property {string} sourceDoc - Relative path to the parsed release document
17
+ * @property {string} sourceUserDoc - Relative path to user.md
18
+ * @property {string?} deadline - Project release deadline
19
+ * @property {number?} daysRemaining - Days remaining until deadline
20
+ * @property {string?} priority - Priority (0 | 1 | 2 | 3)
21
+ * @property {number} [releasesCount] - Number of releases found
22
+ * @property {number} [totalHours] - Total hours across all releases
23
+ * @property {number} [totalIterations] - Total iterations across all releases
24
+ * @property {Array<any>} [allReleases] - List of all releases for project
25
+ *
26
+ * @typedef {Object} DashboardSummary
27
+ * @property {number} totalProjects - Total tracked projects
28
+ * @property {number} totalHours - Sum of hours across projects
29
+ * @property {number} totalIterations - Sum of iterations
30
+ * @property {number} wipCount - Active WIP releases
31
+ * @property {number} closedCount - Closed releases
32
+ * @property {number} [totalReleases] - Total releases counted
33
+ */
34
+ /**
35
+ * DashboardModel - Aggregates release telemetry, tasks and readiness across projects.
36
+ */
37
+ export class DashboardModel extends ModelAsApp {
38
+ static registryFile: {
39
+ help: string;
40
+ default: string;
41
+ type: string;
42
+ };
43
+ static summary: {
44
+ help: string;
45
+ default: {
46
+ totalProjects: number;
47
+ totalHours: number;
48
+ totalIterations: number;
49
+ wipCount: number;
50
+ closedCount: number;
51
+ };
52
+ type: string;
53
+ };
54
+ static projects: {
55
+ help: string;
56
+ default: () => never[];
57
+ type: string;
58
+ };
59
+ static UI: {
60
+ aggregating: string;
61
+ done: string;
62
+ };
63
+ static parseUserMetrics: typeof parseUserMetrics;
64
+ static normalizePriority: typeof normalizePriority;
65
+ static sortTasks: typeof sortTasks;
66
+ static versionToPath: typeof versionToPath;
67
+ /**
68
+ * @param {Partial<DashboardModel>} [data={}]
69
+ * @param {Partial<import('@nan0web/ui').ModelAsAppOptions & { gitTelemetry?: any }>} [options={}]
70
+ */
71
+ constructor(data?: Partial<DashboardModel>, options?: Partial<import("@nan0web/ui").ModelAsAppOptions & {
72
+ gitTelemetry?: any;
73
+ }>);
74
+ /** @type {string} Path to releases.txt registry file */ registryFile: string;
75
+ /** @type {DashboardSummary} Aggregated metrics summary */ summary: DashboardSummary;
76
+ /** @type {ProjectDashboardEntry[]} List of projects with metrics */ projects: ProjectDashboardEntry[];
77
+ /** @type {any} Optional git telemetry adapter */
78
+ _gitTelemetry: any;
79
+ /**
80
+ * Canonical OLMUI Generator: Yields progress, show, and returns result.
81
+ * @returns {AsyncGenerator<import('@nan0web/ui').Intent, any, any>}
82
+ */
83
+ run(): AsyncGenerator<import("@nan0web/ui").Intent, any, any>;
84
+ /**
85
+ * Programmatic aggregation helper
86
+ * @param {Function} [onProgress]
87
+ * @returns {Promise<{ summary: DashboardSummary, projects: ProjectDashboardEntry[] }>}
88
+ */
89
+ aggregate(onProgress?: Function): Promise<{
90
+ summary: DashboardSummary;
91
+ projects: ProjectDashboardEntry[];
92
+ }>;
93
+ aggregateStream(): AsyncGenerator<{
94
+ current: number;
95
+ total: number;
96
+ project: string;
97
+ }, {
98
+ summary: DashboardSummary;
99
+ projects: ({
100
+ name: any;
101
+ version: any;
102
+ path: any;
103
+ status: string;
104
+ hours: number;
105
+ iterations: number;
106
+ rrs: number;
107
+ branch: any;
108
+ gitStatus: any;
109
+ tasks: never[];
110
+ deadline: null;
111
+ daysRemaining: null;
112
+ priority: string;
113
+ releasesCount: number;
114
+ totalHours: number;
115
+ totalIterations: number;
116
+ allReleases: never[];
117
+ sourceDoc: string;
118
+ sourceUserDoc: string;
119
+ userContent: string;
120
+ releaseContent: string;
121
+ } | {
122
+ path: string;
123
+ name: string;
124
+ version: string;
125
+ hours: number;
126
+ iterations: number;
127
+ totalHours: number;
128
+ totalIterations: number;
129
+ releasesCount: number;
130
+ allReleases: {
131
+ version: any;
132
+ path: any;
133
+ hours: number;
134
+ iterations: number;
135
+ rrs: number;
136
+ status: "wip" | "closed" | "unknown";
137
+ tasks: import("./ReleaseParser.js").TaskItem[];
138
+ sourceDoc: string;
139
+ }[];
140
+ rrs: number;
141
+ status: "wip" | "closed" | "unknown";
142
+ tasks: import("./ReleaseParser.js").TaskItem[];
143
+ branch: any;
144
+ gitStatus: any;
145
+ userContent: string;
146
+ releaseContent: string;
147
+ sourceDoc: string;
148
+ sourceUserDoc: string;
149
+ deadline: any;
150
+ daysRemaining: number | null;
151
+ priority: "0" | "1" | "2" | "3";
152
+ })[];
153
+ }, unknown>;
154
+ #private;
155
+ }
156
+ export type TaskItem = import("./ReleaseParser.js").TaskItem;
157
+ export type ProjectDashboardEntry = {
158
+ /**
159
+ * - Relative project path
160
+ */
161
+ path: string;
162
+ /**
163
+ * - Project name
164
+ */
165
+ name: string;
166
+ /**
167
+ * - Current release version
168
+ */
169
+ version: string;
170
+ /**
171
+ * - Development hours spent
172
+ */
173
+ hours: number;
174
+ /**
175
+ * - Test runs / refactor iterations
176
+ */
177
+ iterations: number;
178
+ /**
179
+ * - Release Readiness Score
180
+ */
181
+ rrs: number;
182
+ /**
183
+ * - Release state
184
+ */
185
+ status: "wip" | "closed" | "unknown";
186
+ /**
187
+ * - Parsed tasks from release.md
188
+ */
189
+ tasks: TaskItem[];
190
+ /**
191
+ * - Git branch name
192
+ */
193
+ branch: string;
194
+ /**
195
+ * - Git workspace status
196
+ */
197
+ gitStatus: "clean" | "dirty";
198
+ /**
199
+ * - Raw user.md content
200
+ */
201
+ userContent: string;
202
+ /**
203
+ * - Raw release.md content
204
+ */
205
+ releaseContent: string;
206
+ /**
207
+ * - Relative path to the parsed release document
208
+ */
209
+ sourceDoc: string;
210
+ /**
211
+ * - Relative path to user.md
212
+ */
213
+ sourceUserDoc: string;
214
+ /**
215
+ * - Project release deadline
216
+ */
217
+ deadline: string | null;
218
+ /**
219
+ * - Days remaining until deadline
220
+ */
221
+ daysRemaining: number | null;
222
+ /**
223
+ * - Priority (0 | 1 | 2 | 3)
224
+ */
225
+ priority: string | null;
226
+ /**
227
+ * - Number of releases found
228
+ */
229
+ releasesCount?: number | undefined;
230
+ /**
231
+ * - Total hours across all releases
232
+ */
233
+ totalHours?: number | undefined;
234
+ /**
235
+ * - Total iterations across all releases
236
+ */
237
+ totalIterations?: number | undefined;
238
+ /**
239
+ * - List of all releases for project
240
+ */
241
+ allReleases?: any[] | undefined;
242
+ };
243
+ export type DashboardSummary = {
244
+ /**
245
+ * - Total tracked projects
246
+ */
247
+ totalProjects: number;
248
+ /**
249
+ * - Sum of hours across projects
250
+ */
251
+ totalHours: number;
252
+ /**
253
+ * - Sum of iterations
254
+ */
255
+ totalIterations: number;
256
+ /**
257
+ * - Active WIP releases
258
+ */
259
+ wipCount: number;
260
+ /**
261
+ * - Closed releases
262
+ */
263
+ closedCount: number;
264
+ /**
265
+ * - Total releases counted
266
+ */
267
+ totalReleases?: number | undefined;
268
+ };
269
+ import { ModelAsApp } from '@nan0web/ui';
270
+ import { parseUserMetrics } from './ReleaseParser.js';
271
+ import { normalizePriority } from './ReleaseParser.js';
272
+ import { sortTasks } from './ReleaseParser.js';
273
+ import { versionToPath } from './ReleaseDiscovery.js';
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Reset internal Git caches (useful for testing or cache invalidation)
3
+ */
4
+ export function resetGitCache(): void;
5
+ /**
6
+ * Retrieve git branch and workspace status (clean / dirty)
7
+ * @param {string} [projectDir]
8
+ * @returns {{ branch: string, gitStatus: 'clean' | 'dirty' }}
9
+ */
10
+ export function getGitInfo(projectDir?: string): {
11
+ branch: string;
12
+ gitStatus: "clean" | "dirty";
13
+ };
14
+ /**
15
+ * Retrieve development hours and iterations from git commit log
16
+ * @param {string} [projectDir]
17
+ * @param {string} [releasePath]
18
+ * @returns {{ hours: number, iterations: number }}
19
+ */
20
+ export function getGitCommitTelemetry(projectDir?: string, releasePath?: string): {
21
+ hours: number;
22
+ iterations: number;
23
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Parse semver string into [major, minor, patch] numbers
3
+ * @param {string} [v='']
4
+ * @returns {[number, number, number]}
5
+ */
6
+ export function parseSemver(v?: string): [number, number, number];
7
+ /**
8
+ * Compare two semver strings in descending order
9
+ * @param {string} [a='']
10
+ * @param {string} [b='']
11
+ * @returns {number}
12
+ */
13
+ export function compareSemverDesc(a?: string, b?: string): number;
14
+ /**
15
+ * Format release version to path segments e.g. "1.0.0" -> "1/0/v1.0.0"
16
+ * @param {string} [version='']
17
+ * @returns {string}
18
+ */
19
+ export function versionToPath(version?: string): string;
20
+ /**
21
+ * Check whether a document exists in the virtual database
22
+ * @param {any} db
23
+ * @param {string} path
24
+ * @returns {Promise<boolean>}
25
+ */
26
+ export function documentExists(db: any, path: string): Promise<boolean>;
27
+ /**
28
+ * Load release doc (release.md, task.md, plan.md) and extract tasks
29
+ * @param {any} db
30
+ * @param {string} releaseDir
31
+ * @returns {Promise<{ releaseContent: string, sourceDoc: string, tasks: import('./ReleaseParser.js').TaskItem[] }>}
32
+ */
33
+ export function loadReleaseDoc(db: any, releaseDir: string): Promise<{
34
+ releaseContent: string;
35
+ sourceDoc: string;
36
+ tasks: import("./ReleaseParser.js").TaskItem[];
37
+ }>;
38
+ /**
39
+ * Discover release version directories using database listDir
40
+ * @param {any} db
41
+ * @param {string} projectRoot
42
+ * @returns {Promise<Array<{ version: string, path: string }>>}
43
+ */
44
+ export function discoverReleases(db: any, projectRoot: string): Promise<Array<{
45
+ version: string;
46
+ path: string;
47
+ }>>;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @typedef {Object} TaskItem
3
+ * @property {string} content - Task title or description
4
+ * @property {string} status - todo | InProgress | Done
5
+ * @property {string} slug - Task slug / identifier
6
+ * @property {'0' | '1' | '2' | '3'} [priority] - Numeric priority
7
+ */
8
+ /**
9
+ * Parse frontmatter YAML from markdown text
10
+ * @param {*} input
11
+ * @returns {Record<string, any>}
12
+ */
13
+ export function parseFrontmatter(input: any): Record<string, any>;
14
+ /**
15
+ * Normalize priority to numeric string '0' | '1' | '2' | '3'
16
+ * @param {any} input
17
+ * @returns {'0' | '1' | '2' | '3'}
18
+ */
19
+ export function normalizePriority(input: any): "0" | "1" | "2" | "3";
20
+ /**
21
+ * Extract clean task items from release markdown
22
+ * @param {*} input
23
+ * @returns {TaskItem[]}
24
+ */
25
+ export function extractTasks(input: any): TaskItem[];
26
+ /**
27
+ * Calculate days remaining until deadline
28
+ * @param {string} [deadlineStr]
29
+ * @returns {number | null}
30
+ */
31
+ export function calculateDaysRemaining(deadlineStr?: string): number | null;
32
+ /**
33
+ * Parse user.md content for telemetry metrics (hours, iterations, RRS) across languages
34
+ * @param {*} [input]
35
+ * @returns {{ hours: number, iterations: number, rrs: number }}
36
+ */
37
+ export function parseUserMetrics(input?: any): {
38
+ hours: number;
39
+ iterations: number;
40
+ rrs: number;
41
+ };
42
+ /**
43
+ * Resolve priority from frontmatter or days remaining
44
+ * @param {Record<string, any>} fm
45
+ * @param {number | null} daysRemaining
46
+ * @returns {'0' | '1' | '2' | '3'}
47
+ */
48
+ export function resolvePriority(fm?: Record<string, any>, daysRemaining?: number | null): "0" | "1" | "2" | "3";
49
+ /**
50
+ * Sort tasks by criteria ('priority', 'status', 'alphabetical')
51
+ * @param {TaskItem[]} [tasks=[]]
52
+ * @param {'priority' | 'status' | 'alphabetical'} [criteria='priority']
53
+ * @returns {TaskItem[]}
54
+ */
55
+ export function sortTasks(tasks?: TaskItem[], criteria?: "priority" | "status" | "alphabetical"): TaskItem[];
56
+ /**
57
+ * Determine release status ('wip' | 'closed' | 'unknown')
58
+ * @param {object} params
59
+ * @returns {'wip' | 'closed' | 'unknown'}
60
+ */
61
+ export function determineReleaseStatus({ fmStatus, hasSpec, hasTest, tasks, userStr, metrics }?: object): "wip" | "closed" | "unknown";
62
+ export type TaskItem = {
63
+ /**
64
+ * - Task title or description
65
+ */
66
+ content: string;
67
+ /**
68
+ * - todo | InProgress | Done
69
+ */
70
+ status: string;
71
+ /**
72
+ * - Task slug / identifier
73
+ */
74
+ slug: string;
75
+ /**
76
+ * - Numeric priority
77
+ */
78
+ priority?: "0" | "1" | "2" | "3" | undefined;
79
+ };
@@ -0,0 +1,3 @@
1
+ export { DashboardModel } from "./DashboardModel.js";
2
+ export { parseFrontmatter, extractTasks, calculateDaysRemaining, parseUserMetrics, normalizePriority, resolvePriority, sortTasks, determineReleaseStatus } from "./ReleaseParser.js";
3
+ export { parseSemver, compareSemverDesc, versionToPath, documentExists, loadReleaseDoc, discoverReleases } from "./ReleaseDiscovery.js";
@@ -16,7 +16,9 @@ export default class DepsCommand extends ModelAsApp {
16
16
  * @param {Partial<import('@nan0web/ui').ModelAsAppOptions>} [options]
17
17
  */
18
18
  constructor(data?: Partial<DepsCommand>, options?: Partial<import("@nan0web/ui").ModelAsAppOptions>);
19
- /** @type {boolean} Apply fixes automatically */ fix: boolean;
20
- /** @type {boolean} Update packages to the latest available versions */ latest: boolean;
19
+ /** @type {boolean} Apply fixes automatically */
20
+ fix: boolean;
21
+ /** @type {boolean} Update packages to the latest available versions */
22
+ latest: boolean;
21
23
  }
22
24
  import { ModelAsApp } from '@nan0web/ui';
@@ -13,6 +13,7 @@ export default class InitCommand extends ModelAsApp {
13
13
  * @param {Partial<import('@nan0web/ui').ModelAsAppOptions>} [options]
14
14
  */
15
15
  constructor(data?: Partial<InitCommand>, options?: Partial<import("@nan0web/ui").ModelAsAppOptions>);
16
- /** @type {string} Release version */ version: string;
16
+ /** @type {string} Release version */
17
+ version: string;
17
18
  }
18
19
  import { ModelAsApp } from '@nan0web/ui';
@@ -0,0 +1,18 @@
1
+ /**
2
+ * ListCommand - ModelAsApp Subcommand to list all available releases in chronological order.
3
+ */
4
+ export default class ListCommand extends ModelAsApp {
5
+ static alias: string;
6
+ static UI: {
7
+ title: string;
8
+ help: string;
9
+ noReleases: string;
10
+ };
11
+ /**
12
+ * @param {Partial<ListCommand>} [data]
13
+ * @param {import('@nan0web/types').ModelOptions} [options]
14
+ */
15
+ constructor(data?: Partial<ListCommand>, options?: import("@nan0web/types").ModelOptions);
16
+ run(): AsyncGenerator<import("@nan0web/ui/src/core/Intent.js").ShowIntent, import("@nan0web/ui/src/core/Intent.js").ResultIntent, unknown>;
17
+ }
18
+ import { ModelAsApp } from '@nan0web/ui';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * PreviewCommand - ModelAsApp Subcommand to generate, serve and preview PM-as-Code Web Dashboard.
3
+ */
4
+ export default class PreviewCommand extends WebCommand {
5
+ }
6
+ import WebCommand from './WebCommand.js';
@@ -20,8 +20,11 @@ export default class PublishCommand extends ModelAsApp {
20
20
  * @param {Partial<import('@nan0web/ui').ModelAsAppOptions>} [options]
21
21
  */
22
22
  constructor(data?: Partial<PublishCommand>, options?: Partial<import("@nan0web/ui").ModelAsAppOptions>);
23
- /** @type {boolean} Bump major version */ major: boolean;
24
- /** @type {boolean} Bump minor version */ minor: boolean;
25
- /** @type {boolean} Bump patch version */ patch: boolean;
23
+ /** @type {boolean} Bump major version */
24
+ major: boolean;
25
+ /** @type {boolean} Bump minor version */
26
+ minor: boolean;
27
+ /** @type {boolean} Bump patch version */
28
+ patch: boolean;
26
29
  }
27
30
  import { ModelAsApp } from '@nan0web/ui';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @typedef {Object} ProjectEntry
3
+ * @property {string} path - Project relative or absolute path
4
+ * @property {string} name - Package name from package.json or folder basename
5
+ * @property {string} version - Package version from package.json
6
+ */
7
+ /**
8
+ * RegistryModel - PM-as-Code Project Registry manager.
9
+ * Reads project paths from releases.txt and discovers package metadata.
10
+ */
11
+ export class RegistryModel extends Model {
12
+ static filePath: {
13
+ help: string;
14
+ default: string;
15
+ type: string;
16
+ };
17
+ static projects: {
18
+ help: string;
19
+ default: () => never[];
20
+ type: string;
21
+ };
22
+ static UI: {
23
+ fileNotFound: string;
24
+ loadingProjects: string;
25
+ projectsLoaded: string;
26
+ };
27
+ /**
28
+ * Parse raw content of releases.txt into array of clean paths
29
+ * @param {string} content
30
+ * @returns {string[]}
31
+ */
32
+ static parsePaths(content?: string): string[];
33
+ /**
34
+ * @param {Partial<RegistryModel>} [data]
35
+ * @param {import('@nan0web/types').ModelOptions} [options]
36
+ */
37
+ constructor(data?: Partial<RegistryModel>, options?: import("@nan0web/types").ModelOptions);
38
+ /** @type {string} Path to registry file */ filePath: string;
39
+ /** @type {ProjectEntry[]} List of registered projects */ projects: ProjectEntry[];
40
+ /**
41
+ * Load project entries from registry file using injected DB instance
42
+ * @returns {Promise<ProjectEntry[]>}
43
+ */
44
+ loadProjects(): Promise<ProjectEntry[]>;
45
+ }
46
+ export default RegistryModel;
47
+ export type ProjectEntry = {
48
+ /**
49
+ * - Project relative or absolute path
50
+ */
51
+ path: string;
52
+ /**
53
+ * - Package name from package.json or folder basename
54
+ */
55
+ name: string;
56
+ /**
57
+ * - Package version from package.json
58
+ */
59
+ version: string;
60
+ };
61
+ import { Model } from '@nan0web/types';
@@ -0,0 +1,59 @@
1
+ /**
2
+ * ServeCommand - Universal ModelAsApp for data or release catalogs.
3
+ *
4
+ * Generates HTML content from README.md and release templates using $db and Markdown.
5
+ * Pure OLMUI model: does not start HTTP server, does not call node:fs or child_process.
6
+ *
7
+ * Usage:
8
+ * pnpm exec serve releases/ # Runs via CLI bootstrap
9
+ */
10
+ export default class ServeCommand extends ModelAsApp {
11
+ static alias: string;
12
+ static UI: {
13
+ title: string;
14
+ help: string;
15
+ serving: string;
16
+ dirNotFound: string;
17
+ };
18
+ static dir: {
19
+ help: string;
20
+ positional: boolean;
21
+ type: string;
22
+ default: string;
23
+ };
24
+ static port: {
25
+ help: string;
26
+ default: number;
27
+ type: string;
28
+ alias: string;
29
+ };
30
+ static open: {
31
+ help: string;
32
+ default: boolean;
33
+ type: string;
34
+ };
35
+ /**
36
+ * @param {Partial<ServeCommand>} [data]
37
+ * @param {import('@nan0web/types').ModelOptions} [options]
38
+ */
39
+ constructor(data?: Partial<ServeCommand>, options?: import("@nan0web/types").ModelOptions);
40
+ /** @type {string} */
41
+ dir: string;
42
+ /** @type {number} */
43
+ port: number;
44
+ /** @type {boolean} */
45
+ open: boolean;
46
+ /**
47
+ * Convert markdown string to HTML using @nan0web/markdown
48
+ * @param {string} mdRaw
49
+ * @returns {string}
50
+ */
51
+ renderMarkdownToHtml(mdRaw: string): string;
52
+ /**
53
+ * Render HTML content for the target directory
54
+ * @returns {Promise<string>}
55
+ */
56
+ renderHtml(): Promise<string>;
57
+ run(): AsyncGenerator<import("@nan0web/ui/src/core/Intent.js").ShowIntent, import("@nan0web/ui/src/core/Intent.js").ResultIntent, unknown>;
58
+ }
59
+ import { ModelAsApp } from '@nan0web/ui';
@@ -0,0 +1 @@
1
+ export {};
@@ -12,6 +12,7 @@ export default class SpecCommand extends ModelAsApp {
12
12
  * @param {Partial<import('@nan0web/ui').ModelAsAppOptions>} [options]
13
13
  */
14
14
  constructor(data?: Partial<SpecCommand>, options?: Partial<import("@nan0web/ui").ModelAsAppOptions>);
15
- /** @type {string} Release version filter */ version: string;
15
+ /** @type {string} Release version filter */
16
+ version: string;
16
17
  }
17
18
  import { ModelAsApp } from '@nan0web/ui';
@@ -1,7 +1,46 @@
1
+ /**
2
+ * StatusCommand - ModelAsApp Subcommand to display PM-as-Code dashboard and project inspector.
3
+ */
1
4
  export default class StatusCommand extends ModelAsApp {
5
+ static alias: string;
2
6
  static UI: {
3
7
  title: string;
4
8
  help: string;
9
+ header: string;
10
+ summaryHeader: string;
11
+ summaryRow1: string;
12
+ summaryRow2: string;
13
+ noProjects: string;
5
14
  };
15
+ static registryFile: {
16
+ help: string;
17
+ default: string;
18
+ type: string;
19
+ alias: string;
20
+ };
21
+ static target: {
22
+ help: string;
23
+ default: string;
24
+ positional: boolean;
25
+ type: string;
26
+ };
27
+ static sort: {
28
+ help: string;
29
+ default: string;
30
+ type: string;
31
+ alias: string;
32
+ };
33
+ /**
34
+ * @param {Partial<StatusCommand>} [data]
35
+ * @param {import('@nan0web/types').ModelOptions} [options]
36
+ */
37
+ constructor(data?: Partial<StatusCommand>, options?: import("@nan0web/types").ModelOptions);
38
+ /** @type {string} */ registryFile: string;
39
+ /** @type {string} */ target: string;
40
+ /** @type {string} */ sort: string;
41
+ /**
42
+ * @returns {AsyncGenerator<import('@nan0web/ui').Intent, any, any>}
43
+ */
44
+ run(): AsyncGenerator<import("@nan0web/ui").Intent, any, any>;
6
45
  }
7
46
  import { ModelAsApp } from '@nan0web/ui';