@triedotdev/mcp 1.0.169 → 1.0.171

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.
Files changed (145) hide show
  1. package/README.md +62 -540
  2. package/dist/chunk-2YXOBNKW.js +619 -0
  3. package/dist/chunk-2YXOBNKW.js.map +1 -0
  4. package/dist/chunk-QR64Y5TI.js +363 -0
  5. package/dist/chunk-QR64Y5TI.js.map +1 -0
  6. package/dist/cli/main.d.ts +0 -15
  7. package/dist/cli/main.js +356 -3098
  8. package/dist/cli/main.js.map +1 -1
  9. package/dist/index.js +2 -34
  10. package/dist/index.js.map +1 -1
  11. package/dist/server/mcp-server.js +2 -34
  12. package/package.json +8 -31
  13. package/dist/autonomy-config-FSERX3O3.js +0 -30
  14. package/dist/autonomy-config-FSERX3O3.js.map +0 -1
  15. package/dist/chat-store-JNGNTDSN.js +0 -15
  16. package/dist/chat-store-JNGNTDSN.js.map +0 -1
  17. package/dist/chunk-2HF65EHQ.js +0 -311
  18. package/dist/chunk-2HF65EHQ.js.map +0 -1
  19. package/dist/chunk-3XR6WVAW.js +0 -4011
  20. package/dist/chunk-3XR6WVAW.js.map +0 -1
  21. package/dist/chunk-43X6JBEM.js +0 -36
  22. package/dist/chunk-43X6JBEM.js.map +0 -1
  23. package/dist/chunk-6NLHFIYA.js +0 -344
  24. package/dist/chunk-6NLHFIYA.js.map +0 -1
  25. package/dist/chunk-7IO4YUI3.js +0 -1827
  26. package/dist/chunk-7IO4YUI3.js.map +0 -1
  27. package/dist/chunk-AHD2CBQ7.js +0 -846
  28. package/dist/chunk-AHD2CBQ7.js.map +0 -1
  29. package/dist/chunk-BUTOP5EB.js +0 -931
  30. package/dist/chunk-BUTOP5EB.js.map +0 -1
  31. package/dist/chunk-DGUM43GV.js +0 -11
  32. package/dist/chunk-DGUM43GV.js.map +0 -1
  33. package/dist/chunk-EFWVF6TI.js +0 -267
  34. package/dist/chunk-EFWVF6TI.js.map +0 -1
  35. package/dist/chunk-F6WFNUAY.js +0 -216
  36. package/dist/chunk-F6WFNUAY.js.map +0 -1
  37. package/dist/chunk-FBNURWRY.js +0 -662
  38. package/dist/chunk-FBNURWRY.js.map +0 -1
  39. package/dist/chunk-FQ45QP5A.js +0 -361
  40. package/dist/chunk-FQ45QP5A.js.map +0 -1
  41. package/dist/chunk-FVRO5RN3.js +0 -1306
  42. package/dist/chunk-FVRO5RN3.js.map +0 -1
  43. package/dist/chunk-G2TGF6TR.js +0 -573
  44. package/dist/chunk-G2TGF6TR.js.map +0 -1
  45. package/dist/chunk-G3I7SZLW.js +0 -354
  46. package/dist/chunk-G3I7SZLW.js.map +0 -1
  47. package/dist/chunk-GTKYBOXL.js +0 -700
  48. package/dist/chunk-GTKYBOXL.js.map +0 -1
  49. package/dist/chunk-HVCDY3AK.js +0 -850
  50. package/dist/chunk-HVCDY3AK.js.map +0 -1
  51. package/dist/chunk-I2O5OYQT.js +0 -727
  52. package/dist/chunk-I2O5OYQT.js.map +0 -1
  53. package/dist/chunk-JVMBCWKS.js +0 -348
  54. package/dist/chunk-JVMBCWKS.js.map +0 -1
  55. package/dist/chunk-KCUOWRPX.js +0 -816
  56. package/dist/chunk-KCUOWRPX.js.map +0 -1
  57. package/dist/chunk-KDHN2ZQE.js +0 -313
  58. package/dist/chunk-KDHN2ZQE.js.map +0 -1
  59. package/dist/chunk-ME2OERF5.js +0 -345
  60. package/dist/chunk-ME2OERF5.js.map +0 -1
  61. package/dist/chunk-OBQ74FOU.js +0 -27
  62. package/dist/chunk-OBQ74FOU.js.map +0 -1
  63. package/dist/chunk-Q5EKA5YA.js +0 -254
  64. package/dist/chunk-Q5EKA5YA.js.map +0 -1
  65. package/dist/chunk-Q63FFI6D.js +0 -132
  66. package/dist/chunk-Q63FFI6D.js.map +0 -1
  67. package/dist/chunk-SASNMSB5.js +0 -12597
  68. package/dist/chunk-SASNMSB5.js.map +0 -1
  69. package/dist/chunk-T63OHG4Q.js +0 -440
  70. package/dist/chunk-T63OHG4Q.js.map +0 -1
  71. package/dist/chunk-TN5WEKWI.js +0 -173
  72. package/dist/chunk-TN5WEKWI.js.map +0 -1
  73. package/dist/chunk-VUL52BQL.js +0 -402
  74. package/dist/chunk-VUL52BQL.js.map +0 -1
  75. package/dist/chunk-VVITXIHN.js +0 -189
  76. package/dist/chunk-VVITXIHN.js.map +0 -1
  77. package/dist/chunk-WCN7S3EI.js +0 -14
  78. package/dist/chunk-WCN7S3EI.js.map +0 -1
  79. package/dist/chunk-XPZZFPBZ.js +0 -491
  80. package/dist/chunk-XPZZFPBZ.js.map +0 -1
  81. package/dist/chunk-ZJF5FTBX.js +0 -1396
  82. package/dist/chunk-ZJF5FTBX.js.map +0 -1
  83. package/dist/chunk-ZV2K6M7T.js +0 -74
  84. package/dist/chunk-ZV2K6M7T.js.map +0 -1
  85. package/dist/cli/create-agent.d.ts +0 -1
  86. package/dist/cli/create-agent.js +0 -1050
  87. package/dist/cli/create-agent.js.map +0 -1
  88. package/dist/cli/yolo-daemon.d.ts +0 -1
  89. package/dist/cli/yolo-daemon.js +0 -421
  90. package/dist/cli/yolo-daemon.js.map +0 -1
  91. package/dist/client-NJPZE5JT.js +0 -28
  92. package/dist/client-NJPZE5JT.js.map +0 -1
  93. package/dist/codebase-index-VAPF32XX.js +0 -12
  94. package/dist/codebase-index-VAPF32XX.js.map +0 -1
  95. package/dist/fast-analyzer-3GCCZMLK.js +0 -216
  96. package/dist/fast-analyzer-3GCCZMLK.js.map +0 -1
  97. package/dist/git-EO5SRFMN.js +0 -28
  98. package/dist/git-EO5SRFMN.js.map +0 -1
  99. package/dist/github-ingester-ZOKK6GRS.js +0 -11
  100. package/dist/github-ingester-ZOKK6GRS.js.map +0 -1
  101. package/dist/goal-manager-QUKX2W6C.js +0 -25
  102. package/dist/goal-manager-QUKX2W6C.js.map +0 -1
  103. package/dist/goal-validator-2SFSKKVU.js +0 -24
  104. package/dist/goal-validator-2SFSKKVU.js.map +0 -1
  105. package/dist/graph-B3NA4S7I.js +0 -10
  106. package/dist/graph-B3NA4S7I.js.map +0 -1
  107. package/dist/hypothesis-KCPBR652.js +0 -23
  108. package/dist/hypothesis-KCPBR652.js.map +0 -1
  109. package/dist/incident-index-EFNUSGWL.js +0 -11
  110. package/dist/incident-index-EFNUSGWL.js.map +0 -1
  111. package/dist/insight-store-EC4PLSAW.js +0 -22
  112. package/dist/insight-store-EC4PLSAW.js.map +0 -1
  113. package/dist/issue-store-YAXTNRRY.js +0 -36
  114. package/dist/issue-store-YAXTNRRY.js.map +0 -1
  115. package/dist/ledger-TWZTGDFA.js +0 -58
  116. package/dist/ledger-TWZTGDFA.js.map +0 -1
  117. package/dist/linear-ingester-XXPAZZRW.js +0 -11
  118. package/dist/linear-ingester-XXPAZZRW.js.map +0 -1
  119. package/dist/output-manager-RVJ37XKA.js +0 -13
  120. package/dist/output-manager-RVJ37XKA.js.map +0 -1
  121. package/dist/parse-goal-violation-SACGFG3C.js +0 -8
  122. package/dist/parse-goal-violation-SACGFG3C.js.map +0 -1
  123. package/dist/pattern-discovery-F7LU5K6E.js +0 -8
  124. package/dist/pattern-discovery-F7LU5K6E.js.map +0 -1
  125. package/dist/progress-SRQ2V3BP.js +0 -18
  126. package/dist/progress-SRQ2V3BP.js.map +0 -1
  127. package/dist/project-state-AHPA77SM.js +0 -28
  128. package/dist/project-state-AHPA77SM.js.map +0 -1
  129. package/dist/sync-M2FSWPBC.js +0 -12
  130. package/dist/sync-M2FSWPBC.js.map +0 -1
  131. package/dist/terminal-spawn-5YXDMUCF.js +0 -157
  132. package/dist/terminal-spawn-5YXDMUCF.js.map +0 -1
  133. package/dist/tiered-storage-DYNC5CQ6.js +0 -13
  134. package/dist/tiered-storage-DYNC5CQ6.js.map +0 -1
  135. package/dist/trie-agent-I3HAHY2G.js +0 -26
  136. package/dist/trie-agent-I3HAHY2G.js.map +0 -1
  137. package/dist/ui/chat.html +0 -1014
  138. package/dist/ui/goals.html +0 -967
  139. package/dist/ui/hypotheses.html +0 -1011
  140. package/dist/ui/ledger.html +0 -954
  141. package/dist/ui/nudges.html +0 -995
  142. package/dist/vibe-code-signatures-5ZULYP3D.js +0 -987
  143. package/dist/vibe-code-signatures-5ZULYP3D.js.map +0 -1
  144. package/dist/vulnerability-signatures-2URZSXAQ.js +0 -983
  145. package/dist/vulnerability-signatures-2URZSXAQ.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,40 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startServer
4
- } from "./chunk-3XR6WVAW.js";
5
- import "./chunk-F6WFNUAY.js";
6
- import "./chunk-HVCDY3AK.js";
7
- import "./chunk-Q63FFI6D.js";
8
- import "./chunk-SASNMSB5.js";
9
- import "./chunk-JVMBCWKS.js";
10
- import "./chunk-7IO4YUI3.js";
11
- import "./chunk-I2O5OYQT.js";
12
- import "./chunk-WCN7S3EI.js";
13
- import "./chunk-Q5EKA5YA.js";
14
- import "./chunk-G2TGF6TR.js";
15
- import "./chunk-FBNURWRY.js";
16
- import "./chunk-T63OHG4Q.js";
17
- import "./chunk-FVRO5RN3.js";
18
- import "./chunk-G3I7SZLW.js";
19
- import "./chunk-OBQ74FOU.js";
20
- import "./chunk-XPZZFPBZ.js";
21
- import "./chunk-TN5WEKWI.js";
22
- import "./chunk-ZV2K6M7T.js";
23
- import "./chunk-AHD2CBQ7.js";
24
- import "./chunk-VUL52BQL.js";
25
- import "./chunk-BUTOP5EB.js";
26
- import "./chunk-6NLHFIYA.js";
27
- import "./chunk-FQ45QP5A.js";
28
- import "./chunk-KCUOWRPX.js";
29
- import "./chunk-ZJF5FTBX.js";
30
- import "./chunk-GTKYBOXL.js";
31
- import "./chunk-EFWVF6TI.js";
32
- import "./chunk-43X6JBEM.js";
33
- import "./chunk-ME2OERF5.js";
34
- import "./chunk-VVITXIHN.js";
35
- import "./chunk-KDHN2ZQE.js";
36
- import "./chunk-2HF65EHQ.js";
37
- import "./chunk-DGUM43GV.js";
4
+ } from "./chunk-2YXOBNKW.js";
5
+ import "./chunk-QR64Y5TI.js";
38
6
 
39
7
  // src/index.ts
40
8
  startServer().catch((error) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { startServer } from './server/mcp-server.js';\n\n// Start the MCP server\nstartServer().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,YAAY,EAAE,MAAM,CAAC,UAAU;AAC7B,UAAQ,MAAM,gBAAgB,KAAK;AACnC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { startServer } from './server/mcp-server.js';\n\n// Start the MCP server\nstartServer().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});"],"mappings":";;;;;;;AAKA,YAAY,EAAE,MAAM,CAAC,UAAU;AAC7B,UAAQ,MAAM,gBAAgB,KAAK;AACnC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
@@ -1,40 +1,8 @@
1
1
  import {
2
2
  MCPServer,
3
3
  startServer
4
- } from "../chunk-3XR6WVAW.js";
5
- import "../chunk-F6WFNUAY.js";
6
- import "../chunk-HVCDY3AK.js";
7
- import "../chunk-Q63FFI6D.js";
8
- import "../chunk-SASNMSB5.js";
9
- import "../chunk-JVMBCWKS.js";
10
- import "../chunk-7IO4YUI3.js";
11
- import "../chunk-I2O5OYQT.js";
12
- import "../chunk-WCN7S3EI.js";
13
- import "../chunk-Q5EKA5YA.js";
14
- import "../chunk-G2TGF6TR.js";
15
- import "../chunk-FBNURWRY.js";
16
- import "../chunk-T63OHG4Q.js";
17
- import "../chunk-FVRO5RN3.js";
18
- import "../chunk-G3I7SZLW.js";
19
- import "../chunk-OBQ74FOU.js";
20
- import "../chunk-XPZZFPBZ.js";
21
- import "../chunk-TN5WEKWI.js";
22
- import "../chunk-ZV2K6M7T.js";
23
- import "../chunk-AHD2CBQ7.js";
24
- import "../chunk-VUL52BQL.js";
25
- import "../chunk-BUTOP5EB.js";
26
- import "../chunk-6NLHFIYA.js";
27
- import "../chunk-FQ45QP5A.js";
28
- import "../chunk-KCUOWRPX.js";
29
- import "../chunk-ZJF5FTBX.js";
30
- import "../chunk-GTKYBOXL.js";
31
- import "../chunk-EFWVF6TI.js";
32
- import "../chunk-43X6JBEM.js";
33
- import "../chunk-ME2OERF5.js";
34
- import "../chunk-VVITXIHN.js";
35
- import "../chunk-KDHN2ZQE.js";
36
- import "../chunk-2HF65EHQ.js";
37
- import "../chunk-DGUM43GV.js";
4
+ } from "../chunk-2YXOBNKW.js";
5
+ import "../chunk-QR64Y5TI.js";
38
6
  export {
39
7
  MCPServer,
40
8
  startServer
package/package.json CHANGED
@@ -1,25 +1,20 @@
1
1
  {
2
2
  "name": "@triedotdev/mcp",
3
- "version": "1.0.169",
4
- "description": "Governance ledger for agent-human teams. Decision memory that travels from Cursor to CLI to CI/CD.",
3
+ "version": "1.0.171",
4
+ "description": "Trie cloud context bridge for Cursor and Claude Code.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "trie": "dist/cli/main.js",
9
9
  "mcp": "dist/index.js",
10
10
  "trie-agent": "dist/cli/main.js",
11
- "trie-mcp": "dist/index.js",
12
- "trie-watch": "dist/cli/yolo-daemon.js",
13
- "trie-create": "dist/cli/create-agent.js"
11
+ "trie-mcp": "dist/index.js"
14
12
  },
15
13
  "scripts": {
16
- "build": "tsup && npm run build:ui",
14
+ "build": "tsup",
17
15
  "build:server": "tsup",
18
- "build:ui": "tsx src/ui/build.ts",
19
16
  "dev": "tsx src/index.ts",
20
17
  "test": "vitest",
21
- "test:mcp-apps": "tsx scripts/test-mcp-apps-integration.js",
22
- "preview:ui": "node scripts/preview-ui-apps.js",
23
18
  "lint": "eslint src/**/*.ts",
24
19
  "typecheck": "tsc --noEmit",
25
20
  "prepublishOnly": "npm run build"
@@ -51,36 +46,18 @@
51
46
  "url": "https://buy.stripe.com/5kQbJ12isaFyfVk0Tu00005"
52
47
  },
53
48
  "dependencies": {
54
- "@anthropic-ai/sdk": "^0.29.0",
55
- "@babel/generator": "^7.23.0",
56
- "@babel/parser": "^7.23.0",
57
- "@babel/traverse": "^7.23.0",
58
- "@babel/types": "^7.23.0",
59
- "@modelcontextprotocol/ext-apps": "^1.0.1",
60
- "@modelcontextprotocol/sdk": "^1.0.0",
61
- "@noble/ed25519": "^3.0.0",
62
- "@triedotdev/mcp": "^1.0.166",
63
- "@vercel/blob": "^2.0.0",
64
- "better-sqlite3": "^12.6.2",
65
- "commander": "^11.1.0",
66
- "glob": "^10.3.0",
67
- "ink": "^5.2.1",
68
- "picocolors": "^1.0.0",
69
- "playwright": "^1.57.0",
70
- "react": "^18.3.1",
49
+ "@modelcontextprotocol/sdk": "^1.27.1",
71
50
  "typescript": "^5.3.0",
72
51
  "zod": "^3.22.0"
73
52
  },
53
+ "optionalDependencies": {
54
+ "keytar": "^7.9.0"
55
+ },
74
56
  "devDependencies": {
75
- "@types/babel__generator": "^7.6.8",
76
- "@types/babel__traverse": "^7.20.6",
77
- "@types/better-sqlite3": "^7.6.13",
78
57
  "@types/node": "^20.10.0",
79
- "@types/react": "^18.3.28",
80
58
  "@typescript-eslint/eslint-plugin": "^6.13.0",
81
59
  "@typescript-eslint/parser": "^6.13.0",
82
60
  "eslint": "^8.55.0",
83
- "ink-testing-library": "^4.0.0",
84
61
  "tsup": "^8.0.0",
85
62
  "tsx": "^4.6.0",
86
63
  "vitest": "^1.0.0"
@@ -1,30 +0,0 @@
1
- import {
2
- clearConfigCache,
3
- createIssueHash,
4
- getAutonomyConfig,
5
- getEscalationLevel,
6
- groupFixesByFile,
7
- loadAutonomyConfig,
8
- recordBypass,
9
- saveAutonomyConfig,
10
- shouldAutoFix,
11
- shouldBlockPush,
12
- trackIssueOccurrence
13
- } from "./chunk-ME2OERF5.js";
14
- import "./chunk-VVITXIHN.js";
15
- import "./chunk-KDHN2ZQE.js";
16
- import "./chunk-DGUM43GV.js";
17
- export {
18
- clearConfigCache,
19
- createIssueHash,
20
- getAutonomyConfig,
21
- getEscalationLevel,
22
- groupFixesByFile,
23
- loadAutonomyConfig,
24
- recordBypass,
25
- saveAutonomyConfig,
26
- shouldAutoFix,
27
- shouldBlockPush,
28
- trackIssueOccurrence
29
- };
30
- //# sourceMappingURL=autonomy-config-FSERX3O3.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,15 +0,0 @@
1
- import {
2
- ChatStore,
3
- clearChatStores,
4
- getChatStore
5
- } from "./chunk-JVMBCWKS.js";
6
- import "./chunk-43X6JBEM.js";
7
- import "./chunk-VVITXIHN.js";
8
- import "./chunk-KDHN2ZQE.js";
9
- import "./chunk-DGUM43GV.js";
10
- export {
11
- ChatStore,
12
- clearChatStores,
13
- getChatStore
14
- };
15
- //# sourceMappingURL=chat-store-JNGNTDSN.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,311 +0,0 @@
1
- // src/agent/git.ts
2
- import { existsSync } from "fs";
3
- import path from "path";
4
-
5
- // src/utils/command-runner.ts
6
- import { exec, execFile, execSync } from "child_process";
7
- import { promisify } from "util";
8
-
9
- // src/utils/audit-logger.ts
10
- function createAuditEntry(skillName, skillSource, triggeredBy, targetPath) {
11
- return {
12
- skillName,
13
- skillSource,
14
- triggeredBy,
15
- targetPath,
16
- startedAt: (/* @__PURE__ */ new Date()).toISOString(),
17
- commands: []
18
- };
19
- }
20
- function completeAuditEntry(entry, success, error) {
21
- const result = {
22
- ...entry,
23
- completedAt: (/* @__PURE__ */ new Date()).toISOString(),
24
- success
25
- };
26
- if (error !== void 0) {
27
- result.error = error;
28
- }
29
- return result;
30
- }
31
- async function logSkillExecution(_execution) {
32
- }
33
-
34
- // src/utils/command-runner.ts
35
- var execAsync = promisify(exec);
36
- var execFileAsync = promisify(execFile);
37
- function redact(text) {
38
- return text.replace(/\b(AWS|ANTHROPIC|OPENAI|GITHUB)_[A-Z0-9_]*\s*=\s*([^\s"'`]+)/gi, "$1_<REDACTED>=<REDACTED>").replace(/\bBearer\s+[A-Za-z0-9\-._~+/]+=*\b/g, "Bearer <REDACTED>").replace(/\bghp_[A-Za-z0-9]{20,}\b/g, "ghp_<REDACTED>").replace(/\b(?:xox[baprs]-)[A-Za-z0-9-]{10,}\b/g, "<REDACTED_SLACK_TOKEN>").replace(/\bAKIA[0-9A-Z]{16}\b/g, "AKIA<REDACTED>");
39
- }
40
- function clampOutput(text, maxChars) {
41
- if (text.length <= maxChars) return text;
42
- return text.slice(0, maxChars) + `
43
- \u2026(truncated ${text.length - maxChars} chars)`;
44
- }
45
- function buildCommandRecord(command) {
46
- return {
47
- command,
48
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
49
- };
50
- }
51
- async function finalizeAndWrite(entry, cmd, outcome, options) {
52
- const duration = Date.now() - outcome.startedAt;
53
- cmd.duration = duration;
54
- if (outcome.exitCode !== void 0) {
55
- cmd.exitCode = outcome.exitCode;
56
- }
57
- const captureOutput = options?.captureOutput ?? false;
58
- const redactOutput = options?.redactOutput ?? true;
59
- const maxOutputChars = options?.maxOutputChars ?? 2e3;
60
- if (captureOutput) {
61
- const out = outcome.stdout ?? "";
62
- const err = outcome.stderr ?? "";
63
- cmd.stdout = redactOutput ? redact(clampOutput(out, maxOutputChars)) : clampOutput(out, maxOutputChars);
64
- cmd.stderr = redactOutput ? redact(clampOutput(err, maxOutputChars)) : clampOutput(err, maxOutputChars);
65
- }
66
- const completed = completeAuditEntry(entry, outcome.success, outcome.error);
67
- await logSkillExecution(completed);
68
- }
69
- function runShellCommandSync(command, audit, options) {
70
- const startedAt = Date.now();
71
- const entry = createAuditEntry(audit.actor, audit.source ?? "trie", audit.triggeredBy, audit.targetPath);
72
- const cmd = buildCommandRecord(command);
73
- entry.commands?.push(cmd);
74
- try {
75
- const stdout = execSync(command, {
76
- cwd: options?.cwd,
77
- timeout: options?.timeoutMs,
78
- maxBuffer: options?.maxBuffer,
79
- encoding: "utf-8",
80
- stdio: ["pipe", "pipe", "pipe"]
81
- });
82
- void finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout, stderr: "", startedAt }, options);
83
- return { stdout: stdout ?? "", exitCode: 0 };
84
- } catch (e) {
85
- const err = e;
86
- const stdout = typeof err.stdout === "string" ? err.stdout : "";
87
- const stderr = typeof err.stderr === "string" ? err.stderr : "";
88
- const exitCode = typeof err.status === "number" ? err.status : 1;
89
- void finalizeAndWrite(
90
- entry,
91
- cmd,
92
- { success: false, exitCode, stdout, stderr, error: err.message, startedAt },
93
- { ...options, captureOutput: options?.captureOutput ?? true }
94
- );
95
- return { stdout, exitCode };
96
- }
97
- }
98
- async function runExecFile(file, args, audit, options) {
99
- const startedAt = Date.now();
100
- const command = [file, ...args].join(" ");
101
- const entry = createAuditEntry(audit.actor, audit.source ?? "trie", audit.triggeredBy, audit.targetPath);
102
- const cmd = buildCommandRecord(command);
103
- entry.commands?.push(cmd);
104
- try {
105
- const { stdout, stderr } = await execFileAsync(file, args, {
106
- cwd: options?.cwd,
107
- timeout: options?.timeoutMs,
108
- maxBuffer: options?.maxBuffer
109
- });
110
- await finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout: String(stdout ?? ""), stderr: String(stderr ?? ""), startedAt }, options);
111
- return { stdout: String(stdout ?? ""), stderr: String(stderr ?? ""), exitCode: 0 };
112
- } catch (e) {
113
- const err = e;
114
- const stdout = typeof err.stdout === "string" ? err.stdout : "";
115
- const stderr = typeof err.stderr === "string" ? err.stderr : "";
116
- const exitCode = typeof err.code === "number" ? err.code : 1;
117
- await finalizeAndWrite(
118
- entry,
119
- cmd,
120
- { success: false, exitCode, stdout, stderr, error: err.message, startedAt },
121
- { ...options, captureOutput: options?.captureOutput ?? true }
122
- );
123
- return { stdout, stderr, exitCode };
124
- }
125
- }
126
-
127
- // src/agent/git.ts
128
- async function execGit(args, cwd) {
129
- try {
130
- const { stdout } = await runExecFile(
131
- "git",
132
- ["-C", cwd, ...args],
133
- { actor: "internal:git", triggeredBy: "manual", targetPath: cwd },
134
- { maxBuffer: 10 * 1024 * 1024, captureOutput: false }
135
- );
136
- return stdout.trim();
137
- } catch (error) {
138
- const stderr = error?.stderr?.toString();
139
- if (stderr?.includes("not a git repository") || stderr?.includes("does not have any commits")) {
140
- return null;
141
- }
142
- throw error;
143
- }
144
- }
145
- async function ensureRepo(projectPath) {
146
- const result = await execGit(["rev-parse", "--is-inside-work-tree"], projectPath);
147
- return result === "true";
148
- }
149
- function parseNameStatus(output) {
150
- return output.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => {
151
- const parts = line.split(" ");
152
- const status = parts[0] ?? "";
153
- const filePath = parts[1] ?? "";
154
- const oldPath = parts[2];
155
- const change = { status, path: filePath };
156
- if (oldPath) change.oldPath = oldPath;
157
- return change;
158
- }).filter((entry) => entry.path.length > 0);
159
- }
160
- async function getRecentCommits(projectPath, limit) {
161
- const isRepo = await ensureRepo(projectPath);
162
- if (!isRepo) return [];
163
- const output = await execGit(
164
- ["log", `-n`, String(limit), "--pretty=format:%H%x09%an%x09%ad%x09%s", "--date=iso"],
165
- projectPath
166
- );
167
- if (!output) return [];
168
- return output.split("\n").map((line) => {
169
- const [hash, author, date, message] = line.split(" ");
170
- return { hash, author, date, message };
171
- });
172
- }
173
- async function getLastCommit(projectPath) {
174
- const commits = await getRecentCommits(projectPath, 1);
175
- return commits[0] ?? null;
176
- }
177
- async function getStagedChanges(projectPath) {
178
- const isRepo = await ensureRepo(projectPath);
179
- if (!isRepo) return [];
180
- const output = await execGit(["diff", "--cached", "--name-status"], projectPath);
181
- if (!output) return [];
182
- return parseNameStatus(output);
183
- }
184
- async function getUncommittedChanges(projectPath) {
185
- const isRepo = await ensureRepo(projectPath);
186
- if (!isRepo) return [];
187
- const changes = [];
188
- const unstaged = await execGit(["diff", "--name-status"], projectPath);
189
- if (unstaged) {
190
- changes.push(...parseNameStatus(unstaged));
191
- }
192
- const untracked = await execGit(["ls-files", "--others", "--exclude-standard"], projectPath);
193
- if (untracked) {
194
- changes.push(
195
- ...untracked.split("\n").map((p) => p.trim()).filter(Boolean).map((p) => ({ status: "??", path: p }))
196
- );
197
- }
198
- return changes;
199
- }
200
- async function getGitChangedFiles(projectPath) {
201
- const isRepo = await ensureRepo(projectPath);
202
- if (!isRepo) return null;
203
- const [staged, uncommitted] = await Promise.all([
204
- getStagedChanges(projectPath).catch(() => []),
205
- getUncommittedChanges(projectPath).catch(() => [])
206
- ]);
207
- const paths = /* @__PURE__ */ new Set();
208
- for (const change of [...staged, ...uncommitted]) {
209
- if (change.path) paths.add(change.path);
210
- if (change.oldPath) paths.add(change.oldPath);
211
- }
212
- return [...paths];
213
- }
214
- async function getDiff(projectPath, commitHash) {
215
- const isRepo = await ensureRepo(projectPath);
216
- if (!isRepo) return "";
217
- const diff = await execGit(["show", commitHash, "--unified=3", "--no-color"], projectPath);
218
- return diff ?? "";
219
- }
220
- async function getWorkingTreeDiff(projectPath, stagedOnly = false) {
221
- const isRepo = await ensureRepo(projectPath);
222
- if (!isRepo) return "";
223
- const args = stagedOnly ? ["diff", "--cached", "--unified=3", "--no-color"] : ["diff", "--unified=3", "--no-color"];
224
- const diff = await execGit(args, projectPath);
225
- return diff ?? "";
226
- }
227
- async function getUnpushedCommits(projectPath) {
228
- const isRepo = await ensureRepo(projectPath);
229
- if (!isRepo) return [];
230
- const upstream = await execGit(["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"], projectPath);
231
- if (!upstream) {
232
- return getRecentCommits(projectPath, 10);
233
- }
234
- const output = await execGit(["log", `${upstream}..HEAD`, "--pretty=format:%H%x09%an%x09%ad%x09%s", "--date=iso"], projectPath);
235
- if (!output) return [];
236
- return output.split("\n").filter(Boolean).map((line) => {
237
- const [hash, author, date, message] = line.split(" ");
238
- return { hash, author, date, message };
239
- });
240
- }
241
- function resolveRepoPath(projectPath) {
242
- const gitDir = path.join(projectPath, ".git");
243
- if (existsSync(gitDir)) return projectPath;
244
- return projectPath;
245
- }
246
- async function isGitRepo(projectPath) {
247
- const result = await execGit(["rev-parse", "--is-inside-work-tree"], projectPath);
248
- return result === "true";
249
- }
250
- async function getChangedFilesSinceTimestamp(projectPath, timestamp) {
251
- const isRepo = await isGitRepo(projectPath);
252
- if (!isRepo) return null;
253
- try {
254
- const sinceDate = new Date(timestamp).toISOString();
255
- const GIT_TIMEOUT_MS = 5e3;
256
- const startTime = Date.now();
257
- const committedChangesPromise = execGit(
258
- ["log", `--since=${sinceDate}`, "--name-only", "--pretty=format:"],
259
- projectPath
260
- );
261
- const committedChangesTimeout = new Promise((resolve) => {
262
- setTimeout(() => resolve(null), GIT_TIMEOUT_MS);
263
- });
264
- const committedChanges = await Promise.race([committedChangesPromise, committedChangesTimeout]);
265
- if (Date.now() - startTime > GIT_TIMEOUT_MS) {
266
- return null;
267
- }
268
- const stagedPromise = execGit(["diff", "--cached", "--name-only"], projectPath);
269
- const unstagedPromise = execGit(["diff", "--name-only"], projectPath);
270
- const untrackedPromise = execGit(
271
- ["ls-files", "--others", "--exclude-standard"],
272
- projectPath
273
- );
274
- const timeoutPromise = new Promise((resolve) => {
275
- setTimeout(() => resolve(null), Math.max(0, GIT_TIMEOUT_MS - (Date.now() - startTime)));
276
- });
277
- const [stagedChanges, unstagedChanges, untrackedFiles] = await Promise.race([
278
- Promise.all([stagedPromise, unstagedPromise, untrackedPromise]),
279
- timeoutPromise.then(() => [null, null, null])
280
- ]);
281
- const changedFiles = /* @__PURE__ */ new Set();
282
- const addFiles = (output) => {
283
- if (output) {
284
- output.split("\n").map((f) => f.trim()).filter(Boolean).forEach((f) => changedFiles.add(path.join(projectPath, f)));
285
- }
286
- };
287
- addFiles(committedChanges);
288
- addFiles(stagedChanges);
289
- addFiles(unstagedChanges);
290
- addFiles(untrackedFiles);
291
- return Array.from(changedFiles);
292
- } catch {
293
- return null;
294
- }
295
- }
296
-
297
- export {
298
- runShellCommandSync,
299
- getRecentCommits,
300
- getLastCommit,
301
- getStagedChanges,
302
- getUncommittedChanges,
303
- getGitChangedFiles,
304
- getDiff,
305
- getWorkingTreeDiff,
306
- getUnpushedCommits,
307
- resolveRepoPath,
308
- isGitRepo,
309
- getChangedFilesSinceTimestamp
310
- };
311
- //# sourceMappingURL=chunk-2HF65EHQ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/agent/git.ts","../src/utils/command-runner.ts","../src/utils/audit-logger.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { runExecFile } from '../utils/command-runner.js';\n\nexport interface Commit {\n hash: string;\n author: string;\n date: string;\n message: string;\n}\n\nexport interface Change {\n path: string;\n status: string;\n oldPath?: string;\n}\n\nasync function execGit(args: string[], cwd: string): Promise<string | null> {\n try {\n const { stdout } = await runExecFile(\n 'git',\n ['-C', cwd, ...args],\n { actor: 'internal:git', triggeredBy: 'manual', targetPath: cwd },\n { maxBuffer: 10 * 1024 * 1024, captureOutput: false }\n );\n return stdout.trim();\n } catch (error: any) {\n const stderr: string | undefined = error?.stderr?.toString();\n // Gracefully handle non-git directories and repos with no commits\n if (stderr?.includes('not a git repository') || stderr?.includes('does not have any commits')) {\n return null;\n }\n throw error;\n }\n}\n\nasync function ensureRepo(projectPath: string): Promise<boolean> {\n const result = await execGit(['rev-parse', '--is-inside-work-tree'], projectPath);\n return result === 'true';\n}\n\nfunction parseNameStatus(output: string): Change[] {\n return output\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => {\n const parts = line.split('\\t');\n const status = parts[0] ?? '';\n const filePath = parts[1] ?? '';\n const oldPath = parts[2];\n const change: Change = { status, path: filePath };\n if (oldPath) change.oldPath = oldPath;\n return change;\n })\n .filter((entry) => entry.path.length > 0);\n}\n\nexport async function getRecentCommits(projectPath: string, limit: number): Promise<Commit[]> {\n const isRepo = await ensureRepo(projectPath);\n if (!isRepo) return [];\n\n const output = await execGit(\n ['log', `-n`, String(limit), '--pretty=format:%H%x09%an%x09%ad%x09%s', '--date=iso'],\n projectPath\n );\n\n if (!output) return [];\n\n return output.split('\\n').map((line) => {\n const [hash, author, date, message] = line.split('\\t');\n return { hash, author, date, message } as Commit;\n });\n}\n\nexport async function getLastCommit(projectPath: string): Promise<Commit | null> {\n const commits = await getRecentCommits(projectPath, 1);\n return commits[0] ?? null;\n}\n\nexport async function getStagedChanges(projectPath: string): Promise<Change[]> {\n const isRepo = await ensureRepo(projectPath);\n if (!isRepo) return [];\n\n const output = await execGit(['diff', '--cached', '--name-status'], projectPath);\n if (!output) return [];\n return parseNameStatus(output);\n}\n\nexport async function getUncommittedChanges(projectPath: string): Promise<Change[]> {\n const isRepo = await ensureRepo(projectPath);\n if (!isRepo) return [];\n\n const changes: Change[] = [];\n\n const unstaged = await execGit(['diff', '--name-status'], projectPath);\n if (unstaged) {\n changes.push(...parseNameStatus(unstaged));\n }\n\n const untracked = await execGit(['ls-files', '--others', '--exclude-standard'], projectPath);\n if (untracked) {\n changes.push(\n ...untracked\n .split('\\n')\n .map((p) => p.trim())\n .filter(Boolean)\n .map((p) => ({ status: '??', path: p }))\n );\n }\n\n return changes;\n}\n\n/**\n * Get a flat list of changed file paths in the working tree.\n * Convenience helper used by tooling (e.g. cache invalidation).\n *\n * Returns null if not a git repository.\n */\nexport async function getGitChangedFiles(projectPath: string): Promise<string[] | null> {\n const isRepo = await ensureRepo(projectPath);\n if (!isRepo) return null;\n\n const [staged, uncommitted] = await Promise.all([\n getStagedChanges(projectPath).catch(() => []),\n getUncommittedChanges(projectPath).catch(() => []),\n ]);\n\n const paths = new Set<string>();\n for (const change of [...staged, ...uncommitted]) {\n if (change.path) paths.add(change.path);\n if (change.oldPath) paths.add(change.oldPath);\n }\n\n return [...paths];\n}\n\nexport async function getDiff(projectPath: string, commitHash: string): Promise<string> {\n const isRepo = await ensureRepo(projectPath);\n if (!isRepo) return '';\n\n const diff = await execGit(['show', commitHash, '--unified=3', '--no-color'], projectPath);\n return diff ?? '';\n}\n\nexport async function getWorkingTreeDiff(projectPath: string, stagedOnly = false): Promise<string> {\n const isRepo = await ensureRepo(projectPath);\n if (!isRepo) return '';\n\n const args = stagedOnly ? ['diff', '--cached', '--unified=3', '--no-color'] : ['diff', '--unified=3', '--no-color'];\n const diff = await execGit(args, projectPath);\n return diff ?? '';\n}\n\nexport async function getUnpushedCommits(projectPath: string): Promise<Commit[]> {\n const isRepo = await ensureRepo(projectPath);\n if (!isRepo) return [];\n\n // Handles detached HEAD by falling back to HEAD if upstream missing\n const upstream = await execGit(['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'], projectPath);\n if (!upstream) {\n return getRecentCommits(projectPath, 10);\n }\n\n const output = await execGit(['log', `${upstream}..HEAD`, '--pretty=format:%H%x09%an%x09%ad%x09%s', '--date=iso'], projectPath);\n if (!output) return [];\n\n return output.split('\\n').filter(Boolean).map((line) => {\n const [hash, author, date, message] = line.split('\\t');\n return { hash, author, date, message } as Commit;\n });\n}\n\nexport function resolveRepoPath(projectPath: string): string {\n const gitDir = path.join(projectPath, '.git');\n if (existsSync(gitDir)) return projectPath;\n return projectPath;\n}\n\n/**\n * Check if the given path is inside a git repository\n */\nexport async function isGitRepo(projectPath: string): Promise<boolean> {\n const result = await execGit(['rev-parse', '--is-inside-work-tree'], projectPath);\n return result === 'true';\n}\n\n/**\n * Get files changed since a given timestamp\n * Uses git log to find commits after timestamp, then gets affected files\n * Returns null if not a git repo or on error\n */\nexport async function getChangedFilesSinceTimestamp(\n projectPath: string,\n timestamp: number\n): Promise<string[] | null> {\n const isRepo = await isGitRepo(projectPath);\n if (!isRepo) return null;\n\n try {\n // Convert timestamp to ISO date for git\n const sinceDate = new Date(timestamp).toISOString();\n \n // Set timeout for git operations (5 seconds total)\n const GIT_TIMEOUT_MS = 5000;\n const startTime = Date.now();\n \n // Get all files that changed in commits since the timestamp\n // Use Promise.race to timeout if git operations take too long\n const committedChangesPromise = execGit(\n ['log', `--since=${sinceDate}`, '--name-only', '--pretty=format:'],\n projectPath\n );\n const committedChangesTimeout = new Promise<string | null>((resolve) => {\n setTimeout(() => resolve(null), GIT_TIMEOUT_MS);\n });\n const committedChanges = await Promise.race([committedChangesPromise, committedChangesTimeout]);\n\n // Check if we've exceeded timeout\n if (Date.now() - startTime > GIT_TIMEOUT_MS) {\n return null;\n }\n\n // Get currently modified files (staged + unstaged) - run in parallel with timeout\n const stagedPromise = execGit(['diff', '--cached', '--name-only'], projectPath);\n const unstagedPromise = execGit(['diff', '--name-only'], projectPath);\n const untrackedPromise = execGit(\n ['ls-files', '--others', '--exclude-standard'],\n projectPath\n );\n \n const timeoutPromise = new Promise<null>((resolve) => {\n setTimeout(() => resolve(null), Math.max(0, GIT_TIMEOUT_MS - (Date.now() - startTime)));\n });\n \n const [stagedChanges, unstagedChanges, untrackedFiles] = await Promise.race([\n Promise.all([stagedPromise, unstagedPromise, untrackedPromise]),\n timeoutPromise.then(() => [null, null, null] as const)\n ]);\n\n // Combine all changed files\n const changedFiles = new Set<string>();\n \n const addFiles = (output: string | null) => {\n if (output) {\n output.split('\\n')\n .map(f => f.trim())\n .filter(Boolean)\n .forEach(f => changedFiles.add(path.join(projectPath, f)));\n }\n };\n\n addFiles(committedChanges);\n addFiles(stagedChanges);\n addFiles(unstagedChanges);\n addFiles(untrackedFiles);\n\n return Array.from(changedFiles);\n } catch {\n return null;\n }\n}\n","/**\n * Command Runner (with audit logging)\n *\n * Goal: Whenever Trie runs a shell command, record:\n * - command string\n * - exit code\n * - duration\n * - optional (redacted) stdout/stderr\n */\nimport { exec, execFile, execSync, type ExecException } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nimport {\n createAuditEntry,\n completeAuditEntry,\n logSkillExecution,\n type ExecutedCommand,\n type SkillExecution,\n} from './audit-logger.js';\n\nconst execAsync = promisify(exec);\nconst execFileAsync = promisify(execFile);\n\nexport type { ExecutedCommand, SkillExecution };\nexport type AuditTriggeredBy = SkillExecution['triggeredBy'];\n\nexport interface CommandAuditContext {\n /** Shown as `skillName` in audit logs; use something like `tool:pr-review` */\n actor: string;\n /** Where this came from in the product flow */\n triggeredBy: AuditTriggeredBy;\n /** Usually the working directory / repo path */\n targetPath: string;\n /** Optional string for `skillSource` */\n source?: string;\n}\n\nexport interface RunCommandOptions {\n cwd?: string;\n timeoutMs?: number;\n maxBuffer?: number;\n\n /** Capture stdout/stderr in the audit log */\n captureOutput?: boolean;\n /** Redact obvious secrets from captured output */\n redactOutput?: boolean;\n /** Max chars to keep per output stream */\n maxOutputChars?: number;\n}\n\nfunction redact(text: string): string {\n // Keep this conservative to avoid false redaction and avoid expensive processing.\n return text\n // Common key=value secrets\n .replace(/\\b(AWS|ANTHROPIC|OPENAI|GITHUB)_[A-Z0-9_]*\\s*=\\s*([^\\s\"'`]+)/gi, '$1_<REDACTED>=<REDACTED>')\n // Bearer tokens\n .replace(/\\bBearer\\s+[A-Za-z0-9\\-._~+/]+=*\\b/g, 'Bearer <REDACTED>')\n // GitHub tokens / generic tokens\n .replace(/\\bghp_[A-Za-z0-9]{20,}\\b/g, 'ghp_<REDACTED>')\n .replace(/\\b(?:xox[baprs]-)[A-Za-z0-9-]{10,}\\b/g, '<REDACTED_SLACK_TOKEN>')\n // AWS access key id (best-effort)\n .replace(/\\bAKIA[0-9A-Z]{16}\\b/g, 'AKIA<REDACTED>');\n}\n\nfunction clampOutput(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return text.slice(0, maxChars) + `\\n…(truncated ${text.length - maxChars} chars)`;\n}\n\nfunction buildCommandRecord(command: string): ExecutedCommand {\n return {\n command,\n timestamp: new Date().toISOString(),\n };\n}\n\nasync function finalizeAndWrite(\n entry: SkillExecution,\n cmd: ExecutedCommand,\n outcome: { success: boolean; exitCode?: number; stdout?: string; stderr?: string; error?: string; startedAt: number },\n options?: Pick<RunCommandOptions, 'captureOutput' | 'redactOutput' | 'maxOutputChars'>\n): Promise<void> {\n const duration = Date.now() - outcome.startedAt;\n cmd.duration = duration;\n if (outcome.exitCode !== undefined) {\n cmd.exitCode = outcome.exitCode;\n }\n\n const captureOutput = options?.captureOutput ?? false;\n const redactOutput = options?.redactOutput ?? true;\n const maxOutputChars = options?.maxOutputChars ?? 2000;\n\n if (captureOutput) {\n const out = outcome.stdout ?? '';\n const err = outcome.stderr ?? '';\n cmd.stdout = redactOutput ? redact(clampOutput(out, maxOutputChars)) : clampOutput(out, maxOutputChars);\n cmd.stderr = redactOutput ? redact(clampOutput(err, maxOutputChars)) : clampOutput(err, maxOutputChars);\n }\n\n const completed = completeAuditEntry(entry, outcome.success, outcome.error);\n await logSkillExecution(completed);\n}\n\nexport async function runShellCommand(\n command: string,\n audit: CommandAuditContext,\n options?: RunCommandOptions\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const startedAt = Date.now();\n const entry = createAuditEntry(audit.actor, audit.source ?? 'trie', audit.triggeredBy, audit.targetPath);\n const cmd = buildCommandRecord(command);\n entry.commands?.push(cmd);\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: options?.cwd,\n timeout: options?.timeoutMs,\n maxBuffer: options?.maxBuffer,\n });\n\n await finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout, stderr, startedAt }, options);\n return { stdout: stdout ?? '', stderr: stderr ?? '', exitCode: 0 };\n } catch (e) {\n const err = e as ExecException & { stdout?: unknown; stderr?: unknown; code?: unknown };\n const stdout = typeof err.stdout === 'string' ? err.stdout : '';\n const stderr = typeof err.stderr === 'string' ? err.stderr : '';\n const exitCode = typeof err.code === 'number' ? err.code : 1;\n\n await finalizeAndWrite(\n entry,\n cmd,\n { success: false, exitCode, stdout, stderr, error: err.message, startedAt },\n // Capture output for failures by default (so audits are useful)\n { ...options, captureOutput: options?.captureOutput ?? true }\n );\n\n return { stdout, stderr, exitCode };\n }\n}\n\nexport function runShellCommandSync(\n command: string,\n audit: CommandAuditContext,\n options?: Omit<RunCommandOptions, 'timeoutMs'> & { timeoutMs?: number }\n): { stdout: string; exitCode: number } {\n const startedAt = Date.now();\n const entry = createAuditEntry(audit.actor, audit.source ?? 'trie', audit.triggeredBy, audit.targetPath);\n const cmd = buildCommandRecord(command);\n entry.commands?.push(cmd);\n\n try {\n const stdout = execSync(command, {\n cwd: options?.cwd,\n timeout: options?.timeoutMs,\n maxBuffer: options?.maxBuffer,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n // Fire-and-forget write; sync APIs can’t await.\n void finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout, stderr: '', startedAt }, options);\n return { stdout: stdout ?? '', exitCode: 0 };\n } catch (e) {\n const err = e as ExecException & { stdout?: unknown; stderr?: unknown; status?: unknown };\n const stdout = typeof err.stdout === 'string' ? err.stdout : '';\n const stderr = typeof err.stderr === 'string' ? err.stderr : '';\n const exitCode = typeof err.status === 'number' ? err.status : 1;\n\n void finalizeAndWrite(\n entry,\n cmd,\n { success: false, exitCode, stdout, stderr, error: err.message, startedAt },\n { ...options, captureOutput: options?.captureOutput ?? true }\n );\n\n return { stdout, exitCode };\n }\n}\n\nexport async function runExecFile(\n file: string,\n args: string[],\n audit: CommandAuditContext,\n options?: Omit<RunCommandOptions, 'timeoutMs'> & { timeoutMs?: number }\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const startedAt = Date.now();\n const command = [file, ...args].join(' ');\n const entry = createAuditEntry(audit.actor, audit.source ?? 'trie', audit.triggeredBy, audit.targetPath);\n const cmd = buildCommandRecord(command);\n entry.commands?.push(cmd);\n\n try {\n const { stdout, stderr } = await execFileAsync(file, args, {\n cwd: options?.cwd,\n timeout: options?.timeoutMs,\n maxBuffer: options?.maxBuffer,\n });\n\n await finalizeAndWrite(entry, cmd, { success: true, exitCode: 0, stdout: String(stdout ?? ''), stderr: String(stderr ?? ''), startedAt }, options);\n return { stdout: String(stdout ?? ''), stderr: String(stderr ?? ''), exitCode: 0 };\n } catch (e) {\n const err = e as ExecException & { stdout?: unknown; stderr?: unknown; code?: unknown };\n const stdout = typeof err.stdout === 'string' ? err.stdout : '';\n const stderr = typeof err.stderr === 'string' ? err.stderr : '';\n const exitCode = typeof err.code === 'number' ? err.code : 1;\n\n await finalizeAndWrite(\n entry,\n cmd,\n { success: false, exitCode, stdout, stderr, error: err.message, startedAt },\n { ...options, captureOutput: options?.captureOutput ?? true }\n );\n return { stdout, stderr, exitCode };\n }\n}\n\n","/**\n * Audit logger stub\n *\n * Audit functionality has been integrated into the decision ledger.\n * This module exists to keep legacy CLI/tooling paths working without the old skills system.\n */\n\nexport interface AuditStatistics {\n totalScans: number;\n totalIssues: number;\n criticalCount: number;\n seriousCount: number;\n moderateCount: number;\n lowCount: number;\n totalExecutions: number;\n successfulExecutions: number;\n failedExecutions: number;\n uniqueSkills: number;\n totalCommands: number;\n blockedCommands: number;\n totalNetworkCalls: number;\n blockedNetworkCalls: number;\n}\n\nexport interface AuditEntry {\n id: string;\n timestamp: string;\n command: string;\n status: string;\n commands?: ExecutedCommand[];\n}\n\nexport interface ExecutedCommand {\n command: string;\n timestamp: string;\n exitCode?: number;\n duration?: number;\n stdout?: string;\n stderr?: string;\n}\n\nexport interface SkillExecution {\n skillName: string;\n skillSource: string;\n triggeredBy: 'scan' | 'mcp' | 'cli' | 'watch' | 'manual';\n targetPath: string;\n startedAt: string;\n completedAt?: string;\n success?: boolean;\n error?: string;\n commands?: ExecutedCommand[];\n}\n\nexport function formatAuditLog(_entry: AuditEntry): string {\n return 'Audit logging has been integrated into the decision ledger';\n}\n\nexport function getAuditStatistics(): AuditStatistics {\n return {\n totalScans: 0,\n totalIssues: 0,\n criticalCount: 0,\n seriousCount: 0,\n moderateCount: 0,\n lowCount: 0,\n totalExecutions: 0,\n successfulExecutions: 0,\n failedExecutions: 0,\n uniqueSkills: 0,\n totalCommands: 0,\n blockedCommands: 0,\n totalNetworkCalls: 0,\n blockedNetworkCalls: 0,\n };\n}\n\nexport function createAuditEntry(\n skillName: string,\n skillSource: string,\n triggeredBy: SkillExecution['triggeredBy'],\n targetPath: string\n): SkillExecution {\n return {\n skillName,\n skillSource,\n triggeredBy,\n targetPath,\n startedAt: new Date().toISOString(),\n commands: [],\n };\n}\n\nexport function completeAuditEntry(\n entry: SkillExecution,\n success: boolean,\n error?: string\n): SkillExecution {\n const result: SkillExecution = {\n ...entry,\n completedAt: new Date().toISOString(),\n success,\n };\n if (error !== undefined) {\n result.error = error;\n }\n return result;\n}\n\nexport async function logSkillExecution(_execution: SkillExecution): Promise<void> {\n // Stub - no-op\n}\n\nexport async function getRecentAuditLogs(_limit: number = 10): Promise<AuditEntry[]> {\n return [];\n}\n\nexport async function getSkillAuditLogs(_skillName: string): Promise<AuditEntry[]> {\n return [];\n}\n\n"],"mappings":"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","names":[]}