@phuetz/code-buddy 0.1.24 → 0.1.26

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 (258) hide show
  1. package/README.md +1049 -741
  2. package/dist/agent/codebuddy-agent.d.ts +5 -0
  3. package/dist/agent/codebuddy-agent.js +46 -1
  4. package/dist/agent/codebuddy-agent.js.map +1 -1
  5. package/dist/agent/execution/agent-executor.d.ts +12 -0
  6. package/dist/agent/execution/agent-executor.js +147 -6
  7. package/dist/agent/execution/agent-executor.js.map +1 -1
  8. package/dist/agent/lessons-tracker.d.ts +50 -0
  9. package/dist/agent/lessons-tracker.js +234 -0
  10. package/dist/agent/lessons-tracker.js.map +1 -0
  11. package/dist/agent/message-queue.d.ts +39 -2
  12. package/dist/agent/message-queue.js +67 -2
  13. package/dist/agent/message-queue.js.map +1 -1
  14. package/dist/agent/middleware/index.d.ts +1 -0
  15. package/dist/agent/middleware/index.js +1 -0
  16. package/dist/agent/middleware/index.js.map +1 -1
  17. package/dist/agent/middleware/workflow-guard.d.ts +21 -0
  18. package/dist/agent/middleware/workflow-guard.js +94 -0
  19. package/dist/agent/middleware/workflow-guard.js.map +1 -0
  20. package/dist/agent/repo-profiler.d.ts +61 -0
  21. package/dist/agent/repo-profiler.js +295 -0
  22. package/dist/agent/repo-profiler.js.map +1 -0
  23. package/dist/agent/response-constraint.d.ts +61 -0
  24. package/dist/agent/response-constraint.js +91 -0
  25. package/dist/agent/response-constraint.js.map +1 -0
  26. package/dist/agent/todo-tracker.d.ts +67 -0
  27. package/dist/agent/todo-tracker.js +245 -0
  28. package/dist/agent/todo-tracker.js.map +1 -0
  29. package/dist/agent/tool-handler.d.ts +11 -0
  30. package/dist/agent/tool-handler.js +79 -1
  31. package/dist/agent/tool-handler.js.map +1 -1
  32. package/dist/agent/types.d.ts +20 -2
  33. package/dist/agent/wide-research.d.ts +93 -0
  34. package/dist/agent/wide-research.js +232 -0
  35. package/dist/agent/wide-research.js.map +1 -0
  36. package/dist/channels/index.d.ts +2 -0
  37. package/dist/channels/index.js +2 -0
  38. package/dist/channels/index.js.map +1 -1
  39. package/dist/channels/pro/callback-router.d.ts +54 -0
  40. package/dist/channels/pro/callback-router.js +178 -0
  41. package/dist/channels/pro/callback-router.js.map +1 -0
  42. package/dist/channels/pro/ci-watcher.d.ts +86 -0
  43. package/dist/channels/pro/ci-watcher.js +343 -0
  44. package/dist/channels/pro/ci-watcher.js.map +1 -0
  45. package/dist/channels/pro/diff-first.d.ts +63 -0
  46. package/dist/channels/pro/diff-first.js +187 -0
  47. package/dist/channels/pro/diff-first.js.map +1 -0
  48. package/dist/channels/pro/enhanced-commands.d.ts +83 -0
  49. package/dist/channels/pro/enhanced-commands.js +218 -0
  50. package/dist/channels/pro/enhanced-commands.js.map +1 -0
  51. package/dist/channels/pro/index.d.ts +19 -0
  52. package/dist/channels/pro/index.js +21 -0
  53. package/dist/channels/pro/index.js.map +1 -0
  54. package/dist/channels/pro/pro-features.d.ts +79 -0
  55. package/dist/channels/pro/pro-features.js +203 -0
  56. package/dist/channels/pro/pro-features.js.map +1 -0
  57. package/dist/channels/pro/run-commands.d.ts +59 -0
  58. package/dist/channels/pro/run-commands.js +122 -0
  59. package/dist/channels/pro/run-commands.js.map +1 -0
  60. package/dist/channels/pro/run-tracker.d.ts +74 -0
  61. package/dist/channels/pro/run-tracker.js +252 -0
  62. package/dist/channels/pro/run-tracker.js.map +1 -0
  63. package/dist/channels/pro/scoped-auth.d.ts +97 -0
  64. package/dist/channels/pro/scoped-auth.js +340 -0
  65. package/dist/channels/pro/scoped-auth.js.map +1 -0
  66. package/dist/channels/pro/text-formatter.d.ts +27 -0
  67. package/dist/channels/pro/text-formatter.js +269 -0
  68. package/dist/channels/pro/text-formatter.js.map +1 -0
  69. package/dist/channels/pro/types.d.ts +242 -0
  70. package/dist/channels/pro/types.js +14 -0
  71. package/dist/channels/pro/types.js.map +1 -0
  72. package/dist/channels/streaming-policy.d.ts +66 -0
  73. package/dist/channels/streaming-policy.js +266 -0
  74. package/dist/channels/streaming-policy.js.map +1 -0
  75. package/dist/channels/telegram/ci-watcher.d.ts +5 -0
  76. package/dist/channels/telegram/ci-watcher.js +5 -0
  77. package/dist/channels/telegram/ci-watcher.js.map +1 -0
  78. package/dist/channels/telegram/client.d.ts +28 -0
  79. package/dist/channels/telegram/client.js +147 -1
  80. package/dist/channels/telegram/client.js.map +1 -1
  81. package/dist/channels/telegram/diff-first.d.ts +5 -0
  82. package/dist/channels/telegram/diff-first.js +5 -0
  83. package/dist/channels/telegram/diff-first.js.map +1 -0
  84. package/dist/channels/telegram/enhanced-commands.d.ts +6 -0
  85. package/dist/channels/telegram/enhanced-commands.js +6 -0
  86. package/dist/channels/telegram/enhanced-commands.js.map +1 -0
  87. package/dist/channels/telegram/index.d.ts +6 -0
  88. package/dist/channels/telegram/index.js +6 -0
  89. package/dist/channels/telegram/index.js.map +1 -1
  90. package/dist/channels/telegram/pro-formatter.d.ts +30 -0
  91. package/dist/channels/telegram/pro-formatter.js +276 -0
  92. package/dist/channels/telegram/pro-formatter.js.map +1 -0
  93. package/dist/channels/telegram/run-commands.d.ts +5 -0
  94. package/dist/channels/telegram/run-commands.js +6 -0
  95. package/dist/channels/telegram/run-commands.js.map +1 -0
  96. package/dist/channels/telegram/run-tracker.d.ts +5 -0
  97. package/dist/channels/telegram/run-tracker.js +5 -0
  98. package/dist/channels/telegram/run-tracker.js.map +1 -0
  99. package/dist/channels/telegram/scoped-auth.d.ts +6 -0
  100. package/dist/channels/telegram/scoped-auth.js +5 -0
  101. package/dist/channels/telegram/scoped-auth.js.map +1 -0
  102. package/dist/channels/telegram/types.d.ts +34 -0
  103. package/dist/codebuddy/client.js +14 -1
  104. package/dist/codebuddy/client.js.map +1 -1
  105. package/dist/commands/dev/index.d.ts +12 -0
  106. package/dist/commands/dev/index.js +231 -0
  107. package/dist/commands/dev/index.js.map +1 -0
  108. package/dist/commands/dev/workflows.d.ts +31 -0
  109. package/dist/commands/dev/workflows.js +214 -0
  110. package/dist/commands/dev/workflows.js.map +1 -0
  111. package/dist/commands/execpolicy.d.ts +17 -0
  112. package/dist/commands/execpolicy.js +155 -0
  113. package/dist/commands/execpolicy.js.map +1 -0
  114. package/dist/commands/knowledge.d.ts +13 -0
  115. package/dist/commands/knowledge.js +142 -0
  116. package/dist/commands/knowledge.js.map +1 -0
  117. package/dist/commands/lessons.d.ts +11 -0
  118. package/dist/commands/lessons.js +129 -0
  119. package/dist/commands/lessons.js.map +1 -0
  120. package/dist/commands/pairing.d.ts +14 -0
  121. package/dist/commands/pairing.js +132 -0
  122. package/dist/commands/pairing.js.map +1 -0
  123. package/dist/commands/research/index.d.ts +13 -0
  124. package/dist/commands/research/index.js +91 -0
  125. package/dist/commands/research/index.js.map +1 -0
  126. package/dist/commands/run-cli/index.d.ts +11 -0
  127. package/dist/commands/run-cli/index.js +49 -0
  128. package/dist/commands/run-cli/index.js.map +1 -0
  129. package/dist/commands/todos.d.ts +9 -0
  130. package/dist/commands/todos.js +119 -0
  131. package/dist/commands/todos.js.map +1 -0
  132. package/dist/config/toml-config.d.ts +21 -0
  133. package/dist/config/toml-config.js +15 -0
  134. package/dist/config/toml-config.js.map +1 -1
  135. package/dist/context/enhanced-compression.js +12 -1
  136. package/dist/context/enhanced-compression.js.map +1 -1
  137. package/dist/context/observation-variator.d.ts +44 -0
  138. package/dist/context/observation-variator.js +83 -0
  139. package/dist/context/observation-variator.js.map +1 -0
  140. package/dist/context/precompaction-flush.d.ts +40 -0
  141. package/dist/context/precompaction-flush.js +134 -0
  142. package/dist/context/precompaction-flush.js.map +1 -0
  143. package/dist/context/restorable-compression.d.ts +80 -0
  144. package/dist/context/restorable-compression.js +228 -0
  145. package/dist/context/restorable-compression.js.map +1 -0
  146. package/dist/daemon/daily-reset.d.ts +77 -0
  147. package/dist/daemon/daily-reset.js +175 -0
  148. package/dist/daemon/daily-reset.js.map +1 -0
  149. package/dist/daemon/index.d.ts +1 -0
  150. package/dist/daemon/index.js +1 -0
  151. package/dist/daemon/index.js.map +1 -1
  152. package/dist/index.js +53 -0
  153. package/dist/index.js.map +1 -1
  154. package/dist/knowledge/knowledge-manager.d.ts +77 -0
  155. package/dist/knowledge/knowledge-manager.js +244 -0
  156. package/dist/knowledge/knowledge-manager.js.map +1 -0
  157. package/dist/observability/run-store.d.ts +133 -0
  158. package/dist/observability/run-store.js +419 -0
  159. package/dist/observability/run-store.js.map +1 -0
  160. package/dist/observability/run-viewer.d.ts +33 -0
  161. package/dist/observability/run-viewer.js +254 -0
  162. package/dist/observability/run-viewer.js.map +1 -0
  163. package/dist/optimization/cache-breakpoints.d.ts +52 -0
  164. package/dist/optimization/cache-breakpoints.js +97 -0
  165. package/dist/optimization/cache-breakpoints.js.map +1 -0
  166. package/dist/persistence/session-store.d.ts +3 -1
  167. package/dist/persistence/session-store.js +1 -1
  168. package/dist/persistence/session-store.js.map +1 -1
  169. package/dist/prompts/system-base.js +51 -7
  170. package/dist/prompts/system-base.js.map +1 -1
  171. package/dist/prompts/variation-injector.d.ts +55 -0
  172. package/dist/prompts/variation-injector.js +171 -0
  173. package/dist/prompts/variation-injector.js.map +1 -0
  174. package/dist/prompts/workflow-rules.d.ts +10 -0
  175. package/dist/prompts/workflow-rules.js +79 -0
  176. package/dist/prompts/workflow-rules.js.map +1 -0
  177. package/dist/sandbox/execpolicy.d.ts +45 -0
  178. package/dist/sandbox/execpolicy.js +80 -0
  179. package/dist/sandbox/execpolicy.js.map +1 -1
  180. package/dist/sandbox/os-sandbox.d.ts +25 -0
  181. package/dist/sandbox/os-sandbox.js +73 -0
  182. package/dist/sandbox/os-sandbox.js.map +1 -1
  183. package/dist/security/security-audit.d.ts +10 -0
  184. package/dist/security/security-audit.js +116 -0
  185. package/dist/security/security-audit.js.map +1 -1
  186. package/dist/security/shell-env-policy.d.ts +45 -0
  187. package/dist/security/shell-env-policy.js +141 -0
  188. package/dist/security/shell-env-policy.js.map +1 -0
  189. package/dist/security/ssrf-guard.d.ts +61 -0
  190. package/dist/security/ssrf-guard.js +382 -0
  191. package/dist/security/ssrf-guard.js.map +1 -0
  192. package/dist/security/write-policy.d.ts +57 -0
  193. package/dist/security/write-policy.js +117 -0
  194. package/dist/security/write-policy.js.map +1 -0
  195. package/dist/services/prompt-builder.js +37 -0
  196. package/dist/services/prompt-builder.js.map +1 -1
  197. package/dist/themes/theme-schema.d.ts +10 -10
  198. package/dist/tools/ask-human-tool.d.ts +62 -0
  199. package/dist/tools/ask-human-tool.js +112 -0
  200. package/dist/tools/ask-human-tool.js.map +1 -0
  201. package/dist/tools/bash/bash-tool.d.ts +15 -0
  202. package/dist/tools/bash/bash-tool.js +62 -0
  203. package/dist/tools/bash/bash-tool.js.map +1 -1
  204. package/dist/tools/bash/command-validator.d.ts +1 -0
  205. package/dist/tools/bash/command-validator.js +5 -0
  206. package/dist/tools/bash/command-validator.js.map +1 -1
  207. package/dist/tools/create-skill-tool.d.ts +87 -0
  208. package/dist/tools/create-skill-tool.js +142 -0
  209. package/dist/tools/create-skill-tool.js.map +1 -0
  210. package/dist/tools/fetch-tool.js +5 -3
  211. package/dist/tools/fetch-tool.js.map +1 -1
  212. package/dist/tools/hooks/default-hooks.js +24 -23
  213. package/dist/tools/hooks/default-hooks.js.map +1 -1
  214. package/dist/tools/index.d.ts +1 -0
  215. package/dist/tools/index.js +1 -0
  216. package/dist/tools/index.js.map +1 -1
  217. package/dist/tools/plan-tool.d.ts +22 -0
  218. package/dist/tools/plan-tool.js +128 -0
  219. package/dist/tools/plan-tool.js.map +1 -0
  220. package/dist/tools/registry/attention-tools.d.ts +32 -0
  221. package/dist/tools/registry/attention-tools.js +225 -0
  222. package/dist/tools/registry/attention-tools.js.map +1 -0
  223. package/dist/tools/registry/index.d.ts +9 -1
  224. package/dist/tools/registry/index.js +30 -2
  225. package/dist/tools/registry/index.js.map +1 -1
  226. package/dist/tools/registry/knowledge-tools.d.ts +46 -0
  227. package/dist/tools/registry/knowledge-tools.js +293 -0
  228. package/dist/tools/registry/knowledge-tools.js.map +1 -0
  229. package/dist/tools/registry/lessons-tools.d.ts +48 -0
  230. package/dist/tools/registry/lessons-tools.js +359 -0
  231. package/dist/tools/registry/lessons-tools.js.map +1 -0
  232. package/dist/tools/registry/plan-tools.d.ts +2 -0
  233. package/dist/tools/registry/plan-tools.js +7 -0
  234. package/dist/tools/registry/plan-tools.js.map +1 -0
  235. package/dist/tools/registry/script-tools.d.ts +2 -0
  236. package/dist/tools/registry/script-tools.js +7 -0
  237. package/dist/tools/registry/script-tools.js.map +1 -0
  238. package/dist/tools/registry/tool-aliases.d.ts +44 -0
  239. package/dist/tools/registry/tool-aliases.js +130 -0
  240. package/dist/tools/registry/tool-aliases.js.map +1 -0
  241. package/dist/tools/run-script-tool.d.ts +13 -0
  242. package/dist/tools/run-script-tool.js +146 -0
  243. package/dist/tools/run-script-tool.js.map +1 -0
  244. package/dist/tools/web-search.d.ts +25 -0
  245. package/dist/tools/web-search.js +68 -6
  246. package/dist/tools/web-search.js.map +1 -1
  247. package/dist/utils/config-validation/schema.d.ts +2 -2
  248. package/dist/utils/debug-logger.d.ts +1 -1
  249. package/dist/utils/rtk-compressor.d.ts +13 -10
  250. package/dist/utils/rtk-compressor.js +83 -34
  251. package/dist/utils/rtk-compressor.js.map +1 -1
  252. package/dist/utils/stable-json.d.ts +27 -0
  253. package/dist/utils/stable-json.js +50 -0
  254. package/dist/utils/stable-json.js.map +1 -0
  255. package/dist/webhooks/webhook-manager.d.ts +7 -0
  256. package/dist/webhooks/webhook-manager.js +29 -0
  257. package/dist/webhooks/webhook-manager.js.map +1 -1
  258. package/package.json +1 -1
@@ -0,0 +1,295 @@
1
+ /**
2
+ * RepoProfiler
3
+ *
4
+ * Scans the current repository to detect language, framework, package manager,
5
+ * and build/test commands. Produces a compact contextPack string injected into
6
+ * the agent system prompt to give it awareness of project conventions.
7
+ *
8
+ * Result is cached in .codebuddy/repoProfile.json and invalidated when
9
+ * package.json (or equivalent) changes.
10
+ */
11
+ import fs from 'fs';
12
+ import path from 'path';
13
+ import { logger } from '../utils/logger.js';
14
+ const CACHE_FILENAME = '.codebuddy/repoProfile.json';
15
+ /**
16
+ * Profiles a repository to produce structured metadata.
17
+ */
18
+ export class RepoProfiler {
19
+ cwd;
20
+ cachePath;
21
+ constructor(cwd) {
22
+ this.cwd = cwd || process.cwd();
23
+ this.cachePath = path.join(this.cwd, CACHE_FILENAME);
24
+ }
25
+ /**
26
+ * Get or compute the repo profile.
27
+ * Uses cached result if the primary config file hasn't changed.
28
+ */
29
+ async getProfile() {
30
+ const cached = this.loadCache();
31
+ if (cached && !this.isCacheStale(cached)) {
32
+ return cached;
33
+ }
34
+ const profile = await this.computeProfile();
35
+ this.saveCache(profile);
36
+ return profile;
37
+ }
38
+ /**
39
+ * Force recompute (ignores cache).
40
+ */
41
+ async refresh() {
42
+ const profile = await this.computeProfile();
43
+ this.saveCache(profile);
44
+ return profile;
45
+ }
46
+ // ──────────────────────────────────────────────────────────────
47
+ // Private implementation
48
+ // ──────────────────────────────────────────────────────────────
49
+ async computeProfile() {
50
+ const languages = [];
51
+ let framework;
52
+ let packageManager;
53
+ const commands = {};
54
+ const directories = {};
55
+ const conventions = {};
56
+ let configMtime;
57
+ // ── Node / TypeScript ──────────────────────────────────────
58
+ const pkgJsonPath = path.join(this.cwd, 'package.json');
59
+ if (this.exists(pkgJsonPath)) {
60
+ configMtime = this.mtime(pkgJsonPath);
61
+ languages.push('TypeScript', 'JavaScript');
62
+ try {
63
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
64
+ // Package manager
65
+ if (this.exists(path.join(this.cwd, 'pnpm-lock.yaml'))) {
66
+ packageManager = 'pnpm';
67
+ }
68
+ else if (this.exists(path.join(this.cwd, 'yarn.lock'))) {
69
+ packageManager = 'yarn';
70
+ }
71
+ else {
72
+ packageManager = 'npm';
73
+ }
74
+ const pm = packageManager;
75
+ const run = pm === 'npm' ? 'npm run' : pm;
76
+ // Scripts
77
+ const scripts = pkg.scripts || {};
78
+ if (scripts.test)
79
+ commands.test = `${run} test`;
80
+ if (scripts.lint)
81
+ commands.lint = `${run} lint`;
82
+ if (scripts.format)
83
+ commands.format = `${run} format`;
84
+ if (scripts.build)
85
+ commands.build = `${run} build`;
86
+ // Framework detection from dependencies
87
+ const allDeps = {
88
+ ...pkg.dependencies,
89
+ ...pkg.devDependencies,
90
+ ...pkg.peerDependencies,
91
+ };
92
+ if (allDeps['react'] || allDeps['react-dom'])
93
+ framework = 'React';
94
+ else if (allDeps['next'])
95
+ framework = 'Next.js';
96
+ else if (allDeps['vue'])
97
+ framework = 'Vue';
98
+ else if (allDeps['@angular/core'])
99
+ framework = 'Angular';
100
+ else if (allDeps['express'])
101
+ framework = 'Express';
102
+ else if (allDeps['fastify'])
103
+ framework = 'Fastify';
104
+ else if (allDeps['ink'])
105
+ framework = 'Ink (terminal UI)';
106
+ // Naming convention hint
107
+ if (allDeps['eslint'] || pkg.eslintConfig) {
108
+ conventions.naming = 'camelCase (JS/TS)';
109
+ conventions.lintRules = ['eslint'];
110
+ }
111
+ }
112
+ catch {
113
+ // Malformed package.json — ignore
114
+ }
115
+ }
116
+ // ── Python ────────────────────────────────────────────────
117
+ const pyprojectPath = path.join(this.cwd, 'pyproject.toml');
118
+ const requirementsPath = path.join(this.cwd, 'requirements.txt');
119
+ if (this.exists(pyprojectPath) || this.exists(requirementsPath)) {
120
+ languages.push('Python');
121
+ if (this.exists(pyprojectPath)) {
122
+ packageManager = 'poetry';
123
+ configMtime = configMtime || this.mtime(pyprojectPath);
124
+ commands.test = commands.test || 'poetry run pytest';
125
+ commands.lint = commands.lint || 'poetry run ruff check .';
126
+ commands.format = commands.format || 'poetry run black .';
127
+ }
128
+ else {
129
+ packageManager = 'pip';
130
+ configMtime = configMtime || this.mtime(requirementsPath);
131
+ commands.test = commands.test || 'python -m pytest';
132
+ }
133
+ }
134
+ // ── Rust ─────────────────────────────────────────────────
135
+ const cargoPath = path.join(this.cwd, 'Cargo.toml');
136
+ if (this.exists(cargoPath)) {
137
+ languages.push('Rust');
138
+ packageManager = 'cargo';
139
+ configMtime = configMtime || this.mtime(cargoPath);
140
+ commands.test = commands.test || 'cargo test';
141
+ commands.build = commands.build || 'cargo build --release';
142
+ commands.lint = commands.lint || 'cargo clippy';
143
+ commands.format = commands.format || 'cargo fmt';
144
+ }
145
+ // ── Go ────────────────────────────────────────────────────
146
+ const goModPath = path.join(this.cwd, 'go.mod');
147
+ if (this.exists(goModPath)) {
148
+ languages.push('Go');
149
+ packageManager = 'go';
150
+ configMtime = configMtime || this.mtime(goModPath);
151
+ commands.test = commands.test || 'go test ./...';
152
+ commands.build = commands.build || 'go build ./...';
153
+ commands.lint = commands.lint || 'golangci-lint run';
154
+ commands.format = commands.format || 'gofmt -w .';
155
+ }
156
+ // ── .NET ─────────────────────────────────────────────────
157
+ const hasCsproj = this.glob('*.csproj').length > 0 || this.glob('*.sln').length > 0;
158
+ if (hasCsproj) {
159
+ languages.push('C#');
160
+ packageManager = 'dotnet';
161
+ commands.test = commands.test || 'dotnet test';
162
+ commands.build = commands.build || 'dotnet build';
163
+ commands.format = commands.format || 'dotnet format';
164
+ }
165
+ // ── Common directory detection ────────────────────────────
166
+ for (const candidate of ['src', 'lib', 'app']) {
167
+ if (this.exists(path.join(this.cwd, candidate))) {
168
+ directories.src = candidate;
169
+ break;
170
+ }
171
+ }
172
+ for (const candidate of ['tests', 'test', '__tests__', 'spec']) {
173
+ if (this.exists(path.join(this.cwd, candidate))) {
174
+ directories.tests = candidate;
175
+ break;
176
+ }
177
+ }
178
+ for (const candidate of ['docs', 'documentation', 'doc']) {
179
+ if (this.exists(path.join(this.cwd, candidate))) {
180
+ directories.docs = candidate;
181
+ break;
182
+ }
183
+ }
184
+ // ── Build contextPack ─────────────────────────────────────
185
+ const profile = {
186
+ detectedAt: new Date().toISOString(),
187
+ languages,
188
+ framework,
189
+ packageManager,
190
+ commands,
191
+ directories,
192
+ conventions,
193
+ contextPack: '',
194
+ _configMtime: configMtime,
195
+ };
196
+ profile.contextPack = this.buildContextPack(profile);
197
+ return profile;
198
+ }
199
+ buildContextPack(p) {
200
+ const parts = [];
201
+ if (p.languages.length > 0) {
202
+ parts.push(`Language: ${p.languages.join(', ')}`);
203
+ }
204
+ if (p.framework) {
205
+ parts.push(`Framework: ${p.framework}`);
206
+ }
207
+ if (p.packageManager) {
208
+ parts.push(`Package manager: ${p.packageManager}`);
209
+ }
210
+ const cmds = Object.entries(p.commands)
211
+ .map(([k, v]) => `${k}="${v}"`)
212
+ .join(', ');
213
+ if (cmds) {
214
+ parts.push(`Commands: ${cmds}`);
215
+ }
216
+ const dirs = Object.entries(p.directories)
217
+ .map(([k, v]) => `${k}=${v}`)
218
+ .join(', ');
219
+ if (dirs) {
220
+ parts.push(`Dirs: ${dirs}`);
221
+ }
222
+ if (p.conventions.naming) {
223
+ parts.push(`Naming: ${p.conventions.naming}`);
224
+ }
225
+ return parts.join(' | ');
226
+ }
227
+ loadCache() {
228
+ try {
229
+ if (!fs.existsSync(this.cachePath))
230
+ return null;
231
+ const raw = fs.readFileSync(this.cachePath, 'utf-8');
232
+ return JSON.parse(raw);
233
+ }
234
+ catch {
235
+ return null;
236
+ }
237
+ }
238
+ isCacheStale(cached) {
239
+ if (!cached._configMtime)
240
+ return true;
241
+ // Check if primary config file has changed
242
+ const pkgJsonPath = path.join(this.cwd, 'package.json');
243
+ for (const candidate of [pkgJsonPath, 'pyproject.toml', 'Cargo.toml', 'go.mod'].map((f) => (path.isAbsolute(f) ? f : path.join(this.cwd, f)))) {
244
+ if (fs.existsSync(candidate)) {
245
+ const currentMtime = this.mtime(candidate);
246
+ if (currentMtime !== cached._configMtime)
247
+ return true;
248
+ break;
249
+ }
250
+ }
251
+ return false;
252
+ }
253
+ saveCache(profile) {
254
+ try {
255
+ const dir = path.dirname(this.cachePath);
256
+ if (!fs.existsSync(dir)) {
257
+ fs.mkdirSync(dir, { recursive: true });
258
+ }
259
+ fs.writeFileSync(this.cachePath, JSON.stringify(profile, null, 2));
260
+ }
261
+ catch (err) {
262
+ logger.debug('RepoProfiler: failed to save cache', { err });
263
+ }
264
+ }
265
+ exists(p) {
266
+ return fs.existsSync(p);
267
+ }
268
+ mtime(p) {
269
+ try {
270
+ return fs.statSync(p).mtimeMs;
271
+ }
272
+ catch {
273
+ return 0;
274
+ }
275
+ }
276
+ glob(pattern) {
277
+ try {
278
+ // Simple glob: look for files matching *.ext in cwd
279
+ const ext = pattern.replace('*', '');
280
+ return fs.readdirSync(this.cwd).filter((f) => f.endsWith(ext));
281
+ }
282
+ catch {
283
+ return [];
284
+ }
285
+ }
286
+ }
287
+ /** Singleton instance */
288
+ let _instance = null;
289
+ export function getRepoProfiler(cwd) {
290
+ if (!_instance || cwd) {
291
+ _instance = new RepoProfiler(cwd);
292
+ }
293
+ return _instance;
294
+ }
295
+ //# sourceMappingURL=repo-profiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-profiler.js","sourceRoot":"","sources":["../../src/agent/repo-profiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Response Prefill Modes — Manus AI tool call space restriction
3
+ *
4
+ * Instead of dynamically removing tools from the tool list (which would cause
5
+ * a different prompt hash → KV-cache miss → 10× higher cost), Manus restricts
6
+ * the action space by controlling `tool_choice` on each model call.
7
+ *
8
+ * Three modes:
9
+ * - 'auto' → model chooses freely (default; maps to tool_choice: "auto")
10
+ * - 'required' → model MUST make a tool call (maps to tool_choice: "required")
11
+ * - 'specified' → model MUST call a specific tool or tool-group prefix
12
+ * (maps to tool_choice: {type: "function", function: {name: exactName}}
13
+ * or the first tool whose name starts with namePrefix)
14
+ *
15
+ * Preserves the full tool list so KV-cache hits are maintained.
16
+ * Use for state-machine-like sequencing: "first call must be plan_update,
17
+ * then shell_exec, then file_write".
18
+ */
19
+ export type ResponsePrefillMode = 'auto' | 'required' | 'specified';
20
+ export interface ResponseConstraint {
21
+ /** Prefill mode controlling what the model is allowed to respond with */
22
+ mode: ResponsePrefillMode;
23
+ /**
24
+ * For 'specified' mode: exact tool name or prefix ending in '_'.
25
+ * If a prefix (e.g. "plan_"), the first matching tool is selected.
26
+ */
27
+ nameOrPrefix?: string;
28
+ }
29
+ export type ToolChoiceValue = 'auto' | 'required' | 'none' | {
30
+ type: 'function';
31
+ function: {
32
+ name: string;
33
+ };
34
+ };
35
+ /**
36
+ * Resolve a `ResponseConstraint` to a concrete `tool_choice` value.
37
+ *
38
+ * @param constraint - The desired constraint
39
+ * @param availableToolNames - Names of tools in the current call (for prefix resolution)
40
+ * @returns OpenAI-compatible `tool_choice` value
41
+ */
42
+ export declare function resolveToolChoice(constraint: ResponseConstraint, availableToolNames?: string[]): ToolChoiceValue;
43
+ /**
44
+ * A simple per-session constraint stack. Push constraints for specific turns,
45
+ * pop after the turn completes. The top of the stack is the active constraint.
46
+ *
47
+ * Usage in agent-executor:
48
+ * constraintStack.push({ mode: 'required' }); // force tool call
49
+ * ... run LLM turn ...
50
+ * constraintStack.pop();
51
+ */
52
+ export declare class ResponseConstraintStack {
53
+ private stack;
54
+ push(constraint: ResponseConstraint): void;
55
+ pop(): ResponseConstraint | undefined;
56
+ /** Current active constraint (top of stack), or default 'auto' */
57
+ current(): ResponseConstraint;
58
+ clear(): void;
59
+ isEmpty(): boolean;
60
+ }
61
+ export declare function getResponseConstraintStack(): ResponseConstraintStack;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Response Prefill Modes — Manus AI tool call space restriction
3
+ *
4
+ * Instead of dynamically removing tools from the tool list (which would cause
5
+ * a different prompt hash → KV-cache miss → 10× higher cost), Manus restricts
6
+ * the action space by controlling `tool_choice` on each model call.
7
+ *
8
+ * Three modes:
9
+ * - 'auto' → model chooses freely (default; maps to tool_choice: "auto")
10
+ * - 'required' → model MUST make a tool call (maps to tool_choice: "required")
11
+ * - 'specified' → model MUST call a specific tool or tool-group prefix
12
+ * (maps to tool_choice: {type: "function", function: {name: exactName}}
13
+ * or the first tool whose name starts with namePrefix)
14
+ *
15
+ * Preserves the full tool list so KV-cache hits are maintained.
16
+ * Use for state-machine-like sequencing: "first call must be plan_update,
17
+ * then shell_exec, then file_write".
18
+ */
19
+ /**
20
+ * Resolve a `ResponseConstraint` to a concrete `tool_choice` value.
21
+ *
22
+ * @param constraint - The desired constraint
23
+ * @param availableToolNames - Names of tools in the current call (for prefix resolution)
24
+ * @returns OpenAI-compatible `tool_choice` value
25
+ */
26
+ export function resolveToolChoice(constraint, availableToolNames = []) {
27
+ switch (constraint.mode) {
28
+ case 'auto':
29
+ return 'auto';
30
+ case 'required':
31
+ return 'required';
32
+ case 'specified': {
33
+ const target = constraint.nameOrPrefix;
34
+ if (!target)
35
+ return 'auto';
36
+ // Exact match first
37
+ if (availableToolNames.includes(target)) {
38
+ return { type: 'function', function: { name: target } };
39
+ }
40
+ // Prefix match (e.g. "plan_" matches "plan_update", "plan_read")
41
+ if (target.endsWith('_')) {
42
+ const match = availableToolNames.find(n => n.startsWith(target));
43
+ if (match) {
44
+ return { type: 'function', function: { name: match } };
45
+ }
46
+ }
47
+ // Fallback: 'required' so at least some tool call is forced
48
+ return 'required';
49
+ }
50
+ default:
51
+ return 'auto';
52
+ }
53
+ }
54
+ // ============================================================================
55
+ // Session-level constraint registry
56
+ // ============================================================================
57
+ /**
58
+ * A simple per-session constraint stack. Push constraints for specific turns,
59
+ * pop after the turn completes. The top of the stack is the active constraint.
60
+ *
61
+ * Usage in agent-executor:
62
+ * constraintStack.push({ mode: 'required' }); // force tool call
63
+ * ... run LLM turn ...
64
+ * constraintStack.pop();
65
+ */
66
+ export class ResponseConstraintStack {
67
+ stack = [];
68
+ push(constraint) {
69
+ this.stack.push(constraint);
70
+ }
71
+ pop() {
72
+ return this.stack.pop();
73
+ }
74
+ /** Current active constraint (top of stack), or default 'auto' */
75
+ current() {
76
+ return this.stack[this.stack.length - 1] ?? { mode: 'auto' };
77
+ }
78
+ clear() {
79
+ this.stack = [];
80
+ }
81
+ isEmpty() {
82
+ return this.stack.length === 0;
83
+ }
84
+ }
85
+ let _globalConstraintStack = null;
86
+ export function getResponseConstraintStack() {
87
+ if (!_globalConstraintStack)
88
+ _globalConstraintStack = new ResponseConstraintStack();
89
+ return _globalConstraintStack;
90
+ }
91
+ //# sourceMappingURL=response-constraint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-constraint.js","sourceRoot":"","sources":["../../src/agent/response-constraint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AA4BH;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAA8B,EAC9B,qBAA+B,EAAE;IAEjC,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAEhB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QAEpB,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC;YACvC,IAAI,CAAC,MAAM;gBAAE,OAAO,MAAM,CAAC;YAE3B,oBAAoB;YACpB,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;YAC1D,CAAC;YAED,iEAAiE;YACjE,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;gBACjE,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACzD,CAAC;YACH,CAAC;YAED,4DAA4D;YAC5D,OAAO,UAAU,CAAC;QACpB,CAAC;QAED;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,oCAAoC;AACpC,+EAA+E;AAE/E;;;;;;;;GAQG;AACH,MAAM,OAAO,uBAAuB;IAC1B,KAAK,GAAyB,EAAE,CAAC;IAEzC,IAAI,CAAC,UAA8B;QACjC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IAED,GAAG;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED,kEAAkE;IAClE,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC/D,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IACjC,CAAC;CACF;AAED,IAAI,sBAAsB,GAAmC,IAAI,CAAC;AAElE,MAAM,UAAU,0BAA0B;IACxC,IAAI,CAAC,sBAAsB;QAAE,sBAAsB,GAAG,IAAI,uBAAuB,EAAE,CAAC;IACpF,OAAO,sBAAsB,CAAC;AAChC,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Todo Tracker — Manus AI-inspired attention bias
3
+ *
4
+ * Maintains a persistent `todo.md` in the working directory.
5
+ * On every agent turn the current task list is appended at the END of
6
+ * the LLM context, exploiting recency bias to keep objectives in focus
7
+ * across long sessions ("lost-in-the-middle" mitigation).
8
+ *
9
+ * The agent calls `todo_update` to mutate the list; a thin hook in
10
+ * AgentExecutor re-injects the latest block before each LLM call.
11
+ *
12
+ * Ref: "Context Engineering for AI Agents: Lessons from Building Manus"
13
+ * https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus
14
+ */
15
+ export type TodoStatus = 'pending' | 'in_progress' | 'done' | 'blocked';
16
+ export type TodoPriority = 'high' | 'medium' | 'low';
17
+ export interface TodoItem {
18
+ id: string;
19
+ text: string;
20
+ status: TodoStatus;
21
+ priority: TodoPriority;
22
+ subtasks: TodoItem[];
23
+ createdAt: number;
24
+ updatedAt: number;
25
+ }
26
+ export interface TodoUpdateInput {
27
+ /** Action to perform */
28
+ action: 'add' | 'complete' | 'update' | 'remove' | 'clear_done';
29
+ /** For add/update: item text */
30
+ text?: string;
31
+ /** For complete/update/remove: item id */
32
+ id?: string;
33
+ /** For update: new status */
34
+ status?: TodoStatus;
35
+ /** For add/update: priority (default 'medium') */
36
+ priority?: TodoPriority;
37
+ }
38
+ export declare function getTodoTracker(workDir?: string): TodoTracker;
39
+ export declare class TodoTracker {
40
+ private workDir;
41
+ private todoPath;
42
+ private items;
43
+ private loaded;
44
+ constructor(workDir: string);
45
+ load(): void;
46
+ save(): void;
47
+ add(text: string, priority?: TodoPriority): TodoItem;
48
+ complete(id: string): boolean;
49
+ update(id: string, updates: {
50
+ text?: string;
51
+ status?: TodoStatus;
52
+ priority?: TodoPriority;
53
+ }): boolean;
54
+ remove(id: string): boolean;
55
+ clearDone(): number;
56
+ getAll(): TodoItem[];
57
+ getPending(): TodoItem[];
58
+ hasPending(): boolean;
59
+ /**
60
+ * Build the context suffix injected at the END of the LLM context each turn.
61
+ * Returns null when there are no pending items (avoids noisy injections).
62
+ */
63
+ buildContextSuffix(): string | null;
64
+ private serialise;
65
+ private parseMd;
66
+ private findById;
67
+ }