convene-cli 1.4.0 → 1.4.2

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.
@@ -8,6 +8,7 @@ exports.upsertMarkerBlock = upsertMarkerBlock;
8
8
  exports.removeMarkerBlock = removeMarkerBlock;
9
9
  exports.removeGitignoreGuard = removeGitignoreGuard;
10
10
  exports.removeTomlBlock = removeTomlBlock;
11
+ exports.refreshDocs = refreshDocs;
11
12
  exports.init = init;
12
13
  /**
13
14
  * `convene init` — one-command repo onboarding. IDEMPOTENT + merge-safe
@@ -520,10 +521,97 @@ async function adoptBestPractices(top, slug, opts) {
520
521
  log('· reported adoption to the dashboard');
521
522
  }
522
523
  }
524
+ /**
525
+ * Re-render the managed COORDINATION blocks (CLAUDE.md + AGENTS.md) at the current
526
+ * template. Pure per file (P0-IDEMPOTENT). The two blocks intentionally diverge:
527
+ * CLAUDE.md (conveneBlock) omits the manual-deploy line (its PreToolUse hook gates
528
+ * deploys); AGENTS.md (conveneAgentsBlock) adds it for tools with no in-time gate.
529
+ * upsertMarkerBlock preserves everything OUTSIDE the markers.
530
+ */
531
+ function writeCoordinationBlocks(top, slug, member, baseUrl) {
532
+ const fileBlocks = [
533
+ ['CLAUDE.md', (0, protocol_1.conveneBlock)(slug, member, baseUrl)],
534
+ ['AGENTS.md', (0, protocol_1.conveneAgentsBlock)(slug, member, baseUrl)],
535
+ ];
536
+ for (const [fname, block] of fileBlocks) {
537
+ const file = node_path_1.default.join(top, fname);
538
+ const old = node_fs_1.default.existsSync(file) ? node_fs_1.default.readFileSync(file, 'utf8') : '';
539
+ const result = writeIfChanged(file, upsertMarkerBlock(old, block));
540
+ const note = result === 'created'
541
+ ? 'created — Convene block added'
542
+ : result === 'updated'
543
+ ? 'merged — your content preserved'
544
+ : 'unchanged';
545
+ log(`${result === 'unchanged' ? '·' : '✓'} ${fname} (${note})`);
546
+ }
547
+ }
548
+ /**
549
+ * Stage + commit ONLY the convene files (CONVENE_PATHS) as one isolated commit —
550
+ * never `git add -A`, so convene changes are never bundled into unrelated work.
551
+ * Shared by `convene init --commit` and `convene init --refresh-docs --commit`.
552
+ */
553
+ function commitConveneFiles(top, message, label) {
554
+ const paths = exports.CONVENE_PATHS.filter((p) => node_fs_1.default.existsSync(node_path_1.default.join(top, p)));
555
+ if (paths.length && (0, git_1.gitAddPaths)(paths, top)) {
556
+ const res = (0, git_1.gitCommit)(message, paths, top);
557
+ if (res.ok)
558
+ log(`✓ committed ${label} as one isolated commit${res.sha ? ` (${res.sha})` : ''} — only the convene files were staged.`);
559
+ else
560
+ log('· nothing committed (no staged changes).');
561
+ }
562
+ else if (paths.length) {
563
+ log('⚠ could not stage the convene files — commit them manually.');
564
+ }
565
+ }
566
+ /**
567
+ * `convene init --refresh-docs` — re-render the managed DOC surfaces (CLAUDE.md +
568
+ * AGENTS.md coordination blocks, the cross-agent rule files, and the MCP client
569
+ * configs) at the CURRENT CLI template, for a repo that is ALREADY on Convene.
570
+ *
571
+ * This is the propagation path init/setup lacked: `convene setup` on an already-
572
+ * onboarded repo only re-confirms identity, so improvements to the block templates
573
+ * (e.g. the connect-line in protocol.ts) never reached existing repos. Refresh fixes
574
+ * that with NO network/identity work — every template is a pure function of
575
+ * (slug, member, baseUrl), all read from local config — so it is byte-idempotent.
576
+ * Best-practice CONTENT is intentionally NOT touched here (that is `convene update`'s
577
+ * job: versioned + consented), and CONVENE_PROTOCOL.md is left as-is (write-if-absent
578
+ * / hand-enrichable), same as init.
579
+ */
580
+ async function refreshDocs(opts) {
581
+ const top = (0, git_1.gitToplevel)();
582
+ if (!top)
583
+ (0, ctx_1.die)('not a git repository — run `convene init --refresh-docs` inside a repo');
584
+ const existing = (0, config_1.loadProjectConfig)(top);
585
+ if (!existing?.slug) {
586
+ (0, ctx_1.die)('this repo is not on Convene yet — run `convene setup` first; `--refresh-docs` only re-renders an already-onboarded repo.');
587
+ }
588
+ const cfg = (0, config_1.resolveConfig)();
589
+ const slug = existing.slug;
590
+ const member = cfg.member;
591
+ const baseUrl = cfg.baseUrl;
592
+ const skipAgentRules = opts.noAgentRules === true || opts.agentRules === false;
593
+ const skipMcp = opts.noMcp === true || opts.mcp === false;
594
+ log(`Refreshing Convene managed blocks for "${slug}" at the current template (no identity/network changes)…`);
595
+ writeCoordinationBlocks(top, slug, member, baseUrl);
596
+ if (!skipAgentRules)
597
+ writeAgentRules(top, slug, member, baseUrl);
598
+ if (!skipMcp)
599
+ writeMcpConfigs(top, baseUrl);
600
+ if (opts.commit)
601
+ commitConveneFiles(top, 'Refresh Convene managed blocks to current template', 'the refresh');
602
+ log('');
603
+ log('Done — managed blocks re-rendered. Your content outside the convene markers is untouched.');
604
+ log('(Best-practice content is managed separately — run `convene update` to take catalog changes.)');
605
+ }
523
606
  async function init(opts) {
524
607
  const top = (0, git_1.gitToplevel)();
525
608
  if (!top)
526
609
  (0, ctx_1.die)('not a git repository — run `convene init` inside a repo');
610
+ // `--refresh-docs` is a re-render of an already-onboarded repo's managed blocks —
611
+ // not onboarding. It needs no consent gate / identity / network, so short-circuit
612
+ // here, before all of that.
613
+ if (opts.refreshDocs)
614
+ return refreshDocs(opts);
527
615
  // Consent gate: onboarding writes a footprint and registers per-prompt hooks — it
528
616
  // must be a DELIBERATE choice, never an accidental side-effect. A human at a
529
617
  // terminal (TTY) confirms simply by running it; an agent / CI (no TTY) must pass
@@ -658,21 +746,7 @@ async function init(opts) {
658
746
  // gates deploys), AGENTS.md uses conveneAgentsBlock (adds the explicit
659
747
  // `convene deploy` line for tools with no in-time gate). Each is PURE, so a
660
748
  // re-run is byte-identical per file (P0-IDEMPOTENT).
661
- const fileBlocks = [
662
- ['CLAUDE.md', (0, protocol_1.conveneBlock)(slug, member, baseUrl)],
663
- ['AGENTS.md', (0, protocol_1.conveneAgentsBlock)(slug, member, baseUrl)],
664
- ];
665
- for (const [fname, block] of fileBlocks) {
666
- const file = node_path_1.default.join(top, fname);
667
- const old = node_fs_1.default.existsSync(file) ? node_fs_1.default.readFileSync(file, 'utf8') : '';
668
- const result = writeIfChanged(file, upsertMarkerBlock(old, block));
669
- const note = result === 'created'
670
- ? 'created — Convene block added'
671
- : result === 'updated'
672
- ? 'merged — your content preserved'
673
- : 'unchanged';
674
- log(`${result === 'unchanged' ? '·' : '✓'} ${fname} (${note})`);
675
- }
749
+ writeCoordinationBlocks(top, slug, member, baseUrl);
676
750
  // 6. portable protocol doc — write only if ABSENT (mirrors the memory-seed
677
751
  // pattern). The doc is hand-enrichable; unconditionally overwriting it with
678
752
  // the generated stub would clobber any teammate's expanded protocol spec.
@@ -750,19 +824,8 @@ async function init(opts) {
750
824
  // 8a. optional isolated commit — stage ONLY the convene files (never `git add -A`),
751
825
  // so onboarding can never be bundled into unrelated work (the VAcontractorCo
752
826
  // entangled-commit failure). Off by default; `--commit` opts in.
753
- if (opts.commit) {
754
- const paths = exports.CONVENE_PATHS.filter((p) => node_fs_1.default.existsSync(node_path_1.default.join(top, p)));
755
- if (paths.length && (0, git_1.gitAddPaths)(paths, top)) {
756
- const res = (0, git_1.gitCommit)('Onboard onto Convene coordination bus', paths, top);
757
- if (res.ok)
758
- log(`✓ committed onboarding as one isolated commit${res.sha ? ` (${res.sha})` : ''} — only the convene files were staged.`);
759
- else
760
- log('· nothing committed (no staged changes).');
761
- }
762
- else if (paths.length) {
763
- log('⚠ could not stage the convene files — commit them manually.');
764
- }
765
- }
827
+ if (opts.commit)
828
+ commitConveneFiles(top, 'Onboard onto Convene coordination bus', 'onboarding');
766
829
  // 9. teammate one-liner
767
830
  log('');
768
831
  log(`Done. Project "${slug}" — dashboard: ${baseUrl}/p/${slug}`);
package/dist/index.js CHANGED
@@ -263,6 +263,7 @@ program
263
263
  .option('--yes', 'confirm onboarding non-interactively (required for agents/CI)')
264
264
  .option('--commit', 'commit ONLY the convene files as one isolated commit (never `git add -A`)')
265
265
  .option('--offline', 'write local files only (no API calls)')
266
+ .option('--refresh-docs', 're-render the managed CLAUDE.md/AGENTS.md blocks + agent rules + MCP configs at the current template (already-onboarded repos; no identity/network changes)')
266
267
  .option('--tier <names>', 'best practices: comma-separated tiers to adopt (essentials,recommended,advanced)')
267
268
  .option('--practice <id[=level]>', 'best practice to adopt (id or id=level; repeatable)', (v, acc) => (acc.push(v), acc), [])
268
269
  .option('--all-practices', 'adopt every catalog best practice at its default level')
package/dist/protocol.js CHANGED
@@ -31,7 +31,7 @@ function block(flavor, slug, member, baseUrl) {
31
31
  `This repo is on **Convene** — a tool-agnostic AI development coordination bus — as project \`${slug}\`.`,
32
32
  `Dashboard: ${baseUrl}/p/${slug}`,
33
33
  '',
34
- `> Not connected yet on this machine? Run \`convene setup\` here (or fetch ${baseUrl}/start and follow it) it self-provisions you and plugs into this project.`,
34
+ `> **Asked to get set up / "up and running" with Convene on this machine?** Run these three: \`npm i -g convene-cli@latest\` → \`convene setup\` (follow the prompts) \`convene doctor\`. One time per machine; wires Claude Code **and** Codex. Already connected? \`convene doctor\` confirms it. Detail: ${baseUrl}/start.`,
35
35
  '',
36
36
  'Each turn you get a `<convene-channel>` block — a health line, open items addressed to you, and',
37
37
  'recent activity. (Claude Code injects it via the `convene fetch` UserPromptSubmit hook; with other',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convene-cli",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Convene CLI — AI development coordination bus client + UserPromptSubmit hook. Install: npm i -g convene-cli; then `convene setup`.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://dev.convene.live",