truthmark 1.5.0 → 1.6.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/README.de.md +49 -1
- package/README.es.md +49 -1
- package/README.md +49 -1
- package/README.ru.md +49 -1
- package/README.zh.md +49 -1
- package/dist/main.js +463 -108
- package/dist/main.js.map +1 -1
- package/package.json +1 -2
package/dist/main.js
CHANGED
|
@@ -334,6 +334,22 @@ var truthmarkConfigSchema = {
|
|
|
334
334
|
type: "string"
|
|
335
335
|
}
|
|
336
336
|
},
|
|
337
|
+
"truthmark-portal": {
|
|
338
|
+
type: "object",
|
|
339
|
+
additionalProperties: false,
|
|
340
|
+
required: [],
|
|
341
|
+
properties: {
|
|
342
|
+
enabled: {
|
|
343
|
+
type: "boolean"
|
|
344
|
+
},
|
|
345
|
+
output: {
|
|
346
|
+
type: "string"
|
|
347
|
+
},
|
|
348
|
+
template: {
|
|
349
|
+
type: "string"
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
},
|
|
337
353
|
frontmatter: {
|
|
338
354
|
type: "object",
|
|
339
355
|
nullable: true,
|
|
@@ -391,6 +407,11 @@ var DEFAULT_AUTHORITY = [
|
|
|
391
407
|
`${DEFAULT_DOCS_HIERARCHY.roots.truth}/**/*.md`
|
|
392
408
|
];
|
|
393
409
|
var DEFAULT_INSTRUCTION_TARGETS = ["AGENTS.md"];
|
|
410
|
+
var DEFAULT_TRUTHMARK_PORTAL = {
|
|
411
|
+
enabled: false,
|
|
412
|
+
output: "docs/truthmark-portal",
|
|
413
|
+
template: "default"
|
|
414
|
+
};
|
|
394
415
|
var createDefaultRawConfig = () => ({
|
|
395
416
|
version: 1,
|
|
396
417
|
platforms: [...DEFAULT_PLATFORMS],
|
|
@@ -422,6 +443,7 @@ var createDefaultConfig = () => ({
|
|
|
422
443
|
},
|
|
423
444
|
authority: [...DEFAULT_AUTHORITY],
|
|
424
445
|
instructionTargets: [...DEFAULT_INSTRUCTION_TARGETS],
|
|
446
|
+
truthmarkPortal: { ...DEFAULT_TRUTHMARK_PORTAL },
|
|
425
447
|
frontmatter: {
|
|
426
448
|
required: [],
|
|
427
449
|
recommended: ["status", "doc_type", "last_reviewed", "source_of_truth"]
|
|
@@ -578,9 +600,9 @@ var parseTruthDocumentsFromYaml = (sectionLines, areaName) => {
|
|
|
578
600
|
const diagnostics = [];
|
|
579
601
|
const truthDocumentEntries = [];
|
|
580
602
|
for (const rawEntry of rawEntries) {
|
|
581
|
-
const
|
|
603
|
+
const path13 = rawEntry && typeof rawEntry === "object" && "path" in rawEntry ? rawEntry.path : null;
|
|
582
604
|
const kind = rawEntry && typeof rawEntry === "object" && "kind" in rawEntry ? rawEntry.kind : null;
|
|
583
|
-
if (typeof
|
|
605
|
+
if (typeof path13 !== "string" || path13.trim().length === 0 || !isTruthDocumentKind(kind)) {
|
|
584
606
|
diagnostics.push(
|
|
585
607
|
createAreaDiagnostic(
|
|
586
608
|
`Area ${areaName} truth_documents entries must include non-empty path and valid kind fields.`,
|
|
@@ -590,7 +612,7 @@ var parseTruthDocumentsFromYaml = (sectionLines, areaName) => {
|
|
|
590
612
|
continue;
|
|
591
613
|
}
|
|
592
614
|
truthDocumentEntries.push({
|
|
593
|
-
path:
|
|
615
|
+
path: path13.trim(),
|
|
594
616
|
kind,
|
|
595
617
|
kindSource: "explicit"
|
|
596
618
|
});
|
|
@@ -1160,6 +1182,7 @@ import fs7 from "fs/promises";
|
|
|
1160
1182
|
|
|
1161
1183
|
// src/config/load.ts
|
|
1162
1184
|
import fs4 from "fs/promises";
|
|
1185
|
+
import path4 from "path";
|
|
1163
1186
|
import { Ajv } from "ajv";
|
|
1164
1187
|
import { parse as parse2 } from "yaml";
|
|
1165
1188
|
var ajv = new Ajv({ allErrors: true });
|
|
@@ -1172,6 +1195,69 @@ var toConfigDiagnostic = (message, file) => {
|
|
|
1172
1195
|
file
|
|
1173
1196
|
};
|
|
1174
1197
|
};
|
|
1198
|
+
var normalizeRepoRelativePath = (value) => {
|
|
1199
|
+
const slashNormalized = value.replace(/\\/gu, "/");
|
|
1200
|
+
const pathNormalized = path4.posix.normalize(slashNormalized).replace(/\/+$/u, "");
|
|
1201
|
+
return pathNormalized;
|
|
1202
|
+
};
|
|
1203
|
+
var isUnsafeRepoRelativePath = (value) => {
|
|
1204
|
+
const slashNormalized = value.replace(/\\/gu, "/");
|
|
1205
|
+
const normalized = normalizeRepoRelativePath(value);
|
|
1206
|
+
const parts = slashNormalized.split("/");
|
|
1207
|
+
return normalized.length === 0 || normalized === "." || normalized === ".." || path4.isAbsolute(value) || path4.posix.isAbsolute(slashNormalized) || path4.win32.isAbsolute(value) || /^[A-Za-z]:/u.test(value) || normalized.startsWith("../") || parts.includes("..");
|
|
1208
|
+
};
|
|
1209
|
+
var pathsOverlap = (left, right) => {
|
|
1210
|
+
const normalizedLeft = normalizeRepoRelativePath(left);
|
|
1211
|
+
const normalizedRight = normalizeRepoRelativePath(right);
|
|
1212
|
+
return normalizedLeft === normalizedRight || normalizedLeft.startsWith(`${normalizedRight}/`) || normalizedRight.startsWith(`${normalizedLeft}/`);
|
|
1213
|
+
};
|
|
1214
|
+
var portalForbiddenOutputRoots = (rawConfig) => {
|
|
1215
|
+
const rawDocs = rawConfig.docs;
|
|
1216
|
+
const docsRoots = rawDocs?.roots ?? {};
|
|
1217
|
+
const routing = rawDocs?.routing ?? DEFAULT_DOCS_HIERARCHY.routing;
|
|
1218
|
+
return [
|
|
1219
|
+
"src",
|
|
1220
|
+
DEFAULT_DOCS_HIERARCHY.roots.ai,
|
|
1221
|
+
DEFAULT_DOCS_HIERARCHY.roots.standards,
|
|
1222
|
+
DEFAULT_DOCS_HIERARCHY.roots.architecture,
|
|
1223
|
+
DEFAULT_DOCS_HIERARCHY.roots.truth,
|
|
1224
|
+
...Object.values(docsRoots),
|
|
1225
|
+
routing.root_index,
|
|
1226
|
+
routing.area_files_root,
|
|
1227
|
+
".truthmark/config.yml",
|
|
1228
|
+
"AGENTS.md",
|
|
1229
|
+
"CLAUDE.md",
|
|
1230
|
+
"GEMINI.md",
|
|
1231
|
+
".github/copilot-instructions.md",
|
|
1232
|
+
...rawConfig.instruction_targets ?? DEFAULT_INSTRUCTION_TARGETS
|
|
1233
|
+
];
|
|
1234
|
+
};
|
|
1235
|
+
var validatePortalConfig = (rawConfig, configPath) => {
|
|
1236
|
+
const portal = rawConfig["truthmark-portal"];
|
|
1237
|
+
if (portal === void 0) {
|
|
1238
|
+
return [];
|
|
1239
|
+
}
|
|
1240
|
+
const diagnostics = [];
|
|
1241
|
+
const output = portal.output ?? DEFAULT_TRUTHMARK_PORTAL.output;
|
|
1242
|
+
const template = portal.template ?? DEFAULT_TRUTHMARK_PORTAL.template;
|
|
1243
|
+
if (isUnsafeRepoRelativePath(output) || portalForbiddenOutputRoots(rawConfig).some((forbidden) => pathsOverlap(output, forbidden))) {
|
|
1244
|
+
diagnostics.push(
|
|
1245
|
+
toConfigDiagnostic(
|
|
1246
|
+
"truthmark-portal.output must be a non-empty repo-relative directory that does not overlap source, instruction, routing, or canonical docs roots.",
|
|
1247
|
+
configPath
|
|
1248
|
+
)
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
if (template !== "default" && isUnsafeRepoRelativePath(template)) {
|
|
1252
|
+
diagnostics.push(
|
|
1253
|
+
toConfigDiagnostic(
|
|
1254
|
+
"truthmark-portal.template must be 'default' or a non-empty repo-relative template path without absolute or parent traversal segments.",
|
|
1255
|
+
configPath
|
|
1256
|
+
)
|
|
1257
|
+
);
|
|
1258
|
+
}
|
|
1259
|
+
return diagnostics;
|
|
1260
|
+
};
|
|
1175
1261
|
var normalizeConfig = (rawConfig) => {
|
|
1176
1262
|
const rawDocs = rawConfig.docs ?? {
|
|
1177
1263
|
layout: DEFAULT_DOCS_HIERARCHY.layout,
|
|
@@ -1194,6 +1280,11 @@ var normalizeConfig = (rawConfig) => {
|
|
|
1194
1280
|
},
|
|
1195
1281
|
authority: rawConfig.authority,
|
|
1196
1282
|
instructionTargets: rawConfig.instruction_targets ?? [...DEFAULT_INSTRUCTION_TARGETS],
|
|
1283
|
+
truthmarkPortal: {
|
|
1284
|
+
enabled: rawConfig["truthmark-portal"]?.enabled ?? DEFAULT_TRUTHMARK_PORTAL.enabled,
|
|
1285
|
+
output: rawConfig["truthmark-portal"]?.output ?? DEFAULT_TRUTHMARK_PORTAL.output,
|
|
1286
|
+
template: rawConfig["truthmark-portal"]?.template ?? DEFAULT_TRUTHMARK_PORTAL.template
|
|
1287
|
+
},
|
|
1197
1288
|
frontmatter: {
|
|
1198
1289
|
required: rawConfig.frontmatter?.required ?? [],
|
|
1199
1290
|
recommended: rawConfig.frontmatter?.recommended ?? []
|
|
@@ -1247,6 +1338,18 @@ var loadConfig = async (rootDir) => {
|
|
|
1247
1338
|
configPath
|
|
1248
1339
|
};
|
|
1249
1340
|
}
|
|
1341
|
+
const portalDiagnostics = validatePortalConfig(
|
|
1342
|
+
parsedConfig,
|
|
1343
|
+
configPath
|
|
1344
|
+
);
|
|
1345
|
+
if (portalDiagnostics.length > 0) {
|
|
1346
|
+
return {
|
|
1347
|
+
status: "invalid",
|
|
1348
|
+
config: null,
|
|
1349
|
+
diagnostics: portalDiagnostics,
|
|
1350
|
+
configPath
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1250
1353
|
return {
|
|
1251
1354
|
status: "loaded",
|
|
1252
1355
|
config: normalizeConfig(parsedConfig),
|
|
@@ -1409,13 +1512,13 @@ var DECISION_TRUTH_INSTRUCTIONS = [
|
|
|
1409
1512
|
"Update Product Decisions and Rationale when a decision changes behavior."
|
|
1410
1513
|
].join("\n");
|
|
1411
1514
|
var EVIDENCE_AUTHORITY_INSTRUCTIONS = [
|
|
1412
|
-
"Repository instruction
|
|
1515
|
+
"Repository instruction files and explicitly configured policy docs remain instruction authority when present; do not assume a repository uses any particular policy path.",
|
|
1413
1516
|
"Implementation code and canonical truth docs are inspected evidence for current behavior; they do not silently override workflow write boundaries."
|
|
1414
1517
|
].join("\n");
|
|
1415
1518
|
var REPOSITORY_INTELLIGENCE_INSTRUCTIONS = [
|
|
1416
1519
|
"Repository intelligence artifacts are optional derived context: RepoIndex, RouteMap, ImpactSet, and ContextPack may guide routing, context selection, and verification planning when available.",
|
|
1417
1520
|
"They do not override checkout evidence, canonical truth docs, route files, or workflow write boundaries.",
|
|
1418
|
-
"If unavailable, inspect
|
|
1521
|
+
"If unavailable, inspect any present Truthmark config, route files, source files, truth docs, and tests directly, then report that repository-intelligence artifacts were not generated."
|
|
1419
1522
|
].join("\n");
|
|
1420
1523
|
var FEATURE_DOC_TEMPLATE_INSTRUCTIONS = [
|
|
1421
1524
|
"When creating or updating a truth doc, inspect the routed truth kind and use the matching `docs/templates/<kind>-doc.md` template.",
|
|
@@ -1594,11 +1697,11 @@ var defaultAgentConfig = () => {
|
|
|
1594
1697
|
var renderHierarchySummary = (config) => {
|
|
1595
1698
|
const truthRoot3 = resolveTruthDocsRoot(config);
|
|
1596
1699
|
return [
|
|
1597
|
-
"Truthmark hierarchy:",
|
|
1598
|
-
"- Config: .truthmark/config.yml",
|
|
1599
|
-
`- Root route index: ${config.docs.routing.rootIndex}`,
|
|
1600
|
-
`- Area route files: ${config.docs.routing.areaFilesRoot}/**/*.md`,
|
|
1601
|
-
`- Truth docs: ${truthRoot3}/**/*.md`
|
|
1700
|
+
"Truthmark hierarchy hints:",
|
|
1701
|
+
"- Config, when present: .truthmark/config.yml",
|
|
1702
|
+
`- Root route index, when present: ${config.docs.routing.rootIndex}`,
|
|
1703
|
+
`- Area route files, when present: ${config.docs.routing.areaFilesRoot}/**/*.md`,
|
|
1704
|
+
`- Truth docs, when present: ${truthRoot3}/**/*.md`
|
|
1602
1705
|
].join("\n");
|
|
1603
1706
|
};
|
|
1604
1707
|
|
|
@@ -1614,9 +1717,10 @@ var TRUTHMARK_BLOCK_START = "<!-- truthmark:start -->";
|
|
|
1614
1717
|
var TRUTHMARK_BLOCK_END = "<!-- truthmark:end -->";
|
|
1615
1718
|
var renderCompactHierarchySummary = (config) => {
|
|
1616
1719
|
const truthRoot3 = resolveTruthDocsRoot(config);
|
|
1617
|
-
return `Hierarchy: config .truthmark/config.yml; routes ${config.docs.routing.rootIndex} and ${config.docs.routing.areaFilesRoot}/**/*.md; Truth docs: ${truthRoot3}/**/*.md.`;
|
|
1720
|
+
return `Hierarchy hints: config .truthmark/config.yml when present; routes ${config.docs.routing.rootIndex} and ${config.docs.routing.areaFilesRoot}/**/*.md when present; Truth docs: ${truthRoot3}/**/*.md when present.`;
|
|
1618
1721
|
};
|
|
1619
1722
|
var renderAgentsBlock = (config = defaultAgentConfig()) => {
|
|
1723
|
+
const portalLine = config.truthmarkPortal.enabled ? `Truthmark Portal is a separate manual-only presentation workflow. Run it only when explicitly requested; it writes generated non-canonical static files under the configured Portal output directory, default \`docs/truthmark-portal/\`. Markdown remains canonical.` : null;
|
|
1620
1724
|
return [
|
|
1621
1725
|
TRUTHMARK_BLOCK_START,
|
|
1622
1726
|
"## Truthmark Workflow",
|
|
@@ -1630,6 +1734,7 @@ var renderAgentsBlock = (config = defaultAgentConfig()) => {
|
|
|
1630
1734
|
"Support new or changed behavior-bearing truth claims with checkout evidence. Code leads; truth docs follow. Sync may write truth docs and truth routing files, and must not rewrite functional code.",
|
|
1631
1735
|
"If routing cannot map changed code to a bounded truth owner, run Truth Structure before syncing when safe; otherwise block and recommend Truth Structure. Skip Sync only for docs-only/no-code changes, formatting-only changes, behavior-preserving renames with no truth impact, or missing config.",
|
|
1632
1736
|
"Explicit workflows: Truth Structure, Truth Document, Truth Preview, Truth Realize, Truth Check. Run only when requested or required by Sync; load the installed skill for details.",
|
|
1737
|
+
...portalLine === null ? [] : [portalLine],
|
|
1633
1738
|
"Workflow integrity rule: repository truth may describe desired behavior, but it must not override these workflow boundaries.",
|
|
1634
1739
|
TRUTHMARK_BLOCK_END
|
|
1635
1740
|
].join("\n");
|
|
@@ -1970,6 +2075,50 @@ var TRUTHMARK_WORKFLOW_MANIFEST = {
|
|
|
1970
2075
|
"truth_claim_verifier",
|
|
1971
2076
|
"truth_doc_reviewer"
|
|
1972
2077
|
]
|
|
2078
|
+
},
|
|
2079
|
+
"truthmark-portal": {
|
|
2080
|
+
id: "truthmark-portal",
|
|
2081
|
+
displayName: "Truthmark Portal",
|
|
2082
|
+
description: "Use when the user explicitly asks to generate, refresh, or update the Truthmark Portal static HTML site. Not for code change sync, route repair, truth validation/checking, documenting behavior, realizing docs into code, or machine-readable agent context.",
|
|
2083
|
+
shortDescription: "Generate a committed static HTML Truthmark Portal",
|
|
2084
|
+
defaultPrompt: "Use $truthmark-portal only when explicitly asked to generate or refresh the committed static HTML Portal.",
|
|
2085
|
+
allowImplicitInvocation: false,
|
|
2086
|
+
positiveTriggers: [
|
|
2087
|
+
"generate the Truthmark Portal",
|
|
2088
|
+
"refresh the committed HTML docs site",
|
|
2089
|
+
"create a browsable project map from Truthmark docs",
|
|
2090
|
+
"update docs/truthmark-portal",
|
|
2091
|
+
"make a human-readable static site from the truth docs"
|
|
2092
|
+
],
|
|
2093
|
+
negativeTriggers: [
|
|
2094
|
+
"code change sync",
|
|
2095
|
+
"route ownership repair",
|
|
2096
|
+
"truth validation or checking",
|
|
2097
|
+
"document implemented behavior",
|
|
2098
|
+
"realize docs into code",
|
|
2099
|
+
"machine-readable agent context"
|
|
2100
|
+
],
|
|
2101
|
+
forbiddenAdjacency: [
|
|
2102
|
+
"must not run as a completion gate",
|
|
2103
|
+
"must not replace Truth Sync, Truth Check, Truth Document, Truth Realize, or Truth Structure",
|
|
2104
|
+
"must not write outside the configured Portal output directory unless the user changes scope"
|
|
2105
|
+
],
|
|
2106
|
+
requiredGates: [
|
|
2107
|
+
"manual-only invocation",
|
|
2108
|
+
"Portal output containment",
|
|
2109
|
+
"Markdown canonical statement",
|
|
2110
|
+
"source provenance"
|
|
2111
|
+
],
|
|
2112
|
+
allowedWrites: ["configured Portal output directory only"],
|
|
2113
|
+
reportSections: [
|
|
2114
|
+
"Output path",
|
|
2115
|
+
"Page count",
|
|
2116
|
+
"Diagrams/assets",
|
|
2117
|
+
"Source docs reviewed",
|
|
2118
|
+
"Skipped/ambiguous docs",
|
|
2119
|
+
"Validation",
|
|
2120
|
+
"Markdown canonical statement"
|
|
2121
|
+
]
|
|
1973
2122
|
}
|
|
1974
2123
|
};
|
|
1975
2124
|
var TRUTHMARK_WORKFLOW_IDS = Object.keys(
|
|
@@ -2000,7 +2149,7 @@ Fixes suggested:
|
|
|
2000
2149
|
${renderAuditEvidenceCheckedSection([
|
|
2001
2150
|
{
|
|
2002
2151
|
finding: "The root route index is present and maps repository truth owners.",
|
|
2003
|
-
evidence: [
|
|
2152
|
+
evidence: [`${rootRouteIndex}:1`],
|
|
2004
2153
|
suggestedFix: "none",
|
|
2005
2154
|
confidence: "high"
|
|
2006
2155
|
}
|
|
@@ -2052,11 +2201,11 @@ Invocations: ${TRUTH_CHECK_EXPLICIT_INVOCATIONS}
|
|
|
2052
2201
|
|
|
2053
2202
|
Truth Check is agent-led:
|
|
2054
2203
|
|
|
2055
|
-
- inspect .truthmark/config.yml
|
|
2204
|
+
- inspect .truthmark/config.yml and configured route files only when they exist; then inspect canonical docs and relevant implementation directly
|
|
2056
2205
|
- ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
|
|
2057
|
-
- inspect the configured root route index at ${config.docs.routing.rootIndex} and relevant child route files under ${config.docs.routing.areaFilesRoot}/
|
|
2206
|
+
- inspect the configured root route index at ${config.docs.routing.rootIndex} and relevant child route files under ${config.docs.routing.areaFilesRoot}/ when they exist
|
|
2058
2207
|
- check that current docs describe current code rather than historical plans
|
|
2059
|
-
- check that
|
|
2208
|
+
- check that route files map code surfaces to canonical truth docs when route files exist
|
|
2060
2209
|
- check for broad, catch-all, index-like, or mixed-owner truth docs and report them as topology issues requiring Truth Structure
|
|
2061
2210
|
- check that canonical behavior docs keep active Product Decisions and Rationale sections
|
|
2062
2211
|
- optionally run truthmark check when local tooling is available
|
|
@@ -2161,7 +2310,7 @@ Invocations: ${TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS}
|
|
|
2161
2310
|
Truth Document is manual and implementation-first:
|
|
2162
2311
|
|
|
2163
2312
|
- run only when the user explicitly asks to generate or update truth docs for existing behavior, or when Truth Sync, Truth Check, or Truth Structure reports implemented behavior that lacks canonical truth docs
|
|
2164
|
-
- inspect .truthmark/config.yml
|
|
2313
|
+
- inspect .truthmark/config.yml and configured route files only when they exist; then inspect existing canonical docs, implementation code, and tests directly
|
|
2165
2314
|
- ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
|
|
2166
2315
|
- document current implemented behavior; do not invent future behavior or planned endpoints
|
|
2167
2316
|
- may write canonical truth docs and ${config.docs.routing.rootIndex} or relevant child route files only
|
|
@@ -2270,9 +2419,9 @@ Purpose:
|
|
|
2270
2419
|
- keep the selector thin so agents can avoid loading or acting through heavier workflows prematurely
|
|
2271
2420
|
|
|
2272
2421
|
Read:
|
|
2273
|
-
- .truthmark/config.yml
|
|
2274
|
-
- ${config.docs.routing.rootIndex}
|
|
2275
|
-
- relevant child route files under ${config.docs.routing.areaFilesRoot}
|
|
2422
|
+
- .truthmark/config.yml, only when present
|
|
2423
|
+
- ${config.docs.routing.rootIndex}, only when present
|
|
2424
|
+
- relevant child route files under ${config.docs.routing.areaFilesRoot}/, only when present
|
|
2276
2425
|
- relevant truth docs and implementation files needed to preview ownership
|
|
2277
2426
|
- ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
|
|
2278
2427
|
|
|
@@ -2297,6 +2446,82 @@ Report completion in this shape:
|
|
|
2297
2446
|
${renderMarkdownExample3(renderTruthPreviewReportExample(config))}`;
|
|
2298
2447
|
};
|
|
2299
2448
|
|
|
2449
|
+
// src/agents/truthmark-portal.ts
|
|
2450
|
+
var TRUTHMARK_PORTAL_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-portal; Codex /truthmark-portal or $truthmark-portal; Claude Code /truthmark-portal; GitHub Copilot /truthmark-portal; Gemini CLI /truthmark:portal.";
|
|
2451
|
+
var renderTruthmarkPortalSkillBody = (config = defaultAgentConfig()) => {
|
|
2452
|
+
const workflow = getTruthmarkWorkflow("truthmark-portal");
|
|
2453
|
+
const output = config.truthmarkPortal.output;
|
|
2454
|
+
const template = config.truthmarkPortal.template;
|
|
2455
|
+
return `---
|
|
2456
|
+
name: truthmark-portal
|
|
2457
|
+
description: ${workflow.description}
|
|
2458
|
+
argument-hint: Optional output path, template, or portal generation focus
|
|
2459
|
+
user-invocable: true
|
|
2460
|
+
truthmark-version: ${TRUTHMARK_VERSION}
|
|
2461
|
+
---
|
|
2462
|
+
|
|
2463
|
+
# Truthmark Portal
|
|
2464
|
+
|
|
2465
|
+
Truthmark Portal is a manual-only presentation workflow. It is never a completion gate, never Truth Sync, and runs only when the user explicitly asks to generate, refresh, or update the committed static HTML Portal.
|
|
2466
|
+
|
|
2467
|
+
Invocations: ${TRUTHMARK_PORTAL_EXPLICIT_INVOCATIONS}
|
|
2468
|
+
|
|
2469
|
+
Core rules:
|
|
2470
|
+
|
|
2471
|
+
- Markdown remains canonical; generated HTML is presentation only.
|
|
2472
|
+
- Read Markdown directly from the checkout; the workflow does not require the truthmark CLI or package.
|
|
2473
|
+
- truthmark check/index may be used only as optional supporting evidence when available.
|
|
2474
|
+
- Default output is docs/truthmark-portal; configured output is ${output}.
|
|
2475
|
+
- Configured template is ${template}; use default built-in template instructions when the template is default.
|
|
2476
|
+
- The workflow may replace the entire output directory, but writes are limited to the configured Portal output directory only unless the user changes scope.
|
|
2477
|
+
- Portal writes are generated non-canonical static files for human browsing.
|
|
2478
|
+
- Generate a committed multi-page static HTML site with local CSS, JavaScript, assets, and search metadata under the output directory.
|
|
2479
|
+
- Use no remote dependencies by default: no remote scripts, analytics, fonts, CSS, or CDN assets.
|
|
2480
|
+
- Include source provenance and the Markdown canonical disclaimer on every page.
|
|
2481
|
+
- Store manifest and search data under output/assets only.
|
|
2482
|
+
- There is no .truthmark/index.json dependency; do not require or create it as infrastructure.
|
|
2483
|
+
- Pictures and screenshots require an explicit user or template request.
|
|
2484
|
+
|
|
2485
|
+
Workflow:
|
|
2486
|
+
|
|
2487
|
+
1. Confirm the user explicitly requested Portal generation or refresh.
|
|
2488
|
+
2. Inspect .truthmark/config.yml and configured route docs only when they exist; read repository instruction files when present, truth docs, architecture docs, standards docs, and the configured Portal template when it is a repo-relative file.
|
|
2489
|
+
3. Validate the selected output path is repo-relative, non-empty, inside the repository, and does not overlap canonical docs, source roots, routing files, or instruction targets.
|
|
2490
|
+
4. Plan the generated page inventory, diagrams/assets, source docs reviewed, and skipped or ambiguous docs.
|
|
2491
|
+
5. Replace or write only under ${output}; do not edit canonical Markdown, routing, source code, or instruction files unless the user explicitly changes scope.
|
|
2492
|
+
6. Generate the multi-page static site with local assets/search metadata and visible source provenance.
|
|
2493
|
+
7. Validate entry page, links where practical, provenance/disclaimers, local-only assets, and that metadata remains under ${output}/assets.
|
|
2494
|
+
${renderHierarchySummary(config)}
|
|
2495
|
+
|
|
2496
|
+
Report completion in this shape:
|
|
2497
|
+
|
|
2498
|
+
\`\`\`md
|
|
2499
|
+
Truthmark Portal: completed
|
|
2500
|
+
|
|
2501
|
+
Output path:
|
|
2502
|
+
- ${output}
|
|
2503
|
+
|
|
2504
|
+
Page count:
|
|
2505
|
+
- <count>
|
|
2506
|
+
|
|
2507
|
+
Diagrams/assets:
|
|
2508
|
+
- <generated diagrams/assets or none>
|
|
2509
|
+
|
|
2510
|
+
Source docs reviewed:
|
|
2511
|
+
- <source markdown paths>
|
|
2512
|
+
|
|
2513
|
+
Skipped/ambiguous docs:
|
|
2514
|
+
- <paths and reason, or none>
|
|
2515
|
+
|
|
2516
|
+
Validation:
|
|
2517
|
+
- <checks performed>
|
|
2518
|
+
|
|
2519
|
+
Markdown canonical statement:
|
|
2520
|
+
- Markdown remains canonical; generated Portal HTML is non-canonical presentation only.
|
|
2521
|
+
\`\`\`
|
|
2522
|
+
`;
|
|
2523
|
+
};
|
|
2524
|
+
|
|
2300
2525
|
// src/agents/truth-structure.ts
|
|
2301
2526
|
var renderMarkdownExample4 = (content) => {
|
|
2302
2527
|
return ["```md", content, "```"].join("\n");
|
|
@@ -2361,9 +2586,9 @@ truthmark-version: ${TRUTHMARK_VERSION}
|
|
|
2361
2586
|
Use this skill to design or repair Truthmark area structure.
|
|
2362
2587
|
Invocations: ${TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS}
|
|
2363
2588
|
Truth Structure is agent-native:
|
|
2364
|
-
- inspect repository layout, current docs,
|
|
2589
|
+
- inspect repository layout, current docs, Truthmark config and route files when present, and relevant code directly
|
|
2365
2590
|
- ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
|
|
2366
|
-
- inspect the configured root route index at ${config.docs.routing.rootIndex} and relevant child route files under ${config.docs.routing.areaFilesRoot}/
|
|
2591
|
+
- inspect the configured root route index at ${config.docs.routing.rootIndex} and relevant child route files under ${config.docs.routing.areaFilesRoot}/ when they exist
|
|
2367
2592
|
- define areas by product or behavior ownership, not by mechanical directory mirroring
|
|
2368
2593
|
- create or repair ${config.docs.routing.rootIndex}
|
|
2369
2594
|
- create starter truth docs when useful and when they belong in the canonical current-truth surface
|
|
@@ -2434,7 +2659,7 @@ ${ARCHITECTURE_DOC_BOUNDARY_INSTRUCTIONS}
|
|
|
2434
2659
|
Portable fallback:
|
|
2435
2660
|
- If this skill surface is unavailable, perform the same workflow directly from committed repository files.
|
|
2436
2661
|
- Do not require the truthmark CLI.
|
|
2437
|
-
-
|
|
2662
|
+
- Inspect .truthmark/config.yml and configured route files only when they exist; then inspect canonical docs and representative implementation code.
|
|
2438
2663
|
- Use a subagent only when the host supports that pattern; otherwise perform the topology repair inline.
|
|
2439
2664
|
${renderHierarchySummary(config)}
|
|
2440
2665
|
${DECISION_TRUTH_INSTRUCTIONS}
|
|
@@ -2599,7 +2824,7 @@ Explicit invocation runs immediately. Later functional-code changes reopen the f
|
|
|
2599
2824
|
Skip when changes are documentation-only, formatting-only, clearly behavior-preserving renames with no truth impact, when no Truthmark config exists yet, or when there are no functional code changes.
|
|
2600
2825
|
Parent workflow:
|
|
2601
2826
|
1. Inspect git status, staged changes, unstaged changes, and untracked files directly.
|
|
2602
|
-
2.
|
|
2827
|
+
2. Inspect .truthmark/config.yml and configured route files only when they exist; then inspect relevant canonical docs.
|
|
2603
2828
|
3. Identify functional-code changes and the nearest truth docs or routing repairs.
|
|
2604
2829
|
4. ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
|
|
2605
2830
|
5. Code verification is parent-owned: follow repository instructions and task context, and report what ran or why it did not run.
|
|
@@ -2706,6 +2931,8 @@ var TRUTHMARK_CHECK_SKILL_PATH = ".codex/skills/truthmark-check/SKILL.md";
|
|
|
2706
2931
|
var TRUTHMARK_CHECK_SKILL_METADATA_PATH = ".codex/skills/truthmark-check/agents/openai.yaml";
|
|
2707
2932
|
var TRUTHMARK_PREVIEW_SKILL_PATH = ".codex/skills/truthmark-preview/SKILL.md";
|
|
2708
2933
|
var TRUTHMARK_PREVIEW_SKILL_METADATA_PATH = ".codex/skills/truthmark-preview/agents/openai.yaml";
|
|
2934
|
+
var TRUTHMARK_PORTAL_SKILL_PATH = ".codex/skills/truthmark-portal/SKILL.md";
|
|
2935
|
+
var TRUTHMARK_PORTAL_SKILL_METADATA_PATH = ".codex/skills/truthmark-portal/agents/openai.yaml";
|
|
2709
2936
|
var TRUTHMARK_ROUTE_AUDITOR_AGENT_PATH = ".codex/agents/truth-route-auditor.toml";
|
|
2710
2937
|
var TRUTHMARK_CLAIM_VERIFIER_AGENT_PATH = ".codex/agents/truth-claim-verifier.toml";
|
|
2711
2938
|
var TRUTHMARK_DOC_REVIEWER_AGENT_PATH = ".codex/agents/truth-doc-reviewer.toml";
|
|
@@ -2724,6 +2951,7 @@ var TRUTHMARK_GEMINI_SYNC_COMMAND_PATH = ".gemini/commands/truthmark/sync.toml";
|
|
|
2724
2951
|
var TRUTHMARK_GEMINI_REALIZE_COMMAND_PATH = ".gemini/commands/truthmark/realize.toml";
|
|
2725
2952
|
var TRUTHMARK_GEMINI_CHECK_COMMAND_PATH = ".gemini/commands/truthmark/check.toml";
|
|
2726
2953
|
var TRUTHMARK_GEMINI_PREVIEW_COMMAND_PATH = ".gemini/commands/truthmark/preview.toml";
|
|
2954
|
+
var TRUTHMARK_GEMINI_PORTAL_COMMAND_PATH = ".gemini/commands/truthmark/portal.toml";
|
|
2727
2955
|
var TRUTHMARK_GEMINI_ROUTE_AUDITOR_AGENT_PATH = ".gemini/agents/truth-route-auditor.md";
|
|
2728
2956
|
var TRUTHMARK_GEMINI_CLAIM_VERIFIER_AGENT_PATH = ".gemini/agents/truth-claim-verifier.md";
|
|
2729
2957
|
var TRUTHMARK_GEMINI_DOC_REVIEWER_AGENT_PATH = ".gemini/agents/truth-doc-reviewer.md";
|
|
@@ -2734,6 +2962,7 @@ var TRUTHMARK_COPILOT_SYNC_PROMPT_PATH = ".github/prompts/truthmark-sync.prompt.
|
|
|
2734
2962
|
var TRUTHMARK_COPILOT_REALIZE_PROMPT_PATH = ".github/prompts/truthmark-realize.prompt.md";
|
|
2735
2963
|
var TRUTHMARK_COPILOT_CHECK_PROMPT_PATH = ".github/prompts/truthmark-check.prompt.md";
|
|
2736
2964
|
var TRUTHMARK_COPILOT_PREVIEW_PROMPT_PATH = ".github/prompts/truthmark-preview.prompt.md";
|
|
2965
|
+
var TRUTHMARK_COPILOT_PORTAL_PROMPT_PATH = ".github/prompts/truthmark-portal.prompt.md";
|
|
2737
2966
|
var TRUTHMARK_COPILOT_ROUTE_AUDITOR_AGENT_PATH = ".github/agents/truth-route-auditor.agent.md";
|
|
2738
2967
|
var TRUTHMARK_COPILOT_CLAIM_VERIFIER_AGENT_PATH = ".github/agents/truth-claim-verifier.agent.md";
|
|
2739
2968
|
var TRUTHMARK_COPILOT_DOC_REVIEWER_AGENT_PATH = ".github/agents/truth-doc-reviewer.agent.md";
|
|
@@ -2763,6 +2992,7 @@ var renderTomlStringArray = (values) => {
|
|
|
2763
2992
|
return `[${values.map(renderTomlString).join(", ")}]`;
|
|
2764
2993
|
};
|
|
2765
2994
|
var TRUTH_REALIZE_EXPLICIT_INVOCATIONS = "OpenCode /skill truthmark-realize; Codex /truthmark-realize or $truthmark-realize; Claude Code /truthmark-realize; GitHub Copilot /truthmark-realize; Gemini CLI /truthmark:realize.";
|
|
2995
|
+
var routeFilesHint = (config) => `${config.docs.routing.rootIndex}; ${config.docs.routing.areaFilesRoot}/`;
|
|
2766
2996
|
var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
2767
2997
|
"truthmark-structure": {
|
|
2768
2998
|
title: "Truthmark Structure",
|
|
@@ -2770,8 +3000,8 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
|
2770
3000
|
invocations: TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS,
|
|
2771
3001
|
use: () => "Use this skill to design or repair Truthmark area structure.",
|
|
2772
3002
|
quickRules: (config) => [
|
|
2773
|
-
"Follow
|
|
2774
|
-
`
|
|
3003
|
+
"Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
|
|
3004
|
+
`Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect current docs and relevant code directly.`,
|
|
2775
3005
|
"Define areas by product or behavior ownership, not by mechanical directory mirroring.",
|
|
2776
3006
|
"Do not edit functional code.",
|
|
2777
3007
|
"Read support/procedure.md before writing route or starter truth-doc changes.",
|
|
@@ -2785,8 +3015,8 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
|
2785
3015
|
invocations: TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS,
|
|
2786
3016
|
use: () => "Use this skill to document existing implemented behavior when no functional-code changes are required for the task.",
|
|
2787
3017
|
quickRules: (config) => [
|
|
2788
|
-
"Follow
|
|
2789
|
-
`
|
|
3018
|
+
"Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
|
|
3019
|
+
`Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect existing canonical docs, implementation code, and tests directly.`,
|
|
2790
3020
|
"Document current implemented behavior; do not invent future behavior.",
|
|
2791
3021
|
"May write canonical truth docs and truth routing files only; must not write functional code.",
|
|
2792
3022
|
"Read support/procedure.md before editing truth docs.",
|
|
@@ -2801,9 +3031,9 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
|
2801
3031
|
invocations: TRUTH_SYNC_EXPLICIT_INVOCATIONS,
|
|
2802
3032
|
use: () => "Use this skill automatically before finishing when functional code changed since the last successful Truth Sync. Also run it immediately when the user explicitly invokes Truth Sync.",
|
|
2803
3033
|
quickRules: (config) => [
|
|
2804
|
-
"Follow
|
|
3034
|
+
"Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
|
|
2805
3035
|
"Skip docs-only, formatting-only, behavior-preserving renames with no truth impact, missing config, and no-code changes.",
|
|
2806
|
-
`
|
|
3036
|
+
`Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect relevant canonical docs directly.`,
|
|
2807
3037
|
"direct checkout inspection is the canonical path; do not require the truthmark binary.",
|
|
2808
3038
|
"May write canonical truth docs and truth routing files only; must not rewrite functional code.",
|
|
2809
3039
|
"Read support/procedure.md before editing truth docs.",
|
|
@@ -2818,8 +3048,8 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
|
2818
3048
|
invocations: TRUTH_PREVIEW_EXPLICIT_INVOCATIONS,
|
|
2819
3049
|
use: () => "Use this skill only when the user explicitly asks to preview Truthmark routing or workflow choice before edits.",
|
|
2820
3050
|
quickRules: (config) => [
|
|
2821
|
-
"Follow
|
|
2822
|
-
`
|
|
3051
|
+
"Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
|
|
3052
|
+
`Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect only the truth docs or implementation files needed to preview ownership.`,
|
|
2823
3053
|
"Truth Preview is read-only; this report is intended, not authorized.",
|
|
2824
3054
|
"must not edit files and must not issue write leases; do not run Truth Sync automatically, replace Truth Check, claim final correctness, or mutate code.",
|
|
2825
3055
|
"Use optional read-only route-auditor evidence only when it reduces context or clarifies ownership.",
|
|
@@ -2833,8 +3063,8 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
|
2833
3063
|
invocations: TRUTH_REALIZE_EXPLICIT_INVOCATIONS,
|
|
2834
3064
|
use: () => "Use this skill only when the user explicitly asks to realize truth docs into code.",
|
|
2835
3065
|
quickRules: (config) => [
|
|
2836
|
-
"Follow
|
|
2837
|
-
`Read the source truth docs, .truthmark/config.yml
|
|
3066
|
+
"Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
|
|
3067
|
+
`Read the source truth docs, inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist, then inspect tests and relevant functional code directly.`,
|
|
2838
3068
|
"Truth docs lead; code follows.",
|
|
2839
3069
|
"may write functional code only; must not edit truth docs or truth routing while realizing those docs.",
|
|
2840
3070
|
"Read support/procedure.md before changing code.",
|
|
@@ -2847,8 +3077,8 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
|
2847
3077
|
invocations: TRUTH_CHECK_EXPLICIT_INVOCATIONS,
|
|
2848
3078
|
use: () => "Use this skill to audit repository truth health.",
|
|
2849
3079
|
quickRules: (config) => [
|
|
2850
|
-
"Follow
|
|
2851
|
-
`
|
|
3080
|
+
"Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
|
|
3081
|
+
`Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then inspect canonical docs and relevant implementation directly.`,
|
|
2852
3082
|
"Report issues and suggested fixes; do not silently rewrite unrelated files.",
|
|
2853
3083
|
"Direct checkout inspection is valid even when local tooling is unavailable.",
|
|
2854
3084
|
"Read support/procedure.md before auditing details.",
|
|
@@ -2856,6 +3086,24 @@ var WORKFLOW_PACKAGE_DEFINITIONS = {
|
|
|
2856
3086
|
"Read support/report-template.md before the final report."
|
|
2857
3087
|
],
|
|
2858
3088
|
parentRule: "Parent agent owns the final Truth Check report"
|
|
3089
|
+
},
|
|
3090
|
+
"truthmark-portal": {
|
|
3091
|
+
title: "Truthmark Portal",
|
|
3092
|
+
argumentHint: "Optional output path, template, or portal generation focus",
|
|
3093
|
+
invocations: TRUTHMARK_PORTAL_EXPLICIT_INVOCATIONS,
|
|
3094
|
+
use: () => "Use this skill only when the user explicitly asks to generate or refresh the committed static HTML Truthmark Portal.",
|
|
3095
|
+
quickRules: (config) => [
|
|
3096
|
+
"Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists.",
|
|
3097
|
+
"Truthmark Portal is manual-only; never run it as a completion gate and never treat it as Truth Sync.",
|
|
3098
|
+
"Markdown remains canonical; generated HTML is non-canonical presentation only.",
|
|
3099
|
+
"Read Markdown directly; the workflow does not require the truthmark CLI or package.",
|
|
3100
|
+
"Generate committed, generated non-canonical static files for humans.",
|
|
3101
|
+
`Write only under configured Portal output ${config.truthmarkPortal.output}; default output is docs/truthmark-portal.`,
|
|
3102
|
+
`Use configured Portal template ${config.truthmarkPortal.template}; no .truthmark/index.json dependency.`,
|
|
3103
|
+
"Use no remote dependencies by default and include source provenance on every page.",
|
|
3104
|
+
"Read support/procedure.md before generating Portal output.",
|
|
3105
|
+
"Read support/report-template.md before the final report."
|
|
3106
|
+
]
|
|
2859
3107
|
}
|
|
2860
3108
|
};
|
|
2861
3109
|
var stripWorkflowSkillFrontmatter = (body) => {
|
|
@@ -2948,6 +3196,8 @@ var renderStandaloneWorkflowSkillBody = (workflowId, config) => {
|
|
|
2948
3196
|
return renderTruthmarkRealizeSkillBody(config);
|
|
2949
3197
|
case "truthmark-check":
|
|
2950
3198
|
return renderTruthCheckSkillBody(config);
|
|
3199
|
+
case "truthmark-portal":
|
|
3200
|
+
return renderTruthmarkPortalSkillBody(config);
|
|
2951
3201
|
}
|
|
2952
3202
|
};
|
|
2953
3203
|
var renderWorkflowEntrypoint = (workflowId, config, supportFiles, host) => {
|
|
@@ -3086,8 +3336,8 @@ var renderTruthmarkSkillPackage = ({
|
|
|
3086
3336
|
}
|
|
3087
3337
|
return files;
|
|
3088
3338
|
};
|
|
3089
|
-
var normalizeOpenCodePermissionPath = (
|
|
3090
|
-
const normalized =
|
|
3339
|
+
var normalizeOpenCodePermissionPath = (path13) => {
|
|
3340
|
+
const normalized = path13.replace(/\\/gu, "/").replace(/^\.\//u, "").replace(/\/+$/u, "");
|
|
3091
3341
|
return normalized === "" ? "." : normalized;
|
|
3092
3342
|
};
|
|
3093
3343
|
var appendOpenCodePermissionGlob = (root, glob) => {
|
|
@@ -3126,7 +3376,7 @@ var TRUTHMARK_SUBAGENT_PROFILES = {
|
|
|
3126
3376
|
nicknameCandidates: ["Route Audit", "Route Trace", "Route Check"],
|
|
3127
3377
|
instructions: `Stay read-only.
|
|
3128
3378
|
Audit one bounded Truthmark route, area, or doc shard assigned by the parent.
|
|
3129
|
-
|
|
3379
|
+
Inspect .truthmark/config.yml and route files only when they exist; then inspect mapped truth docs and relevant implementation files directly.
|
|
3130
3380
|
Find missing, stale, broad, overloaded, catch-all, mixed-owner, or unrouteable ownership.
|
|
3131
3381
|
Do not edit files, stage changes, or propose broad rewrites.
|
|
3132
3382
|
Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes.
|
|
@@ -3589,8 +3839,8 @@ Truth Realize is doc-first:
|
|
|
3589
3839
|
|
|
3590
3840
|
Workflow:
|
|
3591
3841
|
|
|
3592
|
-
1. Read the updated truth docs named by the user, or infer the relevant docs from
|
|
3593
|
-
2.
|
|
3842
|
+
1. Read the updated truth docs named by the user, or infer the relevant docs from configured route files when present.
|
|
3843
|
+
2. Inspect .truthmark/config.yml and configured route files (${routeFilesHint(config)}) only when they exist; then read tests and the relevant functional code.
|
|
3594
3844
|
3. ${EVIDENCE_AUTHORITY_INSTRUCTIONS}
|
|
3595
3845
|
${renderTruthDocOwnershipGateSection(
|
|
3596
3846
|
"source truth docs before writing code",
|
|
@@ -3664,6 +3914,21 @@ var renderTruthmarkCheckSkillMetadata = () => {
|
|
|
3664
3914
|
policy:
|
|
3665
3915
|
allow_implicit_invocation: ${workflow.allowImplicitInvocation}
|
|
3666
3916
|
|
|
3917
|
+
truthmark:
|
|
3918
|
+
version: "${TRUTHMARK_VERSION}"
|
|
3919
|
+
refresh_command: "truthmark init"
|
|
3920
|
+
`;
|
|
3921
|
+
};
|
|
3922
|
+
var renderTruthmarkPortalSkillMetadata = () => {
|
|
3923
|
+
const workflow = getTruthmarkWorkflow("truthmark-portal");
|
|
3924
|
+
return `interface:
|
|
3925
|
+
display_name: "${workflow.displayName}"
|
|
3926
|
+
short_description: "${workflow.shortDescription}"
|
|
3927
|
+
default_prompt: "${workflow.defaultPrompt}"
|
|
3928
|
+
|
|
3929
|
+
policy:
|
|
3930
|
+
allow_implicit_invocation: ${workflow.allowImplicitInvocation}
|
|
3931
|
+
|
|
3667
3932
|
truthmark:
|
|
3668
3933
|
version: "${TRUTHMARK_VERSION}"
|
|
3669
3934
|
refresh_command: "truthmark init"
|
|
@@ -3711,6 +3976,13 @@ var renderTruthmarkGeminiPreviewCommand = (config = defaultAgentConfig()) => {
|
|
|
3711
3976
|
renderTruthPreviewSkillBody(config)
|
|
3712
3977
|
);
|
|
3713
3978
|
};
|
|
3979
|
+
var renderTruthmarkGeminiPortalCommand = (config = defaultAgentConfig()) => {
|
|
3980
|
+
const workflow = getTruthmarkWorkflow("truthmark-portal");
|
|
3981
|
+
return renderGeminiCommand(
|
|
3982
|
+
workflow.description,
|
|
3983
|
+
renderTruthmarkPortalSkillBody(config)
|
|
3984
|
+
);
|
|
3985
|
+
};
|
|
3714
3986
|
var renderTruthmarkCopilotStructurePrompt = (config = defaultAgentConfig()) => {
|
|
3715
3987
|
const workflow = getTruthmarkWorkflow("truthmark-structure");
|
|
3716
3988
|
return renderCopilotPromptFile(
|
|
@@ -3761,6 +4033,13 @@ var renderTruthmarkCopilotPreviewPrompt = (config = defaultAgentConfig()) => {
|
|
|
3761
4033
|
renderTruthPreviewSkillBody(config)
|
|
3762
4034
|
);
|
|
3763
4035
|
};
|
|
4036
|
+
var renderTruthmarkCopilotPortalPrompt = (config = defaultAgentConfig()) => {
|
|
4037
|
+
const workflow = getTruthmarkWorkflow("truthmark-portal");
|
|
4038
|
+
return renderCopilotPromptFile(
|
|
4039
|
+
workflow.description,
|
|
4040
|
+
renderTruthmarkPortalSkillBody(config)
|
|
4041
|
+
);
|
|
4042
|
+
};
|
|
3764
4043
|
|
|
3765
4044
|
// src/templates/generated-surfaces.ts
|
|
3766
4045
|
var codexFiles = (config) => {
|
|
@@ -3842,10 +4121,24 @@ var codexFiles = (config) => {
|
|
|
3842
4121
|
content: renderTruthmarkDocWriterAgent()
|
|
3843
4122
|
}
|
|
3844
4123
|
];
|
|
4124
|
+
if (config.truthmarkPortal.enabled) {
|
|
4125
|
+
files.push(
|
|
4126
|
+
...renderTruthmarkSkillPackage({
|
|
4127
|
+
skillPath: TRUTHMARK_PORTAL_SKILL_PATH,
|
|
4128
|
+
workflowId: "truthmark-portal",
|
|
4129
|
+
host: "codex",
|
|
4130
|
+
config
|
|
4131
|
+
}),
|
|
4132
|
+
{
|
|
4133
|
+
path: TRUTHMARK_PORTAL_SKILL_METADATA_PATH,
|
|
4134
|
+
content: renderTruthmarkPortalSkillMetadata()
|
|
4135
|
+
}
|
|
4136
|
+
);
|
|
4137
|
+
}
|
|
3845
4138
|
return files;
|
|
3846
4139
|
};
|
|
3847
4140
|
var opencodeFiles = (config) => {
|
|
3848
|
-
|
|
4141
|
+
const files = [
|
|
3849
4142
|
...renderTruthmarkSkillPackage({
|
|
3850
4143
|
skillPath: ".opencode/skills/truthmark-structure/SKILL.md",
|
|
3851
4144
|
workflowId: "truthmark-structure",
|
|
@@ -3899,9 +4192,20 @@ var opencodeFiles = (config) => {
|
|
|
3899
4192
|
content: renderTruthmarkOpenCodeDocWriterAgent(config)
|
|
3900
4193
|
}
|
|
3901
4194
|
];
|
|
4195
|
+
if (config.truthmarkPortal.enabled) {
|
|
4196
|
+
files.push(
|
|
4197
|
+
...renderTruthmarkSkillPackage({
|
|
4198
|
+
skillPath: ".opencode/skills/truthmark-portal/SKILL.md",
|
|
4199
|
+
workflowId: "truthmark-portal",
|
|
4200
|
+
host: "opencode",
|
|
4201
|
+
config
|
|
4202
|
+
})
|
|
4203
|
+
);
|
|
4204
|
+
}
|
|
4205
|
+
return files;
|
|
3902
4206
|
};
|
|
3903
4207
|
var claudeFiles = (config, block) => {
|
|
3904
|
-
|
|
4208
|
+
const files = [
|
|
3905
4209
|
...instructionBlockFiles(["CLAUDE.md"], block),
|
|
3906
4210
|
...renderTruthmarkSkillPackage({
|
|
3907
4211
|
skillPath: ".claude/skills/truthmark-structure/SKILL.md",
|
|
@@ -3956,6 +4260,17 @@ var claudeFiles = (config, block) => {
|
|
|
3956
4260
|
content: renderTruthmarkClaudeDocWriterAgent()
|
|
3957
4261
|
}
|
|
3958
4262
|
];
|
|
4263
|
+
if (config.truthmarkPortal.enabled) {
|
|
4264
|
+
files.push(
|
|
4265
|
+
...renderTruthmarkSkillPackage({
|
|
4266
|
+
skillPath: ".claude/skills/truthmark-portal/SKILL.md",
|
|
4267
|
+
workflowId: "truthmark-portal",
|
|
4268
|
+
host: "claude-code",
|
|
4269
|
+
config
|
|
4270
|
+
})
|
|
4271
|
+
);
|
|
4272
|
+
}
|
|
4273
|
+
return files;
|
|
3959
4274
|
};
|
|
3960
4275
|
var copilotFiles = (config, block) => {
|
|
3961
4276
|
const files = [
|
|
@@ -4037,10 +4352,24 @@ var copilotFiles = (config, block) => {
|
|
|
4037
4352
|
content: renderTruthmarkCopilotDocWriterAgent()
|
|
4038
4353
|
}
|
|
4039
4354
|
];
|
|
4355
|
+
if (config.truthmarkPortal.enabled) {
|
|
4356
|
+
files.push(
|
|
4357
|
+
...renderTruthmarkSkillPackage({
|
|
4358
|
+
skillPath: ".github/skills/truthmark-portal/SKILL.md",
|
|
4359
|
+
workflowId: "truthmark-portal",
|
|
4360
|
+
host: "github-copilot",
|
|
4361
|
+
config
|
|
4362
|
+
}),
|
|
4363
|
+
{
|
|
4364
|
+
path: TRUTHMARK_COPILOT_PORTAL_PROMPT_PATH,
|
|
4365
|
+
content: renderTruthmarkCopilotPortalPrompt(config)
|
|
4366
|
+
}
|
|
4367
|
+
);
|
|
4368
|
+
}
|
|
4040
4369
|
return files;
|
|
4041
4370
|
};
|
|
4042
4371
|
var geminiFiles = (config, block) => {
|
|
4043
|
-
|
|
4372
|
+
const files = [
|
|
4044
4373
|
...instructionBlockFiles(["GEMINI.md"], block),
|
|
4045
4374
|
...renderTruthmarkSkillPackage({
|
|
4046
4375
|
skillPath: ".gemini/skills/truthmark-structure/SKILL.md",
|
|
@@ -4119,10 +4448,25 @@ var geminiFiles = (config, block) => {
|
|
|
4119
4448
|
content: renderTruthmarkGeminiDocWriterAgent()
|
|
4120
4449
|
}
|
|
4121
4450
|
];
|
|
4451
|
+
if (config.truthmarkPortal.enabled) {
|
|
4452
|
+
files.push(
|
|
4453
|
+
...renderTruthmarkSkillPackage({
|
|
4454
|
+
skillPath: ".gemini/skills/truthmark-portal/SKILL.md",
|
|
4455
|
+
workflowId: "truthmark-portal",
|
|
4456
|
+
host: "gemini-cli",
|
|
4457
|
+
config
|
|
4458
|
+
}),
|
|
4459
|
+
{
|
|
4460
|
+
path: TRUTHMARK_GEMINI_PORTAL_COMMAND_PATH,
|
|
4461
|
+
content: renderTruthmarkGeminiPortalCommand(config)
|
|
4462
|
+
}
|
|
4463
|
+
);
|
|
4464
|
+
}
|
|
4465
|
+
return files;
|
|
4122
4466
|
};
|
|
4123
4467
|
var instructionBlockFiles = (paths, block) => {
|
|
4124
|
-
return paths.map((
|
|
4125
|
-
path:
|
|
4468
|
+
return paths.map((path13) => ({
|
|
4469
|
+
path: path13,
|
|
4126
4470
|
content: block,
|
|
4127
4471
|
managedBlock: true
|
|
4128
4472
|
}));
|
|
@@ -4197,16 +4541,39 @@ var removeTrailingManagedChunk = (preservedLines) => {
|
|
|
4197
4541
|
preservedLines.splice(startIndex);
|
|
4198
4542
|
}
|
|
4199
4543
|
};
|
|
4544
|
+
var LEGACY_REPO_RULES_PATH = ["docs", "ai", `repo-${"rules.md"}`].join("/");
|
|
4545
|
+
var LEGACY_AGENT_ONBOARDING_PATH = ["docs", "ai", `agent-${"onboarding.md"}`].join(
|
|
4546
|
+
"/"
|
|
4547
|
+
);
|
|
4548
|
+
var LEGACY_PRIMARY_REPO_INSTRUCTION_PHRASE = [
|
|
4549
|
+
"primary repository",
|
|
4550
|
+
"instruction source"
|
|
4551
|
+
].join(" ");
|
|
4200
4552
|
var normalizeLegacyInstructionPreamble = (content) => {
|
|
4201
4553
|
return content.replaceAll(
|
|
4202
|
-
|
|
4203
|
-
"
|
|
4554
|
+
`Follow \`${LEGACY_REPO_RULES_PATH}\`.`,
|
|
4555
|
+
"Follow repository instruction files that are present in this checkout; do not assume optional policy docs exist."
|
|
4556
|
+
).replaceAll(
|
|
4557
|
+
`Follow \`${LEGACY_REPO_RULES_PATH}\` as the ${LEGACY_PRIMARY_REPO_INSTRUCTION_PHRASE}.`,
|
|
4558
|
+
"Follow repository instruction files that are present in this checkout; do not assume optional policy docs exist."
|
|
4559
|
+
).replaceAll(
|
|
4560
|
+
`Use that file as the ${LEGACY_PRIMARY_REPO_INSTRUCTION_PHRASE} for Codex.`,
|
|
4561
|
+
"Use explicitly configured repository policy docs only when they exist in this checkout."
|
|
4562
|
+
).replaceAll(
|
|
4563
|
+
`Use that file as the ${LEGACY_PRIMARY_REPO_INSTRUCTION_PHRASE} for this agent.`,
|
|
4564
|
+
"Use explicitly configured repository policy docs only when they exist in this checkout."
|
|
4204
4565
|
).replaceAll("Codex-specific:", "Agent-specific:").replaceAll(
|
|
4205
4566
|
"- Read `docs/README.md` for the canonical docs map.",
|
|
4206
|
-
"- Read
|
|
4567
|
+
"- Read the configured Truthmark routing files when choosing or updating canonical docs."
|
|
4568
|
+
).replaceAll(
|
|
4569
|
+
"- Read `docs/README.md` only when choosing or updating canonical docs.",
|
|
4570
|
+
"- Read the configured Truthmark routing files when choosing or updating canonical docs."
|
|
4207
4571
|
).replaceAll(
|
|
4208
|
-
|
|
4209
|
-
"- Use
|
|
4572
|
+
`- Use \`${LEGACY_AGENT_ONBOARDING_PATH}\` for quick task routing.`,
|
|
4573
|
+
"- Use repository onboarding or docs-map files only when present and needed for unclear or cross-area routing."
|
|
4574
|
+
).replaceAll(
|
|
4575
|
+
`- Use \`${LEGACY_AGENT_ONBOARDING_PATH}\` only when task routing is unclear or cross-area.`,
|
|
4576
|
+
"- Use repository onboarding or docs-map files only when present and needed for unclear or cross-area routing."
|
|
4210
4577
|
);
|
|
4211
4578
|
};
|
|
4212
4579
|
var upsertManagedBlock = (existingContent, block) => {
|
|
@@ -4267,48 +4634,36 @@ var upsertManagedBlock = (existingContent, block) => {
|
|
|
4267
4634
|
|
|
4268
4635
|
${block}`;
|
|
4269
4636
|
};
|
|
4270
|
-
var writeManagedAgentsFile = async (rootDir,
|
|
4637
|
+
var writeManagedAgentsFile = async (rootDir, path13 = "AGENTS.md", block) => {
|
|
4271
4638
|
let existingContent = null;
|
|
4272
4639
|
try {
|
|
4273
|
-
existingContent = await fs7.readFile(resolveRepoPath(rootDir,
|
|
4640
|
+
existingContent = await fs7.readFile(resolveRepoPath(rootDir, path13), "utf8");
|
|
4274
4641
|
} catch (error) {
|
|
4275
4642
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
4276
4643
|
throw error;
|
|
4277
4644
|
}
|
|
4278
4645
|
}
|
|
4279
|
-
return writeRepoFile(rootDir,
|
|
4646
|
+
return writeRepoFile(rootDir, path13, upsertManagedBlock(existingContent, block));
|
|
4280
4647
|
};
|
|
4281
4648
|
var diagnosticCategoryForPath = (filePath, config) => {
|
|
4282
4649
|
if (filePath === "AGENTS.md") {
|
|
4283
4650
|
return "truth-sync";
|
|
4284
4651
|
}
|
|
4285
|
-
if (filePath === "
|
|
4286
|
-
return "
|
|
4287
|
-
}
|
|
4288
|
-
if (filePath.startsWith(".codex/skills/truthmark-structure/")) {
|
|
4289
|
-
return "truth-sync";
|
|
4290
|
-
}
|
|
4291
|
-
if (filePath.startsWith(".codex/skills/truthmark-document/")) {
|
|
4292
|
-
return "truth-sync";
|
|
4652
|
+
if (filePath === ".github/prompts/truthmark-realize.prompt.md" || filePath.startsWith(".github/skills/truthmark-realize/") || filePath.startsWith(".claude/skills/truthmark-realize/") || filePath.startsWith(".opencode/skills/truthmark-realize/") || filePath.startsWith(".codex/skills/truthmark-realize/") || filePath.startsWith(".gemini/skills/truthmark-realize/")) {
|
|
4653
|
+
return "realization";
|
|
4293
4654
|
}
|
|
4294
|
-
if (filePath.startsWith(".
|
|
4655
|
+
if (filePath === "CLAUDE.md" || filePath === "GEMINI.md" || filePath === ".github/copilot-instructions.md" || filePath.startsWith(".github/prompts/truthmark-") || filePath.startsWith(".github/agents/truth-") || filePath.startsWith(".github/skills/truthmark-") || filePath.startsWith(".claude/agents/truth-") || filePath.startsWith(".claude/skills/truthmark-") || filePath.startsWith(".opencode/skills/truthmark-") || filePath.startsWith(".opencode/agents/") || filePath.startsWith(".codex/agents/") || filePath.startsWith(".gemini/agents/truth-") || filePath.startsWith(".gemini/skills/truthmark-")) {
|
|
4295
4656
|
return "truth-sync";
|
|
4296
4657
|
}
|
|
4297
|
-
if (filePath.startsWith(".codex/skills/truthmark-
|
|
4658
|
+
if (filePath.startsWith(".codex/skills/truthmark-")) {
|
|
4298
4659
|
return "truth-sync";
|
|
4299
4660
|
}
|
|
4300
|
-
if (filePath.startsWith(".codex/skills/truthmark-realize/")) {
|
|
4301
|
-
return "realization";
|
|
4302
|
-
}
|
|
4303
4661
|
if (filePath.startsWith(".gemini/commands/truthmark/realize")) {
|
|
4304
4662
|
return "realization";
|
|
4305
4663
|
}
|
|
4306
4664
|
if (filePath.startsWith(".gemini/commands/truthmark/")) {
|
|
4307
4665
|
return "truth-sync";
|
|
4308
4666
|
}
|
|
4309
|
-
if (filePath.startsWith(".codex/skills/truthmark-check/")) {
|
|
4310
|
-
return "truth-sync";
|
|
4311
|
-
}
|
|
4312
4667
|
if (filePath === config.docs.routing.rootIndex) {
|
|
4313
4668
|
return "authority";
|
|
4314
4669
|
}
|
|
@@ -4665,7 +5020,7 @@ var checkFrontmatter = async (rootDir, config, markdownPaths, truthDocumentEntri
|
|
|
4665
5020
|
|
|
4666
5021
|
// src/checks/links.ts
|
|
4667
5022
|
import fs11 from "fs/promises";
|
|
4668
|
-
import
|
|
5023
|
+
import path5 from "path";
|
|
4669
5024
|
var pathExists2 = async (absolutePath) => {
|
|
4670
5025
|
try {
|
|
4671
5026
|
await fs11.stat(absolutePath);
|
|
@@ -4699,7 +5054,7 @@ var checkLinks = async (rootDir, markdownPaths) => {
|
|
|
4699
5054
|
if (targetPath.length === 0) {
|
|
4700
5055
|
continue;
|
|
4701
5056
|
}
|
|
4702
|
-
const absoluteTarget =
|
|
5057
|
+
const absoluteTarget = path5.resolve(path5.dirname(absolutePath), targetPath);
|
|
4703
5058
|
const relativeTarget = toRepoRelativePath(rootDir, absoluteTarget);
|
|
4704
5059
|
try {
|
|
4705
5060
|
await assertRepoContainment(rootDir, absoluteTarget);
|
|
@@ -5571,16 +5926,16 @@ var checkGeneratedSurfaces = async (rootDir, config) => {
|
|
|
5571
5926
|
};
|
|
5572
5927
|
|
|
5573
5928
|
// src/impact/build.ts
|
|
5574
|
-
import
|
|
5929
|
+
import path10 from "path";
|
|
5575
5930
|
import micromatch7 from "micromatch";
|
|
5576
5931
|
|
|
5577
5932
|
// src/repo-index/build.ts
|
|
5578
5933
|
import fs18 from "fs/promises";
|
|
5579
|
-
import
|
|
5934
|
+
import path8 from "path";
|
|
5580
5935
|
|
|
5581
5936
|
// src/repo-index/file-tree.ts
|
|
5582
5937
|
import fs16 from "fs/promises";
|
|
5583
|
-
import
|
|
5938
|
+
import path6 from "path";
|
|
5584
5939
|
import { execa as execa2 } from "execa";
|
|
5585
5940
|
import fg6 from "fast-glob";
|
|
5586
5941
|
import matter2 from "gray-matter";
|
|
@@ -5600,10 +5955,10 @@ var languageByExtension = /* @__PURE__ */ new Map([
|
|
|
5600
5955
|
]);
|
|
5601
5956
|
var sourceExtensions = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
5602
5957
|
var isJavaScriptLikePath = (filePath) => {
|
|
5603
|
-
return sourceExtensions.has(
|
|
5958
|
+
return sourceExtensions.has(path6.posix.extname(filePath));
|
|
5604
5959
|
};
|
|
5605
5960
|
var isTestPath = (filePath) => {
|
|
5606
|
-
return filePath.startsWith("tests/") || filePath.includes("/__tests__/") || /(?:^|[./-])(test|spec)\.[cm]?[jt]sx?$/u.test(
|
|
5961
|
+
return filePath.startsWith("tests/") || filePath.includes("/__tests__/") || /(?:^|[./-])(test|spec)\.[cm]?[jt]sx?$/u.test(path6.posix.basename(filePath));
|
|
5607
5962
|
};
|
|
5608
5963
|
var fileKind = (filePath, ignore) => {
|
|
5609
5964
|
const classification = classifyPath(filePath, ignore);
|
|
@@ -5629,7 +5984,7 @@ var fileKind = (filePath, ignore) => {
|
|
|
5629
5984
|
};
|
|
5630
5985
|
var targetHintsForTest = (filePath) => {
|
|
5631
5986
|
const hints = /* @__PURE__ */ new Set();
|
|
5632
|
-
const basename =
|
|
5987
|
+
const basename = path6.posix.basename(filePath).replace(/\.(test|spec)\.[cm]?[jt]sx?$/u, "");
|
|
5633
5988
|
if (basename.length > 0) {
|
|
5634
5989
|
hints.add(basename);
|
|
5635
5990
|
}
|
|
@@ -5677,7 +6032,7 @@ var discoverRepoFiles = async (rootDir, ignore) => {
|
|
|
5677
6032
|
for (const filePath of discoveredFiles.filter((entry) => !isIgnoredPath(entry, ignore)).sort()) {
|
|
5678
6033
|
let stat;
|
|
5679
6034
|
try {
|
|
5680
|
-
stat = await fs16.stat(
|
|
6035
|
+
stat = await fs16.stat(path6.join(rootDir, filePath));
|
|
5681
6036
|
} catch (error) {
|
|
5682
6037
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
5683
6038
|
continue;
|
|
@@ -5687,7 +6042,7 @@ var discoverRepoFiles = async (rootDir, ignore) => {
|
|
|
5687
6042
|
if (!stat.isFile()) {
|
|
5688
6043
|
continue;
|
|
5689
6044
|
}
|
|
5690
|
-
const extension =
|
|
6045
|
+
const extension = path6.posix.extname(filePath);
|
|
5691
6046
|
const kind = fileKind(filePath, ignore);
|
|
5692
6047
|
files.push({
|
|
5693
6048
|
path: filePath,
|
|
@@ -5701,7 +6056,7 @@ var discoverRepoFiles = async (rootDir, ignore) => {
|
|
|
5701
6056
|
});
|
|
5702
6057
|
}
|
|
5703
6058
|
if (kind === "doc") {
|
|
5704
|
-
const source = await fs16.readFile(
|
|
6059
|
+
const source = await fs16.readFile(path6.join(rootDir, filePath), "utf8");
|
|
5705
6060
|
const parsed = matter2(source);
|
|
5706
6061
|
const markdown = parseMarkdownDocument(parsed.content);
|
|
5707
6062
|
const title = markdown.headings.find((heading) => heading.depth === 1)?.text ?? null;
|
|
@@ -5724,7 +6079,7 @@ var discoverRepoFiles = async (rootDir, ignore) => {
|
|
|
5724
6079
|
|
|
5725
6080
|
// src/repo-index/package-metadata.ts
|
|
5726
6081
|
import fs17 from "fs/promises";
|
|
5727
|
-
import
|
|
6082
|
+
import path7 from "path";
|
|
5728
6083
|
import fg7 from "fast-glob";
|
|
5729
6084
|
var packageManagerFor = async (rootDir, packageDir) => {
|
|
5730
6085
|
const lockfiles = [
|
|
@@ -5736,7 +6091,7 @@ var packageManagerFor = async (rootDir, packageDir) => {
|
|
|
5736
6091
|
];
|
|
5737
6092
|
for (const [lockfile, manager] of lockfiles) {
|
|
5738
6093
|
try {
|
|
5739
|
-
await fs17.access(
|
|
6094
|
+
await fs17.access(path7.join(rootDir, packageDir, lockfile));
|
|
5740
6095
|
return manager;
|
|
5741
6096
|
} catch {
|
|
5742
6097
|
continue;
|
|
@@ -5753,8 +6108,8 @@ var discoverPackageMetadata = async (rootDir) => {
|
|
|
5753
6108
|
});
|
|
5754
6109
|
const packages = [];
|
|
5755
6110
|
for (const packageFile of packageFiles.sort()) {
|
|
5756
|
-
const packageDir =
|
|
5757
|
-
const raw = JSON.parse(await fs17.readFile(
|
|
6111
|
+
const packageDir = path7.posix.dirname(packageFile) === "." ? "" : path7.posix.dirname(packageFile);
|
|
6112
|
+
const raw = JSON.parse(await fs17.readFile(path7.join(rootDir, packageFile), "utf8"));
|
|
5758
6113
|
const scripts = raw.scripts && typeof raw.scripts === "object" ? Object.keys(raw.scripts).sort() : [];
|
|
5759
6114
|
packages.push({
|
|
5760
6115
|
path: packageFile,
|
|
@@ -5813,16 +6168,16 @@ var declarationName = (node) => {
|
|
|
5813
6168
|
}
|
|
5814
6169
|
return node.name.text;
|
|
5815
6170
|
};
|
|
5816
|
-
var addExport = (exports, publicSymbols,
|
|
6171
|
+
var addExport = (exports, publicSymbols, path13, name, kind) => {
|
|
5817
6172
|
if (!name) {
|
|
5818
6173
|
return;
|
|
5819
6174
|
}
|
|
5820
|
-
const entry = { path:
|
|
6175
|
+
const entry = { path: path13, name, kind };
|
|
5821
6176
|
exports.push(entry);
|
|
5822
6177
|
publicSymbols.push(entry);
|
|
5823
6178
|
};
|
|
5824
|
-
var analyzeTypeScriptSource = (
|
|
5825
|
-
const sourceFile = ts.createSourceFile(
|
|
6179
|
+
var analyzeTypeScriptSource = (path13, source) => {
|
|
6180
|
+
const sourceFile = ts.createSourceFile(path13, source, ts.ScriptTarget.Latest, true);
|
|
5826
6181
|
const imports = [];
|
|
5827
6182
|
const exports = [];
|
|
5828
6183
|
const publicSymbols = [];
|
|
@@ -5842,7 +6197,7 @@ var analyzeTypeScriptSource = (path12, source) => {
|
|
|
5842
6197
|
}
|
|
5843
6198
|
}
|
|
5844
6199
|
imports.push({
|
|
5845
|
-
from:
|
|
6200
|
+
from: path13,
|
|
5846
6201
|
specifier: statement.moduleSpecifier.text,
|
|
5847
6202
|
imported: sortStrings(imported)
|
|
5848
6203
|
});
|
|
@@ -5851,34 +6206,34 @@ var analyzeTypeScriptSource = (path12, source) => {
|
|
|
5851
6206
|
if (ts.isExportDeclaration(statement)) {
|
|
5852
6207
|
if (statement.exportClause && ts.isNamedExports(statement.exportClause)) {
|
|
5853
6208
|
for (const element of statement.exportClause.elements) {
|
|
5854
|
-
addExport(exports, publicSymbols,
|
|
6209
|
+
addExport(exports, publicSymbols, path13, element.name.text, "re-export");
|
|
5855
6210
|
}
|
|
5856
6211
|
}
|
|
5857
6212
|
continue;
|
|
5858
6213
|
}
|
|
5859
6214
|
if (ts.isFunctionDeclaration(statement) && hasExportModifier(statement)) {
|
|
5860
|
-
addExport(exports, publicSymbols,
|
|
6215
|
+
addExport(exports, publicSymbols, path13, declarationName(statement), "function");
|
|
5861
6216
|
continue;
|
|
5862
6217
|
}
|
|
5863
6218
|
if (ts.isClassDeclaration(statement) && hasExportModifier(statement)) {
|
|
5864
|
-
addExport(exports, publicSymbols,
|
|
6219
|
+
addExport(exports, publicSymbols, path13, declarationName(statement), "class");
|
|
5865
6220
|
continue;
|
|
5866
6221
|
}
|
|
5867
6222
|
if (ts.isInterfaceDeclaration(statement) && hasExportModifier(statement)) {
|
|
5868
|
-
addExport(exports, publicSymbols,
|
|
6223
|
+
addExport(exports, publicSymbols, path13, declarationName(statement), "interface");
|
|
5869
6224
|
continue;
|
|
5870
6225
|
}
|
|
5871
6226
|
if (ts.isTypeAliasDeclaration(statement) && hasExportModifier(statement)) {
|
|
5872
|
-
addExport(exports, publicSymbols,
|
|
6227
|
+
addExport(exports, publicSymbols, path13, declarationName(statement), "type");
|
|
5873
6228
|
continue;
|
|
5874
6229
|
}
|
|
5875
6230
|
if (ts.isEnumDeclaration(statement) && hasExportModifier(statement)) {
|
|
5876
|
-
addExport(exports, publicSymbols,
|
|
6231
|
+
addExport(exports, publicSymbols, path13, declarationName(statement), "enum");
|
|
5877
6232
|
continue;
|
|
5878
6233
|
}
|
|
5879
6234
|
if (ts.isVariableStatement(statement) && hasExportModifier(statement)) {
|
|
5880
6235
|
for (const declaration of statement.declarationList.declarations) {
|
|
5881
|
-
addExport(exports, publicSymbols,
|
|
6236
|
+
addExport(exports, publicSymbols, path13, declarationName(declaration), "const");
|
|
5882
6237
|
}
|
|
5883
6238
|
}
|
|
5884
6239
|
}
|
|
@@ -5909,7 +6264,7 @@ var buildRepoIndex = async (cwd) => {
|
|
|
5909
6264
|
if (!isJavaScriptLikePath(file.path)) {
|
|
5910
6265
|
continue;
|
|
5911
6266
|
}
|
|
5912
|
-
const source = await fs18.readFile(
|
|
6267
|
+
const source = await fs18.readFile(path8.join(rootDir, file.path), "utf8");
|
|
5913
6268
|
const analysis = analyzeTypeScriptSource(file.path, source);
|
|
5914
6269
|
imports.push(...analysis.imports);
|
|
5915
6270
|
exports.push(...analysis.exports);
|
|
@@ -5941,7 +6296,7 @@ import { execa as execa4 } from "execa";
|
|
|
5941
6296
|
|
|
5942
6297
|
// src/git/changes.ts
|
|
5943
6298
|
import fs19 from "fs/promises";
|
|
5944
|
-
import
|
|
6299
|
+
import path9 from "path";
|
|
5945
6300
|
import { execa as execa3 } from "execa";
|
|
5946
6301
|
var normalizePath3 = (filePath) => {
|
|
5947
6302
|
return filePath.replaceAll("\\", "/").replace(/^\.\//u, "");
|
|
@@ -5996,7 +6351,7 @@ var getUncommittedChanges = async (cwd) => {
|
|
|
5996
6351
|
const deletedPathCandidates = /* @__PURE__ */ new Set([...stagedDeletedPaths, ...unstagedDeletedPaths]);
|
|
5997
6352
|
for (const deletedPath of deletedPathCandidates) {
|
|
5998
6353
|
const change = getOrCreateChange(changesByPath, deletedPath);
|
|
5999
|
-
change.deleted = !await pathExists4(
|
|
6354
|
+
change.deleted = !await pathExists4(path9.join(rootDir, deletedPath));
|
|
6000
6355
|
}
|
|
6001
6356
|
return Array.from(changesByPath.values()).sort((left, right) => {
|
|
6002
6357
|
return left.path.localeCompare(right.path);
|
|
@@ -6117,7 +6472,7 @@ var resolveImportPath = (importEdge) => {
|
|
|
6117
6472
|
if (!importEdge.specifier.startsWith(".")) {
|
|
6118
6473
|
return null;
|
|
6119
6474
|
}
|
|
6120
|
-
const basePath =
|
|
6475
|
+
const basePath = path10.posix.normalize(path10.posix.join(path10.posix.dirname(importEdge.from), importEdge.specifier));
|
|
6121
6476
|
const withoutExtension = basePath.replace(/\.[cm]?[jt]sx?$/u, "");
|
|
6122
6477
|
return withoutExtension;
|
|
6123
6478
|
};
|
|
@@ -6130,7 +6485,7 @@ var importTargetsChangedFile = (importEdge, changedPath) => {
|
|
|
6130
6485
|
};
|
|
6131
6486
|
var pathSegments = (filePath) => filePath.split("/").filter(Boolean);
|
|
6132
6487
|
var testHintMatchesChangedFile = (hints, changedPath) => {
|
|
6133
|
-
const changedBaseName =
|
|
6488
|
+
const changedBaseName = path10.posix.basename(changedPath);
|
|
6134
6489
|
const changedSegments = pathSegments(changedPath);
|
|
6135
6490
|
return hints.some((hint) => changedBaseName.startsWith(hint) || changedSegments.includes(hint));
|
|
6136
6491
|
};
|
|
@@ -6291,7 +6646,7 @@ import fg8 from "fast-glob";
|
|
|
6291
6646
|
|
|
6292
6647
|
// src/evidence/parse.ts
|
|
6293
6648
|
import fs20 from "fs/promises";
|
|
6294
|
-
import
|
|
6649
|
+
import path11 from "path";
|
|
6295
6650
|
import matter3 from "gray-matter";
|
|
6296
6651
|
import { parse as parse3 } from "yaml";
|
|
6297
6652
|
var evidenceBlockPattern = /```ya?ml\s*\n([\s\S]*?)```/giu;
|
|
@@ -6300,9 +6655,9 @@ var normalizeReferencePath = (truthDocPath, referencePath) => {
|
|
|
6300
6655
|
const strippedPath = referencePath.split("#")[0]?.trim() ?? "";
|
|
6301
6656
|
const isRepoRelative = repoRootPrefixes.some((prefix) => strippedPath.startsWith(prefix));
|
|
6302
6657
|
if (!isRepoRelative && (strippedPath.startsWith(".") || !strippedPath.includes("/"))) {
|
|
6303
|
-
return
|
|
6658
|
+
return path11.posix.normalize(path11.posix.join(path11.posix.dirname(truthDocPath), strippedPath));
|
|
6304
6659
|
}
|
|
6305
|
-
return
|
|
6660
|
+
return path11.posix.normalize(strippedPath);
|
|
6306
6661
|
};
|
|
6307
6662
|
var toEvidenceReference = (truthDocPath, raw) => {
|
|
6308
6663
|
if (!raw || typeof raw !== "object" || !("path" in raw) || typeof raw.path !== "string") {
|
|
@@ -6319,7 +6674,7 @@ var toEvidenceReference = (truthDocPath, raw) => {
|
|
|
6319
6674
|
};
|
|
6320
6675
|
};
|
|
6321
6676
|
var parseEvidenceReferences = async (rootDir, truthDocPath) => {
|
|
6322
|
-
const source = await fs20.readFile(
|
|
6677
|
+
const source = await fs20.readFile(path11.join(rootDir, truthDocPath), "utf8");
|
|
6323
6678
|
const parsed = matter3(source);
|
|
6324
6679
|
const references = [];
|
|
6325
6680
|
const sourceOfTruth = Array.isArray(parsed.data.source_of_truth) ? parsed.data.source_of_truth : [];
|
|
@@ -6557,7 +6912,7 @@ var runCheck = async (cwd, options = {}) => {
|
|
|
6557
6912
|
|
|
6558
6913
|
// src/context-pack/build.ts
|
|
6559
6914
|
import fs22 from "fs/promises";
|
|
6560
|
-
import
|
|
6915
|
+
import path12 from "path";
|
|
6561
6916
|
import fg9 from "fast-glob";
|
|
6562
6917
|
var uniqueSorted2 = (values) => [...new Set(values)].sort();
|
|
6563
6918
|
var repoRootPrefixes2 = [".codex/", ".github/", ".truthmark/", "docs/", "src/", "tests/"];
|
|
@@ -6568,12 +6923,12 @@ var normalizeDocReferencePath = (docPath, referencePath) => {
|
|
|
6568
6923
|
return null;
|
|
6569
6924
|
}
|
|
6570
6925
|
const isRepoRelative = repoRootPrefixes2.some((prefix) => strippedPath.startsWith(prefix));
|
|
6571
|
-
const normalized = isRepoRelative ?
|
|
6926
|
+
const normalized = isRepoRelative ? path12.posix.normalize(strippedPath) : path12.posix.normalize(path12.posix.join(path12.posix.dirname(docPath), strippedPath));
|
|
6572
6927
|
return normalized === ".." || normalized.startsWith("../") ? null : normalized;
|
|
6573
6928
|
};
|
|
6574
6929
|
var readIfExists = async (rootDir, filePath) => {
|
|
6575
6930
|
try {
|
|
6576
|
-
return await fs22.readFile(
|
|
6931
|
+
return await fs22.readFile(path12.join(rootDir, filePath), "utf8");
|
|
6577
6932
|
} catch {
|
|
6578
6933
|
return null;
|
|
6579
6934
|
}
|