@yemi33/minions 0.1.2217 → 0.1.2218
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/dashboard.js +30 -0
- package/engine/pr-action.js +45 -0
- package/package.json +1 -1
- package/prompts/cc-system.md +9 -0
package/dashboard.js
CHANGED
|
@@ -13033,6 +13033,36 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
13033
13033
|
}
|
|
13034
13034
|
}},
|
|
13035
13035
|
|
|
13036
|
+
{ method: 'POST', path: '/api/pr-action/offer-create-pr', desc: 'Offer a "Create PR" follow-up chip after Command Center makes a LOCAL code edit itself in a configured project (P-cc-createpr). Validates the project has uncommitted working-tree changes (git status --porcelain in project.localPath) and returns a create-pr follow-up chip — same CC-mediated shape as the pr-action chips, so the existing dashboard chip renderer/click handler light up unchanged. Returns {ok, hasChanges, branch, changedFileCount, followups}; followups is [] when there is nothing to PR. READ-ONLY: never stages/commits/pushes — clicking the chip routes a fresh CC turn that does the commit/push/PR-create/link.', params: 'project (configured project name), branch (optional — defaults to the working-tree current branch), contextOnly (optional bool — link the new PR as context-only instead of auto-managed)', handler: async (req, res) => {
|
|
13037
|
+
const body = await readBody(req);
|
|
13038
|
+
try {
|
|
13039
|
+
reloadConfig();
|
|
13040
|
+
const projectName = typeof body?.project === 'string' ? body.project.trim() : '';
|
|
13041
|
+
if (!projectName) return jsonReply(res, 400, { error: 'project is required' }, req);
|
|
13042
|
+
const project = shared.getProjects(CONFIG).find(p => p && p.name === projectName);
|
|
13043
|
+
if (!project) return jsonReply(res, 404, { error: `unknown project: ${projectName}` }, req);
|
|
13044
|
+
if (!project.localPath) return jsonReply(res, 400, { error: `project ${projectName} has no localPath (no working tree to PR)` }, req);
|
|
13045
|
+
let porcelain = '';
|
|
13046
|
+
let currentBranch = '';
|
|
13047
|
+
try {
|
|
13048
|
+
porcelain = await shared.shellSafeGit(['-C', project.localPath, 'status', '--porcelain']);
|
|
13049
|
+
currentBranch = (await shared.shellSafeGit(['-C', project.localPath, 'rev-parse', '--abbrev-ref', 'HEAD'])).trim();
|
|
13050
|
+
} catch (e) {
|
|
13051
|
+
return jsonReply(res, 400, { error: `git status failed for ${projectName}: ${e.message}` }, req);
|
|
13052
|
+
}
|
|
13053
|
+
const changedFileCount = porcelain.split('\n').map(s => s.trim()).filter(Boolean).length;
|
|
13054
|
+
const hasChanges = changedFileCount > 0;
|
|
13055
|
+
const branch = (typeof body?.branch === 'string' && body.branch.trim()) || currentBranch || '';
|
|
13056
|
+
const followups = hasChanges
|
|
13057
|
+
? prAction.buildCreatePrFollowups({ project: projectName, branch, contextOnly: !!body?.contextOnly })
|
|
13058
|
+
: [];
|
|
13059
|
+
recordCcTurnIfPresent(req, { kind: 'pr-action', id: '', title: `offer create-pr (${projectName})`, project: projectName, followups });
|
|
13060
|
+
return jsonReply(res, 200, { ok: true, hasChanges, branch, changedFileCount, followups }, req);
|
|
13061
|
+
} catch (e) {
|
|
13062
|
+
return jsonReply(res, e.statusCode || 400, { error: e.message }, req);
|
|
13063
|
+
}
|
|
13064
|
+
}},
|
|
13065
|
+
|
|
13036
13066
|
{ method: 'POST', path: '/api/pull-requests/observe', desc: 'Toggle canonical contextOnly flag on a tracked PR (public `observe` body param is preserved as the inverse for backward compat)', params: 'host (github|ado), slug, number, observe (boolean)', handler: async (req, res) => {
|
|
13037
13067
|
const body = await readBody(req);
|
|
13038
13068
|
reloadConfig();
|
package/engine/pr-action.js
CHANGED
|
@@ -128,6 +128,50 @@ function buildPrActionFollowups(record, opts = {}) {
|
|
|
128
128
|
}));
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
// ── "Create PR" follow-up (P-cc-createpr) ───────────────────────────────────
|
|
132
|
+
// Offered after Command Center makes a LOCAL code edit itself (not via a
|
|
133
|
+
// dispatched agent), so the user can open a PR for it with one click. Mirrors
|
|
134
|
+
// the PR_ACTION_FOLLOWUPS chip shape ({ kind, label, message }) so the existing
|
|
135
|
+
// dashboard renderer (_ccFollowupChips) + click handler (ccPrActionFollowup)
|
|
136
|
+
// light up unchanged. CC-mediated by the same deliberate design as the
|
|
137
|
+
// pr-action chips: clicking sends a fresh CC turn that commits/pushes/opens the
|
|
138
|
+
// PR and links it to the tracker — no new server-side git path, maximal reuse.
|
|
139
|
+
const CREATE_PR_FOLLOWUP = Object.freeze({ kind: 'create-pr', label: 'Create PR' });
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Build the "Create PR" follow-up chip(s) for a working-tree change CC just
|
|
143
|
+
* made in `project`. Returns `[]` when no project is given (nothing to act on).
|
|
144
|
+
*
|
|
145
|
+
* `branch` — the working-tree branch to commit on; falls back to "a new
|
|
146
|
+
* well-named branch" wording when absent.
|
|
147
|
+
* `contextOnly` — when true, the chip links the new PR as context-only instead
|
|
148
|
+
* of auto-managed (the default is auto-managed / contextOnly:false).
|
|
149
|
+
*
|
|
150
|
+
* Each chip: `{ kind:'create-pr', label, project, branch, message }` where
|
|
151
|
+
* `message` is the Command Center turn the chip click should send.
|
|
152
|
+
*/
|
|
153
|
+
function buildCreatePrFollowups({ project, branch, contextOnly = false } = {}) {
|
|
154
|
+
const proj = (project && String(project).trim()) || '';
|
|
155
|
+
if (!proj) return [];
|
|
156
|
+
const br = branch && String(branch).trim() ? String(branch).trim() : '';
|
|
157
|
+
const branchClause = br
|
|
158
|
+
? `on the current branch ${br}`
|
|
159
|
+
: 'on a new well-named branch off the project main branch';
|
|
160
|
+
const linkBody = contextOnly
|
|
161
|
+
? `{"url":"<new PR url>","project":"${proj}","contextOnly":true}`
|
|
162
|
+
: `{"url":"<new PR url>","project":"${proj}","contextOnly":false}`;
|
|
163
|
+
const trackNote = contextOnly
|
|
164
|
+
? 'so it is tracked but not auto-reviewed'
|
|
165
|
+
: 'so the engine auto-manages it (review -> fix -> re-review -> auto-merge)';
|
|
166
|
+
const message =
|
|
167
|
+
`Create a PR from the local changes you just made in the ${proj} project. ` +
|
|
168
|
+
`Steps: (1) in that project's working tree, stage and commit the modified files ${branchClause} with a clear conventional-commit message; ` +
|
|
169
|
+
`(2) push the branch; (3) open a PR against the project's main branch using the right CLI for the repo host (gh for GitHub, az repos for ADO); ` +
|
|
170
|
+
`(4) link it to the tracker by calling POST /api/pull-requests/link with ${linkBody} ${trackNote}. ` +
|
|
171
|
+
`Then show me the PR URL.`;
|
|
172
|
+
return [{ kind: CREATE_PR_FOLLOWUP.kind, label: CREATE_PR_FOLLOWUP.label, project: proj, branch: br || null, message }];
|
|
173
|
+
}
|
|
174
|
+
|
|
131
175
|
// Read-only system prompt for the projectless dispatch. Teaches the untrusted-
|
|
132
176
|
// input contract and the injection-signalling marker. Kept inline (no playbook
|
|
133
177
|
// render) because this path has no project/worktree context to inject.
|
|
@@ -538,6 +582,7 @@ module.exports = {
|
|
|
538
582
|
createPrAction,
|
|
539
583
|
buildPrActionPrompt,
|
|
540
584
|
buildPrActionFollowups,
|
|
585
|
+
buildCreatePrFollowups,
|
|
541
586
|
runPrAction,
|
|
542
587
|
postPrActionComment,
|
|
543
588
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2218",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|
package/prompts/cc-system.md
CHANGED
|
@@ -89,6 +89,15 @@ If you start a small task and discover it's actually Medium (3+ files, more tool
|
|
|
89
89
|
|
|
90
90
|
When genuinely in doubt about the size, delegate — agents have isolated worktrees, full tool access, durable work-item tracking, and no turn limits.
|
|
91
91
|
|
|
92
|
+
### After you make a local code edit yourself — offer to open a PR
|
|
93
|
+
When you edit files **yourself** in a configured project's working tree (the Step-3 "do it yourself" path — NOT a change a dispatched agent made in its own worktree), don't leave the diff sitting uncommitted. After you finish editing, call:
|
|
94
|
+
```
|
|
95
|
+
curl -s -X POST http://localhost:{{dashboard_port}}/api/pr-action/offer-create-pr \
|
|
96
|
+
-H 'Content-Type: application/json' -H 'X-CC-Turn-Id: {{cc_turn_id}}' \
|
|
97
|
+
-d '{"project":"<project name>"}'
|
|
98
|
+
```
|
|
99
|
+
This checks the project's working tree (`git status --porcelain`) and, when there are uncommitted changes, returns a **`[Create PR]`** follow-up chip to the user (same chip mechanism as the `pr-action` `[Comment]`/`[Fix once]`/`[Track for auto-fix]` chips). When the user clicks it, you'll receive a turn instructing you to commit → push → open the PR → link it to the tracker. Pass `"contextOnly":true` if the PR should be tracked-but-not-auto-reviewed; omit it to have the engine auto-manage the PR (review → fix → re-review → auto-merge). If `hasChanges` is `false`, there's nothing to PR — skip the offer. Don't commit/push on your own initiative; surface the chip and let the user decide.
|
|
100
|
+
|
|
92
101
|
## When to dispatch vs answer inline
|
|
93
102
|
|
|
94
103
|
- **Action requests** (fix this, implement that, build X, run a build, investigate Y, review PR #N) → dispatch via `POST /api/work-items` (or one of the other state-changing endpoints below). Don't also try to do the work yourself in the chat unless it's truly Small per Step 1.
|