@remits/remits-cli 0.1.95 → 0.1.98

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/README.md CHANGED
@@ -63,7 +63,7 @@ remits-cli install --skills --overwrite true
63
63
  - `components clear` clears staged entries. Scope it with `--component-type` and/or `--component-id`. Component ids are type-local, so an id alone clears that one component when the id is staged in only one family; if the same id is staged across multiple families it returns an ambiguity error asking you to add `--component-type`. With no filter it clears every staged entry for the current branch; pass `--all` to force the full-branch wipe explicitly.
64
64
  - `components stage`, `components status`, and `components clear` print concise summaries by default. Add `--json` or `--verbose` to print the full server response. `components stage` separates local working-tree component deltas from the full materialized staging cache count.
65
65
  - `components sync` performs a server-side sync from the git remote into the Remits platform for the selected branch. It does not run local git commands. After a successful non-dry-run sync, the platform clears the branch/user staging scope so staged aliases cannot keep shadowing the newly synced DB rows.
66
- - On trunk, `components sync` performs the full repo-to-DB reconcile. On a non-trunk branch, it writes `ComponentVariant` overlays only and may refresh branch-local `account-info.json` for the subscribing account that initiated the sync. `--dry-run` is accepted only for non-trunk variant syncs and reports overrides/additions/tombstones without writing variants, caching the sync SHA, updating metadata, or clearing staging. Add `--summary` to dry-run output when you only need counts, removals/tombstones, errors, skipped items, and warnings. `--force-tombstones` is accepted only for non-trunk variant syncs and should be used only when missing trunk component files are intentional tombstone overrides.
66
+ - On trunk, `components sync` performs the full repo-to-DB reconcile. On a non-trunk branch, it writes `ComponentVariant` overlays only and may refresh branch-local `account-info.json`, `account-hierarchy.json`, and `account-configurations.json` for the subscribing account that initiated the sync. `--dry-run` is accepted only for non-trunk variant syncs and reports overrides/additions/tombstones without writing variants, caching the sync SHA, updating metadata, or clearing staging. Add `--summary` to dry-run output when you only need counts, removals/tombstones, errors, skipped items, and warnings. `--force-tombstones` is accepted only for non-trunk variant syncs and should be used only when missing trunk component files are intentional tombstone overrides.
67
67
  - `components commit` is a convenience wrapper that performs local git commit/push, then `components sync`, then local `git fetch`/`git pull --ff-only`.
68
68
  - `components sync` returns the post-sync branch SHA produced by the platform. `components commit` verifies that `origin/<branch>` and local `HEAD` both match that exact SHA after the final pull.
69
69
  - `components push` is deprecated and currently behaves the same as `components stage`.
@@ -173,7 +173,7 @@ There are two separate state areas:
173
173
 
174
174
  - `remits-cli start` prints or records a localhost dashboard URL such as `http://127.0.0.1:8787/`.
175
175
  - Open that page in a browser to inspect the full local remits-cli integration state without manually opening JSON files.
176
- - The page refreshes automatically and includes the latest global state files plus per-repo `account-info.json`, local tools snapshot, and current session log tail for every indexed account repo.
176
+ - The page refreshes automatically and includes the latest global state files plus per-repo `account-info.json`, local tools snapshot, and current session log tail for every indexed account repo. Large account configuration fields live in `account-configurations.json` and should be opened only when needed.
177
177
 
178
178
  ## Tmux Activity Log
179
179
 
package/index.js CHANGED
@@ -2105,6 +2105,9 @@ async function syncComponentsCommand(flags) {
2105
2105
  const forceTombstones = flagEnabled(flags['force-tombstones']) || flagEnabled(flags.forceTombstones);
2106
2106
  const dryRun = flagEnabled(flags['dry-run']) || flagEnabled(flags.dryRun);
2107
2107
  const api = buildAxios(baseUrl, session.token);
2108
+ const changedFromWorkingTree = changedComponentsFromWorkingTree(cwd);
2109
+ const preflightRequested = syncPreflightRequested(flags);
2110
+ const namesOnly = flagEnabled(flags['names-only']) || flagEnabled(flags.namesOnly);
2108
2111
 
2109
2112
  printProdDataBanner({
2110
2113
  dataMode,
@@ -2112,10 +2115,10 @@ async function syncComponentsCommand(flags) {
2112
2115
  baseUrl,
2113
2116
  operation: 'components sync (branch ' + branchName + ')',
2114
2117
  mutating: true,
2115
- dryRun
2118
+ dryRun: dryRun || namesOnly
2116
2119
  });
2117
2120
 
2118
- const response = await loggedPost(api, cwd, '/cli/components', {
2121
+ const syncPayload = {
2119
2122
  token: session.token,
2120
2123
  accountId,
2121
2124
  branchName,
@@ -2124,14 +2127,55 @@ async function syncComponentsCommand(flags) {
2124
2127
  dryRun,
2125
2128
  mode: 'sync',
2126
2129
  components: []
2127
- }).then((r) => r.data);
2130
+ };
2131
+
2132
+ let preflightGate = null;
2133
+ if (preflightRequested && !dryRun) {
2134
+ const statusResponse = await loggedPost(api, cwd, '/cli/components', {
2135
+ token: session.token,
2136
+ accountId,
2137
+ branchName,
2138
+ dataMode,
2139
+ mode: 'status'
2140
+ }).then((r) => r.data);
2141
+
2142
+ const branchContext = statusResponse && statusResponse.branchContext;
2143
+ if (!branchContext || branchContext.onTrunk) {
2144
+ throw new Error('components sync safety preflight requires a non-trunk variant branch because trunk sync has no dry-run plan. Re-run without safety flags only if you intend a full trunk reconcile.');
2145
+ }
2146
+
2147
+ const previewResponse = await loggedPost(api, cwd, '/cli/components', Object.assign({}, syncPayload, {
2148
+ dryRun: true
2149
+ })).then((r) => r.data);
2150
+
2151
+ if (!previewResponse.success) {
2152
+ throw new Error(previewResponse.message || 'Server sync dry-run failed');
2153
+ }
2154
+
2155
+ preflightGate = evaluateSyncGates(previewResponse, flags, changedFromWorkingTree);
2156
+
2157
+ if (namesOnly) {
2158
+ printSessionResolutionWarning(sessionContext);
2159
+ printResolvedBaseUrl(baseUrl);
2160
+ console.log('Data mode:', previewResponse.dataMode || dataMode);
2161
+ console.log('Mode:', 'sync dry-run');
2162
+ console.log('Dry run: no variants were written and staging was not cleared.');
2163
+ printSyncNames(previewResponse);
2164
+ failOnSyncGate(preflightGate);
2165
+ return previewResponse;
2166
+ }
2167
+
2168
+ failOnSyncGate(preflightGate);
2169
+ }
2170
+
2171
+ const response = await loggedPost(api, cwd, '/cli/components', syncPayload).then((r) => r.data);
2128
2172
 
2129
2173
  if (!response.success) {
2130
2174
  throw new Error(response.message || 'Server sync failed');
2131
2175
  }
2132
2176
 
2133
2177
  const summary = buildSyncSummary(response);
2134
- const gate = evaluateSyncGates(response, flags, changedComponentsFromWorkingTree(cwd));
2178
+ const gate = preflightGate || evaluateSyncGates(response, flags, changedFromWorkingTree);
2135
2179
  summary.gates = gate.checks;
2136
2180
 
2137
2181
  if (flagEnabled(flags.json)) {
@@ -2147,7 +2191,7 @@ async function syncComponentsCommand(flags) {
2147
2191
  if (response.sync && response.sync.dryRun) {
2148
2192
  console.log('Dry run: no variants were written and staging was not cleared.');
2149
2193
  }
2150
- if (flagEnabled(flags['names-only']) || flagEnabled(flags.namesOnly)) {
2194
+ if (namesOnly) {
2151
2195
  printSyncNames(response);
2152
2196
  failOnSyncGate(gate);
2153
2197
  return response;
@@ -2162,6 +2206,21 @@ async function syncComponentsCommand(flags) {
2162
2206
  return response;
2163
2207
  }
2164
2208
 
2209
+ function syncPreflightRequested(flags) {
2210
+ return Boolean(
2211
+ flagEnabled(flags['names-only']) ||
2212
+ flagEnabled(flags.namesOnly) ||
2213
+ flagEnabled(flags['changed-only']) ||
2214
+ flagEnabled(flags.changedOnly) ||
2215
+ flagEnabled(flags['fail-on-removed']) ||
2216
+ flagEnabled(flags.failOnRemoved) ||
2217
+ flagEnabled(flags['fail-on-errors']) ||
2218
+ flagEnabled(flags.failOnErrors) ||
2219
+ flags['expected-removed'] != null ||
2220
+ flags.expectedRemoved != null
2221
+ );
2222
+ }
2223
+
2165
2224
  // One "type:id" / "type:name" token per planned write, so an agent can eyeball or diff the plan
2166
2225
  // without paging through the full server response.
2167
2226
  function syncPlanEntries(response) {
@@ -3809,6 +3868,7 @@ function buildRepoSnapshot(entry) {
3809
3868
  : null;
3810
3869
  const repoFiles = [
3811
3870
  { label: 'account-info.json', path: entry.accountInfoPath || path.join(directory, 'account-info.json'), mode: 'json' },
3871
+ { label: 'account-hierarchy.json', path: path.join(directory, 'account-hierarchy.json'), mode: 'json' },
3812
3872
  { label: '.remits-cli/current-session.txt', path: localPaths.currentSessionFile, mode: 'text' },
3813
3873
  { label: '.remits-cli/tools/tools.json', path: path.join(localPaths.toolsDir, 'tools.json'), mode: 'json' },
3814
3874
  { label: '.remits-cli/session log (tail)', path: currentSessionLog, mode: 'tail' }
@@ -5371,10 +5431,10 @@ function printComponentsHelp(subcommand) {
5371
5431
  console.log('--summary prints compact counts, removals/tombstones, errors, skipped items, and warnings.');
5372
5432
  console.log('');
5373
5433
  console.log('Agent safety gates (each exits non-zero instead of printing a wall of JSON):');
5374
- console.log(' --changed-only fail unless every planned write is a component this checkout changed');
5375
- console.log(' --names-only print only "type id name" lines for the planned writes');
5376
- console.log(' --fail-on-removed fail if the plan removes/tombstones anything');
5377
- console.log(' --fail-on-errors fail if the server reported any per-component sync error');
5434
+ console.log(' --changed-only dry-run first; fail unless every planned write is a component this checkout changed');
5435
+ console.log(' --names-only dry-run first; print only "type id name" lines and write nothing');
5436
+ console.log(' --fail-on-removed dry-run first; fail if the plan removes/tombstones anything');
5437
+ console.log(' --fail-on-errors dry-run first; fail if the server reported any per-component sync error');
5378
5438
  console.log(' --expected-removed t:id whitelist an intended removal; repeatable/comma-delimited.');
5379
5439
  console.log(' Implies --fail-on-removed, so any OTHER removal fails.');
5380
5440
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remits/remits-cli",
3
- "version": "0.1.95",
3
+ "version": "0.1.98",
4
4
  "description": "Local CLI for auth, component sync, and live test execution against Remits",
5
5
  "license": "MIT",
6
6
  "private": false,