@remits/remits-cli 0.1.95 → 0.1.97
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 +1 -1
- package/index.js +69 -9
- package/package.json +1 -1
- package/skills/remits-cli/SKILL.md +536 -961
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` 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`.
|
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
|
|
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
|
-
}
|
|
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,
|
|
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 (
|
|
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
|
|
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;
|