@nairon-ai/aegis 0.2.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 (167) hide show
  1. package/.agents/skills/bug-fix/SKILL.md +91 -0
  2. package/.flue/agents/bug-fix.ts +107 -0
  3. package/.flue/app.ts +16 -0
  4. package/Dockerfile +8 -0
  5. package/LICENSE +21 -0
  6. package/README.md +251 -0
  7. package/dist-node/agent/bug-fix-skill.d.ts +2 -0
  8. package/dist-node/agent/bug-fix-skill.d.ts.map +1 -0
  9. package/dist-node/agent/bug-fix-skill.js +64 -0
  10. package/dist-node/agent/bug-fix-skill.js.map +1 -0
  11. package/dist-node/agent/client.d.ts +14 -0
  12. package/dist-node/agent/client.d.ts.map +1 -0
  13. package/dist-node/agent/client.js +110 -0
  14. package/dist-node/agent/client.js.map +1 -0
  15. package/dist-node/cli/commands/deploy.d.ts +3 -0
  16. package/dist-node/cli/commands/deploy.d.ts.map +1 -0
  17. package/dist-node/cli/commands/deploy.js +94 -0
  18. package/dist-node/cli/commands/deploy.js.map +1 -0
  19. package/dist-node/cli/commands/init.d.ts +3 -0
  20. package/dist-node/cli/commands/init.d.ts.map +1 -0
  21. package/dist-node/cli/commands/init.js +115 -0
  22. package/dist-node/cli/commands/init.js.map +1 -0
  23. package/dist-node/cli/commands/pickup.d.ts +11 -0
  24. package/dist-node/cli/commands/pickup.d.ts.map +1 -0
  25. package/dist-node/cli/commands/pickup.js +43 -0
  26. package/dist-node/cli/commands/pickup.js.map +1 -0
  27. package/dist-node/cli/commands/setup.d.ts +3 -0
  28. package/dist-node/cli/commands/setup.d.ts.map +1 -0
  29. package/dist-node/cli/commands/setup.js +163 -0
  30. package/dist-node/cli/commands/setup.js.map +1 -0
  31. package/dist-node/cli/commands/status.d.ts +3 -0
  32. package/dist-node/cli/commands/status.d.ts.map +1 -0
  33. package/dist-node/cli/commands/status.js +26 -0
  34. package/dist-node/cli/commands/status.js.map +1 -0
  35. package/dist-node/cli/index.d.ts +3 -0
  36. package/dist-node/cli/index.d.ts.map +1 -0
  37. package/dist-node/cli/index.js +36 -0
  38. package/dist-node/cli/index.js.map +1 -0
  39. package/dist-node/cli/paths.d.ts +7 -0
  40. package/dist-node/cli/paths.d.ts.map +1 -0
  41. package/dist-node/cli/paths.js +29 -0
  42. package/dist-node/cli/paths.js.map +1 -0
  43. package/dist-node/cli/state.d.ts +16 -0
  44. package/dist-node/cli/state.d.ts.map +1 -0
  45. package/dist-node/cli/state.js +214 -0
  46. package/dist-node/cli/state.js.map +1 -0
  47. package/dist-node/core/pickup.d.ts +14 -0
  48. package/dist-node/core/pickup.d.ts.map +1 -0
  49. package/dist-node/core/pickup.js +42 -0
  50. package/dist-node/core/pickup.js.map +1 -0
  51. package/dist-node/github/index.d.ts +3 -0
  52. package/dist-node/github/index.d.ts.map +1 -0
  53. package/dist-node/github/index.js +2 -0
  54. package/dist-node/github/index.js.map +1 -0
  55. package/dist-node/github/manifest.d.ts +34 -0
  56. package/dist-node/github/manifest.d.ts.map +1 -0
  57. package/dist-node/github/manifest.js +71 -0
  58. package/dist-node/github/manifest.js.map +1 -0
  59. package/dist-node/integrations/github.d.ts +29 -0
  60. package/dist-node/integrations/github.d.ts.map +1 -0
  61. package/dist-node/integrations/github.js +199 -0
  62. package/dist-node/integrations/github.js.map +1 -0
  63. package/dist-node/integrations/linear.d.ts +15 -0
  64. package/dist-node/integrations/linear.d.ts.map +1 -0
  65. package/dist-node/integrations/linear.js +146 -0
  66. package/dist-node/integrations/linear.js.map +1 -0
  67. package/dist-node/integrations/telegram.d.ts +24 -0
  68. package/dist-node/integrations/telegram.d.ts.map +1 -0
  69. package/dist-node/integrations/telegram.js +39 -0
  70. package/dist-node/integrations/telegram.js.map +1 -0
  71. package/dist-node/integrations/webhooks.d.ts +3 -0
  72. package/dist-node/integrations/webhooks.d.ts.map +1 -0
  73. package/dist-node/integrations/webhooks.js +37 -0
  74. package/dist-node/integrations/webhooks.js.map +1 -0
  75. package/dist-node/sandbox/github-token.d.ts +7 -0
  76. package/dist-node/sandbox/github-token.d.ts.map +1 -0
  77. package/dist-node/sandbox/github-token.js +66 -0
  78. package/dist-node/sandbox/github-token.js.map +1 -0
  79. package/dist-node/sandbox/index.d.ts +2 -0
  80. package/dist-node/sandbox/index.d.ts.map +1 -0
  81. package/dist-node/sandbox/index.js +2 -0
  82. package/dist-node/sandbox/index.js.map +1 -0
  83. package/dist-node/server/app.d.ts +9 -0
  84. package/dist-node/server/app.d.ts.map +1 -0
  85. package/dist-node/server/app.js +216 -0
  86. package/dist-node/server/app.js.map +1 -0
  87. package/dist-node/shared/config.d.ts +5 -0
  88. package/dist-node/shared/config.d.ts.map +1 -0
  89. package/dist-node/shared/config.js +135 -0
  90. package/dist-node/shared/config.js.map +1 -0
  91. package/dist-node/shared/constants.d.ts +16 -0
  92. package/dist-node/shared/constants.d.ts.map +1 -0
  93. package/dist-node/shared/constants.js +29 -0
  94. package/dist-node/shared/constants.js.map +1 -0
  95. package/dist-node/shared/format.d.ts +12 -0
  96. package/dist-node/shared/format.d.ts.map +1 -0
  97. package/dist-node/shared/format.js +71 -0
  98. package/dist-node/shared/format.js.map +1 -0
  99. package/dist-node/shared/index.d.ts +7 -0
  100. package/dist-node/shared/index.d.ts.map +1 -0
  101. package/dist-node/shared/index.js +7 -0
  102. package/dist-node/shared/index.js.map +1 -0
  103. package/dist-node/shared/readiness.d.ts +3 -0
  104. package/dist-node/shared/readiness.d.ts.map +1 -0
  105. package/dist-node/shared/readiness.js +91 -0
  106. package/dist-node/shared/readiness.js.map +1 -0
  107. package/dist-node/shared/run-state.d.ts +5 -0
  108. package/dist-node/shared/run-state.d.ts.map +1 -0
  109. package/dist-node/shared/run-state.js +26 -0
  110. package/dist-node/shared/run-state.js.map +1 -0
  111. package/dist-node/shared/types.d.ts +230 -0
  112. package/dist-node/shared/types.d.ts.map +1 -0
  113. package/dist-node/shared/types.js +5 -0
  114. package/dist-node/shared/types.js.map +1 -0
  115. package/dist-node/sources/github.d.ts +15 -0
  116. package/dist-node/sources/github.d.ts.map +1 -0
  117. package/dist-node/sources/github.js +44 -0
  118. package/dist-node/sources/github.js.map +1 -0
  119. package/dist-node/sources/index.d.ts +6 -0
  120. package/dist-node/sources/index.d.ts.map +1 -0
  121. package/dist-node/sources/index.js +16 -0
  122. package/dist-node/sources/index.js.map +1 -0
  123. package/dist-node/sources/linear.d.ts +15 -0
  124. package/dist-node/sources/linear.d.ts.map +1 -0
  125. package/dist-node/sources/linear.js +32 -0
  126. package/dist-node/sources/linear.js.map +1 -0
  127. package/dist-node/sources/types.d.ts +15 -0
  128. package/dist-node/sources/types.d.ts.map +1 -0
  129. package/dist-node/sources/types.js +2 -0
  130. package/dist-node/sources/types.js.map +1 -0
  131. package/docs/RELEASING.md +52 -0
  132. package/docs/SETUP.md +439 -0
  133. package/package.json +64 -0
  134. package/src/agent/bug-fix-skill.ts +63 -0
  135. package/src/agent/client.ts +156 -0
  136. package/src/cli/commands/deploy.ts +106 -0
  137. package/src/cli/commands/init.ts +119 -0
  138. package/src/cli/commands/pickup.ts +44 -0
  139. package/src/cli/commands/setup.ts +217 -0
  140. package/src/cli/commands/status.ts +24 -0
  141. package/src/cli/index.ts +38 -0
  142. package/src/cli/paths.ts +29 -0
  143. package/src/cli/state.ts +228 -0
  144. package/src/core/pickup.ts +66 -0
  145. package/src/github/index.ts +2 -0
  146. package/src/github/manifest.ts +97 -0
  147. package/src/integrations/github.ts +241 -0
  148. package/src/integrations/linear.ts +195 -0
  149. package/src/integrations/telegram.ts +48 -0
  150. package/src/integrations/webhooks.ts +53 -0
  151. package/src/sandbox/github-token.ts +92 -0
  152. package/src/sandbox/index.ts +1 -0
  153. package/src/server/app.ts +292 -0
  154. package/src/shared/config.ts +154 -0
  155. package/src/shared/constants.ts +30 -0
  156. package/src/shared/format.ts +84 -0
  157. package/src/shared/index.ts +6 -0
  158. package/src/shared/readiness.ts +116 -0
  159. package/src/shared/run-state.ts +32 -0
  160. package/src/shared/types.ts +257 -0
  161. package/src/sources/github.ts +57 -0
  162. package/src/sources/index.ts +20 -0
  163. package/src/sources/linear.ts +44 -0
  164. package/src/sources/types.ts +16 -0
  165. package/tsconfig.json +25 -0
  166. package/tsconfig.node.json +16 -0
  167. package/wrangler.jsonc +43 -0
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: bug-fix
3
+ description: Investigate a ready bug ticket, produce a non-technical approval summary, and after approval implement a minimal tested fix.
4
+ ---
5
+
6
+ # Bug Fix
7
+
8
+ You are Aegis, an AFK bug-fixing SRE. You only work on bug tickets. You do not implement features.
9
+
10
+ Read the JSON context file passed in `contextPath`. It contains:
11
+
12
+ - `command`: `plan` or `implement`
13
+ - source ticket title/body/url
14
+ - repo, branch, and context profile
15
+ - optional read-only production context
16
+
17
+ ## Hard Rules
18
+
19
+ - Do not push to `main`.
20
+ - Do not open PRs yourself. Return PR title/body only.
21
+ - Do not use `git add -A` or `git add .`.
22
+ - Do not include secrets in output.
23
+ - If confidence is low, return `blocked` or `needs-info`; do not pretend.
24
+ - Keep the fix minimal. This is bug repair, not refactor time.
25
+ - Run repo-native type checks for changed surfaces when possible.
26
+ - Run the narrowest relevant test suite when possible.
27
+
28
+ ## Human Summary Style
29
+
30
+ `humanSummary` is for Telegram. It must be short, plain English, and skimmable on a phone.
31
+
32
+ Prefer:
33
+
34
+ - what user did
35
+ - what broke
36
+ - why it likely broke at a high level
37
+ - what Aegis wants to change
38
+ - risk
39
+
40
+ Avoid:
41
+
42
+ - file paths
43
+ - function names
44
+ - column names
45
+ - stack internals
46
+ - jargon
47
+
48
+ Use low-level names only when they are the only unambiguous way to explain the problem.
49
+
50
+ ## Plan Command
51
+
52
+ When `command` is `plan`:
53
+
54
+ 1. Read the issue carefully.
55
+ 2. Inspect the codebase and nearest docs.
56
+ 3. If production profile is enabled, use only read-only checks. For a DB, inspect data only. For Vercel logs, use the provided token/project metadata and inspect around the issue timestamp when possible.
57
+ 4. Determine whether there is enough context.
58
+ 5. Return:
59
+ - `awaiting-approval` when likely root cause and fix are clear
60
+ - `needs-info` when one human answer is needed
61
+ - `blocked` when the bug cannot be safely diagnosed
62
+
63
+ Do not edit files during plan.
64
+
65
+ ## Implement Command
66
+
67
+ When `command` is `implement`:
68
+
69
+ 1. Re-read the context and issue.
70
+ 2. Implement the smallest fix that addresses the root cause.
71
+ 3. Add or update regression coverage when practical.
72
+ 4. Run type checks and relevant tests.
73
+ 5. Stage only files you changed with explicit file paths.
74
+ 6. Commit to the current branch.
75
+ 7. Push the current branch to origin.
76
+ 8. Return PR title/body and evidence.
77
+
78
+ If you cannot make a confident fix, return `blocked` or `needs-info` without committing.
79
+
80
+ ## PR Body
81
+
82
+ Include:
83
+
84
+ - summary
85
+ - source ticket link
86
+ - what changed
87
+ - tests run
88
+ - risk
89
+ - note that human review is required
90
+
91
+ Use `Refs`, not `Closes`, unless the context explicitly says otherwise.
@@ -0,0 +1,107 @@
1
+ import { getSandbox } from "@cloudflare/sandbox";
2
+ import type { FlueContext } from "@flue/sdk/client";
3
+ import { cfSandboxToSessionEnv } from "@flue/sdk/cloudflare";
4
+ import * as v from "valibot";
5
+ import { BUG_FIX_SKILL_TEXT } from "../../src/agent/bug-fix-skill.js";
6
+ import {
7
+ AGENT_CONTEXT_PATH,
8
+ BUG_FIX_SKILL,
9
+ SANDBOX_REPO_PATH,
10
+ } from "../../src/shared/constants.js";
11
+ import type { AgentRunContext } from "../../src/shared/types.js";
12
+
13
+ export const triggers = { webhook: true };
14
+
15
+ const PlanSchema = v.object({
16
+ outcome: v.picklist(["awaiting-approval", "needs-info", "blocked"]),
17
+ confidence: v.picklist(["low", "medium", "high"]),
18
+ risk: v.picklist(["low", "medium", "high"]),
19
+ technicalSummary: v.string(),
20
+ humanSummary: v.string(),
21
+ proposedFix: v.string(),
22
+ question: v.optional(v.string()),
23
+ blocker: v.optional(v.string()),
24
+ requiresApproval: v.boolean(),
25
+ });
26
+
27
+ const ImplementationSchema = v.object({
28
+ outcome: v.picklist(["implemented", "blocked", "needs-info"]),
29
+ confidence: v.picklist(["low", "medium", "high"]),
30
+ risk: v.picklist(["low", "medium", "high"]),
31
+ technicalSummary: v.string(),
32
+ humanSummary: v.string(),
33
+ filesChanged: v.array(v.string()),
34
+ testsRun: v.array(v.string()),
35
+ branchName: v.optional(v.string()),
36
+ commitSha: v.optional(v.string()),
37
+ prTitle: v.optional(v.string()),
38
+ prBody: v.optional(v.string()),
39
+ question: v.optional(v.string()),
40
+ blocker: v.optional(v.string()),
41
+ });
42
+
43
+ export default async function ({ init, id, payload, env }: FlueContext) {
44
+ const context = payload as AgentRunContext;
45
+ const sandbox = getSandbox(env.Sandbox, id);
46
+ const sandboxFactory = {
47
+ createSessionEnv: async (options: { cwd?: string }) =>
48
+ cfSandboxToSessionEnv(sandbox, options.cwd),
49
+ };
50
+ const setupHarness = await init({
51
+ name: "setup",
52
+ sandbox: sandboxFactory,
53
+ model: env.AGENT_MODEL ?? "openai/gpt-5.1",
54
+ });
55
+ const setup = await setupHarness.session();
56
+
57
+ await setup.shell(`rm -rf ${SANDBOX_REPO_PATH}`);
58
+ await setup.shell(`git clone ${shellQuote(context.repoCloneUrl)} ${SANDBOX_REPO_PATH}`);
59
+ await setup.shell(`git checkout ${shellQuote(context.baseBranch)}`, { cwd: SANDBOX_REPO_PATH });
60
+ await setup.shell(`git checkout -B ${shellQuote(context.branchName)}`, {
61
+ cwd: SANDBOX_REPO_PATH,
62
+ });
63
+ await setup.shell(`mkdir -p $(dirname ${shellQuote(AGENT_CONTEXT_PATH)})`);
64
+ await setup.shell(
65
+ `cat > ${shellQuote(AGENT_CONTEXT_PATH)} <<'AEGIS_CONTEXT'\n${JSON.stringify(
66
+ context,
67
+ null,
68
+ 2,
69
+ )}\nAEGIS_CONTEXT`,
70
+ );
71
+ const skillPath = `${SANDBOX_REPO_PATH}/.agents/skills/bug-fix/SKILL.md`;
72
+ const skillB64 = btoa(unescape(encodeURIComponent(BUG_FIX_SKILL_TEXT)));
73
+ await setup.shell(`mkdir -p ${shellQuote(`${SANDBOX_REPO_PATH}/.agents/skills/bug-fix`)}`);
74
+ await setup.shell(`echo ${shellQuote(skillB64)} | base64 -d > ${shellQuote(skillPath)}`);
75
+
76
+ const projectHarness = await init({
77
+ name: "project",
78
+ sandbox: sandboxFactory,
79
+ cwd: SANDBOX_REPO_PATH,
80
+ model: env.AGENT_MODEL ?? "openai/gpt-5.1",
81
+ });
82
+ const session = await projectHarness.session();
83
+
84
+ if (context.command === "plan") {
85
+ const { data } = await session.skill(BUG_FIX_SKILL, {
86
+ args: {
87
+ command: "plan",
88
+ contextPath: AGENT_CONTEXT_PATH,
89
+ },
90
+ schema: PlanSchema,
91
+ });
92
+ return data;
93
+ }
94
+
95
+ const { data } = await session.skill(BUG_FIX_SKILL, {
96
+ args: {
97
+ command: "implement",
98
+ contextPath: AGENT_CONTEXT_PATH,
99
+ },
100
+ schema: ImplementationSchema,
101
+ });
102
+ return data;
103
+ }
104
+
105
+ function shellQuote(value: string): string {
106
+ return `'${value.replace(/'/g, "'\\''")}'`;
107
+ }
package/.flue/app.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { flue } from "@flue/sdk/app";
2
+ import { createAegisApp, scheduledPickup } from "../src/server/app.js";
3
+ import type { Bindings } from "../src/shared/types.js";
4
+
5
+ const app = createAegisApp();
6
+ const flueApp = flue();
7
+
8
+ export default {
9
+ fetch(request: Request, env?: Bindings, ctx?: ExecutionContext) {
10
+ if (new URL(request.url).pathname.startsWith("/agents/")) {
11
+ return flueApp.fetch(request, env, ctx);
12
+ }
13
+ return app.fetch(request, env, ctx);
14
+ },
15
+ scheduled: scheduledPickup,
16
+ };
package/Dockerfile ADDED
@@ -0,0 +1,8 @@
1
+ FROM docker.io/cloudflare/sandbox:0.10.1
2
+
3
+ RUN apt-get update && apt-get install -y --no-install-recommends \
4
+ git \
5
+ curl \
6
+ ca-certificates \
7
+ postgresql-client \
8
+ && rm -rf /var/lib/apt/lists/*
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nairon AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,251 @@
1
+ # Aegis
2
+
3
+ Self-hosted AFK bug-fixing agent for GitHub Issues and Linear.
4
+
5
+ Aegis watches bug tickets marked ready to implement, checks whether they have enough context, claims one safely, investigates in a Flue agent running inside Cloudflare Sandbox, posts a human-readable RCA checkpoint, waits for approval, then opens a PR. Human review stays in control.
6
+
7
+ ```text
8
+ GitHub/Linear bug ticket marked ready
9
+ |
10
+ v
11
+ Aegis readiness check
12
+ |
13
+ v
14
+ Flue agent in Cloudflare Sandbox
15
+ |
16
+ v
17
+ RCA checkpoint -> approve from GitHub/Linear or Telegram
18
+ |
19
+ v
20
+ Minimal fix branch -> PR -> stop
21
+ ```
22
+
23
+ ## Start Here
24
+
25
+ If you want to connect Aegis to another repo and monitor its bugs, follow [docs/SETUP.md](docs/SETUP.md).
26
+
27
+ Short version:
28
+
29
+ 1. In your product repo, run `npx @nairon-ai/aegis init`.
30
+ 2. Create a Cloudflare account and use Workers Paid for deployed cloud mode.
31
+ 3. Log in with `npx wrangler login`.
32
+ 4. Create GitHub access for the repo Aegis should fix.
33
+ 5. Run `npx @nairon-ai/aegis setup`.
34
+ 6. Add `bug` and `ready to implement` labels to the monitored repo.
35
+ 7. Run `npx @nairon-ai/aegis pickup --dry-run`.
36
+ 8. Run `npx @nairon-ai/aegis deploy`.
37
+ 9. Add webhooks after deploy.
38
+
39
+ ## Two Repos
40
+
41
+ Aegis is installed from npm/GitHub and configured inside the app repo.
42
+
43
+ - **Aegis package:** this repo, installed through `npx` or as a dev dependency.
44
+ - **Monitored repo:** the product repo Aegis fixes, for example `your-org/your-app`.
45
+ - **Project config:** `.aegis/` in the monitored repo.
46
+
47
+ `MONITORED_REPO=your-org/your-app` is the pointer between them.
48
+
49
+ ## Do I Need Cloudflare?
50
+
51
+ - **Local dry-run:** no Cloudflare required. `npx @nairon-ai/aegis pickup --dry-run` only scans GitHub/Linear and prints decisions.
52
+ - **Real AFK watcher:** yes. Aegis v1 deploys as a Cloudflare Worker and runs coding work in Cloudflare Sandbox/Containers.
53
+ - **Database:** no. Aegis uses GitHub/Linear labels, statuses, comments, and PR branches as its state tracker.
54
+
55
+ Cloudflare Sandbox is currently available on Workers Paid and uses Docker during deploy. See Cloudflare's [Sandbox overview](https://developers.cloudflare.com/sandbox/) and [getting started guide](https://developers.cloudflare.com/sandbox/get-started/).
56
+
57
+ ## What Aegis Does
58
+
59
+ - Watches GitHub Issues and/or Linear issues.
60
+ - Picks up bugs only.
61
+ - Requires a ready signal plus a readiness check.
62
+ - Uses Flue as the programmable agent harness.
63
+ - Runs code work in Cloudflare Sandbox.
64
+ - Uses GitHub/Linear as the tracker and durable state.
65
+ - Optionally sends Telegram approval summaries.
66
+ - Optionally gives the agent read-only DB access and Vercel logs.
67
+ - Opens PRs, then stops. No auto-merge.
68
+
69
+ ## What Aegis Does Not Do
70
+
71
+ - It does not host customer code or secrets for you.
72
+ - It does not require a database.
73
+ - It does not implement features in v1.
74
+ - It does not write to production systems by default.
75
+ - It does not self-heal PR review comments yet.
76
+ - It does not require Sentry. Error providers should be linked or pasted into the issue.
77
+
78
+ ## Requirements
79
+
80
+ - Bun
81
+ - Docker running locally for Cloudflare Sandbox image deploy
82
+ - Cloudflare account and Workers Paid for deployed mode
83
+ - GitHub App or GitHub token with Contents, Issues, and Pull Requests read/write access
84
+ - OpenAI API key or another Flue-supported model provider key
85
+ - Optional: Linear API key
86
+ - Optional: Telegram bot
87
+ - Optional: read-only production database URL
88
+ - Optional: Vercel API token/project ID for logs
89
+
90
+ ## Quick Start
91
+
92
+ ```bash
93
+ cd your-product-repo
94
+ npx @nairon-ai/aegis init
95
+ npx @nairon-ai/aegis setup
96
+ ```
97
+
98
+ Create a bug in the monitored repo with:
99
+
100
+ - label: `bug`
101
+ - label: `ready to implement`
102
+ - enough context: what happened, what should have happened, where it happened, and an error/log excerpt if available
103
+
104
+ Then run:
105
+
106
+ ```bash
107
+ npx @nairon-ai/aegis pickup --dry-run
108
+ ```
109
+
110
+ If that finds the issue, deploy:
111
+
112
+ ```bash
113
+ npx wrangler login
114
+ npx @nairon-ai/aegis deploy
115
+ ```
116
+
117
+ Then configure webhooks using the Worker URL printed by deploy. Full details: [docs/SETUP.md](docs/SETUP.md).
118
+
119
+ ## How Pickup Works
120
+
121
+ Aegis scans every 10 minutes and also reacts to GitHub/Linear webhooks.
122
+
123
+ Manual cloud trigger:
124
+
125
+ ```bash
126
+ curl -X POST https://YOUR_WORKER.workers.dev/api/pickup
127
+ ```
128
+
129
+ For each ticket:
130
+
131
+ 1. Must be labeled/statused ready.
132
+ 2. Must be a bug.
133
+ 3. Must have enough context.
134
+ 4. Must not already have an active Aegis run.
135
+ 5. Aegis claims it.
136
+ 6. Aegis starts a Flue planning run.
137
+
138
+ If context is too thin, Aegis comments with one concrete question and does not burn a sandbox run.
139
+
140
+ ## Approval Flow
141
+
142
+ Aegis posts the full RCA to GitHub/Linear.
143
+
144
+ Telegram gets a short non-technical summary:
145
+
146
+ ```text
147
+ Aegis found a likely fix
148
+
149
+ Bug: Users see an error after clicking Checkout
150
+
151
+ Why: The app expects a related record to exist, but sometimes it is missing.
152
+
153
+ Fix: Add a safe check and a regression test.
154
+ Risk: Low
155
+
156
+ Approve: /aegis proceed <run-id>
157
+ Stop: /aegis stop <run-id>
158
+ ```
159
+
160
+ Approve from GitHub/Linear or Telegram:
161
+
162
+ ```text
163
+ /aegis proceed <run-id>
164
+ ```
165
+
166
+ Cancel:
167
+
168
+ ```text
169
+ /aegis stop <run-id>
170
+ ```
171
+
172
+ Ask a follow-up or add context:
173
+
174
+ ```text
175
+ /aegis ask <run-id> <question or extra detail>
176
+ ```
177
+
178
+ Aegis reruns the planning checkpoint with that extra context.
179
+
180
+ ## Production Context
181
+
182
+ Minimal mode uses only:
183
+
184
+ - issue text
185
+ - repo code
186
+
187
+ Production mode can add:
188
+
189
+ - read-only `DATABASE_URL`
190
+ - Vercel logs around the issue time
191
+
192
+ Use read-only production access. Do not give Aegis write access unless you have a tighter policy layer.
193
+
194
+ ## Commands
195
+
196
+ ```bash
197
+ npx @nairon-ai/aegis init
198
+ npx @nairon-ai/aegis setup
199
+ npx @nairon-ai/aegis pickup --dry-run
200
+ npx @nairon-ai/aegis status
201
+ npx @nairon-ai/aegis deploy
202
+ ```
203
+
204
+ ## Releases
205
+
206
+ Aegis uses semantic-release. Push conventional commits to `main`:
207
+
208
+ - `fix:` -> patch npm release
209
+ - `feat:` -> minor npm release
210
+ - `feat!:` or `BREAKING CHANGE:` -> major npm release
211
+
212
+ See [docs/RELEASING.md](docs/RELEASING.md).
213
+
214
+ Worker endpoints:
215
+
216
+ ```text
217
+ GET /
218
+ GET /api/pickup
219
+ POST /api/pickup
220
+ POST /api/runs/:id/proceed
221
+ POST /api/runs/:id/stop
222
+ POST /webhook/github
223
+ POST /webhook/linear
224
+ POST /webhook/telegram
225
+ POST /agents/bug-fix/:runId
226
+ ```
227
+
228
+ ## Architecture
229
+
230
+ ```text
231
+ .flue/app.ts Worker app wrapper + Flue route
232
+ .flue/agents/bug-fix.ts Flue coding agent
233
+ .agents/skills/bug-fix Agent instructions
234
+ src/server/app.ts Hono routes, cron, webhooks
235
+ src/core/pickup.ts scan/claim orchestration
236
+ src/sources/* GitHub + Linear source adapters
237
+ src/integrations/* GitHub, Linear, Telegram, webhook helpers
238
+ src/shared/* config, types, readiness, formatting
239
+ ```
240
+
241
+ ## Current Limits
242
+
243
+ - Bugs only.
244
+ - PR self-heal is not implemented.
245
+ - WhatsApp is not implemented.
246
+ - Arbitrary third-party tool connectors are not implemented.
247
+ - Cloudflare Sandbox is the primary runtime; freestyle.sh support was removed.
248
+
249
+ ## License
250
+
251
+ MIT
@@ -0,0 +1,2 @@
1
+ export declare const BUG_FIX_SKILL_TEXT = "---\nname: bug-fix\ndescription: Investigate a ready bug ticket, produce a non-technical approval summary, and after approval implement a minimal tested fix.\n---\n\n# Bug Fix\n\nYou are Aegis, an AFK bug-fixing SRE. You only work on bug tickets. You do not implement features.\n\nRead the JSON context file passed in contextPath. It contains the command, source ticket, repo, branch, and optional production context.\n\n## Hard Rules\n\n- Do not push to main.\n- Do not open PRs yourself. Return PR title/body only.\n- Do not use git add -A or git add .\n- Do not include secrets in output.\n- If confidence is low, return blocked or needs-info.\n- Keep the fix minimal.\n- Run repo-native type checks for changed surfaces when possible.\n- Run the narrowest relevant test suite when possible.\n\n## Human Summary Style\n\nhumanSummary is for Telegram. Keep it short, plain English, and skimmable on a phone.\n\nPrefer: what user did, what broke, why it likely broke at a high level, what Aegis wants to change, risk.\n\nAvoid: file paths, function names, column names, stack internals, and jargon unless unavoidable.\n\n## Plan Command\n\nWhen command is plan:\n\n1. Read the issue carefully.\n2. Inspect the codebase and nearest docs.\n3. If production profile is enabled, use only read-only checks.\n4. Determine whether there is enough context.\n5. Return awaiting-approval, needs-info, or blocked.\n\nDo not edit files during plan.\n\n## Implement Command\n\nWhen command is implement:\n\n1. Re-read the context and issue.\n2. Implement the smallest fix that addresses the root cause.\n3. Add or update regression coverage when practical.\n4. Run type checks and relevant tests.\n5. Stage only files you changed with explicit file paths.\n6. Commit to the current branch.\n7. Push the current branch to origin.\n8. Return PR title/body and evidence.\n\nIf you cannot make a confident fix, return blocked or needs-info without committing.\n\n## PR Body\n\nInclude summary, source ticket link, what changed, tests run, risk, and note that human review is required.\n\nUse Refs, not Closes, unless the context explicitly says otherwise.\n";
2
+ //# sourceMappingURL=bug-fix-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bug-fix-skill.d.ts","sourceRoot":"","sources":["../../src/agent/bug-fix-skill.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,kmEA8D9B,CAAC"}
@@ -0,0 +1,64 @@
1
+ export const BUG_FIX_SKILL_TEXT = `---
2
+ name: bug-fix
3
+ description: Investigate a ready bug ticket, produce a non-technical approval summary, and after approval implement a minimal tested fix.
4
+ ---
5
+
6
+ # Bug Fix
7
+
8
+ You are Aegis, an AFK bug-fixing SRE. You only work on bug tickets. You do not implement features.
9
+
10
+ Read the JSON context file passed in contextPath. It contains the command, source ticket, repo, branch, and optional production context.
11
+
12
+ ## Hard Rules
13
+
14
+ - Do not push to main.
15
+ - Do not open PRs yourself. Return PR title/body only.
16
+ - Do not use git add -A or git add .
17
+ - Do not include secrets in output.
18
+ - If confidence is low, return blocked or needs-info.
19
+ - Keep the fix minimal.
20
+ - Run repo-native type checks for changed surfaces when possible.
21
+ - Run the narrowest relevant test suite when possible.
22
+
23
+ ## Human Summary Style
24
+
25
+ humanSummary is for Telegram. Keep it short, plain English, and skimmable on a phone.
26
+
27
+ Prefer: what user did, what broke, why it likely broke at a high level, what Aegis wants to change, risk.
28
+
29
+ Avoid: file paths, function names, column names, stack internals, and jargon unless unavoidable.
30
+
31
+ ## Plan Command
32
+
33
+ When command is plan:
34
+
35
+ 1. Read the issue carefully.
36
+ 2. Inspect the codebase and nearest docs.
37
+ 3. If production profile is enabled, use only read-only checks.
38
+ 4. Determine whether there is enough context.
39
+ 5. Return awaiting-approval, needs-info, or blocked.
40
+
41
+ Do not edit files during plan.
42
+
43
+ ## Implement Command
44
+
45
+ When command is implement:
46
+
47
+ 1. Re-read the context and issue.
48
+ 2. Implement the smallest fix that addresses the root cause.
49
+ 3. Add or update regression coverage when practical.
50
+ 4. Run type checks and relevant tests.
51
+ 5. Stage only files you changed with explicit file paths.
52
+ 6. Commit to the current branch.
53
+ 7. Push the current branch to origin.
54
+ 8. Return PR title/body and evidence.
55
+
56
+ If you cannot make a confident fix, return blocked or needs-info without committing.
57
+
58
+ ## PR Body
59
+
60
+ Include summary, source ticket link, what changed, tests run, risk, and note that human review is required.
61
+
62
+ Use Refs, not Closes, unless the context explicitly says otherwise.
63
+ `;
64
+ //# sourceMappingURL=bug-fix-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bug-fix-skill.js","sourceRoot":"","sources":["../../src/agent/bug-fix-skill.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8DjC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { AegisConfig, ReadinessDecision, WorkItem, WorkRun } from "../shared/types.js";
2
+ export declare function startPlanRun(params: {
3
+ config: AegisConfig;
4
+ item: WorkItem;
5
+ run: WorkRun;
6
+ decision: ReadinessDecision;
7
+ }): Promise<void>;
8
+ export declare function startImplementationRun(params: {
9
+ config: AegisConfig;
10
+ item: WorkItem;
11
+ run: WorkRun;
12
+ approvedBy: string;
13
+ }): Promise<void>;
14
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/agent/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,WAAW,EAIX,iBAAiB,EACjB,QAAQ,EACR,OAAO,EACP,MAAM,oBAAoB,CAAC;AAG5B,wBAAsB,YAAY,CAAC,MAAM,EAAE;IAC1C,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,iBAAiB,CAAC;CAC5B,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhB;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACpD,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkChB"}