@ipul-labs/forge 1.22.0 → 1.35.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 (294) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +153 -78
  3. package/dist/apple-touch-icon.png +0 -0
  4. package/dist/assets/index-BmEuPeOG.js +27 -0
  5. package/dist/assets/index-CSH1OQYQ.css +1 -0
  6. package/dist/boot-check.js +98 -0
  7. package/dist/favicon.svg +8 -0
  8. package/dist/icon-192.png +0 -0
  9. package/dist/icon-512.png +0 -0
  10. package/dist/icon.svg +12 -0
  11. package/dist/index.html +33 -0
  12. package/dist/manifest.webmanifest +18 -0
  13. package/dist/theme-init.js +11 -0
  14. package/lib/bin/cli/analyze.d.ts.map +1 -1
  15. package/lib/bin/cli/analyze.js +3 -44
  16. package/lib/bin/cli/analyze.js.map +1 -1
  17. package/lib/bin/cli/apply.d.ts.map +1 -1
  18. package/lib/bin/cli/apply.js +2 -20
  19. package/lib/bin/cli/apply.js.map +1 -1
  20. package/lib/bin/cli/cifix.d.ts.map +1 -1
  21. package/lib/bin/cli/cifix.js +4 -28
  22. package/lib/bin/cli/cifix.js.map +1 -1
  23. package/lib/bin/cli/close.d.ts.map +1 -1
  24. package/lib/bin/cli/close.js +2 -33
  25. package/lib/bin/cli/close.js.map +1 -1
  26. package/lib/bin/cli/createIssue.d.ts.map +1 -1
  27. package/lib/bin/cli/createIssue.js +3 -12
  28. package/lib/bin/cli/createIssue.js.map +1 -1
  29. package/lib/bin/cli/doctor.d.ts.map +1 -1
  30. package/lib/bin/cli/doctor.js +3 -4
  31. package/lib/bin/cli/doctor.js.map +1 -1
  32. package/lib/bin/cli/init.js +1 -10
  33. package/lib/bin/cli/init.js.map +1 -1
  34. package/lib/bin/cli/issue.d.ts.map +1 -1
  35. package/lib/bin/cli/issue.js +3 -12
  36. package/lib/bin/cli/issue.js.map +1 -1
  37. package/lib/bin/cli/issues.d.ts.map +1 -1
  38. package/lib/bin/cli/issues.js +3 -12
  39. package/lib/bin/cli/issues.js.map +1 -1
  40. package/lib/bin/cli/merge.d.ts.map +1 -1
  41. package/lib/bin/cli/merge.js +4 -20
  42. package/lib/bin/cli/merge.js.map +1 -1
  43. package/lib/bin/cli/refine.d.ts.map +1 -1
  44. package/lib/bin/cli/refine.js +2 -26
  45. package/lib/bin/cli/refine.js.map +1 -1
  46. package/lib/bin/cli/repl.d.ts.map +1 -1
  47. package/lib/bin/cli/repl.js +4 -13
  48. package/lib/bin/cli/repl.js.map +1 -1
  49. package/lib/bin/cli/repos.d.ts.map +1 -1
  50. package/lib/bin/cli/repos.js +1 -11
  51. package/lib/bin/cli/repos.js.map +1 -1
  52. package/lib/bin/cli/resetPassword.d.ts +21 -0
  53. package/lib/bin/cli/resetPassword.d.ts.map +1 -0
  54. package/lib/bin/cli/resetPassword.js +69 -0
  55. package/lib/bin/cli/resetPassword.js.map +1 -0
  56. package/lib/bin/cli/resolution.d.ts.map +1 -1
  57. package/lib/bin/cli/resolution.js +2 -19
  58. package/lib/bin/cli/resolution.js.map +1 -1
  59. package/lib/bin/cli/serverClient.d.ts +2 -0
  60. package/lib/bin/cli/serverClient.d.ts.map +1 -1
  61. package/lib/bin/cli/serverClient.js +8 -4
  62. package/lib/bin/cli/serverClient.js.map +1 -1
  63. package/lib/bin/cli/session.d.ts.map +1 -1
  64. package/lib/bin/cli/session.js.map +1 -1
  65. package/lib/bin/cli/sessionStore.d.ts +1 -1
  66. package/lib/bin/cli/sessionStore.js +2 -2
  67. package/lib/bin/cli/sessionStore.js.map +1 -1
  68. package/lib/bin/cli/ship.d.ts.map +1 -1
  69. package/lib/bin/cli/ship.js +15 -23
  70. package/lib/bin/cli/ship.js.map +1 -1
  71. package/lib/bin/cli/update.d.ts.map +1 -1
  72. package/lib/bin/cli/update.js +34 -28
  73. package/lib/bin/cli/update.js.map +1 -1
  74. package/lib/bin/cli/updatePlan.d.ts +30 -0
  75. package/lib/bin/cli/updatePlan.d.ts.map +1 -0
  76. package/lib/bin/cli/updatePlan.js +50 -0
  77. package/lib/bin/cli/updatePlan.js.map +1 -0
  78. package/lib/bin/cli/utils.d.ts +3 -0
  79. package/lib/bin/cli/utils.d.ts.map +1 -1
  80. package/lib/bin/cli/utils.js +7 -23
  81. package/lib/bin/cli/utils.js.map +1 -1
  82. package/lib/bin/cli/validate.d.ts.map +1 -1
  83. package/lib/bin/cli/validate.js +3 -25
  84. package/lib/bin/cli/validate.js.map +1 -1
  85. package/lib/bin/cli/watch.d.ts.map +1 -1
  86. package/lib/bin/cli/watch.js +3 -12
  87. package/lib/bin/cli/watch.js.map +1 -1
  88. package/lib/bin/forge-agent.js +10 -22
  89. package/lib/bin/forge-agent.js.map +1 -1
  90. package/lib/server/app.d.ts +24 -0
  91. package/lib/server/app.d.ts.map +1 -0
  92. package/lib/server/app.js +58 -0
  93. package/lib/server/app.js.map +1 -0
  94. package/lib/server/forge/analyses/analysisStore.d.ts +53 -0
  95. package/lib/server/forge/analyses/analysisStore.d.ts.map +1 -0
  96. package/lib/server/forge/analyses/analysisStore.js +77 -0
  97. package/lib/server/forge/analyses/analysisStore.js.map +1 -0
  98. package/lib/server/forge/auth/apiTokens.d.ts +34 -0
  99. package/lib/server/forge/auth/apiTokens.d.ts.map +1 -0
  100. package/lib/server/forge/auth/apiTokens.js +44 -0
  101. package/lib/server/forge/auth/apiTokens.js.map +1 -0
  102. package/lib/server/forge/auth/auditLog.d.ts +36 -0
  103. package/lib/server/forge/auth/auditLog.d.ts.map +1 -0
  104. package/lib/server/forge/auth/auditLog.js +56 -0
  105. package/lib/server/forge/auth/auditLog.js.map +1 -0
  106. package/lib/server/forge/auth/authConfig.d.ts +13 -0
  107. package/lib/server/forge/auth/authConfig.d.ts.map +1 -0
  108. package/lib/server/forge/auth/authConfig.js +37 -0
  109. package/lib/server/forge/auth/authConfig.js.map +1 -0
  110. package/lib/server/forge/auth/createAuth.d.ts +130 -0
  111. package/lib/server/forge/auth/createAuth.d.ts.map +1 -0
  112. package/lib/server/forge/auth/createAuth.js +387 -0
  113. package/lib/server/forge/auth/createAuth.js.map +1 -0
  114. package/lib/server/forge/auth/middleware.d.ts +10 -0
  115. package/lib/server/forge/auth/middleware.d.ts.map +1 -0
  116. package/lib/server/forge/auth/middleware.js +22 -0
  117. package/lib/server/forge/auth/middleware.js.map +1 -0
  118. package/lib/server/forge/auth/oidc.d.ts +38 -0
  119. package/lib/server/forge/auth/oidc.d.ts.map +1 -0
  120. package/lib/server/forge/auth/oidc.js +63 -0
  121. package/lib/server/forge/auth/oidc.js.map +1 -0
  122. package/lib/server/forge/auth/passwords.d.ts +7 -0
  123. package/lib/server/forge/auth/passwords.d.ts.map +1 -0
  124. package/lib/server/forge/auth/passwords.js +28 -0
  125. package/lib/server/forge/auth/passwords.js.map +1 -0
  126. package/lib/server/forge/auth/resetPassword.d.ts +14 -0
  127. package/lib/server/forge/auth/resetPassword.d.ts.map +1 -0
  128. package/lib/server/forge/auth/resetPassword.js +29 -0
  129. package/lib/server/forge/auth/resetPassword.js.map +1 -0
  130. package/lib/server/forge/auth/roles.d.ts +7 -0
  131. package/lib/server/forge/auth/roles.d.ts.map +1 -0
  132. package/lib/server/forge/auth/roles.js +15 -0
  133. package/lib/server/forge/auth/roles.js.map +1 -0
  134. package/lib/server/forge/auth/sessions.d.ts +27 -0
  135. package/lib/server/forge/auth/sessions.d.ts.map +1 -0
  136. package/lib/server/forge/auth/sessions.js +37 -0
  137. package/lib/server/forge/auth/sessions.js.map +1 -0
  138. package/lib/server/forge/auth/testHarness.d.ts +104 -0
  139. package/lib/server/forge/auth/testHarness.d.ts.map +1 -0
  140. package/lib/server/forge/auth/testHarness.js +53 -0
  141. package/lib/server/forge/auth/testHarness.js.map +1 -0
  142. package/lib/server/forge/auth/tokenHash.d.ts +3 -0
  143. package/lib/server/forge/auth/tokenHash.d.ts.map +1 -0
  144. package/lib/server/forge/auth/tokenHash.js +4 -0
  145. package/lib/server/forge/auth/tokenHash.js.map +1 -0
  146. package/lib/server/forge/auth/users.d.ts +51 -0
  147. package/lib/server/forge/auth/users.d.ts.map +1 -0
  148. package/lib/server/forge/auth/users.js +118 -0
  149. package/lib/server/forge/auth/users.js.map +1 -0
  150. package/lib/server/forge/core/ForgeAgent.d.ts +43 -1
  151. package/lib/server/forge/core/ForgeAgent.d.ts.map +1 -1
  152. package/lib/server/forge/core/ForgeAgent.js +209 -61
  153. package/lib/server/forge/core/ForgeAgent.js.map +1 -1
  154. package/lib/server/forge/core/agentClient.d.ts +7 -23
  155. package/lib/server/forge/core/agentClient.d.ts.map +1 -1
  156. package/lib/server/forge/core/agentClient.js +10 -25
  157. package/lib/server/forge/core/agentClient.js.map +1 -1
  158. package/lib/server/forge/core/claudeClient.d.ts +24 -1
  159. package/lib/server/forge/core/claudeClient.d.ts.map +1 -1
  160. package/lib/server/forge/core/claudeClient.js +25 -7
  161. package/lib/server/forge/core/claudeClient.js.map +1 -1
  162. package/lib/server/forge/core/configStore.d.ts +11 -1
  163. package/lib/server/forge/core/configStore.d.ts.map +1 -1
  164. package/lib/server/forge/core/configStore.js +33 -2
  165. package/lib/server/forge/core/configStore.js.map +1 -1
  166. package/lib/server/forge/core/dependencyPaths.d.ts +19 -0
  167. package/lib/server/forge/core/dependencyPaths.d.ts.map +1 -0
  168. package/lib/server/forge/core/dependencyPaths.js +32 -0
  169. package/lib/server/forge/core/dependencyPaths.js.map +1 -0
  170. package/lib/server/forge/core/evidence.d.ts +43 -0
  171. package/lib/server/forge/core/evidence.d.ts.map +1 -0
  172. package/lib/server/forge/core/evidence.js +108 -0
  173. package/lib/server/forge/core/evidence.js.map +1 -0
  174. package/lib/server/forge/core/jobs.d.ts +2 -0
  175. package/lib/server/forge/core/jobs.d.ts.map +1 -1
  176. package/lib/server/forge/core/jobs.js +8 -0
  177. package/lib/server/forge/core/jobs.js.map +1 -1
  178. package/lib/server/forge/core/localRepo.d.ts +31 -10
  179. package/lib/server/forge/core/localRepo.d.ts.map +1 -1
  180. package/lib/server/forge/core/localRepo.js +48 -82
  181. package/lib/server/forge/core/localRepo.js.map +1 -1
  182. package/lib/server/forge/core/prompts.d.ts +3 -1
  183. package/lib/server/forge/core/prompts.d.ts.map +1 -1
  184. package/lib/server/forge/core/prompts.js +14 -5
  185. package/lib/server/forge/core/prompts.js.map +1 -1
  186. package/lib/server/forge/core/providers/azuredevops.d.ts +4 -2
  187. package/lib/server/forge/core/providers/azuredevops.d.ts.map +1 -1
  188. package/lib/server/forge/core/providers/azuredevops.js +12 -2
  189. package/lib/server/forge/core/providers/azuredevops.js.map +1 -1
  190. package/lib/server/forge/core/providers/base.d.ts +29 -4
  191. package/lib/server/forge/core/providers/base.d.ts.map +1 -1
  192. package/lib/server/forge/core/providers/base.js +21 -3
  193. package/lib/server/forge/core/providers/base.js.map +1 -1
  194. package/lib/server/forge/core/providers/github.d.ts +7 -7
  195. package/lib/server/forge/core/providers/github.d.ts.map +1 -1
  196. package/lib/server/forge/core/providers/github.js +13 -4
  197. package/lib/server/forge/core/providers/github.js.map +1 -1
  198. package/lib/server/forge/core/providers/gitlab.d.ts +20 -3
  199. package/lib/server/forge/core/providers/gitlab.d.ts.map +1 -1
  200. package/lib/server/forge/core/providers/gitlab.js +65 -5
  201. package/lib/server/forge/core/providers/gitlab.js.map +1 -1
  202. package/lib/server/forge/core/providers/types.d.ts +20 -0
  203. package/lib/server/forge/core/providers/types.d.ts.map +1 -1
  204. package/lib/server/forge/core/secretBox.d.ts +17 -0
  205. package/lib/server/forge/core/secretBox.d.ts.map +1 -0
  206. package/lib/server/forge/core/secretBox.js +74 -0
  207. package/lib/server/forge/core/secretBox.js.map +1 -0
  208. package/lib/server/forge/core/types.d.ts +7 -1
  209. package/lib/server/forge/core/types.d.ts.map +1 -1
  210. package/lib/server/forge/core/validator/clone.d.ts +5 -4
  211. package/lib/server/forge/core/validator/clone.d.ts.map +1 -1
  212. package/lib/server/forge/core/validator/clone.js +6 -86
  213. package/lib/server/forge/core/validator/clone.js.map +1 -1
  214. package/lib/server/forge/core/validator/cmd.d.ts.map +1 -1
  215. package/lib/server/forge/core/validator/cmd.js +4 -1
  216. package/lib/server/forge/core/validator/cmd.js.map +1 -1
  217. package/lib/server/forge/core/validator/projectType.d.ts.map +1 -1
  218. package/lib/server/forge/core/validator/projectType.js +2 -1
  219. package/lib/server/forge/core/validator/projectType.js.map +1 -1
  220. package/lib/server/forge/core/validator/runners/node.d.ts.map +1 -1
  221. package/lib/server/forge/core/validator/runners/node.js +6 -2
  222. package/lib/server/forge/core/validator/runners/node.js.map +1 -1
  223. package/lib/server/forge/core/validator.d.ts.map +1 -1
  224. package/lib/server/forge/core/validator.js +28 -22
  225. package/lib/server/forge/core/validator.js.map +1 -1
  226. package/lib/server/forge/core/workspaces.d.ts +70 -0
  227. package/lib/server/forge/core/workspaces.d.ts.map +1 -0
  228. package/lib/server/forge/core/workspaces.js +348 -0
  229. package/lib/server/forge/core/workspaces.js.map +1 -0
  230. package/lib/server/forge/db/database.d.ts +22 -0
  231. package/lib/server/forge/db/database.d.ts.map +1 -0
  232. package/lib/server/forge/db/database.js +71 -0
  233. package/lib/server/forge/db/database.js.map +1 -0
  234. package/lib/server/forge/db/migrations.d.ts +11 -0
  235. package/lib/server/forge/db/migrations.d.ts.map +1 -0
  236. package/lib/server/forge/db/migrations.js +87 -0
  237. package/lib/server/forge/db/migrations.js.map +1 -0
  238. package/lib/server/forge/routes.d.ts.map +1 -1
  239. package/lib/server/forge/routes.js +413 -163
  240. package/lib/server/forge/routes.js.map +1 -1
  241. package/lib/server/forge/sse.d.ts +10 -0
  242. package/lib/server/forge/sse.d.ts.map +1 -0
  243. package/lib/server/forge/sse.js +22 -0
  244. package/lib/server/forge/sse.js.map +1 -0
  245. package/lib/server/spa.d.ts +12 -0
  246. package/lib/server/spa.d.ts.map +1 -0
  247. package/lib/server/spa.js +23 -0
  248. package/lib/server/spa.js.map +1 -0
  249. package/lib/server.js +9 -24
  250. package/lib/server.js.map +1 -1
  251. package/lib/shared/events.d.ts +3 -0
  252. package/lib/shared/events.d.ts.map +1 -1
  253. package/lib/shared/events.js +3 -0
  254. package/lib/shared/events.js.map +1 -1
  255. package/lib/shared/packageRoot.d.ts +11 -0
  256. package/lib/shared/packageRoot.d.ts.map +1 -0
  257. package/lib/shared/packageRoot.js +23 -0
  258. package/lib/shared/packageRoot.js.map +1 -0
  259. package/lib/shared/project.d.ts +3 -0
  260. package/lib/shared/project.d.ts.map +1 -0
  261. package/lib/shared/project.js +3 -0
  262. package/lib/shared/project.js.map +1 -0
  263. package/package.json +24 -9
  264. package/lib/bin/cli/improve.d.ts +0 -2
  265. package/lib/bin/cli/improve.d.ts.map +0 -1
  266. package/lib/bin/cli/improve.js +0 -189
  267. package/lib/bin/cli/improve.js.map +0 -1
  268. package/lib/bin/cli/stats.d.ts +0 -2
  269. package/lib/bin/cli/stats.d.ts.map +0 -1
  270. package/lib/bin/cli/stats.js +0 -78
  271. package/lib/bin/cli/stats.js.map +0 -1
  272. package/lib/server/forge/core/k8s.d.ts +0 -18
  273. package/lib/server/forge/core/k8s.d.ts.map +0 -1
  274. package/lib/server/forge/core/k8s.js +0 -49
  275. package/lib/server/forge/core/k8s.js.map +0 -1
  276. package/lib/server/forge/core/openclawClient.d.ts +0 -61
  277. package/lib/server/forge/core/openclawClient.d.ts.map +0 -1
  278. package/lib/server/forge/core/openclawClient.js +0 -111
  279. package/lib/server/forge/core/openclawClient.js.map +0 -1
  280. package/lib/server/forge/core/quotaClient.d.ts +0 -48
  281. package/lib/server/forge/core/quotaClient.d.ts.map +0 -1
  282. package/lib/server/forge/core/quotaClient.js +0 -88
  283. package/lib/server/forge/core/quotaClient.js.map +0 -1
  284. package/lib/server/forge/core/selfImprove.d.ts +0 -43
  285. package/lib/server/forge/core/selfImprove.d.ts.map +0 -1
  286. package/lib/server/forge/core/selfImprove.js +0 -372
  287. package/lib/server/forge/core/selfImprove.js.map +0 -1
  288. package/lib/server/forge/core/telemetry.d.ts +0 -100
  289. package/lib/server/forge/core/telemetry.d.ts.map +0 -1
  290. package/lib/server/forge/core/telemetry.js +0 -273
  291. package/lib/server/forge/core/telemetry.js.map +0 -1
  292. package/scripts/fix-shebang.cjs +0 -11
  293. package/scripts/inject-readme.cjs +0 -23
  294. package/scripts/local-rollout.sh +0 -134
@@ -1,273 +0,0 @@
1
- /**
2
- * server/forge/core/telemetry.ts
3
- *
4
- * Append-only telemetry store for Forge's self-improvement loop.
5
- *
6
- * Every analysis, refine, CI-fix, apply, validate, merge, and close records
7
- * its outcome here. The data feeds pattern detection which can identify
8
- * recurring failures and propose fixes against Forge's own repo.
9
- *
10
- * Storage: ~/.forge/telemetry/
11
- * events.ndjson — append-only log of every telemetry event
12
- * summary.json — rolling aggregates (updated on each write)
13
- *
14
- * Events are fire-and-forget — telemetry failures never break the main flow.
15
- */
16
- import { existsSync } from "node:fs";
17
- import fs from "node:fs/promises";
18
- import os from "node:os";
19
- import path from "node:path";
20
- // ─── Storage ─────────────────────────────────────────────────────────────────
21
- function telemetryDir() {
22
- return process.env.FORGE_TELEMETRY_PATH ?? path.join(os.homedir(), ".forge", "telemetry");
23
- }
24
- function eventsFile() { return path.join(telemetryDir(), "events.ndjson"); }
25
- function summaryFile() { return path.join(telemetryDir(), "summary.json"); }
26
- const MAX_RECENT_ERRORS = 50;
27
- async function ensureDir() {
28
- await fs.mkdir(telemetryDir(), { recursive: true, mode: 0o700 });
29
- }
30
- // ─── Public API ──────────────────────────────────────────────────────────────
31
- export async function record(event) {
32
- try {
33
- await ensureDir();
34
- const line = JSON.stringify(event) + "\n";
35
- await fs.appendFile(eventsFile(), line, { encoding: "utf8", mode: 0o600 });
36
- await updateSummary(event);
37
- // Fire-and-forget auto-evaluation after recording
38
- triggerAutoEval().catch(() => { });
39
- }
40
- catch {
41
- // telemetry is best-effort — never break the main flow
42
- }
43
- }
44
- let autoEvalPending = false;
45
- async function triggerAutoEval() {
46
- if (autoEvalPending)
47
- return;
48
- autoEvalPending = true;
49
- try {
50
- const { maybeAutoEvaluate } = await import("./selfImprove.js");
51
- await maybeAutoEvaluate();
52
- }
53
- catch {
54
- // auto-eval is best-effort
55
- }
56
- finally {
57
- autoEvalPending = false;
58
- }
59
- }
60
- export function buildEvent(operation, repo, iid, success, startTime, opts = {}) {
61
- return {
62
- ts: new Date().toISOString(),
63
- operation,
64
- repo,
65
- iid,
66
- success,
67
- durationMs: Date.now() - startTime,
68
- ...opts,
69
- };
70
- }
71
- export async function getSummary() {
72
- try {
73
- if (!existsSync(summaryFile()))
74
- return emptySummary();
75
- const raw = await fs.readFile(summaryFile(), "utf8");
76
- return JSON.parse(raw);
77
- }
78
- catch {
79
- return emptySummary();
80
- }
81
- }
82
- export async function getRecentEvents(limit = 100) {
83
- try {
84
- if (!existsSync(eventsFile()))
85
- return [];
86
- const raw = await fs.readFile(eventsFile(), "utf8");
87
- const lines = raw.trim().split("\n").filter(Boolean);
88
- return lines
89
- .slice(-limit)
90
- .map((line) => {
91
- try {
92
- return JSON.parse(line);
93
- }
94
- catch {
95
- return null;
96
- }
97
- })
98
- .filter((e) => e !== null);
99
- }
100
- catch {
101
- return [];
102
- }
103
- }
104
- export async function getFailurePatterns() {
105
- const events = await getRecentEvents(500);
106
- const failures = events.filter((e) => !e.success && !e.resolved);
107
- if (failures.length === 0)
108
- return [];
109
- const patterns = new Map();
110
- for (const f of failures) {
111
- const errorKey = normalizeError(f.error ?? "unknown");
112
- const key = `${f.operation}:${errorKey}`;
113
- if (!patterns.has(key)) {
114
- patterns.set(key, {
115
- operation: f.operation,
116
- errorPattern: errorKey,
117
- count: 0,
118
- repos: new Set(),
119
- firstSeen: f.ts,
120
- lastSeen: f.ts,
121
- examples: [],
122
- });
123
- }
124
- const p = patterns.get(key);
125
- p.count++;
126
- p.repos.add(f.repo);
127
- p.lastSeen = f.ts;
128
- if (p.examples.length < 3) {
129
- p.examples.push({ ts: f.ts, repo: f.repo, iid: f.iid, error: f.error ?? "" });
130
- }
131
- }
132
- return Array.from(patterns.values())
133
- .filter((p) => p.count >= 2)
134
- .sort((a, b) => b.count - a.count)
135
- .map((p) => ({ ...p, repos: Array.from(p.repos) }));
136
- }
137
- /**
138
- * Mark failure events as resolved when the underlying issue has been fixed.
139
- * Matches events by operation and error substring. Resolved events are
140
- * excluded from getFailurePatterns() and the summary is rebuilt.
141
- *
142
- * Returns the number of events resolved.
143
- */
144
- export async function resolvePatterns(operation, errorMatch) {
145
- try {
146
- if (!existsSync(eventsFile()))
147
- return 0;
148
- const raw = await fs.readFile(eventsFile(), "utf8");
149
- const lines = raw.trim().split("\n").filter(Boolean);
150
- let resolved = 0;
151
- const updated = [];
152
- for (const line of lines) {
153
- try {
154
- const evt = JSON.parse(line);
155
- if (!evt.success &&
156
- !evt.resolved &&
157
- evt.operation === operation &&
158
- evt.error &&
159
- normalizeError(evt.error).includes(normalizeError(errorMatch))) {
160
- evt.resolved = true;
161
- evt.resolvedAt = new Date().toISOString();
162
- resolved++;
163
- }
164
- updated.push(JSON.stringify(evt));
165
- }
166
- catch {
167
- updated.push(line);
168
- }
169
- }
170
- if (resolved > 0) {
171
- await fs.writeFile(eventsFile(), updated.join("\n") + "\n", { encoding: "utf8", mode: 0o600 });
172
- await rebuildSummary();
173
- }
174
- return resolved;
175
- }
176
- catch {
177
- return 0;
178
- }
179
- }
180
- async function rebuildSummary() {
181
- const events = await getRecentEvents(10000);
182
- const summary = emptySummary();
183
- summary.totalEvents = events.length;
184
- for (const event of events) {
185
- if (!summary.byOperation[event.operation]) {
186
- summary.byOperation[event.operation] = emptyStats();
187
- }
188
- const stats = summary.byOperation[event.operation];
189
- stats.total++;
190
- if (event.resolved) {
191
- stats.successes++;
192
- }
193
- else if (event.success) {
194
- stats.successes++;
195
- }
196
- else {
197
- stats.failures++;
198
- if (event.error) {
199
- summary.recentErrors.push({
200
- ts: event.ts,
201
- operation: event.operation,
202
- repo: event.repo,
203
- iid: event.iid,
204
- error: event.error,
205
- });
206
- }
207
- }
208
- stats.avgDurationMs = Math.round(((stats.avgDurationMs * (stats.total - 1)) + event.durationMs) / stats.total);
209
- if (event.tokens) {
210
- stats.totalTokensIn += event.tokens.input;
211
- stats.totalTokensOut += event.tokens.output;
212
- }
213
- if (event.cost)
214
- stats.totalCost += event.cost;
215
- }
216
- if (summary.recentErrors.length > 50) {
217
- summary.recentErrors = summary.recentErrors.slice(-50);
218
- }
219
- summary.lastUpdated = new Date().toISOString();
220
- await fs.writeFile(summaryFile(), JSON.stringify(summary, null, 2), { encoding: "utf8", mode: 0o600 });
221
- }
222
- // ─── Internal ────────────────────────────────────────────────────────────────
223
- function emptySummary() {
224
- return { totalEvents: 0, byOperation: {}, recentErrors: [], lastUpdated: new Date().toISOString() };
225
- }
226
- function emptyStats() {
227
- return { total: 0, successes: 0, failures: 0, avgDurationMs: 0, totalTokensIn: 0, totalTokensOut: 0, totalCost: 0 };
228
- }
229
- async function updateSummary(event) {
230
- const summary = await getSummary();
231
- summary.totalEvents++;
232
- summary.lastUpdated = new Date().toISOString();
233
- if (!summary.byOperation[event.operation]) {
234
- summary.byOperation[event.operation] = emptyStats();
235
- }
236
- const stats = summary.byOperation[event.operation];
237
- stats.total++;
238
- if (event.success)
239
- stats.successes++;
240
- else
241
- stats.failures++;
242
- // Rolling average duration
243
- stats.avgDurationMs = Math.round(((stats.avgDurationMs * (stats.total - 1)) + event.durationMs) / stats.total);
244
- if (event.tokens) {
245
- stats.totalTokensIn += event.tokens.input;
246
- stats.totalTokensOut += event.tokens.output;
247
- }
248
- if (event.cost)
249
- stats.totalCost += event.cost;
250
- if (!event.success && event.error) {
251
- summary.recentErrors.push({
252
- ts: event.ts,
253
- operation: event.operation,
254
- repo: event.repo,
255
- iid: event.iid,
256
- error: event.error,
257
- });
258
- if (summary.recentErrors.length > MAX_RECENT_ERRORS) {
259
- summary.recentErrors = summary.recentErrors.slice(-MAX_RECENT_ERRORS);
260
- }
261
- }
262
- await fs.writeFile(summaryFile(), JSON.stringify(summary, null, 2), { encoding: "utf8", mode: 0o600 });
263
- }
264
- function normalizeError(error) {
265
- return error
266
- .replace(/\d+/g, "N")
267
- .replace(/[a-f0-9]{8,}/gi, "HASH")
268
- .replace(/https?:\/\/\S+/g, "URL")
269
- .replace(/\s+/g, " ")
270
- .trim()
271
- .slice(0, 120);
272
- }
273
- //# sourceMappingURL=telemetry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../../../server/forge/core/telemetry.ts"],"names":[],"mappings":"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"}
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env node
2
- const fs = require("fs");
3
- const path = require("path");
4
-
5
- const bin = path.resolve(__dirname, "..", "lib", "bin", "forge-agent.js");
6
- if (!fs.existsSync(bin)) process.exit(0);
7
-
8
- let content = fs.readFileSync(bin, "utf8");
9
- content = content.replace(/^#!\/usr\/bin\/env tsx/, "#!/usr/bin/env node");
10
- fs.writeFileSync(bin, content);
11
- fs.chmodSync(bin, 0o755);
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env node
2
- const fs = require("fs");
3
- const path = require("path");
4
-
5
- const root = path.resolve(__dirname, "..");
6
- const pkgPath = path.join(root, "package.json");
7
- const readmePath = path.join(root, "README.md");
8
-
9
- if (!fs.existsSync(readmePath)) process.exit(0);
10
-
11
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
12
- pkg.readme = fs.readFileSync(readmePath, "utf8");
13
-
14
- // Rewrite bin/main/exports to compiled lib/ paths for npm publish
15
- pkg.bin = { forge: "lib/bin/forge-agent.js" };
16
- pkg.main = "lib/server/forge/routes.js";
17
- pkg.exports = {
18
- ".": "./lib/server/forge/routes.js",
19
- "./agent": "./lib/server/forge/core/ForgeAgent.js",
20
- "./providers": "./lib/server/forge/core/providers/index.js",
21
- };
22
-
23
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
@@ -1,134 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ──────────────────────────────────────────────────────────────────────────────
3
- # Local dry-run of the same manifests + commands the *-rollout CI jobs execute.
4
- # Catches manifest bugs, missing env vars, image-pull problems, and rollout
5
- # logic errors BEFORE burning another CI cycle. Uses your local kubeconfig
6
- # (admin creds against k3s), so it does NOT test the agent SA's RBAC — for
7
- # that, the actual CI run is still the source of truth.
8
- #
9
- # ./scripts/local-rollout.sh [test|prep|prod] [image-tag]
10
- #
11
- # Defaults: env=test, image-tag=<current deployment's tag OR "latest">
12
- #
13
- # Exits non-zero on the first failure with a clear message.
14
- # ──────────────────────────────────────────────────────────────────────────────
15
-
16
- set -euo pipefail
17
-
18
- ENV=${1:-test}
19
- IMAGE_TAG=${2:-}
20
-
21
- case "$ENV" in
22
- test) NS=test; DEPLOY=forge-test; MANIFEST_DIR=manifests/test/forge-test ;;
23
- prep) NS=prep; DEPLOY=forge-prep; MANIFEST_DIR=manifests/prep/forge-prep ;;
24
- prod) NS=prod; DEPLOY=forge; MANIFEST_DIR=manifests/prod/forge ;;
25
- *) echo "Usage: $0 [test|prep|prod] [image-tag]"; exit 2 ;;
26
- esac
27
-
28
- # All envs pull from the same consolidated image repo. Per-env differences
29
- # live in the manifests, not in the image.
30
- IMAGE_REPO=iplayulisten/forge
31
-
32
- # ─── Helpers ──────────────────────────────────────────────────────────────────
33
-
34
- c_step() { printf '\n\033[1;34m── %s ──\033[0m\n' "$*"; }
35
- c_ok() { printf '\033[1;32m✓\033[0m %s\n' "$*"; }
36
- c_warn() { printf '\033[1;33m⚠\033[0m %s\n' "$*"; }
37
- c_fail() { printf '\033[1;31m✗\033[0m %s\n' "$*"; exit 1; }
38
-
39
- require() { command -v "$1" >/dev/null 2>&1 || c_fail "missing required binary: $1"; }
40
-
41
- # ─── Preflight ────────────────────────────────────────────────────────────────
42
-
43
- c_step "Preflight"
44
- require kubectl
45
- require openssl
46
-
47
- CTX=$(kubectl config current-context 2>/dev/null || true)
48
- [ -n "$CTX" ] || c_fail "no current kubectl context — set one with 'kubectl config use-context <name>'"
49
- c_ok "kubectl context: $CTX"
50
-
51
- if ! kubectl get ns "$NS" >/dev/null 2>&1; then
52
- c_warn "namespace '$NS' doesn't exist — creating it"
53
- kubectl create namespace "$NS"
54
- c_ok "namespace '$NS' created"
55
- else
56
- c_ok "namespace '$NS' exists"
57
- fi
58
-
59
- [ -d "$MANIFEST_DIR" ] || c_fail "manifest dir not found: $MANIFEST_DIR"
60
- c_ok "manifest dir: $MANIFEST_DIR"
61
-
62
- # ─── Secret creation (mirrors CI) ─────────────────────────────────────────────
63
-
64
- c_step "Secret: forge-secret"
65
- : "${FORGE_TOKEN:=}"
66
- : "${ANTHROPIC_API_KEY:=}"
67
- : "${GITLAB_TOKEN:=}"
68
-
69
- if [ -z "$FORGE_TOKEN" ]; then
70
- c_warn "FORGE_TOKEN unset — generating a throwaway for this run"
71
- FORGE_TOKEN=$(openssl rand -hex 32)
72
- fi
73
- [ -n "$GITLAB_TOKEN" ] || c_warn "GITLAB_TOKEN unset (forge backend needs this at runtime — ok for manifest test)"
74
- [ -n "$ANTHROPIC_API_KEY" ] || c_warn "ANTHROPIC_API_KEY unset (optional, only needed for quota probe)"
75
-
76
- kubectl create secret generic forge-secret \
77
- --from-literal=FORGE_TOKEN="$FORGE_TOKEN" \
78
- --from-literal=ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
79
- --from-literal=GITLAB_TOKEN="$GITLAB_TOKEN" \
80
- -n "$NS" --dry-run=client -o yaml | kubectl apply -f -
81
- c_ok "forge-secret applied"
82
-
83
- # ─── Apply manifests in CI order ──────────────────────────────────────────────
84
-
85
- for f in config-map.yaml service.yaml deployment.yaml; do
86
- path="$MANIFEST_DIR/$f"
87
- [ -f "$path" ] || c_fail "missing manifest: $path"
88
- c_step "Applying $f"
89
- kubectl apply -f "$path"
90
- c_ok "$f applied"
91
- done
92
-
93
- # ─── Image tag ────────────────────────────────────────────────────────────────
94
-
95
- if [ -z "$IMAGE_TAG" ]; then
96
- CURRENT_IMAGE=$(kubectl get deploy/"$DEPLOY" -n "$NS" -o jsonpath='{.spec.template.spec.containers[0].image}' 2>/dev/null || true)
97
- if [ -n "$CURRENT_IMAGE" ] && [ "$CURRENT_IMAGE" != "*__VERSION__*" ] && [[ "$CURRENT_IMAGE" != *__VERSION__* ]]; then
98
- IMAGE_TAG=${CURRENT_IMAGE##*:}
99
- c_ok "reusing current deployment image tag: $IMAGE_TAG"
100
- else
101
- IMAGE_TAG=latest
102
- c_warn "no usable tag in current deployment — falling back to '$IMAGE_TAG' (may fail to pull)"
103
- fi
104
- fi
105
-
106
- c_step "kubectl set image → ${IMAGE_REPO}:${IMAGE_TAG}"
107
- kubectl set image deployment/"$DEPLOY" -n "$NS" "${DEPLOY}=${IMAGE_REPO}:${IMAGE_TAG}"
108
- c_ok "image set"
109
-
110
- # ─── Rollout ──────────────────────────────────────────────────────────────────
111
-
112
- c_step "Rollout status (120s timeout)"
113
- if kubectl rollout status deployment/"$DEPLOY" -n "$NS" --timeout=120s; then
114
- c_ok "rollout succeeded"
115
- else
116
- c_warn "rollout did not finish in 120s — dumping pod state to help diagnose"
117
- kubectl get pods -n "$NS" -l app="$DEPLOY" -o wide || true
118
- kubectl describe deployment/"$DEPLOY" -n "$NS" | sed -n '/Events:/,$p' || true
119
- kubectl get events -n "$NS" --sort-by=.lastTimestamp | tail -20 || true
120
- exit 1
121
- fi
122
-
123
- # ─── Summary ──────────────────────────────────────────────────────────────────
124
-
125
- c_step "Summary"
126
- kubectl get pods,svc,deploy -n "$NS" -l app="$DEPLOY"
127
- c_ok "local rollout for '$ENV' passed"
128
- echo
129
- echo "Next: push CI. If CI fails where this didn't, it's agent SA RBAC."
130
- echo "To tear down what this script created:"
131
- echo " kubectl delete -f $MANIFEST_DIR/deployment.yaml -n $NS"
132
- echo " kubectl delete -f $MANIFEST_DIR/service.yaml -n $NS"
133
- echo " kubectl delete -f $MANIFEST_DIR/config-map.yaml -n $NS"
134
- echo " kubectl delete secret forge-secret -n $NS"