@ipul-labs/forge 1.21.2 → 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.
- package/LICENSE +21 -0
- package/README.md +161 -78
- package/dist/apple-touch-icon.png +0 -0
- package/dist/assets/index-BmEuPeOG.js +27 -0
- package/dist/assets/index-CSH1OQYQ.css +1 -0
- package/dist/boot-check.js +98 -0
- package/dist/favicon.svg +8 -0
- package/dist/icon-192.png +0 -0
- package/dist/icon-512.png +0 -0
- package/dist/icon.svg +12 -0
- package/dist/index.html +33 -0
- package/dist/manifest.webmanifest +18 -0
- package/dist/theme-init.js +11 -0
- package/lib/bin/cli/analyze.d.ts.map +1 -1
- package/lib/bin/cli/analyze.js +3 -44
- package/lib/bin/cli/analyze.js.map +1 -1
- package/lib/bin/cli/apply.d.ts.map +1 -1
- package/lib/bin/cli/apply.js +2 -20
- package/lib/bin/cli/apply.js.map +1 -1
- package/lib/bin/cli/cifix.d.ts.map +1 -1
- package/lib/bin/cli/cifix.js +4 -28
- package/lib/bin/cli/cifix.js.map +1 -1
- package/lib/bin/cli/close.d.ts.map +1 -1
- package/lib/bin/cli/close.js +2 -33
- package/lib/bin/cli/close.js.map +1 -1
- package/lib/bin/cli/createIssue.d.ts.map +1 -1
- package/lib/bin/cli/createIssue.js +3 -12
- package/lib/bin/cli/createIssue.js.map +1 -1
- package/lib/bin/cli/doctor.d.ts.map +1 -1
- package/lib/bin/cli/doctor.js +3 -4
- package/lib/bin/cli/doctor.js.map +1 -1
- package/lib/bin/cli/init.js +1 -10
- package/lib/bin/cli/init.js.map +1 -1
- package/lib/bin/cli/issue.d.ts.map +1 -1
- package/lib/bin/cli/issue.js +3 -12
- package/lib/bin/cli/issue.js.map +1 -1
- package/lib/bin/cli/issues.d.ts.map +1 -1
- package/lib/bin/cli/issues.js +3 -12
- package/lib/bin/cli/issues.js.map +1 -1
- package/lib/bin/cli/merge.d.ts.map +1 -1
- package/lib/bin/cli/merge.js +4 -20
- package/lib/bin/cli/merge.js.map +1 -1
- package/lib/bin/cli/refine.d.ts.map +1 -1
- package/lib/bin/cli/refine.js +2 -26
- package/lib/bin/cli/refine.js.map +1 -1
- package/lib/bin/cli/repl.d.ts.map +1 -1
- package/lib/bin/cli/repl.js +4 -13
- package/lib/bin/cli/repl.js.map +1 -1
- package/lib/bin/cli/repos.d.ts.map +1 -1
- package/lib/bin/cli/repos.js +1 -11
- package/lib/bin/cli/repos.js.map +1 -1
- package/lib/bin/cli/resetPassword.d.ts +21 -0
- package/lib/bin/cli/resetPassword.d.ts.map +1 -0
- package/lib/bin/cli/resetPassword.js +69 -0
- package/lib/bin/cli/resetPassword.js.map +1 -0
- package/lib/bin/cli/resolution.d.ts.map +1 -1
- package/lib/bin/cli/resolution.js +2 -19
- package/lib/bin/cli/resolution.js.map +1 -1
- package/lib/bin/cli/serverClient.d.ts +2 -0
- package/lib/bin/cli/serverClient.d.ts.map +1 -1
- package/lib/bin/cli/serverClient.js +8 -4
- package/lib/bin/cli/serverClient.js.map +1 -1
- package/lib/bin/cli/session.d.ts.map +1 -1
- package/lib/bin/cli/session.js.map +1 -1
- package/lib/bin/cli/sessionStore.d.ts +1 -1
- package/lib/bin/cli/sessionStore.js +2 -2
- package/lib/bin/cli/sessionStore.js.map +1 -1
- package/lib/bin/cli/ship.d.ts.map +1 -1
- package/lib/bin/cli/ship.js +15 -23
- package/lib/bin/cli/ship.js.map +1 -1
- package/lib/bin/cli/update.d.ts.map +1 -1
- package/lib/bin/cli/update.js +34 -28
- package/lib/bin/cli/update.js.map +1 -1
- package/lib/bin/cli/updatePlan.d.ts +30 -0
- package/lib/bin/cli/updatePlan.d.ts.map +1 -0
- package/lib/bin/cli/updatePlan.js +50 -0
- package/lib/bin/cli/updatePlan.js.map +1 -0
- package/lib/bin/cli/utils.d.ts +3 -0
- package/lib/bin/cli/utils.d.ts.map +1 -1
- package/lib/bin/cli/utils.js +7 -23
- package/lib/bin/cli/utils.js.map +1 -1
- package/lib/bin/cli/validate.d.ts.map +1 -1
- package/lib/bin/cli/validate.js +3 -25
- package/lib/bin/cli/validate.js.map +1 -1
- package/lib/bin/cli/watch.d.ts.map +1 -1
- package/lib/bin/cli/watch.js +3 -12
- package/lib/bin/cli/watch.js.map +1 -1
- package/lib/bin/forge-agent.js +10 -22
- package/lib/bin/forge-agent.js.map +1 -1
- package/lib/server/app.d.ts +24 -0
- package/lib/server/app.d.ts.map +1 -0
- package/lib/server/app.js +58 -0
- package/lib/server/app.js.map +1 -0
- package/lib/server/forge/analyses/analysisStore.d.ts +53 -0
- package/lib/server/forge/analyses/analysisStore.d.ts.map +1 -0
- package/lib/server/forge/analyses/analysisStore.js +77 -0
- package/lib/server/forge/analyses/analysisStore.js.map +1 -0
- package/lib/server/forge/auth/apiTokens.d.ts +34 -0
- package/lib/server/forge/auth/apiTokens.d.ts.map +1 -0
- package/lib/server/forge/auth/apiTokens.js +44 -0
- package/lib/server/forge/auth/apiTokens.js.map +1 -0
- package/lib/server/forge/auth/auditLog.d.ts +36 -0
- package/lib/server/forge/auth/auditLog.d.ts.map +1 -0
- package/lib/server/forge/auth/auditLog.js +56 -0
- package/lib/server/forge/auth/auditLog.js.map +1 -0
- package/lib/server/forge/auth/authConfig.d.ts +13 -0
- package/lib/server/forge/auth/authConfig.d.ts.map +1 -0
- package/lib/server/forge/auth/authConfig.js +37 -0
- package/lib/server/forge/auth/authConfig.js.map +1 -0
- package/lib/server/forge/auth/createAuth.d.ts +130 -0
- package/lib/server/forge/auth/createAuth.d.ts.map +1 -0
- package/lib/server/forge/auth/createAuth.js +387 -0
- package/lib/server/forge/auth/createAuth.js.map +1 -0
- package/lib/server/forge/auth/middleware.d.ts +10 -0
- package/lib/server/forge/auth/middleware.d.ts.map +1 -0
- package/lib/server/forge/auth/middleware.js +22 -0
- package/lib/server/forge/auth/middleware.js.map +1 -0
- package/lib/server/forge/auth/oidc.d.ts +38 -0
- package/lib/server/forge/auth/oidc.d.ts.map +1 -0
- package/lib/server/forge/auth/oidc.js +63 -0
- package/lib/server/forge/auth/oidc.js.map +1 -0
- package/lib/server/forge/auth/passwords.d.ts +7 -0
- package/lib/server/forge/auth/passwords.d.ts.map +1 -0
- package/lib/server/forge/auth/passwords.js +28 -0
- package/lib/server/forge/auth/passwords.js.map +1 -0
- package/lib/server/forge/auth/resetPassword.d.ts +14 -0
- package/lib/server/forge/auth/resetPassword.d.ts.map +1 -0
- package/lib/server/forge/auth/resetPassword.js +29 -0
- package/lib/server/forge/auth/resetPassword.js.map +1 -0
- package/lib/server/forge/auth/roles.d.ts +7 -0
- package/lib/server/forge/auth/roles.d.ts.map +1 -0
- package/lib/server/forge/auth/roles.js +15 -0
- package/lib/server/forge/auth/roles.js.map +1 -0
- package/lib/server/forge/auth/sessions.d.ts +27 -0
- package/lib/server/forge/auth/sessions.d.ts.map +1 -0
- package/lib/server/forge/auth/sessions.js +37 -0
- package/lib/server/forge/auth/sessions.js.map +1 -0
- package/lib/server/forge/auth/testHarness.d.ts +104 -0
- package/lib/server/forge/auth/testHarness.d.ts.map +1 -0
- package/lib/server/forge/auth/testHarness.js +53 -0
- package/lib/server/forge/auth/testHarness.js.map +1 -0
- package/lib/server/forge/auth/tokenHash.d.ts +3 -0
- package/lib/server/forge/auth/tokenHash.d.ts.map +1 -0
- package/lib/server/forge/auth/tokenHash.js +4 -0
- package/lib/server/forge/auth/tokenHash.js.map +1 -0
- package/lib/server/forge/auth/users.d.ts +51 -0
- package/lib/server/forge/auth/users.d.ts.map +1 -0
- package/lib/server/forge/auth/users.js +118 -0
- package/lib/server/forge/auth/users.js.map +1 -0
- package/lib/server/forge/core/ForgeAgent.d.ts +58 -1
- package/lib/server/forge/core/ForgeAgent.d.ts.map +1 -1
- package/lib/server/forge/core/ForgeAgent.js +280 -32
- package/lib/server/forge/core/ForgeAgent.js.map +1 -1
- package/lib/server/forge/core/agentClient.d.ts +7 -5
- package/lib/server/forge/core/agentClient.d.ts.map +1 -1
- package/lib/server/forge/core/agentClient.js +11 -15
- package/lib/server/forge/core/agentClient.js.map +1 -1
- package/lib/server/forge/core/agentMode.d.ts +38 -0
- package/lib/server/forge/core/agentMode.d.ts.map +1 -0
- package/lib/server/forge/core/agentMode.js +43 -0
- package/lib/server/forge/core/agentMode.js.map +1 -0
- package/lib/server/forge/core/claudeClient.d.ts +63 -0
- package/lib/server/forge/core/claudeClient.d.ts.map +1 -1
- package/lib/server/forge/core/claudeClient.js +142 -50
- package/lib/server/forge/core/claudeClient.js.map +1 -1
- package/lib/server/forge/core/configStore.d.ts +12 -1
- package/lib/server/forge/core/configStore.d.ts.map +1 -1
- package/lib/server/forge/core/configStore.js +39 -2
- package/lib/server/forge/core/configStore.js.map +1 -1
- package/lib/server/forge/core/dependencyPaths.d.ts +19 -0
- package/lib/server/forge/core/dependencyPaths.d.ts.map +1 -0
- package/lib/server/forge/core/dependencyPaths.js +32 -0
- package/lib/server/forge/core/dependencyPaths.js.map +1 -0
- package/lib/server/forge/core/evidence.d.ts +43 -0
- package/lib/server/forge/core/evidence.d.ts.map +1 -0
- package/lib/server/forge/core/evidence.js +108 -0
- package/lib/server/forge/core/evidence.js.map +1 -0
- package/lib/server/forge/core/jobs.d.ts +2 -0
- package/lib/server/forge/core/jobs.d.ts.map +1 -1
- package/lib/server/forge/core/jobs.js +8 -0
- package/lib/server/forge/core/jobs.js.map +1 -1
- package/lib/server/forge/core/localRepo.d.ts +48 -7
- package/lib/server/forge/core/localRepo.d.ts.map +1 -1
- package/lib/server/forge/core/localRepo.js +123 -69
- package/lib/server/forge/core/localRepo.js.map +1 -1
- package/lib/server/forge/core/prompts.d.ts +20 -0
- package/lib/server/forge/core/prompts.d.ts.map +1 -1
- package/lib/server/forge/core/prompts.js +59 -0
- package/lib/server/forge/core/prompts.js.map +1 -1
- package/lib/server/forge/core/providers/azuredevops.d.ts +4 -2
- package/lib/server/forge/core/providers/azuredevops.d.ts.map +1 -1
- package/lib/server/forge/core/providers/azuredevops.js +12 -2
- package/lib/server/forge/core/providers/azuredevops.js.map +1 -1
- package/lib/server/forge/core/providers/base.d.ts +29 -4
- package/lib/server/forge/core/providers/base.d.ts.map +1 -1
- package/lib/server/forge/core/providers/base.js +21 -3
- package/lib/server/forge/core/providers/base.js.map +1 -1
- package/lib/server/forge/core/providers/github.d.ts +7 -7
- package/lib/server/forge/core/providers/github.d.ts.map +1 -1
- package/lib/server/forge/core/providers/github.js +13 -4
- package/lib/server/forge/core/providers/github.js.map +1 -1
- package/lib/server/forge/core/providers/gitlab.d.ts +20 -3
- package/lib/server/forge/core/providers/gitlab.d.ts.map +1 -1
- package/lib/server/forge/core/providers/gitlab.js +65 -5
- package/lib/server/forge/core/providers/gitlab.js.map +1 -1
- package/lib/server/forge/core/providers/types.d.ts +20 -0
- package/lib/server/forge/core/providers/types.d.ts.map +1 -1
- package/lib/server/forge/core/secretBox.d.ts +17 -0
- package/lib/server/forge/core/secretBox.d.ts.map +1 -0
- package/lib/server/forge/core/secretBox.js +74 -0
- package/lib/server/forge/core/secretBox.js.map +1 -0
- package/lib/server/forge/core/types.d.ts +8 -1
- package/lib/server/forge/core/types.d.ts.map +1 -1
- package/lib/server/forge/core/validator/clone.d.ts +5 -4
- package/lib/server/forge/core/validator/clone.d.ts.map +1 -1
- package/lib/server/forge/core/validator/clone.js +6 -86
- package/lib/server/forge/core/validator/clone.js.map +1 -1
- package/lib/server/forge/core/validator/cmd.d.ts.map +1 -1
- package/lib/server/forge/core/validator/cmd.js +4 -1
- package/lib/server/forge/core/validator/cmd.js.map +1 -1
- package/lib/server/forge/core/validator/projectType.d.ts.map +1 -1
- package/lib/server/forge/core/validator/projectType.js +2 -1
- package/lib/server/forge/core/validator/projectType.js.map +1 -1
- package/lib/server/forge/core/validator/runners/node.d.ts.map +1 -1
- package/lib/server/forge/core/validator/runners/node.js +6 -2
- package/lib/server/forge/core/validator/runners/node.js.map +1 -1
- package/lib/server/forge/core/validator.d.ts.map +1 -1
- package/lib/server/forge/core/validator.js +28 -22
- package/lib/server/forge/core/validator.js.map +1 -1
- package/lib/server/forge/core/workspaces.d.ts +70 -0
- package/lib/server/forge/core/workspaces.d.ts.map +1 -0
- package/lib/server/forge/core/workspaces.js +348 -0
- package/lib/server/forge/core/workspaces.js.map +1 -0
- package/lib/server/forge/db/database.d.ts +22 -0
- package/lib/server/forge/db/database.d.ts.map +1 -0
- package/lib/server/forge/db/database.js +71 -0
- package/lib/server/forge/db/database.js.map +1 -0
- package/lib/server/forge/db/migrations.d.ts +11 -0
- package/lib/server/forge/db/migrations.d.ts.map +1 -0
- package/lib/server/forge/db/migrations.js +87 -0
- package/lib/server/forge/db/migrations.js.map +1 -0
- package/lib/server/forge/routes.d.ts.map +1 -1
- package/lib/server/forge/routes.js +413 -163
- package/lib/server/forge/routes.js.map +1 -1
- package/lib/server/forge/sse.d.ts +10 -0
- package/lib/server/forge/sse.d.ts.map +1 -0
- package/lib/server/forge/sse.js +22 -0
- package/lib/server/forge/sse.js.map +1 -0
- package/lib/server/spa.d.ts +12 -0
- package/lib/server/spa.d.ts.map +1 -0
- package/lib/server/spa.js +23 -0
- package/lib/server/spa.js.map +1 -0
- package/lib/server.js +9 -24
- package/lib/server.js.map +1 -1
- package/lib/shared/events.d.ts +3 -0
- package/lib/shared/events.d.ts.map +1 -1
- package/lib/shared/events.js +3 -0
- package/lib/shared/events.js.map +1 -1
- package/lib/shared/packageRoot.d.ts +11 -0
- package/lib/shared/packageRoot.d.ts.map +1 -0
- package/lib/shared/packageRoot.js +23 -0
- package/lib/shared/packageRoot.js.map +1 -0
- package/lib/shared/project.d.ts +3 -0
- package/lib/shared/project.d.ts.map +1 -0
- package/lib/shared/project.js +3 -0
- package/lib/shared/project.js.map +1 -0
- package/package.json +24 -9
- package/lib/bin/cli/improve.d.ts +0 -2
- package/lib/bin/cli/improve.d.ts.map +0 -1
- package/lib/bin/cli/improve.js +0 -189
- package/lib/bin/cli/improve.js.map +0 -1
- package/lib/bin/cli/stats.d.ts +0 -2
- package/lib/bin/cli/stats.d.ts.map +0 -1
- package/lib/bin/cli/stats.js +0 -78
- package/lib/bin/cli/stats.js.map +0 -1
- package/lib/server/forge/core/k8s.d.ts +0 -18
- package/lib/server/forge/core/k8s.d.ts.map +0 -1
- package/lib/server/forge/core/k8s.js +0 -49
- package/lib/server/forge/core/k8s.js.map +0 -1
- package/lib/server/forge/core/openclawClient.d.ts +0 -61
- package/lib/server/forge/core/openclawClient.d.ts.map +0 -1
- package/lib/server/forge/core/openclawClient.js +0 -111
- package/lib/server/forge/core/openclawClient.js.map +0 -1
- package/lib/server/forge/core/quotaClient.d.ts +0 -48
- package/lib/server/forge/core/quotaClient.d.ts.map +0 -1
- package/lib/server/forge/core/quotaClient.js +0 -88
- package/lib/server/forge/core/quotaClient.js.map +0 -1
- package/lib/server/forge/core/selfImprove.d.ts +0 -43
- package/lib/server/forge/core/selfImprove.d.ts.map +0 -1
- package/lib/server/forge/core/selfImprove.js +0 -372
- package/lib/server/forge/core/selfImprove.js.map +0 -1
- package/lib/server/forge/core/telemetry.d.ts +0 -100
- package/lib/server/forge/core/telemetry.d.ts.map +0 -1
- package/lib/server/forge/core/telemetry.js +0 -273
- package/lib/server/forge/core/telemetry.js.map +0 -1
- package/scripts/fix-shebang.cjs +0 -11
- package/scripts/inject-readme.cjs +0 -23
- 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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"}
|
package/scripts/fix-shebang.cjs
DELETED
|
@@ -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");
|
package/scripts/local-rollout.sh
DELETED
|
@@ -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"
|