create-byan-agent 2.35.0 → 2.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +203 -0
  2. package/install/bin/create-byan-agent-v2.js +15 -0
  3. package/install/lib/claude-native-setup.js +12 -38
  4. package/install/lib/platforms/claude-code.js +28 -19
  5. package/install/package.json +1 -1
  6. package/install/packages/platform-config/lib/mcp-config.js +71 -5
  7. package/install/templates/.claude/CLAUDE.md +1 -0
  8. package/install/templates/.claude/hooks/inject-delivery-default.js +46 -0
  9. package/install/templates/.claude/hooks/leantime-fd-sync.js +12 -1
  10. package/install/templates/.claude/hooks/lib/delivery-contract.js +143 -0
  11. package/install/templates/.claude/hooks/lib/punt-detect.js +143 -0
  12. package/install/templates/.claude/hooks/lib/strict-config.json +14 -0
  13. package/install/templates/.claude/hooks/punt-guard.js +126 -0
  14. package/install/templates/.claude/hooks/strict-stop-guard.js +29 -6
  15. package/install/templates/.claude/settings.json +8 -0
  16. package/install/templates/.claude/skills/byan-strict/SKILL.md +9 -0
  17. package/install/templates/.githooks/pre-commit +18 -0
  18. package/install/templates/_byan/_config/delivery-default.json +22 -0
  19. package/install/templates/_byan/_config/strict-mode.yaml +25 -0
  20. package/install/templates/_byan/agent/byan/byan-soul.md +40 -0
  21. package/install/templates/_byan/mcp/byan-mcp-server/channel-entry.js +46 -0
  22. package/install/templates/_byan/mcp/byan-mcp-server/lib/channel-poll.js +128 -0
  23. package/install/templates/_byan/mcp/byan-mcp-server/lib/channel-server.js +234 -0
  24. package/install/templates/_byan/mcp/byan-mcp-server/lib/completeness-evidence.js +159 -0
  25. package/install/templates/_byan/mcp/byan-mcp-server/lib/leantime-fd-core.js +60 -2
  26. package/install/templates/_byan/mcp/byan-mcp-server/lib/leantime-sync.js +4 -1
  27. package/install/templates/_byan/mcp/byan-mcp-server/lib/precommit-gate.js +68 -2
  28. package/install/templates/_byan/mcp/byan-mcp-server/lib/strict-mode.js +78 -1
  29. package/install/templates/_byan/mcp/byan-mcp-server/lib/sync-rules.js +40 -2
  30. package/install/templates/_byan/mcp/byan-mcp-server/skill-bundles-manifest.json +1 -1
  31. package/install/templates/dist/skill-bundles/byan-strict.zip +0 -0
  32. package/install/templates/docs/leantime-integration.md +11 -1
  33. package/node_modules/byan-platform-config/lib/mcp-config.js +71 -5
  34. package/package.json +1 -1
  35. package/install/templates/.mcp.json.tmpl +0 -8
@@ -1,6 +1,66 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
1
3
  import { getStatus, MIN_PASSES } from './strict-mode.js';
2
4
  import { fetchSession, syncEnabled } from './strict-sync.js';
3
5
 
6
+ // F2 (additive): the completeness-evidence gate at commit time. Reads the
7
+ // completeness ledger written by strict complete(). It only ever BLOCKS when
8
+ // delivery-default.json completenessGate.armed === true (default false). With
9
+ // the gate disarmed this is a no-op and the gate decision is exactly as before.
10
+ const DELIVERY_CONFIG_REL = path.join('_byan', '_config', 'delivery-default.json');
11
+ const COMPLETENESS_LEDGER_REL = path.join('_byan-output', 'completeness-ledger.jsonl');
12
+
13
+ function completenessGateArmed(projectRoot) {
14
+ try {
15
+ const p = path.join(projectRoot || process.cwd(), DELIVERY_CONFIG_REL);
16
+ if (!fs.existsSync(p)) return false;
17
+ const cfg = JSON.parse(fs.readFileSync(p, 'utf8'));
18
+ return !!(cfg && cfg.completenessGate && cfg.completenessGate.armed === true);
19
+ } catch {
20
+ return false; // A broken/absent config never arms the gate.
21
+ }
22
+ }
23
+
24
+ // Last completeness-ledger entry for the given scope_hash, or null. Best-effort.
25
+ function lastCompletenessEntry(projectRoot, scopeHash) {
26
+ try {
27
+ const p = path.join(projectRoot || process.cwd(), COMPLETENESS_LEDGER_REL);
28
+ if (!fs.existsSync(p)) return null;
29
+ const lines = fs
30
+ .readFileSync(p, 'utf8')
31
+ .split('\n')
32
+ .filter((l) => l.trim());
33
+ for (let i = lines.length - 1; i >= 0; i--) {
34
+ try {
35
+ const e = JSON.parse(lines[i]);
36
+ if (!scopeHash || e.scope_hash === scopeHash) return e;
37
+ } catch {
38
+ // skip a malformed line
39
+ }
40
+ }
41
+ } catch {
42
+ // unreadable ledger -> treat as no evidence record
43
+ }
44
+ return null;
45
+ }
46
+
47
+ // Pure overlay: given a base decision (PASS), apply the armed completeness gate.
48
+ // Returns the base decision untouched when disarmed or when the base already
49
+ // blocks; otherwise blocks when the completeness ledger shows missing criteria.
50
+ export function applyCompletenessGate(base, { armed, entry }) {
51
+ if (!base.pass || !armed) return base;
52
+ if (entry && Array.isArray(entry.missing) && entry.missing.length) {
53
+ return {
54
+ pass: false,
55
+ reason:
56
+ `Completeness gate ARMED: the completed strict session left ` +
57
+ `${entry.missing.length} code-shaped criteria without evidence ` +
58
+ `(${entry.missing.join('; ')}). Provide the artifacts before committing.`,
59
+ };
60
+ }
61
+ return base;
62
+ }
63
+
4
64
  // BYAN Strict Mode pre-commit gate.
5
65
  //
6
66
  // The final, platform-agnostic net. Claude Code has in-session hooks; Codex
@@ -104,6 +164,7 @@ export async function evaluateGate({ projectRoot, fetchImpl } = {}) {
104
164
  const local = getStatus({ projectRoot });
105
165
  const normalizedLocal = normalizeLocal(local);
106
166
 
167
+ let base;
107
168
  // Consult the authority when there is a session to check and a token is set.
108
169
  if (normalizedLocal.sessionId && syncEnabled()) {
109
170
  const remote = await fetchSession(
@@ -111,10 +172,15 @@ export async function evaluateGate({ projectRoot, fetchImpl } = {}) {
111
172
  fetchImpl ? { fetchImpl } : {}
112
173
  );
113
174
  if (remote.ok && remote.data) {
114
- return decide(normalizeApi(remote.data));
175
+ base = decide(normalizeApi(remote.data));
115
176
  }
116
177
  // API unreachable / not found -> fall back to local mirror.
117
178
  }
179
+ if (!base) base = decide(normalizedLocal);
118
180
 
119
- return decide(normalizedLocal);
181
+ // F2 overlay: disarmed by default -> returns `base` unchanged.
182
+ const armed = completenessGateArmed(projectRoot);
183
+ if (!armed) return base;
184
+ const entry = lastCompletenessEntry(projectRoot, local.scope_hash);
185
+ return applyCompletenessGate(base, { armed, entry });
120
186
  }
@@ -1,12 +1,50 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import crypto from 'node:crypto';
4
+ import { buildEvidence } from './completeness-evidence.js';
4
5
 
5
6
  const STRICT_DIR = '.byan-strict';
6
7
  const STATE_FILE = 'state.json';
7
8
  const AUDIT_FILE = 'audit.log';
8
9
  const MIN_SELF_VERIFY_PASSES = 3;
9
10
 
11
+ // F2 completeness-evidence gate. complete() ATTACHES an evidence report and, when
12
+ // the gate is ARMED (delivery-default.json completenessGate.armed === true),
13
+ // hard-rejects a completion that leaves code-shaped criteria without evidence.
14
+ // Default DISARMED: complete() behaves exactly as before (passCount >= 3 + last
15
+ // verdict ok), the report is pure observation, and every completion appends one
16
+ // line to the completeness ledger so arming later is data-informed.
17
+ const DELIVERY_CONFIG_REL = path.join('_byan', '_config', 'delivery-default.json');
18
+ const COMPLETENESS_LEDGER_REL = path.join('_byan-output', 'completeness-ledger.jsonl');
19
+
20
+ function readDeliveryConfig(projectRoot) {
21
+ try {
22
+ const p = path.join(resolveRoot(projectRoot), DELIVERY_CONFIG_REL);
23
+ if (fs.existsSync(p)) {
24
+ const cfg = JSON.parse(fs.readFileSync(p, 'utf8'));
25
+ if (cfg && typeof cfg === 'object') return cfg;
26
+ }
27
+ } catch {
28
+ // A broken config must NOT arm the gate — fail safe toward disarmed.
29
+ }
30
+ return {};
31
+ }
32
+
33
+ function completenessGateArmed(config) {
34
+ const g = config && config.completenessGate;
35
+ return !!(g && g.armed === true);
36
+ }
37
+
38
+ function appendCompletenessLedger(entry, projectRoot) {
39
+ try {
40
+ const p = path.join(resolveRoot(projectRoot), COMPLETENESS_LEDGER_REL);
41
+ fs.mkdirSync(path.dirname(p), { recursive: true });
42
+ fs.appendFileSync(p, JSON.stringify(entry) + '\n');
43
+ } catch {
44
+ // The observation ledger is best-effort — never break completion.
45
+ }
46
+ }
47
+
10
48
  function resolveRoot(projectRoot) {
11
49
  return projectRoot || process.env.CLAUDE_PROJECT_DIR || process.cwd();
12
50
  }
@@ -234,7 +272,7 @@ export function selfVerify({
234
272
  };
235
273
  }
236
274
 
237
- export function complete({ projectRoot, now = new Date() } = {}) {
275
+ export function complete({ projectRoot, now = new Date(), context = {}, evidenceIo } = {}) {
238
276
  const state = readState(projectRoot);
239
277
  if (!state || !state.active) {
240
278
  throw new Error('No active strict session.');
@@ -258,6 +296,42 @@ export function complete({ projectRoot, now = new Date() } = {}) {
258
296
  );
259
297
  }
260
298
 
299
+ // F2 (additive): collect the completeness-evidence report over the locked
300
+ // criteria + allowed paths. Always observed + ledgered; only ENFORCED when the
301
+ // gate is armed in delivery-default.json (default false -> behaviour unchanged).
302
+ const deliveryConfig = readDeliveryConfig(projectRoot);
303
+ const gateArmed = completenessGateArmed(deliveryConfig);
304
+ const evidence = buildEvidence({
305
+ criteria: state.scope_lock.acceptance_criteria || [],
306
+ allowedPaths: state.scope_lock.allowed_paths || [],
307
+ context,
308
+ projectRoot: resolveRoot(projectRoot),
309
+ io: evidenceIo,
310
+ });
311
+ appendCompletenessLedger(
312
+ {
313
+ ts: now.toISOString(),
314
+ event: gateArmed ? (evidence.missing.length ? 'would-reject' : 'pass') : 'observed-disarmed',
315
+ strict_session_id: state.strict_session_id,
316
+ scope_hash: state.scope_lock.scope_hash,
317
+ armed: gateArmed,
318
+ missing: evidence.missing,
319
+ per_criterion: evidence.perCriterion.map((c) => ({
320
+ criterion: c.criterion,
321
+ kind: c.kind,
322
+ hasEvidence: c.hasEvidence,
323
+ })),
324
+ },
325
+ projectRoot
326
+ );
327
+ if (gateArmed && evidence.missing.length) {
328
+ throw new Error(
329
+ `Cannot complete: completeness gate is ARMED and ${evidence.missing.length} ` +
330
+ `code-shaped criteria have no evidence (file / green test / diff): ` +
331
+ `${evidence.missing.join('; ')}. Provide the missing artifacts or re-lock the scope.`
332
+ );
333
+ }
334
+
261
335
  const auditEntries = readAuditLog(projectRoot);
262
336
  const auditPayload = JSON.stringify({
263
337
  scope_hash: state.scope_lock.scope_hash,
@@ -296,6 +370,9 @@ export function complete({ projectRoot, now = new Date() } = {}) {
296
370
  // Surfaced for the C3 learning-loop feed: an explicit ELO domain on the
297
371
  // locked scope means a completed session is a VALIDATED outcome.
298
372
  domain: state.scope_lock.domain || '',
373
+ // F2 (additive): the completeness-evidence report. Attached whether or not
374
+ // the gate is armed; with the gate disarmed it is pure observation.
375
+ evidence,
299
376
  };
300
377
  }
301
378
 
@@ -83,6 +83,15 @@ export function renderStrictConfig(cfg) {
83
83
  version: cfg.version,
84
84
  min_passes: cfg.self_verify.min_passes,
85
85
  last_verdict_must_be: cfg.self_verify.last_verdict_must_be,
86
+ // Measured recurring self-verify blind spots (from byan_insight_digest).
87
+ // Carried into the runtime config so a hook/UI can surface them at verify
88
+ // time; [] when the YAML omits the block (older source stays valid).
89
+ self_verify_checklist: Array.isArray(cfg.self_verify.checklist)
90
+ ? cfg.self_verify.checklist.map((c) => ({
91
+ theme: c.theme,
92
+ check: String(c.check || '').trim(),
93
+ }))
94
+ : [],
86
95
  min_score: cfg.confidence.min_score,
87
96
  auto_keywords: cfg.activation.auto_keywords,
88
97
  completion_claim_markers: cfg.hooks.completion_claim_markers,
@@ -102,6 +111,16 @@ function mantraLines(cfg) {
102
111
  .join('\n');
103
112
  }
104
113
 
114
+ // Renders the measured self-verify checklist (cfg.self_verify.checklist) as
115
+ // markdown bullets. Empty string when the block is absent, so an older config
116
+ // simply omits the section rather than emitting an empty header.
117
+ function checklistLines(cfg) {
118
+ const items = Array.isArray(cfg.self_verify.checklist) ? cfg.self_verify.checklist : [];
119
+ return items
120
+ .map((c) => `- **${c.theme}** — ${String(c.check || '').trim()}`)
121
+ .join('\n');
122
+ }
123
+
105
124
  // Projects the strict mantras into the shape the MantraValidator consumes
106
125
  // (mirrors src/byan-v2/data/mantras.json). Lets the pre-commit mantra gate
107
126
  // score strict artifacts against the strict ruleset instead of the persona one.
@@ -168,7 +187,18 @@ complete. Downgrading the scope is the failure this mode exists to prevent.
168
187
  4. **Complete** with \`byan_strict_complete\` to earn the audit token. Without it,
169
188
  the pre-commit gate blocks the commit.
170
189
 
171
- ## Hard claims
190
+ ${
191
+ checklistLines(cfg)
192
+ ? `## Self-verify checklist
193
+
194
+ Measured recurring blind spots (harvested by \`byan_insight_digest\`). Check these
195
+ each self-verify pass, on top of the locked acceptance criteria:
196
+
197
+ ${checklistLines(cfg)}
198
+
199
+ `
200
+ : ''
201
+ }## Hard claims
172
202
 
173
203
  Claims in security, performance, or compliance need LEVEL-1 sourcing
174
204
  (${cfg.confidence.min_score}%) or they are BLOCKED.
@@ -189,7 +219,15 @@ The strict tools (\`byan_strict_lock_scope\`, \`byan_strict_self_verify\`,
189
219
  by the \`byan\` MCP server. A commit without a fresh, matching audit token is
190
220
  blocked by the pre-commit gate.
191
221
 
192
- Hard mantras:
222
+ ${
223
+ checklistLines(cfg)
224
+ ? `Self-verify checklist (measured recurring blind spots — check each pass):
225
+
226
+ ${checklistLines(cfg)}
227
+
228
+ `
229
+ : ''
230
+ }Hard mantras:
193
231
 
194
232
  ${mantraLines(cfg)}`;
195
233
  }
@@ -244,7 +244,7 @@
244
244
  "name": "byan-strict",
245
245
  "module": "core",
246
246
  "tier": "connector-bound",
247
- "sourceHash": "e8e0ac502220056a5057d2801ad5a512ce2bc7e54c08d9bc1844419d93ff58a6"
247
+ "sourceHash": "f9fb75d4fbd93ec8b624a61369b205889cd27c79cf2a5701e67a1619af60d0b0"
248
248
  },
249
249
  "byan-suitability": {
250
250
  "name": "byan-suitability",
@@ -13,7 +13,7 @@ events:
13
13
  | FD phase / event | Effect on the board |
14
14
  |------------------|---------------------|
15
15
  | DISCOVERY (project confirmed) | create-or-fetch the Leantime project |
16
- | DISPATCH (per backlog feature) | one task per feature |
16
+ | DISPATCH (per backlog feature) | one task per feature, with effort (storypoints), priority and a description |
17
17
  | BUILD (feature starts) | task -> column `doing` |
18
18
  | REVIEW needs-rework / VALIDATE KO | task -> column `blocked` |
19
19
  | VALIDATE OK | task -> column `review` |
@@ -23,6 +23,16 @@ The FD lifecycle columns (`todo|doing|blocked|review|done`) are resolved to the
23
23
  project's configured Leantime status ids at call time (statuses are per-project
24
24
  ints), with a conservative fallback when the labels cannot be read.
25
25
 
26
+ Each created task also carries the BYAN signal, not just a bare title:
27
+
28
+ - **effort** -- `storypoints` from the feature's complexity: a finite `complexity`
29
+ (0-100) bucketed on the Fibonacci scale (`<=15->2`, `16-39->5`, `40-69->8`,
30
+ `>=70->13`), else derived from priority (`P1->8`, `P2->5`, `P3->3`, default 3).
31
+ - **priority** -- `P1`/`P2`/`P3` mapped to Leantime `3`/`2`/`1` (omitted when unknown).
32
+ - **description** -- `BYAN FD <id> -- <headline>`, plus `[complexity:N]` when known.
33
+ It also carries the complexity if the Leantime effort field name differs from
34
+ the presumed `storypoints` (a `[UNVERIFIED]` wire detail, see Troubleshooting).
35
+
26
36
  ## Automatic sync (the leantime-fd-sync hook)
27
37
 
28
38
  You do not call the `byan_leantime_*` tools by hand. A Claude Code `PostToolUse`
@@ -27,6 +27,13 @@ const path = require('path');
27
27
  const fs = require('fs-extra');
28
28
 
29
29
  const MCP_SERVER_REL_PATH = '_byan/mcp/byan-mcp-server/server.js';
30
+ // Channel entrypoint: a SEPARATE MCP server (research preview) spawned by Claude
31
+ // Code via --dangerously-load-development-channels. Same relative-path discipline
32
+ // as the main server (relative to projectRoot, never absolute) so the entry is
33
+ // portable across machines/OSes and stays valid when the repo is moved or shipped
34
+ // via npm. The entry is INERT by default: registering it in .mcp.json does NOT
35
+ // enable the channel (that needs the explicit --dangerously-load flag at launch).
36
+ const MCP_CHANNEL_REL_PATH = '_byan/mcp/byan-mcp-server/channel-entry.js';
30
37
  const TOKEN_PLACEHOLDER = '${BYAN_API_TOKEN}';
31
38
  const LEANTIME_URL_PLACEHOLDER = '${LEANTIME_API_URL}';
32
39
  const LEANTIME_TOKEN_PLACEHOLDER = '${LEANTIME_API_TOKEN}';
@@ -87,15 +94,66 @@ function mergeByanEntry(existingConfig, { apiUrl, token } = {}) {
87
94
  delete env.BYAN_API_URL;
88
95
  delete env.BYAN_API_TOKEN;
89
96
 
97
+ // The canonical RELATIVE path is forced on `args` AFTER ...existing so it always
98
+ // wins -- this REPAIRS a stale entry that carried an absolute path (a pre-2.37.x
99
+ // install): relative survives a moved / npm-shipped repo, absolute does not, and
100
+ // Claude Code spawns the server with cwd=projectRoot so the relative path resolves
101
+ // identically. `command` is only F1-orthogonal (the interpreter, not a path), so a
102
+ // user-chosen command is preserved; we default to 'node' only when absent. Other
103
+ // pre-existing keys are still preserved.
90
104
  const entry = {
91
- command: 'node',
92
- args: [MCP_SERVER_REL_PATH],
93
105
  ...existing,
106
+ command: existing.command || 'node',
107
+ args: [MCP_SERVER_REL_PATH],
94
108
  };
95
109
  if (Object.keys(env).length > 0) entry.env = env;
96
110
  else delete entry.env;
97
111
 
98
112
  cfg.mcpServers.byan = entry;
113
+
114
+ // The channel entry is written alongside byan from the SAME merge so there is
115
+ // a single source of truth for the byan MCP registration. It is inert.
116
+ return mergeChannelEntry(cfg);
117
+ }
118
+
119
+ /**
120
+ * Pure merge — no I/O. Adds the `byan-channel` MCP server entry alongside byan.
121
+ *
122
+ * This entry is a Claude Code research-preview channel (CC v2.1.80+). It is
123
+ * INERT by default: present in .mcp.json but only loaded when the user launches
124
+ * with `claude --dangerously-load-development-channels server:byan-channel`.
125
+ * Registering it does NOT auto-activate anything — this function writes NO
126
+ * channelsEnabled / allowedChannelPlugins / --dangerously-load flag.
127
+ *
128
+ * Same portability discipline as the byan entry: a RELATIVE path (never
129
+ * absolute), no secret in env (the channel resolves its own config at boot via
130
+ * resolve-config.js: env -> ~/.byan/credentials.json -> defaults). An existing
131
+ * byan-channel entry is preserved (command/args/env) so the merge is idempotent.
132
+ *
133
+ * @param {object} existingConfig — current parsed config
134
+ * @returns {object} new merged config
135
+ */
136
+ function mergeChannelEntry(existingConfig) {
137
+ const cfg = existingConfig && typeof existingConfig === 'object' ? { ...existingConfig } : {};
138
+ cfg.mcpServers = { ...(cfg.mcpServers || {}) };
139
+
140
+ const existing = cfg.mcpServers['byan-channel'] || {};
141
+
142
+ // The canonical RELATIVE path + the empty (secret-free) env are forced AFTER
143
+ // ...existing so they always win, normalizing a stale entry (absolute path, or
144
+ // a stray env) while preserving any other pre-existing key. env stays empty: the
145
+ // channel resolves BYAN_API_URL/TOKEN itself via resolve-config.js -- writing a
146
+ // secret here would land it in tracked git, and the channel has no legitimate
147
+ // env contract of its own (Leantime refs live on the byan entry). `command` is
148
+ // F1-orthogonal so a user-chosen interpreter is preserved, 'node' only as the
149
+ // default. Idempotent: re-running yields the same entry.
150
+ cfg.mcpServers['byan-channel'] = {
151
+ ...existing,
152
+ command: existing.command || 'node',
153
+ args: [MCP_CHANNEL_REL_PATH],
154
+ env: {},
155
+ };
156
+
99
157
  return cfg;
100
158
  }
101
159
 
@@ -141,14 +199,20 @@ function mergeLeantimeRefs(existingConfig) {
141
199
  env.LEANTIME_API_URL = LEANTIME_URL_PLACEHOLDER;
142
200
  env.LEANTIME_API_TOKEN = LEANTIME_TOKEN_PLACEHOLDER;
143
201
 
202
+ // Same discipline as mergeByanEntry: args forced to the canonical RELATIVE path
203
+ // (normalizes a stale absolute one), command preserved (F1-orthogonal), env
204
+ // carries the merged Leantime refs.
144
205
  cfg.mcpServers.byan = {
145
- command: 'node',
146
- args: [MCP_SERVER_REL_PATH],
147
206
  ...existing,
207
+ command: existing.command || 'node',
208
+ args: [MCP_SERVER_REL_PATH],
148
209
  env,
149
210
  };
150
211
 
151
- return cfg;
212
+ // Keep the channel entry coherent with the byan entry: ensureLeantimeRefs runs
213
+ // after ensureMcpConfig in the installer, but routing through mergeChannelEntry
214
+ // here makes the byan-channel registration robust to call order (idempotent).
215
+ return mergeChannelEntry(cfg);
152
216
  }
153
217
 
154
218
  /**
@@ -252,12 +316,14 @@ module.exports = {
252
316
  ensureMcpConfig,
253
317
  readMcpConfig,
254
318
  mergeByanEntry,
319
+ mergeChannelEntry,
255
320
  mergeLeantimeRefs,
256
321
  ensureLeantimeRefs,
257
322
  addMcpEntry,
258
323
  removeMcpEntry,
259
324
  looksLikeSecret,
260
325
  MCP_SERVER_REL_PATH,
326
+ MCP_CHANNEL_REL_PATH,
261
327
  TOKEN_PLACEHOLDER,
262
328
  LEANTIME_URL_PLACEHOLDER,
263
329
  LEANTIME_TOKEN_PLACEHOLDER,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-byan-agent",
3
- "version": "2.35.0",
3
+ "version": "2.39.0",
4
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": {
@@ -1,8 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "byan": {
4
- "command": "node",
5
- "args": ["{{PROJECT_ROOT}}/_byan/mcp/byan-mcp-server/server.js"]
6
- }
7
- }
8
- }