@remits/remits-cli 0.1.118 → 0.1.120
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 +4 -2
- package/index.js +358 -33
- package/package.json +1 -1
- package/skills/remits-cli/SKILL.md +4 -0
- package/skills/remits-cli/references/command-reference.md +15 -3
- package/skills/remits-cli/references/component-resolution.md +15 -6
- package/skills/remits-cli/references/development-loop.md +16 -0
package/README.md
CHANGED
|
@@ -71,9 +71,10 @@ remits-cli install --skills --overwrite true
|
|
|
71
71
|
- An **empty workset never clears a lane**: `--workset` on a clean working tree stages nothing and leaves the lane as it is. Pass `--empty-workset clear` to opt in, or use `components clear --all`.
|
|
72
72
|
- A **deleted component file cannot be represented in Redis staging** — clearing a staged entry falls back to the committed row, so the component still resolves. Those changes are reported as NOT REPRESENTABLE. On a non-trunk variant branch, prove a deletion through `components sync --dry-run --summary --fail-on-errors`; on trunk there is no dry-run plan, so use the full pre-sync safety check before any mutating reconcile.
|
|
73
73
|
- Schema `.meta.yml` sidecars can stage/sync the schema flags: `enableTrigger`, `enableFullText`, `enableRAG`, `enableRevisions`, `enableBigQuerySync`, `enableRules`, `anchor`, and `auxiliary`.
|
|
74
|
-
- `components status` shows the branch/user staging entries that can shadow DB components during CLI-scoped test-mode execution.
|
|
74
|
+
- `components status` shows the branch/user staging entries that can shadow DB components during CLI-scoped test-mode execution, plus the other live lanes on the account.
|
|
75
|
+
- `components lanes` lists every indexed staging lane on the account. `components entries --lane-id <id>` reads the authoritative staged files for one lane without switching your workspace, clearing anything, or using SQL.
|
|
75
76
|
- `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.
|
|
76
|
-
- `components stage`, `components status`, and `components clear` print concise summaries by default. Add `--json` or `--verbose` to print the full server response.
|
|
77
|
+
- `components stage`, `components status`, `components lanes`, `components entries`, and `components clear` print concise summaries by default. Add `--json` or `--verbose` to print the full server response.
|
|
77
78
|
- `components stage` and `components status` report three separate numbers, and they answer three different questions: the **workset** (components git reports this working tree changed), what was **submitted**, and the materialized **overlay** the lane now holds — which is what a run resolves. A number that could not be established prints as `unknown`, never as `0`.
|
|
78
79
|
- `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.
|
|
79
80
|
- 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.
|
|
@@ -83,6 +84,7 @@ remits-cli install --skills --overwrite true
|
|
|
83
84
|
- `accountId` resolution for CLI commands: explicit `--account-id` flag wins, then the current repo's `account-info.json` (`resolution.accountId`, then the short-lived `repoContext.accountInfoAccountId`, then the legacy top-level id — legacy files are rooted at the hierarchy ROOT, so their top-level `id` may be an ancestor), then the active session.
|
|
84
85
|
- For `remits-cli tool`, read/discovery tools treat that resolved account as the **scope root**. You do not need the owning child account id for an exact document/record lookup: pass `--scope children`, or put `scope:"children"` in `--input`, and use the returned `resolvedTargetAccountId` for follow-up writes/runs. Use `--target-account-id` when you already know the exact owner, `--account-ids` for an explicit bounded owner list, and `--anchor-account-id` only to disambiguate multi-parent paths. Mutating tools still require an exact target.
|
|
85
86
|
- Auth sessions are stored per `accountId + dataMode + baseUrl`, so the same account can stay authenticated against both localhost and production without overwriting the other session.
|
|
87
|
+
- Active verification envelopes are scoped per `baseUrl + accountId + branch + workspace + dataMode`, so a localhost envelope does not silently capture evidence from a production command. Pass `--verify-envelope <id>` for an intentional cross-context attachment.
|
|
86
88
|
- `--base-url` and `--data-mode` are independent. `--base-url` chooses the Remits host (`http://localhost:8080` vs deployed prod), while `--data-mode` chooses the data segment on that host (`test` vs `prod`). Do not assume `--data-mode prod` means the deployed prod host, or that `--data-mode test` means localhost.
|
|
87
89
|
- `remits-cli start` scans the machine for `account-info.json` files and rebuilds `~/.remits-cli/account-repos.json` before bringing up the background service.
|
|
88
90
|
- Front-stage guides are **not** bundled with the CLI npm package. For account-work commands (`components`, `test`, `token`, `tools`, `tool`) and on `auth`, `remits-cli` downloads the latest guides from the authenticated `/cli/guides` endpoint and writes them into the current account repo: root `platform-overview.md` / `development-guide.md`, `guides/*.md`, `guides/features/*.md`, and the agent-guidance files `CLAUDE.md` / `AGENTS.md` / `GEMINI.md` (from `docs/front-stage/remits-components-zip-readme.md`).
|
package/index.js
CHANGED
|
@@ -546,6 +546,7 @@ function localStatePaths(cwd) {
|
|
|
546
546
|
toolResponsesDir: path.join(base, 'tool-responses'),
|
|
547
547
|
verificationDir: path.join(base, 'verification'),
|
|
548
548
|
activeVerificationFile: path.join(base, 'verification', 'active'),
|
|
549
|
+
activeVerificationContextsFile: path.join(base, 'verification', 'active-contexts.json'),
|
|
549
550
|
currentSessionFile: path.join(base, 'current-session.txt'),
|
|
550
551
|
workspaceFile: path.join(base, 'workspace')
|
|
551
552
|
};
|
|
@@ -771,7 +772,49 @@ function verificationPaths(cwd, envelopeId) {
|
|
|
771
772
|
};
|
|
772
773
|
}
|
|
773
774
|
|
|
774
|
-
function
|
|
775
|
+
function verificationContextKey(context = {}) {
|
|
776
|
+
const baseUrl = normalizeBaseUrl(context.baseUrl || context.host || DEFAULT_BASE_URL);
|
|
777
|
+
const accountId = context.accountId != null ? String(context.accountId) : 'unknown-account';
|
|
778
|
+
const branchName = context.branchName || context.branch || 'unknown-branch';
|
|
779
|
+
const workspace = normalizeWorkspace(context.workspace) || 'shared';
|
|
780
|
+
const dataMode = normalizeDataMode(context.dataMode);
|
|
781
|
+
return [baseUrl, accountId, branchName, workspace, dataMode].join('|');
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function readActiveVerificationContexts(cwd) {
|
|
785
|
+
const file = localStatePaths(cwd).activeVerificationContextsFile;
|
|
786
|
+
if (!fs.existsSync(file)) return {};
|
|
787
|
+
try {
|
|
788
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
789
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
|
|
790
|
+
} catch (_) {
|
|
791
|
+
return {};
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
function writeActiveVerificationContexts(cwd, contexts) {
|
|
796
|
+
const paths = ensureLocalState(cwd);
|
|
797
|
+
atomicWriteFile(paths.activeVerificationContextsFile, JSON.stringify(contexts || {}, null, 2));
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function activeVerificationContext(cwd, flags = {}, session = null, accountId = null) {
|
|
801
|
+
return {
|
|
802
|
+
baseUrl: normalizeBaseUrl(flags['base-url'] || (session && session.baseUrl) || DEFAULT_BASE_URL),
|
|
803
|
+
accountId,
|
|
804
|
+
branchName: flags.branch || currentBranch(cwd),
|
|
805
|
+
workspace: resolveWorkspace(cwd, flags),
|
|
806
|
+
dataMode: resolveDataMode(flags, session)
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
function readActiveVerificationEnvelope(cwd, context = null) {
|
|
811
|
+
if (context) {
|
|
812
|
+
const contexts = readActiveVerificationContexts(cwd);
|
|
813
|
+
const entry = contexts[verificationContextKey(context)];
|
|
814
|
+
if (entry && typeof entry === 'object') return entry.envelopeId || null;
|
|
815
|
+
if (typeof entry === 'string') return entry || null;
|
|
816
|
+
return null;
|
|
817
|
+
}
|
|
775
818
|
const file = verificationPaths(cwd).activeFile;
|
|
776
819
|
try {
|
|
777
820
|
if (!fs.existsSync(file)) return null;
|
|
@@ -782,8 +825,25 @@ function readActiveVerificationEnvelope(cwd) {
|
|
|
782
825
|
}
|
|
783
826
|
}
|
|
784
827
|
|
|
785
|
-
function writeActiveVerificationEnvelope(cwd, envelopeId) {
|
|
828
|
+
function writeActiveVerificationEnvelope(cwd, envelopeId, context = null) {
|
|
786
829
|
const paths = verificationPaths(cwd);
|
|
830
|
+
if (context) {
|
|
831
|
+
const contexts = readActiveVerificationContexts(cwd);
|
|
832
|
+
const key = verificationContextKey(context);
|
|
833
|
+
if (!envelopeId) {
|
|
834
|
+
delete contexts[key];
|
|
835
|
+
} else {
|
|
836
|
+
contexts[key] = {
|
|
837
|
+
envelopeId: String(envelopeId),
|
|
838
|
+
updatedAt: new Date().toISOString(),
|
|
839
|
+
context: Object.assign({}, context, {
|
|
840
|
+
baseUrl: normalizeBaseUrl(context.baseUrl || context.host || DEFAULT_BASE_URL),
|
|
841
|
+
workspace: normalizeWorkspace(context.workspace)
|
|
842
|
+
})
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
writeActiveVerificationContexts(cwd, contexts);
|
|
846
|
+
}
|
|
787
847
|
if (!envelopeId) {
|
|
788
848
|
try { if (fs.existsSync(paths.activeFile)) fs.unlinkSync(paths.activeFile); } catch (_) { /* best-effort */ }
|
|
789
849
|
return null;
|
|
@@ -792,11 +852,11 @@ function writeActiveVerificationEnvelope(cwd, envelopeId) {
|
|
|
792
852
|
return String(envelopeId);
|
|
793
853
|
}
|
|
794
854
|
|
|
795
|
-
function verificationEnvelopeIdForCommand(cwd, flags = {}) {
|
|
855
|
+
function verificationEnvelopeIdForCommand(cwd, flags = {}, context = null) {
|
|
796
856
|
if (flagEnabled(flags['no-verify-envelope']) || flagEnabled(flags.noVerifyEnvelope)) return null;
|
|
797
857
|
const explicit = flags['verify-envelope'] || flags.verifyEnvelope || flags.envelope;
|
|
798
858
|
if (explicit !== undefined && explicit !== null && explicit !== true) return String(explicit).trim() || null;
|
|
799
|
-
return readActiveVerificationEnvelope(cwd);
|
|
859
|
+
return context ? readActiveVerificationEnvelope(cwd, context) : readActiveVerificationEnvelope(cwd);
|
|
800
860
|
}
|
|
801
861
|
|
|
802
862
|
function writeLocalVerificationEnvelope(cwd, envelope) {
|
|
@@ -903,7 +963,8 @@ async function postVerificationCommand(api, cwd, session, accountId, command, pa
|
|
|
903
963
|
}
|
|
904
964
|
|
|
905
965
|
async function appendVerificationPacket(api, cwd, session, accountId, flags, packet, options = {}) {
|
|
906
|
-
const
|
|
966
|
+
const context = activeVerificationContext(cwd, flags, session, accountId);
|
|
967
|
+
const envelopeId = verificationEnvelopeIdForCommand(cwd, flags, context);
|
|
907
968
|
if (!envelopeId) return null;
|
|
908
969
|
const finalPacket = Object.assign({
|
|
909
970
|
packetId: crypto.randomUUID(),
|
|
@@ -929,6 +990,52 @@ async function appendVerificationPacket(api, cwd, session, accountId, flags, pac
|
|
|
929
990
|
}
|
|
930
991
|
}
|
|
931
992
|
|
|
993
|
+
function formatTime(value) {
|
|
994
|
+
if (!value) return 'unknown';
|
|
995
|
+
const n = Number(value);
|
|
996
|
+
const date = Number.isFinite(n) ? new Date(n) : new Date(value);
|
|
997
|
+
if (Number.isNaN(date.getTime())) return String(value);
|
|
998
|
+
return date.toISOString();
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
function printVerificationSummaryLine(env) {
|
|
1002
|
+
const health = env.health ? ' health=' + env.health : '';
|
|
1003
|
+
const failures = env.currentFailureCount ? ' currentFailures=' + env.currentFailureCount : (env.failedCount ? ' failed=' + env.failedCount : '');
|
|
1004
|
+
const required = ' required=' + (env.satisfiedCount || 0) + '/' + (env.requiredCount || 0);
|
|
1005
|
+
const noManifest = env.noRequiredEvidence ? ' no-manifest' : '';
|
|
1006
|
+
const lane = [env.branchName || 'unknown-branch', env.workspace ? 'ws:' + env.workspace : 'shared', env.dataMode || null, env.sourceLayer || null]
|
|
1007
|
+
.filter(Boolean).join(' | ');
|
|
1008
|
+
console.log('- ' + (env.envelopeId || '(no id)') + ' ' + (env.status || 'unknown') + health + failures + required + noManifest);
|
|
1009
|
+
if (env.summary) console.log(' ' + env.summary);
|
|
1010
|
+
console.log(' ' + lane + ' packets=' + (env.packetCount || 0) + ' updated=' + formatTime(env.updatedAtMs || env.latestPacketAtMs));
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
function printVerificationEnvelope(envelope, fallbackEnvelopeId) {
|
|
1014
|
+
console.log('Verification envelope:', envelope.envelopeId || fallbackEnvelopeId);
|
|
1015
|
+
if (envelope.summary) console.log('Summary:', envelope.summary);
|
|
1016
|
+
console.log('Status:', envelope.status || 'unknown');
|
|
1017
|
+
const evaluation = envelope.evaluation || {};
|
|
1018
|
+
if (evaluation.health) console.log('Health:', evaluation.health);
|
|
1019
|
+
if (evaluation.noRequiredEvidence) {
|
|
1020
|
+
console.log('Required evidence: none declared - evidence packets do not prove a complete acceptance contract.');
|
|
1021
|
+
} else {
|
|
1022
|
+
console.log('Required evidence:', (evaluation.satisfiedCount || 0) + '/' + (evaluation.requiredCount || 0));
|
|
1023
|
+
}
|
|
1024
|
+
if (evaluation.failedCount) {
|
|
1025
|
+
console.log('Failed packets:', evaluation.failedCount, 'current failures:', evaluation.currentFailureCount || 0);
|
|
1026
|
+
}
|
|
1027
|
+
const packets = Array.isArray(envelope.packets) ? envelope.packets : [];
|
|
1028
|
+
console.log('Packets:', packets.length);
|
|
1029
|
+
packets.slice(-20).forEach((packet) => {
|
|
1030
|
+
const status = packet.stale ? ' stale' : (packet.success === false ? ' failed' : '');
|
|
1031
|
+
const claim = packet.claim ? ' - ' + packet.claim : '';
|
|
1032
|
+
console.log('- ' + (packet.type || 'unknown') + ' ' + (packet.packetId || '') + status + claim);
|
|
1033
|
+
});
|
|
1034
|
+
if (packets.length > 20) {
|
|
1035
|
+
console.log(' ...' + (packets.length - 20) + ' earlier packet(s); rerun with --json for the full envelope');
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
932
1039
|
function buildCommandWorld(response, fallback = {}) {
|
|
933
1040
|
const source = (response && response.staging) || {};
|
|
934
1041
|
const resolution = (response && response.resolution) || {};
|
|
@@ -2752,8 +2859,8 @@ async function pushComponentsCommand(flags) {
|
|
|
2752
2859
|
world: buildCommandWorld(response, { accountId, dataMode, branchName, workspace, host: normalizeBaseUrl(baseUrl), sourceLayer: 'staged' }),
|
|
2753
2860
|
revision: collectVerificationSource(cwd, flags),
|
|
2754
2861
|
assertions: [
|
|
2755
|
-
{
|
|
2756
|
-
{
|
|
2862
|
+
{ id: 'stage', stageMode },
|
|
2863
|
+
{ id: 'staging_lane', value: response.stagingLane }
|
|
2757
2864
|
],
|
|
2758
2865
|
evidenceCategories: ['stage', 'staging_lane'],
|
|
2759
2866
|
rawRefs: { command: 'components stage' },
|
|
@@ -2995,6 +3102,9 @@ function printStageSummary(response, flags) {
|
|
|
2995
3102
|
}
|
|
2996
3103
|
|
|
2997
3104
|
printUnrepresentableChanges(response.unrepresentableChanges || (stage.unrepresentable || []));
|
|
3105
|
+
if (typeof printAccountLanes === 'function') {
|
|
3106
|
+
printAccountLanes(response);
|
|
3107
|
+
}
|
|
2998
3108
|
printComponentCommandResponse('Components stage', response, flags);
|
|
2999
3109
|
}
|
|
3000
3110
|
|
|
@@ -3040,6 +3150,61 @@ function printStatusSummary(response, flags) {
|
|
|
3040
3150
|
printComponentCommandResponse('Components staging', response, flags);
|
|
3041
3151
|
}
|
|
3042
3152
|
|
|
3153
|
+
function printLanesSummary(response, flags) {
|
|
3154
|
+
printBranchContext(response);
|
|
3155
|
+
const lanes = Array.isArray(response.lanes) ? response.lanes : (Array.isArray(response.accountLanes) ? response.accountLanes : []);
|
|
3156
|
+
console.log('Staging lanes for account ' + response.accountId + ':', lanes.length);
|
|
3157
|
+
if (!lanes.length) {
|
|
3158
|
+
console.log('No staged lanes are currently indexed for this account.');
|
|
3159
|
+
return;
|
|
3160
|
+
}
|
|
3161
|
+
lanes.forEach((lane) => printStagingLaneRow(lane));
|
|
3162
|
+
console.log('');
|
|
3163
|
+
console.log('Inspect a lane: remits-cli components entries --lane-id <laneId>');
|
|
3164
|
+
console.log('Or by scope: remits-cli components entries --lane-account-id <id> --cli-user-id <id> --branch <name> [--workspace <name>]');
|
|
3165
|
+
printComponentCommandResponse('Components lanes', response, flags);
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
function printStagingLaneRow(lane) {
|
|
3169
|
+
const world = lane.onTrunk === true ? 'trunk'
|
|
3170
|
+
: lane.onTrunk === false ? 'variant'
|
|
3171
|
+
: 'unknown-world';
|
|
3172
|
+
const ws = lane.workspace ? ' [ws:' + lane.workspace + ']' : ' [shared]';
|
|
3173
|
+
const workset = lane.worksetKnown && lane.worksetCountAsOf != null
|
|
3174
|
+
? ' workset ' + lane.worksetCountAsOf
|
|
3175
|
+
: ' workset unknown';
|
|
3176
|
+
const shared = lane.sharedLane === true ? ' SHARED' : '';
|
|
3177
|
+
const ttl = lane.expiresInSeconds != null ? ' expires ~' + Math.round(lane.expiresInSeconds / 60) + 'm' : '';
|
|
3178
|
+
console.log('- ' + (lane.laneId || lane.stagingLane || '(no lane id)'));
|
|
3179
|
+
console.log(' ' + lane.branchName + ws + ' ' + world + shared + ' overlay ' + (lane.stagedCountAsOf || lane.stagedCount || 0) + workset + ttl);
|
|
3180
|
+
if (lane.userEmail || lane.cliUserId) console.log(' owner: ' + (lane.userEmail || 'user #' + lane.cliUserId) + ' cliUserId=' + lane.cliUserId);
|
|
3181
|
+
if (lane.typeCounts) console.log(' types: ' + Object.entries(lane.typeCounts).map(([k, v]) => k + ':' + v).join(', '));
|
|
3182
|
+
}
|
|
3183
|
+
|
|
3184
|
+
function printEntriesSummary(response, flags) {
|
|
3185
|
+
console.log('Staging lane:', response.stagingLane || response.laneId);
|
|
3186
|
+
console.log('Account:', response.accountId, 'CLI user:', response.cliUserId);
|
|
3187
|
+
console.log('Branch:', response.branchName, 'Workspace:', response.workspace || 'shared');
|
|
3188
|
+
printLaneSummary(response);
|
|
3189
|
+
printComponentTypeCounts(response.entries || []);
|
|
3190
|
+
const entries = Array.isArray(response.entries) ? response.entries : [];
|
|
3191
|
+
if (entries.length) {
|
|
3192
|
+
console.log('');
|
|
3193
|
+
entries.slice(0, flagEnabled(flags.verbose) ? entries.length : 40).forEach((entry) => {
|
|
3194
|
+
const id = entry.componentId != null ? '#' + entry.componentId : '(new)';
|
|
3195
|
+
const name = entry.componentName || entry.name || '';
|
|
3196
|
+
const pathText = entry.path ? ' ' + entry.path : '';
|
|
3197
|
+
const fields = Array.isArray(entry.stagedFields) && entry.stagedFields.length ? ' fields=' + entry.stagedFields.join(',') : '';
|
|
3198
|
+
const inWorkset = entry.stageInWorkset === true ? ' workset' : (entry.stageInWorkset === false ? ' retained' : '');
|
|
3199
|
+
console.log('- ' + (entry.type || entry.componentType || 'component') + ' ' + id + (name ? ' ' + name : '') + inWorkset + fields + pathText);
|
|
3200
|
+
});
|
|
3201
|
+
if (!flagEnabled(flags.verbose) && entries.length > 40) {
|
|
3202
|
+
console.log(' ...' + (entries.length - 40) + ' more; rerun with --verbose or --json');
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
printComponentCommandResponse('Components entries', response, flags);
|
|
3206
|
+
}
|
|
3207
|
+
|
|
3043
3208
|
/**
|
|
3044
3209
|
* What THIS lane holds, separated into the work in flight and the overlay carried along with it.
|
|
3045
3210
|
*
|
|
@@ -3269,6 +3434,85 @@ async function statusComponentsCommand(flags) {
|
|
|
3269
3434
|
return response;
|
|
3270
3435
|
}
|
|
3271
3436
|
|
|
3437
|
+
async function lanesComponentsCommand(flags) {
|
|
3438
|
+
const cwd = process.cwd();
|
|
3439
|
+
ensureLocalState(cwd);
|
|
3440
|
+
const sessionContext = resolveSessionContext(cwd, flags);
|
|
3441
|
+
const { session, accountId } = sessionContext;
|
|
3442
|
+
const baseUrl = flags['base-url'] || session.baseUrl || DEFAULT_BASE_URL;
|
|
3443
|
+
const branchName = flags.branch || currentBranch(cwd);
|
|
3444
|
+
const workspace = resolveWorkspace(cwd, flags);
|
|
3445
|
+
const dataMode = resolveDataMode(flags, session);
|
|
3446
|
+
const api = buildAxios(baseUrl, session.token);
|
|
3447
|
+
|
|
3448
|
+
const response = await loggedPost(api, cwd, '/cli/components', {
|
|
3449
|
+
token: session.token,
|
|
3450
|
+
accountId,
|
|
3451
|
+
branchName,
|
|
3452
|
+
workspace,
|
|
3453
|
+
dataMode,
|
|
3454
|
+
mode: 'lanes'
|
|
3455
|
+
}).then((r) => r.data);
|
|
3456
|
+
|
|
3457
|
+
if (!response.success) {
|
|
3458
|
+
throw new Error(response.message || 'Staging lanes failed');
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
if (flagEnabled(flags.json)) {
|
|
3462
|
+
console.log(JSON.stringify(response, null, 2));
|
|
3463
|
+
return response;
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3466
|
+
printSessionResolutionWarning(sessionContext);
|
|
3467
|
+
printResolvedBaseUrl(baseUrl);
|
|
3468
|
+
console.log('Data mode:', response.dataMode || dataMode);
|
|
3469
|
+
printLanesSummary(response, flags);
|
|
3470
|
+
return response;
|
|
3471
|
+
}
|
|
3472
|
+
|
|
3473
|
+
async function entriesComponentsCommand(flags) {
|
|
3474
|
+
const cwd = process.cwd();
|
|
3475
|
+
ensureLocalState(cwd);
|
|
3476
|
+
const sessionContext = resolveSessionContext(cwd, flags);
|
|
3477
|
+
const { session, accountId } = sessionContext;
|
|
3478
|
+
const baseUrl = flags['base-url'] || session.baseUrl || DEFAULT_BASE_URL;
|
|
3479
|
+
const branchName = flags.branch || currentBranch(cwd);
|
|
3480
|
+
const workspace = resolveWorkspace(cwd, flags);
|
|
3481
|
+
const dataMode = resolveDataMode(flags, session);
|
|
3482
|
+
const api = buildAxios(baseUrl, session.token);
|
|
3483
|
+
|
|
3484
|
+
const response = await loggedPost(api, cwd, '/cli/components', {
|
|
3485
|
+
token: session.token,
|
|
3486
|
+
accountId,
|
|
3487
|
+
branchName,
|
|
3488
|
+
workspace,
|
|
3489
|
+
dataMode,
|
|
3490
|
+
mode: 'entries',
|
|
3491
|
+
laneId: flags['lane-id'] || flags.lane,
|
|
3492
|
+
laneAccountId: flags['lane-account-id'] || flags.ownerAccountId || flags['owner-account-id'],
|
|
3493
|
+
cliUserId: flags['cli-user-id'] || flags.userId || flags['user-id'],
|
|
3494
|
+
laneBranchName: flags['lane-branch'] || flags.targetBranch || flags['target-branch'],
|
|
3495
|
+
laneWorkspace: flags['lane-workspace'] || flags.targetWorkspace || flags['target-workspace'],
|
|
3496
|
+
componentType: flags['component-type'] || flags.type,
|
|
3497
|
+
componentId: flags['component-id'] || flags.id
|
|
3498
|
+
}).then((r) => r.data);
|
|
3499
|
+
|
|
3500
|
+
if (!response.success) {
|
|
3501
|
+
throw new Error(response.message || 'Staging entries failed');
|
|
3502
|
+
}
|
|
3503
|
+
|
|
3504
|
+
if (flagEnabled(flags.json)) {
|
|
3505
|
+
console.log(JSON.stringify(response, null, 2));
|
|
3506
|
+
return response;
|
|
3507
|
+
}
|
|
3508
|
+
|
|
3509
|
+
printSessionResolutionWarning(sessionContext);
|
|
3510
|
+
printResolvedBaseUrl(baseUrl);
|
|
3511
|
+
console.log('Data mode:', response.dataMode || dataMode);
|
|
3512
|
+
printEntriesSummary(response, flags);
|
|
3513
|
+
return response;
|
|
3514
|
+
}
|
|
3515
|
+
|
|
3272
3516
|
async function clearComponentsCommand(flags) {
|
|
3273
3517
|
const cwd = process.cwd();
|
|
3274
3518
|
ensureLocalState(cwd);
|
|
@@ -4560,6 +4804,9 @@ async function testCommand(flags) {
|
|
|
4560
4804
|
printSessionResolutionWarning(sessionContext);
|
|
4561
4805
|
printResolvedBaseUrl(baseUrl);
|
|
4562
4806
|
printStagingLane(branchName, workspace, workspaceSource(cwd, flags));
|
|
4807
|
+
if (start.staging && Array.isArray(start.staging.accountLanes)) {
|
|
4808
|
+
printAccountLanes({ accountLanes: start.staging.accountLanes, branchName, workspace });
|
|
4809
|
+
}
|
|
4563
4810
|
console.log('Test run started:', start.taskId);
|
|
4564
4811
|
runtimeState.currentTestTaskId = start.taskId;
|
|
4565
4812
|
|
|
@@ -4687,6 +4934,7 @@ async function tokenCommand(flags) {
|
|
|
4687
4934
|
variantBranch: data.variantBranch,
|
|
4688
4935
|
workspace: data.workspace !== undefined ? data.workspace : workspace,
|
|
4689
4936
|
stagingLane: data.stagingLane,
|
|
4937
|
+
accountLanes: data.accountLanes,
|
|
4690
4938
|
dataMode: data.dataMode || dataMode,
|
|
4691
4939
|
shortBasePath: data.shortBasePath,
|
|
4692
4940
|
embeddableUrl
|
|
@@ -5059,10 +5307,26 @@ async function verifyCommand(flags, subcommand) {
|
|
|
5059
5307
|
ensureLocalState(cwd);
|
|
5060
5308
|
const sub = String(subcommand || (flags._ && flags._[1]) || 'status').toLowerCase();
|
|
5061
5309
|
|
|
5310
|
+
const sessionContext = resolveSessionContext(cwd, flags);
|
|
5311
|
+
const { session, accountId } = sessionContext;
|
|
5312
|
+
const baseUrl = flags['base-url'] || session.baseUrl || DEFAULT_BASE_URL;
|
|
5313
|
+
const dataMode = resolveDataMode(flags, session);
|
|
5314
|
+
const branchName = flags.branch || currentBranch(cwd);
|
|
5315
|
+
const workspace = resolveWorkspace(cwd, flags);
|
|
5316
|
+
const api = buildAxios(baseUrl, session.token);
|
|
5317
|
+
const activeContext = activeVerificationContext(cwd, flags, session, accountId);
|
|
5318
|
+
|
|
5062
5319
|
if (sub === 'current') {
|
|
5063
|
-
const active = readActiveVerificationEnvelope(cwd);
|
|
5320
|
+
const active = readActiveVerificationEnvelope(cwd, activeContext);
|
|
5321
|
+
printSessionResolutionWarning(sessionContext);
|
|
5322
|
+
printResolvedBaseUrl(baseUrl);
|
|
5323
|
+
console.log('Context:', 'account=' + accountId + ', branch=' + branchName + ', workspace=' + (workspace || 'shared') + ', dataMode=' + dataMode);
|
|
5064
5324
|
if (!active) {
|
|
5065
|
-
|
|
5325
|
+
const legacy = readActiveVerificationEnvelope(cwd);
|
|
5326
|
+
console.log('No active verification envelope for this context.');
|
|
5327
|
+
if (legacy) {
|
|
5328
|
+
console.log('Legacy active envelope ignored for this context:', legacy);
|
|
5329
|
+
}
|
|
5066
5330
|
return;
|
|
5067
5331
|
}
|
|
5068
5332
|
console.log('Active verification envelope:', active);
|
|
@@ -5074,25 +5338,25 @@ async function verifyCommand(flags, subcommand) {
|
|
|
5074
5338
|
if (sub === 'use') {
|
|
5075
5339
|
const envelopeId = flags._ && flags._[2] || flags.envelope || flags['verify-envelope'];
|
|
5076
5340
|
if (!envelopeId) throw new Error('Usage: remits-cli verify use <envelopeId>');
|
|
5077
|
-
writeActiveVerificationEnvelope(cwd, envelopeId);
|
|
5341
|
+
writeActiveVerificationEnvelope(cwd, envelopeId, activeContext);
|
|
5078
5342
|
console.log('Active verification envelope:', envelopeId);
|
|
5343
|
+
console.log('Context:', 'account=' + accountId + ', branch=' + branchName + ', workspace=' + (workspace || 'shared') + ', dataMode=' + dataMode);
|
|
5079
5344
|
return;
|
|
5080
5345
|
}
|
|
5081
5346
|
|
|
5082
5347
|
if (sub === 'clear') {
|
|
5083
|
-
|
|
5084
|
-
|
|
5348
|
+
if (flagEnabled(flags.all)) {
|
|
5349
|
+
writeActiveVerificationEnvelope(cwd, null);
|
|
5350
|
+
writeActiveVerificationContexts(cwd, {});
|
|
5351
|
+
console.log('All active verification envelope pointers cleared for this checkout.');
|
|
5352
|
+
} else {
|
|
5353
|
+
writeActiveVerificationEnvelope(cwd, null, activeContext);
|
|
5354
|
+
console.log('Verification envelope cleared for this context.');
|
|
5355
|
+
console.log('Context:', 'account=' + accountId + ', branch=' + branchName + ', workspace=' + (workspace || 'shared') + ', dataMode=' + dataMode);
|
|
5356
|
+
}
|
|
5085
5357
|
return;
|
|
5086
5358
|
}
|
|
5087
5359
|
|
|
5088
|
-
const sessionContext = resolveSessionContext(cwd, flags);
|
|
5089
|
-
const { session, accountId } = sessionContext;
|
|
5090
|
-
const baseUrl = flags['base-url'] || session.baseUrl || DEFAULT_BASE_URL;
|
|
5091
|
-
const dataMode = resolveDataMode(flags, session);
|
|
5092
|
-
const branchName = flags.branch || currentBranch(cwd);
|
|
5093
|
-
const workspace = resolveWorkspace(cwd, flags);
|
|
5094
|
-
const api = buildAxios(baseUrl, session.token);
|
|
5095
|
-
|
|
5096
5360
|
if (sub === 'start') {
|
|
5097
5361
|
const summary = flags.summary || flags._ && flags._.slice(2).join(' ');
|
|
5098
5362
|
if (!summary) throw new Error('verify start requires --summary "..."');
|
|
@@ -5129,14 +5393,29 @@ async function verifyCommand(flags, subcommand) {
|
|
|
5129
5393
|
});
|
|
5130
5394
|
const envelope = response.envelope;
|
|
5131
5395
|
writeLocalVerificationEnvelope(cwd, envelope);
|
|
5132
|
-
writeActiveVerificationEnvelope(cwd, envelope.envelopeId);
|
|
5396
|
+
writeActiveVerificationEnvelope(cwd, envelope.envelopeId, activeContext);
|
|
5133
5397
|
console.log('Verification envelope started:', envelope.envelopeId);
|
|
5134
5398
|
console.log('Target:', 'account=' + accountId + ', branch=' + branchName + ', workspace=' + (workspace || 'shared') + ', dataMode=' + dataMode);
|
|
5135
5399
|
console.log('Local mirror:', verificationPaths(cwd, envelope.envelopeId).base);
|
|
5136
5400
|
return envelope;
|
|
5137
5401
|
}
|
|
5138
5402
|
|
|
5139
|
-
|
|
5403
|
+
if (sub === 'list' || sub === 'summaries') {
|
|
5404
|
+
const response = await postVerificationCommand(api, cwd, session, accountId, 'list', {
|
|
5405
|
+
max: flags.max || flags.limit || 50
|
|
5406
|
+
});
|
|
5407
|
+
if (flagEnabled(flags.json)) {
|
|
5408
|
+
console.log(JSON.stringify(response, null, 2));
|
|
5409
|
+
return response;
|
|
5410
|
+
}
|
|
5411
|
+
printSessionResolutionWarning(sessionContext);
|
|
5412
|
+
printResolvedBaseUrl(baseUrl);
|
|
5413
|
+
console.log('Verification envelopes:', (response.envelopes || []).length);
|
|
5414
|
+
(response.envelopes || []).forEach((env) => printVerificationSummaryLine(env));
|
|
5415
|
+
return response;
|
|
5416
|
+
}
|
|
5417
|
+
|
|
5418
|
+
const envelopeId = flags.envelope || flags['verify-envelope'] || flags.id || readActiveVerificationEnvelope(cwd, activeContext);
|
|
5140
5419
|
if (!envelopeId) {
|
|
5141
5420
|
throw new Error('No verification envelope selected. Run `remits-cli verify start --summary "..."` or pass --envelope <id>.');
|
|
5142
5421
|
}
|
|
@@ -5168,14 +5447,7 @@ async function verifyCommand(flags, subcommand) {
|
|
|
5168
5447
|
return response.envelope || response;
|
|
5169
5448
|
}
|
|
5170
5449
|
const envelope = response.envelope || {};
|
|
5171
|
-
|
|
5172
|
-
if (envelope.summary) console.log('Summary:', envelope.summary);
|
|
5173
|
-
console.log('Status:', envelope.status || 'unknown');
|
|
5174
|
-
const packets = Array.isArray(envelope.packets) ? envelope.packets : [];
|
|
5175
|
-
console.log('Packets:', packets.length);
|
|
5176
|
-
packets.forEach((packet) => {
|
|
5177
|
-
console.log('- ' + (packet.type || 'unknown') + ' ' + (packet.packetId || '') + (packet.success === false ? ' failed' : ''));
|
|
5178
|
-
});
|
|
5450
|
+
printVerificationEnvelope(envelope, envelopeId);
|
|
5179
5451
|
return envelope;
|
|
5180
5452
|
}
|
|
5181
5453
|
|
|
@@ -5268,6 +5540,24 @@ async function verifyCommand(flags, subcommand) {
|
|
|
5268
5540
|
return response.envelope;
|
|
5269
5541
|
}
|
|
5270
5542
|
|
|
5543
|
+
if (sub === 'abandon' || sub === 'close') {
|
|
5544
|
+
const reason = flags.reason || flags.message || flags._ && flags._.slice(2).join(' ') || 'abandoned';
|
|
5545
|
+
const response = await postVerificationCommand(api, cwd, session, accountId, 'abandon', { envelopeId, reason });
|
|
5546
|
+
writeLocalVerificationEnvelope(cwd, response.envelope);
|
|
5547
|
+
console.log('Envelope abandoned:', envelopeId);
|
|
5548
|
+
return response.envelope;
|
|
5549
|
+
}
|
|
5550
|
+
|
|
5551
|
+
if (sub === 'supersede') {
|
|
5552
|
+
const supersededBy = flags['superseded-by'] || flags.supersededBy || flags.next || flags._ && flags._[2];
|
|
5553
|
+
if (!supersededBy) throw new Error('verify supersede requires --superseded-by <envelopeId>');
|
|
5554
|
+
const reason = flags.reason || flags.message || 'superseded by a newer verification envelope';
|
|
5555
|
+
const response = await postVerificationCommand(api, cwd, session, accountId, 'supersede', { envelopeId, supersededBy, reason });
|
|
5556
|
+
writeLocalVerificationEnvelope(cwd, response.envelope);
|
|
5557
|
+
console.log('Envelope superseded:', envelopeId, '->', supersededBy);
|
|
5558
|
+
return response.envelope;
|
|
5559
|
+
}
|
|
5560
|
+
|
|
5271
5561
|
if (sub === 'status' || sub === 'report') {
|
|
5272
5562
|
let statusPacket = null;
|
|
5273
5563
|
try {
|
|
@@ -10825,6 +11115,23 @@ function printComponentsHelp(subcommand) {
|
|
|
10825
11115
|
console.log('whether another agent is staging alongside you.');
|
|
10826
11116
|
return;
|
|
10827
11117
|
}
|
|
11118
|
+
if (subcommand === 'lanes' || subcommand === 'lane') {
|
|
11119
|
+
console.log('Usage: remits-cli components lanes [--base-url URL] [--account-id ID] [--branch BRANCH] [--workspace NAME] [--json]');
|
|
11120
|
+
console.log('');
|
|
11121
|
+
console.log('Lists every indexed staging lane on the account, across users, branches, and workspaces.');
|
|
11122
|
+
console.log('This is read-only and uses the same lane registry that powers the admin Platforms view.');
|
|
11123
|
+
console.log('Use `components entries --lane-id <id>` to inspect the actual staged files in a lane.');
|
|
11124
|
+
return;
|
|
11125
|
+
}
|
|
11126
|
+
if (subcommand === 'entries' || subcommand === 'entry' || subcommand === 'staged') {
|
|
11127
|
+
console.log('Usage: remits-cli components entries --lane-id ID [--base-url URL] [--account-id ID] [--json|--verbose]');
|
|
11128
|
+
console.log(' remits-cli components entries --lane-account-id ID --cli-user-id ID --branch BRANCH [--workspace NAME]');
|
|
11129
|
+
console.log('');
|
|
11130
|
+
console.log('Reads the authoritative staged entries for one lane from Redis staging keys.');
|
|
11131
|
+
console.log('Use this for review/audit: it does not switch your workspace, impersonate another user,');
|
|
11132
|
+
console.log('clear anything, or affect what your own runs resolve.');
|
|
11133
|
+
return;
|
|
11134
|
+
}
|
|
10828
11135
|
if (subcommand === 'clear') {
|
|
10829
11136
|
console.log('Usage: remits-cli components clear [--base-url URL] [--account-id ID] [--branch BRANCH] [--workspace NAME] [--component-type TYPE] [--component-id ID] [--all] [--json|--verbose]');
|
|
10830
11137
|
console.log('');
|
|
@@ -10846,12 +11153,14 @@ function printComponentsHelp(subcommand) {
|
|
|
10846
11153
|
console.log('`remits-cli components sync --safe`.');
|
|
10847
11154
|
return;
|
|
10848
11155
|
}
|
|
10849
|
-
console.log('Usage: remits-cli components <stage|status|clear|sync|commit|promotion|branches|branch>');
|
|
11156
|
+
console.log('Usage: remits-cli components <stage|status|lanes|entries|clear|sync|commit|promotion|branches|branch>');
|
|
10850
11157
|
console.log('');
|
|
10851
11158
|
console.log('All staging subcommands accept --workspace NAME to isolate a lane on the same branch,');
|
|
10852
11159
|
console.log('so several agents can iterate at once. See: remits-cli workspace --help');
|
|
10853
11160
|
console.log(' remits-cli components stage [--workset|--changed-only] [--base-url URL] [--account-id ID] [--branch BRANCH] [--data-mode test|prod] [--json|--verbose]');
|
|
10854
11161
|
console.log(' remits-cli components status [--base-url URL] [--account-id ID] [--branch BRANCH] [--component-type TYPE --component-id ID] [--json|--verbose]');
|
|
11162
|
+
console.log(' remits-cli components lanes [--base-url URL] [--account-id ID] [--json]');
|
|
11163
|
+
console.log(' remits-cli components entries --lane-id ID [--base-url URL] [--account-id ID] [--json|--verbose]');
|
|
10855
11164
|
console.log(' remits-cli components clear [--base-url URL] [--account-id ID] [--branch BRANCH] [--component-type TYPE] [--component-id ID] [--all] [--json|--verbose]');
|
|
10856
11165
|
console.log(' remits-cli components sync [--safe] [--base-url URL] [--account-id ID] [--branch BRANCH] [--data-mode test|prod] [--force-tombstones] [--dry-run] [--summary]');
|
|
10857
11166
|
console.log(' remits-cli components commit [--safe] [--message "msg"] [--allow-empty true|false] [--skip-git true|false] [--branch BRANCH] [--data-mode test|prod] [--force-tombstones]');
|
|
@@ -10931,12 +11240,16 @@ function printVerifyHelp() {
|
|
|
10931
11240
|
console.log('');
|
|
10932
11241
|
console.log('Envelope lifecycle:');
|
|
10933
11242
|
console.log(' remits-cli verify start --summary "..." [--manifest file.json] [--ticket ID]');
|
|
11243
|
+
console.log(' remits-cli verify list [--max 50] [--json]');
|
|
10934
11244
|
console.log(' remits-cli verify use <envelopeId>');
|
|
10935
11245
|
console.log(' remits-cli verify current');
|
|
10936
|
-
console.log(' remits-cli verify clear');
|
|
11246
|
+
console.log(' remits-cli verify clear [--all]');
|
|
10937
11247
|
console.log(' remits-cli verify show [--envelope ID] [--json]');
|
|
10938
11248
|
console.log(' remits-cli verify status [--envelope ID]');
|
|
10939
11249
|
console.log(' remits-cli verify report [--envelope ID]');
|
|
11250
|
+
console.log(' remits-cli verify abandon --envelope ID --reason "..."');
|
|
11251
|
+
console.log(' remits-cli verify supersede --envelope ID --superseded-by ID [--reason "..."]');
|
|
11252
|
+
console.log(' Active envelopes are scoped by host, account, branch, workspace, and data mode.');
|
|
10940
11253
|
console.log('');
|
|
10941
11254
|
console.log('Manifest and manual evidence:');
|
|
10942
11255
|
console.log(' remits-cli verify manifest --file file.json [--envelope ID]');
|
|
@@ -11034,9 +11347,11 @@ async function main() {
|
|
|
11034
11347
|
console.log(' remits-cli tool status --call-id <callId> [--base-url URL] [--account-id ID] [--data-mode test|prod]');
|
|
11035
11348
|
console.log(' remits-cli workspace [show|use <name>|use --auto|clear] # isolate staging when several agents share a repo');
|
|
11036
11349
|
console.log(' remits-cli verify start --summary "..." [--manifest file.json] # start a verification envelope');
|
|
11037
|
-
console.log(' remits-cli verify [current|use|clear|status|report|attach|test|token|stage|sync|tool]');
|
|
11350
|
+
console.log(' remits-cli verify [current|list|use|clear|show|status|report|attach|abandon|supersede|test|token|stage|sync|tool]');
|
|
11038
11351
|
console.log(' remits-cli components stage [--workset|--changed-only] [--base-url URL] [--account-id ID] [--branch BRANCH] [--workspace NAME] [--data-mode test|prod] [--json|--verbose]');
|
|
11039
11352
|
console.log(' remits-cli components status [--base-url URL] [--account-id ID] [--branch BRANCH] [--workspace NAME] [--component-type TYPE --component-id ID] [--json|--verbose]');
|
|
11353
|
+
console.log(' remits-cli components lanes [--base-url URL] [--account-id ID] [--json]');
|
|
11354
|
+
console.log(' remits-cli components entries --lane-id ID [--base-url URL] [--account-id ID] [--json|--verbose]');
|
|
11040
11355
|
console.log(' remits-cli components clear [--base-url URL] [--account-id ID] [--branch BRANCH] [--workspace NAME] [--component-type TYPE] [--component-id ID] [--all] [--json|--verbose]');
|
|
11041
11356
|
console.log(' remits-cli components sync [--safe] [--base-url URL] [--account-id ID] [--branch BRANCH] [--data-mode test|prod] [--force-tombstones] [--dry-run] [--summary]');
|
|
11042
11357
|
console.log(' remits-cli components commit [--message \"msg\"] [--allow-empty true|false] [--skip-git true|false] [--branch BRANCH] [--data-mode test|prod] [--force-tombstones]');
|
|
@@ -11139,6 +11454,16 @@ async function main() {
|
|
|
11139
11454
|
return;
|
|
11140
11455
|
}
|
|
11141
11456
|
|
|
11457
|
+
if (command === 'components' && (subcommand === 'lanes' || subcommand === 'lane')) {
|
|
11458
|
+
await lanesComponentsCommand(args);
|
|
11459
|
+
return;
|
|
11460
|
+
}
|
|
11461
|
+
|
|
11462
|
+
if (command === 'components' && (subcommand === 'entries' || subcommand === 'entry' || subcommand === 'staged')) {
|
|
11463
|
+
await entriesComponentsCommand(args);
|
|
11464
|
+
return;
|
|
11465
|
+
}
|
|
11466
|
+
|
|
11142
11467
|
if (command === 'components' && subcommand === 'clear') {
|
|
11143
11468
|
await clearComponentsCommand(args);
|
|
11144
11469
|
return;
|
package/package.json
CHANGED
|
@@ -101,6 +101,10 @@ reference named after it.
|
|
|
101
101
|
holds — what a run resolves. The workset is what git says you changed. A full stage makes them differ
|
|
102
102
|
by the size of the repo, and `--changed-only` merges, so it can never shrink an overlay it inherited.
|
|
103
103
|
`components status` prints all three numbers; so does the console. (`component-resolution.md`)
|
|
104
|
+
- **Review other lanes with read-only commands, not SQL.** `components lanes` lists every indexed lane on
|
|
105
|
+
the account, and `components entries --lane-id <id>` shows the actual staged files in one lane without
|
|
106
|
+
changing your workspace or clearing anything. Use these when another agent's workstream is relevant.
|
|
107
|
+
(`component-resolution.md`, `command-reference.md`)
|
|
104
108
|
- **Host and data mode are two independent decisions.** `--base-url` picks the Remits host,
|
|
105
109
|
`--data-mode` picks the data segment on it. Neither implies the other. (`command-reference.md`)
|
|
106
110
|
- **`test run` ignores the stored session data lane.** It defaults to `test` even when `whoami` shows
|
|
@@ -194,6 +194,8 @@ remits-cli data-mode [set test|prod]
|
|
|
194
194
|
remits-cli components stage [--workset | --changed-only] [--branch <name>] [--workspace <name>] [--empty-workset clear] [--data-mode test|prod] [--json|--verbose] # default = FULL SNAPSHOT of the repo; --workset = only what git says changed, lane reconciled to it
|
|
195
195
|
remits-cli workspace [show | use <name> | use --auto | clear]
|
|
196
196
|
remits-cli components status [--branch <name>] [--component-type <type>] [--component-id <id>] [--json|--verbose]
|
|
197
|
+
remits-cli components lanes [--json] # every indexed staging lane on the account
|
|
198
|
+
remits-cli components entries --lane-id <id> [--json|--verbose] # authoritative staged files for one lane
|
|
197
199
|
remits-cli components clear [--branch <name>] [--component-type <type>] [--component-id <id>] [--all] [--json|--verbose] # id alone scopes to one component when unambiguous (ids are type-local; add --component-type if the same id is staged in multiple families); no filter clears the whole branch scope; --all forces the full wipe
|
|
198
200
|
remits-cli components sync [--safe [--yes]] [--branch <name>] [--data-mode test|prod] [--force-tombstones] [--dry-run] [--summary] [--changed-only [--changed-since <ref>]] # gated; on trunk = full repo->DB reconcile, on a variant branch = ComponentVariant overlays only
|
|
199
201
|
remits-cli components commit [--safe] [--message "msg"] [--data-mode test|prod] [--force-tombstones] # --safe gates phase 2; it cannot un-push phase 1
|
|
@@ -211,9 +213,10 @@ remits-cli tools [--branch <name>] [--data-mode test|prod] [--variant-branch <na
|
|
|
211
213
|
remits-cli tool --name <toolName> [--branch <name>] [--input "{...}"] [--data-mode test|prod] [--variant-branch <name|none>] [--timeout-ms 60000] [--async true --wait true]
|
|
212
214
|
remits-cli tool status --call-id <callId> [--data-mode test|prod]
|
|
213
215
|
remits-cli verify start --summary "..." [--manifest file.json] [--ticket ID]
|
|
216
|
+
remits-cli verify list [--max 50] [--json]
|
|
214
217
|
remits-cli verify use <envelopeId>
|
|
215
218
|
remits-cli verify current
|
|
216
|
-
remits-cli verify clear
|
|
219
|
+
remits-cli verify clear [--all]
|
|
217
220
|
remits-cli verify show [--envelope ID] [--json]
|
|
218
221
|
remits-cli verify manifest --file file.json [--envelope ID]
|
|
219
222
|
remits-cli verify manifest --print [--envelope ID]
|
|
@@ -230,6 +233,8 @@ remits-cli verify sync --safe
|
|
|
230
233
|
remits-cli verify tool --name <toolName> [--input "{...}"]
|
|
231
234
|
remits-cli verify status [--envelope ID]
|
|
232
235
|
remits-cli verify report [--envelope ID]
|
|
236
|
+
remits-cli verify abandon --envelope ID --reason "..."
|
|
237
|
+
remits-cli verify supersede --envelope ID --superseded-by <envelopeId> [--reason "..."]
|
|
233
238
|
```
|
|
234
239
|
|
|
235
240
|
### Verification envelopes
|
|
@@ -245,8 +250,11 @@ remits-cli components status
|
|
|
245
250
|
remits-cli verify start --summary "Hosted upload updates an existing profile" --manifest acceptance.json
|
|
246
251
|
```
|
|
247
252
|
|
|
248
|
-
An active envelope is stored
|
|
249
|
-
|
|
253
|
+
An active envelope is stored per command world: `baseUrl + accountId + branch + workspace + dataMode`.
|
|
254
|
+
The legacy `./.remits-cli/verification/active` pointer is still understood for compatibility, but normal
|
|
255
|
+
auto-attachment uses `./.remits-cli/verification/active-contexts.json`, so a localhost envelope does not
|
|
256
|
+
silently capture evidence from a production command. Stage/test/token/tool/sync commands attach evidence
|
|
257
|
+
automatically while an envelope is active for that context. The explicit wrappers do the same thing and
|
|
250
258
|
make the intent visible in terminal history:
|
|
251
259
|
|
|
252
260
|
```bash
|
|
@@ -260,6 +268,10 @@ remits-cli verify report
|
|
|
260
268
|
Existing commands also accept `--verify-envelope <id>` to attach to a specific envelope and
|
|
261
269
|
`--no-verify-envelope` to suppress automatic attachment for one command.
|
|
262
270
|
|
|
271
|
+
Use `remits-cli verify list` to review open envelopes for the account without SQL. If a newer envelope
|
|
272
|
+
replaces an older one, use `verify supersede`; if a duplicate or abandoned attempt should no longer read
|
|
273
|
+
as live work, use `verify abandon`. Both keep the evidence history.
|
|
274
|
+
|
|
263
275
|
The manifest is the proof contract. It should name the world being exercised: repo account, host,
|
|
264
276
|
git/component branch, workspace, data mode, source layer, user journeys, artifacts and hashes, and the
|
|
265
277
|
evidence categories required before the final response may claim the work is done. If the manifest
|
|
@@ -153,9 +153,16 @@ TestMode still uses the committed DB source. Staging remains a dev/verification
|
|
|
153
153
|
- **Confirm the DB version:** `mcp_component_view` reads the live DB source directly (no staging, no compile
|
|
154
154
|
cache), so it is the source of truth for "what was committed."
|
|
155
155
|
- **Ask the CLI what is staged:** `remits-cli components status` lists this lane's staged entries,
|
|
156
|
-
including staged fields, aliases, hashes, and TTLs.
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
including staged fields, aliases, hashes, and TTLs. It also reports the other indexed lanes on the
|
|
157
|
+
account so you can see parallel work before assuming you are alone. The default terminal output is
|
|
158
|
+
concise; pass `--json` or `--verbose` when you need the full staged-entry payload.
|
|
159
|
+
- **Inspect another lane without impersonating it:** `remits-cli components lanes` lists every indexed
|
|
160
|
+
lane on the account; `remits-cli components entries --lane-id <id>` reads the authoritative staged
|
|
161
|
+
files for one lane. These are read-only review surfaces. They do not switch your workspace, clear
|
|
162
|
+
anything, or change what your own test/token/tool runs resolve.
|
|
163
|
+
- **Clear only your own lane:** `remits-cli components clear` removes entries when you intentionally want
|
|
164
|
+
to fall back to DB source. `--all` is scoped to the command's account/user/branch/workspace lane, not
|
|
165
|
+
every lane another agent may be using.
|
|
159
166
|
|
|
160
167
|
### Working alongside other agents: the staging WORKSPACE
|
|
161
168
|
|
|
@@ -198,9 +205,11 @@ commit write `ComponentVariant` overlays for a branch nobody subscribes to).
|
|
|
198
205
|
- Every stage / test run / token / clear prints its `Staging lane:` — if a change seems to have had no
|
|
199
206
|
effect, check that line FIRST. A mismatched lane resolves committed source, which looks identical to
|
|
200
207
|
"the stage did not work".
|
|
201
|
-
- `remits-cli components status`
|
|
202
|
-
|
|
203
|
-
|
|
208
|
+
- `remits-cli components status`, `components stage`, `test run`, and `token` include the current
|
|
209
|
+
account's lane context in their responses. A shared current lane is printed loudly; sibling lanes are
|
|
210
|
+
listed when they matter.
|
|
211
|
+
- `remits-cli components lanes` is the review view across users/branches/workspaces, and
|
|
212
|
+
`remits-cli components entries --lane-id <id>` is the drill-down into actual staged files.
|
|
204
213
|
- `remits-cli components clear --all` is scoped to YOUR lane and never touches another agent's.
|
|
205
214
|
|
|
206
215
|
### A lane holds an OVERLAY; your workset is a different number
|
|
@@ -270,6 +270,22 @@ interchangeable:
|
|
|
270
270
|
A missing answer is printed as `unknown`, never as `0`: "git could not answer" and "git says nothing
|
|
271
271
|
changed" are different facts and only one of them is a number.
|
|
272
272
|
|
|
273
|
+
##### Review lanes without changing them
|
|
274
|
+
|
|
275
|
+
`components status` is still the normal first read: it tells you which world this checkout resolves,
|
|
276
|
+
what this lane holds, and whether other account lanes are live. For review/debugging, use the dedicated
|
|
277
|
+
read-only surfaces:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
remits-cli components lanes
|
|
281
|
+
remits-cli components entries --lane-id <id>
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
`components lanes` shows every indexed lane on the account across users, branches and workspaces.
|
|
285
|
+
`components entries` reads the authoritative staged files for one lane. It does not switch your
|
|
286
|
+
workspace, clear entries, or affect what your own runs resolve. Use it before assuming a shared lane is
|
|
287
|
+
safe to overwrite, and when reviewing another agent's workstream from the CLI.
|
|
288
|
+
|
|
273
289
|
**THE STAGE-BEFORE-RUN RULE:** You MUST run `remits-cli components stage` after EVERY file edit and BEFORE any test run or verification. The platform executes whatever version is in the staging cache at the moment the test starts. If you edit a file and run a test without staging first, the test runs the OLD code — not your changes. This is the single most common mistake. Never skip staging. The sequence is always: **edit → stage → run**.
|
|
274
290
|
|
|
275
291
|
This applies to:
|