@xn-intenton-z2a/agentic-lib 7.1.25 → 7.1.27
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/README.md +62 -16
- package/package.json +1 -1
- package/src/actions/agentic-step/action.yml +1 -1
- package/src/actions/agentic-step/index.js +2 -0
- package/src/actions/agentic-step/tasks/supervise.js +285 -0
- package/src/agents/agent-supervisor.md +30 -0
- package/src/seeds/init.yml +15 -0
- package/src/seeds/zero-README.md +71 -5
- package/src/seeds/zero-package.json +1 -1
- package/src/workflows/agent-flow-transform.yml +1 -1
package/README.md
CHANGED
|
@@ -23,16 +23,20 @@ Or start from the [repository0 template](https://github.com/xn-intenton-z2a/repo
|
|
|
23
23
|
MISSION.md Your project goals in plain English
|
|
24
24
|
|
|
|
25
25
|
v
|
|
26
|
-
[
|
|
26
|
+
[supervisor] LLM gathers repo state, picks actions
|
|
27
27
|
|
|
|
28
|
-
|
|
28
|
+
+-----+-----+-----+-----+
|
|
29
|
+
v v v v v
|
|
30
|
+
transform maintain review fix discussions
|
|
31
|
+
| | | | |
|
|
32
|
+
v v v v v
|
|
29
33
|
Issue -> Code -> Test -> PR -> Merge -> Next Issue
|
|
30
34
|
^ |
|
|
31
35
|
+---------------------------------------+
|
|
32
36
|
Autonomous cycle
|
|
33
37
|
```
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
An LLM supervisor runs on a configurable schedule, gathers full repository context (open issues, PRs, workflow runs, features, activity), and strategically dispatches other workflows. Each workflow uses the `agentic-step` action to call the Copilot SDK with context from your repository and produce targeted changes. Users can interact with the system through a GitHub Discussions bot, which relays requests to the supervisor.
|
|
36
40
|
|
|
37
41
|
## Initialisation
|
|
38
42
|
|
|
@@ -69,10 +73,10 @@ your-repo/
|
|
|
69
73
|
│ │
|
|
70
74
|
│ └── agentic-lib/ # [INIT] Internal infrastructure (always overwritten)
|
|
71
75
|
│ ├── actions/
|
|
72
|
-
│ │ ├── agentic-step/ # The Copilot SDK action (
|
|
76
|
+
│ │ ├── agentic-step/ # The Copilot SDK action (9 task handlers)
|
|
73
77
|
│ │ ├── commit-if-changed/ # Composite: conditional git commit
|
|
74
78
|
│ │ └── setup-npmrc/ # Composite: npm registry auth
|
|
75
|
-
│ ├── agents/ #
|
|
79
|
+
│ ├── agents/ # 8 prompt files + config YAML
|
|
76
80
|
│ ├── seeds/ # Seed files for reset
|
|
77
81
|
│ └── scripts/ # Utility scripts
|
|
78
82
|
│
|
|
@@ -104,13 +108,48 @@ The `init.yml` workflow is distributed from seeds (like `test.yml`) and runs `np
|
|
|
104
108
|
|
|
105
109
|
### GitHub Repository Settings
|
|
106
110
|
|
|
107
|
-
After `init`, configure
|
|
111
|
+
After `init`, configure your GitHub repository with the following tokens, permissions, and settings.
|
|
112
|
+
|
|
113
|
+
#### Required Secrets
|
|
114
|
+
|
|
115
|
+
| Secret | Type | Permissions | Purpose |
|
|
116
|
+
|--------|------|-------------|---------|
|
|
117
|
+
| `COPILOT_GITHUB_TOKEN` | Fine-grained PAT | **Copilot** (read) | Authenticates with the GitHub Copilot SDK for all agentic tasks |
|
|
118
|
+
| `WORKFLOW_TOKEN` | Classic PAT | **workflow** scope | Required by `init.yml` to push workflow file changes (GITHUB_TOKEN cannot modify `.github/workflows/`) |
|
|
119
|
+
|
|
120
|
+
**Creating `COPILOT_GITHUB_TOKEN`:**
|
|
121
|
+
1. Go to [github.com/settings/tokens](https://github.com/settings/tokens) → Fine-grained tokens → Generate new token
|
|
122
|
+
2. Set repository access to your target repo (or all repos)
|
|
123
|
+
3. Under "Account permissions", enable **GitHub Copilot** → Read
|
|
124
|
+
4. Copy the token and add it as a repository secret: Settings → Secrets and variables → Actions → New repository secret
|
|
125
|
+
|
|
126
|
+
**Creating `WORKFLOW_TOKEN`:**
|
|
127
|
+
1. Go to [github.com/settings/tokens](https://github.com/settings/tokens) → Tokens (classic) → Generate new token
|
|
128
|
+
2. Select the **workflow** scope (this includes repo access)
|
|
129
|
+
3. Set expiration (max 90 days for enterprise orgs)
|
|
130
|
+
4. Copy the token and add it as a repository secret
|
|
131
|
+
|
|
132
|
+
#### Repository Settings
|
|
133
|
+
|
|
134
|
+
| Setting | Where | Value | Purpose |
|
|
135
|
+
|---------|-------|-------|---------|
|
|
136
|
+
| GitHub Actions | Settings → Actions → General | Allow all actions | Workflows must be able to run |
|
|
137
|
+
| Workflow permissions | Settings → Actions → General | Read and write | Workflows need to create branches, PRs, and push commits |
|
|
138
|
+
| Allow GitHub Actions to create PRs | Settings → Actions → General | Checked | Required for automerge and init workflows |
|
|
139
|
+
| GitHub Discussions | Settings → General → Features | Enabled | Required for the discussions bot |
|
|
140
|
+
| Branch protection (optional) | Settings → Branches | Require PR reviews | Recommended: prevents direct pushes, ensures review |
|
|
141
|
+
|
|
142
|
+
#### Permissions Summary
|
|
143
|
+
|
|
144
|
+
The workflows use `permissions: write-all` in the workflow files. The key permissions used are:
|
|
108
145
|
|
|
109
|
-
|
|
|
110
|
-
|
|
111
|
-
| `
|
|
112
|
-
|
|
|
113
|
-
|
|
|
146
|
+
| Permission | Used by | Purpose |
|
|
147
|
+
|------------|---------|---------|
|
|
148
|
+
| `contents: write` | All agent workflows | Create branches, push commits |
|
|
149
|
+
| `pull-requests: write` | Transform, fix-code | Create and update PRs |
|
|
150
|
+
| `issues: write` | Review, enhance, supervisor | Create, label, close issues |
|
|
151
|
+
| `actions: write` | Supervisor | Dispatch other workflows |
|
|
152
|
+
| `discussions: write` | Discussions bot | Post replies to discussions |
|
|
114
153
|
|
|
115
154
|
## Configuration
|
|
116
155
|
|
|
@@ -118,16 +157,20 @@ Configuration lives in `agentic-lib.toml` at your project root:
|
|
|
118
157
|
|
|
119
158
|
```toml
|
|
120
159
|
[schedule]
|
|
121
|
-
tier = "schedule-1"
|
|
160
|
+
tier = "schedule-1" # schedule-1 through schedule-4
|
|
161
|
+
supervisor = "daily" # off | weekly | daily | hourly | continuous
|
|
122
162
|
|
|
123
163
|
[paths]
|
|
124
164
|
mission = "MISSION.md"
|
|
125
165
|
source = "src/lib/"
|
|
126
166
|
tests = "tests/unit/"
|
|
127
167
|
features = "features/"
|
|
168
|
+
library = "library/"
|
|
128
169
|
docs = "docs/"
|
|
129
170
|
readme = "README.md"
|
|
130
171
|
dependencies = "package.json"
|
|
172
|
+
contributing = "CONTRIBUTING.md"
|
|
173
|
+
library-sources = "SOURCES.md"
|
|
131
174
|
|
|
132
175
|
[execution]
|
|
133
176
|
build = "npm run build"
|
|
@@ -139,6 +182,8 @@ feature-issues = 2
|
|
|
139
182
|
maintenance-issues = 1
|
|
140
183
|
attempts-per-branch = 3
|
|
141
184
|
attempts-per-issue = 2
|
|
185
|
+
features-limit = 4
|
|
186
|
+
library-limit = 32
|
|
142
187
|
|
|
143
188
|
[bot]
|
|
144
189
|
log-file = "intentïon.md"
|
|
@@ -152,6 +197,7 @@ The core of the system is a single GitHub Action that handles all autonomous tas
|
|
|
152
197
|
|
|
153
198
|
| Task | Purpose |
|
|
154
199
|
|------|---------|
|
|
200
|
+
| `supervise` | Gather repo context, choose and dispatch actions strategically |
|
|
155
201
|
| `transform` | Transform the codebase toward the mission |
|
|
156
202
|
| `resolve-issue` | Read an issue and generate code to resolve it |
|
|
157
203
|
| `fix-code` | Fix failing tests or lint errors |
|
|
@@ -161,7 +207,7 @@ The core of the system is a single GitHub Action that handles all autonomous tas
|
|
|
161
207
|
| `review-issue` | Review and close resolved issues |
|
|
162
208
|
| `discussions` | Respond to GitHub Discussions |
|
|
163
209
|
|
|
164
|
-
Each task calls the GitHub Copilot SDK with context assembled from your repository (mission, code, tests, features) and writes changes back to the working tree.
|
|
210
|
+
Each task calls the GitHub Copilot SDK with context assembled from your repository (mission, code, tests, features) and writes changes back to the working tree. The supervisor can dispatch any of the other tasks via workflow dispatch.
|
|
165
211
|
|
|
166
212
|
## CLI Task Commands
|
|
167
213
|
|
|
@@ -277,16 +323,16 @@ This repository is the source for the `@xn-intenton-z2a/agentic-lib` npm package
|
|
|
277
323
|
|
|
278
324
|
```
|
|
279
325
|
src/
|
|
280
|
-
├── workflows/
|
|
326
|
+
├── workflows/ 8 GitHub Actions workflow templates
|
|
281
327
|
├── actions/ 3 composite/SDK actions (agentic-step, commit-if-changed, setup-npmrc)
|
|
282
|
-
├── agents/
|
|
328
|
+
├── agents/ 8 agent prompt files + 1 config
|
|
283
329
|
├── seeds/ 7 seed files (test.yml + 6 project seed files for --purge reset)
|
|
284
330
|
└── scripts/ 7 utility scripts distributed to consumers
|
|
285
331
|
```
|
|
286
332
|
|
|
287
333
|
### Testing
|
|
288
334
|
|
|
289
|
-
|
|
335
|
+
269 unit tests across 22 test files, plus system tests:
|
|
290
336
|
|
|
291
337
|
```bash
|
|
292
338
|
npm test # Run all tests (vitest)
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@ inputs:
|
|
|
13
13
|
task:
|
|
14
14
|
description: >
|
|
15
15
|
The task to perform. One of: resolve-issue, fix-code, transform, maintain-features,
|
|
16
|
-
maintain-library, enhance-issue, review-issue, discussions
|
|
16
|
+
maintain-library, enhance-issue, review-issue, discussions, supervise
|
|
17
17
|
required: true
|
|
18
18
|
config:
|
|
19
19
|
description: "Path to agentic-lib.yml configuration file"
|
|
@@ -20,6 +20,7 @@ import { maintainLibrary } from "./tasks/maintain-library.js";
|
|
|
20
20
|
import { enhanceIssue } from "./tasks/enhance-issue.js";
|
|
21
21
|
import { reviewIssue } from "./tasks/review-issue.js";
|
|
22
22
|
import { discussions } from "./tasks/discussions.js";
|
|
23
|
+
import { supervise } from "./tasks/supervise.js";
|
|
23
24
|
|
|
24
25
|
const TASKS = {
|
|
25
26
|
"resolve-issue": resolveIssue,
|
|
@@ -30,6 +31,7 @@ const TASKS = {
|
|
|
30
31
|
"enhance-issue": enhanceIssue,
|
|
31
32
|
"review-issue": reviewIssue,
|
|
32
33
|
"discussions": discussions,
|
|
34
|
+
"supervise": supervise,
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
async function run() {
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Copyright (C) 2025-2026 Polycode Limited
|
|
3
|
+
// tasks/supervise.js — Supervisor orchestration via LLM
|
|
4
|
+
//
|
|
5
|
+
// Gathers repository context (issues, PRs, workflows, features, library, activity),
|
|
6
|
+
// asks the Copilot SDK to choose multiple concurrent actions, then dispatches them.
|
|
7
|
+
|
|
8
|
+
import * as core from "@actions/core";
|
|
9
|
+
import { existsSync } from "fs";
|
|
10
|
+
import { runCopilotTask, readOptionalFile, scanDirectory } from "../copilot.js";
|
|
11
|
+
|
|
12
|
+
async function gatherContext(octokit, repo, config) {
|
|
13
|
+
const mission = readOptionalFile(config.paths.mission.path);
|
|
14
|
+
const recentActivity = readOptionalFile(config.intentionBot.intentionFilepath).split("\n").slice(-20).join("\n");
|
|
15
|
+
|
|
16
|
+
const featuresPath = config.paths.features.path;
|
|
17
|
+
const featureNames = existsSync(featuresPath)
|
|
18
|
+
? scanDirectory(featuresPath, ".md").map((f) => f.name.replace(".md", ""))
|
|
19
|
+
: [];
|
|
20
|
+
const featuresLimit = config.paths.features.limit || 4;
|
|
21
|
+
|
|
22
|
+
const libraryPath = config.paths.library?.path || "library/";
|
|
23
|
+
const libraryNames = existsSync(libraryPath)
|
|
24
|
+
? scanDirectory(libraryPath, ".md").map((f) => f.name.replace(".md", ""))
|
|
25
|
+
: [];
|
|
26
|
+
const libraryLimit = config.paths.library?.limit || 32;
|
|
27
|
+
|
|
28
|
+
const { data: openIssues } = await octokit.rest.issues.listForRepo({
|
|
29
|
+
...repo,
|
|
30
|
+
state: "open",
|
|
31
|
+
per_page: 20,
|
|
32
|
+
sort: "updated",
|
|
33
|
+
direction: "desc",
|
|
34
|
+
});
|
|
35
|
+
const issuesSummary = openIssues
|
|
36
|
+
.filter((i) => !i.pull_request)
|
|
37
|
+
.map((i) => {
|
|
38
|
+
const age = Math.floor((Date.now() - new Date(i.created_at).getTime()) / 86400000);
|
|
39
|
+
const labels = i.labels.map((l) => l.name).join(", ");
|
|
40
|
+
return `#${i.number}: ${i.title} [${labels || "no labels"}] (${age}d old)`;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const { data: openPRs } = await octokit.rest.pulls.list({
|
|
44
|
+
...repo,
|
|
45
|
+
state: "open",
|
|
46
|
+
per_page: 10,
|
|
47
|
+
sort: "updated",
|
|
48
|
+
direction: "desc",
|
|
49
|
+
});
|
|
50
|
+
const prsSummary = openPRs.map((pr) => {
|
|
51
|
+
const age = Math.floor((Date.now() - new Date(pr.created_at).getTime()) / 86400000);
|
|
52
|
+
const labels = pr.labels.map((l) => l.name).join(", ");
|
|
53
|
+
return `#${pr.number}: ${pr.title} (${pr.head.ref}) [${labels || "no labels"}] (${age}d old)`;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
let workflowsSummary = [];
|
|
57
|
+
try {
|
|
58
|
+
const { data: runs } = await octokit.rest.actions.listWorkflowRunsForRepo({
|
|
59
|
+
...repo,
|
|
60
|
+
per_page: 10,
|
|
61
|
+
});
|
|
62
|
+
workflowsSummary = runs.workflow_runs.map((r) => `${r.name}: ${r.conclusion || r.status} (${r.created_at})`);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
core.warning(`Could not fetch workflow runs: ${err.message}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
mission,
|
|
69
|
+
recentActivity,
|
|
70
|
+
featureNames,
|
|
71
|
+
featuresLimit,
|
|
72
|
+
libraryNames,
|
|
73
|
+
libraryLimit,
|
|
74
|
+
issuesSummary,
|
|
75
|
+
prsSummary,
|
|
76
|
+
workflowsSummary,
|
|
77
|
+
schedule: config.schedule,
|
|
78
|
+
supervisor: config.supervisor,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function buildPrompt(ctx, agentInstructions) {
|
|
83
|
+
return [
|
|
84
|
+
"## Instructions",
|
|
85
|
+
agentInstructions,
|
|
86
|
+
"",
|
|
87
|
+
"## Mission",
|
|
88
|
+
ctx.mission || "(no mission defined)",
|
|
89
|
+
"",
|
|
90
|
+
"## Repository State",
|
|
91
|
+
`### Open Issues (${ctx.issuesSummary.length})`,
|
|
92
|
+
ctx.issuesSummary.join("\n") || "none",
|
|
93
|
+
"",
|
|
94
|
+
`### Open PRs (${ctx.prsSummary.length})`,
|
|
95
|
+
ctx.prsSummary.join("\n") || "none",
|
|
96
|
+
"",
|
|
97
|
+
`### Features (${ctx.featureNames.length}/${ctx.featuresLimit})`,
|
|
98
|
+
ctx.featureNames.join(", ") || "none",
|
|
99
|
+
"",
|
|
100
|
+
`### Library Docs (${ctx.libraryNames.length}/${ctx.libraryLimit})`,
|
|
101
|
+
ctx.libraryNames.join(", ") || "none",
|
|
102
|
+
"",
|
|
103
|
+
`### Recent Workflow Runs`,
|
|
104
|
+
ctx.workflowsSummary.join("\n") || "none",
|
|
105
|
+
"",
|
|
106
|
+
`### Recent Activity`,
|
|
107
|
+
ctx.recentActivity || "none",
|
|
108
|
+
"",
|
|
109
|
+
`### Schedule: ${ctx.schedule}, Supervisor: ${ctx.supervisor}`,
|
|
110
|
+
"",
|
|
111
|
+
"## Available Actions",
|
|
112
|
+
"Pick one or more actions. Output them in the format below.",
|
|
113
|
+
"",
|
|
114
|
+
"### Workflow Dispatches",
|
|
115
|
+
"- `dispatch:agent-flow-transform` — Pick up next issue, generate code, open PR",
|
|
116
|
+
"- `dispatch:agent-flow-maintain` — Refresh feature definitions and library docs",
|
|
117
|
+
"- `dispatch:agent-flow-review` — Close resolved issues, enhance issue criteria",
|
|
118
|
+
"- `dispatch:agent-flow-fix-code | pr-number: <N>` — Fix a failing PR",
|
|
119
|
+
"- `dispatch:agent-discussions-bot` — Proactively post in discussions",
|
|
120
|
+
"",
|
|
121
|
+
"### GitHub API Actions",
|
|
122
|
+
"- `github:create-issue | title: <text> | labels: <comma-separated>` — Create a new issue",
|
|
123
|
+
"- `github:label-issue | issue-number: <N> | labels: <comma-separated>` — Add labels to an issue",
|
|
124
|
+
"- `github:close-issue | issue-number: <N>` — Close an issue",
|
|
125
|
+
"",
|
|
126
|
+
"### Communication",
|
|
127
|
+
"- `respond:discussions | message: <text> | discussion-url: <url>` — Reply via discussions bot",
|
|
128
|
+
"- `nop` — No action needed this cycle",
|
|
129
|
+
"",
|
|
130
|
+
"## Output Format",
|
|
131
|
+
"Respond with EXACTLY this structure:",
|
|
132
|
+
"```",
|
|
133
|
+
"[ACTIONS]",
|
|
134
|
+
"action-name | param: value | param: value",
|
|
135
|
+
"[/ACTIONS]",
|
|
136
|
+
"[REASONING]",
|
|
137
|
+
"Why you chose these actions...",
|
|
138
|
+
"[/REASONING]",
|
|
139
|
+
"```",
|
|
140
|
+
].join("\n");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function parseActions(content) {
|
|
144
|
+
const actionsMatch = content.match(/\[ACTIONS\]([\s\S]*?)\[\/ACTIONS\]/);
|
|
145
|
+
if (!actionsMatch) return [];
|
|
146
|
+
|
|
147
|
+
return actionsMatch[1]
|
|
148
|
+
.split("\n")
|
|
149
|
+
.map((line) => line.trim())
|
|
150
|
+
.filter((line) => line && !line.startsWith("#"))
|
|
151
|
+
.map((line) => {
|
|
152
|
+
const parts = line.split("|").map((p) => p.trim());
|
|
153
|
+
const action = parts[0];
|
|
154
|
+
const params = {};
|
|
155
|
+
for (const part of parts.slice(1)) {
|
|
156
|
+
const colonIdx = part.indexOf(":");
|
|
157
|
+
if (colonIdx > 0) {
|
|
158
|
+
params[part.substring(0, colonIdx).trim()] = part.substring(colonIdx + 1).trim();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return { action, params };
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function parseReasoning(content) {
|
|
166
|
+
const match = content.match(/\[REASONING\]([\s\S]*?)\[\/REASONING\]/);
|
|
167
|
+
return match ? match[1].trim() : "";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async function executeDispatch(octokit, repo, actionName, params) {
|
|
171
|
+
const workflowFile = actionName.replace("dispatch:", "") + ".yml";
|
|
172
|
+
const inputs = {};
|
|
173
|
+
if (params["pr-number"]) inputs["pr-number"] = params["pr-number"];
|
|
174
|
+
core.info(`Dispatching workflow: ${workflowFile}`);
|
|
175
|
+
await octokit.rest.actions.createWorkflowDispatch({ ...repo, workflow_id: workflowFile, ref: "main", inputs });
|
|
176
|
+
return `dispatched:${workflowFile}`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function executeCreateIssue(octokit, repo, params) {
|
|
180
|
+
const title = params.title || "Untitled issue";
|
|
181
|
+
const labels = params.labels ? params.labels.split(",").map((l) => l.trim()) : ["automated"];
|
|
182
|
+
core.info(`Creating issue: ${title}`);
|
|
183
|
+
const { data: issue } = await octokit.rest.issues.create({ ...repo, title, labels });
|
|
184
|
+
return `created-issue:#${issue.number}`;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function executeLabelIssue(octokit, repo, params) {
|
|
188
|
+
const issueNumber = Number(params["issue-number"]);
|
|
189
|
+
const labels = params.labels ? params.labels.split(",").map((l) => l.trim()) : [];
|
|
190
|
+
if (issueNumber && labels.length > 0) {
|
|
191
|
+
core.info(`Labelling issue #${issueNumber}: ${labels.join(", ")}`);
|
|
192
|
+
await octokit.rest.issues.addLabels({ ...repo, issue_number: issueNumber, labels });
|
|
193
|
+
return `labelled-issue:#${issueNumber}`;
|
|
194
|
+
}
|
|
195
|
+
return "skipped:label-issue-missing-params";
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function executeCloseIssue(octokit, repo, params) {
|
|
199
|
+
const issueNumber = Number(params["issue-number"]);
|
|
200
|
+
if (issueNumber) {
|
|
201
|
+
core.info(`Closing issue #${issueNumber}`);
|
|
202
|
+
await octokit.rest.issues.update({ ...repo, issue_number: issueNumber, state: "closed" });
|
|
203
|
+
return `closed-issue:#${issueNumber}`;
|
|
204
|
+
}
|
|
205
|
+
return "skipped:close-issue-missing-number";
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async function executeRespondDiscussions(octokit, repo, params) {
|
|
209
|
+
const message = params.message || "";
|
|
210
|
+
const url = params["discussion-url"] || "";
|
|
211
|
+
if (message) {
|
|
212
|
+
core.info(`Dispatching discussions bot with response: ${message.substring(0, 100)}`);
|
|
213
|
+
await octokit.rest.actions.createWorkflowDispatch({
|
|
214
|
+
...repo,
|
|
215
|
+
workflow_id: "agent-discussions-bot.yml",
|
|
216
|
+
ref: "main",
|
|
217
|
+
inputs: {},
|
|
218
|
+
});
|
|
219
|
+
return `respond-discussions:${url || "no-url"}`;
|
|
220
|
+
}
|
|
221
|
+
return "skipped:respond-no-message";
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const ACTION_HANDLERS = {
|
|
225
|
+
"github:create-issue": executeCreateIssue,
|
|
226
|
+
"github:label-issue": executeLabelIssue,
|
|
227
|
+
"github:close-issue": executeCloseIssue,
|
|
228
|
+
"respond:discussions": executeRespondDiscussions,
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
async function executeAction(octokit, repo, action, params) {
|
|
232
|
+
if (action.startsWith("dispatch:")) return executeDispatch(octokit, repo, action, params);
|
|
233
|
+
if (action === "nop") return "nop";
|
|
234
|
+
const handler = ACTION_HANDLERS[action];
|
|
235
|
+
if (handler) return handler(octokit, repo, params);
|
|
236
|
+
core.warning(`Unknown action: ${action}`);
|
|
237
|
+
return `unknown:${action}`;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Supervisor task: gather context, ask LLM to choose actions, execute them.
|
|
242
|
+
*
|
|
243
|
+
* @param {Object} context - Task context from index.js
|
|
244
|
+
* @returns {Promise<Object>} Result with outcome, tokensUsed, model
|
|
245
|
+
*/
|
|
246
|
+
export async function supervise(context) {
|
|
247
|
+
const { octokit, repo, config, instructions, model } = context;
|
|
248
|
+
|
|
249
|
+
const ctx = await gatherContext(octokit, repo, config);
|
|
250
|
+
const agentInstructions = instructions || "You are the supervisor. Decide what actions to take.";
|
|
251
|
+
const prompt = buildPrompt(ctx, agentInstructions);
|
|
252
|
+
|
|
253
|
+
const { content, tokensUsed } = await runCopilotTask({
|
|
254
|
+
model,
|
|
255
|
+
systemMessage:
|
|
256
|
+
"You are the supervisor of an autonomous coding repository. Your job is to advance the mission by choosing which workflows to dispatch and which GitHub actions to take. Pick multiple actions when appropriate. Be strategic — consider what's already in progress, what's blocked, and what will make the most impact.",
|
|
257
|
+
prompt,
|
|
258
|
+
writablePaths: [],
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
const actions = parseActions(content);
|
|
262
|
+
const reasoning = parseReasoning(content);
|
|
263
|
+
|
|
264
|
+
core.info(`Supervisor reasoning: ${reasoning.substring(0, 200)}`);
|
|
265
|
+
core.info(`Supervisor chose ${actions.length} action(s)`);
|
|
266
|
+
|
|
267
|
+
const results = [];
|
|
268
|
+
for (const { action, params } of actions) {
|
|
269
|
+
try {
|
|
270
|
+
const result = await executeAction(octokit, repo, action, params);
|
|
271
|
+
results.push(result);
|
|
272
|
+
core.info(`Action result: ${result}`);
|
|
273
|
+
} catch (err) {
|
|
274
|
+
core.warning(`Action ${action} failed: ${err.message}`);
|
|
275
|
+
results.push(`error:${action}:${err.message}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
outcome: actions.length === 0 ? "nop" : `supervised:${actions.length}-actions`,
|
|
281
|
+
tokensUsed,
|
|
282
|
+
model,
|
|
283
|
+
details: `Actions: ${results.join(", ")}\nReasoning: ${reasoning.substring(0, 300)}`,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
You are the supervisor of an autonomous coding repository. Your job is to advance the mission by strategically choosing which workflows to dispatch and which GitHub actions to take.
|
|
2
|
+
|
|
3
|
+
## Decision Framework
|
|
4
|
+
|
|
5
|
+
1. **Check what's already in progress** — don't duplicate work. If a transform is running, don't dispatch another.
|
|
6
|
+
2. **Prioritise unblocking** — fix failing PRs before starting new features. Close resolved issues to free capacity.
|
|
7
|
+
3. **Balance the pipeline** — maintain a healthy mix of feature work, maintenance, and review.
|
|
8
|
+
4. **Respect limits** — don't create issues beyond the WIP limit. Don't dispatch workflows that will fail due to missing prerequisites.
|
|
9
|
+
5. **Be strategic about timing** — if the schedule is hourly, you can afford to spread work across cycles. If daily, batch more aggressively.
|
|
10
|
+
|
|
11
|
+
## When to use each action
|
|
12
|
+
|
|
13
|
+
- **dispatch:agent-flow-transform** — When there are open issues ready to work on and no transform is currently running.
|
|
14
|
+
- **dispatch:agent-flow-maintain** — When features or library docs are below their limits, or haven't been refreshed recently.
|
|
15
|
+
- **dispatch:agent-flow-review** — When there are open automated issues that might be resolved, or issues that need better acceptance criteria.
|
|
16
|
+
- **dispatch:agent-flow-fix-code** — When a specific PR has failing checks. Always include the pr-number.
|
|
17
|
+
- **dispatch:agent-discussions-bot** — When you want to proactively engage in discussions or respond to a user request.
|
|
18
|
+
- **github:create-issue** — When you identify a gap between the mission and current features. Always include a descriptive title and relevant labels.
|
|
19
|
+
- **github:label-issue** — When an issue needs better categorisation for prioritisation.
|
|
20
|
+
- **github:close-issue** — When an issue is clearly resolved or no longer relevant.
|
|
21
|
+
- **respond:discussions** — When replying to a user request that came through the discussions bot. Include the discussion URL and a clear message.
|
|
22
|
+
- **nop** — When everything is running smoothly and no intervention is needed.
|
|
23
|
+
|
|
24
|
+
## Guidelines
|
|
25
|
+
|
|
26
|
+
- Pick multiple actions when appropriate — concurrent work is encouraged.
|
|
27
|
+
- Always explain your reasoning — this helps future cycles understand the trajectory.
|
|
28
|
+
- When a user has made a request via discussions, prioritise responding to it.
|
|
29
|
+
- Don't dispatch the same workflow twice in one cycle.
|
|
30
|
+
- If recent workflow runs show failures, investigate before dispatching more work.
|
package/src/seeds/init.yml
CHANGED
|
@@ -27,6 +27,11 @@ on:
|
|
|
27
27
|
type: boolean
|
|
28
28
|
required: false
|
|
29
29
|
default: false
|
|
30
|
+
mission:
|
|
31
|
+
description: "Mission text for MISSION.md (leave empty to use seed default)"
|
|
32
|
+
type: string
|
|
33
|
+
required: false
|
|
34
|
+
default: ""
|
|
30
35
|
|
|
31
36
|
permissions: write-all
|
|
32
37
|
|
|
@@ -42,9 +47,12 @@ jobs:
|
|
|
42
47
|
echo "mode=${MODE:-update}" >> $GITHUB_OUTPUT
|
|
43
48
|
DRY_RUN='${{ inputs.dry-run }}'
|
|
44
49
|
echo "dry-run=${DRY_RUN:-false}" >> $GITHUB_OUTPUT
|
|
50
|
+
MISSION='${{ inputs.mission }}'
|
|
51
|
+
echo "mission=${MISSION}" >> $GITHUB_OUTPUT
|
|
45
52
|
outputs:
|
|
46
53
|
mode: ${{ steps.normalise.outputs.mode }}
|
|
47
54
|
dry-run: ${{ steps.normalise.outputs.dry-run }}
|
|
55
|
+
mission: ${{ steps.normalise.outputs.mission }}
|
|
48
56
|
|
|
49
57
|
init:
|
|
50
58
|
needs: params
|
|
@@ -52,6 +60,7 @@ jobs:
|
|
|
52
60
|
env:
|
|
53
61
|
INIT_MODE: ${{ needs.params.outputs.mode }}
|
|
54
62
|
INIT_DRY_RUN: ${{ needs.params.outputs.dry-run }}
|
|
63
|
+
INIT_MISSION: ${{ needs.params.outputs.mission }}
|
|
55
64
|
steps:
|
|
56
65
|
- uses: actions/checkout@v4
|
|
57
66
|
with:
|
|
@@ -78,6 +87,12 @@ jobs:
|
|
|
78
87
|
if [ "$INIT_DRY_RUN" = "true" ]; then FLAGS="$FLAGS --dry-run"; fi
|
|
79
88
|
npx @xn-intenton-z2a/agentic-lib $FLAGS
|
|
80
89
|
|
|
90
|
+
- name: Write mission (if provided)
|
|
91
|
+
if: env.INIT_MISSION != ''
|
|
92
|
+
run: |
|
|
93
|
+
printf '# Mission\n\n%s\n' "$INIT_MISSION" > MISSION.md
|
|
94
|
+
echo "Wrote custom mission to MISSION.md"
|
|
95
|
+
|
|
81
96
|
- run: npm install
|
|
82
97
|
|
|
83
98
|
- name: Install agentic-step deps
|
package/src/seeds/zero-README.md
CHANGED
|
@@ -1,13 +1,79 @@
|
|
|
1
1
|
# repo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This repository is powered by [intentïon agentic-lib](https://github.com/xn-intenton-z2a/agentic-lib) — autonomous code transformation driven by GitHub Copilot. Write a mission, and the system generates issues, writes code, runs tests, and opens pull requests on a schedule.
|
|
4
4
|
|
|
5
5
|
## Getting Started
|
|
6
6
|
|
|
7
|
-
1. Write your mission in `MISSION.md`
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
7
|
+
1. **Write your mission** in [`MISSION.md`](MISSION.md) — describe what you want to build in plain English
|
|
8
|
+
2. **Configure GitHub** — see [Setup](#setup) below
|
|
9
|
+
3. **Push to main** — the autonomous workflows take over from here
|
|
10
|
+
|
|
11
|
+
The system will create issues from your mission, generate code to resolve them, run tests, and open PRs. A supervisor agent orchestrates the pipeline, and you can interact through GitHub Discussions.
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
### Required Secrets
|
|
16
|
+
|
|
17
|
+
Add these in your repository: **Settings → Secrets and variables → Actions → New repository secret**
|
|
18
|
+
|
|
19
|
+
| Secret | How to create | Purpose |
|
|
20
|
+
|--------|---------------|---------|
|
|
21
|
+
| `COPILOT_GITHUB_TOKEN` | [Fine-grained PAT](https://github.com/settings/tokens?type=beta) with **GitHub Copilot** → Read permission | Authenticates with the Copilot SDK for all agentic tasks |
|
|
22
|
+
| `WORKFLOW_TOKEN` | [Classic PAT](https://github.com/settings/tokens) with **workflow** scope | Allows `init.yml` to update workflow files (GITHUB_TOKEN cannot modify `.github/workflows/`) |
|
|
23
|
+
|
|
24
|
+
### Repository Settings
|
|
25
|
+
|
|
26
|
+
| Setting | Where | Value |
|
|
27
|
+
|---------|-------|-------|
|
|
28
|
+
| GitHub Actions | Settings → Actions → General | Allow all actions |
|
|
29
|
+
| Workflow permissions | Settings → Actions → General | Read and write permissions |
|
|
30
|
+
| Allow GitHub Actions to create PRs | Settings → Actions → General | Checked |
|
|
31
|
+
| GitHub Discussions | Settings → General → Features | Enabled (for the discussions bot) |
|
|
32
|
+
|
|
33
|
+
### Optional: Branch Protection
|
|
34
|
+
|
|
35
|
+
For production repositories, consider adding branch protection on `main`:
|
|
36
|
+
- Require pull request reviews before merging
|
|
37
|
+
- Require status checks to pass (select the `test` workflow)
|
|
38
|
+
|
|
39
|
+
## How It Works
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
MISSION.md → [supervisor] → dispatch workflows → Issue → Code → Test → PR → Merge
|
|
43
|
+
↑ |
|
|
44
|
+
+——————————————————————————+
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The pipeline runs as GitHub Actions workflows. An LLM supervisor gathers repository context (issues, PRs, workflow runs, features) and strategically dispatches other workflows. Each workflow uses the Copilot SDK to make targeted changes.
|
|
48
|
+
|
|
49
|
+
## Configuration
|
|
50
|
+
|
|
51
|
+
Edit `agentic-lib.toml` to tune the system:
|
|
52
|
+
|
|
53
|
+
```toml
|
|
54
|
+
[schedule]
|
|
55
|
+
supervisor = "daily" # off | weekly | daily | hourly | continuous
|
|
56
|
+
|
|
57
|
+
[paths]
|
|
58
|
+
mission = "MISSION.md"
|
|
59
|
+
source = "src/lib/"
|
|
60
|
+
tests = "tests/unit/"
|
|
61
|
+
|
|
62
|
+
[limits]
|
|
63
|
+
feature-issues = 2 # max concurrent feature issues
|
|
64
|
+
attempts-per-issue = 2 # max retries per issue
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Updating
|
|
68
|
+
|
|
69
|
+
The `init.yml` workflow runs daily and updates the agentic infrastructure automatically. To update manually:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx @xn-intenton-z2a/agentic-lib@latest init
|
|
73
|
+
```
|
|
10
74
|
|
|
11
75
|
## Links
|
|
12
76
|
|
|
13
|
-
- [MISSION.md](MISSION.md)
|
|
77
|
+
- [MISSION.md](MISSION.md) — your project goals
|
|
78
|
+
- [agentic-lib documentation](https://github.com/xn-intenton-z2a/agentic-lib) — full SDK docs
|
|
79
|
+
- [intentïon website](https://xn--intenton-z2a.com)
|