@backendkit-labs/agent-coding 0.14.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.
Files changed (193) hide show
  1. package/dist/agents/AgentLoader.d.ts +33 -0
  2. package/dist/agents/AgentLoader.d.ts.map +1 -0
  3. package/dist/agents/AgentLoader.js +167 -0
  4. package/dist/agents/AgentLoader.js.map +1 -0
  5. package/dist/agents/profiles.d.ts +3 -0
  6. package/dist/agents/profiles.d.ts.map +1 -0
  7. package/dist/agents/profiles.js +121 -0
  8. package/dist/agents/profiles.js.map +1 -0
  9. package/dist/agents/prompts/architecture.d.ts +2 -0
  10. package/dist/agents/prompts/architecture.d.ts.map +1 -0
  11. package/dist/agents/prompts/architecture.js +151 -0
  12. package/dist/agents/prompts/architecture.js.map +1 -0
  13. package/dist/agents/prompts/backend.d.ts +2 -0
  14. package/dist/agents/prompts/backend.d.ts.map +1 -0
  15. package/dist/agents/prompts/backend.js +96 -0
  16. package/dist/agents/prompts/backend.js.map +1 -0
  17. package/dist/agents/prompts/coder.d.ts +2 -0
  18. package/dist/agents/prompts/coder.d.ts.map +1 -0
  19. package/dist/agents/prompts/coder.js +50 -0
  20. package/dist/agents/prompts/coder.js.map +1 -0
  21. package/dist/agents/prompts/data.d.ts +2 -0
  22. package/dist/agents/prompts/data.d.ts.map +1 -0
  23. package/dist/agents/prompts/data.js +123 -0
  24. package/dist/agents/prompts/data.js.map +1 -0
  25. package/dist/agents/prompts/frontend.d.ts +2 -0
  26. package/dist/agents/prompts/frontend.d.ts.map +1 -0
  27. package/dist/agents/prompts/frontend.js +91 -0
  28. package/dist/agents/prompts/frontend.js.map +1 -0
  29. package/dist/agents/prompts/general.d.ts +2 -0
  30. package/dist/agents/prompts/general.d.ts.map +1 -0
  31. package/dist/agents/prompts/general.js +93 -0
  32. package/dist/agents/prompts/general.js.map +1 -0
  33. package/dist/agents/prompts/infrastructure.d.ts +2 -0
  34. package/dist/agents/prompts/infrastructure.d.ts.map +1 -0
  35. package/dist/agents/prompts/infrastructure.js +145 -0
  36. package/dist/agents/prompts/infrastructure.js.map +1 -0
  37. package/dist/agents/prompts/project-manager.d.ts +2 -0
  38. package/dist/agents/prompts/project-manager.d.ts.map +1 -0
  39. package/dist/agents/prompts/project-manager.js +66 -0
  40. package/dist/agents/prompts/project-manager.js.map +1 -0
  41. package/dist/agents/prompts/qa.d.ts +2 -0
  42. package/dist/agents/prompts/qa.d.ts.map +1 -0
  43. package/dist/agents/prompts/qa.js +166 -0
  44. package/dist/agents/prompts/qa.js.map +1 -0
  45. package/dist/agents/prompts/security.d.ts +2 -0
  46. package/dist/agents/prompts/security.d.ts.map +1 -0
  47. package/dist/agents/prompts/security.js +129 -0
  48. package/dist/agents/prompts/security.js.map +1 -0
  49. package/dist/config/ConfigLoader.d.ts +27 -0
  50. package/dist/config/ConfigLoader.d.ts.map +1 -0
  51. package/dist/config/ConfigLoader.js +167 -0
  52. package/dist/config/ConfigLoader.js.map +1 -0
  53. package/dist/index.d.ts +160 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +340 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/orchestration/capability-matrix.d.ts +10 -0
  58. package/dist/orchestration/capability-matrix.d.ts.map +1 -0
  59. package/dist/orchestration/capability-matrix.js +48 -0
  60. package/dist/orchestration/capability-matrix.js.map +1 -0
  61. package/dist/providers/AnthropicProvider.d.ts +20 -0
  62. package/dist/providers/AnthropicProvider.d.ts.map +1 -0
  63. package/dist/providers/AnthropicProvider.js +185 -0
  64. package/dist/providers/AnthropicProvider.js.map +1 -0
  65. package/dist/providers/DeepSeekProvider.d.ts +11 -0
  66. package/dist/providers/DeepSeekProvider.d.ts.map +1 -0
  67. package/dist/providers/DeepSeekProvider.js +18 -0
  68. package/dist/providers/DeepSeekProvider.js.map +1 -0
  69. package/dist/providers/OpenAICompatibleProvider.d.ts +22 -0
  70. package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -0
  71. package/dist/providers/OpenAICompatibleProvider.js +124 -0
  72. package/dist/providers/OpenAICompatibleProvider.js.map +1 -0
  73. package/dist/skills/builtins/global.d.ts +7 -0
  74. package/dist/skills/builtins/global.d.ts.map +1 -0
  75. package/dist/skills/builtins/global.js +208 -0
  76. package/dist/skills/builtins/global.js.map +1 -0
  77. package/dist/skills/builtins/go-pack.d.ts +7 -0
  78. package/dist/skills/builtins/go-pack.d.ts.map +1 -0
  79. package/dist/skills/builtins/go-pack.js +263 -0
  80. package/dist/skills/builtins/go-pack.js.map +1 -0
  81. package/dist/skills/builtins/java-pack.d.ts +7 -0
  82. package/dist/skills/builtins/java-pack.d.ts.map +1 -0
  83. package/dist/skills/builtins/java-pack.js +272 -0
  84. package/dist/skills/builtins/java-pack.js.map +1 -0
  85. package/dist/skills/builtins/kotlin-pack.d.ts +9 -0
  86. package/dist/skills/builtins/kotlin-pack.d.ts.map +1 -0
  87. package/dist/skills/builtins/kotlin-pack.js +292 -0
  88. package/dist/skills/builtins/kotlin-pack.js.map +1 -0
  89. package/dist/skills/builtins/node-pack.d.ts +7 -0
  90. package/dist/skills/builtins/node-pack.d.ts.map +1 -0
  91. package/dist/skills/builtins/node-pack.js +750 -0
  92. package/dist/skills/builtins/node-pack.js.map +1 -0
  93. package/dist/skills/builtins/python-pack.d.ts +7 -0
  94. package/dist/skills/builtins/python-pack.d.ts.map +1 -0
  95. package/dist/skills/builtins/python-pack.js +303 -0
  96. package/dist/skills/builtins/python-pack.js.map +1 -0
  97. package/dist/skills/index.d.ts +7 -0
  98. package/dist/skills/index.d.ts.map +1 -0
  99. package/dist/skills/index.js +16 -0
  100. package/dist/skills/index.js.map +1 -0
  101. package/dist/store/LearningRouter.d.ts +17 -0
  102. package/dist/store/LearningRouter.d.ts.map +1 -0
  103. package/dist/store/LearningRouter.js +165 -0
  104. package/dist/store/LearningRouter.js.map +1 -0
  105. package/dist/store/PersistentMemory.d.ts +10 -0
  106. package/dist/store/PersistentMemory.d.ts.map +1 -0
  107. package/dist/store/PersistentMemory.js +29 -0
  108. package/dist/store/PersistentMemory.js.map +1 -0
  109. package/dist/store/ProjectStore.d.ts +29 -0
  110. package/dist/store/ProjectStore.d.ts.map +1 -0
  111. package/dist/store/ProjectStore.js +191 -0
  112. package/dist/store/ProjectStore.js.map +1 -0
  113. package/dist/store/__tests__/PersistentMemory.test.d.ts +2 -0
  114. package/dist/store/__tests__/PersistentMemory.test.d.ts.map +1 -0
  115. package/dist/store/__tests__/PersistentMemory.test.js +46 -0
  116. package/dist/store/__tests__/PersistentMemory.test.js.map +1 -0
  117. package/dist/tools/__tests__/file-tools.test.d.ts +2 -0
  118. package/dist/tools/__tests__/file-tools.test.d.ts.map +1 -0
  119. package/dist/tools/__tests__/file-tools.test.js +144 -0
  120. package/dist/tools/__tests__/file-tools.test.js.map +1 -0
  121. package/dist/tools/__tests__/path-sandbox.test.d.ts +2 -0
  122. package/dist/tools/__tests__/path-sandbox.test.d.ts.map +1 -0
  123. package/dist/tools/__tests__/path-sandbox.test.js +45 -0
  124. package/dist/tools/__tests__/path-sandbox.test.js.map +1 -0
  125. package/dist/tools/__tests__/run-command.test.d.ts +2 -0
  126. package/dist/tools/__tests__/run-command.test.d.ts.map +1 -0
  127. package/dist/tools/__tests__/run-command.test.js +61 -0
  128. package/dist/tools/__tests__/run-command.test.js.map +1 -0
  129. package/dist/tools/append-log.d.ts +2 -0
  130. package/dist/tools/append-log.d.ts.map +1 -0
  131. package/dist/tools/append-log.js +3 -0
  132. package/dist/tools/append-log.js.map +1 -0
  133. package/dist/tools/edit-file.d.ts +2 -0
  134. package/dist/tools/edit-file.d.ts.map +1 -0
  135. package/dist/tools/edit-file.js +45 -0
  136. package/dist/tools/edit-file.js.map +1 -0
  137. package/dist/tools/list-directory.d.ts +2 -0
  138. package/dist/tools/list-directory.d.ts.map +1 -0
  139. package/dist/tools/list-directory.js +47 -0
  140. package/dist/tools/list-directory.js.map +1 -0
  141. package/dist/tools/path-sandbox.d.ts +31 -0
  142. package/dist/tools/path-sandbox.d.ts.map +1 -0
  143. package/dist/tools/path-sandbox.js +99 -0
  144. package/dist/tools/path-sandbox.js.map +1 -0
  145. package/dist/tools/read-file.d.ts +2 -0
  146. package/dist/tools/read-file.d.ts.map +1 -0
  147. package/dist/tools/read-file.js +28 -0
  148. package/dist/tools/read-file.js.map +1 -0
  149. package/dist/tools/run-command.d.ts +2 -0
  150. package/dist/tools/run-command.d.ts.map +1 -0
  151. package/dist/tools/run-command.js +192 -0
  152. package/dist/tools/run-command.js.map +1 -0
  153. package/dist/tools/save-audit.d.ts +4 -0
  154. package/dist/tools/save-audit.d.ts.map +1 -0
  155. package/dist/tools/save-audit.js +42 -0
  156. package/dist/tools/save-audit.js.map +1 -0
  157. package/dist/tools/save-context.d.ts +2 -0
  158. package/dist/tools/save-context.d.ts.map +1 -0
  159. package/dist/tools/save-context.js +18 -0
  160. package/dist/tools/save-context.js.map +1 -0
  161. package/dist/tools/save-learning.d.ts +2 -0
  162. package/dist/tools/save-learning.d.ts.map +1 -0
  163. package/dist/tools/save-learning.js +41 -0
  164. package/dist/tools/save-learning.js.map +1 -0
  165. package/dist/tools/save-user-preference.d.ts +3 -0
  166. package/dist/tools/save-user-preference.d.ts.map +1 -0
  167. package/dist/tools/save-user-preference.js +22 -0
  168. package/dist/tools/save-user-preference.js.map +1 -0
  169. package/dist/tools/search-files.d.ts +2 -0
  170. package/dist/tools/search-files.d.ts.map +1 -0
  171. package/dist/tools/search-files.js +170 -0
  172. package/dist/tools/search-files.js.map +1 -0
  173. package/dist/tools/secret-scanner.d.ts +15 -0
  174. package/dist/tools/secret-scanner.d.ts.map +1 -0
  175. package/dist/tools/secret-scanner.js +44 -0
  176. package/dist/tools/secret-scanner.js.map +1 -0
  177. package/dist/tools/update-session.d.ts +3 -0
  178. package/dist/tools/update-session.d.ts.map +1 -0
  179. package/dist/tools/update-session.js +49 -0
  180. package/dist/tools/update-session.js.map +1 -0
  181. package/dist/tools/write-file.d.ts +2 -0
  182. package/dist/tools/write-file.d.ts.map +1 -0
  183. package/dist/tools/write-file.js +32 -0
  184. package/dist/tools/write-file.js.map +1 -0
  185. package/dist/workflows/InitWorkflow.d.ts +6 -0
  186. package/dist/workflows/InitWorkflow.d.ts.map +1 -0
  187. package/dist/workflows/InitWorkflow.js +448 -0
  188. package/dist/workflows/InitWorkflow.js.map +1 -0
  189. package/dist/workflows/__tests__/InitWorkflow.test.d.ts +2 -0
  190. package/dist/workflows/__tests__/InitWorkflow.test.d.ts.map +1 -0
  191. package/dist/workflows/__tests__/InitWorkflow.test.js +43 -0
  192. package/dist/workflows/__tests__/InitWorkflow.test.js.map +1 -0
  193. package/package.json +34 -0
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.editFileTool = void 0;
4
+ const fs_1 = require("fs");
5
+ const agent_core_1 = require("@backendkit-labs/agent-core");
6
+ const path_sandbox_1 = require("./path-sandbox");
7
+ const secret_scanner_1 = require("./secret-scanner");
8
+ exports.editFileTool = (0, agent_core_1.defineTool)({
9
+ name: 'edit_file',
10
+ description: 'Replace an exact string in a file. Safer than write_file for partial edits.',
11
+ input: agent_core_1.z.object({
12
+ file_path: agent_core_1.z.string().describe('Path to the file'),
13
+ old_string: agent_core_1.z.string().describe('Exact text to replace (must be unique in the file)'),
14
+ new_string: agent_core_1.z.string().describe('Replacement text'),
15
+ replace_all: agent_core_1.z.boolean().default(false).describe('Replace all occurrences (default: false)'),
16
+ }),
17
+ execute: async ({ file_path, old_string, new_string, replace_all }, ctx) => {
18
+ try {
19
+ const abs = (0, path_sandbox_1.resolveAndCheck)(ctx.workingDir, file_path);
20
+ const fwWarn = (0, path_sandbox_1.checkFrameworkProtection)(abs, ctx.workingDir);
21
+ if (fwWarn)
22
+ return `Error: ${fwWarn}`;
23
+ const content = (0, fs_1.readFileSync)(abs, 'utf-8');
24
+ if (!content.includes(old_string)) {
25
+ return `Error: old_string not found in "${abs}"`;
26
+ }
27
+ if (!replace_all) {
28
+ const count = content.split(old_string).length - 1;
29
+ if (count > 1) {
30
+ return `Error: old_string appears ${count} times in "${abs}". Use replace_all: true or provide more context.`;
31
+ }
32
+ }
33
+ const updated = replace_all
34
+ ? content.split(old_string).join(new_string)
35
+ : content.replace(old_string, new_string);
36
+ const warning = (0, secret_scanner_1.warnIfSecrets)(abs, updated);
37
+ (0, agent_core_1.atomicWriteSync)(abs, updated);
38
+ return warning ? `Edited: ${abs}\n⚠ ${warning}` : `Edited: ${abs}`;
39
+ }
40
+ catch (err) {
41
+ return `Error: ${err.message}`;
42
+ }
43
+ },
44
+ });
45
+ //# sourceMappingURL=edit-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-file.js","sourceRoot":"","sources":["../../src/tools/edit-file.ts"],"names":[],"mappings":";;;AAAA,2BAAkC;AAClC,4DAA6E;AAC7E,iDAA2E;AAC3E,qDAAiD;AAEpC,QAAA,YAAY,GAAG,IAAA,uBAAU,EAAC;IACnC,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,6EAA6E;IAC1F,KAAK,EAAE,cAAC,CAAC,MAAM,CAAC;QACZ,SAAS,EAAI,cAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QACpD,UAAU,EAAG,cAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QACtF,UAAU,EAAG,cAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QACpD,WAAW,EAAE,cAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,0CAA0C,CAAC;KAC/F,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,EAAE;QACvE,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,IAAA,8BAAe,EAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,IAAA,uCAAwB,EAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7D,IAAI,MAAM;gBAAE,OAAO,UAAU,MAAM,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAE3C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBAChC,OAAO,mCAAmC,GAAG,GAAG,CAAC;YACrD,CAAC;YAED,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;gBACnD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACZ,OAAO,6BAA6B,KAAK,cAAc,GAAG,mDAAmD,CAAC;gBAClH,CAAC;YACL,CAAC;YAED,MAAM,OAAO,GAAG,WAAW;gBACvB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;gBAC5C,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAE9C,MAAM,OAAO,GAAG,IAAA,8BAAa,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC5C,IAAA,4BAAe,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,OAAO,CAAC,CAAC,CAAC,WAAW,GAAG,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,OAAO,UAAW,GAAa,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC;IACL,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const listDirectoryTool: import("@backendkit-labs/agent-core").ToolDefinition;
2
+ //# sourceMappingURL=list-directory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-directory.d.ts","sourceRoot":"","sources":["../../src/tools/list-directory.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,iBAAiB,sDAkB5B,CAAC"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listDirectoryTool = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const agent_core_1 = require("@backendkit-labs/agent-core");
7
+ const path_sandbox_1 = require("./path-sandbox");
8
+ function listRecursive(dir, depth, maxDepth) {
9
+ if (depth > maxDepth)
10
+ return [];
11
+ const lines = [];
12
+ for (const entry of (0, fs_1.readdirSync)(dir, { withFileTypes: true })) {
13
+ if (entry.name.startsWith('.') || entry.name === 'node_modules')
14
+ continue;
15
+ const indent = ' '.repeat(depth);
16
+ if (entry.isDirectory()) {
17
+ lines.push(`${indent}${entry.name}/`);
18
+ lines.push(...listRecursive((0, path_1.join)(dir, entry.name), depth + 1, maxDepth));
19
+ }
20
+ else {
21
+ lines.push(`${indent}${entry.name}`);
22
+ }
23
+ }
24
+ return lines;
25
+ }
26
+ exports.listDirectoryTool = (0, agent_core_1.defineTool)({
27
+ name: 'list_directory',
28
+ description: 'List files and directories inside the working directory, recursively.',
29
+ input: agent_core_1.z.object({
30
+ path: agent_core_1.z.string().describe('Directory path to list'),
31
+ max_depth: agent_core_1.z.number().int().min(1).max(10).default(3).describe('Max recursion depth (default: 3)'),
32
+ }),
33
+ execute: async ({ path: inputPath, max_depth }, ctx) => {
34
+ try {
35
+ const abs = (0, path_sandbox_1.resolveAndCheck)(ctx.workingDir, inputPath);
36
+ const stat = (0, fs_1.statSync)(abs);
37
+ if (!stat.isDirectory())
38
+ return `${abs} (file, not a directory)`;
39
+ const lines = listRecursive(abs, 0, max_depth);
40
+ return lines.join('\n') || '(empty directory)';
41
+ }
42
+ catch (err) {
43
+ return `Error: ${err.message}`;
44
+ }
45
+ },
46
+ });
47
+ //# sourceMappingURL=list-directory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-directory.js","sourceRoot":"","sources":["../../src/tools/list-directory.ts"],"names":[],"mappings":";;;AAAA,2BAA2C;AAC3C,+BAA4B;AAC5B,4DAA4D;AAC5D,iDAAiD;AAEjD,SAAS,aAAa,CAAC,GAAW,EAAE,KAAa,EAAE,QAAgB;IAC/D,IAAI,KAAK,GAAG,QAAQ;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,IAAA,gBAAW,EAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5D,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;YAAE,SAAS;QAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAA,WAAI,EAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC7E,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAEY,QAAA,iBAAiB,GAAG,IAAA,uBAAU,EAAC;IACxC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,uEAAuE;IACpF,KAAK,EAAE,cAAC,CAAC,MAAM,CAAC;QACZ,IAAI,EAAO,cAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QACxD,SAAS,EAAE,cAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC;KACrG,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE;QACnD,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,IAAA,8BAAe,EAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACvD,MAAM,IAAI,GAAG,IAAA,aAAQ,EAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBAAE,OAAO,GAAG,GAAG,0BAA0B,CAAC;YACjE,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;YAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,OAAO,UAAW,GAAa,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC;IACL,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Resolves `filePath` relative to `workingDir` and verifies the result
3
+ * is contained within `workingDir`. Throws on path traversal attempts.
4
+ *
5
+ * Uses prefix comparison instead of relative() to correctly handle cross-drive
6
+ * paths (D:\outside) and UNC paths (\\server\share) on Windows, where relative()
7
+ * returns an absolute path that does not start with '..'.
8
+ */
9
+ /**
10
+ * Resolves `filePath` and verifies it is contained within one of the allowed
11
+ * roots: `workingDir` (primary) or any `additionalRoots` (e.g. the agent's
12
+ * memory directory at ~/.{appName}/projects/{key}).
13
+ * Throws on path traversal attempts outside all allowed roots.
14
+ */
15
+ export declare function resolveAndCheck(workingDir: string | undefined, filePath: string, additionalRoots?: string[]): string;
16
+ /**
17
+ * Blocks writes to framework source directories when the agent is running in a
18
+ * project context (workingDir is NOT a framework package directory).
19
+ *
20
+ * Returns an error string when protection triggers, undefined when the write
21
+ * is safe.
22
+ *
23
+ * Protection is SKIPPED when:
24
+ * - workingDir itself is inside a protected segment (user is developing the
25
+ * framework — all writes to framework source are intentional).
26
+ * - workingDir is the monorepo root (user has explicitly scoped to the full
27
+ * repo; checkFrameworkProtection cannot tell which project they intend to
28
+ * work on, so it defers to path-sandbox alone and the startup warning).
29
+ */
30
+ export declare function checkFrameworkProtection(abs: string, workingDir: string | undefined): string | undefined;
31
+ //# sourceMappingURL=path-sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-sandbox.d.ts","sourceRoot":"","sources":["../../src/tools/path-sandbox.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH;;;;;GAKG;AACH,wBAAgB,eAAe,CAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,QAAQ,EAAE,MAAM,EAChB,eAAe,GAAE,MAAM,EAAO,GAC/B,MAAM,CA2BR;AAmBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAgCxG"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveAndCheck = resolveAndCheck;
4
+ exports.checkFrameworkProtection = checkFrameworkProtection;
5
+ const path_1 = require("path");
6
+ /**
7
+ * Resolves `filePath` relative to `workingDir` and verifies the result
8
+ * is contained within `workingDir`. Throws on path traversal attempts.
9
+ *
10
+ * Uses prefix comparison instead of relative() to correctly handle cross-drive
11
+ * paths (D:\outside) and UNC paths (\\server\share) on Windows, where relative()
12
+ * returns an absolute path that does not start with '..'.
13
+ */
14
+ /**
15
+ * Resolves `filePath` and verifies it is contained within one of the allowed
16
+ * roots: `workingDir` (primary) or any `additionalRoots` (e.g. the agent's
17
+ * memory directory at ~/.{appName}/projects/{key}).
18
+ * Throws on path traversal attempts outside all allowed roots.
19
+ */
20
+ function resolveAndCheck(workingDir, filePath, additionalRoots = []) {
21
+ const cwd = workingDir ?? process.cwd();
22
+ const abs = (0, path_1.resolve)(cwd, filePath);
23
+ // Normalize separators to forward slashes before comparison so that
24
+ // mixed-slash paths (workingDir passed as C:/... but resolve() returns C:\...)
25
+ // don't cause false-negative containment checks on Windows.
26
+ const norm = (p) => {
27
+ const s = process.platform === 'win32' ? p.toLowerCase() : p;
28
+ return s.replace(/\\/g, '/');
29
+ };
30
+ const isInside = (root) => {
31
+ const prefix = norm(root).endsWith('/') ? norm(root) : norm(root) + '/';
32
+ return norm(abs) === norm(root) || norm(abs).startsWith(prefix);
33
+ };
34
+ if (isInside(cwd))
35
+ return abs;
36
+ for (const root of additionalRoots) {
37
+ if (isInside(root))
38
+ return abs;
39
+ }
40
+ throw new Error(`Access denied: "${filePath}" resolves outside the working directory. ` +
41
+ `Path traversal is not allowed.`);
42
+ }
43
+ /**
44
+ * Framework-level directory segments that agents must never modify.
45
+ * These are core source directories — writing to them from a project context
46
+ * would corrupt the framework itself.
47
+ *
48
+ * Checked as relative path segments so they work regardless of where the
49
+ * monorepo is installed.
50
+ */
51
+ const PROTECTED_SEGMENTS = [
52
+ 'packages/core/src',
53
+ 'packages/coding/src',
54
+ 'packages/mcp-server/src',
55
+ 'packages\\core\\src',
56
+ 'packages\\coding\\src',
57
+ 'packages\\mcp-server\\src',
58
+ ];
59
+ /**
60
+ * Blocks writes to framework source directories when the agent is running in a
61
+ * project context (workingDir is NOT a framework package directory).
62
+ *
63
+ * Returns an error string when protection triggers, undefined when the write
64
+ * is safe.
65
+ *
66
+ * Protection is SKIPPED when:
67
+ * - workingDir itself is inside a protected segment (user is developing the
68
+ * framework — all writes to framework source are intentional).
69
+ * - workingDir is the monorepo root (user has explicitly scoped to the full
70
+ * repo; checkFrameworkProtection cannot tell which project they intend to
71
+ * work on, so it defers to path-sandbox alone and the startup warning).
72
+ */
73
+ function checkFrameworkProtection(abs, workingDir) {
74
+ if (!workingDir)
75
+ return undefined;
76
+ const cwdNorm = workingDir.replace(/\\/g, '/').toLowerCase();
77
+ const absNorm = abs.replace(/\\/g, '/').toLowerCase();
78
+ // Skip protection when workingDir IS a framework package directory.
79
+ // The user is deliberately developing the framework.
80
+ const workingOnFramework = PROTECTED_SEGMENTS.some(seg => cwdNorm.includes(seg.replace(/\\/g, '/').toLowerCase()));
81
+ if (workingOnFramework)
82
+ return undefined;
83
+ // Skip protection when the target is not inside a protected segment.
84
+ const triggered = PROTECTED_SEGMENTS.find(seg => absNorm.includes(seg.replace(/\\/g, '/').toLowerCase()));
85
+ if (!triggered)
86
+ return undefined;
87
+ // Skip protection when workingDir is a direct ancestor of the protected
88
+ // segment — i.e., the monorepo root. Use /cwd or WORKING_DIR to narrow scope.
89
+ const triggerNorm = triggered.replace(/\\/g, '/').toLowerCase();
90
+ const isAncestor = triggerNorm.startsWith(cwdNorm.replace(/\\/g, '/')) ||
91
+ cwdNorm.split('/').length <= 2; // very short path = likely root
92
+ if (isAncestor)
93
+ return undefined;
94
+ const rel = (0, path_1.relative)(workingDir, abs).replace(/\\/g, '/');
95
+ return (`⛔ Framework protection: "${rel}" is inside a protected source directory. ` +
96
+ `Agents should not modify framework source files while working on a project. ` +
97
+ `Use /cwd <framework-root> or set WORKING_DIR to the repo root if you intend to develop the framework.`);
98
+ }
99
+ //# sourceMappingURL=path-sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-sandbox.js","sourceRoot":"","sources":["../../src/tools/path-sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const readFileTool: import("@backendkit-labs/agent-core").ToolDefinition;
2
+ //# sourceMappingURL=read-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-file.d.ts","sourceRoot":"","sources":["../../src/tools/read-file.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,sDAmBvB,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readFileTool = void 0;
4
+ const fs_1 = require("fs");
5
+ const agent_core_1 = require("@backendkit-labs/agent-core");
6
+ const path_sandbox_1 = require("./path-sandbox");
7
+ exports.readFileTool = (0, agent_core_1.defineTool)({
8
+ name: 'read_file',
9
+ description: [
10
+ 'Read the contents of a file.',
11
+ 'Allowed roots: the active working directory and the agent memory directory (~/.{appName}/projects/{key}/).',
12
+ 'Use relative paths for project files; use the full path for memory files (e.g. memory/session.md).',
13
+ ].join(' '),
14
+ input: agent_core_1.z.object({
15
+ file_path: agent_core_1.z.string().describe('Relative path (project file) or full path (memory file)'),
16
+ }),
17
+ execute: async ({ file_path }, ctx) => {
18
+ try {
19
+ const memoryDir = ctx.store?.projectDir;
20
+ const abs = (0, path_sandbox_1.resolveAndCheck)(ctx.workingDir, file_path, memoryDir ? [memoryDir] : []);
21
+ return (0, fs_1.readFileSync)(abs, 'utf-8');
22
+ }
23
+ catch (err) {
24
+ return `Error: ${err.message}`;
25
+ }
26
+ },
27
+ });
28
+ //# sourceMappingURL=read-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../src/tools/read-file.ts"],"names":[],"mappings":";;;AAAA,2BAAkC;AAClC,4DAA4D;AAC5D,iDAAiD;AAEpC,QAAA,YAAY,GAAG,IAAA,uBAAU,EAAC;IACnC,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE;QACT,8BAA8B;QAC9B,4GAA4G;QAC5G,oGAAoG;KACvG,CAAC,IAAI,CAAC,GAAG,CAAC;IACX,KAAK,EAAE,cAAC,CAAC,MAAM,CAAC;QACZ,SAAS,EAAE,cAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;KAC5F,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE;QAClC,IAAI,CAAC;YACD,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC;YACxC,MAAM,GAAG,GAAG,IAAA,8BAAe,EAAC,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrF,OAAO,IAAA,iBAAY,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,OAAO,UAAW,GAAa,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC;IACL,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const runCommandTool: import("@backendkit-labs/agent-core").ToolDefinition;
2
+ //# sourceMappingURL=run-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-command.d.ts","sourceRoot":"","sources":["../../src/tools/run-command.ts"],"names":[],"mappings":"AAuFA,eAAO,MAAM,cAAc,sDAwHzB,CAAC"}
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runCommandTool = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const agent_core_1 = require("@backendkit-labs/agent-core");
6
+ const path_sandbox_1 = require("./path-sandbox");
7
+ const MAX_OUTPUT = 20_000;
8
+ /**
9
+ * Allowed base binaries. ALL binaries in a chained command (pipes, &&, ;)
10
+ * must be present here — not just the first one.
11
+ */
12
+ const COMMAND_ALLOWLIST = new Set([
13
+ // Node / JS ecosystem
14
+ 'node', 'npm', 'npx', 'yarn', 'pnpm', 'bun', 'tsx', 'ts-node', 'tsc',
15
+ // Test / lint / format
16
+ 'jest', 'vitest', 'mocha', 'c8', 'nyc', 'eslint', 'prettier', 'biome', 'stylelint',
17
+ // Version control
18
+ 'git', 'gh',
19
+ // Python
20
+ 'python', 'python3', 'pip', 'pip3', 'uv', 'poetry', 'pytest', 'ruff', 'mypy',
21
+ // Go
22
+ 'go', 'golangci-lint',
23
+ // Rust
24
+ 'cargo',
25
+ // JVM
26
+ 'mvn', 'gradle', 'gradlew', 'java', 'javac', 'kotlin', 'kotlinc',
27
+ // Shell utilities (safe subset)
28
+ 'echo', 'cat', 'ls', 'pwd', 'which', 'where', 'env', 'printenv',
29
+ 'head', 'tail', 'grep', 'find', 'wc', 'sort', 'uniq', 'diff', 'jq', 'yq',
30
+ 'mkdir', 'cp', 'mv', 'rm', 'touch', 'chmod',
31
+ 'sleep', 'timeout', 'date', 'xargs',
32
+ // Windows equivalents
33
+ 'dir', 'type', 'copy', 'move', 'del', 'rd', 'md', 'icacls', 'attrib',
34
+ // Containers / infra
35
+ 'docker', 'docker-compose', 'kubectl', 'helm',
36
+ 'terraform', 'pulumi', 'ansible', 'ansible-playbook',
37
+ // Network
38
+ 'curl', 'wget',
39
+ // Build
40
+ 'make', 'act',
41
+ ]);
42
+ /** Extract the base binary name from a single command segment. */
43
+ function extractBin(command) {
44
+ // Strip leading env var assignments like KEY=val CMD ...
45
+ const stripped = command.trim().replace(/^(?:[A-Za-z_][A-Za-z0-9_]*=\S*\s+)+/, '');
46
+ const first = stripped.split(/[\s|;&<>]/)[0] ?? '';
47
+ // Strip any path prefix (e.g. ./node_modules/.bin/jest → jest)
48
+ return first.split('/').pop()?.split('\\').pop() ?? '';
49
+ }
50
+ /**
51
+ * C1: Split a shell command at operator boundaries and return the binary of
52
+ * each segment. Quoted strings are neutralized first so operators inside
53
+ * quotes are not treated as delimiters.
54
+ */
55
+ function extractAllBins(command) {
56
+ const noQuotes = command.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, '""');
57
+ // Strip I/O redirects (e.g. 2>&1, >/dev/null, 2>file, >> file) before
58
+ // splitting so that the target filename is never treated as a command binary.
59
+ // \s* after >>? consumes optional whitespace before the filename/target.
60
+ const noRedirects = noQuotes.replace(/[0-9]*>>?\s*(?:&[0-9]*|\S*)/g, '');
61
+ const segments = noRedirects.split(/&&|\|\||[|;`]|\$\(|(?<!>)&(?!&)/).map(s => s.trim()).filter(Boolean);
62
+ return segments.map(extractBin).filter(Boolean);
63
+ }
64
+ /**
65
+ * Parse `cd <dir> && <rest>` pattern and return the target cwd + real command.
66
+ * Handles both Unix (`cd dir && cmd`) and Windows (`cd /D dir && cmd`) forms.
67
+ */
68
+ function parseCdAndCommand(command) {
69
+ const match = command.trim().match(/^cd(?:\s+\/D)?\s+([^\s&]+)\s*&&\s*(.+)$/i);
70
+ if (match) {
71
+ return { resolvedCd: match[1].trim(), command: match[2].trim() };
72
+ }
73
+ return { command };
74
+ }
75
+ /** A1: Windows binary-only remap — applied to the leading binary, never to args. */
76
+ const WIN_BIN_MAP = {
77
+ pwd: 'echo %cd%',
78
+ ls: 'dir',
79
+ which: 'where',
80
+ cat: 'type',
81
+ touch: 'type nul >>',
82
+ };
83
+ exports.runCommandTool = (0, agent_core_1.defineTool)({
84
+ name: 'run_command',
85
+ description: 'Execute a shell command in the working directory. ' +
86
+ 'Use the optional `cwd` parameter to run in a subdirectory instead of `cd dir && cmd`. ' +
87
+ 'Allowed binaries: npm, git, node, python, go, cargo, docker, kubectl, and common build/test/lint tools. ' +
88
+ 'Shell features (pipes, &&, redirects) are supported when ALL commands in the chain are on the allowlist.',
89
+ input: agent_core_1.z.object({
90
+ command: agent_core_1.z.string().describe('Shell command to execute'),
91
+ cwd: agent_core_1.z.string().optional().describe('Subdirectory to run in, relative to the working directory (e.g. "frontend", "packages/api")'),
92
+ timeout_ms: agent_core_1.z.number().int().min(1000).max(300_000).default(30_000).describe('Timeout in ms (default: 30 000)'),
93
+ }),
94
+ execute: async ({ command, cwd, timeout_ms }, ctx) => {
95
+ const baseDir = ctx.workingDir ?? process.cwd();
96
+ // Parse `cd dir && cmd` patterns transparently
97
+ const { resolvedCd, command: realCommand } = parseCdAndCommand(command);
98
+ const effectiveCdDir = resolvedCd ?? cwd;
99
+ // C2: apply path sandbox to cwd — prevents running outside the working directory
100
+ let workDir;
101
+ if (effectiveCdDir) {
102
+ try {
103
+ workDir = (0, path_sandbox_1.resolveAndCheck)(baseDir, effectiveCdDir);
104
+ }
105
+ catch (err) {
106
+ return `Error: ${err.message}`;
107
+ }
108
+ }
109
+ else {
110
+ workDir = baseDir;
111
+ }
112
+ // A1: Windows binary normalization — only the leading binary, not args
113
+ let effectiveCommand = realCommand;
114
+ const bin = extractBin(effectiveCommand);
115
+ if (process.platform === 'win32') {
116
+ const envVarMatch = effectiveCommand.match(/^((?:[A-Za-z_][A-Za-z0-9_]*=\S*\s+)*)/);
117
+ const envVarPrefix = envVarMatch?.[0] ?? '';
118
+ const afterEnvVars = effectiveCommand.slice(envVarPrefix.length);
119
+ if (bin === 'sleep') {
120
+ const seconds = afterEnvVars.slice(bin.length).trim().split(/\s+/)[0] ?? '1';
121
+ effectiveCommand = `${envVarPrefix}timeout /t ${seconds} /nobreak >nul`;
122
+ }
123
+ else if (bin in WIN_BIN_MAP) {
124
+ effectiveCommand = envVarPrefix + WIN_BIN_MAP[bin] + afterEnvVars.slice(bin.length);
125
+ }
126
+ }
127
+ // C1: validate ALL binaries in the chain, not just the first
128
+ const allBins = extractAllBins(effectiveCommand);
129
+ const blockedBin = allBins.find(b => !COMMAND_ALLOWLIST.has(b));
130
+ if (blockedBin) {
131
+ return `Error: Command "${blockedBin}" is not in the allowed list. ` +
132
+ `Allowed: ${[...COMMAND_ALLOWLIST].join(', ')}`;
133
+ }
134
+ // C3: per-agent command blocklist — steers agents toward MCP tools
135
+ const agentBlocked = ctx.blockedCommands ?? [];
136
+ if (agentBlocked.length > 0) {
137
+ const forbidden = allBins.find(b => agentBlocked.includes(b));
138
+ if (forbidden) {
139
+ return (`Error: Command "${forbidden}" is not available for agent "${ctx.agentId}". ` +
140
+ `This agent uses MCP tools for this capability instead of running shell commands directly. ` +
141
+ `Use the appropriate MCP tool (e.g. pg_create, pg_run_sql) to accomplish this task.`);
142
+ }
143
+ }
144
+ // Use async spawn — spawnSync blocks the entire main process thread,
145
+ // which freezes Electron's IPC channel for the duration of the command.
146
+ const output = await new Promise((resolve) => {
147
+ const chunks = [];
148
+ let totalLen = 0;
149
+ let timedOut = false;
150
+ const proc = (0, child_process_1.spawn)(effectiveCommand, {
151
+ shell: true,
152
+ cwd: workDir,
153
+ timeout: timeout_ms,
154
+ });
155
+ const collect = (data) => {
156
+ if (totalLen >= MAX_OUTPUT * 2)
157
+ return;
158
+ const s = data.toString('utf-8');
159
+ chunks.push(s);
160
+ totalLen += s.length;
161
+ };
162
+ proc.stdout.on('data', collect);
163
+ proc.stderr.on('data', collect);
164
+ const timer = setTimeout(() => {
165
+ timedOut = true;
166
+ proc.kill();
167
+ resolve(`Error: Command timed out after ${timeout_ms}ms`);
168
+ }, timeout_ms);
169
+ proc.on('error', (err) => {
170
+ clearTimeout(timer);
171
+ resolve(`Error: ${err.message}`);
172
+ });
173
+ proc.on('close', (code) => {
174
+ if (timedOut)
175
+ return;
176
+ clearTimeout(timer);
177
+ const raw = chunks.join('').trim();
178
+ const truncated = raw.length > MAX_OUTPUT
179
+ ? raw.slice(0, MAX_OUTPUT) + `\n[truncated — ${raw.length} total chars]`
180
+ : raw;
181
+ if (code !== 0 && !truncated) {
182
+ resolve(`Error: Command exited with status ${code}`);
183
+ }
184
+ else {
185
+ resolve(truncated || '(no output)');
186
+ }
187
+ });
188
+ });
189
+ return output;
190
+ },
191
+ });
192
+ //# sourceMappingURL=run-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../src/tools/run-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const saveAuditTool: import("@backendkit-labs/agent-core").ToolDefinition;
2
+ export declare const getLatestAuditTool: import("@backendkit-labs/agent-core").ToolDefinition;
3
+ export declare const listAuditsTool: import("@backendkit-labs/agent-core").ToolDefinition;
4
+ //# sourceMappingURL=save-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-audit.d.ts","sourceRoot":"","sources":["../../src/tools/save-audit.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,sDAYxB,CAAC;AAEH,eAAO,MAAM,kBAAkB,sDAU7B,CAAC;AAEH,eAAO,MAAM,cAAc,sDASzB,CAAC"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listAuditsTool = exports.getLatestAuditTool = exports.saveAuditTool = void 0;
4
+ const agent_core_1 = require("@backendkit-labs/agent-core");
5
+ exports.saveAuditTool = (0, agent_core_1.defineTool)({
6
+ name: 'save_audit',
7
+ description: "Save the results of a project audit (security, QA, architecture, etc.) with today's date.",
8
+ input: agent_core_1.z.object({
9
+ agent_id: agent_core_1.z.string().min(1).describe('Agent ID performing the audit (e.g. security, qa-engineer)'),
10
+ content: agent_core_1.z.string().min(1).describe('Full audit report in markdown'),
11
+ }),
12
+ execute: async ({ agent_id, content }, ctx) => {
13
+ if (!ctx.store)
14
+ return 'Error: no persistent store configured';
15
+ ctx.store.saveAudit(agent_id, content);
16
+ return `Audit saved for agent "${agent_id}".`;
17
+ },
18
+ });
19
+ exports.getLatestAuditTool = (0, agent_core_1.defineTool)({
20
+ name: 'get_latest_audit',
21
+ description: 'Retrieve the most recent audit report for a given agent type.',
22
+ input: agent_core_1.z.object({
23
+ agent_id: agent_core_1.z.string().min(1).describe('Agent ID to retrieve audit for (e.g. security, qa-engineer)'),
24
+ }),
25
+ execute: async ({ agent_id }, ctx) => {
26
+ if (!ctx.store)
27
+ return 'Error: no persistent store configured';
28
+ return ctx.store.getLatestAudit(agent_id) ?? `No previous audit found for "${agent_id}".`;
29
+ },
30
+ });
31
+ exports.listAuditsTool = (0, agent_core_1.defineTool)({
32
+ name: 'list_audits',
33
+ description: 'List all saved audit files for this project.',
34
+ input: agent_core_1.z.object({}),
35
+ execute: async (_args, ctx) => {
36
+ if (!ctx.store)
37
+ return 'Error: no persistent store configured';
38
+ const audits = ctx.store.listAudits();
39
+ return audits.length > 0 ? audits.join('\n') : 'No audits saved yet.';
40
+ },
41
+ });
42
+ //# sourceMappingURL=save-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-audit.js","sourceRoot":"","sources":["../../src/tools/save-audit.ts"],"names":[],"mappings":";;;AAAA,4DAA4D;AAE/C,QAAA,aAAa,GAAG,IAAA,uBAAU,EAAC;IACpC,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,2FAA2F;IACxG,KAAK,EAAE,cAAC,CAAC,MAAM,CAAC;QACZ,QAAQ,EAAE,cAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,4DAA4D,CAAC;QAClG,OAAO,EAAG,cAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC;KACxE,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE;QAC1C,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO,uCAAuC,CAAC;QAC/D,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACvC,OAAO,0BAA0B,QAAQ,IAAI,CAAC;IAClD,CAAC;CACJ,CAAC,CAAC;AAEU,QAAA,kBAAkB,GAAG,IAAA,uBAAU,EAAC;IACzC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,+DAA+D;IAC5E,KAAK,EAAE,cAAC,CAAC,MAAM,CAAC;QACZ,QAAQ,EAAE,cAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6DAA6D,CAAC;KACtG,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE;QACjC,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO,uCAAuC,CAAC;QAC/D,OAAO,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,gCAAgC,QAAQ,IAAI,CAAC;IAC9F,CAAC;CACJ,CAAC,CAAC;AAEU,QAAA,cAAc,GAAG,IAAA,uBAAU,EAAC;IACrC,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,8CAA8C;IAC3D,KAAK,EAAE,cAAC,CAAC,MAAM,CAAC,EAAE,CAAC;IACnB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC1B,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO,uCAAuC,CAAC;QAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACtC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC;IAC1E,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const saveContextTool: import("@backendkit-labs/agent-core").ToolDefinition;
2
+ //# sourceMappingURL=save-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-context.d.ts","sourceRoot":"","sources":["../../src/tools/save-context.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,sDAW1B,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.saveContextTool = void 0;
4
+ const agent_core_1 = require("@backendkit-labs/agent-core");
5
+ exports.saveContextTool = (0, agent_core_1.defineTool)({
6
+ name: 'save_context',
7
+ description: 'Save a discovery about the project — tech stack, architecture, key files, conventions. Persists across sessions.',
8
+ input: agent_core_1.z.object({
9
+ content: agent_core_1.z.string().min(1).describe('The context to save (markdown supported)'),
10
+ }),
11
+ execute: async ({ content }, ctx) => {
12
+ if (!ctx.store)
13
+ return 'Error: no persistent store configured';
14
+ ctx.store.appendContext(content);
15
+ return 'Context saved.';
16
+ },
17
+ });
18
+ //# sourceMappingURL=save-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-context.js","sourceRoot":"","sources":["../../src/tools/save-context.ts"],"names":[],"mappings":";;;AAAA,4DAA4D;AAE/C,QAAA,eAAe,GAAG,IAAA,uBAAU,EAAC;IACtC,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,kHAAkH;IAC/H,KAAK,EAAE,cAAC,CAAC,MAAM,CAAC;QACZ,OAAO,EAAE,cAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0CAA0C,CAAC;KAClF,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE;QAChC,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO,uCAAuC,CAAC;QAC/D,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACjC,OAAO,gBAAgB,CAAC;IAC5B,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const saveLearningTool: import("@backendkit-labs/agent-core").ToolDefinition;
2
+ //# sourceMappingURL=save-learning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-learning.d.ts","sourceRoot":"","sources":["../../src/tools/save-learning.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,sDAoC3B,CAAC"}