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.
- package/dist/commands/init.js +91 -28
- package/dist/index.js +1 -0
- package/dist/protocol.js +1 -1
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
`>
|
|
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.
|
|
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",
|