@remits/remits-cli 0.1.138 → 0.1.141
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 -3
- package/index.js +241 -5
- package/package.json +1 -1
- package/skills/remits-cli/SKILL.md +17 -0
- package/skills/remits-cli/references/branch-variants.md +37 -1
- package/skills/remits-cli/references/command-reference.md +5 -0
- package/skills/remits-cli/references/component-integrity.md +4 -0
- package/skills/remits-cli/references/component-resolution.md +11 -0
- package/skills/remits-cli/references/development-loop.md +40 -4
- package/skills/remits-cli/references/tool-reference.md +18 -4
- package/skills/remits-cli/references/troubleshooting.md +3 -0
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@ git add -A
|
|
|
33
33
|
git commit -m "sync passing changes"
|
|
34
34
|
git push
|
|
35
35
|
remits-cli components sync --safe # variant branch: gated, dry-runs first, refuses surprises
|
|
36
|
+
remits-cli components sync doctor # read-only sync/promotion/staging diagnosis
|
|
36
37
|
remits-cli components sync
|
|
37
38
|
remits-cli components sync --branch feature_branch --dry-run
|
|
38
39
|
remits-cli components sync --branch feature_branch --dry-run --summary
|
|
@@ -84,7 +85,7 @@ remits-cli install --skills --overwrite true
|
|
|
84
85
|
- `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.
|
|
85
86
|
- 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.
|
|
86
87
|
- `components commit` is a convenience wrapper that performs local git commit/push, then `components sync`, then local `git fetch`/`git pull --ff-only`.
|
|
87
|
-
- `components sync` returns the post-sync branch SHA produced by the platform. `components commit` verifies that `origin/<branch>` and local `HEAD` both match
|
|
88
|
+
- `components sync` returns the post-sync branch SHA produced by the platform. `components sync doctor` is read-only and assembles local HEAD, origin HEAD, platform last-sync SHA, staging shadow risk, promotion freshness, repository mismatch, and the next safe action when sync state is confusing. `components commit` verifies that `origin/<branch>` and local `HEAD` both match the exact synced SHA after the final pull.
|
|
88
89
|
- `components push` is deprecated and currently behaves the same as `components stage`.
|
|
89
90
|
- `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.
|
|
90
91
|
- 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.
|
|
@@ -100,8 +101,8 @@ remits-cli install --skills --overwrite true
|
|
|
100
101
|
- Branch defaults to the current local git branch.
|
|
101
102
|
- Data mode defaults to `test`. For `remits-cli test run`, that default is now enforced even if the most-recent authenticated session for the account is `prod`; a production test run therefore requires an explicit `--data-mode prod` on the command line. Use `remits-cli data-mode set prod` only for production investigation.
|
|
102
103
|
- If the same account is authenticated against more than one host and you omit `--base-url`, the CLI auto-resolves the best matching session and now prints the resolved host. Pass `--base-url` explicitly whenever the target host matters.
|
|
103
|
-
- `--names` is `|`-delimited and may be repeated. A comma
|
|
104
|
-
|
|
104
|
+
- `--names` is `|`-delimited and may be repeated. A comma is part of the selector, so comma-bearing case
|
|
105
|
+
names can be passed literally.
|
|
105
106
|
- Nested help is available before required-argument validation, including `remits-cli test run --help`, `remits-cli components sync --help`, and `remits-cli tool --help`.
|
|
106
107
|
- `components sync --safe` is the recommended agent path on a variant branch. It expands to `--summary --changed-only --fail-on-errors --fail-on-removed`, resolves `--changed-since` from the branch's merge base with trunk when you did not name one (local refs only; it never runs an implicit `git fetch`), and prints the planned writes before mutating unless `--yes` is passed. On trunk there is no plan to gate, so it states what a trunk reconcile does and requires `--yes`.
|
|
107
108
|
- `components sync` has fail-closed safety gates for unattended/agent use. Each exits non-zero instead of printing a wall of JSON: `--changed-only` (fail unless every planned write is a component this checkout edited), `--names-only` (print only `BUCKET type:id name` lines), `--fail-on-removed`, `--fail-on-errors`, and `--expected-removed <type:id>` (repeatable or comma-delimited; implies `--fail-on-removed`, so any removal you did not name fails). `--changed-only` also fails closed when the checkout is not a git working tree, because "git could not answer" must never be read as "nothing changed".
|
package/index.js
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
- L4107 Skill Delivery And TOC Resolution
|
|
12
12
|
- L4417 Auth And Component Staging
|
|
13
13
|
- L5032 Component Summaries, Status, And Sync Gates
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
14
|
+
- L7332 Branches, Promotion, Commit, And Test Runs
|
|
15
|
+
- L9421 Tokens, Tools, Verification, And Config
|
|
16
|
+
- L10848 Service Dashboard And WebSocket Listener
|
|
17
|
+
- L12971 Agent And Ticket Workflows
|
|
18
|
+
- L16566 Help, Auto Update, And Command Dispatch
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
/*
|
|
@@ -5994,6 +5994,234 @@ async function clearComponentsCommand(flags) {
|
|
|
5994
5994
|
return response;
|
|
5995
5995
|
}
|
|
5996
5996
|
|
|
5997
|
+
async function syncDoctorComponentsCommand(rawFlags) {
|
|
5998
|
+
const cwd = process.cwd();
|
|
5999
|
+
const flags = Object.assign({}, rawFlags);
|
|
6000
|
+
ensureLocalState(cwd);
|
|
6001
|
+
const sessionContext = resolveSessionContext(cwd, flags);
|
|
6002
|
+
requireAccountRepoContext(cwd, flags, 'components sync doctor', sessionContext);
|
|
6003
|
+
const { session, accountId } = sessionContext;
|
|
6004
|
+
const baseUrl = flags['base-url'] || session.baseUrl || DEFAULT_BASE_URL;
|
|
6005
|
+
const branchName = flags.branch || currentBranch(cwd);
|
|
6006
|
+
const workspace = resolveWorkspace(cwd, flags);
|
|
6007
|
+
const dataMode = resolveDataMode(flags, session);
|
|
6008
|
+
const api = buildAxios(baseUrl, session.token);
|
|
6009
|
+
|
|
6010
|
+
const statusResponse = await loggedPost(api, cwd, '/cli/components', {
|
|
6011
|
+
token: session.token,
|
|
6012
|
+
accountId,
|
|
6013
|
+
branchName,
|
|
6014
|
+
workspace,
|
|
6015
|
+
dataMode,
|
|
6016
|
+
mode: 'status'
|
|
6017
|
+
}).then((r) => r.data);
|
|
6018
|
+
|
|
6019
|
+
if (!statusResponse.success) {
|
|
6020
|
+
throw new Error(statusResponse.message || 'Staging status failed');
|
|
6021
|
+
}
|
|
6022
|
+
|
|
6023
|
+
statusResponse.freshness = stagingFreshness({
|
|
6024
|
+
head: safeGitValue(cwd, 'git rev-parse HEAD'),
|
|
6025
|
+
originHead: safeGitValue(cwd, 'git rev-parse ' + shellQuote('origin/' + branchName)),
|
|
6026
|
+
lastSyncedSha: statusResponse.branchContext && statusResponse.branchContext.lastSyncedSha,
|
|
6027
|
+
entries: statusResponse.entries,
|
|
6028
|
+
laneSummary: statusResponse.laneSummary,
|
|
6029
|
+
isAncestor: (a, b) => gitIsAncestor(cwd, a, b)
|
|
6030
|
+
});
|
|
6031
|
+
statusResponse.repositoryCheck = repositoryCheck(cwd, statusResponse.branchContext);
|
|
6032
|
+
|
|
6033
|
+
let promotionResponse = null;
|
|
6034
|
+
try {
|
|
6035
|
+
promotionResponse = await loggedPost(api, cwd, '/cli/branches', {
|
|
6036
|
+
token: session.token,
|
|
6037
|
+
accountId,
|
|
6038
|
+
mode: 'promotion',
|
|
6039
|
+
branchName
|
|
6040
|
+
}, { skipSessionLog: true }).then((r) => r.data);
|
|
6041
|
+
} catch (err) {
|
|
6042
|
+
const data = err && err.response && err.response.data;
|
|
6043
|
+
promotionResponse = {
|
|
6044
|
+
success: false,
|
|
6045
|
+
message: data && data.message ? data.message : describeError(err)
|
|
6046
|
+
};
|
|
6047
|
+
}
|
|
6048
|
+
|
|
6049
|
+
const report = buildSyncDoctorReport({
|
|
6050
|
+
accountId,
|
|
6051
|
+
branchName,
|
|
6052
|
+
workspace,
|
|
6053
|
+
dataMode: statusResponse.dataMode || dataMode,
|
|
6054
|
+
baseUrl: normalizeBaseUrl(baseUrl),
|
|
6055
|
+
local: {
|
|
6056
|
+
head: safeGitValue(cwd, 'git rev-parse HEAD'),
|
|
6057
|
+
originHead: safeGitValue(cwd, 'git rev-parse ' + shellQuote('origin/' + branchName)),
|
|
6058
|
+
upstream: safeGitValue(cwd, 'git rev-parse --abbrev-ref --symbolic-full-name @{u}'),
|
|
6059
|
+
aheadBehind: safeGitValue(cwd, 'git rev-list --left-right --count HEAD...origin/' + shellQuote(branchName))
|
|
6060
|
+
},
|
|
6061
|
+
status: statusResponse,
|
|
6062
|
+
promotion: promotionResponse
|
|
6063
|
+
});
|
|
6064
|
+
|
|
6065
|
+
if (flagEnabled(flags.json)) {
|
|
6066
|
+
console.log(JSON.stringify(report, null, 2));
|
|
6067
|
+
return report;
|
|
6068
|
+
}
|
|
6069
|
+
|
|
6070
|
+
printSessionResolutionWarning(sessionContext);
|
|
6071
|
+
printResolvedBaseUrl(baseUrl);
|
|
6072
|
+
printSyncDoctorReport(report);
|
|
6073
|
+
return report;
|
|
6074
|
+
}
|
|
6075
|
+
|
|
6076
|
+
function selectedPromotionEntry(promotion, branchName) {
|
|
6077
|
+
if (!promotion || promotion.success === false) return null;
|
|
6078
|
+
const entries = Array.isArray(promotion.branches) ? promotion.branches : [promotion];
|
|
6079
|
+
return entries.find((entry) => String(entry && entry.branch || '') === String(branchName)) || entries[0] || null;
|
|
6080
|
+
}
|
|
6081
|
+
|
|
6082
|
+
function syncDoctorStagedCount(status) {
|
|
6083
|
+
const laneSummary = status && status.laneSummary || {};
|
|
6084
|
+
const candidates = [laneSummary.stagedCount, laneSummary.count, laneSummary.total, status && status.stagedCount];
|
|
6085
|
+
for (const value of candidates) {
|
|
6086
|
+
const number = Number(value);
|
|
6087
|
+
if (Number.isFinite(number)) return number;
|
|
6088
|
+
}
|
|
6089
|
+
return Array.isArray(status && status.entries) ? status.entries.length : 0;
|
|
6090
|
+
}
|
|
6091
|
+
|
|
6092
|
+
function buildSyncDoctorReport(input) {
|
|
6093
|
+
const status = input.status || {};
|
|
6094
|
+
const promotion = input.promotion || null;
|
|
6095
|
+
const entry = selectedPromotionEntry(promotion, input.branchName);
|
|
6096
|
+
const platform = entry && entry.platform || {};
|
|
6097
|
+
const git = entry && entry.git || {};
|
|
6098
|
+
const branchContext = status.branchContext || {};
|
|
6099
|
+
const stagedCount = syncDoctorStagedCount(status);
|
|
6100
|
+
const report = {
|
|
6101
|
+
success: status.success !== false,
|
|
6102
|
+
accountId: input.accountId,
|
|
6103
|
+
branchName: input.branchName,
|
|
6104
|
+
workspace: input.workspace || null,
|
|
6105
|
+
dataMode: input.dataMode,
|
|
6106
|
+
host: input.baseUrl,
|
|
6107
|
+
local: input.local || {},
|
|
6108
|
+
world: status.variantWorld || null,
|
|
6109
|
+
branchContext,
|
|
6110
|
+
repositoryCheck: status.repositoryCheck || null,
|
|
6111
|
+
staging: {
|
|
6112
|
+
laneId: status.laneSummary && status.laneSummary.laneId || status.stagingLane || null,
|
|
6113
|
+
stagedCount,
|
|
6114
|
+
contentHash: status.laneSummary && status.laneSummary.contentHash || null,
|
|
6115
|
+
freshness: status.freshness || null
|
|
6116
|
+
},
|
|
6117
|
+
platform: {
|
|
6118
|
+
lastSyncedSha: branchContext.lastSyncedSha || null,
|
|
6119
|
+
syncRepository: branchContext.repository || null,
|
|
6120
|
+
mode: branchContextIsTrunk(branchContext) ? 'trunk' : 'variant'
|
|
6121
|
+
},
|
|
6122
|
+
promotion: entry ? {
|
|
6123
|
+
available: true,
|
|
6124
|
+
branch: entry.branch,
|
|
6125
|
+
phase: entry.phase || null,
|
|
6126
|
+
summary: entry.summary || null,
|
|
6127
|
+
remoteBranchHeadSha: git.branchHeadSha || null,
|
|
6128
|
+
remoteTrunkHeadSha: git.trunkHeadSha || null,
|
|
6129
|
+
overlaysComputedFrom: platform.syncedSha || null,
|
|
6130
|
+
overlayFreshness: platform.freshness || null,
|
|
6131
|
+
overridden: platform.overridden,
|
|
6132
|
+
branchOnly: platform.added,
|
|
6133
|
+
tombstoned: platform.removed,
|
|
6134
|
+
drifted: platform.drifted,
|
|
6135
|
+
blockers: entry.blockers || [],
|
|
6136
|
+
nextSteps: entry.nextSteps || []
|
|
6137
|
+
} : {
|
|
6138
|
+
available: false,
|
|
6139
|
+
message: promotion && promotion.message || 'promotion status unavailable'
|
|
6140
|
+
}
|
|
6141
|
+
};
|
|
6142
|
+
report.recommendations = syncDoctorRecommendations(report);
|
|
6143
|
+
return report;
|
|
6144
|
+
}
|
|
6145
|
+
|
|
6146
|
+
function syncDoctorRecommendations(report) {
|
|
6147
|
+
const recs = [];
|
|
6148
|
+
const repo = report.repositoryCheck;
|
|
6149
|
+
if (repo && repo.matches === false) {
|
|
6150
|
+
recs.push('Run sync from the checkout whose origin matches the platform repository: ' + repo.platformRepository + '.');
|
|
6151
|
+
}
|
|
6152
|
+
const freshness = report.staging && report.staging.freshness || {};
|
|
6153
|
+
if (freshness.landedSinceHead === true) {
|
|
6154
|
+
recs.push('Pull the platform-synced commit before trusting this lane: git fetch origin && git pull --ff-only, then re-stage.');
|
|
6155
|
+
}
|
|
6156
|
+
if (freshness.entriesBehindLastSync > 0) {
|
|
6157
|
+
recs.push('Re-stage from the current checkout with `remits-cli components stage --workset`; the lane shadows rows landed after it was staged.');
|
|
6158
|
+
}
|
|
6159
|
+
if ((report.staging && report.staging.stagedCount || 0) > 0) {
|
|
6160
|
+
recs.push('Committed-variant verification will be shadowed by this staging lane; clear it or use an unused --branch with --variant-branch before proving committed source.');
|
|
6161
|
+
}
|
|
6162
|
+
const promo = report.promotion || {};
|
|
6163
|
+
if (promo.available && Array.isArray(promo.blockers) && promo.blockers.length) {
|
|
6164
|
+
recs.push('Do not sync yet; `components promotion` reports blockers. Follow its next steps before mutating.');
|
|
6165
|
+
} else if (promo.available && promo.overlayFreshness && promo.overlayFreshness !== 'current') {
|
|
6166
|
+
recs.push('Stored overlays are stale relative to the branch/trunk pair. Re-read promotion, merge as instructed, then run one gated sync.');
|
|
6167
|
+
}
|
|
6168
|
+
if (report.platform && report.platform.mode === 'variant') {
|
|
6169
|
+
recs.push('Agent landing path: push the branch, run `remits-cli components sync --safe --yes` once, then `git pull --ff-only`.');
|
|
6170
|
+
} else {
|
|
6171
|
+
recs.push('Trunk sync has no dry-run plan. Use `remits-cli components sync --safe --yes` only when you intend the authoritative trunk reconcile.');
|
|
6172
|
+
}
|
|
6173
|
+
recs.push('If a sync times out client-side, treat the result as unknown: observe with `components sync doctor` or `components promotion`; do not put `components sync` in a polling loop.');
|
|
6174
|
+
return Array.from(new Set(recs));
|
|
6175
|
+
}
|
|
6176
|
+
|
|
6177
|
+
function printSyncDoctorReport(report) {
|
|
6178
|
+
console.log('Sync doctor');
|
|
6179
|
+
console.log('Account:', report.accountId);
|
|
6180
|
+
console.log('Data mode:', report.dataMode);
|
|
6181
|
+
console.log('Git branch:', report.branchName);
|
|
6182
|
+
console.log('Workspace:', report.workspace || 'shared default lane');
|
|
6183
|
+
console.log('Mode:', report.platform.mode);
|
|
6184
|
+
console.log('');
|
|
6185
|
+
console.log('Local git:');
|
|
6186
|
+
console.log(' HEAD: ' + short(report.local.head));
|
|
6187
|
+
console.log(' origin HEAD: ' + short(report.local.originHead));
|
|
6188
|
+
if (report.local.upstream) console.log(' upstream: ' + report.local.upstream);
|
|
6189
|
+
if (report.local.aheadBehind) console.log(' HEAD...origin/' + report.branchName + ': ' + report.local.aheadBehind.trim() + ' (left=local, right=remote)');
|
|
6190
|
+
console.log('');
|
|
6191
|
+
console.log('Platform sync:');
|
|
6192
|
+
console.log(' repository: ' + (report.platform.syncRepository || 'unknown'));
|
|
6193
|
+
console.log(' last synced SHA: ' + short(report.platform.lastSyncedSha));
|
|
6194
|
+
if (report.repositoryCheck && report.repositoryCheck.matches === false) {
|
|
6195
|
+
console.log(' REPOSITORY MISMATCH: checkout origin is ' + report.repositoryCheck.checkoutOrigin);
|
|
6196
|
+
}
|
|
6197
|
+
console.log('');
|
|
6198
|
+
console.log('Staging lane:');
|
|
6199
|
+
console.log(' staged entries: ' + report.staging.stagedCount);
|
|
6200
|
+
if (report.staging.contentHash) console.log(' content hash: ' + report.staging.contentHash);
|
|
6201
|
+
printStagingFreshness(report.staging.freshness);
|
|
6202
|
+
console.log('');
|
|
6203
|
+
console.log('Promotion / variant status:');
|
|
6204
|
+
if (report.promotion.available) {
|
|
6205
|
+
console.log(' phase: ' + (report.promotion.phase || 'unknown'));
|
|
6206
|
+
console.log(' remote branch HEAD: ' + short(report.promotion.remoteBranchHeadSha));
|
|
6207
|
+
console.log(' overlays computed from:' + ' ' + short(report.promotion.overlaysComputedFrom) +
|
|
6208
|
+
(report.promotion.overlayFreshness ? ' [' + report.promotion.overlayFreshness + ']' : ''));
|
|
6209
|
+
console.log(' overlays: overridden ' + (report.promotion.overridden ?? 'unknown') +
|
|
6210
|
+
', branch-only ' + (report.promotion.branchOnly ?? 'unknown') +
|
|
6211
|
+
', tombstoned ' + (report.promotion.tombstoned ?? 'unknown') +
|
|
6212
|
+
', drifted ' + (report.promotion.drifted ?? 'unknown'));
|
|
6213
|
+
if (report.promotion.blockers && report.promotion.blockers.length) {
|
|
6214
|
+
console.log(' blockers: ' + report.promotion.blockers.length);
|
|
6215
|
+
report.promotion.blockers.slice(0, 8).forEach((b) => console.log(' - ' + b.code + ': ' + b.message));
|
|
6216
|
+
}
|
|
6217
|
+
} else {
|
|
6218
|
+
console.log(' unavailable: ' + report.promotion.message);
|
|
6219
|
+
}
|
|
6220
|
+
console.log('');
|
|
6221
|
+
console.log('Recommended next action:');
|
|
6222
|
+
report.recommendations.forEach((line) => console.log(' - ' + line));
|
|
6223
|
+
}
|
|
6224
|
+
|
|
5997
6225
|
async function syncComponentsCommand(rawFlags) {
|
|
5998
6226
|
const cwd = process.cwd();
|
|
5999
6227
|
// `--safe` is a NAME for the gate combination that should be the default agent path, not a new gate.
|
|
@@ -16537,11 +16765,14 @@ function printComponentsHelp(subcommand) {
|
|
|
16537
16765
|
}
|
|
16538
16766
|
if (subcommand === 'sync') {
|
|
16539
16767
|
console.log('Usage: remits-cli components sync [--base-url URL] [--account-id ID] [--branch BRANCH] [--data-mode test|prod] [--force-tombstones] [--dry-run] [--create-variant-branch] [--summary] [--json]');
|
|
16768
|
+
console.log(' remits-cli components sync doctor [--json]');
|
|
16540
16769
|
console.log('');
|
|
16541
16770
|
console.log('On trunk this reconciles the pushed repository into live component rows.');
|
|
16542
16771
|
console.log('On a variant branch this writes ComponentVariant overlays only.');
|
|
16543
16772
|
console.log('--dry-run is only supported on variant branches and writes nothing.');
|
|
16544
16773
|
console.log('--summary prints compact counts, removals/tombstones, errors, skipped items, and warnings.');
|
|
16774
|
+
console.log('`sync doctor` is read-only. It assembles local HEAD, origin HEAD, platform last sync,');
|
|
16775
|
+
console.log('staging shadow risk, promotion freshness, repository mismatch, and the next safe action.');
|
|
16545
16776
|
console.log('');
|
|
16546
16777
|
console.log('Agent safety gates (each exits non-zero instead of printing a wall of JSON):');
|
|
16547
16778
|
console.log(' --safe THE RECOMMENDED PATH on a variant branch. Expands to');
|
|
@@ -17084,6 +17315,11 @@ async function main() {
|
|
|
17084
17315
|
return;
|
|
17085
17316
|
}
|
|
17086
17317
|
|
|
17318
|
+
if (command === 'components' && subcommand === 'sync' && String(args._ && args._[2] || '').toLowerCase() === 'doctor') {
|
|
17319
|
+
await syncDoctorComponentsCommand(args);
|
|
17320
|
+
return;
|
|
17321
|
+
}
|
|
17322
|
+
|
|
17087
17323
|
if (command === 'components' && subcommand === 'sync') {
|
|
17088
17324
|
await syncComponentsCommand(args);
|
|
17089
17325
|
return;
|
package/package.json
CHANGED
|
@@ -92,6 +92,12 @@ reference named after it.
|
|
|
92
92
|
"branch" or "verified"; say what was actually proven: Test pass, browser journey, corpus measurement,
|
|
93
93
|
sync mutation, or ticket lifecycle state. (`component-resolution.md`, `branch-variants.md`,
|
|
94
94
|
`development-loop.md`, `support-tickets.md`)
|
|
95
|
+
- **Embeddable verification is browser verification.** For page, widget, form, upload, or other
|
|
96
|
+
browser-facing changes, mint a URL with `remits-cli token` and drive it with `playwright-cli`.
|
|
97
|
+
Prefer this over `curl`: `curl` can prove an HTTP response or inspect an action payload, but it does
|
|
98
|
+
not run JavaScript, Alpine, CSS/assets, redirects, cookies/session handling, uploads, iframes,
|
|
99
|
+
shadow-DOM placement, or websocket behavior. (`development-loop.md`,
|
|
100
|
+
`docs/front-stage/components/embeddable-components.md`, `docs/front-stage/features/web-browser-automation.md`)
|
|
95
101
|
- **Land only from trunk or a real variant branch.** A per-agent/feature branch (`components status` says
|
|
96
102
|
`FEATURE BRANCH … [subscription-fallback]`) is safe to stage and run from — it resolves the same world
|
|
97
103
|
as its target — but `components commit`/`sync` refuse it. Merge into the branch it resolves and land
|
|
@@ -107,6 +113,11 @@ reference named after it.
|
|
|
107
113
|
updating, renaming, and **hard-deleting** rows. Prefer the observable
|
|
108
114
|
`git commit → git push → components sync → git pull`. On trunk it refuses before any git write unless
|
|
109
115
|
you pass `--yes`. (`component-integrity.md`)
|
|
116
|
+
- **Do not hand-roll sync watchers.** A sync is a write; an observation loop must never start a fresh
|
|
117
|
+
`components sync`. Use `remits-cli components sync doctor` and `components promotion` to read sync /
|
|
118
|
+
overlay state. If a sync times out client-side, the result is unknown, not failed; observe before any
|
|
119
|
+
retry. Do not use `setsid`, `nohup`, `disown`, `tmux`, or shell-specific detach tricks to make sync
|
|
120
|
+
lifecycle work. (`development-loop.md`, `branch-variants.md`)
|
|
110
121
|
- **After anyone lands, ask whether your lane is stale: `remits-cli components status`.** A landing clears
|
|
111
122
|
only the lander's lane; yours keeps shadowing their new rows with content staged from the old base.
|
|
112
123
|
`LANDED SINCE YOUR BASE` / `STALE OVERLAY` mean pull, re-stage, then verify — a pass against a stale
|
|
@@ -169,6 +180,12 @@ reference named after it.
|
|
|
169
180
|
component (preferred, because it becomes regression protection) or a browser flow through
|
|
170
181
|
`remits-cli token`. "Just do it" and "that's fine, commit it" are not evidence. If you genuinely
|
|
171
182
|
cannot verify, say what you would need and ask. (`development-loop.md`)
|
|
183
|
+
- **Match the proof to the claim.** A mocked Test is a seam proof; a sync packet is durable source
|
|
184
|
+
movement; a token/browser run is journey proof; a corpus consistency report is repeatability proof. If
|
|
185
|
+
the request says "same file twice", "repeatability", "consistency", "same answer", or "model variance",
|
|
186
|
+
start with a corpus/evaluation or other repeated live measurement under an explicit AI budget; mocked
|
|
187
|
+
seam suites are guardrails, not acceptance. (`development-loop.md`, `component-resolution.md`,
|
|
188
|
+
`docs/front-stage/components/test-components.md`)
|
|
172
189
|
- **`remits-cli evidence` answers "what have I actually run, and in which world?"** Every stage, test,
|
|
173
190
|
token, tool and sync appends one world-stamped line automatically, per actor. Nothing to start,
|
|
174
191
|
nothing to satisfy. Read it before you re-run something, and quote it when you report what you
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
- [Which world does your working tree resolve? (read this before you run anything)](#which-world-does-your-working-tree-resolve-read-this-before-you-run-anything)
|
|
13
13
|
- [Two levers, two different questions](#two-levers-two-different-questions)
|
|
14
14
|
- [The SDLC is identical on a variant branch](#the-sdlc-is-identical-on-a-variant-branch)
|
|
15
|
+
- [Long-running variant sync](#long-running-variant-sync)
|
|
15
16
|
- [Where am I in the promotion loop?](#where-am-i-in-the-promotion-loop)
|
|
16
17
|
- [Subscribing, unsubscribing, retiring](#subscribing-unsubscribing-retiring)
|
|
17
18
|
- [Danger profile on a variant branch (different, not absent)](#danger-profile-on-a-variant-branch-different-not-absent)
|
|
@@ -237,7 +238,7 @@ remits-cli test run --test "Invoice Tests" # the feature_bran
|
|
|
237
238
|
remits-cli test run --test "Invoice Tests" --as-account 101 # ...as the real subscriber
|
|
238
239
|
git add -A && git commit -m "..." && git push origin feature_branch
|
|
239
240
|
remits-cli components sync --dry-run # inspect overrides/additions/tombstones without writes
|
|
240
|
-
remits-cli components sync
|
|
241
|
+
remits-cli components sync --safe --yes # agent/noninteractive: writes ComponentVariant overlays ONLY
|
|
241
242
|
```
|
|
242
243
|
|
|
243
244
|
`components stage` validates changed runtime-compiled source through the active branch/workspace lane,
|
|
@@ -252,6 +253,41 @@ for you, and merging a branch promotes its **deletions** as hard deletes. Do not
|
|
|
252
253
|
`remits-cli components sync --summary --timeout-ms 300000`; the platform may need longer than the default
|
|
253
254
|
60 seconds to create rows, push rename/meta commits, and regenerate account metadata.
|
|
254
255
|
|
|
256
|
+
### Long-running variant sync
|
|
257
|
+
|
|
258
|
+
A variant sync writes durable `ComponentVariant` overlays only. The proof that subscribers can resolve the
|
|
259
|
+
new committed branch source is the overlay set's computed SHA, not the fact that your local process once
|
|
260
|
+
started a sync.
|
|
261
|
+
|
|
262
|
+
Use this shape for agent landings:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
git push origin <branch>
|
|
266
|
+
remits-cli components sync --safe --yes
|
|
267
|
+
git pull --ff-only origin <branch>
|
|
268
|
+
remits-cli components sync doctor
|
|
269
|
+
remits-cli components promotion --branch <branch> --no-fail
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`--safe --yes` skips the interactive prompt after the safe dry-run gates pass; it does not skip the gates.
|
|
273
|
+
If the client times out, the result is **unknown**. Do not immediately re-run `components sync`, and never
|
|
274
|
+
write a polling loop that invokes it. Observe with `components sync doctor` and
|
|
275
|
+
`components promotion --branch <branch> --no-fail`; a read loop may inspect, but only one command should
|
|
276
|
+
start the write.
|
|
277
|
+
|
|
278
|
+
Read the promotion report precisely:
|
|
279
|
+
|
|
280
|
+
- `branch HEAD` in the git section says what the remote branch currently points at.
|
|
281
|
+
- `overlays computed from` in the platform section says what subscribers resolve right now.
|
|
282
|
+
- A cached status or a local process exit is not proof that overlays advanced.
|
|
283
|
+
- Immediately after a sync, metadata refresh and compile caches can lag by a moment; committed-variant
|
|
284
|
+
verification still has to clear or avoid staged overlays first.
|
|
285
|
+
|
|
286
|
+
Host and account provenance are part of this proof. A subscriber can be subscribed to a branch that
|
|
287
|
+
currently stores zero overlays, which means the selected branch resolves trunk behavior. Before comparing
|
|
288
|
+
uploads or browser runs, read the token/test/tool world: host, execution account, component branch,
|
|
289
|
+
`variantBranchSource`, data lane, and resolved database.
|
|
290
|
+
|
|
255
291
|
### Where am I in the promotion loop?
|
|
256
292
|
|
|
257
293
|
```bash
|
|
@@ -246,6 +246,7 @@ remits-cli components lanes [--json] # every indexed sta
|
|
|
246
246
|
remits-cli components entries --lane-id <id> [--json|--verbose] # authoritative staged files for one lane
|
|
247
247
|
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
|
|
248
248
|
remits-cli components sync [--safe [--yes]] [--branch <name>] [--data-mode test|prod] [--force-tombstones] [--dry-run] [--create-variant-branch] [--summary] [--changed-only [--changed-since <ref>]] # gated; on trunk = full repo->DB reconcile, on a variant branch = ComponentVariant overlays only
|
|
249
|
+
remits-cli components sync doctor [--branch <name>] [--json] # read-only: local/remote/platform sync facts, staging shadow risk, promotion freshness, recommended next action
|
|
249
250
|
remits-cli components commit [--yes] [--safe] [--allow-shared-branch] [--create-variant-branch] [--message|-m "msg"] [--data-mode test|prod] [--force-tombstones] [--json [--summary]] # phase 1 merge-stages + compile-validates changed source (never reconciles the lane); on TRUNK refuses before any git write unless --yes; --safe gates variant sync writes
|
|
250
251
|
remits-cli components branches [--json] # branches carrying committed variants, with counts + drift
|
|
251
252
|
remits-cli components branch <name> [--json] # one branch: owner account, overridden / added / removed, drift flags, subscribers
|
|
@@ -579,6 +580,10 @@ For tests specifically:
|
|
|
579
580
|
- `--summary` on `components sync` prints compact counts plus named updated (with the fields that
|
|
580
581
|
changed), renamed, skipped, removal/tombstone, error, and gate details instead of the full payload. A
|
|
581
582
|
trunk sync reports an untouched component under `unchanged`, not `updated`.
|
|
583
|
+
- `components sync doctor` does not mutate. Use it when a sync timed out, status/promotion disagree, or
|
|
584
|
+
you need to know whether staged entries would shadow committed-variant verification. It prints local
|
|
585
|
+
`HEAD`, `origin/<branch>`, platform last-sync SHA, overlay freshness, repository mismatch, and a
|
|
586
|
+
recommended next action.
|
|
582
587
|
- `--json` on `components stage`, `components sync`, `components commit`, and `tool` prints one
|
|
583
588
|
parseable JSON document to stdout. Safety banners and prose go to stderr, and sync safety-gate failures
|
|
584
589
|
are reported inside `gateViolations` with a non-zero exit code instead of appending prose after the JSON.
|
|
@@ -71,6 +71,9 @@ local working tree** — and:
|
|
|
71
71
|
> want it versioned in git, addressable by a stable id, or discoverable by another agent, it is not
|
|
72
72
|
> auxiliary. Symptom to recognize: *"I added `new_Foo.groovy`, synced, and it neither appeared on the account
|
|
73
73
|
> nor got renamed."* Check the sidecar's `auxiliary` flag first.
|
|
74
|
+
>
|
|
75
|
+
> For durable Test suites that should be part of the promotion confirmation set, keep `auxiliary: false` and
|
|
76
|
+
> add `regression: true`. The admin Test runner can select only those suites without hand-picking every case.
|
|
74
77
|
|
|
75
78
|
**The single most important consequence:** the id in a component's **filename is load-bearing**. If a file's id
|
|
76
79
|
no longer matches its DB row (a renumber or move across ids), the next sync will **create a duplicate at the
|
|
@@ -90,6 +93,7 @@ every live component present at its real id, and nothing extra.
|
|
|
90
93
|
| `remits-cli components stage` (alias: deprecated `push`) | **Redis staging cache only.** Never mutates the DB or git. The safe iteration surface. A plain stage or `--workset` RECONCILES the lane (entries outside the manifest are dropped); `--changed-only` merges. | none for the DB; a lane you share with another agent is reconciled by the first two |
|
|
91
94
|
| `remits-cli components status` | Reads this lane's staging scope (account/user/branch/workspace) and branch resolution, and lists every other lane on the branch. | none |
|
|
92
95
|
| `remits-cli components clear` | Clears THIS lane's staging cache without changing DB or git. Never touches another workspace lane. | none |
|
|
96
|
+
| `remits-cli components sync doctor` | Reads local git, platform status, staging freshness, repository match, and promotion/overlay freshness. It is the safe diagnostic when sync state is confusing. | none |
|
|
93
97
|
| `remits-cli components sync` **on trunk** | **Server-side git→DB reconcile of the whole account** (create/update/**delete**/rename). Reads the pushed remote; ignores local files. | **high** |
|
|
94
98
|
| `remits-cli components sync` **on a variant branch** | Writes `ComponentVariant` overlays for that branch only. Never touches trunk rows or the account's trunk branch. When the checkout identifies a subscribing account, the branch-local `account-info.json` is refreshed for that subscriber; `--dry-run` reports the plan without writes. | medium (a missing file becomes a **tombstone** that hides the component from subscribers) |
|
|
95
99
|
| `remits-cli components commit` | **One shot:** changed-source compile validation (a `--changed-only` MERGE stage, so it never reconciles the lane) + `git add -A` + commit + `git push` + **`components sync`** + `git pull --ff-only`. Blindly stages the *entire* working tree (including any drift) and reconciles it into prod. Inherits the danger of whichever sync mode the branch selects. | **highest on trunk** |
|
|
@@ -64,6 +64,17 @@ source-layer facts the command observed. A staged test packet is proof of the st
|
|
|
64
64
|
is proof of a source transition; a token packet is proof of the browser token's resolution tuple. Those
|
|
65
65
|
are not interchangeable.
|
|
66
66
|
|
|
67
|
+
Use proof words narrowly:
|
|
68
|
+
|
|
69
|
+
| Evidence | What it proves | What it does NOT prove |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `components stage --workset` | The platform accepted the staged workset and compile-checked changed runtime source | Any committed component changed, or any user journey works |
|
|
72
|
+
| `test run` with staged entries | The selected Test passed against this staging lane/world | The committed variant/trunk source passes |
|
|
73
|
+
| `components sync` / sync packet | Durable source moved from the git remote into trunk rows or variant overlays | Browser/upload behavior, or repeated live AI consistency |
|
|
74
|
+
| `components promotion` / `sync doctor` | Which remote SHA and overlay SHA the platform reports now | That a workflow was exercised after the overlay advanced |
|
|
75
|
+
| `token` / browser flow | The browser entry point resolved a host/account/lane/source tuple and the journey worked there | Persisted document fields are stable or equal across repeated runs |
|
|
76
|
+
| `corpus consistency` / repeated live measurement | The same artifact's recorded metrics were stable or unstable across runs in that world | A mocked seam suite caught all customer-facing variance |
|
|
77
|
+
|
|
67
78
|
Use `remits-cli verify report` before summarizing the work. It will say when the evidence only covered
|
|
68
79
|
staged source, when committed variant/trunk proof is missing, when the manifest world does not match the
|
|
69
80
|
packet world, or when later packet facts made an earlier proof stale. Packets carry a lane content hash,
|
|
@@ -159,6 +159,11 @@ Two ways to prove it:
|
|
|
159
159
|
Use a Test when the behavior can be asserted programmatically, a browser when the change is visual.
|
|
160
160
|
Often both.
|
|
161
161
|
|
|
162
|
+
For Embeddables, prefer `playwright-cli` over `curl`. A `curl` request can confirm the server returned
|
|
163
|
+
something or expose a JSON/action payload, but it is not evidence that the user-facing page works:
|
|
164
|
+
JavaScript, Alpine initialization, assets, cookies/session state, redirects, file controls, iframe/embed
|
|
165
|
+
placement, and websocket updates all require a browser.
|
|
166
|
+
|
|
162
167
|
**Never skip verification.** "Just do it" and "that's fine, commit it" are not evidence. If you genuinely
|
|
163
168
|
cannot verify — no Test component, no relevant embeddable — say what you would need and ask how the user
|
|
164
169
|
wants to proceed rather than reporting the work as done.
|
|
@@ -515,6 +520,10 @@ playwright-cli fill "#amount" "500.00"
|
|
|
515
520
|
playwright-cli eval "() => document.querySelector('.total-amount').textContent"
|
|
516
521
|
```
|
|
517
522
|
|
|
523
|
+
Use this browser path for Embeddable acceptance. `curl` is acceptable for narrow diagnostics such as
|
|
524
|
+
checking an HTTP status or inspecting a server-rendered payload, but it does not prove the page initializes
|
|
525
|
+
or behaves correctly in a browser.
|
|
526
|
+
|
|
518
527
|
The `testMode` metadata confirms you're testing against staged changes, not production.
|
|
519
528
|
|
|
520
529
|
**Two different token keys come back, for two different jobs.** When `--path` resolves to an
|
|
@@ -547,13 +556,20 @@ remits-cli tool --name "mcp_firestore_search" --input '{"accountId": <ID>, "coll
|
|
|
547
556
|
|
|
548
557
|
For long-running backend verification, use the Action runner's own async mode (`executionMode:"async"`) and
|
|
549
558
|
poll by `actionRunId` rather than holding a single request open (see `command-reference.md` → *Tool Execution Lifecycle* for why not
|
|
550
|
-
to also stack the CLI `--async` flag)
|
|
559
|
+
to also stack the CLI `--async` flag). For job-style Actions where you need durable Event lifecycle,
|
|
560
|
+
recovery, or interruption, use `executionMode:"event"` instead and poll the same way:
|
|
551
561
|
|
|
552
562
|
```bash
|
|
553
563
|
remits-cli tool --name "mcp_run_action" --input '{"accountId": <ID>, "actionId": <ACTION_ID>, "executionMode": "async", "actionInput": {...}}' --data-mode test
|
|
554
564
|
# then poll: {"controlAction":"status","accountId": <ID>, "actionRunId":"<actionRunId>"}
|
|
555
565
|
```
|
|
556
566
|
|
|
567
|
+
Read the returned world and lifecycle fields before deciding what happened. `dataMode` is the data lane
|
|
568
|
+
the run actually used; `componentSource` / `componentBranch` / `stagingLane` say which source world ran.
|
|
569
|
+
For event mode, `awaiting_delivery` means the Event exists but has not been claimed yet, not that the
|
|
570
|
+
Action failed. If that state persists, use `mcp_event_diagnostics` on the returned `eventId` instead of
|
|
571
|
+
guessing that the queue, Action source, or data lane is wrong.
|
|
572
|
+
|
|
557
573
|
#### Step 5: Iterate If Needed
|
|
558
574
|
|
|
559
575
|
If verification reveals issues, repeat the loop: **edit → stage → run**. Every iteration must include a fresh `remits-cli components stage` after your edits and before the next test run. Never run a test immediately after editing without staging first — the platform will execute the previous version, not your latest changes.
|
|
@@ -630,12 +646,17 @@ IDs or when unexpected deletes/renumbers are present.
|
|
|
630
646
|
Only after those checks pass, and only when the user intends to promote the repo to the platform database:
|
|
631
647
|
|
|
632
648
|
```bash
|
|
633
|
-
# On a VARIANT branch
|
|
649
|
+
# On a VARIANT branch in an agent/noninteractive session — dry-runs first, refuses surprises,
|
|
650
|
+
# and skips only the confirmation prompt, not the gates.
|
|
651
|
+
remits-cli components sync --safe --yes
|
|
652
|
+
git pull --ff-only origin <branch>
|
|
653
|
+
|
|
654
|
+
# On a VARIANT branch in a human interactive shell — same gates, then asks before writing.
|
|
634
655
|
remits-cli components sync --safe
|
|
635
656
|
git pull --ff-only origin <branch>
|
|
636
657
|
|
|
637
658
|
# On TRUNK — there is no plan to gate, so --safe explains what a trunk reconcile does and needs --yes.
|
|
638
|
-
remits-cli components sync
|
|
659
|
+
remits-cli components sync --safe --yes
|
|
639
660
|
git pull --ff-only origin <branch>
|
|
640
661
|
```
|
|
641
662
|
|
|
@@ -655,14 +676,29 @@ remits-cli components sync --safe --expected-removed action:50
|
|
|
655
676
|
|
|
656
677
|
`--force-tombstones` stays explicit and human-owned. Never pass it to get past a refusal.
|
|
657
678
|
|
|
679
|
+
If sync state is confusing, use the read-only diagnostic instead of building shell loops:
|
|
680
|
+
|
|
681
|
+
```bash
|
|
682
|
+
remits-cli components sync doctor
|
|
683
|
+
remits-cli components promotion --branch <branch> --no-fail
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
`components sync doctor` assembles local `HEAD`, `origin/<branch>`, the platform's last synced SHA,
|
|
687
|
+
promotion freshness, staging shadow risk, repository mismatch, and a recommended next action. A client
|
|
688
|
+
timeout does **not** prove the sync failed; it means the result is unknown. Observe before retrying.
|
|
689
|
+
Never put `components sync` inside a polling loop, and do not use shell detach tricks (`setsid`, `nohup`,
|
|
690
|
+
`disown`, `tmux`, ...). A loop may read status/promotion/doctor; it must never start writes.
|
|
691
|
+
|
|
658
692
|
##### Verifying the COMMITTED variant, not your staging
|
|
659
693
|
|
|
660
694
|
After a sync, staged entries still win for CLI-scoped runs, so a test that passes may be testing your
|
|
661
|
-
staging rather than what you just committed. Clear the lane first
|
|
695
|
+
staging rather than what you just committed. Clear the lane first, then verify the subscriber/variant
|
|
696
|
+
world explicitly:
|
|
662
697
|
|
|
663
698
|
```bash
|
|
664
699
|
remits-cli components clear --all
|
|
665
700
|
remits-cli test run --test <id-or-name> --as-account <subscriber-id>
|
|
701
|
+
remits-cli components sync doctor
|
|
666
702
|
```
|
|
667
703
|
|
|
668
704
|
`remits-cli components sync` is the authoritative platform-sync step. It does not perform local git operations,
|
|
@@ -485,9 +485,23 @@ same way (`controlAction:"status"` + `actionRunId`) — the status resolves the
|
|
|
485
485
|
remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name mcp_run_action --input '{"actionId":200,"executionMode":"event","actionRunId":"my-stable-run-id","actionInput":{}}' --data-mode prod
|
|
486
486
|
```
|
|
487
487
|
|
|
488
|
-
|
|
489
|
-
`
|
|
490
|
-
`
|
|
488
|
+
Event-mode start means "the Event was created and dispatched", not "the Action has finished". Returned
|
|
489
|
+
fields on the async/event start: `actionRunId`, `status:"running"`, `executionMode`, `threadGroupingId`,
|
|
490
|
+
`componentSource`, `componentSignature`, and (event mode) `eventId`/`eventStatus` plus `dispatchMode` when
|
|
491
|
+
available. The `status` poll adds `result` on async completion, or `message`/`error` on failure.
|
|
492
|
+
|
|
493
|
+
Event-mode status values to read deliberately:
|
|
494
|
+
|
|
495
|
+
| `status` | Meaning | What to do |
|
|
496
|
+
|---|---|---|
|
|
497
|
+
| `awaiting_delivery` | The backing Event exists but has not been claimed by a worker yet (`eventStatus` is usually `PENDING`/`QUEUED`, `eventStartTime` is null) | Wait briefly, then inspect `eventDelivery` / `eventNode`; use `mcp_event_diagnostics` if it stays there |
|
|
498
|
+
| `running` | The Event was claimed and is processing | Wait or inspect logs/traces by `threadGroupingId` |
|
|
499
|
+
| `completed` | The backing Event reached `SUCCESS` | Read the Action's persisted outputs / activity trail |
|
|
500
|
+
| `failed` | The backing Event reached `FAILURE`, `CANCELED`, or `INTERRUPTED` | Read `eventStatus`, `errorMessage`, alerts, and `mcp_event_diagnostics` |
|
|
501
|
+
|
|
502
|
+
If an old run is stuck at `QUEUED` and never reports `awaiting_delivery` or fresh delivery fields, start a
|
|
503
|
+
new event-mode run after confirming the System Account tools are synced. Do not keep polling a run that was
|
|
504
|
+
created by an older tool version whose dispatch path already missed delivery.
|
|
491
505
|
|
|
492
506
|
Every response (describe, direct, async start, and failures) also states the world the run resolved:
|
|
493
507
|
`executionAccountId`, `componentOwnerAccountId`, `componentSource` (`staged` / `variant` / `db`),
|
|
@@ -501,7 +515,7 @@ closest existing names; check that the lane named there is the one you staged in
|
|
|
501
515
|
|
|
502
516
|
> **In event mode the EVENT is the source of truth, not the promise.** `status` is driven by the Event's
|
|
503
517
|
> own state; the value the dispatch call returned is reported separately as `dispatchResult` and is **not**
|
|
504
|
-
> the Action's result. Read `eventStatus` for the outcome.
|
|
518
|
+
> the Action's result. Read `eventStatus`, `eventStartTime`, and `eventDelivery` for the lifecycle outcome.
|
|
505
519
|
|
|
506
520
|
#### Stopping a run — `controlAction:'interrupt'`
|
|
507
521
|
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
| Tool parameters rejected | Tool schemas may be cached. Run `remits-cli tools` to refresh `.remits-cli/shared/tools/tools.json` with latest schemas. |
|
|
29
29
|
| Tool response missing | Run `remits-cli doctor local-state`, then check `./.remits-cli/actors/<local-agent>/tool-responses/` and any legacy flat `./.remits-cli/tool-responses/` fallback it reports. |
|
|
30
30
|
| Long-running tool times out | For `mcp_run_action`/`mcp_run_agent`, use the tool's own `executionMode:"async"` and poll with a `controlAction:"status"` call (see `command-reference.md` → *Tool Execution Lifecycle*). For other long tools without their own async, use `remits-cli tool --async true` and poll `remits-cli tool status --call-id <callId>`. `--timeout-ms` only adjusts the per-request HTTP timeout; it is not a substitute for async. |
|
|
31
|
+
| `mcp_run_action` event-mode status is `awaiting_delivery` | The backing Event row exists but no worker has claimed it yet. This is a lifecycle state, not an Action failure and not proof of the wrong data lane. Poll once or twice; if it persists, run `mcp_event_diagnostics` with the returned `eventId` and inspect `eventDelivery`, `eventStartTime`, `eventNode`, and queue/action-node health. |
|
|
32
|
+
| An old `mcp_run_action` event-mode run is stuck `QUEUED` | Do not keep trying to recover the stale run in place. Confirm the System Account tools are synced, start a fresh run with a stable `actionRunId`, and poll that. Interrupt/cancel the stale Event if it would confuse later investigation. |
|
|
33
|
+
| `components sync` timed out, or you are unsure whether overlays advanced | Treat the result as **unknown**, not failed. Run `remits-cli components sync doctor` and `remits-cli components promotion --branch <branch> --no-fail`. Do not put `components sync` in a polling loop and do not use shell detach tricks; observation may poll, writes may not. |
|
|
31
34
|
| Need to continue tracking a long Action or Agent after terminal disconnect | Read `./.remits-cli/actors/<local-agent>/tool-responses/<callId>.json` for the returned `actionRunId`/`agentRunId`/`sessionId`/`threadGroupingId` (or the legacy flat fallback if `doctor local-state` reports it there). Re-poll the run with a `controlAction:"status"` call carrying that `actionRunId`/`agentRunId`, or inspect the agent session via `mcp_ai_session_search` with the `sessionId`. |
|
|
32
35
|
| Staged change has no effect in a live (non-CLI) run | Staged overrides resolve only under a CLI TestMode (`branchName`+`cliUserId`). Live webhooks and other non-CLI runtime paths still use the DB (trunk, or the account's subscribed variant). `commit` to make it durable. See `component-resolution.md`. |
|
|
33
36
|
| Need to know an account's shape (role, type, parents, namespace, branch, host/login routes) | Read `resolution` — from the repo's `account-info.json`, or `mcp_account_user_admin` `action:'account'` (cheap), or `mcp_account_view` (full inventory): `role`/`summary`, `type`, `resolvedDatabaseName`, `domainName`/`resolvedDomainName`, `authPath`/`targetPath`, `relationships`, `componentBranch`, plus top-level `componentBranches`. Never infer structure from the account's name. |
|