@triedotdev/mcp 1.0.110 → 1.0.111

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/cli/main.js CHANGED
@@ -1,39 +1,34 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- IncidentIndex,
4
- LearningEngine,
5
3
  LinearIngester,
6
4
  completeBootstrap,
5
+ getSkillCategories,
6
+ initProjectInfo,
7
+ initializeBootstrapFiles,
8
+ loadConfig,
9
+ loadContextState,
10
+ loadProjectInfo,
11
+ needsBootstrap,
12
+ projectInfoExists,
13
+ saveConfig
14
+ } from "../chunk-TKMV7JKN.js";
15
+ import {
16
+ IncidentIndex,
17
+ LearningEngine,
7
18
  exportToJson,
8
19
  formatAuditLog,
9
20
  formatFriendlyError,
10
21
  getAuditStatistics,
11
- getAutonomyConfig,
12
22
  getRecentAuditLogs,
13
23
  getSkillAuditLogs,
14
- getSkillCategories,
15
24
  getStagedChanges,
16
25
  getUncommittedChanges,
17
26
  handleCheckpointCommand,
18
27
  importFromJson,
19
- initProjectInfo,
20
- initializeBootstrapFiles,
21
- loadConfig,
22
- loadContextState,
23
- loadProjectInfo,
24
- needsBootstrap,
28
+ isTrieInitialized,
25
29
  perceiveCurrentChanges,
26
- projectInfoExists,
27
- reasonAboutChangesHumanReadable,
28
- recordBypass,
29
- saveConfig,
30
- shouldAutoFix,
31
- shouldBlockPush,
32
- trackIssueOccurrence
33
- } from "../chunk-FLBK5ILJ.js";
34
- import {
35
- isTrieInitialized
36
- } from "../chunk-HIKONDDO.js";
30
+ reasonAboutChangesHumanReadable
31
+ } from "../chunk-QYOACM2C.js";
37
32
  import {
38
33
  ContextGraph,
39
34
  GotchaPredictor,
@@ -42,7 +37,7 @@ import {
42
37
  listTrackedProjects,
43
38
  searchGlobalPatterns,
44
39
  updateGlobalMemoryMd
45
- } from "../chunk-OTTR5JX4.js";
40
+ } from "../chunk-6QR6QZIX.js";
46
41
  import "../chunk-IXO4G4D3.js";
47
42
  import {
48
43
  getDailyLogs,
@@ -65,7 +60,7 @@ import {
65
60
  } from "../chunk-DGUM43GV.js";
66
61
 
67
62
  // src/cli/main.ts
68
- import { resolve, join as join3, dirname } from "path";
63
+ import { resolve, join as join4, dirname } from "path";
69
64
  import { readFileSync } from "fs";
70
65
  import { fileURLToPath } from "url";
71
66
 
@@ -710,6 +705,274 @@ async function handleCheckCommand(args) {
710
705
  }
711
706
  }
712
707
 
708
+ // src/utils/autonomy-config.ts
709
+ import { readFile, writeFile, mkdir } from "fs/promises";
710
+ import { existsSync } from "fs";
711
+ import { join } from "path";
712
+
713
+ // src/types/autonomy.ts
714
+ var DEFAULT_AUTONOMY_CONFIG = {
715
+ level: "proactive",
716
+ autoCheck: {
717
+ enabled: true,
718
+ threshold: 5,
719
+ onCritical: true,
720
+ cooldownMs: 3e4
721
+ // 30 seconds
722
+ },
723
+ autoFix: {
724
+ enabled: true,
725
+ askFirst: true,
726
+ // Always ask (human-in-the-loop)
727
+ categories: ["trivial", "safe"],
728
+ allowedFixTypes: [
729
+ "remove-console-log",
730
+ "remove-unused-import",
731
+ "add-missing-await",
732
+ "fix-typo"
733
+ ]
734
+ },
735
+ pushBlocking: {
736
+ enabled: true,
737
+ allowBypass: true,
738
+ blockOn: ["critical"],
739
+ bypassMethods: ["env", "flag", "confirm"],
740
+ logBypasses: true
741
+ },
742
+ progressiveEscalation: {
743
+ enabled: true,
744
+ thresholds: {
745
+ suggest: 1,
746
+ autoCheck: 3,
747
+ escalate: 5,
748
+ block: 10
749
+ },
750
+ windowMs: 24 * 60 * 60 * 1e3
751
+ // 24 hours
752
+ }
753
+ };
754
+
755
+ // src/utils/autonomy-config.ts
756
+ import { createHash } from "crypto";
757
+ async function loadAutonomyConfig(projectPath) {
758
+ const configPath = join(getTrieDirectory(projectPath), "config.json");
759
+ try {
760
+ if (!existsSync(configPath)) {
761
+ return { ...DEFAULT_AUTONOMY_CONFIG };
762
+ }
763
+ const content = await readFile(configPath, "utf-8");
764
+ const config = JSON.parse(content);
765
+ return mergeWithDefaults(config.autonomy || {});
766
+ } catch (error) {
767
+ console.error("Failed to load autonomy config:", error);
768
+ return { ...DEFAULT_AUTONOMY_CONFIG };
769
+ }
770
+ }
771
+ function mergeWithDefaults(partial) {
772
+ return {
773
+ level: partial.level ?? DEFAULT_AUTONOMY_CONFIG.level,
774
+ autoCheck: {
775
+ ...DEFAULT_AUTONOMY_CONFIG.autoCheck,
776
+ ...partial.autoCheck || {}
777
+ },
778
+ autoFix: {
779
+ ...DEFAULT_AUTONOMY_CONFIG.autoFix,
780
+ ...partial.autoFix || {}
781
+ },
782
+ pushBlocking: {
783
+ ...DEFAULT_AUTONOMY_CONFIG.pushBlocking,
784
+ ...partial.pushBlocking || {}
785
+ },
786
+ progressiveEscalation: {
787
+ ...DEFAULT_AUTONOMY_CONFIG.progressiveEscalation,
788
+ ...partial.progressiveEscalation || {},
789
+ thresholds: {
790
+ ...DEFAULT_AUTONOMY_CONFIG.progressiveEscalation.thresholds,
791
+ ...partial.progressiveEscalation?.thresholds || {}
792
+ }
793
+ }
794
+ };
795
+ }
796
+ var occurrenceCache = /* @__PURE__ */ new Map();
797
+ async function getOccurrences(projectPath) {
798
+ if (occurrenceCache.has(projectPath)) {
799
+ return occurrenceCache.get(projectPath);
800
+ }
801
+ const occurrencesPath = join(getTrieDirectory(projectPath), "memory", "occurrences.json");
802
+ const occurrences = /* @__PURE__ */ new Map();
803
+ try {
804
+ if (existsSync(occurrencesPath)) {
805
+ const content = await readFile(occurrencesPath, "utf-8");
806
+ const data = JSON.parse(content);
807
+ for (const [hash, occ] of Object.entries(data)) {
808
+ occurrences.set(hash, occ);
809
+ }
810
+ }
811
+ } catch {
812
+ }
813
+ occurrenceCache.set(projectPath, occurrences);
814
+ return occurrences;
815
+ }
816
+ async function saveOccurrences(projectPath) {
817
+ const occurrences = occurrenceCache.get(projectPath);
818
+ if (!occurrences) return;
819
+ const occurrencesPath = join(getTrieDirectory(projectPath), "memory", "occurrences.json");
820
+ const memoryDir = join(getTrieDirectory(projectPath), "memory");
821
+ try {
822
+ if (!existsSync(memoryDir)) {
823
+ await mkdir(memoryDir, { recursive: true });
824
+ }
825
+ const data = {};
826
+ for (const [hash, occ] of occurrences.entries()) {
827
+ data[hash] = occ;
828
+ }
829
+ await writeFile(occurrencesPath, JSON.stringify(data, null, 2));
830
+ } catch (error) {
831
+ console.error("Failed to save occurrences:", error);
832
+ }
833
+ }
834
+ function createIssueHash(file, line, issueType) {
835
+ const input = `${file}:${line || 0}:${issueType}`;
836
+ return createHash("md5").update(input).digest("hex").slice(0, 12);
837
+ }
838
+ async function trackIssueOccurrence(projectPath, file, line, issueType, config) {
839
+ const occurrences = await getOccurrences(projectPath);
840
+ const hash = createIssueHash(file, line, issueType);
841
+ const now = Date.now();
842
+ let occurrence = occurrences.get(hash);
843
+ if (occurrence) {
844
+ const windowMs = config.progressiveEscalation.windowMs;
845
+ if (now - occurrence.firstSeen > windowMs) {
846
+ occurrence = {
847
+ hash,
848
+ firstSeen: now,
849
+ lastSeen: now,
850
+ count: 1,
851
+ escalationLevel: "suggest",
852
+ notified: false,
853
+ bypassed: false,
854
+ bypassHistory: occurrence.bypassHistory
855
+ // Keep bypass history
856
+ };
857
+ } else {
858
+ occurrence.lastSeen = now;
859
+ occurrence.count++;
860
+ const thresholds = config.progressiveEscalation.thresholds;
861
+ if (occurrence.count >= thresholds.block) {
862
+ occurrence.escalationLevel = "block";
863
+ } else if (occurrence.count >= thresholds.escalate) {
864
+ occurrence.escalationLevel = "escalate";
865
+ } else if (occurrence.count >= thresholds.autoCheck) {
866
+ occurrence.escalationLevel = "autoCheck";
867
+ }
868
+ }
869
+ } else {
870
+ occurrence = {
871
+ hash,
872
+ firstSeen: now,
873
+ lastSeen: now,
874
+ count: 1,
875
+ escalationLevel: "suggest",
876
+ notified: false,
877
+ bypassed: false,
878
+ bypassHistory: []
879
+ };
880
+ }
881
+ occurrences.set(hash, occurrence);
882
+ await saveOccurrences(projectPath);
883
+ return occurrence;
884
+ }
885
+ async function recordBypass(projectPath, file, line, issueType, method, reason) {
886
+ const occurrences = await getOccurrences(projectPath);
887
+ const hash = createIssueHash(file, line, issueType);
888
+ const occurrence = occurrences.get(hash);
889
+ if (occurrence) {
890
+ occurrence.bypassed = true;
891
+ occurrence.bypassHistory.push({
892
+ timestamp: Date.now(),
893
+ method,
894
+ ...reason !== void 0 ? { reason } : {}
895
+ });
896
+ await saveOccurrences(projectPath);
897
+ }
898
+ }
899
+ function shouldAutoFix(fix, config) {
900
+ if (!config.autoFix.enabled) {
901
+ return false;
902
+ }
903
+ const allowedCategories = config.autoFix.categories;
904
+ if (!allowedCategories.includes(fix.category) && !allowedCategories.includes("all")) {
905
+ return false;
906
+ }
907
+ if (config.autoFix.allowedFixTypes.length > 0 && !config.autoFix.allowedFixTypes.includes(fix.type)) {
908
+ return false;
909
+ }
910
+ if (fix.confidence < 0.9) {
911
+ return false;
912
+ }
913
+ return true;
914
+ }
915
+ function shouldBlockPush(issues, config) {
916
+ if (!config.pushBlocking.enabled) {
917
+ return {
918
+ blocked: false,
919
+ blockingIssues: [],
920
+ bypassed: false
921
+ };
922
+ }
923
+ const blockingIssues = issues.filter(
924
+ (issue) => config.pushBlocking.blockOn.includes(issue.severity)
925
+ );
926
+ if (blockingIssues.length === 0) {
927
+ return {
928
+ blocked: false,
929
+ blockingIssues: [],
930
+ bypassed: false
931
+ };
932
+ }
933
+ const envBypass = process.env.TRIE_BYPASS === "1" || process.env.TRIE_BYPASS === "true";
934
+ if (envBypass && config.pushBlocking.allowBypass) {
935
+ return {
936
+ blocked: false,
937
+ blockingIssues,
938
+ bypassed: true,
939
+ bypassMethod: "env"
940
+ };
941
+ }
942
+ const bypassInstructions = buildBypassInstructions(config);
943
+ return {
944
+ blocked: true,
945
+ reason: `${blockingIssues.length} ${blockingIssues[0]?.severity || "critical"} issue(s) must be fixed before pushing`,
946
+ blockingIssues,
947
+ bypassInstructions,
948
+ bypassed: false
949
+ };
950
+ }
951
+ function buildBypassInstructions(config) {
952
+ const instructions = [];
953
+ if (config.pushBlocking.bypassMethods.includes("env")) {
954
+ instructions.push("\u2022 Set TRIE_BYPASS=1 to bypass: TRIE_BYPASS=1 git push");
955
+ }
956
+ if (config.pushBlocking.bypassMethods.includes("flag")) {
957
+ instructions.push("\u2022 Use --no-verify flag: git push --no-verify");
958
+ }
959
+ if (config.pushBlocking.bypassMethods.includes("confirm")) {
960
+ instructions.push("\u2022 Run: trie bypass --confirm to bypass this push");
961
+ }
962
+ return instructions.join("\n");
963
+ }
964
+ var configCache = /* @__PURE__ */ new Map();
965
+ var CACHE_TTL = 6e4;
966
+ async function getAutonomyConfig(projectPath) {
967
+ const cached = configCache.get(projectPath);
968
+ if (cached && Date.now() - cached.loadedAt < CACHE_TTL) {
969
+ return cached.config;
970
+ }
971
+ const config = await loadAutonomyConfig(projectPath);
972
+ configCache.set(projectPath, { config, loadedAt: Date.now() });
973
+ return config;
974
+ }
975
+
713
976
  // src/cli/pre-push.ts
714
977
  import pc from "picocolors";
715
978
  function parseArgs2(args) {
@@ -843,8 +1106,8 @@ function collectIssuesForBlocking(reasoning) {
843
1106
  }
844
1107
 
845
1108
  // src/cli/auto-fix.ts
846
- import { readFile, writeFile } from "fs/promises";
847
- import { existsSync } from "fs";
1109
+ import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
1110
+ import { existsSync as existsSync2 } from "fs";
848
1111
  import { createInterface } from "readline";
849
1112
  import pc2 from "picocolors";
850
1113
  function detectAutoFixes(issues) {
@@ -920,11 +1183,11 @@ function displayFixPreview(fix, index, total) {
920
1183
  }
921
1184
  async function applyFix(fix) {
922
1185
  try {
923
- if (!existsSync(fix.file)) {
1186
+ if (!existsSync2(fix.file)) {
924
1187
  console.error(pc2.red(`File not found: ${fix.file}`));
925
1188
  return false;
926
1189
  }
927
- const content = await readFile(fix.file, "utf-8");
1190
+ const content = await readFile2(fix.file, "utf-8");
928
1191
  const lines = content.split("\n");
929
1192
  if (fix.line === void 0 || fix.line < 1 || fix.line > lines.length) {
930
1193
  console.error(pc2.red(`Invalid line number: ${fix.line}`));
@@ -943,7 +1206,7 @@ async function applyFix(fix) {
943
1206
  console.error(pc2.red(`Unknown fix type: ${fix.type}`));
944
1207
  return false;
945
1208
  }
946
- await writeFile(fix.file, newContent);
1209
+ await writeFile2(fix.file, newContent);
947
1210
  console.error(pc2.green(`\u2713 Applied fix to ${fix.file}:${fix.line}`));
948
1211
  if (originalLine) {
949
1212
  console.error(pc2.dim(` Removed: ${originalLine.trim().slice(0, 60)}...`));
@@ -957,11 +1220,11 @@ async function applyFix(fix) {
957
1220
  async function loadFixContent(fixes) {
958
1221
  const enrichedFixes = [];
959
1222
  for (const fix of fixes) {
960
- if (!fix.line || !existsSync(fix.file)) {
1223
+ if (!fix.line || !existsSync2(fix.file)) {
961
1224
  continue;
962
1225
  }
963
1226
  try {
964
- const content = await readFile(fix.file, "utf-8");
1227
+ const content = await readFile2(fix.file, "utf-8");
965
1228
  const lines = content.split("\n");
966
1229
  const originalLine = lines[fix.line - 1];
967
1230
  if (originalLine) {
@@ -1625,8 +1888,8 @@ async function handleQuietCommand() {
1625
1888
  }
1626
1889
 
1627
1890
  // src/cli/ci.ts
1628
- import { writeFileSync, existsSync as existsSync2, mkdirSync } from "fs";
1629
- import { join } from "path";
1891
+ import { writeFileSync, existsSync as existsSync3, mkdirSync } from "fs";
1892
+ import { join as join2 } from "path";
1630
1893
  import pc4 from "picocolors";
1631
1894
  var WORKFLOW_TEMPLATE = `# Trie Security Scan with Memory Persistence
1632
1895
  # Generated by: trie ci
@@ -1717,8 +1980,8 @@ jobs:
1717
1980
  `;
1718
1981
  function handleCISetupCommand(args) {
1719
1982
  const workDir = getWorkingDirectory(void 0, true);
1720
- const workflowsDir = join(workDir, ".github", "workflows");
1721
- const workflowPath = join(workflowsDir, "trie-scan.yml");
1983
+ const workflowsDir = join2(workDir, ".github", "workflows");
1984
+ const workflowPath = join2(workflowsDir, "trie-scan.yml");
1722
1985
  const isMinimal = args.includes("--minimal") || args.includes("-m");
1723
1986
  const isDryRun = args.includes("--dry-run") || args.includes("-n");
1724
1987
  const showHelp3 = args.includes("--help") || args.includes("-h");
@@ -1767,13 +2030,13 @@ ${pc4.bold("REQUIRED SECRETS:")}
1767
2030
  console.log(pc4.dim("\nRun without --dry-run to create the file."));
1768
2031
  return;
1769
2032
  }
1770
- if (existsSync2(workflowPath)) {
2033
+ if (existsSync3(workflowPath)) {
1771
2034
  console.log(pc4.yellow("Workflow already exists: .github/workflows/trie-scan.yml"));
1772
2035
  console.log(pc4.dim(" Run with --dry-run to preview what would be written."));
1773
2036
  console.log(pc4.dim(" Delete the existing file to regenerate."));
1774
2037
  return;
1775
2038
  }
1776
- if (!existsSync2(workflowsDir)) {
2039
+ if (!existsSync3(workflowsDir)) {
1777
2040
  mkdirSync(workflowsDir, { recursive: true });
1778
2041
  }
1779
2042
  writeFileSync(workflowPath, template);
@@ -2019,21 +2282,21 @@ async function handleLearnCommand(args) {
2019
2282
  }
2020
2283
 
2021
2284
  // src/cli/patterns.ts
2022
- import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
2023
- import { existsSync as existsSync4 } from "fs";
2285
+ import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
2286
+ import { existsSync as existsSync5 } from "fs";
2024
2287
  import { basename as basename2 } from "path";
2025
2288
  import picocolors3 from "picocolors";
2026
2289
 
2027
2290
  // src/patterns/saved-patterns.ts
2028
- import { createHash } from "crypto";
2029
- import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
2030
- import { existsSync as existsSync3 } from "fs";
2031
- import { join as join2, basename } from "path";
2291
+ import { createHash as createHash2 } from "crypto";
2292
+ import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
2293
+ import { existsSync as existsSync4 } from "fs";
2294
+ import { join as join3, basename } from "path";
2032
2295
  async function loadSavedPatterns(workDir) {
2033
- const patternsPath = join2(getTrieDirectory(workDir), "saved-patterns.json");
2296
+ const patternsPath = join3(getTrieDirectory(workDir), "saved-patterns.json");
2034
2297
  try {
2035
- if (existsSync3(patternsPath)) {
2036
- const content = await readFile2(patternsPath, "utf-8");
2298
+ if (existsSync4(patternsPath)) {
2299
+ const content = await readFile3(patternsPath, "utf-8");
2037
2300
  return JSON.parse(content);
2038
2301
  }
2039
2302
  } catch {
@@ -2041,10 +2304,10 @@ async function loadSavedPatterns(workDir) {
2041
2304
  return [];
2042
2305
  }
2043
2306
  async function savePatternsToProject(patterns, workDir) {
2044
- const { mkdir } = await import("fs/promises");
2045
- const patternsPath = join2(getTrieDirectory(workDir), "saved-patterns.json");
2046
- await mkdir(getTrieDirectory(workDir), { recursive: true });
2047
- await writeFile2(patternsPath, JSON.stringify(patterns, null, 2));
2307
+ const { mkdir: mkdir2 } = await import("fs/promises");
2308
+ const patternsPath = join3(getTrieDirectory(workDir), "saved-patterns.json");
2309
+ await mkdir2(getTrieDirectory(workDir), { recursive: true });
2310
+ await writeFile3(patternsPath, JSON.stringify(patterns, null, 2));
2048
2311
  }
2049
2312
  async function savePatternToProject(pattern, workDir) {
2050
2313
  const patterns = await loadSavedPatterns(workDir);
@@ -2079,14 +2342,14 @@ function detectPatternType(target, workDir) {
2079
2342
  if (scoutNames.includes(target.toLowerCase())) {
2080
2343
  return "detection-rule";
2081
2344
  }
2082
- const fullPath = join2(workDir, target);
2083
- if (existsSync3(fullPath) || target.includes("/") || target.includes("*") || target.endsWith(".ts") || target.endsWith(".js")) {
2345
+ const fullPath = join3(workDir, target);
2346
+ if (existsSync4(fullPath) || target.includes("/") || target.includes("*") || target.endsWith(".ts") || target.endsWith(".js")) {
2084
2347
  return "file-structure";
2085
2348
  }
2086
2349
  return "code-pattern";
2087
2350
  }
2088
2351
  function generatePatternId(target, type) {
2089
- const hash = createHash("sha256").update(`${type}:${target}`).digest("hex").slice(0, 12);
2352
+ const hash = createHash2("sha256").update(`${type}:${target}`).digest("hex").slice(0, 12);
2090
2353
  return `${type}-${hash}`;
2091
2354
  }
2092
2355
  async function createSavedPattern(target, note, workDir) {
@@ -2238,7 +2501,7 @@ async function handleExportPatterns(args, workDir) {
2238
2501
  exportedFrom: basename2(workDir),
2239
2502
  patterns
2240
2503
  };
2241
- await writeFile3(outputPath, JSON.stringify(exportData, null, 2));
2504
+ await writeFile4(outputPath, JSON.stringify(exportData, null, 2));
2242
2505
  console.log(picocolors3.green(`\u2713 Exported ${patterns.length} patterns to ${outputPath}`));
2243
2506
  console.log(picocolors3.dim(` Import to another project with: trie patterns import ${outputPath}`));
2244
2507
  }
@@ -2248,11 +2511,11 @@ async function handleImportPatterns(args, workDir) {
2248
2511
  console.error(picocolors3.red("Usage: trie patterns import <path-to-patterns.json>"));
2249
2512
  process.exit(1);
2250
2513
  }
2251
- if (!existsSync4(inputPath)) {
2514
+ if (!existsSync5(inputPath)) {
2252
2515
  console.error(picocolors3.red(`File not found: ${inputPath}`));
2253
2516
  process.exit(1);
2254
2517
  }
2255
- const content = await readFile3(inputPath, "utf-8");
2518
+ const content = await readFile4(inputPath, "utf-8");
2256
2519
  const importData = JSON.parse(content);
2257
2520
  if (!importData.patterns || !Array.isArray(importData.patterns)) {
2258
2521
  console.error(picocolors3.red("Invalid pattern file format."));
@@ -2581,7 +2844,7 @@ Next steps:
2581
2844
  }
2582
2845
  if (subcommand === "edit") {
2583
2846
  const editor = process.env.EDITOR || process.env.VISUAL || "nano";
2584
- const projectPath = join3(getTrieDirectory(workDir), "PROJECT.md");
2847
+ const projectPath = join4(getTrieDirectory(workDir), "PROJECT.md");
2585
2848
  if (!projectInfoExists(workDir)) {
2586
2849
  console.log("No PROJECT.md found. Creating one first...");
2587
2850
  await initProjectInfo(workDir);
@@ -2627,7 +2890,7 @@ This info is available via trie://project MCP resource.
2627
2890
  \u2551 \u{1F4CB} Project Information \u2551
2628
2891
  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
2629
2892
 
2630
- Path: ${join3(getTrieDirectory(workDir), "PROJECT.md")}
2893
+ Path: ${join4(getTrieDirectory(workDir), "PROJECT.md")}
2631
2894
 
2632
2895
  ${"-".repeat(68)}
2633
2896
  `);