@lwelliott/cortex-cli 1.0.3
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/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/cli/audit.d.ts +3 -0
- package/dist/cli/audit.d.ts.map +1 -0
- package/dist/cli/audit.js +78 -0
- package/dist/cli/audit.js.map +1 -0
- package/dist/cli/doc.d.ts +3 -0
- package/dist/cli/doc.d.ts.map +1 -0
- package/dist/cli/doc.js +291 -0
- package/dist/cli/doc.js.map +1 -0
- package/dist/cli/entity.d.ts +3 -0
- package/dist/cli/entity.d.ts.map +1 -0
- package/dist/cli/entity.js +135 -0
- package/dist/cli/entity.js.map +1 -0
- package/dist/cli/format-selector.d.ts +30 -0
- package/dist/cli/format-selector.d.ts.map +1 -0
- package/dist/cli/format-selector.js +101 -0
- package/dist/cli/format-selector.js.map +1 -0
- package/dist/cli/formatters/audit-formatter.d.ts +33 -0
- package/dist/cli/formatters/audit-formatter.d.ts.map +1 -0
- package/dist/cli/formatters/audit-formatter.js +204 -0
- package/dist/cli/formatters/audit-formatter.js.map +1 -0
- package/dist/cli/formatters/json.d.ts +10 -0
- package/dist/cli/formatters/json.d.ts.map +1 -0
- package/dist/cli/formatters/json.js +31 -0
- package/dist/cli/formatters/json.js.map +1 -0
- package/dist/cli/formatters/markdown.d.ts +12 -0
- package/dist/cli/formatters/markdown.d.ts.map +1 -0
- package/dist/cli/formatters/markdown.js +341 -0
- package/dist/cli/formatters/markdown.js.map +1 -0
- package/dist/cli/formatters/quiet.d.ts +15 -0
- package/dist/cli/formatters/quiet.d.ts.map +1 -0
- package/dist/cli/formatters/quiet.js +75 -0
- package/dist/cli/formatters/quiet.js.map +1 -0
- package/dist/cli/formatters/table.d.ts +11 -0
- package/dist/cli/formatters/table.d.ts.map +1 -0
- package/dist/cli/formatters/table.js +726 -0
- package/dist/cli/formatters/table.js.map +1 -0
- package/dist/cli/graph.d.ts +3 -0
- package/dist/cli/graph.d.ts.map +1 -0
- package/dist/cli/graph.js +209 -0
- package/dist/cli/graph.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +144 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/lesson.d.ts +3 -0
- package/dist/cli/lesson.d.ts.map +1 -0
- package/dist/cli/lesson.js +85 -0
- package/dist/cli/lesson.js.map +1 -0
- package/dist/cli/project-resolver.d.ts +17 -0
- package/dist/cli/project-resolver.d.ts.map +1 -0
- package/dist/cli/project-resolver.js +25 -0
- package/dist/cli/project-resolver.js.map +1 -0
- package/dist/cli/project.d.ts +12 -0
- package/dist/cli/project.d.ts.map +1 -0
- package/dist/cli/project.js +169 -0
- package/dist/cli/project.js.map +1 -0
- package/dist/cli/relation.d.ts +3 -0
- package/dist/cli/relation.d.ts.map +1 -0
- package/dist/cli/relation.js +128 -0
- package/dist/cli/relation.js.map +1 -0
- package/dist/cli/review.d.ts +3 -0
- package/dist/cli/review.d.ts.map +1 -0
- package/dist/cli/review.js +131 -0
- package/dist/cli/review.js.map +1 -0
- package/dist/cli/router.d.ts +38 -0
- package/dist/cli/router.d.ts.map +1 -0
- package/dist/cli/router.js +49 -0
- package/dist/cli/router.js.map +1 -0
- package/dist/cli/schema.d.ts +3 -0
- package/dist/cli/schema.d.ts.map +1 -0
- package/dist/cli/schema.js +94 -0
- package/dist/cli/schema.js.map +1 -0
- package/dist/cli/sprint.d.ts +12 -0
- package/dist/cli/sprint.d.ts.map +1 -0
- package/dist/cli/sprint.js +200 -0
- package/dist/cli/sprint.js.map +1 -0
- package/dist/cli/task.d.ts +12 -0
- package/dist/cli/task.d.ts.map +1 -0
- package/dist/cli/task.js +252 -0
- package/dist/cli/task.js.map +1 -0
- package/dist/cli/test-report.d.ts +3 -0
- package/dist/cli/test-report.d.ts.map +1 -0
- package/dist/cli/test-report.js +134 -0
- package/dist/cli/test-report.js.map +1 -0
- package/dist/cli/validate.d.ts +8 -0
- package/dist/cli/validate.d.ts.map +1 -0
- package/dist/cli/validate.js +86 -0
- package/dist/cli/validate.js.map +1 -0
- package/dist/config/config.d.ts +18 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +70 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/registry.d.ts +52 -0
- package/dist/config/registry.d.ts.map +1 -0
- package/dist/config/registry.js +193 -0
- package/dist/config/registry.js.map +1 -0
- package/dist/config/resolver.d.ts +26 -0
- package/dist/config/resolver.d.ts.map +1 -0
- package/dist/config/resolver.js +87 -0
- package/dist/config/resolver.js.map +1 -0
- package/dist/db/builtin-schema-constants.d.ts +109 -0
- package/dist/db/builtin-schema-constants.d.ts.map +1 -0
- package/dist/db/builtin-schema-constants.js +32 -0
- package/dist/db/builtin-schema-constants.js.map +1 -0
- package/dist/db/connection.d.ts +34 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +140 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/generated/schema-types.d.ts +134 -0
- package/dist/db/generated/schema-types.d.ts.map +1 -0
- package/dist/db/generated/schema-types.js +31 -0
- package/dist/db/generated/schema-types.js.map +1 -0
- package/dist/db/locks.d.ts +106 -0
- package/dist/db/locks.d.ts.map +1 -0
- package/dist/db/locks.js +211 -0
- package/dist/db/locks.js.map +1 -0
- package/dist/db/migration.d.ts +65 -0
- package/dist/db/migration.d.ts.map +1 -0
- package/dist/db/migration.js +233 -0
- package/dist/db/migration.js.map +1 -0
- package/dist/db/retry.d.ts +26 -0
- package/dist/db/retry.d.ts.map +1 -0
- package/dist/db/retry.js +71 -0
- package/dist/db/retry.js.map +1 -0
- package/dist/db/schema.d.ts +21 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +830 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/models/common.d.ts +27 -0
- package/dist/models/common.d.ts.map +1 -0
- package/dist/models/common.js +4 -0
- package/dist/models/common.js.map +1 -0
- package/dist/models/document.d.ts +89 -0
- package/dist/models/document.d.ts.map +1 -0
- package/dist/models/document.js +5 -0
- package/dist/models/document.js.map +1 -0
- package/dist/models/entity-model.d.ts +30 -0
- package/dist/models/entity-model.d.ts.map +1 -0
- package/dist/models/entity-model.js +99 -0
- package/dist/models/entity-model.js.map +1 -0
- package/dist/models/entity.d.ts +88 -0
- package/dist/models/entity.d.ts.map +1 -0
- package/dist/models/entity.js +5 -0
- package/dist/models/entity.js.map +1 -0
- package/dist/models/graph-schema.d.ts +43 -0
- package/dist/models/graph-schema.d.ts.map +1 -0
- package/dist/models/graph-schema.js +76 -0
- package/dist/models/graph-schema.js.map +1 -0
- package/dist/models/project.d.ts +49 -0
- package/dist/models/project.d.ts.map +1 -0
- package/dist/models/project.js +18 -0
- package/dist/models/project.js.map +1 -0
- package/dist/models/relation.d.ts +35 -0
- package/dist/models/relation.d.ts.map +1 -0
- package/dist/models/relation.js +212 -0
- package/dist/models/relation.js.map +1 -0
- package/dist/models/review.d.ts +86 -0
- package/dist/models/review.d.ts.map +1 -0
- package/dist/models/review.js +5 -0
- package/dist/models/review.js.map +1 -0
- package/dist/models/sprint.d.ts +38 -0
- package/dist/models/sprint.d.ts.map +1 -0
- package/dist/models/sprint.js +4 -0
- package/dist/models/sprint.js.map +1 -0
- package/dist/models/task.d.ts +75 -0
- package/dist/models/task.d.ts.map +1 -0
- package/dist/models/task.js +4 -0
- package/dist/models/task.js.map +1 -0
- package/dist/models/validation.d.ts +25 -0
- package/dist/models/validation.d.ts.map +1 -0
- package/dist/models/validation.js +4 -0
- package/dist/models/validation.js.map +1 -0
- package/dist/services/audit-check-service.d.ts +16 -0
- package/dist/services/audit-check-service.d.ts.map +1 -0
- package/dist/services/audit-check-service.js +137 -0
- package/dist/services/audit-check-service.js.map +1 -0
- package/dist/services/audit-checks/dangling-relations-check.d.ts +7 -0
- package/dist/services/audit-checks/dangling-relations-check.d.ts.map +1 -0
- package/dist/services/audit-checks/dangling-relations-check.js +52 -0
- package/dist/services/audit-checks/dangling-relations-check.js.map +1 -0
- package/dist/services/audit-checks/duplicate-ids-check.d.ts +4 -0
- package/dist/services/audit-checks/duplicate-ids-check.d.ts.map +1 -0
- package/dist/services/audit-checks/duplicate-ids-check.js +49 -0
- package/dist/services/audit-checks/duplicate-ids-check.js.map +1 -0
- package/dist/services/audit-checks/fix-engine.d.ts +24 -0
- package/dist/services/audit-checks/fix-engine.d.ts.map +1 -0
- package/dist/services/audit-checks/fix-engine.js +114 -0
- package/dist/services/audit-checks/fix-engine.js.map +1 -0
- package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.d.ts +9 -0
- package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.d.ts.map +1 -0
- package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.js +56 -0
- package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.js.map +1 -0
- package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.d.ts +10 -0
- package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.d.ts.map +1 -0
- package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.js +57 -0
- package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.js.map +1 -0
- package/dist/services/audit-checks/fs-nfs-to-ts-check.d.ts +9 -0
- package/dist/services/audit-checks/fs-nfs-to-ts-check.d.ts.map +1 -0
- package/dist/services/audit-checks/fs-nfs-to-ts-check.js +56 -0
- package/dist/services/audit-checks/fs-nfs-to-ts-check.js.map +1 -0
- package/dist/services/audit-checks/inverse-consistency-check.d.ts +7 -0
- package/dist/services/audit-checks/inverse-consistency-check.d.ts.map +1 -0
- package/dist/services/audit-checks/inverse-consistency-check.js +54 -0
- package/dist/services/audit-checks/inverse-consistency-check.js.map +1 -0
- package/dist/services/audit-checks/mapping-check.d.ts +4 -0
- package/dist/services/audit-checks/mapping-check.d.ts.map +1 -0
- package/dist/services/audit-checks/mapping-check.js +74 -0
- package/dist/services/audit-checks/mapping-check.js.map +1 -0
- package/dist/services/audit-checks/orphan-documents-check.d.ts +9 -0
- package/dist/services/audit-checks/orphan-documents-check.d.ts.map +1 -0
- package/dist/services/audit-checks/orphan-documents-check.js +54 -0
- package/dist/services/audit-checks/orphan-documents-check.js.map +1 -0
- package/dist/services/audit-checks/orphan-entities-check.d.ts +4 -0
- package/dist/services/audit-checks/orphan-entities-check.d.ts.map +1 -0
- package/dist/services/audit-checks/orphan-entities-check.js +39 -0
- package/dist/services/audit-checks/orphan-entities-check.js.map +1 -0
- package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.d.ts +9 -0
- package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.d.ts.map +1 -0
- package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.js +56 -0
- package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.js.map +1 -0
- package/dist/services/audit-checks/sprint-consistency-check.d.ts +4 -0
- package/dist/services/audit-checks/sprint-consistency-check.d.ts.map +1 -0
- package/dist/services/audit-checks/sprint-consistency-check.js +80 -0
- package/dist/services/audit-checks/sprint-consistency-check.js.map +1 -0
- package/dist/services/audit-checks/src-filesystem-only-check.d.ts +10 -0
- package/dist/services/audit-checks/src-filesystem-only-check.d.ts.map +1 -0
- package/dist/services/audit-checks/src-filesystem-only-check.js +106 -0
- package/dist/services/audit-checks/src-filesystem-only-check.js.map +1 -0
- package/dist/services/audit-checks/ts-to-tc-check.d.ts +10 -0
- package/dist/services/audit-checks/ts-to-tc-check.d.ts.map +1 -0
- package/dist/services/audit-checks/ts-to-tc-check.js +58 -0
- package/dist/services/audit-checks/ts-to-tc-check.js.map +1 -0
- package/dist/services/audit-checks/type-mismatch-check.d.ts +4 -0
- package/dist/services/audit-checks/type-mismatch-check.d.ts.map +1 -0
- package/dist/services/audit-checks/type-mismatch-check.js +55 -0
- package/dist/services/audit-checks/type-mismatch-check.js.map +1 -0
- package/dist/services/audit-checks/types.d.ts +66 -0
- package/dist/services/audit-checks/types.d.ts.map +1 -0
- package/dist/services/audit-checks/types.js +30 -0
- package/dist/services/audit-checks/types.js.map +1 -0
- package/dist/services/audit-checks/us-to-fr-nfr-check.d.ts +9 -0
- package/dist/services/audit-checks/us-to-fr-nfr-check.d.ts.map +1 -0
- package/dist/services/audit-checks/us-to-fr-nfr-check.js +56 -0
- package/dist/services/audit-checks/us-to-fr-nfr-check.js.map +1 -0
- package/dist/services/doc-entity-mapping.d.ts +19 -0
- package/dist/services/doc-entity-mapping.d.ts.map +1 -0
- package/dist/services/doc-entity-mapping.js +35 -0
- package/dist/services/doc-entity-mapping.js.map +1 -0
- package/dist/services/document-service.d.ts +58 -0
- package/dist/services/document-service.d.ts.map +1 -0
- package/dist/services/document-service.js +409 -0
- package/dist/services/document-service.js.map +1 -0
- package/dist/services/graph-export-service.d.ts +12 -0
- package/dist/services/graph-export-service.d.ts.map +1 -0
- package/dist/services/graph-export-service.js +112 -0
- package/dist/services/graph-export-service.js.map +1 -0
- package/dist/services/graph-service.d.ts +21 -0
- package/dist/services/graph-service.d.ts.map +1 -0
- package/dist/services/graph-service.js +49 -0
- package/dist/services/graph-service.js.map +1 -0
- package/dist/services/graph-validation-service.d.ts +13 -0
- package/dist/services/graph-validation-service.d.ts.map +1 -0
- package/dist/services/graph-validation-service.js +171 -0
- package/dist/services/graph-validation-service.js.map +1 -0
- package/dist/services/project.d.ts +80 -0
- package/dist/services/project.d.ts.map +1 -0
- package/dist/services/project.js +256 -0
- package/dist/services/project.js.map +1 -0
- package/dist/services/review-service.d.ts +81 -0
- package/dist/services/review-service.d.ts.map +1 -0
- package/dist/services/review-service.js +242 -0
- package/dist/services/review-service.js.map +1 -0
- package/dist/services/schema-migration-service.d.ts +44 -0
- package/dist/services/schema-migration-service.d.ts.map +1 -0
- package/dist/services/schema-migration-service.js +894 -0
- package/dist/services/schema-migration-service.js.map +1 -0
- package/dist/services/sprint.d.ts +71 -0
- package/dist/services/sprint.d.ts.map +1 -0
- package/dist/services/sprint.js +238 -0
- package/dist/services/sprint.js.map +1 -0
- package/dist/services/stage-validator.d.ts +36 -0
- package/dist/services/stage-validator.d.ts.map +1 -0
- package/dist/services/stage-validator.js +78 -0
- package/dist/services/stage-validator.js.map +1 -0
- package/dist/services/task.d.ts +75 -0
- package/dist/services/task.d.ts.map +1 -0
- package/dist/services/task.js +487 -0
- package/dist/services/task.js.map +1 -0
- package/dist/services/validation.d.ts +24 -0
- package/dist/services/validation.d.ts.map +1 -0
- package/dist/services/validation.js +53 -0
- package/dist/services/validation.js.map +1 -0
- package/dist/state-machines/sprint-state.d.ts +25 -0
- package/dist/state-machines/sprint-state.d.ts.map +1 -0
- package/dist/state-machines/sprint-state.js +64 -0
- package/dist/state-machines/sprint-state.js.map +1 -0
- package/dist/state-machines/task-state.d.ts +31 -0
- package/dist/state-machines/task-state.d.ts.map +1 -0
- package/dist/state-machines/task-state.js +83 -0
- package/dist/state-machines/task-state.js.map +1 -0
- package/dist/utils/errors.d.ts +673 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +1447 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/format.d.ts +52 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +65 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/validators/board-integrity.d.ts +25 -0
- package/dist/validators/board-integrity.d.ts.map +1 -0
- package/dist/validators/board-integrity.js +102 -0
- package/dist/validators/board-integrity.js.map +1 -0
- package/dist/validators/board-shape.d.ts +13 -0
- package/dist/validators/board-shape.d.ts.map +1 -0
- package/dist/validators/board-shape.js +74 -0
- package/dist/validators/board-shape.js.map +1 -0
- package/dist/validators/owner-validator.d.ts +30 -0
- package/dist/validators/owner-validator.d.ts.map +1 -0
- package/dist/validators/owner-validator.js +70 -0
- package/dist/validators/owner-validator.js.map +1 -0
- package/dist/validators/spawn-legality.d.ts +19 -0
- package/dist/validators/spawn-legality.d.ts.map +1 -0
- package/dist/validators/spawn-legality.js +77 -0
- package/dist/validators/spawn-legality.js.map +1 -0
- package/dist/validators/state-field-checker.d.ts +8 -0
- package/dist/validators/state-field-checker.d.ts.map +1 -0
- package/dist/validators/state-field-checker.js +47 -0
- package/dist/validators/state-field-checker.js.map +1 -0
- package/dist/validators/state-field-recorder.d.ts +39 -0
- package/dist/validators/state-field-recorder.d.ts.map +1 -0
- package/dist/validators/state-field-recorder.js +62 -0
- package/dist/validators/state-field-recorder.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// CLI subcommands for test-report group
|
|
3
|
+
// SAD-0031: Explicit Command IDs, --task removal, --content-file import
|
|
4
|
+
// SAD-0010: --content-file replaces --report-path, atomic import, show command
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createTestReportGroup = createTestReportGroup;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const review_service_1 = require("../services/review-service");
|
|
10
|
+
const sprint_1 = require("../services/sprint");
|
|
11
|
+
const connection_1 = require("../db/connection");
|
|
12
|
+
const migration_1 = require("../db/migration");
|
|
13
|
+
const project_resolver_1 = require("./project-resolver");
|
|
14
|
+
const format_selector_1 = require("./format-selector");
|
|
15
|
+
const errors_1 = require("../utils/errors");
|
|
16
|
+
function run(fn, optsOrCmd) {
|
|
17
|
+
try {
|
|
18
|
+
const opts = optsOrCmd instanceof commander_1.Command ? optsOrCmd.optsWithGlobals() : optsOrCmd;
|
|
19
|
+
console.log(fn(opts));
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
const opts = optsOrCmd instanceof commander_1.Command ? optsOrCmd.optsWithGlobals() : optsOrCmd;
|
|
23
|
+
const format = (0, format_selector_1.selectFormat)({ quiet: opts.quiet, json: opts.json, format: opts.format });
|
|
24
|
+
console.error((0, format_selector_1.formatErrorOutput)(err instanceof Error ? err : new Error(String(err)), format));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function createTestReportGroup() {
|
|
29
|
+
const group = new commander_1.Command('test-report').description('Test execution reports');
|
|
30
|
+
// test-report add — uses --content-file (atomic import), positional <id> (SAD-0031/FS-SS-028-0001)
|
|
31
|
+
group.command('add')
|
|
32
|
+
.description('Add a test report')
|
|
33
|
+
.argument('<id>', 'Test report ID (4-digit zero-padded, e.g., 0001)')
|
|
34
|
+
.option('--sprint <id>', 'Sprint ID')
|
|
35
|
+
.requiredOption('--total <n>', 'Total tests')
|
|
36
|
+
.requiredOption('--passed <n>', 'Passed tests')
|
|
37
|
+
.requiredOption('--failed <n>', 'Failed tests')
|
|
38
|
+
.option('--skipped <n>', 'Skipped tests', '0')
|
|
39
|
+
.option('--command <cmd>', 'Test command')
|
|
40
|
+
.option('--duration <ms>', 'Duration in milliseconds')
|
|
41
|
+
.option('--content-file <path>', 'File to read report content from (replaces --report-path)')
|
|
42
|
+
.action((testReportId, _opts, _cmd) => {
|
|
43
|
+
run((opts) => {
|
|
44
|
+
const format = (0, format_selector_1.selectFormat)(opts);
|
|
45
|
+
const resolved = (0, project_resolver_1.resolveFromCLI)(opts);
|
|
46
|
+
const db = (0, connection_1.openConnection)(resolved.dbPath);
|
|
47
|
+
const contentFilePath = (opts.contentFile ?? opts.contentfile ?? opts.content_file);
|
|
48
|
+
try {
|
|
49
|
+
(0, migration_1.initializeSchema)(db);
|
|
50
|
+
// Reject deprecated --report-path (SAD-0031 Part A)
|
|
51
|
+
if (opts.reportPath !== undefined || opts.report_path !== undefined) {
|
|
52
|
+
throw new errors_1.TestReportReportPathRejectedError();
|
|
53
|
+
}
|
|
54
|
+
// Count consistency warning (non-blocking)
|
|
55
|
+
const total = Number(opts.total);
|
|
56
|
+
const passed = Number(opts.passed);
|
|
57
|
+
const failed = Number(opts.failed);
|
|
58
|
+
const skipped = Number(opts.skipped);
|
|
59
|
+
// Step 1: Read content file (before transaction — fail fast)
|
|
60
|
+
let content = '';
|
|
61
|
+
if (contentFilePath) {
|
|
62
|
+
try {
|
|
63
|
+
content = (0, fs_1.readFileSync)(contentFilePath, 'utf-8');
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
throw new errors_1.TestReportContentFileError(contentFilePath);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const sprintId = (0, sprint_1.resolveSprint)(db, opts.sprint).id;
|
|
70
|
+
// Steps 3-5: DB write + commit
|
|
71
|
+
const result = (0, review_service_1.addTestReport)(db, sprintId, testReportId, total, passed, failed, {
|
|
72
|
+
skipCount: skipped,
|
|
73
|
+
command: opts.command,
|
|
74
|
+
duration: opts.duration ? Number(opts.duration) : undefined,
|
|
75
|
+
content,
|
|
76
|
+
});
|
|
77
|
+
// Step 6: Delete file after successful commit
|
|
78
|
+
if (contentFilePath) {
|
|
79
|
+
try {
|
|
80
|
+
(0, fs_1.unlinkSync)(contentFilePath);
|
|
81
|
+
}
|
|
82
|
+
catch { /* best effort */ }
|
|
83
|
+
}
|
|
84
|
+
return (0, format_selector_1.formatOutput)(result, format, 'test-report');
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
db.close();
|
|
88
|
+
}
|
|
89
|
+
}, _cmd);
|
|
90
|
+
});
|
|
91
|
+
// test-report list — --task removed per SAD-0031 Part B
|
|
92
|
+
group.command('list')
|
|
93
|
+
.description('List test reports')
|
|
94
|
+
.option('--sprint <id>', 'Filter by sprint')
|
|
95
|
+
.action((_opts, _cmd) => {
|
|
96
|
+
run((opts) => {
|
|
97
|
+
const format = (0, format_selector_1.selectFormat)(opts);
|
|
98
|
+
const resolved = (0, project_resolver_1.resolveFromCLI)(opts);
|
|
99
|
+
const db = (0, connection_1.openConnection)(resolved.dbPath);
|
|
100
|
+
try {
|
|
101
|
+
(0, migration_1.initializeSchema)(db);
|
|
102
|
+
const sprintId = (0, sprint_1.resolveSprint)(db, opts.sprint).id;
|
|
103
|
+
const results = (0, review_service_1.listTestReports)(db, sprintId);
|
|
104
|
+
return (0, format_selector_1.formatOutput)(results, format, 'test-report');
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
db.close();
|
|
108
|
+
}
|
|
109
|
+
}, _cmd);
|
|
110
|
+
});
|
|
111
|
+
// test-report show — sprint-scoped (URD-026 Part A, SAD-0031)
|
|
112
|
+
group.command('show')
|
|
113
|
+
.description('Show test report detail')
|
|
114
|
+
.argument('<id>', 'Test report ID')
|
|
115
|
+
.option('--sprint <id>', 'Sprint ID')
|
|
116
|
+
.action((id, _opts, _cmd) => {
|
|
117
|
+
run((opts) => {
|
|
118
|
+
const format = (0, format_selector_1.selectFormat)(opts, true); // isShowCommand = true → default markdown
|
|
119
|
+
const resolved = (0, project_resolver_1.resolveFromCLI)(opts);
|
|
120
|
+
const db = (0, connection_1.openConnection)(resolved.dbPath);
|
|
121
|
+
try {
|
|
122
|
+
(0, migration_1.initializeSchema)(db);
|
|
123
|
+
const sprintId = (0, sprint_1.resolveSprint)(db, opts.sprint).id;
|
|
124
|
+
const result = (0, review_service_1.getTestReport)(db, id, sprintId);
|
|
125
|
+
return (0, format_selector_1.formatOutput)(result, format, 'test-report');
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
db.close();
|
|
129
|
+
}
|
|
130
|
+
}, _cmd);
|
|
131
|
+
});
|
|
132
|
+
return group;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=test-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-report.js","sourceRoot":"","sources":["../../src/cli/test-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export declare function createValidateBoardCommand(): Command;
|
|
3
|
+
export declare function createValidateSpawnCommand(): Command;
|
|
4
|
+
/**
|
|
5
|
+
* Create the validate command group with all subcommands.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createValidateGroup(): Command;
|
|
8
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,wBAAgB,0BAA0B,IAAI,OAAO,CAqBpD;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CA8BpD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// CLI subcommands for validation group
|
|
3
|
+
// MOD-006: Validation
|
|
4
|
+
// Follows same pattern as src/cli/project.ts
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createValidateBoardCommand = createValidateBoardCommand;
|
|
7
|
+
exports.createValidateSpawnCommand = createValidateSpawnCommand;
|
|
8
|
+
exports.createValidateGroup = createValidateGroup;
|
|
9
|
+
const commander_1 = require("commander");
|
|
10
|
+
const validation_1 = require("../services/validation");
|
|
11
|
+
const connection_1 = require("../db/connection");
|
|
12
|
+
const migration_1 = require("../db/migration");
|
|
13
|
+
const project_resolver_1 = require("./project-resolver");
|
|
14
|
+
const format_selector_1 = require("./format-selector");
|
|
15
|
+
function executeHandler(runner, optsOrCmd) {
|
|
16
|
+
try {
|
|
17
|
+
const options = optsOrCmd instanceof commander_1.Command ? optsOrCmd.optsWithGlobals() : optsOrCmd;
|
|
18
|
+
console.log(runner(options));
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
const options = optsOrCmd instanceof commander_1.Command ? optsOrCmd.optsWithGlobals() : optsOrCmd;
|
|
22
|
+
const format = (0, format_selector_1.selectFormat)({
|
|
23
|
+
quiet: options.quiet,
|
|
24
|
+
json: options.json,
|
|
25
|
+
format: options.format,
|
|
26
|
+
});
|
|
27
|
+
console.error((0, format_selector_1.formatErrorOutput)(err instanceof Error ? err : new Error(String(err)), format));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function createValidateBoardCommand() {
|
|
32
|
+
const cmd = new commander_1.Command('board')
|
|
33
|
+
.description('Validate board integrity for a sprint')
|
|
34
|
+
.option('--sprint <id>', 'Sprint ID (uses default if omitted)');
|
|
35
|
+
cmd.action(() => {
|
|
36
|
+
executeHandler((opts) => {
|
|
37
|
+
const format = (0, format_selector_1.selectFormat)(opts);
|
|
38
|
+
const resolved = (0, project_resolver_1.resolveFromCLI)(opts);
|
|
39
|
+
const db = (0, connection_1.openConnection)(resolved.dbPath);
|
|
40
|
+
try {
|
|
41
|
+
(0, migration_1.initializeSchema)(db);
|
|
42
|
+
const result = (0, validation_1.validateBoard)(db, opts.sprint);
|
|
43
|
+
return (0, format_selector_1.formatOutput)(result, format, 'validation');
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
db.close();
|
|
47
|
+
}
|
|
48
|
+
}, cmd);
|
|
49
|
+
});
|
|
50
|
+
return cmd;
|
|
51
|
+
}
|
|
52
|
+
function createValidateSpawnCommand() {
|
|
53
|
+
const cmd = new commander_1.Command('spawn')
|
|
54
|
+
.description('Check spawn legality')
|
|
55
|
+
.requiredOption('--sprint <id>', 'Sprint ID')
|
|
56
|
+
.requiredOption('--task <id>', 'Task ID to spawn from')
|
|
57
|
+
.requiredOption('--stage <s>', 'Spawn stage (analyst, architect, coder, tester)')
|
|
58
|
+
.requiredOption('--role <r>', 'Role that will own the spawned task');
|
|
59
|
+
cmd.action(() => {
|
|
60
|
+
executeHandler((opts) => {
|
|
61
|
+
const format = (0, format_selector_1.selectFormat)(opts);
|
|
62
|
+
const resolved = (0, project_resolver_1.resolveFromCLI)(opts);
|
|
63
|
+
const db = (0, connection_1.openConnection)(resolved.dbPath);
|
|
64
|
+
try {
|
|
65
|
+
(0, migration_1.initializeSchema)(db);
|
|
66
|
+
const result = (0, validation_1.validateSpawn)(db, opts.sprint, opts.task, opts.stage, opts.role);
|
|
67
|
+
return (0, format_selector_1.formatOutput)(result, format, 'spawn');
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
db.close();
|
|
71
|
+
}
|
|
72
|
+
}, cmd);
|
|
73
|
+
});
|
|
74
|
+
return cmd;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create the validate command group with all subcommands.
|
|
78
|
+
*/
|
|
79
|
+
function createValidateGroup() {
|
|
80
|
+
const cmd = new commander_1.Command('validate')
|
|
81
|
+
.description('Validate board integrity and spawn legality');
|
|
82
|
+
cmd.addCommand(createValidateBoardCommand());
|
|
83
|
+
cmd.addCommand(createValidateSpawnCommand());
|
|
84
|
+
return cmd;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GlobalConfig } from '../models/project';
|
|
2
|
+
/** Default path for the global config */
|
|
3
|
+
export declare const DEFAULT_CONFIG_PATH: string;
|
|
4
|
+
/**
|
|
5
|
+
* Load the global config from disk.
|
|
6
|
+
* Creates the file with empty config if it doesn't exist.
|
|
7
|
+
*/
|
|
8
|
+
export declare function loadConfig(configPath?: string): GlobalConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Save the global config to disk.
|
|
11
|
+
* Creates parent directories if they don't exist.
|
|
12
|
+
*/
|
|
13
|
+
export declare function saveConfig(config: GlobalConfig, configPath?: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Update config with partial changes.
|
|
16
|
+
*/
|
|
17
|
+
export declare function updateConfig(updates: Partial<GlobalConfig>, configPath?: string): GlobalConfig;
|
|
18
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,yCAAyC;AACzC,eAAO,MAAM,mBAAmB,QAAyB,CAAC;AAQ1D;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,CAwB5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAgB1E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,CAK9F"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Global config manager
|
|
3
|
+
// Manages ~/.config/cortex-cli/config.json
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.DEFAULT_CONFIG_PATH = void 0;
|
|
6
|
+
exports.loadConfig = loadConfig;
|
|
7
|
+
exports.saveConfig = saveConfig;
|
|
8
|
+
exports.updateConfig = updateConfig;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const project_1 = require("../models/project");
|
|
12
|
+
const errors_1 = require("../utils/errors");
|
|
13
|
+
/** Default path for the global config */
|
|
14
|
+
exports.DEFAULT_CONFIG_PATH = getDefaultConfigPath();
|
|
15
|
+
function getDefaultConfigPath() {
|
|
16
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
17
|
+
const configDir = xdgConfig || `${process.env.HOME}/.config`;
|
|
18
|
+
return `${configDir}/cortex-cli/config.json`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Load the global config from disk.
|
|
22
|
+
* Creates the file with empty config if it doesn't exist.
|
|
23
|
+
*/
|
|
24
|
+
function loadConfig(configPath) {
|
|
25
|
+
const path = configPath ?? exports.DEFAULT_CONFIG_PATH;
|
|
26
|
+
if (!(0, fs_1.existsSync)(path)) {
|
|
27
|
+
saveConfig(project_1.EMPTY_CONFIG, path);
|
|
28
|
+
return { ...project_1.EMPTY_CONFIG };
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const content = (0, fs_1.readFileSync)(path, 'utf-8');
|
|
32
|
+
const data = JSON.parse(content);
|
|
33
|
+
if (typeof data.version !== 'number') {
|
|
34
|
+
throw new errors_1.ConfigError(`Invalid config format at "${path}"`);
|
|
35
|
+
}
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (err instanceof errors_1.ConfigError)
|
|
40
|
+
throw err;
|
|
41
|
+
throw new errors_1.ConfigError(`Failed to read config at "${path}": ${err instanceof Error ? err.message : String(err)}`, { path, originalError: err });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Save the global config to disk.
|
|
46
|
+
* Creates parent directories if they don't exist.
|
|
47
|
+
*/
|
|
48
|
+
function saveConfig(config, configPath) {
|
|
49
|
+
const path = configPath ?? exports.DEFAULT_CONFIG_PATH;
|
|
50
|
+
try {
|
|
51
|
+
const dir = (0, path_1.dirname)(path);
|
|
52
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
53
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
54
|
+
}
|
|
55
|
+
(0, fs_1.writeFileSync)(path, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw new errors_1.ConfigError(`Failed to write config at "${path}": ${err instanceof Error ? err.message : String(err)}`, { path, originalError: err });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Update config with partial changes.
|
|
63
|
+
*/
|
|
64
|
+
function updateConfig(updates, configPath) {
|
|
65
|
+
const config = loadConfig(configPath);
|
|
66
|
+
Object.assign(config, updates);
|
|
67
|
+
saveConfig(config, configPath);
|
|
68
|
+
return config;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":";AAAA,wBAAwB;AACxB,2CAA2C;;;AAqB3C,gCAwBC;AAMD,gCAgBC;AAKD,oCAKC;AA3ED,2BAAwE;AACxE,+BAA+B;AAE/B,+CAAiD;AACjD,4CAA8C;AAE9C,yCAAyC;AAC5B,QAAA,mBAAmB,GAAG,oBAAoB,EAAE,CAAC;AAE1D,SAAS,oBAAoB;IAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9C,MAAM,SAAS,GAAG,SAAS,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC;IAC7D,OAAO,GAAG,SAAS,yBAAyB,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAgB,UAAU,CAAC,UAAmB;IAC5C,MAAM,IAAI,GAAG,UAAU,IAAI,2BAAmB,CAAC;IAE/C,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,EAAE,CAAC;QACtB,UAAU,CAAC,sBAAY,EAAE,IAAI,CAAC,CAAC;QAC/B,OAAO,EAAE,GAAG,sBAAY,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAiB,CAAC;QAEjD,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,oBAAW,CAAC,6BAA6B,IAAI,GAAG,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,oBAAW;YAAE,MAAM,GAAG,CAAC;QAC1C,MAAM,IAAI,oBAAW,CACnB,6BAA6B,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EACzF,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,CAC7B,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,UAAU,CAAC,MAAoB,EAAE,UAAmB;IAClE,MAAM,IAAI,GAAG,UAAU,IAAI,2BAAmB,CAAC;IAE/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,cAAO,EAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAA,eAAU,EAAC,GAAG,CAAC,EAAE,CAAC;YACrB,IAAA,cAAS,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,IAAA,kBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,oBAAW,CACnB,8BAA8B,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC1F,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,CAC7B,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,OAA8B,EAAE,UAAmB;IAC9E,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ProjectsRegistry, ProjectEntry } from '../models/project';
|
|
2
|
+
/** Default path for the global projects registry */
|
|
3
|
+
export declare const DEFAULT_REGISTRY_PATH: string;
|
|
4
|
+
/**
|
|
5
|
+
* Load the projects registry from disk.
|
|
6
|
+
* Creates the file with empty registry if it doesn't exist.
|
|
7
|
+
* Per FS-SS-002-0010 VR-003: cleans up stale .tmp files from interrupted writes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadRegistry(registryPath?: string): ProjectsRegistry;
|
|
10
|
+
/**
|
|
11
|
+
* Save the projects registry to disk atomically.
|
|
12
|
+
* Per FS-SS-002-0010 VR-003: write to temp file, then rename.
|
|
13
|
+
* Rename is atomic on POSIX (same filesystem).
|
|
14
|
+
*/
|
|
15
|
+
export declare function saveRegistry(registry: ProjectsRegistry, registryPath?: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Add a project to the registry.
|
|
18
|
+
* @throws DuplicateProjectError (ERR-PROJ-001) if the project name already exists
|
|
19
|
+
*/
|
|
20
|
+
export declare function addProject(name: string, folder: string, registryPath?: string): ProjectsRegistry;
|
|
21
|
+
/**
|
|
22
|
+
* Remove a project from the registry.
|
|
23
|
+
* @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
|
|
24
|
+
*/
|
|
25
|
+
export declare function removeProject(name: string, registryPath?: string): ProjectsRegistry;
|
|
26
|
+
/**
|
|
27
|
+
* Get a project entry from the registry.
|
|
28
|
+
* @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
|
|
29
|
+
*/
|
|
30
|
+
export declare function getProject(name: string, registryPath?: string): ProjectEntry;
|
|
31
|
+
/**
|
|
32
|
+
* List all registered projects.
|
|
33
|
+
*/
|
|
34
|
+
export declare function listProjects(registryPath?: string): ProjectsRegistry;
|
|
35
|
+
/**
|
|
36
|
+
* Set the default project.
|
|
37
|
+
* @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
|
|
38
|
+
*/
|
|
39
|
+
export declare function setDefaultProject(name: string, registryPath?: string): ProjectsRegistry;
|
|
40
|
+
/**
|
|
41
|
+
* Get the default project name (or null if none set).
|
|
42
|
+
*/
|
|
43
|
+
export declare function getDefaultProject(registryPath?: string): string | null;
|
|
44
|
+
/**
|
|
45
|
+
* Find a project by folder path (for CWD resolution).
|
|
46
|
+
* Uses longest-prefix match to handle subdirectories.
|
|
47
|
+
*/
|
|
48
|
+
export declare function findProjectByFolder(folder: string, registryPath?: string): {
|
|
49
|
+
name: string;
|
|
50
|
+
entry: ProjectEntry;
|
|
51
|
+
} | null;
|
|
52
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/config/registry.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAWxE,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,QAA2B,CAAC;AAQ9D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CA+CpE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAyBpF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAmBhG;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAgBnF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,CAS5E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAEpE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAUvF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAAG,IAAI,CAiBvH"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Global project registry manager
|
|
3
|
+
// Implements AD-0001: JSON Registry for Global Project Registry
|
|
4
|
+
// Manages ~/.config/cortex-cli/registry.json
|
|
5
|
+
// + FS-SS-002-0010 VR-003 (atomic writes), ERR-REG-001..005
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DEFAULT_REGISTRY_PATH = void 0;
|
|
8
|
+
exports.loadRegistry = loadRegistry;
|
|
9
|
+
exports.saveRegistry = saveRegistry;
|
|
10
|
+
exports.addProject = addProject;
|
|
11
|
+
exports.removeProject = removeProject;
|
|
12
|
+
exports.getProject = getProject;
|
|
13
|
+
exports.listProjects = listProjects;
|
|
14
|
+
exports.setDefaultProject = setDefaultProject;
|
|
15
|
+
exports.getDefaultProject = getDefaultProject;
|
|
16
|
+
exports.findProjectByFolder = findProjectByFolder;
|
|
17
|
+
const fs_1 = require("fs");
|
|
18
|
+
const path_1 = require("path");
|
|
19
|
+
const errors_1 = require("../utils/errors");
|
|
20
|
+
/** Default path for the global projects registry */
|
|
21
|
+
exports.DEFAULT_REGISTRY_PATH = getDefaultRegistryPath();
|
|
22
|
+
function getDefaultRegistryPath() {
|
|
23
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
24
|
+
const configDir = xdgConfig || `${process.env.HOME}/.config`;
|
|
25
|
+
return `${configDir}/cortex-cli/registry.json`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load the projects registry from disk.
|
|
29
|
+
* Creates the file with empty registry if it doesn't exist.
|
|
30
|
+
* Per FS-SS-002-0010 VR-003: cleans up stale .tmp files from interrupted writes.
|
|
31
|
+
*/
|
|
32
|
+
function loadRegistry(registryPath) {
|
|
33
|
+
const path = registryPath ?? getDefaultRegistryPath();
|
|
34
|
+
// Clean up stale temp file from interrupted write (VR-003 safety)
|
|
35
|
+
const tmpPath = `${path}.tmp`;
|
|
36
|
+
if ((0, fs_1.existsSync)(tmpPath)) {
|
|
37
|
+
try {
|
|
38
|
+
(0, fs_1.unlinkSync)(tmpPath);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Ignore cleanup failures — the main file is authoritative
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (!(0, fs_1.existsSync)(path)) {
|
|
45
|
+
const empty = { version: 1, default: null, projects: {} };
|
|
46
|
+
saveRegistry(empty, path);
|
|
47
|
+
return empty;
|
|
48
|
+
}
|
|
49
|
+
let content;
|
|
50
|
+
try {
|
|
51
|
+
content = (0, fs_1.readFileSync)(path, 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
throw new errors_1.RegistryReadError(err instanceof Error ? err.message : String(err));
|
|
55
|
+
}
|
|
56
|
+
let data;
|
|
57
|
+
try {
|
|
58
|
+
data = JSON.parse(content);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
throw new errors_1.RegistryInvalidJsonError(err instanceof Error ? err.message : String(err));
|
|
62
|
+
}
|
|
63
|
+
// Basic validation (VR-004: tolerate formatting differences)
|
|
64
|
+
if (typeof data !== 'object' || data === null ||
|
|
65
|
+
typeof data.version !== 'number' ||
|
|
66
|
+
typeof data.projects !== 'object') {
|
|
67
|
+
throw new errors_1.RegistryInvalidStructureError('missing or invalid "version" (number) or "projects" (object) fields');
|
|
68
|
+
}
|
|
69
|
+
return data;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Save the projects registry to disk atomically.
|
|
73
|
+
* Per FS-SS-002-0010 VR-003: write to temp file, then rename.
|
|
74
|
+
* Rename is atomic on POSIX (same filesystem).
|
|
75
|
+
*/
|
|
76
|
+
function saveRegistry(registry, registryPath) {
|
|
77
|
+
const path = registryPath ?? exports.DEFAULT_REGISTRY_PATH;
|
|
78
|
+
try {
|
|
79
|
+
const dir = (0, path_1.dirname)(path);
|
|
80
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
81
|
+
try {
|
|
82
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
throw new errors_1.RegistryDirCreateError(err instanceof Error ? err.message : String(err));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Atomic write: write to .tmp then rename (VR-003)
|
|
89
|
+
const tmpPath = `${path}.tmp`;
|
|
90
|
+
(0, fs_1.writeFileSync)(tmpPath, JSON.stringify(registry, null, 2) + '\n', 'utf-8');
|
|
91
|
+
(0, fs_1.renameSync)(tmpPath, path);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
if (err instanceof errors_1.RegistryDirCreateError)
|
|
95
|
+
throw err;
|
|
96
|
+
throw new errors_1.RegistryWriteError(err instanceof Error ? err.message : String(err));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Add a project to the registry.
|
|
101
|
+
* @throws DuplicateProjectError (ERR-PROJ-001) if the project name already exists
|
|
102
|
+
*/
|
|
103
|
+
function addProject(name, folder, registryPath) {
|
|
104
|
+
const registry = loadRegistry(registryPath);
|
|
105
|
+
if (registry.projects[name]) {
|
|
106
|
+
throw new errors_1.DuplicateProjectError(name);
|
|
107
|
+
}
|
|
108
|
+
registry.projects[name] = {
|
|
109
|
+
folder,
|
|
110
|
+
added_at: new Date().toISOString(),
|
|
111
|
+
};
|
|
112
|
+
// If this is the first project, set it as default
|
|
113
|
+
if (Object.keys(registry.projects).length === 1 && !registry.default) {
|
|
114
|
+
registry.default = name;
|
|
115
|
+
}
|
|
116
|
+
saveRegistry(registry, registryPath);
|
|
117
|
+
return registry;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Remove a project from the registry.
|
|
121
|
+
* @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
|
|
122
|
+
*/
|
|
123
|
+
function removeProject(name, registryPath) {
|
|
124
|
+
const registry = loadRegistry(registryPath);
|
|
125
|
+
if (!registry.projects[name]) {
|
|
126
|
+
throw new errors_1.ProjectNotFoundError(name);
|
|
127
|
+
}
|
|
128
|
+
delete registry.projects[name];
|
|
129
|
+
// If we removed the default project, clear the default
|
|
130
|
+
if (registry.default === name) {
|
|
131
|
+
registry.default = null;
|
|
132
|
+
}
|
|
133
|
+
saveRegistry(registry, registryPath);
|
|
134
|
+
return registry;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get a project entry from the registry.
|
|
138
|
+
* @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
|
|
139
|
+
*/
|
|
140
|
+
function getProject(name, registryPath) {
|
|
141
|
+
const registry = loadRegistry(registryPath);
|
|
142
|
+
const entry = registry.projects[name];
|
|
143
|
+
if (!entry) {
|
|
144
|
+
throw new errors_1.ProjectNotFoundError(name);
|
|
145
|
+
}
|
|
146
|
+
return entry;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* List all registered projects.
|
|
150
|
+
*/
|
|
151
|
+
function listProjects(registryPath) {
|
|
152
|
+
return loadRegistry(registryPath);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Set the default project.
|
|
156
|
+
* @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
|
|
157
|
+
*/
|
|
158
|
+
function setDefaultProject(name, registryPath) {
|
|
159
|
+
const registry = loadRegistry(registryPath);
|
|
160
|
+
if (!registry.projects[name]) {
|
|
161
|
+
throw new errors_1.ProjectNotFoundError(name);
|
|
162
|
+
}
|
|
163
|
+
registry.default = name;
|
|
164
|
+
saveRegistry(registry, registryPath);
|
|
165
|
+
return registry;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get the default project name (or null if none set).
|
|
169
|
+
*/
|
|
170
|
+
function getDefaultProject(registryPath) {
|
|
171
|
+
const registry = loadRegistry(registryPath);
|
|
172
|
+
return registry.default;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Find a project by folder path (for CWD resolution).
|
|
176
|
+
* Uses longest-prefix match to handle subdirectories.
|
|
177
|
+
*/
|
|
178
|
+
function findProjectByFolder(folder, registryPath) {
|
|
179
|
+
const registry = loadRegistry(registryPath);
|
|
180
|
+
let bestMatch = null;
|
|
181
|
+
for (const [name, entry] of Object.entries(registry.projects)) {
|
|
182
|
+
// Normalize both paths for comparison
|
|
183
|
+
const normalizedFolder = folder.replace(/\/+$/, '');
|
|
184
|
+
const normalizedEntry = entry.folder.replace(/\/+$/, '');
|
|
185
|
+
if (normalizedFolder === normalizedEntry || normalizedFolder.startsWith(normalizedEntry + '/')) {
|
|
186
|
+
if (!bestMatch || normalizedEntry.length > bestMatch.matchLen) {
|
|
187
|
+
bestMatch = { name, entry, matchLen: normalizedEntry.length };
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return bestMatch ? { name: bestMatch.name, entry: bestMatch.entry } : null;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/config/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ResolvedProject } from '../models/project';
|
|
2
|
+
/** Environment variable name for project override */
|
|
3
|
+
export declare const ENV_PROJECT_VAR = "CORTEX_CLI_PROJECT";
|
|
4
|
+
/** Options for project resolution */
|
|
5
|
+
export interface ResolveOptions {
|
|
6
|
+
/** Explicit project name from --project flag */
|
|
7
|
+
flag?: string;
|
|
8
|
+
/** Override environment variable (for testing) */
|
|
9
|
+
envVar?: string;
|
|
10
|
+
/** Override current working directory (for testing) */
|
|
11
|
+
cwd?: string;
|
|
12
|
+
/** Override registry path (for testing) */
|
|
13
|
+
registryPath?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolve which project to use.
|
|
17
|
+
*
|
|
18
|
+
* Priority cascade (AD-0005):
|
|
19
|
+
* 1. --project flag (explicit)
|
|
20
|
+
* 2. CORTEX_CLI_PROJECT environment variable
|
|
21
|
+
* 3. Default project from registry
|
|
22
|
+
* 4. Current working directory matches a registered project folder
|
|
23
|
+
* 5. Error: ProjectResolutionError (ERR-PROJ-011)
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveProject(opts?: ResolveOptions): ResolvedProject;
|
|
26
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/config/resolver.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAQzD,qDAAqD;AACrD,eAAO,MAAM,eAAe,uBAAuB,CAAC;AAEpD,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,eAAe,CAoErE"}
|