@lwelliott/cortex-cli 1.0.7 → 1.0.8
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 +7 -5
- package/dist/cli/project-resolver.js +1 -1
- package/dist/cli/project-resolver.js.map +1 -1
- package/dist/config/config.d.ts +8 -2
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +25 -9
- package/dist/config/config.js.map +1 -1
- package/dist/config/paths.d.ts +13 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +76 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/registry.d.ts +10 -3
- package/dist/config/registry.d.ts.map +1 -1
- package/dist/config/registry.js +49 -13
- package/dist/config/registry.js.map +1 -1
- package/dist/config/resolver.d.ts +6 -9
- package/dist/config/resolver.d.ts.map +1 -1
- package/dist/config/resolver.js +13 -30
- package/dist/config/resolver.js.map +1 -1
- package/dist/models/project.d.ts +3 -3
- package/dist/models/project.d.ts.map +1 -1
- package/dist/services/project.js +4 -4
- package/dist/services/project.js.map +1 -1
- package/dist/utils/errors.d.ts +5 -4
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +13 -13
- package/dist/utils/errors.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/entity.d.ts +0 -3
- package/dist/cli/entity.d.ts.map +0 -1
- package/dist/cli/entity.js +0 -135
- package/dist/cli/entity.js.map +0 -1
- package/dist/cli/schema.d.ts +0 -3
- package/dist/cli/schema.d.ts.map +0 -1
- package/dist/cli/schema.js +0 -94
- package/dist/cli/schema.js.map +0 -1
- package/dist/db/builtin-schema-constants.d.ts +0 -109
- package/dist/db/builtin-schema-constants.d.ts.map +0 -1
- package/dist/db/builtin-schema-constants.js +0 -32
- package/dist/db/builtin-schema-constants.js.map +0 -1
- package/dist/models/entity-model.d.ts +0 -30
- package/dist/models/entity-model.d.ts.map +0 -1
- package/dist/models/entity-model.js +0 -99
- package/dist/models/entity-model.js.map +0 -1
- package/dist/services/audit-checks/mapping-check.d.ts +0 -4
- package/dist/services/audit-checks/mapping-check.d.ts.map +0 -1
- package/dist/services/audit-checks/mapping-check.js +0 -74
- package/dist/services/audit-checks/mapping-check.js.map +0 -1
- package/dist/services/audit-checks/orphan-entities-check.d.ts +0 -4
- package/dist/services/audit-checks/orphan-entities-check.d.ts.map +0 -1
- package/dist/services/audit-checks/orphan-entities-check.js +0 -39
- package/dist/services/audit-checks/orphan-entities-check.js.map +0 -1
- package/dist/services/audit-checks/sprint-consistency-check.d.ts +0 -4
- package/dist/services/audit-checks/sprint-consistency-check.d.ts.map +0 -1
- package/dist/services/audit-checks/sprint-consistency-check.js +0 -80
- package/dist/services/audit-checks/sprint-consistency-check.js.map +0 -1
- package/dist/services/audit-checks/type-mismatch-check.d.ts +0 -4
- package/dist/services/audit-checks/type-mismatch-check.d.ts.map +0 -1
- package/dist/services/audit-checks/type-mismatch-check.js +0 -55
- package/dist/services/audit-checks/type-mismatch-check.js.map +0 -1
- package/dist/services/doc-entity-mapping.d.ts +0 -19
- package/dist/services/doc-entity-mapping.d.ts.map +0 -1
- package/dist/services/doc-entity-mapping.js +0 -35
- package/dist/services/doc-entity-mapping.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ A TypeScript CLI for managing software project artifacts — sprints, kanban boa
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@lwelliott/cortex-cli) [](https://github.com/lwelliot/cortex-cli/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
+
> **Latest release:** v1.0.8 — [Release notes](releases/release-notes-1.0.8.md)
|
|
8
|
+
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
9
11
|
### From npm (recommended)
|
|
@@ -52,11 +54,11 @@ cortex-cli --project my-project sprint set-status sprint-001 --status CLOSED
|
|
|
52
54
|
|
|
53
55
|
## Project Resolution
|
|
54
56
|
|
|
55
|
-
Every command requires an explicit project.
|
|
57
|
+
Every command requires an explicit project. Resolution follows this priority order:
|
|
56
58
|
|
|
57
|
-
1. `--project <name>` flag
|
|
58
|
-
2.
|
|
59
|
-
3.
|
|
59
|
+
1. `--project <name>` flag — highest priority; if specified but the name is not found in the registry, the command fails immediately (short-circuit — no fall-through to CWD match)
|
|
60
|
+
2. Current working directory match — if the CWD is within a registered project directory, that project is used
|
|
61
|
+
3. If neither method resolves a project, the command fails with an error instructing the user to use `--project <name>` or run from a registered project directory
|
|
60
62
|
|
|
61
63
|
There is no longer a default project concept.
|
|
62
64
|
|
|
@@ -197,7 +199,7 @@ Dropped Dropped In Review In Progress In Review
|
|
|
197
199
|
|
|
198
200
|
| Option | Description |
|
|
199
201
|
|--------|-------------|
|
|
200
|
-
| `-p, --project <name>` | Target a specific project (required unless
|
|
202
|
+
| `-p, --project <name>` | Target a specific project (required unless CWD is in a registered project directory) |
|
|
201
203
|
| `--sprint <id>` | Scope to a sprint |
|
|
202
204
|
| `--format <type>` | Output format: table, json, markdown, quiet |
|
|
203
205
|
| `--json` | Shorthand for `--format json` |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Project resolver adapter for CLI context
|
|
3
|
-
// Wraps MOD-002 ProjectResolver for CLI context (flag ->
|
|
3
|
+
// Wraps MOD-002 ProjectResolver for CLI context (flag -> CWD)
|
|
4
4
|
// Implements AD-0012: Single Entry Point with Declarative Routing
|
|
5
5
|
// Module: MOD-007
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-resolver.js","sourceRoot":"","sources":["../../src/cli/project-resolver.ts"],"names":[],"mappings":";AAAA,2CAA2C;AAC3C,
|
|
1
|
+
{"version":3,"file":"project-resolver.js","sourceRoot":"","sources":["../../src/cli/project-resolver.ts"],"names":[],"mappings":";AAAA,2CAA2C;AAC3C,8DAA8D;AAC9D,kEAAkE;AAClE,kBAAkB;;AAgBlB,wCAIC;AAKD,8BAEC;AAzBD,iDAAoD;AAUpD;;;GAGG;AACH,SAAgB,cAAc,CAAC,IAAa;IAC1C,OAAO,IAAA,yBAAc,EAAC;QACpB,IAAI,EAAE,IAAI,CAAC,OAA6B;KACzC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,OAAwB;IAChD,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC"}
|
package/dist/config/config.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { GlobalConfig } from '../models/project';
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the effective config path at call time.
|
|
4
|
+
* Checks primary dir first, then legacy fallback, then defaults to primary.
|
|
5
|
+
* Replaced the former module-level DEFAULT_CONFIG_PATH const to avoid
|
|
6
|
+
* capturing a stale path when the primary directory is created after import.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getDefaultConfigPath(): string;
|
|
4
9
|
/**
|
|
5
10
|
* Load the global config from disk.
|
|
6
11
|
* Creates the file with empty config if it doesn't exist.
|
|
@@ -9,6 +14,7 @@ export declare function loadConfig(configPath?: string): GlobalConfig;
|
|
|
9
14
|
/**
|
|
10
15
|
* Save the global config to disk.
|
|
11
16
|
* Creates parent directories if they don't exist.
|
|
17
|
+
* Writes to the primary path regardless of where the config was loaded from.
|
|
12
18
|
*/
|
|
13
19
|
export declare function saveConfig(config: GlobalConfig, configPath?: string): void;
|
|
14
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKtD;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAY7C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,CAwB5D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAiB1E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,CAK9F"}
|
package/dist/config/config.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Global config manager
|
|
3
|
-
// Manages
|
|
3
|
+
// Manages <base>/.cortex-cli/config.json
|
|
4
|
+
// Primary path: <base>/.cortex-cli/ (POSIX: $HOME, Windows: %APPDATA%)
|
|
5
|
+
// Legacy fallback (read-only): <base>/.config/cortex-cli/
|
|
4
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.
|
|
7
|
+
exports.getDefaultConfigPath = getDefaultConfigPath;
|
|
6
8
|
exports.loadConfig = loadConfig;
|
|
7
9
|
exports.saveConfig = saveConfig;
|
|
8
10
|
exports.updateConfig = updateConfig;
|
|
@@ -10,19 +12,31 @@ const fs_1 = require("fs");
|
|
|
10
12
|
const path_1 = require("path");
|
|
11
13
|
const project_1 = require("../models/project");
|
|
12
14
|
const errors_1 = require("../utils/errors");
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
const paths_1 = require("./paths");
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the effective config path at call time.
|
|
18
|
+
* Checks primary dir first, then legacy fallback, then defaults to primary.
|
|
19
|
+
* Replaced the former module-level DEFAULT_CONFIG_PATH const to avoid
|
|
20
|
+
* capturing a stale path when the primary directory is created after import.
|
|
21
|
+
*/
|
|
15
22
|
function getDefaultConfigPath() {
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
23
|
+
const primaryDir = (0, paths_1.getPrimaryConfigDir)();
|
|
24
|
+
const legacyDir = (0, paths_1.getLegacyConfigDir)();
|
|
25
|
+
if ((0, fs_1.existsSync)(primaryDir)) {
|
|
26
|
+
return (0, path_1.join)(primaryDir, 'config.json');
|
|
27
|
+
}
|
|
28
|
+
if ((0, fs_1.existsSync)(legacyDir)) {
|
|
29
|
+
return (0, path_1.join)(legacyDir, 'config.json');
|
|
30
|
+
}
|
|
31
|
+
// Neither exists — use primary (will be created on first write)
|
|
32
|
+
return (0, path_1.join)(primaryDir, 'config.json');
|
|
19
33
|
}
|
|
20
34
|
/**
|
|
21
35
|
* Load the global config from disk.
|
|
22
36
|
* Creates the file with empty config if it doesn't exist.
|
|
23
37
|
*/
|
|
24
38
|
function loadConfig(configPath) {
|
|
25
|
-
const path = configPath ??
|
|
39
|
+
const path = configPath ?? getDefaultConfigPath();
|
|
26
40
|
if (!(0, fs_1.existsSync)(path)) {
|
|
27
41
|
saveConfig(project_1.EMPTY_CONFIG, path);
|
|
28
42
|
return { ...project_1.EMPTY_CONFIG };
|
|
@@ -44,13 +58,15 @@ function loadConfig(configPath) {
|
|
|
44
58
|
/**
|
|
45
59
|
* Save the global config to disk.
|
|
46
60
|
* Creates parent directories if they don't exist.
|
|
61
|
+
* Writes to the primary path regardless of where the config was loaded from.
|
|
47
62
|
*/
|
|
48
63
|
function saveConfig(config, configPath) {
|
|
49
|
-
const path = configPath ??
|
|
64
|
+
const path = configPath ?? (0, path_1.join)((0, paths_1.getPrimaryConfigDir)(), 'config.json');
|
|
50
65
|
try {
|
|
51
66
|
const dir = (0, path_1.dirname)(path);
|
|
52
67
|
if (!(0, fs_1.existsSync)(dir)) {
|
|
53
68
|
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
69
|
+
(0, paths_1.ensureConfigDirWritable)(dir);
|
|
54
70
|
}
|
|
55
71
|
(0, fs_1.writeFileSync)(path, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
56
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":";AAAA,wBAAwB;AACxB,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Get the platform-appropriate base directory for config files */
|
|
2
|
+
export declare function getConfigBaseDir(): string;
|
|
3
|
+
/** Primary config directory: <base>/.cortex-cli/ */
|
|
4
|
+
export declare function getPrimaryConfigDir(): string;
|
|
5
|
+
/** Legacy config directory (read-only fallback): <base>/.config/cortex-cli/ */
|
|
6
|
+
export declare function getLegacyConfigDir(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Verify that the resolved config directory is writable.
|
|
9
|
+
* Returns the directory path if it is accessible or can be created,
|
|
10
|
+
* throws ConfigBaseDirError if the directory exists but is not writable.
|
|
11
|
+
*/
|
|
12
|
+
export declare function ensureConfigDirWritable(dir: string): string;
|
|
13
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/config/paths.ts"],"names":[],"mappings":"AAWA,mEAAmE;AACnE,wBAAgB,gBAAgB,IAAI,MAAM,CA0BzC;AAED,oDAAoD;AACpD,wBAAgB,mBAAmB,IAAI,MAAM,CAM5C;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,IAAI,MAAM,CAM3C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkB3D"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Platform-aware config directory resolution
|
|
3
|
+
// Resolves config base directory: POSIX uses $HOME, Windows uses %APPDATA%
|
|
4
|
+
// Primary path: <base>/.cortex-cli/
|
|
5
|
+
// Legacy fallback (read-only): <base>/.config/cortex-cli/
|
|
6
|
+
// Implements AD-0005 config directory resolution
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.getConfigBaseDir = getConfigBaseDir;
|
|
9
|
+
exports.getPrimaryConfigDir = getPrimaryConfigDir;
|
|
10
|
+
exports.getLegacyConfigDir = getLegacyConfigDir;
|
|
11
|
+
exports.ensureConfigDirWritable = ensureConfigDirWritable;
|
|
12
|
+
const os_1 = require("os");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const fs_1 = require("fs");
|
|
15
|
+
const errors_1 = require("../utils/errors");
|
|
16
|
+
/** Get the platform-appropriate base directory for config files */
|
|
17
|
+
function getConfigBaseDir() {
|
|
18
|
+
// Support XDG_CONFIG_HOME override (POSIX standard, also used by tests)
|
|
19
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
20
|
+
if (xdgConfig) {
|
|
21
|
+
return xdgConfig;
|
|
22
|
+
}
|
|
23
|
+
if ((0, os_1.platform)() === 'win32') {
|
|
24
|
+
const appData = process.env.APPDATA;
|
|
25
|
+
if (!appData) {
|
|
26
|
+
throw new errors_1.ConfigBaseDirError('APPDATA environment variable is not set — cannot resolve config directory', 'APPDATA');
|
|
27
|
+
}
|
|
28
|
+
return appData;
|
|
29
|
+
}
|
|
30
|
+
// POSIX: use $HOME
|
|
31
|
+
const home = process.env.HOME;
|
|
32
|
+
if (!home) {
|
|
33
|
+
throw new errors_1.ConfigBaseDirError('HOME environment variable is not set — cannot resolve config directory', 'HOME');
|
|
34
|
+
}
|
|
35
|
+
return home;
|
|
36
|
+
}
|
|
37
|
+
/** Primary config directory: <base>/.cortex-cli/ */
|
|
38
|
+
function getPrimaryConfigDir() {
|
|
39
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
40
|
+
if (xdgConfig) {
|
|
41
|
+
return (0, path_1.join)(xdgConfig, 'cortex-cli');
|
|
42
|
+
}
|
|
43
|
+
return (0, path_1.join)(getConfigBaseDir(), '.cortex-cli');
|
|
44
|
+
}
|
|
45
|
+
/** Legacy config directory (read-only fallback): <base>/.config/cortex-cli/ */
|
|
46
|
+
function getLegacyConfigDir() {
|
|
47
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
48
|
+
if (xdgConfig) {
|
|
49
|
+
return (0, path_1.join)(xdgConfig, 'cortex-cli');
|
|
50
|
+
}
|
|
51
|
+
return (0, path_1.join)(getConfigBaseDir(), '.config', 'cortex-cli');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Verify that the resolved config directory is writable.
|
|
55
|
+
* Returns the directory path if it is accessible or can be created,
|
|
56
|
+
* throws ConfigBaseDirError if the directory exists but is not writable.
|
|
57
|
+
*/
|
|
58
|
+
function ensureConfigDirWritable(dir) {
|
|
59
|
+
try {
|
|
60
|
+
(0, fs_1.accessSync)(dir, fs_1.constants.W_OK);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const code = err.code;
|
|
64
|
+
// ENOENT: directory doesn't exist yet — fine, creation happens downstream
|
|
65
|
+
if (code === 'ENOENT') {
|
|
66
|
+
return dir;
|
|
67
|
+
}
|
|
68
|
+
// EACCES / EPERM: directory exists but we don't have write permission
|
|
69
|
+
if (code === 'EACCES' || code === 'EPERM') {
|
|
70
|
+
throw new errors_1.ConfigBaseDirError(`Config directory "${dir}" exists but is not writable`);
|
|
71
|
+
}
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
return dir;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/config/paths.ts"],"names":[],"mappings":";AAAA,6CAA6C;AAC7C,2EAA2E;AAC3E,oCAAoC;AACpC,0DAA0D;AAC1D,iDAAiD;;AAQjD,4CA0BC;AAGD,kDAMC;AAGD,gDAMC;AAOD,0DAkBC;AA3ED,2BAA8B;AAC9B,+BAA4B;AAC5B,2BAA2C;AAC3C,4CAAqD;AAErD,mEAAmE;AACnE,SAAgB,gBAAgB;IAC9B,wEAAwE;IACxE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAA,aAAQ,GAAE,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QACpC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,2BAAkB,CAC1B,2EAA2E,EAC3E,SAAS,CACV,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,mBAAmB;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,2BAAkB,CAC1B,wEAAwE,EACxE,MAAM,CACP,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oDAAoD;AACpD,SAAgB,mBAAmB;IACjC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,IAAA,WAAI,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,IAAA,WAAI,EAAC,gBAAgB,EAAE,EAAE,aAAa,CAAC,CAAC;AACjD,CAAC;AAED,+EAA+E;AAC/E,SAAgB,kBAAkB;IAChC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,IAAA,WAAI,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,IAAA,WAAI,EAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,GAAW;IACjD,IAAI,CAAC;QACH,IAAA,eAAU,EAAC,GAAG,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,0EAA0E;QAC1E,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,sEAAsE;QACtE,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1C,MAAM,IAAI,2BAAkB,CAC1B,qBAAqB,GAAG,8BAA8B,CACvD,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { ProjectsRegistry, ProjectEntry } from '../models/project';
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the effective registry path at call time.
|
|
4
|
+
* Checks primary dir first, then legacy fallback, then defaults to primary.
|
|
5
|
+
* Replaced the former module-level DEFAULT_REGISTRY_PATH const to avoid
|
|
6
|
+
* capturing a stale path when the primary directory is created after import.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getDefaultRegistryPath(): string;
|
|
4
9
|
/**
|
|
5
10
|
* Load the projects registry from disk.
|
|
6
11
|
* Creates the file with empty registry if it doesn't exist.
|
|
@@ -10,7 +15,8 @@ export declare function loadRegistry(registryPath?: string): ProjectsRegistry;
|
|
|
10
15
|
/**
|
|
11
16
|
* Save the projects registry to disk atomically.
|
|
12
17
|
* Per FS-SS-002-0010 VR-003: write to temp file, then rename.
|
|
13
|
-
* Rename is atomic on POSIX
|
|
18
|
+
* Rename is atomic on POSIX and reliable on Windows for same-volume moves.
|
|
19
|
+
* Writes always go to the primary path.
|
|
14
20
|
*/
|
|
15
21
|
export declare function saveRegistry(registry: ProjectsRegistry, registryPath?: string): void;
|
|
16
22
|
/**
|
|
@@ -35,6 +41,7 @@ export declare function listProjects(registryPath?: string): ProjectsRegistry;
|
|
|
35
41
|
/**
|
|
36
42
|
* Find a project by folder path (for CWD resolution).
|
|
37
43
|
* Uses longest-prefix match to handle subdirectories.
|
|
44
|
+
* Per FS-SS-002-0007 VR-003: paths are normalized to OS-native format before comparison.
|
|
38
45
|
*/
|
|
39
46
|
export declare function findProjectByFolder(folder: string, registryPath?: string): {
|
|
40
47
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/config/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/config/registry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAYxE;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAY/C;AAOD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CA+CpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CA0BpF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAchG;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAWnF;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;;;;GAIG;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,CAmCvH"}
|
package/dist/config/registry.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Global project registry manager
|
|
3
3
|
// Implements AD-0001: JSON Registry for Global Project Registry
|
|
4
|
-
//
|
|
4
|
+
// Primary path: <base>/.cortex-cli/registry.json (POSIX: $HOME, Windows: %APPDATA%)
|
|
5
|
+
// Legacy fallback (read-only): <base>/.config/cortex-cli/registry.json
|
|
5
6
|
// + FS-SS-002-0010 VR-003 (atomic writes), ERR-REG-001..005
|
|
6
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
8
|
+
exports.getDefaultRegistryPath = getDefaultRegistryPath;
|
|
8
9
|
exports.loadRegistry = loadRegistry;
|
|
9
10
|
exports.saveRegistry = saveRegistry;
|
|
10
11
|
exports.addProject = addProject;
|
|
@@ -15,12 +16,28 @@ exports.findProjectByFolder = findProjectByFolder;
|
|
|
15
16
|
const fs_1 = require("fs");
|
|
16
17
|
const path_1 = require("path");
|
|
17
18
|
const errors_1 = require("../utils/errors");
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const paths_1 = require("./paths");
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the effective registry path at call time.
|
|
22
|
+
* Checks primary dir first, then legacy fallback, then defaults to primary.
|
|
23
|
+
* Replaced the former module-level DEFAULT_REGISTRY_PATH const to avoid
|
|
24
|
+
* capturing a stale path when the primary directory is created after import.
|
|
25
|
+
*/
|
|
20
26
|
function getDefaultRegistryPath() {
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
27
|
+
const primaryDir = (0, paths_1.getPrimaryConfigDir)();
|
|
28
|
+
const legacyDir = (0, paths_1.getLegacyConfigDir)();
|
|
29
|
+
if ((0, fs_1.existsSync)(primaryDir)) {
|
|
30
|
+
return (0, path_1.join)(primaryDir, 'registry.json');
|
|
31
|
+
}
|
|
32
|
+
if ((0, fs_1.existsSync)(legacyDir)) {
|
|
33
|
+
return (0, path_1.join)(legacyDir, 'registry.json');
|
|
34
|
+
}
|
|
35
|
+
// Neither exists — use primary (will be created on first write)
|
|
36
|
+
return (0, path_1.join)(primaryDir, 'registry.json');
|
|
37
|
+
}
|
|
38
|
+
/** Primary registry path (always writes go here) */
|
|
39
|
+
function getPrimaryRegistryPath() {
|
|
40
|
+
return (0, path_1.join)((0, paths_1.getPrimaryConfigDir)(), 'registry.json');
|
|
24
41
|
}
|
|
25
42
|
/**
|
|
26
43
|
* Load the projects registry from disk.
|
|
@@ -69,15 +86,17 @@ function loadRegistry(registryPath) {
|
|
|
69
86
|
/**
|
|
70
87
|
* Save the projects registry to disk atomically.
|
|
71
88
|
* Per FS-SS-002-0010 VR-003: write to temp file, then rename.
|
|
72
|
-
* Rename is atomic on POSIX
|
|
89
|
+
* Rename is atomic on POSIX and reliable on Windows for same-volume moves.
|
|
90
|
+
* Writes always go to the primary path.
|
|
73
91
|
*/
|
|
74
92
|
function saveRegistry(registry, registryPath) {
|
|
75
|
-
const path = registryPath ??
|
|
93
|
+
const path = registryPath ?? getPrimaryRegistryPath();
|
|
76
94
|
try {
|
|
77
95
|
const dir = (0, path_1.dirname)(path);
|
|
78
96
|
if (!(0, fs_1.existsSync)(dir)) {
|
|
79
97
|
try {
|
|
80
98
|
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
99
|
+
(0, paths_1.ensureConfigDirWritable)(dir);
|
|
81
100
|
}
|
|
82
101
|
catch (err) {
|
|
83
102
|
throw new errors_1.RegistryDirCreateError(err instanceof Error ? err.message : String(err));
|
|
@@ -144,15 +163,32 @@ function listProjects(registryPath) {
|
|
|
144
163
|
/**
|
|
145
164
|
* Find a project by folder path (for CWD resolution).
|
|
146
165
|
* Uses longest-prefix match to handle subdirectories.
|
|
166
|
+
* Per FS-SS-002-0007 VR-003: paths are normalized to OS-native format before comparison.
|
|
147
167
|
*/
|
|
148
168
|
function findProjectByFolder(folder, registryPath) {
|
|
149
169
|
const registry = loadRegistry(registryPath);
|
|
150
170
|
let bestMatch = null;
|
|
171
|
+
// Normalize paths to OS-native separators
|
|
172
|
+
const isWindows = process.platform === 'win32';
|
|
173
|
+
const normalize = (p) => {
|
|
174
|
+
// Strip trailing slashes, normalize separators to OS-native
|
|
175
|
+
let normalized = p.replace(/[/\\]+$/, '');
|
|
176
|
+
if (isWindows) {
|
|
177
|
+
// On Windows, normalize forward slashes to backslashes
|
|
178
|
+
normalized = normalized.replace(/\//g, '\\');
|
|
179
|
+
}
|
|
180
|
+
return normalized;
|
|
181
|
+
};
|
|
182
|
+
// On Windows, normalize to lowercase for case-insensitive comparison
|
|
183
|
+
const compareFolder = isWindows ? normalize(folder).toLowerCase() : normalize(folder);
|
|
184
|
+
const sep = isWindows ? '\\' : '/';
|
|
151
185
|
for (const [name, entry] of Object.entries(registry.projects)) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
186
|
+
const normalizedEntry = isWindows
|
|
187
|
+
? normalize(entry.folder).toLowerCase()
|
|
188
|
+
: normalize(entry.folder);
|
|
189
|
+
// Exact match or the CWD starts with the entry folder followed by a separator
|
|
190
|
+
if (compareFolder === normalizedEntry ||
|
|
191
|
+
(compareFolder.startsWith(normalizedEntry + sep))) {
|
|
156
192
|
if (!bestMatch || normalizedEntry.length > bestMatch.matchLen) {
|
|
157
193
|
bestMatch = { name, entry, matchLen: normalizedEntry.length };
|
|
158
194
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/config/registry.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,gEAAgE;AAChE,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/config/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
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
2
|
/** Options for project resolution */
|
|
5
3
|
export interface ResolveOptions {
|
|
6
4
|
/** Explicit project name from --project flag */
|
|
7
5
|
flag?: string;
|
|
8
|
-
/** Override environment variable (for testing) */
|
|
9
|
-
envVar?: string;
|
|
10
6
|
/** Override current working directory (for testing) */
|
|
11
7
|
cwd?: string;
|
|
12
8
|
/** Override registry path (for testing) */
|
|
@@ -15,11 +11,12 @@ export interface ResolveOptions {
|
|
|
15
11
|
/**
|
|
16
12
|
* Resolve which project to use.
|
|
17
13
|
*
|
|
18
|
-
* Priority cascade (AD-0005
|
|
19
|
-
* 1. --project flag (explicit)
|
|
20
|
-
* 2.
|
|
21
|
-
* 3.
|
|
22
|
-
*
|
|
14
|
+
* Priority cascade (AD-0005):
|
|
15
|
+
* 1. --project flag (explicit) — fails immediately on unknown name (ERR-PROJ-009)
|
|
16
|
+
* 2. Current working directory matches a registered project folder
|
|
17
|
+
* 3. Error: ProjectResolutionError (ERR-PROJ-011)
|
|
18
|
+
*
|
|
19
|
+
* There is no default project and no environment variable step.
|
|
23
20
|
*/
|
|
24
21
|
export declare function resolveProject(opts?: ResolveOptions): ResolvedProject;
|
|
25
22
|
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/config/resolver.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOzD,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,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,CAoCrE"}
|
package/dist/config/resolver.js
CHANGED
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Project resolution logic
|
|
3
|
-
// Implements AD-0005: Project Resolution Cascade (
|
|
4
|
-
// Resolution order: --project flag → env var → CWD → error
|
|
3
|
+
// Implements AD-0005: Project Resolution Cascade (2-step: --project flag → CWD → error)
|
|
5
4
|
// + FS-SS-002-0007 (error codes), FS-SS-002-0008 (resolution error)
|
|
6
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.ENV_PROJECT_VAR = void 0;
|
|
8
6
|
exports.resolveProject = resolveProject;
|
|
7
|
+
const path_1 = require("path");
|
|
9
8
|
const errors_1 = require("../utils/errors");
|
|
10
9
|
const registry_1 = require("./registry");
|
|
11
|
-
/** Environment variable name for project override */
|
|
12
|
-
exports.ENV_PROJECT_VAR = 'CORTEX_CLI_PROJECT';
|
|
13
10
|
/**
|
|
14
11
|
* Resolve which project to use.
|
|
15
12
|
*
|
|
16
|
-
* Priority cascade (AD-0005
|
|
17
|
-
* 1. --project flag (explicit)
|
|
18
|
-
* 2.
|
|
19
|
-
* 3.
|
|
20
|
-
*
|
|
13
|
+
* Priority cascade (AD-0005):
|
|
14
|
+
* 1. --project flag (explicit) — fails immediately on unknown name (ERR-PROJ-009)
|
|
15
|
+
* 2. Current working directory matches a registered project folder
|
|
16
|
+
* 3. Error: ProjectResolutionError (ERR-PROJ-011)
|
|
17
|
+
*
|
|
18
|
+
* There is no default project and no environment variable step.
|
|
21
19
|
*/
|
|
22
20
|
function resolveProject(opts) {
|
|
23
21
|
const options = opts ?? {};
|
|
24
22
|
const registry = (0, registry_1.loadRegistry)(options.registryPath);
|
|
25
23
|
// Track attempted methods for error reporting (FS-SS-002-0008 VR-001)
|
|
26
24
|
const attemptedMethods = [];
|
|
27
|
-
// 1. Check --project flag
|
|
25
|
+
// 1. Check --project flag (short-circuits on miss — no CWD fallthrough)
|
|
28
26
|
if (options.flag) {
|
|
29
27
|
const entry = registry.projects[options.flag];
|
|
30
28
|
if (!entry) {
|
|
@@ -33,38 +31,23 @@ function resolveProject(opts) {
|
|
|
33
31
|
return {
|
|
34
32
|
name: options.flag,
|
|
35
33
|
folder: entry.folder,
|
|
36
|
-
dbPath:
|
|
34
|
+
dbPath: (0, path_1.join)(entry.folder, 'pmp', 'project.db'),
|
|
37
35
|
resolutionMethod: 'flag',
|
|
38
36
|
};
|
|
39
37
|
}
|
|
40
|
-
// 2. Check
|
|
41
|
-
const envProject = options.envVar ?? process.env[exports.ENV_PROJECT_VAR];
|
|
42
|
-
if (envProject) {
|
|
43
|
-
const entry = registry.projects[envProject];
|
|
44
|
-
if (!entry) {
|
|
45
|
-
throw new errors_1.ProjectEnvNotFoundError(envProject);
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
name: envProject,
|
|
49
|
-
folder: entry.folder,
|
|
50
|
-
dbPath: `${entry.folder}/pmp/project.db`,
|
|
51
|
-
resolutionMethod: 'env',
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
attemptedMethods.push('CORTEX_CLI_PROJECT not set');
|
|
55
|
-
// 3. Check CWD match
|
|
38
|
+
// 2. Check CWD match
|
|
56
39
|
const cwd = options.cwd ?? process.cwd();
|
|
57
40
|
const match = (0, registry_1.findProjectByFolder)(cwd, options.registryPath);
|
|
58
41
|
if (match) {
|
|
59
42
|
return {
|
|
60
43
|
name: match.name,
|
|
61
44
|
folder: match.entry.folder,
|
|
62
|
-
dbPath:
|
|
45
|
+
dbPath: (0, path_1.join)(match.entry.folder, 'pmp', 'project.db'),
|
|
63
46
|
resolutionMethod: 'cwd',
|
|
64
47
|
};
|
|
65
48
|
}
|
|
66
49
|
attemptedMethods.push(`CWD '${cwd}' not inside any registered project`);
|
|
67
|
-
//
|
|
50
|
+
// 3. No project found — list attempted methods (FS-SS-002-0008 VR-001)
|
|
68
51
|
throw new errors_1.ProjectResolutionError(attemptedMethods);
|
|
69
52
|
}
|
|
70
53
|
//# sourceMappingURL=resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/config/resolver.ts"],"names":[],"mappings":";AAAA,2BAA2B;AAC3B,
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/config/resolver.ts"],"names":[],"mappings":";AAAA,2BAA2B;AAC3B,wFAAwF;AACxF,oEAAoE;;AA8BpE,wCAoCC;AAhED,+BAA4B;AAE5B,4CAGyB;AACzB,yCAA+D;AAY/D;;;;;;;;;GASG;AACH,SAAgB,cAAc,CAAC,IAAqB;IAClD,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAA,uBAAY,EAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAEpD,sEAAsE;IACtE,MAAM,gBAAgB,GAAa,EAAE,CAAC;IAEtC,wEAAwE;IACxE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,iCAAwB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QACD,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,IAAA,WAAI,EAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC;YAC/C,gBAAgB,EAAE,MAAM;SACzB,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,IAAA,8BAAmB,EAAC,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7D,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;YAC1B,MAAM,EAAE,IAAA,WAAI,EAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC;YACrD,gBAAgB,EAAE,KAAK;SACxB,CAAC;IACJ,CAAC;IACD,gBAAgB,CAAC,IAAI,CAAC,QAAQ,GAAG,qCAAqC,CAAC,CAAC;IAExE,uEAAuE;IACvE,MAAM,IAAI,+BAAsB,CAAC,gBAAgB,CAAC,CAAC;AACrD,CAAC"}
|
package/dist/models/project.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Global projects registry structure (~/.
|
|
1
|
+
/** Global projects registry structure (~/.cortex-cli/registry.json) */
|
|
2
2
|
export interface ProjectsRegistry {
|
|
3
3
|
version: number;
|
|
4
4
|
projects: Record<string, ProjectEntry>;
|
|
@@ -8,7 +8,7 @@ export interface ProjectEntry {
|
|
|
8
8
|
folder: string;
|
|
9
9
|
added_at: string;
|
|
10
10
|
}
|
|
11
|
-
/** Global config structure (~/.
|
|
11
|
+
/** Global config structure (~/.cortex-cli/config.json) */
|
|
12
12
|
export interface GlobalConfig {
|
|
13
13
|
version: number;
|
|
14
14
|
/** @deprecated v2: No longer read/written by the project resolution system. Retained for config.json backward compatibility. */
|
|
@@ -38,7 +38,7 @@ export interface ResolvedProject {
|
|
|
38
38
|
name: string;
|
|
39
39
|
folder: string;
|
|
40
40
|
dbPath: string;
|
|
41
|
-
resolutionMethod: 'flag' | '
|
|
41
|
+
resolutionMethod: 'flag' | 'cwd';
|
|
42
42
|
}
|
|
43
43
|
/** Empty registry template */
|
|
44
44
|
export declare const EMPTY_REGISTRY: ProjectsRegistry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/models/project.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/models/project.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACxC;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,gIAAgI;IAChI,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,mDAAmD;AACnD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,KAAK,CAAC;CAClC;AAED,8BAA8B;AAC9B,eAAO,MAAM,cAAc,EAAE,gBAG5B,CAAC;AAEF,4BAA4B;AAC5B,eAAO,MAAM,YAAY,EAAE,YAK1B,CAAC"}
|