@remixhq/claude-plugin 0.1.19 → 0.1.21
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/.claude-plugin/plugin.json +1 -1
- package/agents/remix-collab.md +10 -10
- package/dist/hook-post-collab.cjs +3 -7
- package/dist/hook-post-collab.cjs.map +1 -1
- package/dist/hook-pre-git.cjs +6 -6
- package/dist/hook-pre-git.cjs.map +1 -1
- package/dist/hook-stop-collab.cjs +34 -40
- package/dist/hook-stop-collab.cjs.map +1 -1
- package/dist/hook-user-prompt.cjs +9 -13
- package/dist/hook-user-prompt.cjs.map +1 -1
- package/dist/index.js +3 -7
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.cjs +17 -352
- package/dist/mcp-server.cjs.map +1 -1
- package/package.json +3 -7
- package/skills/review-merge-request/SKILL.md +2 -2
- package/skills/safe-collab-workflow/SKILL.md +13 -15
- package/skills/submit-change-step/SKILL.md +25 -54
- package/skills/sync-and-reconcile/SKILL.md +2 -2
- package/dist/historical.d.ts +0 -31
- package/dist/historical.js +0 -443
- package/dist/historical.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@remixhq/claude-plugin",
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.21",
|
|
7
7
|
description: "Claude Code plugin for Remix collaboration workflows",
|
|
8
8
|
homepage: "https://github.com/RemixDotOne/remix-claude-plugin",
|
|
9
9
|
license: "MIT",
|
|
@@ -30,10 +30,6 @@ var package_default = {
|
|
|
30
30
|
".": {
|
|
31
31
|
types: "./dist/index.d.ts",
|
|
32
32
|
import: "./dist/index.js"
|
|
33
|
-
},
|
|
34
|
-
"./historical": {
|
|
35
|
-
types: "./dist/historical.d.ts",
|
|
36
|
-
import: "./dist/historical.js"
|
|
37
33
|
}
|
|
38
34
|
},
|
|
39
35
|
scripts: {
|
|
@@ -45,8 +41,8 @@ var package_default = {
|
|
|
45
41
|
prepack: "npm run build"
|
|
46
42
|
},
|
|
47
43
|
dependencies: {
|
|
48
|
-
"@remixhq/core": "^0.1.
|
|
49
|
-
"@remixhq/mcp": "^0.1.
|
|
44
|
+
"@remixhq/core": "^0.1.15",
|
|
45
|
+
"@remixhq/mcp": "^0.1.16"
|
|
50
46
|
},
|
|
51
47
|
devDependencies: {
|
|
52
48
|
"@types/node": "^25.4.0",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/metadata.ts"],"sourcesContent":["{\n \"name\": \"@remixhq/claude-plugin\",\n \"version\": \"0.1.
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/metadata.ts"],"sourcesContent":["{\n \"name\": \"@remixhq/claude-plugin\",\n \"version\": \"0.1.21\",\n \"description\": \"Claude Code plugin for Remix collaboration workflows\",\n \"homepage\": \"https://github.com/RemixDotOne/remix-claude-plugin\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/RemixDotOne/remix-claude-plugin.git\"\n },\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"files\": [\n \"dist\",\n \".claude-plugin/plugin.json\",\n \".mcp.json\",\n \"skills\",\n \"hooks\",\n \"agents\"\n ],\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"postbuild\": \"node -e \\\"const fs=require('node:fs'); for (const p of ['dist/mcp-server.cjs','dist/hook-pre-git.cjs','dist/hook-user-prompt.cjs','dist/hook-post-collab.cjs','dist/hook-stop-collab.cjs']) fs.chmodSync(p, 0o755);\\\"\",\n \"dev\": \"tsx src/mcp-server.ts\",\n \"typecheck\": \"tsc -p tsconfig.json --noEmit\",\n \"test\": \"node --import tsx --test src/**/*.test.ts\",\n \"prepack\": \"npm run build\"\n },\n \"dependencies\": {\n \"@remixhq/core\": \"^0.1.15\",\n \"@remixhq/mcp\": \"^0.1.16\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.4.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.9.3\"\n }\n}\n","import pkg from \"../package.json\";\n\nexport const pluginMetadata = {\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n pluginId: \"remix\",\n agentName: \"remix-collab\",\n};\n"],"mappings":";;;AAAA;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,UAAY;AAAA,EACZ,SAAW;AAAA,EACX,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,EACT;AAAA,EACA,MAAQ;AAAA,EACR,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,eAAiB;AAAA,IACf,QAAU;AAAA,EACZ;AAAA,EACA,OAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAW;AAAA,IACT,KAAK;AAAA,MACH,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,WAAa;AAAA,IACb,KAAO;AAAA,IACP,WAAa;AAAA,IACb,MAAQ;AAAA,IACR,SAAW;AAAA,EACb;AAAA,EACA,cAAgB;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EAClB;AAAA,EACA,iBAAmB;AAAA,IACjB,eAAe;AAAA,IACf,MAAQ;AAAA,IACR,KAAO;AAAA,IACP,YAAc;AAAA,EAChB;AACF;;;AC/CO,IAAM,iBAAiB;AAAA,EAC5B,MAAM,gBAAI;AAAA,EACV,SAAS,gBAAI;AAAA,EACb,aAAa,gBAAI;AAAA,EACjB,UAAU;AAAA,EACV,WAAW;AACb;","names":[]}
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -21451,33 +21451,6 @@ async function pruneTerminalAsyncJobs() {
|
|
|
21451
21451
|
}).map((job) => deleteAsyncJob(job.id))
|
|
21452
21452
|
);
|
|
21453
21453
|
}
|
|
21454
|
-
async function awaitAsyncJob(params) {
|
|
21455
|
-
const pollIntervalMs = Math.max(50, params.pollIntervalMs ?? 500);
|
|
21456
|
-
const deadline = Date.now() + params.timeoutMs;
|
|
21457
|
-
let lastSeen = null;
|
|
21458
|
-
while (Date.now() < deadline) {
|
|
21459
|
-
const job = await readAsyncJob(params.jobId);
|
|
21460
|
-
if (job) {
|
|
21461
|
-
lastSeen = job;
|
|
21462
|
-
if (job.status === "completed") return { status: "completed", job };
|
|
21463
|
-
if (job.status === "failed") return { status: "failed", job };
|
|
21464
|
-
} else if (lastSeen) {
|
|
21465
|
-
return { status: "timeout", job: lastSeen };
|
|
21466
|
-
} else {
|
|
21467
|
-
return { status: "timeout", job: null };
|
|
21468
|
-
}
|
|
21469
|
-
const remaining = deadline - Date.now();
|
|
21470
|
-
if (remaining <= 0) break;
|
|
21471
|
-
await new Promise((resolve) => setTimeout(resolve, Math.min(pollIntervalMs, remaining)));
|
|
21472
|
-
}
|
|
21473
|
-
const final = await readAsyncJob(params.jobId);
|
|
21474
|
-
if (final) {
|
|
21475
|
-
if (final.status === "completed") return { status: "completed", job: final };
|
|
21476
|
-
if (final.status === "failed") return { status: "failed", job: final };
|
|
21477
|
-
return { status: "timeout", job: final };
|
|
21478
|
-
}
|
|
21479
|
-
return { status: "timeout", job: lastSeen };
|
|
21480
|
-
}
|
|
21481
21454
|
function getBaselinePath(params) {
|
|
21482
21455
|
return import_path6.default.join(getBaselinesRoot(), `${buildLaneStateKey(params)}.json`);
|
|
21483
21456
|
}
|
|
@@ -21872,11 +21845,6 @@ function normalizeJob2(input) {
|
|
|
21872
21845
|
metadata: input.metadata ?? {}
|
|
21873
21846
|
};
|
|
21874
21847
|
}
|
|
21875
|
-
async function enqueuePendingFinalizeJob(input) {
|
|
21876
|
-
const job = normalizeJob2(input);
|
|
21877
|
-
await writeJsonAtomic(getJobPath(job.id), job);
|
|
21878
|
-
return job;
|
|
21879
|
-
}
|
|
21880
21848
|
async function readPendingFinalizeJob(jobId) {
|
|
21881
21849
|
try {
|
|
21882
21850
|
const raw = await import_promises18.default.readFile(getJobPath(jobId), "utf8");
|
|
@@ -23587,28 +23555,6 @@ async function processClaimedPendingFinalizeJobInner(params) {
|
|
|
23587
23555
|
warnings: []
|
|
23588
23556
|
};
|
|
23589
23557
|
}
|
|
23590
|
-
async function enqueueCapturedFinalizeTurn(params) {
|
|
23591
|
-
return enqueuePendingFinalizeJob({
|
|
23592
|
-
status: "queued",
|
|
23593
|
-
repoRoot: params.repoRoot,
|
|
23594
|
-
repoFingerprint: params.repoFingerprint,
|
|
23595
|
-
currentAppId: params.currentAppId,
|
|
23596
|
-
laneId: params.laneId,
|
|
23597
|
-
threadId: params.threadId,
|
|
23598
|
-
branchName: params.branchName,
|
|
23599
|
-
prompt: params.prompt,
|
|
23600
|
-
assistantResponse: params.assistantResponse,
|
|
23601
|
-
baselineSnapshotId: params.baselineSnapshotId,
|
|
23602
|
-
baselineServerHeadHash: params.baselineServerHeadHash,
|
|
23603
|
-
currentSnapshotId: params.currentSnapshotId,
|
|
23604
|
-
idempotencyKey: params.idempotencyKey,
|
|
23605
|
-
error: null,
|
|
23606
|
-
retryCount: 0,
|
|
23607
|
-
lastAttemptAt: null,
|
|
23608
|
-
nextRetryAt: params.nextRetryAt ?? null,
|
|
23609
|
-
metadata: params.metadata ?? {}
|
|
23610
|
-
});
|
|
23611
|
-
}
|
|
23612
23558
|
async function drainPendingFinalizeQueue(params) {
|
|
23613
23559
|
await prunePendingFinalizeJobs();
|
|
23614
23560
|
const jobs = await listPendingFinalizeJobs();
|
|
@@ -23629,199 +23575,6 @@ async function drainPendingFinalizeQueue(params) {
|
|
|
23629
23575
|
}
|
|
23630
23576
|
return results;
|
|
23631
23577
|
}
|
|
23632
|
-
var FINALIZE_AWAIT_INIT_POST_TIMEOUT_MS = 6e4;
|
|
23633
|
-
function collectWarnings(value) {
|
|
23634
|
-
if (!Array.isArray(value)) return [];
|
|
23635
|
-
return value.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
23636
|
-
}
|
|
23637
|
-
var FINALIZE_QUEUED_WARNING = "Queued only: the local Remix turn was captured, but no remote change step or collab turn exists yet. Drain or await finalize before merge-related flows.";
|
|
23638
|
-
async function collabFinalizeTurn(params) {
|
|
23639
|
-
const repoRoot = await findGitRoot(params.cwd);
|
|
23640
|
-
const binding = await ensureActiveLaneBinding({
|
|
23641
|
-
repoRoot,
|
|
23642
|
-
api: params.api,
|
|
23643
|
-
operation: "`remix collab finalize-turn`"
|
|
23644
|
-
});
|
|
23645
|
-
if (!binding) {
|
|
23646
|
-
throw new RemixError("Repository is not bound to Remix.", {
|
|
23647
|
-
exitCode: 2,
|
|
23648
|
-
hint: "Run `remix collab init` first."
|
|
23649
|
-
});
|
|
23650
|
-
}
|
|
23651
|
-
const prompt = params.prompt.trim();
|
|
23652
|
-
const assistantResponse = params.assistantResponse.trim();
|
|
23653
|
-
if (!prompt) throw new RemixError("Prompt is required.", { exitCode: 2 });
|
|
23654
|
-
if (!assistantResponse) throw new RemixError("Assistant response is required.", { exitCode: 2 });
|
|
23655
|
-
if (params.diff?.trim()) {
|
|
23656
|
-
throw new RemixError("External diff submission is no longer supported for `finalize_turn`.", {
|
|
23657
|
-
exitCode: 2,
|
|
23658
|
-
hint: "Finalize turns now capture the real workspace boundary from the local snapshot store."
|
|
23659
|
-
});
|
|
23660
|
-
}
|
|
23661
|
-
const pendingInit = await findPendingAsyncJob({
|
|
23662
|
-
repoRoot,
|
|
23663
|
-
branchName: binding.branchName ?? null,
|
|
23664
|
-
kind: "init"
|
|
23665
|
-
});
|
|
23666
|
-
if (pendingInit) {
|
|
23667
|
-
throw new RemixError("Cannot finalize a turn while the initial Remix import is still processing.", {
|
|
23668
|
-
exitCode: 2,
|
|
23669
|
-
hint: `Init job ${pendingInit.id} is still in the background queue. Run \`remix collab status\` to check progress.`
|
|
23670
|
-
});
|
|
23671
|
-
}
|
|
23672
|
-
const pendingInitPost = await findPendingAsyncJob({
|
|
23673
|
-
repoRoot,
|
|
23674
|
-
branchName: binding.branchName ?? null,
|
|
23675
|
-
kind: "init_post"
|
|
23676
|
-
});
|
|
23677
|
-
if (pendingInitPost) {
|
|
23678
|
-
const result = await awaitAsyncJob({
|
|
23679
|
-
jobId: pendingInitPost.id,
|
|
23680
|
-
timeoutMs: FINALIZE_AWAIT_INIT_POST_TIMEOUT_MS,
|
|
23681
|
-
pollIntervalMs: 500
|
|
23682
|
-
});
|
|
23683
|
-
if (result.status === "failed") {
|
|
23684
|
-
throw new RemixError("The initial Remix import failed; this turn cannot be recorded.", {
|
|
23685
|
-
exitCode: 2,
|
|
23686
|
-
hint: (result.job?.error ? `Last error: ${result.job.error}
|
|
23687
|
-
|
|
23688
|
-
` : "") + "Run `remix collab init` again to retry \u2014 the post-init drainer cleared the local binding so this is safe."
|
|
23689
|
-
});
|
|
23690
|
-
}
|
|
23691
|
-
if (result.status === "timeout") {
|
|
23692
|
-
throw new RemixError("Timed out waiting for the initial Remix import to finish provisioning.", {
|
|
23693
|
-
exitCode: 2,
|
|
23694
|
-
hint: `Init post job ${pendingInitPost.id} did not complete within ${Math.round(
|
|
23695
|
-
FINALIZE_AWAIT_INIT_POST_TIMEOUT_MS / 1e3
|
|
23696
|
-
)}s. Run \`remix collab status\` to check progress, then retry once it reports ready.`
|
|
23697
|
-
});
|
|
23698
|
-
}
|
|
23699
|
-
}
|
|
23700
|
-
const pendingReAnchor = await findPendingAsyncJob({
|
|
23701
|
-
repoRoot,
|
|
23702
|
-
branchName: binding.branchName ?? null,
|
|
23703
|
-
kind: "re_anchor"
|
|
23704
|
-
});
|
|
23705
|
-
if (pendingReAnchor) {
|
|
23706
|
-
throw new RemixError("Cannot finalize a turn while a re-anchor is still processing.", {
|
|
23707
|
-
exitCode: 2,
|
|
23708
|
-
hint: `Re-anchor job ${pendingReAnchor.id} is still in the background queue. Run \`remix collab status\` to check progress.`
|
|
23709
|
-
});
|
|
23710
|
-
}
|
|
23711
|
-
const detected = await collabDetectRepoState({
|
|
23712
|
-
api: params.api,
|
|
23713
|
-
cwd: repoRoot,
|
|
23714
|
-
allowBranchMismatch: params.allowBranchMismatch
|
|
23715
|
-
});
|
|
23716
|
-
if (detected.status === "not_bound") {
|
|
23717
|
-
throw new RemixError("Repository is not bound to Remix.", {
|
|
23718
|
-
code: "not_bound",
|
|
23719
|
-
exitCode: 2,
|
|
23720
|
-
hint: detected.hint
|
|
23721
|
-
});
|
|
23722
|
-
}
|
|
23723
|
-
if (detected.status === "branch_binding_missing" || detected.status === "family_ambiguous") {
|
|
23724
|
-
throw new RemixError(detected.hint || "Current branch is not ready for Remix recording.", {
|
|
23725
|
-
code: detected.status,
|
|
23726
|
-
exitCode: 2,
|
|
23727
|
-
hint: detected.hint
|
|
23728
|
-
});
|
|
23729
|
-
}
|
|
23730
|
-
if (detected.status === "metadata_conflict" || detected.status === "branch_mismatch") {
|
|
23731
|
-
throw new RemixError("Repository must be realigned before finalizing the turn.", {
|
|
23732
|
-
code: detected.status,
|
|
23733
|
-
exitCode: 2,
|
|
23734
|
-
hint: detected.hint
|
|
23735
|
-
});
|
|
23736
|
-
}
|
|
23737
|
-
if (detected.status === "missing_head" || detected.status === "remote_error") {
|
|
23738
|
-
throw new RemixError(detected.hint || "Failed to determine the current repo state.", {
|
|
23739
|
-
code: detected.status,
|
|
23740
|
-
exitCode: 1,
|
|
23741
|
-
hint: detected.hint
|
|
23742
|
-
});
|
|
23743
|
-
}
|
|
23744
|
-
if (detected.repoState === "server_only_changed") {
|
|
23745
|
-
throw new RemixError("Server changes must be pulled locally before finalizing this turn.", {
|
|
23746
|
-
code: "pull_required",
|
|
23747
|
-
exitCode: 2,
|
|
23748
|
-
hint: detected.hint
|
|
23749
|
-
});
|
|
23750
|
-
}
|
|
23751
|
-
if (detected.repoState === "external_local_base_changed") {
|
|
23752
|
-
throw new RemixError("The local checkout must be re-anchored before finalizing this turn.", {
|
|
23753
|
-
code: "re_anchor_required",
|
|
23754
|
-
exitCode: 2,
|
|
23755
|
-
hint: detected.hint
|
|
23756
|
-
});
|
|
23757
|
-
}
|
|
23758
|
-
const baseline = await readLocalBaseline({
|
|
23759
|
-
repoFingerprint: binding.repoFingerprint,
|
|
23760
|
-
laneId: binding.laneId,
|
|
23761
|
-
repoRoot
|
|
23762
|
-
});
|
|
23763
|
-
if (!baseline) {
|
|
23764
|
-
throw new RemixError("Local Remix baseline is missing for this lane.", {
|
|
23765
|
-
exitCode: 2,
|
|
23766
|
-
hint: "Run `remix collab re-anchor` to create a fresh baseline."
|
|
23767
|
-
});
|
|
23768
|
-
}
|
|
23769
|
-
const snapshot = await captureLocalSnapshot({
|
|
23770
|
-
repoRoot,
|
|
23771
|
-
repoFingerprint: binding.repoFingerprint,
|
|
23772
|
-
laneId: binding.laneId,
|
|
23773
|
-
branchName: binding.branchName
|
|
23774
|
-
});
|
|
23775
|
-
const mode = snapshot.snapshotHash === baseline.lastSnapshotHash ? "no_diff_turn" : "changed_turn";
|
|
23776
|
-
const idempotencyKey = params.idempotencyKey?.trim() || buildDeterministicIdempotencyKey({
|
|
23777
|
-
kind: "collab_finalize_turn_boundary_v1",
|
|
23778
|
-
appId: binding.currentAppId,
|
|
23779
|
-
laneId: binding.laneId,
|
|
23780
|
-
baselineSnapshotId: baseline.lastSnapshotId,
|
|
23781
|
-
baselineServerHeadHash: baseline.lastServerHeadHash,
|
|
23782
|
-
currentSnapshotId: snapshot.id,
|
|
23783
|
-
currentSnapshotHash: snapshot.snapshotHash,
|
|
23784
|
-
repoState: detected.repoState,
|
|
23785
|
-
prompt,
|
|
23786
|
-
assistantResponse
|
|
23787
|
-
});
|
|
23788
|
-
const awaitingDeadlineMs = typeof params.awaitingUsageDeadlineMs === "number" && params.awaitingUsageDeadlineMs > 0 ? params.awaitingUsageDeadlineMs : null;
|
|
23789
|
-
const nextRetryAt = awaitingDeadlineMs === null ? null : new Date(Date.now() + awaitingDeadlineMs).toISOString();
|
|
23790
|
-
const job = await enqueueCapturedFinalizeTurn({
|
|
23791
|
-
repoRoot,
|
|
23792
|
-
repoFingerprint: binding.repoFingerprint,
|
|
23793
|
-
currentAppId: binding.currentAppId,
|
|
23794
|
-
laneId: binding.laneId,
|
|
23795
|
-
threadId: binding.threadId,
|
|
23796
|
-
branchName: binding.branchName,
|
|
23797
|
-
prompt,
|
|
23798
|
-
assistantResponse,
|
|
23799
|
-
baselineSnapshotId: baseline.lastSnapshotId,
|
|
23800
|
-
baselineServerHeadHash: baseline.lastServerHeadHash,
|
|
23801
|
-
currentSnapshotId: snapshot.id,
|
|
23802
|
-
idempotencyKey,
|
|
23803
|
-
metadata: {
|
|
23804
|
-
remoteUrl: binding.remoteUrl,
|
|
23805
|
-
defaultBranch: binding.defaultBranch,
|
|
23806
|
-
actor: params.actor ?? null,
|
|
23807
|
-
repoState: detected.repoState,
|
|
23808
|
-
turnUsage: params.turnUsage ?? null,
|
|
23809
|
-
promptedAt: typeof params.promptedAt === "string" && params.promptedAt.trim() ? params.promptedAt.trim() : null
|
|
23810
|
-
},
|
|
23811
|
-
nextRetryAt
|
|
23812
|
-
});
|
|
23813
|
-
return {
|
|
23814
|
-
mode,
|
|
23815
|
-
idempotencyKey,
|
|
23816
|
-
queued: true,
|
|
23817
|
-
jobId: job.id,
|
|
23818
|
-
repoState: detected.repoState,
|
|
23819
|
-
changeStep: null,
|
|
23820
|
-
collabTurn: null,
|
|
23821
|
-
autoSync: null,
|
|
23822
|
-
warnings: [FINALIZE_QUEUED_WARNING, ...collectWarnings(detected.warnings)]
|
|
23823
|
-
};
|
|
23824
|
-
}
|
|
23825
23578
|
var FINALIZE_PREFLIGHT_FAILURE_CODES = [
|
|
23826
23579
|
// Repo has no .remix/ binding at all. Fix: `remix collab init`.
|
|
23827
23580
|
"not_bound",
|
|
@@ -56076,7 +55829,6 @@ async function resolveConfig(_opts) {
|
|
|
56076
55829
|
// node_modules/@remixhq/mcp/dist/index.js
|
|
56077
55830
|
var import_path16 = __toESM(require("path"), 1);
|
|
56078
55831
|
var import_child_process = require("child_process");
|
|
56079
|
-
var import_child_process2 = require("child_process");
|
|
56080
55832
|
var import_fs3 = require("fs");
|
|
56081
55833
|
var import_path17 = __toESM(require("path"), 1);
|
|
56082
55834
|
async function createRemixTokenProvider(config2) {
|
|
@@ -56536,14 +56288,6 @@ var recordTurnInputSchema = {
|
|
|
56536
56288
|
allowBranchMismatch: external_exports.boolean().optional(),
|
|
56537
56289
|
idempotencyKey: external_exports.string().trim().min(1).optional()
|
|
56538
56290
|
};
|
|
56539
|
-
var finalizeTurnInputSchema = {
|
|
56540
|
-
...commonRequestFieldsSchema,
|
|
56541
|
-
prompt: external_exports.string().trim().min(1),
|
|
56542
|
-
assistantResponse: external_exports.string().trim().min(1),
|
|
56543
|
-
sync: external_exports.boolean().optional(),
|
|
56544
|
-
allowBranchMismatch: external_exports.boolean().optional(),
|
|
56545
|
-
idempotencyKey: external_exports.string().trim().min(1).optional()
|
|
56546
|
-
};
|
|
56547
56291
|
var previewInputSchema = {
|
|
56548
56292
|
...commonRequestFieldsSchema
|
|
56549
56293
|
};
|
|
@@ -56713,17 +56457,6 @@ var addDataSchema = external_exports.object({
|
|
|
56713
56457
|
changeStep: genericRecordSchema
|
|
56714
56458
|
});
|
|
56715
56459
|
var recordTurnDataSchema = genericRecordSchema;
|
|
56716
|
-
var finalizeTurnDataSchema = external_exports.object({
|
|
56717
|
-
mode: external_exports.enum(["changed_turn", "no_diff_turn"]),
|
|
56718
|
-
idempotencyKey: external_exports.string().min(1),
|
|
56719
|
-
queued: external_exports.boolean(),
|
|
56720
|
-
jobId: external_exports.string().nullable(),
|
|
56721
|
-
repoState: external_exports.string().nullable(),
|
|
56722
|
-
changeStep: genericRecordSchema.nullable(),
|
|
56723
|
-
collabTurn: genericRecordSchema.nullable(),
|
|
56724
|
-
autoSync: genericRecordSchema.nullable(),
|
|
56725
|
-
warnings: external_exports.array(external_exports.string())
|
|
56726
|
-
});
|
|
56727
56460
|
var drainFinalizeQueueDataSchema = external_exports.object({
|
|
56728
56461
|
processed: external_exports.number().int().nonnegative(),
|
|
56729
56462
|
results: external_exports.array(genericRecordSchema)
|
|
@@ -56803,7 +56536,6 @@ var remixSuccessSchema = makeSuccessSchema(remixDataSchema);
|
|
|
56803
56536
|
var checkoutSuccessSchema = makeSuccessSchema(checkoutDataSchema);
|
|
56804
56537
|
var addSuccessSchema = makeSuccessSchema(addDataSchema);
|
|
56805
56538
|
var recordTurnSuccessSchema = makeSuccessSchema(recordTurnDataSchema);
|
|
56806
|
-
var finalizeTurnSuccessSchema = makeSuccessSchema(finalizeTurnDataSchema);
|
|
56807
56539
|
var drainFinalizeQueueSuccessSchema = makeSuccessSchema(drainFinalizeQueueDataSchema);
|
|
56808
56540
|
var syncSuccessSchema = makeSuccessSchema(syncDataSchema);
|
|
56809
56541
|
var reAnchorSuccessSchema = makeSuccessSchema(reAnchorDataSchema);
|
|
@@ -56844,17 +56576,17 @@ function getRecommendedNextActions(status) {
|
|
|
56844
56576
|
return ["Run remix_collab_sync_preview, then remix_collab_sync_apply if the preview is acceptable. This pulls the server delta into the local working tree without rewriting local git history."];
|
|
56845
56577
|
case "re_anchor":
|
|
56846
56578
|
return [
|
|
56847
|
-
"Run remix_collab_re_anchor_preview, then remix_collab_re_anchor_apply. This seeds a local Remix baseline. It is required because no local baseline exists for this lane yet (fresh clone, deleted .remix/ state, or first init didn't seed) \u2014 not because of any specific git operation. After it succeeds,
|
|
56579
|
+
"Run remix_collab_re_anchor_preview, then remix_collab_re_anchor_apply. This seeds a local Remix baseline. It is required because no local baseline exists for this lane yet (fresh clone, deleted .remix/ state, or first init didn't seed) \u2014 not because of any specific git operation. After it succeeds, automatic hook recording can capture completed turns."
|
|
56848
56580
|
];
|
|
56849
56581
|
case "record":
|
|
56850
56582
|
return [
|
|
56851
|
-
"
|
|
56583
|
+
"No MCP recording tool is required. Automatic hook finalization will capture the local boundary at the end of the completed turn; this covers agent edits, manual user edits, git commit, git pull, git merge, git rebase, and git reset."
|
|
56852
56584
|
];
|
|
56853
56585
|
case "reconcile":
|
|
56854
56586
|
return ["Run remix_collab_reconcile_preview before attempting remix_collab_reconcile_apply. Reconcile applies only when both the local workspace and the server lane changed since the last agreed baseline."];
|
|
56855
56587
|
case "await_finalize":
|
|
56856
56588
|
return [
|
|
56857
|
-
"Run remix_collab_drain_finalize_queue before merge-related or recovery flows.
|
|
56589
|
+
"Run remix_collab_drain_finalize_queue before merge-related or recovery flows. Hook recording is queued until the local finalize queue is drained."
|
|
56858
56590
|
];
|
|
56859
56591
|
case "review_queue":
|
|
56860
56592
|
return ["Run remix_collab_review_queue to inspect reviewable merge requests instead of using local git merge flows."];
|
|
@@ -56866,12 +56598,12 @@ function getRecommendedNextActions(status) {
|
|
|
56866
56598
|
return [];
|
|
56867
56599
|
}
|
|
56868
56600
|
}
|
|
56869
|
-
function
|
|
56601
|
+
function collectWarnings(value) {
|
|
56870
56602
|
if (!value || !Array.isArray(value)) return [];
|
|
56871
56603
|
return value.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
56872
56604
|
}
|
|
56873
56605
|
function collectResultWarnings(value) {
|
|
56874
|
-
return
|
|
56606
|
+
return collectWarnings(value.warnings);
|
|
56875
56607
|
}
|
|
56876
56608
|
function truncateText(value, maxChars) {
|
|
56877
56609
|
if (value.length <= maxChars) {
|
|
@@ -56889,17 +56621,6 @@ function truncateText(value, maxChars) {
|
|
|
56889
56621
|
originalChars: value.length
|
|
56890
56622
|
};
|
|
56891
56623
|
}
|
|
56892
|
-
function spawnFinalizeQueueDrainer() {
|
|
56893
|
-
const entrypoint = process.argv[1];
|
|
56894
|
-
if (!entrypoint) return false;
|
|
56895
|
-
const child = (0, import_child_process.spawn)(process.execPath, [...process.execArgv, entrypoint, "--drain-finalize-queue"], {
|
|
56896
|
-
detached: true,
|
|
56897
|
-
stdio: "ignore",
|
|
56898
|
-
env: process.env
|
|
56899
|
-
});
|
|
56900
|
-
child.unref();
|
|
56901
|
-
return true;
|
|
56902
|
-
}
|
|
56903
56624
|
async function drainBeforeMutation(api) {
|
|
56904
56625
|
const results = await drainPendingFinalizeQueue({ api });
|
|
56905
56626
|
return results.flatMap((result) => collectResultWarnings(result));
|
|
@@ -56942,7 +56663,7 @@ async function initCollab(params) {
|
|
|
56942
56663
|
data: syncResult,
|
|
56943
56664
|
warnings: collectResultWarnings(result),
|
|
56944
56665
|
recommendedNextActions: syncResult.baselineStatus === "requires_re_anchor" ? [
|
|
56945
|
-
"This checkout has no local Remix baseline yet. Run remix_collab_re_anchor_preview, then remix_collab_re_anchor_apply to seed one. After it succeeds,
|
|
56666
|
+
"This checkout has no local Remix baseline yet. Run remix_collab_re_anchor_preview, then remix_collab_re_anchor_apply to seed one. After it succeeds, automatic hook recording can capture completed turns."
|
|
56946
56667
|
] : syncResult.baselineStatus === "requires_sync" ? [
|
|
56947
56668
|
"Run remix_collab_sync_preview, then remix_collab_sync_apply to pull the server delta and create the first local baseline for this checkout."
|
|
56948
56669
|
] : ["Run remix_collab_status to inspect sync, reconcile, and merge-request readiness before mutating bound-repo state."],
|
|
@@ -57007,36 +56728,6 @@ async function checkoutCollab(params) {
|
|
|
57007
56728
|
}
|
|
57008
56729
|
};
|
|
57009
56730
|
}
|
|
57010
|
-
async function finalizeCollabTurn(params) {
|
|
57011
|
-
const api = await createCollabApiClient();
|
|
57012
|
-
const repoRoot = await findGitRoot(params.cwd);
|
|
57013
|
-
const result = await collabFinalizeTurn({
|
|
57014
|
-
api,
|
|
57015
|
-
cwd: params.cwd,
|
|
57016
|
-
prompt: params.prompt,
|
|
57017
|
-
assistantResponse: params.assistantResponse,
|
|
57018
|
-
sync: params.sync,
|
|
57019
|
-
allowBranchMismatch: params.allowBranchMismatch ?? false,
|
|
57020
|
-
idempotencyKey: params.idempotencyKey ?? null,
|
|
57021
|
-
actor: params.agent,
|
|
57022
|
-
awaitingUsageDeadlineMs: params.awaitingUsageDeadlineMs ?? null
|
|
57023
|
-
});
|
|
57024
|
-
const hasAwaitingDeadline = typeof params.awaitingUsageDeadlineMs === "number" && params.awaitingUsageDeadlineMs > 0;
|
|
57025
|
-
if (result.queued && !hasAwaitingDeadline) {
|
|
57026
|
-
if (!spawnFinalizeQueueDrainer()) {
|
|
57027
|
-
await drainPendingFinalizeQueue({ api });
|
|
57028
|
-
}
|
|
57029
|
-
}
|
|
57030
|
-
return {
|
|
57031
|
-
data: result,
|
|
57032
|
-
warnings: result.warnings,
|
|
57033
|
-
recommendedNextActions: result.queued ? ["Run remix_collab_drain_finalize_queue before merge-related flows if you need this queued turn recorded immediately."] : [],
|
|
57034
|
-
logContext: {
|
|
57035
|
-
repoRoot,
|
|
57036
|
-
appId: result.changeStep?.appId ?? result.collabTurn?.appId ?? null
|
|
57037
|
-
}
|
|
57038
|
-
};
|
|
57039
|
-
}
|
|
57040
56731
|
async function drainFinalizeQueue(params) {
|
|
57041
56732
|
const api = await createCollabApiClient();
|
|
57042
56733
|
const repoRoot = await findGitRoot(params.cwd);
|
|
@@ -57085,9 +56776,9 @@ async function reAnchor(params) {
|
|
|
57085
56776
|
});
|
|
57086
56777
|
return {
|
|
57087
56778
|
data: result,
|
|
57088
|
-
warnings:
|
|
56779
|
+
warnings: collectWarnings(result.warnings),
|
|
57089
56780
|
recommendedNextActions: params.dryRun ? [
|
|
57090
|
-
"Run remix_collab_re_anchor_apply with confirm=true to seed a local Remix baseline for this checkout. Re-anchor is for missing-baseline cases only and does not replace
|
|
56781
|
+
"Run remix_collab_re_anchor_apply with confirm=true to seed a local Remix baseline for this checkout. Re-anchor is for missing-baseline cases only and does not replace automatic hook recording for ordinary local content changes."
|
|
57091
56782
|
] : [],
|
|
57092
56783
|
logContext: {
|
|
57093
56784
|
repoRoot: result.repoRoot,
|
|
@@ -57269,7 +56960,7 @@ async function reconcile(params) {
|
|
|
57269
56960
|
});
|
|
57270
56961
|
return {
|
|
57271
56962
|
data: result,
|
|
57272
|
-
warnings: [...drainWarnings, ...
|
|
56963
|
+
warnings: [...drainWarnings, ...collectWarnings(result.warnings)],
|
|
57273
56964
|
recommendedNextActions: params.dryRun ? ["Run remix_collab_reconcile_apply with confirm=true only if the preview is acceptable. This is the explicit Remix recovery flow for diverged state."] : [],
|
|
57274
56965
|
risks: params.dryRun ? ["Reconcile may upload local history to recover the server lane onto the latest agreed state before future recording continues."] : [],
|
|
57275
56966
|
logContext: {
|
|
@@ -57829,7 +57520,7 @@ function spawnHistoryImportDetached(repoRoot) {
|
|
|
57829
57520
|
const logPath = import_path17.default.join(repoRoot, LOG_REL_PATH);
|
|
57830
57521
|
const out = (0, import_fs3.openSync)(logPath, "a");
|
|
57831
57522
|
const err = (0, import_fs3.openSync)(logPath, "a");
|
|
57832
|
-
const child = (0,
|
|
57523
|
+
const child = (0, import_child_process.spawn)(
|
|
57833
57524
|
"remix",
|
|
57834
57525
|
[
|
|
57835
57526
|
"history",
|
|
@@ -57970,7 +57661,7 @@ function registerCollabTools(server, context) {
|
|
|
57970
57661
|
});
|
|
57971
57662
|
registerTool(server, context, {
|
|
57972
57663
|
name: "remix_collab_init",
|
|
57973
|
-
description: "Import the current repository into Remix and write the local binding file. Synchronous: by the time this tool resolves, the local binding file AND the local Remix baseline are both on disk, so
|
|
57664
|
+
description: "Import the current repository into Remix and write the local binding file. Synchronous: by the time this tool resolves, the local binding file AND the local Remix baseline are both on disk, so automatic hook recording can capture subsequent completed turns. Brand-new init on the default branch typically takes ~10s; non-default-branch init can take 30-90s while the server provisions a feature lane. The result includes `reused: boolean` (false for a brand-new app, true if a binding already existed) plus the canonical app/project identifiers and the dashboard URL. Use forceNew=true only when intentionally creating a new canonical family from scratch in a previously-bound repo; do NOT use forceNew as a retry mechanism for a failed init \u2014 it creates orphan backend apps and triggers canonical-family ambiguity errors on subsequent inits in this directory.",
|
|
57974
57665
|
access: "remote_write",
|
|
57975
57666
|
inputSchema: initInputSchema,
|
|
57976
57667
|
outputSchema: initSuccessSchema,
|
|
@@ -58054,31 +57745,9 @@ function registerCollabTools(server, context) {
|
|
|
58054
57745
|
});
|
|
58055
57746
|
}
|
|
58056
57747
|
});
|
|
58057
|
-
registerTool(server, context, {
|
|
58058
|
-
name: "remix_collab_finalize_turn",
|
|
58059
|
-
description: "Primary turn recorder for the current bound repository. Required: call this exactly once before the final response on every turn that touched a Remix-bound repo. Captures the current boundary locally and queues remote processing. Queued only: no remote change step exists yet until the finalize queue drains. Runtime exception: if this turn's context contains a [Remix runtime status] system note from the Remix UserPromptSubmit hook stating that the Stop hook will record this turn automatically, do NOT call this tool \u2014 the runtime is recording it on your behalf and a manual call would create a duplicate record. The runtime note is the only sanctioned override; trivial prompts, error states, and ambiguity all still require this call.",
|
|
58060
|
-
access: "local_write",
|
|
58061
|
-
inputSchema: finalizeTurnInputSchema,
|
|
58062
|
-
outputSchema: finalizeTurnSuccessSchema,
|
|
58063
|
-
annotations: getAnnotations("local_write", { idempotent: true }),
|
|
58064
|
-
run: async (args) => {
|
|
58065
|
-
const input = external_exports.object(finalizeTurnInputSchema).parse(args);
|
|
58066
|
-
const cwd = resolvePolicyCwd(context.policy, input.cwd);
|
|
58067
|
-
return finalizeCollabTurn({
|
|
58068
|
-
cwd,
|
|
58069
|
-
prompt: input.prompt,
|
|
58070
|
-
assistantResponse: input.assistantResponse,
|
|
58071
|
-
sync: input.sync,
|
|
58072
|
-
allowBranchMismatch: input.allowBranchMismatch ?? false,
|
|
58073
|
-
idempotencyKey: input.idempotencyKey,
|
|
58074
|
-
agent: context.agentMetadata,
|
|
58075
|
-
awaitingUsageDeadlineMs: 3e4
|
|
58076
|
-
});
|
|
58077
|
-
}
|
|
58078
|
-
});
|
|
58079
57748
|
registerTool(server, context, {
|
|
58080
57749
|
name: "remix_collab_drain_finalize_queue",
|
|
58081
|
-
description: "Drain the local finalize queue and record queued
|
|
57750
|
+
description: "Drain the local finalize queue and record queued hook-finalize jobs immediately. NOT required as a precondition for `remix_collab_request_merge` or `remix_collab_reconcile_apply` \u2014 those tools drain the queue internally before they run. Useful only for explicit recovery flows (e.g. status reports `await_finalize` and you want to flush before re-checking). Runtime exception: if this turn's context contains a [Remix runtime status] system note from the Remix UserPromptSubmit hook, the runtime drains the queue automatically in the background; do NOT call this tool unless an explicit recovery flow requires it.",
|
|
58082
57751
|
access: "local_write",
|
|
58083
57752
|
inputSchema: drainFinalizeQueueInputSchema,
|
|
58084
57753
|
outputSchema: drainFinalizeQueueSuccessSchema,
|
|
@@ -58116,7 +57785,7 @@ function registerCollabTools(server, context) {
|
|
|
58116
57785
|
});
|
|
58117
57786
|
registerTool(server, context, {
|
|
58118
57787
|
name: "remix_collab_re_anchor_preview",
|
|
58119
|
-
description: "Preview whether this checkout needs a fresh local Remix baseline. Use only when status reports `re_anchor` (no local baseline exists for this lane yet \u2014 fresh clone, deleted `.remix/` state, or first init didn't seed). Re-anchor does not replace
|
|
57788
|
+
description: "Preview whether this checkout needs a fresh local Remix baseline. Use only when status reports `re_anchor` (no local baseline exists for this lane yet \u2014 fresh clone, deleted `.remix/` state, or first init didn't seed). Re-anchor does not replace automatic hook recording; ordinary local content changes (including merges, pulls, and rebases) are captured at the completed-turn boundary, not by re-anchor.",
|
|
58120
57789
|
access: "read",
|
|
58121
57790
|
inputSchema: previewInputSchema,
|
|
58122
57791
|
outputSchema: reAnchorSuccessSchema,
|
|
@@ -58128,7 +57797,7 @@ function registerCollabTools(server, context) {
|
|
|
58128
57797
|
});
|
|
58129
57798
|
registerTool(server, context, {
|
|
58130
57799
|
name: "remix_collab_re_anchor_apply",
|
|
58131
|
-
description: "Establish a local Remix baseline for the current checkout against the existing app head, without rewriting the local checkout afterward. Required only when status reports `re_anchor` (missing local baseline). It does not replace
|
|
57800
|
+
description: "Establish a local Remix baseline for the current checkout against the existing app head, without rewriting the local checkout afterward. Required only when status reports `re_anchor` (missing local baseline). It does not replace automatic hook recording \u2014 local commits, pulls, merges, and rebases are still captured at the completed-turn boundary.",
|
|
58132
57801
|
access: "local_write",
|
|
58133
57802
|
inputSchema: reAnchorInputSchema,
|
|
58134
57803
|
outputSchema: reAnchorSuccessSchema,
|
|
@@ -60067,7 +59736,7 @@ async function listPendingTurnStateSummaries() {
|
|
|
60067
59736
|
// package.json
|
|
60068
59737
|
var package_default = {
|
|
60069
59738
|
name: "@remixhq/claude-plugin",
|
|
60070
|
-
version: "0.1.
|
|
59739
|
+
version: "0.1.21",
|
|
60071
59740
|
description: "Claude Code plugin for Remix collaboration workflows",
|
|
60072
59741
|
homepage: "https://github.com/RemixDotOne/remix-claude-plugin",
|
|
60073
59742
|
license: "MIT",
|
|
@@ -60094,10 +59763,6 @@ var package_default = {
|
|
|
60094
59763
|
".": {
|
|
60095
59764
|
types: "./dist/index.d.ts",
|
|
60096
59765
|
import: "./dist/index.js"
|
|
60097
|
-
},
|
|
60098
|
-
"./historical": {
|
|
60099
|
-
types: "./dist/historical.d.ts",
|
|
60100
|
-
import: "./dist/historical.js"
|
|
60101
59766
|
}
|
|
60102
59767
|
},
|
|
60103
59768
|
scripts: {
|
|
@@ -60109,8 +59774,8 @@ var package_default = {
|
|
|
60109
59774
|
prepack: "npm run build"
|
|
60110
59775
|
},
|
|
60111
59776
|
dependencies: {
|
|
60112
|
-
"@remixhq/core": "^0.1.
|
|
60113
|
-
"@remixhq/mcp": "^0.1.
|
|
59777
|
+
"@remixhq/core": "^0.1.15",
|
|
59778
|
+
"@remixhq/mcp": "^0.1.16"
|
|
60114
59779
|
},
|
|
60115
59780
|
devDependencies: {
|
|
60116
59781
|
"@types/node": "^25.4.0",
|