mdkg 0.0.8 → 0.1.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.
- package/CHANGELOG.md +71 -0
- package/CONTRIBUTING.md +124 -0
- package/README.md +49 -14
- package/dist/cli.js +113 -32
- package/dist/commands/checkpoint.js +19 -2
- package/dist/commands/event.js +12 -0
- package/dist/commands/init.js +4 -0
- package/dist/commands/init_manifest.js +131 -0
- package/dist/commands/new.js +57 -21
- package/dist/commands/pack.js +14 -0
- package/dist/commands/query_output.js +2 -0
- package/dist/commands/search.js +8 -0
- package/dist/commands/show.js +7 -0
- package/dist/commands/skill.js +80 -12
- package/dist/commands/task.js +42 -12
- package/dist/commands/upgrade.js +286 -0
- package/dist/commands/validate.js +31 -3
- package/dist/commands/workspace.js +105 -13
- package/dist/core/config.js +217 -22
- package/dist/core/migrate.js +39 -5
- package/dist/core/version.js +31 -0
- package/dist/core/workspace_path.js +41 -0
- package/dist/graph/agent_file_types.js +392 -0
- package/dist/graph/edges.js +13 -10
- package/dist/graph/frontmatter.js +33 -0
- package/dist/graph/indexer.js +1 -0
- package/dist/graph/node.js +43 -16
- package/dist/graph/skills_indexer.js +14 -1
- package/dist/graph/template_schema.js +13 -126
- package/dist/graph/validate_graph.js +302 -2
- package/dist/init/AGENT_START.md +14 -2
- package/dist/init/CLI_COMMAND_MATRIX.md +49 -1
- package/dist/init/README.md +14 -0
- package/dist/init/core/rule-6-templates-and-schemas.md +1 -3
- package/dist/init/init-manifest.json +197 -0
- package/dist/init/legacy/v0.0.9-init-manifest.json +197 -0
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +12 -11
- package/dist/init/templates/default/dispute.md +31 -0
- package/dist/init/templates/default/feedback.md +27 -0
- package/dist/init/templates/default/proposal.md +35 -0
- package/dist/init/templates/default/receipt.md +31 -0
- package/dist/init/templates/default/spec.md +43 -0
- package/dist/init/templates/default/work.md +44 -0
- package/dist/init/templates/default/work_order.md +32 -0
- package/dist/pack/export_json.js +3 -0
- package/dist/pack/export_md.js +9 -0
- package/dist/pack/export_xml.js +9 -0
- package/dist/pack/order.js +7 -0
- package/dist/pack/pack.js +1 -0
- package/dist/templates/loader.js +2 -2
- package/dist/util/argparse.js +2 -0
- package/dist/util/id.js +19 -0
- package/package.json +10 -2
- package/scripts/postinstall.js +89 -0
package/dist/core/config.js
CHANGED
|
@@ -3,10 +3,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateConfigSchema = validateConfigSchema;
|
|
6
7
|
exports.loadConfig = loadConfig;
|
|
7
8
|
const fs_1 = __importDefault(require("fs"));
|
|
8
9
|
const paths_1 = require("./paths");
|
|
9
10
|
const migrate_1 = require("./migrate");
|
|
11
|
+
const workspace_path_1 = require("./workspace_path");
|
|
12
|
+
const WORKSPACE_ALIAS_RE = /^[a-z][a-z0-9_]*$/;
|
|
13
|
+
const PACK_EDGE_KEYS = new Set([
|
|
14
|
+
"parent",
|
|
15
|
+
"epic",
|
|
16
|
+
"relates",
|
|
17
|
+
"blocked_by",
|
|
18
|
+
"blocks",
|
|
19
|
+
"prev",
|
|
20
|
+
"next",
|
|
21
|
+
]);
|
|
22
|
+
const NEXT_WORK_STRATEGIES = new Set(["chain_then_priority"]);
|
|
10
23
|
function isObject(value) {
|
|
11
24
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
25
|
}
|
|
@@ -17,6 +30,17 @@ function requireString(value, path, errors) {
|
|
|
17
30
|
}
|
|
18
31
|
return value;
|
|
19
32
|
}
|
|
33
|
+
function requireStringInSet(value, path, allowed, errors) {
|
|
34
|
+
const raw = requireString(value, path, errors);
|
|
35
|
+
if (raw === undefined) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
if (!allowed.has(raw)) {
|
|
39
|
+
errors.push(`${path} must be one of ${Array.from(allowed).join(", ")}`);
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
return raw;
|
|
43
|
+
}
|
|
20
44
|
function requireBoolean(value, path, errors) {
|
|
21
45
|
if (typeof value !== "boolean") {
|
|
22
46
|
errors.push(`${path} must be a boolean`);
|
|
@@ -31,6 +55,39 @@ function requireNumber(value, path, errors) {
|
|
|
31
55
|
}
|
|
32
56
|
return value;
|
|
33
57
|
}
|
|
58
|
+
function requireInteger(value, path, errors) {
|
|
59
|
+
const number = requireNumber(value, path, errors);
|
|
60
|
+
if (number === undefined) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
if (!Number.isInteger(number)) {
|
|
64
|
+
errors.push(`${path} must be an integer`);
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
return number;
|
|
68
|
+
}
|
|
69
|
+
function requireNonNegativeInteger(value, path, errors) {
|
|
70
|
+
const integer = requireInteger(value, path, errors);
|
|
71
|
+
if (integer === undefined) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
if (integer < 0) {
|
|
75
|
+
errors.push(`${path} must be a non-negative integer`);
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
return integer;
|
|
79
|
+
}
|
|
80
|
+
function requirePositiveInteger(value, path, errors) {
|
|
81
|
+
const integer = requireInteger(value, path, errors);
|
|
82
|
+
if (integer === undefined) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
if (integer <= 0) {
|
|
86
|
+
errors.push(`${path} must be a positive integer`);
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
return integer;
|
|
90
|
+
}
|
|
34
91
|
function requireStringArray(value, path, errors) {
|
|
35
92
|
if (!Array.isArray(value)) {
|
|
36
93
|
errors.push(`${path} must be an array of strings`);
|
|
@@ -46,6 +103,53 @@ function requireStringArray(value, path, errors) {
|
|
|
46
103
|
}
|
|
47
104
|
return items;
|
|
48
105
|
}
|
|
106
|
+
function requireLowercaseUniqueStringArray(value, path, errors, allowEmpty = false) {
|
|
107
|
+
const items = requireStringArray(value, path, errors);
|
|
108
|
+
if (items === undefined) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
if (items.length === 0) {
|
|
112
|
+
if (!allowEmpty) {
|
|
113
|
+
errors.push(`${path} must not be empty`);
|
|
114
|
+
}
|
|
115
|
+
return items;
|
|
116
|
+
}
|
|
117
|
+
const seen = new Set();
|
|
118
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
119
|
+
const item = items[i];
|
|
120
|
+
if (item.trim().length === 0) {
|
|
121
|
+
errors.push(`${path}[${i}] must not be empty`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (item !== item.trim()) {
|
|
125
|
+
errors.push(`${path}[${i}] must not include surrounding whitespace`);
|
|
126
|
+
}
|
|
127
|
+
if (item !== item.toLowerCase()) {
|
|
128
|
+
errors.push(`${path}[${i}] must be lowercase`);
|
|
129
|
+
}
|
|
130
|
+
if (seen.has(item)) {
|
|
131
|
+
errors.push(`${path} must not contain duplicate value "${item}"`);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
seen.add(item);
|
|
135
|
+
}
|
|
136
|
+
return items;
|
|
137
|
+
}
|
|
138
|
+
function requireKnownLowercaseUniqueStringArray(value, path, allowed, errors, allowEmpty = false) {
|
|
139
|
+
const items = requireLowercaseUniqueStringArray(value, path, errors, allowEmpty);
|
|
140
|
+
if (items === undefined) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
144
|
+
if (items[i].trim().length === 0) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (!allowed.has(items[i])) {
|
|
148
|
+
errors.push(`${path}[${i}] must be one of ${Array.from(allowed).join(", ")}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return items;
|
|
152
|
+
}
|
|
49
153
|
function requireObject(value, path, errors) {
|
|
50
154
|
if (!isObject(value)) {
|
|
51
155
|
errors.push(`${path} must be an object`);
|
|
@@ -53,6 +157,29 @@ function requireObject(value, path, errors) {
|
|
|
53
157
|
}
|
|
54
158
|
return value;
|
|
55
159
|
}
|
|
160
|
+
function validateWorkspaceAlias(alias, errors) {
|
|
161
|
+
if (alias === "all") {
|
|
162
|
+
errors.push("workspaces.all alias is reserved");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (alias !== alias.toLowerCase() || !WORKSPACE_ALIAS_RE.test(alias)) {
|
|
166
|
+
errors.push(`workspaces.${alias} alias must be lowercase and use [a-z0-9_]`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function requireContainedPath(value, path, errors) {
|
|
170
|
+
const raw = requireString(value, path, errors);
|
|
171
|
+
if (!raw) {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
return (0, workspace_path_1.normalizeContainedWorkspacePath)(raw, path);
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
179
|
+
errors.push(message);
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
56
183
|
function validateConfigSchema(raw) {
|
|
57
184
|
const errors = [];
|
|
58
185
|
if (!isObject(raw)) {
|
|
@@ -70,50 +197,70 @@ function validateConfigSchema(raw) {
|
|
|
70
197
|
? {
|
|
71
198
|
auto_reindex: requireBoolean(indexRaw.auto_reindex, "index.auto_reindex", errors),
|
|
72
199
|
tolerant: requireBoolean(indexRaw.tolerant, "index.tolerant", errors),
|
|
73
|
-
global_index_path:
|
|
200
|
+
global_index_path: requireContainedPath(indexRaw.global_index_path, "index.global_index_path", errors),
|
|
74
201
|
}
|
|
75
202
|
: undefined;
|
|
76
203
|
const packLimitsRaw = packRaw ? requireObject(packRaw.limits, "pack.limits", errors) : undefined;
|
|
77
204
|
const pack = packRaw
|
|
78
205
|
? {
|
|
79
|
-
default_depth:
|
|
80
|
-
default_edges:
|
|
81
|
-
verbose_core_list_path:
|
|
206
|
+
default_depth: requireNonNegativeInteger(packRaw.default_depth, "pack.default_depth", errors),
|
|
207
|
+
default_edges: requireKnownLowercaseUniqueStringArray(packRaw.default_edges, "pack.default_edges", PACK_EDGE_KEYS, errors, true),
|
|
208
|
+
verbose_core_list_path: requireContainedPath(packRaw.verbose_core_list_path, "pack.verbose_core_list_path", errors),
|
|
82
209
|
limits: packLimitsRaw
|
|
83
210
|
? {
|
|
84
|
-
max_nodes:
|
|
85
|
-
max_bytes:
|
|
211
|
+
max_nodes: requirePositiveInteger(packLimitsRaw.max_nodes, "pack.limits.max_nodes", errors),
|
|
212
|
+
max_bytes: requirePositiveInteger(packLimitsRaw.max_bytes, "pack.limits.max_bytes", errors),
|
|
86
213
|
}
|
|
87
214
|
: undefined,
|
|
88
215
|
}
|
|
89
216
|
: undefined;
|
|
90
217
|
const templates = templatesRaw
|
|
91
218
|
? {
|
|
92
|
-
root_path:
|
|
219
|
+
root_path: requireContainedPath(templatesRaw.root_path, "templates.root_path", errors),
|
|
93
220
|
default_set: requireString(templatesRaw.default_set, "templates.default_set", errors),
|
|
94
221
|
workspace_overrides_enabled: requireBoolean(templatesRaw.workspace_overrides_enabled, "templates.workspace_overrides_enabled", errors),
|
|
95
222
|
}
|
|
96
223
|
: undefined;
|
|
97
224
|
const workNextRaw = workRaw ? requireObject(workRaw.next, "work.next", errors) : undefined;
|
|
98
225
|
const work = workRaw
|
|
99
|
-
? {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
226
|
+
? (() => {
|
|
227
|
+
const statusEnum = requireLowercaseUniqueStringArray(workRaw.status_enum, "work.status_enum", errors);
|
|
228
|
+
const priorityMin = requireInteger(workRaw.priority_min, "work.priority_min", errors);
|
|
229
|
+
const priorityMax = requireInteger(workRaw.priority_max, "work.priority_max", errors);
|
|
230
|
+
if (priorityMin !== undefined &&
|
|
231
|
+
priorityMax !== undefined &&
|
|
232
|
+
priorityMin > priorityMax) {
|
|
233
|
+
errors.push("work.priority_min must be less than or equal to work.priority_max");
|
|
234
|
+
}
|
|
235
|
+
const statusPreference = workNextRaw
|
|
236
|
+
? requireLowercaseUniqueStringArray(workNextRaw.status_preference, "work.next.status_preference", errors)
|
|
237
|
+
: undefined;
|
|
238
|
+
if (statusEnum !== undefined && statusPreference !== undefined) {
|
|
239
|
+
const allowedStatuses = new Set(statusEnum);
|
|
240
|
+
for (let i = 0; i < statusPreference.length; i += 1) {
|
|
241
|
+
if (!allowedStatuses.has(statusPreference[i])) {
|
|
242
|
+
errors.push(`work.next.status_preference[${i}] must be listed in work.status_enum`);
|
|
243
|
+
}
|
|
107
244
|
}
|
|
108
|
-
|
|
109
|
-
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
status_enum: statusEnum,
|
|
248
|
+
priority_min: priorityMin,
|
|
249
|
+
priority_max: priorityMax,
|
|
250
|
+
next: workNextRaw
|
|
251
|
+
? {
|
|
252
|
+
strategy: requireStringInSet(workNextRaw.strategy, "work.next.strategy", NEXT_WORK_STRATEGIES, errors),
|
|
253
|
+
status_preference: statusPreference,
|
|
254
|
+
}
|
|
255
|
+
: undefined,
|
|
256
|
+
};
|
|
257
|
+
})()
|
|
110
258
|
: undefined;
|
|
111
259
|
const workspaces = {};
|
|
260
|
+
const workspaceDocRootOwners = new Map();
|
|
112
261
|
if (workspacesRaw) {
|
|
113
262
|
for (const [alias, entry] of Object.entries(workspacesRaw)) {
|
|
114
|
-
|
|
115
|
-
errors.push(`workspaces.${alias} alias must be lowercase`);
|
|
116
|
-
}
|
|
263
|
+
validateWorkspaceAlias(alias, errors);
|
|
117
264
|
const ws = requireObject(entry, `workspaces.${alias}`, errors);
|
|
118
265
|
if (!ws) {
|
|
119
266
|
continue;
|
|
@@ -122,14 +269,62 @@ function validateConfigSchema(raw) {
|
|
|
122
269
|
const wsEnabled = requireBoolean(ws.enabled, `workspaces.${alias}.enabled`, errors);
|
|
123
270
|
const wsMdkgDir = requireString(ws.mdkg_dir, `workspaces.${alias}.mdkg_dir`, errors);
|
|
124
271
|
if (wsPath && wsEnabled !== undefined && wsMdkgDir) {
|
|
272
|
+
let normalizedPath;
|
|
273
|
+
let normalizedMdkgDir;
|
|
274
|
+
try {
|
|
275
|
+
normalizedPath = (0, workspace_path_1.normalizeContainedWorkspacePath)(wsPath, `workspaces.${alias}.path`);
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
279
|
+
errors.push(message);
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
normalizedMdkgDir = (0, workspace_path_1.normalizeContainedWorkspacePath)(wsMdkgDir, `workspaces.${alias}.mdkg_dir`);
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
286
|
+
errors.push(message);
|
|
287
|
+
}
|
|
288
|
+
if (!normalizedPath || !normalizedMdkgDir) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if (alias !== "root" && (0, workspace_path_1.isRootWorkspacePath)(normalizedPath)) {
|
|
292
|
+
errors.push(`workspaces.${alias}.path must not be "." for non-root workspaces`);
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const docRootKey = (0, workspace_path_1.workspaceDocumentRootKey)(normalizedPath, normalizedMdkgDir);
|
|
296
|
+
const existingAlias = workspaceDocRootOwners.get(docRootKey);
|
|
297
|
+
if (existingAlias) {
|
|
298
|
+
errors.push(`workspaces.${alias} document root duplicates workspaces.${existingAlias}`);
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
workspaceDocRootOwners.set(docRootKey, alias);
|
|
125
302
|
workspaces[alias] = {
|
|
126
|
-
path:
|
|
303
|
+
path: normalizedPath,
|
|
127
304
|
enabled: wsEnabled,
|
|
128
|
-
mdkg_dir:
|
|
305
|
+
mdkg_dir: normalizedMdkgDir,
|
|
129
306
|
};
|
|
130
307
|
}
|
|
131
308
|
}
|
|
132
309
|
}
|
|
310
|
+
const rootWorkspace = workspaces.root;
|
|
311
|
+
if (root_required !== undefined && root_required !== true) {
|
|
312
|
+
errors.push("root_required must be true");
|
|
313
|
+
}
|
|
314
|
+
if (!rootWorkspace) {
|
|
315
|
+
errors.push("workspaces.root is required");
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
if (rootWorkspace.path !== ".") {
|
|
319
|
+
errors.push('workspaces.root.path must be "."');
|
|
320
|
+
}
|
|
321
|
+
if (rootWorkspace.enabled !== true) {
|
|
322
|
+
errors.push("workspaces.root.enabled must be true");
|
|
323
|
+
}
|
|
324
|
+
if (rootWorkspace.mdkg_dir !== ".mdkg") {
|
|
325
|
+
errors.push('workspaces.root.mdkg_dir must be ".mdkg"');
|
|
326
|
+
}
|
|
327
|
+
}
|
|
133
328
|
if (errors.length > 0) {
|
|
134
329
|
throw new Error(`config validation failed:\n${errors.join("\n")}`);
|
|
135
330
|
}
|
package/dist/core/migrate.js
CHANGED
|
@@ -3,15 +3,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.LATEST_SCHEMA_VERSION = void 0;
|
|
4
4
|
exports.migrateConfig = migrateConfig;
|
|
5
5
|
exports.LATEST_SCHEMA_VERSION = 1;
|
|
6
|
-
const
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const LEGACY_SCHEMA_VERSION = 0;
|
|
7
|
+
function isJsonObject(value) {
|
|
8
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
function getSchemaVersion(raw) {
|
|
11
11
|
const version = raw.schema_version;
|
|
12
|
+
if (version === undefined) {
|
|
13
|
+
return LEGACY_SCHEMA_VERSION;
|
|
14
|
+
}
|
|
12
15
|
if (typeof version !== "number" || !Number.isInteger(version)) {
|
|
13
16
|
throw new Error("config schema_version must be an integer");
|
|
14
17
|
}
|
|
18
|
+
if (version < LEGACY_SCHEMA_VERSION) {
|
|
19
|
+
throw new Error("config schema_version must be non-negative");
|
|
20
|
+
}
|
|
21
|
+
return version;
|
|
22
|
+
}
|
|
23
|
+
function migrateLegacyConfig(input) {
|
|
24
|
+
if (!isJsonObject(input)) {
|
|
25
|
+
throw new Error("config must be a JSON object");
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
...input,
|
|
29
|
+
schema_version: 1,
|
|
30
|
+
workspaces: input.workspaces === undefined
|
|
31
|
+
? {
|
|
32
|
+
root: {
|
|
33
|
+
path: ".",
|
|
34
|
+
enabled: true,
|
|
35
|
+
mdkg_dir: ".mdkg",
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
: input.workspaces,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const MIGRATIONS = {
|
|
42
|
+
[LEGACY_SCHEMA_VERSION]: migrateLegacyConfig,
|
|
43
|
+
};
|
|
44
|
+
function migrateConfig(raw) {
|
|
45
|
+
if (!isJsonObject(raw)) {
|
|
46
|
+
throw new Error("config must be a JSON object");
|
|
47
|
+
}
|
|
48
|
+
const version = getSchemaVersion(raw);
|
|
15
49
|
if (version > exports.LATEST_SCHEMA_VERSION) {
|
|
16
50
|
throw new Error(`config schema_version ${version} is newer than supported ${exports.LATEST_SCHEMA_VERSION}`);
|
|
17
51
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.readPackageVersion = readPackageVersion;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function readPackageVersion(startDir = __dirname) {
|
|
10
|
+
let current = path_1.default.resolve(startDir);
|
|
11
|
+
for (let i = 0; i < 5; i += 1) {
|
|
12
|
+
const packagePath = path_1.default.join(current, "package.json");
|
|
13
|
+
if (fs_1.default.existsSync(packagePath)) {
|
|
14
|
+
try {
|
|
15
|
+
const raw = JSON.parse(fs_1.default.readFileSync(packagePath, "utf8"));
|
|
16
|
+
if (raw.name === "mdkg" && typeof raw.version === "string" && raw.version.trim().length > 0) {
|
|
17
|
+
return raw.version;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return "unknown";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const parent = path_1.default.dirname(current);
|
|
25
|
+
if (parent === current) {
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
current = parent;
|
|
29
|
+
}
|
|
30
|
+
return "unknown";
|
|
31
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.normalizeContainedWorkspacePath = normalizeContainedWorkspacePath;
|
|
7
|
+
exports.isRootWorkspacePath = isRootWorkspacePath;
|
|
8
|
+
exports.workspaceDocumentRootKey = workspaceDocumentRootKey;
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
function isAbsoluteOnSupportedPlatform(value) {
|
|
11
|
+
return path_1.default.isAbsolute(value) || path_1.default.posix.isAbsolute(value) || path_1.default.win32.isAbsolute(value);
|
|
12
|
+
}
|
|
13
|
+
function normalizeContainedWorkspacePath(value, label) {
|
|
14
|
+
const normalized = value.trim();
|
|
15
|
+
if (!normalized) {
|
|
16
|
+
throw new Error(`${label} cannot be empty`);
|
|
17
|
+
}
|
|
18
|
+
if (normalized.includes("\0")) {
|
|
19
|
+
throw new Error(`${label} cannot contain NUL bytes`);
|
|
20
|
+
}
|
|
21
|
+
if (isAbsoluteOnSupportedPlatform(normalized)) {
|
|
22
|
+
throw new Error(`${label} must be relative`);
|
|
23
|
+
}
|
|
24
|
+
if (normalized.split(/[\\/]+/).some((part) => part === "..")) {
|
|
25
|
+
throw new Error(`${label} cannot contain parent-directory components`);
|
|
26
|
+
}
|
|
27
|
+
return normalized;
|
|
28
|
+
}
|
|
29
|
+
function isRootWorkspacePath(value) {
|
|
30
|
+
const parts = value
|
|
31
|
+
.trim()
|
|
32
|
+
.split(/[\\/]+/)
|
|
33
|
+
.filter(Boolean);
|
|
34
|
+
return parts.length > 0 && parts.every((part) => part === ".");
|
|
35
|
+
}
|
|
36
|
+
function workspaceDocumentRootKey(workspacePath, mdkgDir) {
|
|
37
|
+
return [workspacePath, mdkgDir]
|
|
38
|
+
.flatMap((value) => value.trim().split(/[\\/]+/))
|
|
39
|
+
.filter((part) => part && part !== ".")
|
|
40
|
+
.join("/");
|
|
41
|
+
}
|