get-tbd 0.1.26 → 0.1.27
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/dist/bin.mjs +119 -29
- package/dist/bin.mjs.map +1 -1
- package/dist/cli.mjs +114 -35
- package/dist/cli.mjs.map +1 -1
- package/dist/{config-b20Kf5pW.mjs → config-B38rbI9u.mjs} +2 -2
- package/dist/{config-b20Kf5pW.mjs.map → config-B38rbI9u.mjs.map} +1 -1
- package/dist/{config-BZte2m3w.mjs → config-C0ITTrtc.mjs} +1 -1
- package/dist/{id-mapping-BtBwq5nG.mjs → id-mapping-CqrrLgeX.mjs} +2 -2
- package/dist/{id-mapping-BtBwq5nG.mjs.map → id-mapping-CqrrLgeX.mjs.map} +1 -1
- package/dist/{id-mapping-BA_xn516.mjs → id-mapping-Ctfl_nc1.mjs} +1 -1
- package/dist/index.d.mts +13 -1
- package/dist/index.mjs +3 -3
- package/dist/{schemas-BQYmDnkv.mjs → schemas-C8mOQykE.mjs} +17 -5
- package/dist/schemas-C8mOQykE.mjs.map +1 -0
- package/dist/{src-DQcOQnFp.mjs → src-BIE27KDA.mjs} +3 -3
- package/dist/{src-DQcOQnFp.mjs.map → src-BIE27KDA.mjs.map} +1 -1
- package/dist/tbd +119 -29
- package/package.json +1 -1
- package/dist/schemas-BQYmDnkv.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as insertAfterFrontmatter, c as noopLogger, i as serializeIssue, n as parseIssue, o as parseMarkdown, r as parseMarkdownWithFrontmatter, s as stripFrontmatter, t as VERSION$1 } from "./src-
|
|
1
|
+
import { S as IssueTitle, b as IssueSchema, g as ISSUE_TITLE_MAX_LENGTH, n as AtticEntrySchema, t as ATTIC_ENTRY_FIELD_ORDER, x as IssueStatus, y as IssueKind } from "./schemas-C8mOQykE.mjs";
|
|
2
|
+
import { a as insertAfterFrontmatter, c as noopLogger, i as serializeIssue, n as parseIssue, o as parseMarkdown, r as parseMarkdownWithFrontmatter, s as stripFrontmatter, t as VERSION$1 } from "./src-BIE27KDA.mjs";
|
|
3
3
|
import { a as parseYamlWithConflictDetection, d as PAGINATION_LINE_THRESHOLD, f as PARENT_CONTEXT_MAX_LINES, l as comparisonChain, n as detectDuplicateYamlKeys, o as sortKeys, s as stringifyYaml, u as ordering } from "./yaml-utils-BPy991by.mjs";
|
|
4
|
-
import { A as isValidWorkspaceName, C as TBD_SHORTCUTS_STANDARD, D as WORKTREE_DIR, E as WORKSPACES_DIR, M as resolveDataSyncDir, O as WORKTREE_DIR_NAME, S as TBD_GUIDELINES_DIR, T as TBD_TEMPLATES_DIR, _ as DEFAULT_SHORTCUT_PATHS, a as isInitialized, b as TBD_DIR, c as readConfigWithMigration, d as writeConfig, g as DEFAULT_GUIDELINES_PATHS, h as DATA_SYNC_DIR_NAME, i as initConfig, j as resolveAtticDir, k as getWorkspaceDir, l as readLocalState, m as DATA_SYNC_DIR, n as findTbdRoot, o as markWelcomeSeen, p as CHARS_PER_TOKEN, r as hasSeenWelcome, s as readConfig, u as updateLocalState, v as DEFAULT_TEMPLATE_PATHS, w as TBD_SHORTCUTS_SYSTEM, x as TBD_DOCS_DIR, y as SYNC_BRANCH } from "./config-
|
|
5
|
-
import { _ as formatDisplayId, a as hasShortId, b as normalizeIssueId, c as parseIdMappingFromYaml, d as resolveToInternalId, f as saveIdMapping, g as formatDebugId, h as extractUlidFromInternalId, i as generateUniqueShortId, l as reconcileMappings, m as extractShortId, o as loadIdMapping, p as extractPrefix, s as mergeIdMappings, t as addIdMapping, u as resolveIdMappingConflicts, v as generateInternalId, x as validateIssueId, y as makeInternalId } from "./id-mapping-
|
|
4
|
+
import { A as isValidWorkspaceName, C as TBD_SHORTCUTS_STANDARD, D as WORKTREE_DIR, E as WORKSPACES_DIR, M as resolveDataSyncDir, O as WORKTREE_DIR_NAME, S as TBD_GUIDELINES_DIR, T as TBD_TEMPLATES_DIR, _ as DEFAULT_SHORTCUT_PATHS, a as isInitialized, b as TBD_DIR, c as readConfigWithMigration, d as writeConfig, g as DEFAULT_GUIDELINES_PATHS, h as DATA_SYNC_DIR_NAME, i as initConfig, j as resolveAtticDir, k as getWorkspaceDir, l as readLocalState, m as DATA_SYNC_DIR, n as findTbdRoot, o as markWelcomeSeen, p as CHARS_PER_TOKEN, r as hasSeenWelcome, s as readConfig, u as updateLocalState, v as DEFAULT_TEMPLATE_PATHS, w as TBD_SHORTCUTS_SYSTEM, x as TBD_DOCS_DIR, y as SYNC_BRANCH } from "./config-B38rbI9u.mjs";
|
|
5
|
+
import { _ as formatDisplayId, a as hasShortId, b as normalizeIssueId, c as parseIdMappingFromYaml, d as resolveToInternalId, f as saveIdMapping, g as formatDebugId, h as extractUlidFromInternalId, i as generateUniqueShortId, l as reconcileMappings, m as extractShortId, o as loadIdMapping, p as extractPrefix, s as mergeIdMappings, t as addIdMapping, u as resolveIdMappingConflicts, v as generateInternalId, x as validateIssueId, y as makeInternalId } from "./id-mapping-CqrrLgeX.mjs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
|
+
import { ZodError } from "zod";
|
|
7
8
|
import matter from "gray-matter";
|
|
8
9
|
import { parse } from "yaml";
|
|
9
10
|
import { Command } from "commander";
|
|
@@ -1754,7 +1755,7 @@ async function migrateDataToWorktree(baseDir, removeSource = false) {
|
|
|
1754
1755
|
for (const file of issueFiles) await cp(join(wrongIssuesPath, file), join(correctIssuesPath, file));
|
|
1755
1756
|
for (const file of mappingFiles) if (file === "ids.yml") {
|
|
1756
1757
|
const { readFile } = await import("node:fs/promises");
|
|
1757
|
-
const { loadIdMapping, mergeIdMappings, saveIdMapping, resolveIdMappingConflicts } = await import("./id-mapping-
|
|
1758
|
+
const { loadIdMapping, mergeIdMappings, saveIdMapping, resolveIdMappingConflicts } = await import("./id-mapping-Ctfl_nc1.mjs");
|
|
1758
1759
|
const sourceMapping = resolveIdMappingConflicts(await readFile(join(wrongMappingsPath, file), "utf-8"));
|
|
1759
1760
|
let targetMapping;
|
|
1760
1761
|
try {
|
|
@@ -1883,6 +1884,29 @@ const initCommand = new Command("init").description("Initialize tbd in a git rep
|
|
|
1883
1884
|
await new InitHandler(command).run(options);
|
|
1884
1885
|
});
|
|
1885
1886
|
|
|
1887
|
+
//#endregion
|
|
1888
|
+
//#region src/utils/zod-error-utils.ts
|
|
1889
|
+
/**
|
|
1890
|
+
* Helpers for rendering Zod errors without relying on object inspection.
|
|
1891
|
+
*/
|
|
1892
|
+
/**
|
|
1893
|
+
* Format a ZodError as concise path-qualified messages for CLI output.
|
|
1894
|
+
*/
|
|
1895
|
+
function formatZodError(error) {
|
|
1896
|
+
const messages = error.issues.map((issue) => {
|
|
1897
|
+
return `${issue.path.length > 0 ? issue.path.join(".") : "<root>"}: ${issue.message}`;
|
|
1898
|
+
});
|
|
1899
|
+
return messages.length > 0 ? messages.join("; ") : error.message;
|
|
1900
|
+
}
|
|
1901
|
+
/**
|
|
1902
|
+
* Format unknown thrown values as safe strings for warnings and diagnostics.
|
|
1903
|
+
*/
|
|
1904
|
+
function formatUnknownError(error) {
|
|
1905
|
+
if (error instanceof ZodError) return formatZodError(error);
|
|
1906
|
+
if (error instanceof Error) return error.message;
|
|
1907
|
+
return String(error);
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1886
1910
|
//#endregion
|
|
1887
1911
|
//#region src/file/storage.ts
|
|
1888
1912
|
/**
|
|
@@ -1894,6 +1918,10 @@ const initCommand = new Command("init").description("Initialize tbd in a git rep
|
|
|
1894
1918
|
* See: tbd-design.md §3.2 Storage Layer
|
|
1895
1919
|
*/
|
|
1896
1920
|
/**
|
|
1921
|
+
* Maximum issue files read concurrently to avoid exhausting file descriptors in large repos.
|
|
1922
|
+
*/
|
|
1923
|
+
const ISSUE_READ_BATCH_SIZE = 200;
|
|
1924
|
+
/**
|
|
1897
1925
|
* Get the path to an issue file.
|
|
1898
1926
|
*/
|
|
1899
1927
|
function getIssuePath(baseDir, id) {
|
|
@@ -1911,7 +1939,8 @@ async function readIssue(baseDir, id) {
|
|
|
1911
1939
|
* Uses atomic write to prevent corruption.
|
|
1912
1940
|
*/
|
|
1913
1941
|
async function writeIssue(baseDir, issue) {
|
|
1914
|
-
|
|
1942
|
+
const validIssue = IssueSchema.parse(issue);
|
|
1943
|
+
await writeFile(getIssuePath(baseDir, validIssue.id), serializeIssue(validIssue));
|
|
1915
1944
|
}
|
|
1916
1945
|
/**
|
|
1917
1946
|
* List all issues in the worktree.
|
|
@@ -1919,7 +1948,8 @@ async function writeIssue(baseDir, issue) {
|
|
|
1919
1948
|
*
|
|
1920
1949
|
* Uses parallel file reading for better performance with many issues.
|
|
1921
1950
|
*/
|
|
1922
|
-
async function listIssues(baseDir) {
|
|
1951
|
+
async function listIssues(baseDir, options = {}) {
|
|
1952
|
+
const warnOnInvalid = options.warnOnInvalid ?? true;
|
|
1923
1953
|
const issuesDir = join(baseDir, "issues");
|
|
1924
1954
|
let files;
|
|
1925
1955
|
try {
|
|
@@ -1928,10 +1958,9 @@ async function listIssues(baseDir) {
|
|
|
1928
1958
|
return [];
|
|
1929
1959
|
}
|
|
1930
1960
|
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
1931
|
-
const BATCH_SIZE = 200;
|
|
1932
1961
|
const issues = [];
|
|
1933
|
-
for (let i = 0; i < mdFiles.length; i +=
|
|
1934
|
-
const batch = mdFiles.slice(i, i +
|
|
1962
|
+
for (let i = 0; i < mdFiles.length; i += ISSUE_READ_BATCH_SIZE) {
|
|
1963
|
+
const batch = mdFiles.slice(i, i + ISSUE_READ_BATCH_SIZE);
|
|
1935
1964
|
const fileContents = await Promise.all(batch.map(async (file) => {
|
|
1936
1965
|
const filePath = join(issuesDir, file);
|
|
1937
1966
|
try {
|
|
@@ -1939,25 +1968,38 @@ async function listIssues(baseDir) {
|
|
|
1939
1968
|
file,
|
|
1940
1969
|
content: await readFile(filePath, "utf-8")
|
|
1941
1970
|
};
|
|
1942
|
-
} catch {
|
|
1971
|
+
} catch (error) {
|
|
1943
1972
|
return {
|
|
1944
1973
|
file,
|
|
1945
|
-
|
|
1974
|
+
error: formatUnknownError(error)
|
|
1946
1975
|
};
|
|
1947
1976
|
}
|
|
1948
1977
|
}));
|
|
1949
|
-
for (const
|
|
1950
|
-
if (
|
|
1978
|
+
for (const result of fileContents) {
|
|
1979
|
+
if ("error" in result) {
|
|
1980
|
+
reportInvalidIssueFile({
|
|
1981
|
+
file: result.file,
|
|
1982
|
+
reason: `failed to read file: ${result.error}`
|
|
1983
|
+
}, warnOnInvalid, options.onInvalidIssue);
|
|
1984
|
+
continue;
|
|
1985
|
+
}
|
|
1951
1986
|
try {
|
|
1952
|
-
const issue = parseIssue(content);
|
|
1987
|
+
const issue = parseIssue(result.content);
|
|
1953
1988
|
issues.push(issue);
|
|
1954
1989
|
} catch (error) {
|
|
1955
|
-
|
|
1990
|
+
reportInvalidIssueFile({
|
|
1991
|
+
file: result.file,
|
|
1992
|
+
reason: formatUnknownError(error)
|
|
1993
|
+
}, warnOnInvalid, options.onInvalidIssue);
|
|
1956
1994
|
}
|
|
1957
1995
|
}
|
|
1958
1996
|
}
|
|
1959
1997
|
return issues;
|
|
1960
1998
|
}
|
|
1999
|
+
function reportInvalidIssueFile(invalidIssue, warnOnInvalid, onInvalidIssue) {
|
|
2000
|
+
onInvalidIssue?.(invalidIssue);
|
|
2001
|
+
if (warnOnInvalid) console.warn(`Skipping invalid issue file: ${invalidIssue.file}: ${invalidIssue.reason}`);
|
|
2002
|
+
}
|
|
1961
2003
|
|
|
1962
2004
|
//#endregion
|
|
1963
2005
|
//#region src/lib/priority.ts
|
|
@@ -2150,6 +2192,22 @@ async function resolveAndValidatePath(inputPath, projectRoot, cwd) {
|
|
|
2150
2192
|
return resolved;
|
|
2151
2193
|
}
|
|
2152
2194
|
|
|
2195
|
+
//#endregion
|
|
2196
|
+
//#region src/cli/lib/issue-input-validation.ts
|
|
2197
|
+
/**
|
|
2198
|
+
* CLI validation helpers for user-provided issue fields.
|
|
2199
|
+
*/
|
|
2200
|
+
/**
|
|
2201
|
+
* Validate a CLI-provided issue title with actionable user-facing errors.
|
|
2202
|
+
*/
|
|
2203
|
+
function validateIssueTitle(title, options) {
|
|
2204
|
+
if (options.rejectBlank ? title.trim().length === 0 : title.length === 0) throw new ValidationError(options.emptyMessage);
|
|
2205
|
+
if (title.length > ISSUE_TITLE_MAX_LENGTH) throw new ValidationError(`Title is too long (${title.length} chars, max ${ISSUE_TITLE_MAX_LENGTH}). Move detail into the description body.`);
|
|
2206
|
+
const result = IssueTitle.safeParse(title);
|
|
2207
|
+
if (!result.success) throw new ValidationError(`Invalid title: ${formatZodError(result.error)}`);
|
|
2208
|
+
return title;
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2153
2211
|
//#endregion
|
|
2154
2212
|
//#region src/cli/commands/create.ts
|
|
2155
2213
|
/**
|
|
@@ -2161,6 +2219,10 @@ var CreateHandler = class extends BaseCommand {
|
|
|
2161
2219
|
async run(title, options) {
|
|
2162
2220
|
const tbdRoot = await requireInit();
|
|
2163
2221
|
if (!title && !options.fromFile) throw new ValidationError("Title is required. Use: tbd create \"Issue title\"");
|
|
2222
|
+
const validatedTitle = title === void 0 ? void 0 : validateIssueTitle(title, {
|
|
2223
|
+
emptyMessage: "Title is required. Use: tbd create \"Issue title\"",
|
|
2224
|
+
rejectBlank: true
|
|
2225
|
+
});
|
|
2164
2226
|
const kind = this.parseKind(options.type ?? "task");
|
|
2165
2227
|
const priority = this.validatePriority(options.priority ?? "2");
|
|
2166
2228
|
let description = options.description;
|
|
@@ -2177,7 +2239,7 @@ var CreateHandler = class extends BaseCommand {
|
|
|
2177
2239
|
throw new ValidationError(getPathErrorMessage(error));
|
|
2178
2240
|
}
|
|
2179
2241
|
if (this.checkDryRun("Would create issue", {
|
|
2180
|
-
title,
|
|
2242
|
+
title: validatedTitle,
|
|
2181
2243
|
kind,
|
|
2182
2244
|
priority,
|
|
2183
2245
|
spec: specPath,
|
|
@@ -2209,7 +2271,7 @@ var CreateHandler = class extends BaseCommand {
|
|
|
2209
2271
|
type: "is",
|
|
2210
2272
|
id,
|
|
2211
2273
|
version: 1,
|
|
2212
|
-
title,
|
|
2274
|
+
title: validatedTitle,
|
|
2213
2275
|
kind,
|
|
2214
2276
|
status: "open",
|
|
2215
2277
|
priority,
|
|
@@ -2241,9 +2303,9 @@ var CreateHandler = class extends BaseCommand {
|
|
|
2241
2303
|
this.output.data({
|
|
2242
2304
|
id: displayId,
|
|
2243
2305
|
internalId: id,
|
|
2244
|
-
title
|
|
2306
|
+
title: validatedTitle
|
|
2245
2307
|
}, () => {
|
|
2246
|
-
this.output.success(`Created ${displayId}: ${
|
|
2308
|
+
this.output.success(`Created ${displayId}: ${validatedTitle}`);
|
|
2247
2309
|
});
|
|
2248
2310
|
}
|
|
2249
2311
|
parseKind(value) {
|
|
@@ -3059,7 +3121,10 @@ var UpdateHandler = class extends BaseCommand {
|
|
|
3059
3121
|
}
|
|
3060
3122
|
try {
|
|
3061
3123
|
const { frontmatter, description, notes } = parseMarkdownWithFrontmatter(content);
|
|
3062
|
-
if (typeof frontmatter.title === "string") updates.title = frontmatter.title
|
|
3124
|
+
if (typeof frontmatter.title === "string") updates.title = validateIssueTitle(frontmatter.title, {
|
|
3125
|
+
emptyMessage: "Title cannot be empty",
|
|
3126
|
+
rejectBlank: true
|
|
3127
|
+
});
|
|
3063
3128
|
if (typeof frontmatter.status === "string") {
|
|
3064
3129
|
const result = IssueStatus.safeParse(frontmatter.status);
|
|
3065
3130
|
if (result.success) updates.status = result.data;
|
|
@@ -3090,10 +3155,10 @@ var UpdateHandler = class extends BaseCommand {
|
|
|
3090
3155
|
}
|
|
3091
3156
|
return updates;
|
|
3092
3157
|
}
|
|
3093
|
-
if (options.title !== void 0) {
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
}
|
|
3158
|
+
if (options.title !== void 0) updates.title = validateIssueTitle(options.title, {
|
|
3159
|
+
emptyMessage: "Title cannot be empty",
|
|
3160
|
+
rejectBlank: true
|
|
3161
|
+
});
|
|
3097
3162
|
if (options.status) {
|
|
3098
3163
|
const result = IssueStatus.safeParse(options.status);
|
|
3099
3164
|
if (!result.success) throw new ValidationError(`Invalid status: ${options.status}`);
|
|
@@ -6302,6 +6367,7 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6302
6367
|
cwd = "";
|
|
6303
6368
|
config = null;
|
|
6304
6369
|
issues = [];
|
|
6370
|
+
invalidIssueFiles = [];
|
|
6305
6371
|
async run(options) {
|
|
6306
6372
|
const tbdRoot = await requireInit();
|
|
6307
6373
|
this.cwd = tbdRoot;
|
|
@@ -6310,7 +6376,11 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6310
6376
|
this.config = await readConfig(this.cwd);
|
|
6311
6377
|
} catch {}
|
|
6312
6378
|
try {
|
|
6313
|
-
this.
|
|
6379
|
+
this.invalidIssueFiles = [];
|
|
6380
|
+
this.issues = await listIssues(this.dataSyncDir, {
|
|
6381
|
+
warnOnInvalid: false,
|
|
6382
|
+
onInvalidIssue: (invalidIssue) => this.invalidIssueFiles.push(invalidIssue)
|
|
6383
|
+
});
|
|
6314
6384
|
} catch {}
|
|
6315
6385
|
const statusInfo = await this.gatherStatusInfo();
|
|
6316
6386
|
const statsInfo = await this.gatherStatsInfo();
|
|
@@ -6323,14 +6393,18 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6323
6393
|
healthChecks.push(await this.checkIdMappingConflicts(options.fix));
|
|
6324
6394
|
healthChecks.push(await this.checkIdMappingDuplicates(options.fix));
|
|
6325
6395
|
healthChecks.push(await this.checkTempFiles(options.fix));
|
|
6326
|
-
healthChecks.push(this.checkIssueValidity(this.issues));
|
|
6396
|
+
healthChecks.push(this.checkIssueValidity(this.issues, this.invalidIssueFiles));
|
|
6327
6397
|
healthChecks.push(await this.checkWorktree(options.fix));
|
|
6328
6398
|
const dataLocationResult = await this.checkDataLocation(options.fix);
|
|
6329
6399
|
healthChecks.push(dataLocationResult);
|
|
6330
6400
|
if (dataLocationResult.status === "ok" && dataLocationResult.message?.includes("migrated")) {
|
|
6331
6401
|
this.dataSyncDir = await resolveDataSyncDir(this.cwd);
|
|
6332
6402
|
try {
|
|
6333
|
-
this.
|
|
6403
|
+
this.invalidIssueFiles = [];
|
|
6404
|
+
this.issues = await listIssues(this.dataSyncDir, {
|
|
6405
|
+
warnOnInvalid: false,
|
|
6406
|
+
onInvalidIssue: (invalidIssue) => this.invalidIssueFiles.push(invalidIssue)
|
|
6407
|
+
});
|
|
6334
6408
|
} catch {}
|
|
6335
6409
|
}
|
|
6336
6410
|
const parsedMaxHistory = options.maxHistory ? parseInt(options.maxHistory, 10) : 50;
|
|
@@ -6561,7 +6635,7 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6561
6635
|
status: "ok"
|
|
6562
6636
|
};
|
|
6563
6637
|
if (fix && !this.checkDryRun("Resolve merge conflicts in ids.yml")) try {
|
|
6564
|
-
const { resolveIdMappingConflicts, saveIdMapping } = await import("./id-mapping-
|
|
6638
|
+
const { resolveIdMappingConflicts, saveIdMapping } = await import("./id-mapping-Ctfl_nc1.mjs");
|
|
6565
6639
|
const resolved = resolveIdMappingConflicts(content);
|
|
6566
6640
|
await saveIdMapping(this.dataSyncDir, resolved);
|
|
6567
6641
|
return {
|
|
@@ -6610,7 +6684,7 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6610
6684
|
status: "ok"
|
|
6611
6685
|
};
|
|
6612
6686
|
if (fix && !this.checkDryRun("Fix duplicate ID mapping keys")) try {
|
|
6613
|
-
const { loadIdMapping, saveIdMapping } = await import("./id-mapping-
|
|
6687
|
+
const { loadIdMapping, saveIdMapping } = await import("./id-mapping-Ctfl_nc1.mjs");
|
|
6614
6688
|
const mapping = await loadIdMapping(this.dataSyncDir);
|
|
6615
6689
|
await saveIdMapping(this.dataSyncDir, mapping);
|
|
6616
6690
|
return {
|
|
@@ -6673,8 +6747,12 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6673
6747
|
suggestion: "Run: tbd doctor --fix"
|
|
6674
6748
|
};
|
|
6675
6749
|
}
|
|
6676
|
-
checkIssueValidity(issues) {
|
|
6750
|
+
checkIssueValidity(issues, invalidIssueFiles) {
|
|
6677
6751
|
const invalid = [];
|
|
6752
|
+
for (const invalidIssueFile of invalidIssueFiles) invalid.push({
|
|
6753
|
+
id: invalidIssueFile.file,
|
|
6754
|
+
reason: invalidIssueFile.reason
|
|
6755
|
+
});
|
|
6678
6756
|
for (const issue of issues) {
|
|
6679
6757
|
const issueId = issue.id ?? "unknown";
|
|
6680
6758
|
if (!issue.id) {
|
|
@@ -6724,7 +6802,8 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6724
6802
|
return {
|
|
6725
6803
|
name: "Issue validity",
|
|
6726
6804
|
status: "error",
|
|
6727
|
-
message: `${invalid.length} invalid issue(s)`,
|
|
6805
|
+
message: `${invalid.length} invalid issue file(s)`,
|
|
6806
|
+
path: join(CONFIG_DIR, "issues"),
|
|
6728
6807
|
details: invalid.map((i) => `${i.id}: ${i.reason}`),
|
|
6729
6808
|
suggestion: "Manually fix or delete invalid issue files"
|
|
6730
6809
|
};
|
|
@@ -6744,7 +6823,7 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6744
6823
|
name: "ID mapping coverage",
|
|
6745
6824
|
status: "ok"
|
|
6746
6825
|
};
|
|
6747
|
-
const { loadIdMapping, saveIdMapping, reconcileMappings } = await import("./id-mapping-
|
|
6826
|
+
const { loadIdMapping, saveIdMapping, reconcileMappings } = await import("./id-mapping-Ctfl_nc1.mjs");
|
|
6748
6827
|
const mapping = await loadIdMapping(this.dataSyncDir);
|
|
6749
6828
|
const missingIds = [];
|
|
6750
6829
|
for (const issue of this.issues) {
|
|
@@ -6756,10 +6835,10 @@ var DoctorHandler = class extends BaseCommand {
|
|
|
6756
6835
|
status: "ok"
|
|
6757
6836
|
};
|
|
6758
6837
|
if (fix && !this.checkDryRun("Create missing ID mappings")) {
|
|
6759
|
-
const { parseIdMappingFromYaml, mergeIdMappings } = await import("./id-mapping-
|
|
6838
|
+
const { parseIdMappingFromYaml, mergeIdMappings } = await import("./id-mapping-Ctfl_nc1.mjs");
|
|
6760
6839
|
let historicalMapping;
|
|
6761
6840
|
try {
|
|
6762
|
-
const syncBranch = (await import("./config-
|
|
6841
|
+
const syncBranch = (await import("./config-C0ITTrtc.mjs").then((m) => m.readConfig(this.cwd))).sync.branch;
|
|
6763
6842
|
const logArgs = ["log", "--format=%H"];
|
|
6764
6843
|
if (maxHistory > 0) logArgs.push(`-${maxHistory}`);
|
|
6765
6844
|
logArgs.push(syncBranch, "--", `${DATA_SYNC_DIR}/mappings/ids.yml`);
|