@yemi33/minions 0.1.1938 → 0.1.1940
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.
|
@@ -60,7 +60,9 @@ function formatToolSummary(name, input) {
|
|
|
60
60
|
}
|
|
61
61
|
default: {
|
|
62
62
|
var keys = Object.keys(inp);
|
|
63
|
-
|
|
63
|
+
// No-input case (e.g. ACP chips that carry their full label in `name`
|
|
64
|
+
// like "Fetch /api/status") — render the name verbatim, no parens.
|
|
65
|
+
if (keys.length === 0) return escHtml(name);
|
|
64
66
|
var firstKey = keys[0];
|
|
65
67
|
var firstVal = String(inp[firstKey] || '');
|
|
66
68
|
if (firstVal.length > 40) firstVal = firstVal.slice(0, 37) + '...';
|
package/docs/distribution.md
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
# Distribution & Publishing
|
|
2
2
|
|
|
3
|
-
Minions is distributed as an npm package (`@yemi33/minions`) from a sanitized package boundary.
|
|
3
|
+
Minions is distributed as an npm package (`@yemi33/minions`) from a sanitized package boundary. The source lives across three GitHub remotes, with a strict one-way port direction (see [Three-Remote Topology](#three-remote-topology)).
|
|
4
|
+
|
|
5
|
+
## Three-Remote Topology
|
|
6
|
+
|
|
7
|
+
| Remote (local name on `D:/squad`) | URL | Role |
|
|
8
|
+
|-----------------------------------|-----|------|
|
|
9
|
+
| `origin` | `https://github.com/yemi33/minions` | **Authoring source of truth.** All normal code changes (engine, dashboard, playbooks, agents, etc.) land here first. Triggers npm publish + downstream mirrors. |
|
|
10
|
+
| `emu` | `https://github.com/yemishin_microsoft/minions` | Microsoft-identity mirror of `yemi33/minions`. Automated via `.github/workflows/mirror-to-emu.yml`. |
|
|
11
|
+
| `opg` | `https://github.com/opg-microsoft/minions` | **Compliant store** under the `opg-microsoft` org. Automated mirror to a sync branch via `.github/workflows/mirror-to-opg.yml`; `main` is reconciled by a maintainer PR because it carries enterprise/compliance-only commits (see below). |
|
|
12
|
+
|
|
13
|
+
### Port direction
|
|
14
|
+
|
|
15
|
+
**Strictly one-way: `yemi33` → `emu`, `yemi33` → `opg`.**
|
|
16
|
+
|
|
17
|
+
- **Do NOT port from `emu` or `opg` back into `yemi33`.** Their `main` branches may carry org-specific compliance content (`.github/policies/*`, `.github/acl/*`, `.github/compliance/*`, JIT access policy, internal access lists, MS-org issue templates) that has no business in the personal-fork authoring source.
|
|
18
|
+
- **Direct pushes to `opg-microsoft/minions` are allowed for enterprise/compliance-specific changes only.** Examples: editing `.github/policies/jit.yml`, updating `.github/acl/access.yml`, modifying `.github/compliance/inventory.yml`. These changes stay on `opg` and are not backported.
|
|
19
|
+
- Other teams (Microsoft infra, compliance review) may also push to `opg-microsoft/minions` directly. Treat its `main` as potentially ahead of `yemi33`/`emu` on policy files.
|
|
20
|
+
|
|
21
|
+
### Why opg can't use the same direct-mirror pattern as emu
|
|
22
|
+
|
|
23
|
+
`mirror-to-emu.yml` does `git push emu HEAD:master` — direct overwrite, because `emu/master` is meant to be a 1:1 reflection of `yemi33/master`. `opg-microsoft/minions` is different: its `main` carries enterprise-only commits that don't exist on `yemi33/master`, so a force-push to `opg/main` would destroy them. Instead, `mirror-to-opg.yml` force-pushes `yemi33/master` to `opg/sync/yemi33-master` (a dedicated bot-owned branch), and a maintainer opens or updates a PR from `sync/yemi33-master` → `main` for review. The first such PR uses `--allow-unrelated-histories` to bridge the initial divergence; subsequent ones merge incrementally.
|
|
24
|
+
|
|
25
|
+
### Required secrets on `yemi33/minions`
|
|
26
|
+
|
|
27
|
+
| Secret | Purpose | Workflow |
|
|
28
|
+
|--------|---------|----------|
|
|
29
|
+
| `NPM_TOKEN` | npm publish | `publish.yml` |
|
|
30
|
+
| `EMU_PUSH_TOKEN` | Push to `yemishin_microsoft/minions` | `mirror-to-emu.yml` |
|
|
31
|
+
| `EMU_PACKAGES_TOKEN` | Publish to `@yemishin_microsoft` internal registry | `publish-internal-github-packages.yml` |
|
|
32
|
+
| `OPG_PUSH_TOKEN` | Push to `opg-microsoft/minions` sync branch | `mirror-to-opg.yml` |
|
|
33
|
+
|
|
34
|
+
Each mirror workflow gracefully skips with a warning if its token secret is unset, so unconfigured downstreams never block the primary publish path.
|
|
4
35
|
|
|
5
36
|
## Distribution Boundary
|
|
6
37
|
|
package/engine/cc-worker-pool.js
CHANGED
|
@@ -252,9 +252,7 @@ class Worker {
|
|
|
252
252
|
try { this.inflight.onChunk(text); } catch { /* swallow */ }
|
|
253
253
|
}
|
|
254
254
|
} else if (update.sessionUpdate === 'tool_call' && this.inflight.onToolUse) {
|
|
255
|
-
// ACP `tool_call` (pending) →
|
|
256
|
-
// _mapAcpToolCallToToolUse so the dashboard's formatToolSummary
|
|
257
|
-
// formatters (Bash → "$ <cmd>", etc.) work unchanged.
|
|
255
|
+
// ACP `tool_call` (pending) → chip label via _mapAcpToolCallToToolUse.
|
|
258
256
|
const mapped = _mapAcpToolCallToToolUse(update);
|
|
259
257
|
if (mapped) {
|
|
260
258
|
try { this.inflight.onToolUse(mapped.name, mapped.input, update.toolCallId); }
|
|
@@ -447,50 +445,40 @@ function _extractChunkText(content) {
|
|
|
447
445
|
// (Bash → "$ <cmd>", Read → "Reading <path>", etc.). Unknown kinds fall back
|
|
448
446
|
// to ACP's human-readable `title` with the raw input attached, which renders
|
|
449
447
|
// through the default `<title>(<key>: <val>)` formatter.
|
|
448
|
+
// Map an ACP `tool_call` notification to a chip label. Strategy:
|
|
449
|
+
//
|
|
450
|
+
// 1. Detect well-known shapes by rawInput field presence and route through
|
|
451
|
+
// formatToolSummary's Claude-tool formatters (Bash → "$ <cmd>",
|
|
452
|
+
// Grep → "Searching `pat` in path", Read → "Reading <path>"). Preserves
|
|
453
|
+
// the granular detail you actually want when reading the chip list.
|
|
454
|
+
//
|
|
455
|
+
// 2. Fall back to ACP's human-curated `title` for anything that doesn't
|
|
456
|
+
// match. Title is always populated and immune to field-name drift, so
|
|
457
|
+
// the empty-`$` failure mode (kind:execute with no `command`) becomes
|
|
458
|
+
// a clean "Find work item W-..." chip instead of a broken stub.
|
|
459
|
+
//
|
|
460
|
+
// Kind-based routing is intentionally NOT used — ACP overloads `kind:read`
|
|
461
|
+
// for both file-view and grep, and `kind:execute` sometimes arrives without
|
|
462
|
+
// a `command`. Field-detection on rawInput is more reliable.
|
|
450
463
|
function _mapAcpToolCallToToolUse(update) {
|
|
451
464
|
if (!update || update.sessionUpdate !== 'tool_call') return null;
|
|
452
465
|
const rawInput = (update.rawInput && typeof update.rawInput === 'object') ? update.rawInput : {};
|
|
453
|
-
const
|
|
454
|
-
const title = update.title || '';
|
|
455
|
-
|
|
456
|
-
// Field-name normalization: Copilot ACP and Claude tool_use use different
|
|
457
|
-
// keys for the same concept (Copilot `path`, Claude `file_path`). Normalize
|
|
458
|
-
// here so the dashboard's formatToolSummary — written against Claude's
|
|
459
|
-
// names — produces the same chip text on both runtimes.
|
|
460
|
-
const filePath = rawInput.file_path || rawInput.path || rawInput.filePath || '';
|
|
461
|
-
|
|
462
|
-
// Pattern (Grep) — Copilot uses `paths` (plural) for the search scope where
|
|
463
|
-
// Claude's Grep takes `path`.
|
|
464
|
-
if (typeof rawInput.pattern === 'string') {
|
|
465
|
-
return {
|
|
466
|
-
name: 'Grep',
|
|
467
|
-
input: { pattern: rawInput.pattern, path: rawInput.paths || rawInput.path || '.' },
|
|
468
|
-
};
|
|
469
|
-
}
|
|
466
|
+
const title = update.title || update.kind || 'Tool';
|
|
470
467
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
case 'fetch':
|
|
484
|
-
return { name: 'WebFetch', input: rawInput };
|
|
485
|
-
case 'think':
|
|
486
|
-
return { name: title || 'Think', input: rawInput };
|
|
487
|
-
default:
|
|
488
|
-
// Unknown kind — use ACP's human-readable title as the chip label and
|
|
489
|
-
// drop rawInput so formatToolSummary's default branch shows just the
|
|
490
|
-
// title (avoids `<title>(<key>: <val>)` clutter when the input shape
|
|
491
|
-
// is unfamiliar).
|
|
492
|
-
return { name: title || kind || 'Tool', input: {} };
|
|
468
|
+
if (typeof rawInput.command === 'string' && rawInput.command) {
|
|
469
|
+
return { name: 'Bash', input: { command: rawInput.command } };
|
|
470
|
+
}
|
|
471
|
+
if (typeof rawInput.pattern === 'string' && rawInput.pattern) {
|
|
472
|
+
return { name: 'Grep', input: { pattern: rawInput.pattern, path: rawInput.paths || rawInput.path || '.' } };
|
|
473
|
+
}
|
|
474
|
+
if (typeof rawInput.path === 'string' && rawInput.path) {
|
|
475
|
+
const isEdit = String(update.kind || '').toLowerCase() === 'edit';
|
|
476
|
+
return { name: isEdit ? 'Edit' : 'Read', input: { file_path: rawInput.path } };
|
|
477
|
+
}
|
|
478
|
+
if (typeof rawInput.url === 'string' && rawInput.url) {
|
|
479
|
+
return { name: 'WebFetch', input: { url: rawInput.url } };
|
|
493
480
|
}
|
|
481
|
+
return { name: title, input: {} };
|
|
494
482
|
}
|
|
495
483
|
|
|
496
484
|
// ── Public API ────────────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1940",
|
|
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"
|