convene-cli 1.4.2 → 1.4.3

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.
@@ -552,15 +552,29 @@ function writeCoordinationBlocks(top, slug, member, baseUrl) {
552
552
  */
553
553
  function commitConveneFiles(top, message, label) {
554
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) {
555
+ if (!paths.length)
556
+ return;
557
+ // Decide up front whether anything under the managed paths is actually pending
558
+ // (staged/unstaged/untracked). This makes `--commit` deterministic and TRANSPARENT:
559
+ // a clean re-render says "already up to date" instead of a vague no-op, and a tree
560
+ // dirtied by an EARLIER `--refresh-docs` (without `--commit`) still gets committed
561
+ // — the gotcha that previously left changes stranded.
562
+ const pending = (0, git_1.gitPendingPaths)(paths, top);
563
+ if (!pending.length) {
564
+ log(`· ${label}: managed files already committed — nothing to commit.`);
565
+ return;
566
+ }
567
+ if (!(0, git_1.gitAddPaths)(paths, top)) {
563
568
  log('⚠ could not stage the convene files — commit them manually.');
569
+ return;
570
+ }
571
+ const res = (0, git_1.gitCommit)(message, paths, top);
572
+ if (res.ok) {
573
+ log(`✓ committed ${label} as one isolated commit${res.sha ? ` (${res.sha})` : ''} — ${pending.length} convene file(s) staged, nothing else.`);
574
+ }
575
+ else {
576
+ // pending changes existed but the commit did not land — never silent.
577
+ log(`⚠ ${pending.length} convene file(s) are staged but the commit did not land — commit them manually (\`git commit\`).`);
564
578
  }
565
579
  }
566
580
  /**
package/dist/git.js CHANGED
@@ -26,6 +26,7 @@ exports.gitConfigUnsetLocal = gitConfigUnsetLocal;
26
26
  exports.pathIsTracked = pathIsTracked;
27
27
  exports.hasStagedChanges = hasStagedChanges;
28
28
  exports.gitAddPaths = gitAddPaths;
29
+ exports.gitPendingPaths = gitPendingPaths;
29
30
  exports.gitCommit = gitCommit;
30
31
  exports.gitPathIsIgnored = gitPathIsIgnored;
31
32
  /** Cross-platform git helpers. No shell strings — spawn git directly (P0-XPLAT). */
@@ -305,6 +306,30 @@ function gitAddPaths(paths, cwd = process.cwd()) {
305
306
  return false;
306
307
  }
307
308
  }
309
+ /**
310
+ * The subset of `paths` that have PENDING changes (staged, unstaged, or untracked),
311
+ * via `git status --porcelain -- <paths>`. Lets a caller decide whether there is
312
+ * anything to commit BEFORE running `git commit` — so an isolated-commit helper can
313
+ * say "already up to date" plainly instead of relying on a non-zero `git commit`
314
+ * exit. Returns [] on any error / clean tree (never throws).
315
+ */
316
+ function gitPendingPaths(paths, cwd = process.cwd()) {
317
+ if (paths.length === 0)
318
+ return [];
319
+ try {
320
+ const r = (0, node_child_process_1.spawnSync)('git', ['status', '--porcelain', '--', ...paths], { cwd, encoding: 'utf8', timeout: 5000 });
321
+ if (r.status !== 0 || !r.stdout)
322
+ return [];
323
+ // Porcelain v1 line: "XY <path>"; we only need the count/names, not the status.
324
+ return r.stdout
325
+ .split('\n')
326
+ .map((l) => l.slice(3).trim())
327
+ .filter(Boolean);
328
+ }
329
+ catch {
330
+ return [];
331
+ }
332
+ }
308
333
  /**
309
334
  * Commit ONLY the given pathspecs (`git commit -m <msg> -- <paths>`), leaving any
310
335
  * other staged changes untouched — the isolated-commit guarantee. Returns the short
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convene-cli",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
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",