create-byan-agent 2.23.0 → 2.26.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/CHANGELOG.md +230 -0
- package/README.md +9 -12
- package/install/bin/create-byan-agent-v2.js +29 -169
- package/install/lib/agent-generator.js +5 -5
- package/install/lib/byan-web-integration.js +1 -1
- package/install/lib/claude-native-setup.js +1 -1
- package/install/lib/phase2-chat.js +3 -10
- package/install/lib/platforms/claude-code.js +2 -2
- package/install/lib/platforms/index.js +0 -2
- package/install/lib/project-agents-generator.js +3 -3
- package/install/lib/staging-consent.js +3 -3
- package/install/lib/subagent-generator.js +3 -3
- package/install/lib/yanstaller/agent-launcher.js +1 -27
- package/install/lib/yanstaller/detector.js +4 -4
- package/install/lib/yanstaller/installer.js +0 -2
- package/install/lib/yanstaller/interviewer.js +1 -1
- package/install/lib/yanstaller/platform-selector.js +1 -13
- package/install/package.json +1 -1
- package/install/src/byan-v2/context/session-state.js +2 -2
- package/install/src/byan-v2/index.js +2 -6
- package/install/src/byan-v2/orchestrator/generation-state.js +4 -4
- package/install/src/webui/api.js +0 -2
- package/install/src/webui/chat/bridge.js +1 -13
- package/install/src/webui/chat/cli-detector.js +0 -23
- package/install/src/webui/public/app.js +1 -3
- package/install/src/webui/public/chat.html +0 -2
- package/install/src/webui/public/chat.js +0 -1
- package/install/src/webui/public/index.html +2 -2
- package/install/templates/.claude/CLAUDE.md +13 -2
- package/install/templates/.claude/agents/bmad-byan.md +1 -1
- package/install/templates/.claude/hooks/autobench-stop-guard.js +286 -0
- package/install/templates/.claude/hooks/drain-advisory.js +85 -0
- package/install/templates/.claude/hooks/fact-check-absolutes.js +1 -61
- package/install/templates/.claude/hooks/fact-check-claims.js +69 -0
- package/install/templates/.claude/hooks/fd-response-check.js +37 -46
- package/install/templates/.claude/hooks/inject-soul.js +64 -25
- package/install/templates/.claude/hooks/leantime-fd-sync.js +216 -0
- package/install/templates/.claude/hooks/lib/autobench-config.json +81 -0
- package/install/templates/.claude/hooks/lib/autobench-fc-enrich.js +251 -0
- package/install/templates/.claude/hooks/lib/autobench-ledger-report.js +253 -0
- package/install/templates/.claude/hooks/lib/autobench-runtime.js +199 -0
- package/install/templates/.claude/hooks/lib/fact-check-core.js +69 -0
- package/install/templates/.claude/hooks/lib/failure-detector.js +18 -4
- package/install/templates/.claude/hooks/lib/transcript-read.js +137 -0
- package/install/templates/.claude/hooks/soul-memory-check.js +49 -25
- package/install/templates/.claude/hooks/soul-memory-triggers.js +27 -8
- package/install/templates/.claude/hooks/stage-to-byan.js +25 -7
- package/install/templates/.claude/hooks/strict-stop-guard.js +4 -16
- package/install/templates/.claude/rules/benchmark.md +251 -0
- package/install/templates/.claude/rules/byan-agents.md +0 -1
- package/install/templates/.claude/rules/byan-api.md +64 -0
- package/install/templates/.claude/rules/fact-check.md +1 -1
- package/install/templates/.claude/rules/strict-mode.md +10 -9
- package/install/templates/.claude/settings.json +16 -0
- package/install/templates/.claude/skills/byan-benchmark/SKILL.md +159 -0
- package/install/templates/.claude/skills/byan-byan/SKILL.md +73 -12
- package/install/templates/.claude/skills/byan-fact-check/SKILL.md +1 -1
- package/install/templates/.claude/skills/byan-hermes-dispatch/SKILL.md +5 -6
- package/install/templates/.claude/skills/byan-insight/SKILL.md +56 -0
- package/install/templates/.claude/skills/byan-orchestrate/SKILL.md +11 -3
- package/install/templates/.claude/skills/byan-strict/SKILL.md +4 -1
- package/install/templates/.claude/workflows/INDEX.md +2 -1
- package/install/templates/.claude/workflows/byan-benchmark.js +328 -0
- package/install/templates/.claude/workflows/check-implementation-readiness.js +1 -1
- package/install/templates/_byan/_config/agent-manifest.csv +1 -1
- package/install/templates/_byan/_config/autobench.yaml +510 -0
- package/install/templates/_byan/_config/strict-mode.yaml +9 -3
- package/install/templates/_byan/_config/workflow-manifest.csv +1 -0
- package/install/templates/_byan/agent/byan/byan.md +1 -3
- package/install/templates/_byan/agent/byan-flat/byan.md +1 -3
- package/install/templates/_byan/agent/byan-test/byan-test.md +2 -2
- package/install/templates/_byan/agent/byan-test-flat/byan-test.md +2 -2
- package/install/templates/_byan/agent/byan.optimized/byan.optimized.md +2 -2
- package/install/templates/_byan/agent/byan.optimized-v2/byan.optimized-v2.md +2 -2
- package/install/templates/_byan/agent/claude/claude.md +0 -2
- package/install/templates/_byan/agent/codex/codex.md +0 -2
- package/install/templates/_byan/agent/rachid/rachid.md +2 -10
- package/install/templates/_byan/agent/rachid-flat/rachid.md +2 -11
- package/install/templates/_byan/agent/turbo-whisper/turbo-whisper.md +2 -5
- package/install/templates/_byan/agent/turbo-whisper-integration/turbo-whisper-integration.md +5 -13
- package/install/templates/_byan/agent/yanstaller/yanstaller.md +2 -24
- package/install/templates/_byan/config.yaml +0 -1
- package/install/templates/_byan/core/activation/soul-activation.md +3 -3
- package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-insight-digest.js +31 -0
- package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-sync-rules.js +20 -4
- package/install/templates/_byan/mcp/byan-mcp-server/lib/advisory-autofeed.js +96 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/index-generator.js +1 -1
- package/install/templates/_byan/mcp/byan-mcp-server/lib/insight-harvest.js +220 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/kanban.js +6 -3
- package/install/templates/_byan/mcp/byan-mcp-server/lib/leantime-fd-core.js +205 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/leantime-sync.js +415 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/outcome-buffer.js +64 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/precommit-gate.js +1 -1
- package/install/templates/_byan/mcp/byan-mcp-server/lib/strict-activation.js +1 -1
- package/install/templates/_byan/mcp/byan-mcp-server/lib/strict-mode.js +8 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/sync-rules.js +172 -23
- package/install/templates/_byan/mcp/byan-mcp-server/lib/workflows-generator.js +1 -0
- package/install/templates/_byan/mcp/byan-mcp-server/server.js +262 -81
- package/install/templates/_byan/worker/launchers/README.md +4 -24
- package/install/templates/_byan/worker/workers.md +8 -9
- package/install/templates/_byan/workflow/simple/bmb/byan-benchmark/workflow.md +86 -0
- package/install/templates/_byan/workflow/simple/byan/feature-workflow.md +2 -2
- package/install/templates/docs/leantime-integration.md +160 -0
- package/package.json +3 -7
- package/src/byan-v2/context/session-state.js +2 -2
- package/src/byan-v2/generation/mantra-validator.js +3 -3
- package/src/byan-v2/index.js +1 -5
- package/src/byan-v2/integration/voice-integration.js +1 -1
- package/src/byan-v2/orchestrator/generation-state.js +4 -4
- package/src/loadbalancer/loadbalancer.js +1 -1
- package/src/staging/staging.js +20 -6
- package/install/bin/build-copilot-stubs.js +0 -138
- package/install/lib/platforms/copilot-cli.js +0 -123
- package/install/lib/platforms/vscode.js +0 -51
- package/install/src/byan-v2/context/copilot-context.js +0 -79
- package/install/src/webui/chat/copilot-adapter.js +0 -68
- package/install/templates/.claude/agents/bmad-marc.md +0 -25
- package/install/templates/.claude/skills/byan-marc/SKILL.md +0 -20
- package/install/templates/.github/agents/bmad-agent-bmad-master.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmb-agent-builder.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmb-module-builder.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmb-workflow-builder.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-analyst.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-architect.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-dev.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-pm.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-quinn.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-sm.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-tech-writer.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-ux-designer.md +0 -16
- package/install/templates/.github/agents/bmad-agent-byan-test.md +0 -33
- package/install/templates/.github/agents/bmad-agent-byan-v2.md +0 -44
- package/install/templates/.github/agents/bmad-agent-byan.md +0 -1062
- package/install/templates/.github/agents/bmad-agent-carmack.md +0 -14
- package/install/templates/.github/agents/bmad-agent-cis-brainstorming-coach.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-creative-problem-solver.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-design-thinking-coach.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-innovation-strategist.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-presentation-master.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-storyteller.md +0 -16
- package/install/templates/.github/agents/bmad-agent-claude.md +0 -49
- package/install/templates/.github/agents/bmad-agent-codex.md +0 -49
- package/install/templates/.github/agents/bmad-agent-drawio.md +0 -45
- package/install/templates/.github/agents/bmad-agent-fact-checker.md +0 -16
- package/install/templates/.github/agents/bmad-agent-forgeron.md +0 -15
- package/install/templates/.github/agents/bmad-agent-jimmy.md +0 -15
- package/install/templates/.github/agents/bmad-agent-marc.md +0 -49
- package/install/templates/.github/agents/bmad-agent-mike.md +0 -15
- package/install/templates/.github/agents/bmad-agent-patnote.md +0 -49
- package/install/templates/.github/agents/bmad-agent-rachid.md +0 -48
- package/install/templates/.github/agents/bmad-agent-skeptic.md +0 -16
- package/install/templates/.github/agents/bmad-agent-tao.md +0 -14
- package/install/templates/.github/agents/bmad-agent-tea-tea.md +0 -16
- package/install/templates/.github/agents/bmad-agent-test-dynamic.md +0 -22
- package/install/templates/.github/agents/bmad-agent-yanstaller-interview.md +0 -50
- package/install/templates/.github/agents/bmad-agent-yanstaller-phase2.md +0 -189
- package/install/templates/.github/agents/bmad-agent-yanstaller.md +0 -350
- package/install/templates/.github/agents/expert-merise-agile.md +0 -178
- package/install/templates/.github/agents/franck.md +0 -379
- package/install/templates/.github/agents/hermes.md +0 -575
- package/install/templates/.github/extensions/byan-staging/extension.mjs +0 -169
- package/install/templates/.github/extensions/byan-staging/package.json +0 -8
- package/install/templates/_byan/agent/marc/marc-soul.md +0 -47
- package/install/templates/_byan/agent/marc/marc-tao.md +0 -77
- package/install/templates/_byan/agent/marc/marc.md +0 -324
- package/install/templates/_byan/agent/marc-flat/marc.md +0 -387
- package/install/templates/_byan/mcp/byan-mcp-server/lib/copilot.js +0 -148
- package/install/templates/_byan/worker/launchers/launch-yanstaller-copilot.md +0 -173
- package/install/templates/workers/cost-optimizer.js +0 -169
- package/src/byan-v2/context/copilot-context.js +0 -79
- package/src/core/dispatcher/execution-router.js +0 -66
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Leantime integration (one-way FD -> board)
|
|
2
|
+
|
|
3
|
+
BYAN can mirror its Feature Development (FD) lifecycle onto a self-hosted
|
|
4
|
+
Leantime board. The link is one-way: the FD workflow drives the Leantime board;
|
|
5
|
+
the board does not drive FD. The integration is optional and best-effort — when
|
|
6
|
+
it is not configured, or Leantime is unreachable, every FD phase still advances.
|
|
7
|
+
|
|
8
|
+
## What it does
|
|
9
|
+
|
|
10
|
+
When configured, the FD workflow fires `byan_leantime_*` MCP tools at phase
|
|
11
|
+
events:
|
|
12
|
+
|
|
13
|
+
| FD phase / event | Effect on the board |
|
|
14
|
+
|------------------|---------------------|
|
|
15
|
+
| DISCOVERY (project confirmed) | create-or-fetch the Leantime project |
|
|
16
|
+
| DISPATCH (per backlog feature) | one task per feature |
|
|
17
|
+
| BUILD (feature starts) | task -> column `doing` |
|
|
18
|
+
| REVIEW needs-rework / VALIDATE KO | task -> column `blocked` |
|
|
19
|
+
| VALIDATE OK | task -> column `review` |
|
|
20
|
+
| DOC done / feature completed | task -> column `done` |
|
|
21
|
+
|
|
22
|
+
The FD lifecycle columns (`todo|doing|blocked|review|done`) are resolved to the
|
|
23
|
+
project's configured Leantime status ids at call time (statuses are per-project
|
|
24
|
+
ints), with a conservative fallback when the labels cannot be read.
|
|
25
|
+
|
|
26
|
+
## Automatic sync (the leantime-fd-sync hook)
|
|
27
|
+
|
|
28
|
+
You do not call the `byan_leantime_*` tools by hand. A Claude Code `PostToolUse`
|
|
29
|
+
hook (`.claude/hooks/leantime-fd-sync.js`, registered in `.claude/settings.json`)
|
|
30
|
+
fires after `byan_fd_advance` / `byan_fd_update` and applies the table above with
|
|
31
|
+
no agent action:
|
|
32
|
+
|
|
33
|
+
- It reads the fd-state the MCP tool echoes (it does not read or write
|
|
34
|
+
`fd-state.json`) and keeps the Leantime id map in a gitignored sidecar
|
|
35
|
+
`.byan-leantime/map.json` keyed by `fd_id`.
|
|
36
|
+
- The sidecar is the idempotence ledger: a project or task is created only when
|
|
37
|
+
its id is absent, so a REFACTOR loop re-builds without a duplicate.
|
|
38
|
+
- It is best-effort and bounded: it exits 0 in every path (a sync issue does not
|
|
39
|
+
block the turn), no-ops when Leantime is off, and self-heals a dropped call on
|
|
40
|
+
the next phase event (a per-call timeout plus a hook wall-clock budget).
|
|
41
|
+
- It logs every attempt to `.byan-leantime/sync.jsonl` and surfaces a one-line
|
|
42
|
+
notice only on a real failure (`non_json` / `timeout` / `http_*` / `rpc_error`).
|
|
43
|
+
|
|
44
|
+
The pure decision logic lives in
|
|
45
|
+
`_byan/mcp/byan-mcp-server/lib/leantime-fd-core.js` (`decideActions`); the hook is
|
|
46
|
+
a thin I/O shell. Removing the hook from `.claude/settings.json` falls back to the
|
|
47
|
+
manual MCP tools below.
|
|
48
|
+
|
|
49
|
+
### Human visibility (auto-assign)
|
|
50
|
+
|
|
51
|
+
A project created through the API is owned by the API service user, so it stays
|
|
52
|
+
hidden from a person's project selector until that person is related to it. Set
|
|
53
|
+
`LEANTIME_ASSIGN_USER_ID` to your Leantime user id and the hook relates you to the
|
|
54
|
+
created project (and sets you as the default task assignee). The underlying RPC
|
|
55
|
+
(`editUserProjectRelations`) reconciles a user's whole project list, so the assign
|
|
56
|
+
reads your current projects first and writes the union — fail-closed if that read
|
|
57
|
+
is incomplete, to avoid unassigning your other projects.
|
|
58
|
+
|
|
59
|
+
## Configuration
|
|
60
|
+
|
|
61
|
+
Two environment variables drive the integration. They are distinct from
|
|
62
|
+
`BYAN_API_URL` (byan_web) — Leantime is a separate backend.
|
|
63
|
+
|
|
64
|
+
| Var | Role |
|
|
65
|
+
|-----|------|
|
|
66
|
+
| `LEANTIME_API_URL` | Base of the Leantime instance: the host that serves `/api/jsonrpc` (the backend), without a trailing `/api` — the client appends `/api/jsonrpc`. |
|
|
67
|
+
| `LEANTIME_API_TOKEN` | The Leantime API key, sent as the `x-api-key` header. |
|
|
68
|
+
| `LEANTIME_CLIENT_ID` | Optional. clientId for project creation (otherwise the first client returned, else 1). |
|
|
69
|
+
| `LEANTIME_ASSIGN_USER_ID` | Optional. Your Leantime user id; the hook relates you to the created project (so it shows in your selector) and sets you as the default task assignee. Absent -> the project is visible only to the API service user. |
|
|
70
|
+
|
|
71
|
+
Put the secret in `.claude/settings.local.json` (gitignored), out of any tracked
|
|
72
|
+
file:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"env": {
|
|
77
|
+
"LEANTIME_API_URL": "https://your-leantime-host",
|
|
78
|
+
"LEANTIME_API_TOKEN": "lt_xxxxxxxx"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`.mcp.json` references these as `${LEANTIME_API_URL}` / `${LEANTIME_API_TOKEN}`
|
|
84
|
+
(env expansion), so the secret stays out of version control. Reconnect the MCP
|
|
85
|
+
server after editing `settings.local.json`.
|
|
86
|
+
|
|
87
|
+
When the pair is absent, the `byan_leantime_*` tools report `enabled: false` and
|
|
88
|
+
the FD proceeds unchanged.
|
|
89
|
+
|
|
90
|
+
## Generating the Leantime API key
|
|
91
|
+
|
|
92
|
+
Verified against Leantime source (3.7.x). Two credential types, both sent as the
|
|
93
|
+
`x-api-key` header.
|
|
94
|
+
|
|
95
|
+
### API key (service account — recommended for BYAN)
|
|
96
|
+
|
|
97
|
+
1. Log in to Leantime with an Admin or Owner account.
|
|
98
|
+
2. Open **Company Settings** (cogs icon). In a French UI the tab is labeled
|
|
99
|
+
**"Cle d'API"** (i18n key `tabs.apiKeys`), not "API" — a common reason the
|
|
100
|
+
option seems missing.
|
|
101
|
+
3. Click **Generate API Key**, set a role + project scope, then Save.
|
|
102
|
+
4. Copy the secret at once — it is shown one time, then hashed in the database.
|
|
103
|
+
The value carries an `lt_` prefix.
|
|
104
|
+
|
|
105
|
+
Direct URL to the create form: `{host}/api/newApiKey`. A redirect to a 403 there
|
|
106
|
+
means the account is below the role gate (`NewApiKey::run()` requires
|
|
107
|
+
owner/admin); that gate is the usual reason a non-admin user does not see the
|
|
108
|
+
menu.
|
|
109
|
+
|
|
110
|
+
In Leantime an API key is implemented as a service user
|
|
111
|
+
(`zp_user.source='api'`), so there is no separate "api keys" database table.
|
|
112
|
+
|
|
113
|
+
### Personal Access Token (per user)
|
|
114
|
+
|
|
115
|
+
Profile -> "Personal Access Tokens" tab. This tab is present when the Advanced
|
|
116
|
+
Auth plugin is installed (self-hosted). Without it, use the API key above.
|
|
117
|
+
|
|
118
|
+
There is no `.env` flag to enable the API: `/api/jsonrpc` is part of Leantime
|
|
119
|
+
core; the access barrier is the role.
|
|
120
|
+
|
|
121
|
+
## Tools
|
|
122
|
+
|
|
123
|
+
| Tool | Role |
|
|
124
|
+
|------|------|
|
|
125
|
+
| `byan_leantime_ping` | Healthcheck: reports api_url, token_configured, enabled, reachable. Does not throw. |
|
|
126
|
+
| `byan_leantime_project_ensure` | Create-or-fetch a project by name (idempotent), returns the id. |
|
|
127
|
+
| `byan_leantime_task_create` | Create a task from a backlog item, returns the task id. |
|
|
128
|
+
| `byan_leantime_task_move` | Move a task to a column (`todo\|doing\|blocked\|review\|done`). |
|
|
129
|
+
| `byan_leantime_task_assign` | Set the assignee (editorId). |
|
|
130
|
+
| `byan_leantime_task_get` | Read a task by id. |
|
|
131
|
+
| `byan_leantime_board_get` | Read a project board grouped by column. |
|
|
132
|
+
|
|
133
|
+
Every tool except `byan_leantime_ping` is gated by `requireLeantime` (returns a
|
|
134
|
+
clear error when the env pair is absent rather than calling an unconfigured
|
|
135
|
+
host).
|
|
136
|
+
|
|
137
|
+
## Troubleshooting
|
|
138
|
+
|
|
139
|
+
Each call returns `{ ok, synced, reason? }`. A non-synced result surfaces a
|
|
140
|
+
reason instead of pretending the board moved:
|
|
141
|
+
|
|
142
|
+
| reason | meaning + fix |
|
|
143
|
+
|--------|---------------|
|
|
144
|
+
| `no_base` / `no_token` | The integration is off (env not set). Configure the pair. |
|
|
145
|
+
| `non_json` | `LEANTIME_API_URL` points at the Leantime UI host, which returned an HTML login page instead of JSON-RPC. Point it at the backend host that serves `/api/jsonrpc`. |
|
|
146
|
+
| `timeout` / `http_<status>` / `rpc_error` | Transient or wire issue. The FD phase still advances; the move retries at the next phase event. |
|
|
147
|
+
| `create_rejected` | The server returned a falsy id for a create. Inspect the returned data. |
|
|
148
|
+
| `unresolved_status` | A column could not be mapped to a Leantime status id for this project. |
|
|
149
|
+
|
|
150
|
+
## Security
|
|
151
|
+
|
|
152
|
+
The API key lives only in `.claude/settings.local.json` (gitignored at both repo
|
|
153
|
+
and global level). The tracked `.mcp.json` carries only `${...}` placeholders.
|
|
154
|
+
`byan_leantime_ping` reports `token_configured` as a boolean and does not echo
|
|
155
|
+
the token.
|
|
156
|
+
|
|
157
|
+
## See also
|
|
158
|
+
|
|
159
|
+
- Agent-facing reference (compact): `.claude/rules/byan-api.md` section 8.
|
|
160
|
+
- FD wiring (fire points per phase): `.claude/skills/byan-byan/SKILL.md` section 2.5.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-byan-agent",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "BYAN v2.8 - Intelligent AI agent creator with ELO trust system + scientific fact-check + Hermes universal dispatcher + native Claude Code integration (hooks, skills, MCP server). Multi-platform (
|
|
3
|
+
"version": "2.26.0",
|
|
4
|
+
"description": "BYAN v2.8 - Intelligent AI agent creator with ELO trust system + scientific fact-check + Hermes universal dispatcher + native Claude Code integration (hooks, skills, MCP server). Multi-platform (Claude Code, Codex). Merise Agile + TDD + 71 Mantras. ~54% LLM cost savings.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-byan-agent": "./install/bin/create-byan-agent-v2.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"test:watch": "jest --watch",
|
|
18
18
|
"test:e2e": "jest install/__tests__/post-install.e2e.test.js",
|
|
19
19
|
"setup-turbo-whisper": "node install/setup-turbo-whisper.js",
|
|
20
|
-
"byan": "echo \"BYAN agent installed.
|
|
20
|
+
"byan": "echo \"BYAN agent installed. Open Claude Code (or Codex) in this project.\"",
|
|
21
21
|
"version": "node scripts/sync-install-version.js && git add install/package.json",
|
|
22
22
|
"app:dev": "npm --prefix app run dev",
|
|
23
23
|
"app:build": "npm --prefix app run build",
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"ai",
|
|
30
30
|
"multi-agent",
|
|
31
31
|
"workflow",
|
|
32
|
-
"github-copilot",
|
|
33
32
|
"agent-builder",
|
|
34
33
|
"bmad",
|
|
35
34
|
"merise-agile",
|
|
@@ -118,8 +117,5 @@
|
|
|
118
117
|
"statements": 80
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
|
-
},
|
|
122
|
-
"optionalDependencies": {
|
|
123
|
-
"byan-copilot-router": "^1.0.1"
|
|
124
120
|
}
|
|
125
121
|
}
|
|
@@ -23,9 +23,9 @@ class MantraValidator {
|
|
|
23
23
|
this.agentContent = null;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
// Strict-mode artifacts (the byan-strict skill, AGENTS.md block
|
|
27
|
-
//
|
|
28
|
-
//
|
|
26
|
+
// Strict-mode artifacts (the byan-strict skill, AGENTS.md block) are
|
|
27
|
+
// validated against the strict mantra set, not the 64 persona mantras.
|
|
28
|
+
// The set is generated by byan-sync-rules from strict-mode.yaml.
|
|
29
29
|
_loadStrictMantras() {
|
|
30
30
|
try {
|
|
31
31
|
const p = path.join(__dirname, '../data/strict-mantras.json');
|
package/src/byan-v2/index.js
CHANGED
|
@@ -182,16 +182,12 @@ class ByanV2 {
|
|
|
182
182
|
medium: 60
|
|
183
183
|
},
|
|
184
184
|
outputDir: './_byan-output',
|
|
185
|
-
env: customConfig.env ||
|
|
185
|
+
env: customConfig.env || 'standalone'
|
|
186
186
|
};
|
|
187
187
|
|
|
188
188
|
return { ...defaults, ...customConfig };
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
isCopilotContext() {
|
|
192
|
-
return this.config.env === 'copilot' || process.env.GITHUB_COPILOT === 'true';
|
|
193
|
-
}
|
|
194
|
-
|
|
195
191
|
async startSession() {
|
|
196
192
|
this.logger.info('Starting BYAN session', {
|
|
197
193
|
event: 'session_start',
|
|
@@ -9,7 +9,7 @@ const execAsync = promisify(exec);
|
|
|
9
9
|
* VoiceIntegration - Turbo Whisper voice input integration for BYAN v2
|
|
10
10
|
*
|
|
11
11
|
* Enables voice-driven agent interaction through Turbo Whisper transcription.
|
|
12
|
-
* Supports
|
|
12
|
+
* Supports Claude Code and Codex platforms.
|
|
13
13
|
*
|
|
14
14
|
* @version 2.1.0
|
|
15
15
|
* @module integration/voice-integration
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GenerationState - Story 4.4
|
|
3
|
-
* Generates agent profile in BMAD
|
|
4
|
-
*
|
|
3
|
+
* Generates agent profile in BMAD format
|
|
4
|
+
*
|
|
5
5
|
* Format:
|
|
6
6
|
* - YAML frontmatter (name, description)
|
|
7
7
|
* - XML structure (<agent>, <persona>, <menu>, <capabilities>)
|
|
8
|
-
* -
|
|
8
|
+
* - Saved under the _byan/agent/ layout
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const Logger = require('../observability/logger');
|
|
@@ -178,7 +178,7 @@ class GenerationState {
|
|
|
178
178
|
*/
|
|
179
179
|
getDefaultSavePath() {
|
|
180
180
|
const name = this.sessionState.agentProfileDraft?.name || 'agent';
|
|
181
|
-
return
|
|
181
|
+
return `_byan/agent/${name}/${name}.md`;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
/**
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Integration with RateLimitTracker + SharedStateStore + SessionBridge
|
|
9
9
|
*
|
|
10
10
|
* Sits ABOVE existing BYAN routers:
|
|
11
|
-
* LoadBalancer (picks PLATFORM) →
|
|
11
|
+
* LoadBalancer (picks PLATFORM) → byan_dispatch (picks STRATEGY + model TIER)
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
const { EventEmitter } = require('events');
|
package/src/staging/staging.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BYAN staging core — extract / filter / dedup / queue / flush conversation
|
|
3
|
-
* knowledge from any supported CLI (claude-code,
|
|
3
|
+
* knowledge from any supported CLI (claude-code, codex) to a
|
|
4
4
|
* byan_web instance via POST /api/memory.
|
|
5
5
|
*
|
|
6
6
|
* Usage from a Claude Code Stop hook :
|
|
7
7
|
* const { processTurn } = require('./staging');
|
|
8
8
|
* await processTurn({ turn, cliSource: 'claude-code', config, projectRoot });
|
|
9
9
|
*
|
|
10
|
-
* Usage from a Copilot CLI extension.mjs :
|
|
11
|
-
* import { processTurn } from '<repo>/src/staging/staging.js';
|
|
12
|
-
* await processTurn({ turn, cliSource: 'copilot-cli', config, projectRoot });
|
|
13
|
-
*
|
|
14
10
|
* Contract :
|
|
15
11
|
* - processTurn() is idempotent (dedup by content hash)
|
|
16
12
|
* - never throws — errors go to the retry queue
|
|
@@ -304,7 +300,25 @@ async function postEntry({ entry, url, token, projectId }) {
|
|
|
304
300
|
err.status = res.status;
|
|
305
301
|
throw err;
|
|
306
302
|
}
|
|
307
|
-
|
|
303
|
+
// A 2xx is necessary but not sufficient: an authentik/SSO proxy answers an
|
|
304
|
+
// unauthenticated API call with 200 + an HTML login page. Swallowing that as
|
|
305
|
+
// success (the old res.json().catch(()=>({}))) silently drops the turn while
|
|
306
|
+
// reporting "flushed". Require the body to actually parse as JSON; otherwise
|
|
307
|
+
// treat it as a failure so it surfaces as a visible last_error in the queue.
|
|
308
|
+
const text = await res.text();
|
|
309
|
+
// An empty 2xx body (e.g. 204 No Content) is a benign success, not a wall —
|
|
310
|
+
// the SSO wall always carries an HTML body. Do not invert it into a failure.
|
|
311
|
+
if (!text || !text.trim()) return {};
|
|
312
|
+
try {
|
|
313
|
+
return JSON.parse(text);
|
|
314
|
+
} catch {
|
|
315
|
+
const ct = res.headers.get('content-type') || 'none';
|
|
316
|
+
const err = new Error(
|
|
317
|
+
`non-JSON 2xx (likely an auth/SSO wall; content-type ${ct}): ${text.slice(0, 120).replace(/\s+/g, ' ')}`
|
|
318
|
+
);
|
|
319
|
+
err.status = res.status;
|
|
320
|
+
throw err;
|
|
321
|
+
}
|
|
308
322
|
}
|
|
309
323
|
|
|
310
324
|
async function flush({ config, projectRoot, maxAttempts = 5 } = {}) {
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Build Copilot CLI agent stubs from BYAN source files.
|
|
5
|
-
*
|
|
6
|
-
* Copilot CLI treats .github/agents/*.md as system instructions.
|
|
7
|
-
* It does NOT dynamically load files referenced in the content.
|
|
8
|
-
* This script inlines the full agent + soul + tao content into
|
|
9
|
-
* each stub so Copilot CLI has everything it needs.
|
|
10
|
-
*
|
|
11
|
-
* Usage: node build-copilot-stubs.js [--agent byan] [--all]
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const fs = require('fs');
|
|
15
|
-
const path = require('path');
|
|
16
|
-
const layoutResolver = require('../../src/byan-v2/lib/layout-resolver');
|
|
17
|
-
|
|
18
|
-
const ROOT = path.resolve(__dirname, '..', '..');
|
|
19
|
-
const AGENTS_DIR = path.join(ROOT, '.github', 'agents');
|
|
20
|
-
const BYAN_DIR = path.join(ROOT, '_byan');
|
|
21
|
-
|
|
22
|
-
function readFile(filePath) {
|
|
23
|
-
try {
|
|
24
|
-
return fs.readFileSync(filePath, 'utf-8');
|
|
25
|
-
} catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function stripFrontmatter(content) {
|
|
31
|
-
return content.replace(/^---\s*\n[\s\S]*?\n---\s*\n?/, '');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function buildByanStub() {
|
|
35
|
-
// Layout resolver: Gen3 _byan/agent/byan/ first, Gen2 fallback.
|
|
36
|
-
const agentHit = layoutResolver.resolveAgent('byan', { projectRoot: ROOT });
|
|
37
|
-
const agentContent = agentHit ? readFile(agentHit.path) : null;
|
|
38
|
-
if (!agentContent) {
|
|
39
|
-
console.error('Cannot find the byan agent file (looked in Gen3 _byan/agent/byan/ and Gen2 layouts)');
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const soulHit = layoutResolver.resolveSoul('soul', { projectRoot: ROOT });
|
|
44
|
-
const taoHit = layoutResolver.resolveSoul('tao', { projectRoot: ROOT });
|
|
45
|
-
const soulContent = soulHit ? readFile(soulHit.path) : null;
|
|
46
|
-
const taoContent = taoHit ? readFile(taoHit.path) : null;
|
|
47
|
-
const soulActivation = readFile(path.join(BYAN_DIR, 'core', 'activation', 'soul-activation.md'));
|
|
48
|
-
|
|
49
|
-
const agentBody = stripFrontmatter(agentContent);
|
|
50
|
-
const soulBody = soulContent ? stripFrontmatter(soulContent) : '';
|
|
51
|
-
const taoBody = taoContent ? stripFrontmatter(taoContent) : '';
|
|
52
|
-
const activationBody = soulActivation ? stripFrontmatter(soulActivation) : '';
|
|
53
|
-
|
|
54
|
-
const stub = `---
|
|
55
|
-
name: 'byan'
|
|
56
|
-
description: 'BYAN - Builder of YAN - Agent Creator Specialist'
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
${agentBody}
|
|
60
|
-
|
|
61
|
-
<!-- ============================================================ -->
|
|
62
|
-
<!-- INLINED: Soul System (soul.md + tao.md + soul-activation.md) -->
|
|
63
|
-
<!-- ============================================================ -->
|
|
64
|
-
|
|
65
|
-
<soul-system>
|
|
66
|
-
|
|
67
|
-
<!-- soul.md -->
|
|
68
|
-
${soulBody}
|
|
69
|
-
|
|
70
|
-
<!-- tao.md -->
|
|
71
|
-
${taoBody}
|
|
72
|
-
|
|
73
|
-
<!-- soul-activation.md -->
|
|
74
|
-
${activationBody}
|
|
75
|
-
|
|
76
|
-
</soul-system>
|
|
77
|
-
`;
|
|
78
|
-
|
|
79
|
-
const outPath = path.join(AGENTS_DIR, 'bmad-agent-byan.md');
|
|
80
|
-
fs.writeFileSync(outPath, stub, 'utf-8');
|
|
81
|
-
|
|
82
|
-
const size = Buffer.byteLength(stub, 'utf-8');
|
|
83
|
-
console.log(`Built: ${outPath} (${(size / 1024).toFixed(1)} KB)`);
|
|
84
|
-
return outPath;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function buildModuleAgentStub(agentName, moduleName) {
|
|
88
|
-
// Resolve the agent across layouts (Gen3 _byan/agent/<name>/, Gen2 flat +
|
|
89
|
-
// per-module); fall back to the explicit module path passed on the CLI.
|
|
90
|
-
const agentHit = layoutResolver.resolveAgent(agentName, { projectRoot: ROOT });
|
|
91
|
-
const agentPath = agentHit ? agentHit.path : path.join(BYAN_DIR, moduleName, 'agents', `${agentName}.md`);
|
|
92
|
-
const agentContent = readFile(agentPath);
|
|
93
|
-
if (!agentContent) {
|
|
94
|
-
console.error(`Cannot read agent ${agentName} (looked via resolver and ${path.relative(ROOT, agentPath)})`);
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const agentBody = stripFrontmatter(agentContent);
|
|
99
|
-
|
|
100
|
-
// Soul sibling lives next to the resolved agent file.
|
|
101
|
-
const soulPath = path.join(path.dirname(agentPath), `${agentName}-soul.md`);
|
|
102
|
-
const soulContent = readFile(soulPath);
|
|
103
|
-
const soulSection = soulContent ? `\n<!-- soul: ${agentName}-soul.md -->\n${stripFrontmatter(soulContent)}\n` : '';
|
|
104
|
-
|
|
105
|
-
const stub = `---
|
|
106
|
-
name: '${agentName}'
|
|
107
|
-
description: '${agentName} agent'
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
${agentBody}
|
|
111
|
-
${soulSection}
|
|
112
|
-
`;
|
|
113
|
-
|
|
114
|
-
const outPath = path.join(AGENTS_DIR, `bmad-agent-${agentName}.md`);
|
|
115
|
-
fs.writeFileSync(outPath, stub, 'utf-8');
|
|
116
|
-
|
|
117
|
-
const size = Buffer.byteLength(stub, 'utf-8');
|
|
118
|
-
console.log(`Built: ${outPath} (${(size / 1024).toFixed(1)} KB)`);
|
|
119
|
-
return outPath;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// --- CLI ---
|
|
123
|
-
const args = process.argv.slice(2);
|
|
124
|
-
const agentArg = args.indexOf('--agent') >= 0 ? args[args.indexOf('--agent') + 1] : null;
|
|
125
|
-
const buildAll = args.includes('--all');
|
|
126
|
-
|
|
127
|
-
if (agentArg === 'byan' || buildAll || args.length === 0) {
|
|
128
|
-
buildByanStub();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (agentArg && agentArg !== 'byan') {
|
|
132
|
-
const mod = args.indexOf('--module') >= 0 ? args[args.indexOf('--module') + 1] : 'bmm';
|
|
133
|
-
buildModuleAgentStub(agentArg, mod);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (buildAll || args.length === 0) {
|
|
137
|
-
console.log('\nDone. Run this after editing _byan/agents/byan.md, soul.md, or tao.md.');
|
|
138
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GitHub Copilot CLI Platform Support
|
|
3
|
-
*
|
|
4
|
-
* Detects and installs agents for GitHub Copilot CLI.
|
|
5
|
-
*
|
|
6
|
-
* @module platforms/copilot-cli
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const fileUtils = require('../utils/file-utils');
|
|
11
|
-
const yamlUtils = require('../utils/yaml-utils');
|
|
12
|
-
const { execSync } = require('child_process');
|
|
13
|
-
|
|
14
|
-
const PLATFORM_NAME = 'GitHub Copilot CLI';
|
|
15
|
-
const STUB_DIR = '.github/agents';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Detect if Copilot CLI is installed
|
|
19
|
-
*
|
|
20
|
-
* With 10s timeout protection to prevent hanging.
|
|
21
|
-
*
|
|
22
|
-
* @returns {Promise<boolean|{detected: boolean, error: string}>}
|
|
23
|
-
*/
|
|
24
|
-
async function detect() {
|
|
25
|
-
// Timeout promise (10 seconds)
|
|
26
|
-
const timeoutPromise = new Promise((resolve) =>
|
|
27
|
-
setTimeout(() => resolve({
|
|
28
|
-
detected: false,
|
|
29
|
-
error: 'Detection timeout after 10s'
|
|
30
|
-
}), 10000)
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
// Detection promise
|
|
34
|
-
const detectionPromise = (async () => {
|
|
35
|
-
try {
|
|
36
|
-
// Check if github-copilot-cli is installed
|
|
37
|
-
execSync('which github-copilot-cli', { encoding: 'utf8', stdio: 'ignore' });
|
|
38
|
-
return true;
|
|
39
|
-
} catch {
|
|
40
|
-
// Also check for .github/agents/ directory
|
|
41
|
-
return fileUtils.exists(STUB_DIR);
|
|
42
|
-
}
|
|
43
|
-
})();
|
|
44
|
-
|
|
45
|
-
// Race between detection and timeout
|
|
46
|
-
return Promise.race([detectionPromise, timeoutPromise]);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Install agents for Copilot CLI
|
|
51
|
-
*
|
|
52
|
-
* @param {string} projectRoot - Project root directory
|
|
53
|
-
* @param {string[]} agents - Agent names to install
|
|
54
|
-
* @param {Object} config - Installation config
|
|
55
|
-
* @returns {Promise<{success: boolean, installed: number}>}
|
|
56
|
-
*/
|
|
57
|
-
async function install(projectRoot, agents, config) {
|
|
58
|
-
const stubsDir = path.join(projectRoot, STUB_DIR);
|
|
59
|
-
await fileUtils.ensureDir(stubsDir);
|
|
60
|
-
|
|
61
|
-
let installed = 0;
|
|
62
|
-
|
|
63
|
-
for (const agentName of agents) {
|
|
64
|
-
await generateStub(stubsDir, agentName, config);
|
|
65
|
-
installed++;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
success: true,
|
|
70
|
-
installed
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Generate Copilot CLI stub with YAML frontmatter
|
|
76
|
-
*
|
|
77
|
-
* @param {string} stubsDir - Stubs directory path
|
|
78
|
-
* @param {string} agentName - Agent name
|
|
79
|
-
* @param {Object} config - Installation config
|
|
80
|
-
* @returns {Promise<void>}
|
|
81
|
-
*/
|
|
82
|
-
async function generateStub(stubsDir, agentName, config) {
|
|
83
|
-
const stubPath = path.join(stubsDir, `${agentName}.md`);
|
|
84
|
-
|
|
85
|
-
const frontmatter = {
|
|
86
|
-
name: agentName,
|
|
87
|
-
description: `${agentName} agent from BYAN platform`
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const content = `---
|
|
91
|
-
${yamlUtils.dump(frontmatter).trim()}
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
|
95
|
-
|
|
96
|
-
<agent-activation CRITICAL="TRUE">
|
|
97
|
-
1. LOAD the FULL agent file from {project-root}/_byan/agent/${agentName}/${agentName}.md (new layout); if absent, {project-root}/_byan/*/agents/${agentName}.md (legacy layout)
|
|
98
|
-
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
|
99
|
-
3. FOLLOW every step in the <activation> section precisely
|
|
100
|
-
4. DISPLAY the welcome/greeting as instructed
|
|
101
|
-
5. PRESENT the numbered menu
|
|
102
|
-
6. WAIT for user input before proceeding
|
|
103
|
-
</agent-activation>
|
|
104
|
-
`;
|
|
105
|
-
|
|
106
|
-
await fileUtils.writeFile(stubPath, content);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Get platform installation path
|
|
111
|
-
*
|
|
112
|
-
* @returns {string}
|
|
113
|
-
*/
|
|
114
|
-
function getPath() {
|
|
115
|
-
return STUB_DIR;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
module.exports = {
|
|
119
|
-
name: PLATFORM_NAME,
|
|
120
|
-
detect,
|
|
121
|
-
install,
|
|
122
|
-
getPath
|
|
123
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VSCode Copilot Extension Platform Support
|
|
3
|
-
*
|
|
4
|
-
* Detects and installs agents for VSCode Copilot Extension.
|
|
5
|
-
* Same format as Copilot CLI.
|
|
6
|
-
*
|
|
7
|
-
* @module platforms/vscode
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const copilotCli = require('./copilot-cli');
|
|
11
|
-
|
|
12
|
-
const PLATFORM_NAME = 'VSCode Copilot Extension';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Detect if VSCode with Copilot extension is installed
|
|
16
|
-
*
|
|
17
|
-
* @returns {Promise<boolean>}
|
|
18
|
-
*/
|
|
19
|
-
async function detect() {
|
|
20
|
-
// VSCode uses same stub format as Copilot CLI
|
|
21
|
-
return copilotCli.detect();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Install agents for VSCode
|
|
26
|
-
*
|
|
27
|
-
* @param {string} projectRoot - Project root directory
|
|
28
|
-
* @param {string[]} agents - Agent names to install
|
|
29
|
-
* @param {Object} config - Installation config
|
|
30
|
-
* @returns {Promise<{success: boolean, installed: number}>}
|
|
31
|
-
*/
|
|
32
|
-
async function install(projectRoot, agents, config) {
|
|
33
|
-
// Reuse Copilot CLI installation (same format)
|
|
34
|
-
return copilotCli.install(projectRoot, agents, config);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get platform installation path
|
|
39
|
-
*
|
|
40
|
-
* @returns {string}
|
|
41
|
-
*/
|
|
42
|
-
function getPath() {
|
|
43
|
-
return copilotCli.getPath();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
module.exports = {
|
|
47
|
-
name: PLATFORM_NAME,
|
|
48
|
-
detect,
|
|
49
|
-
install,
|
|
50
|
-
getPath
|
|
51
|
-
};
|