@mutmutco/codex-plugin 4.6.39 → 4.6.41
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/cli/dist/main.cjs
CHANGED
|
@@ -19611,6 +19611,48 @@ function isValidSecretKey(key) {
|
|
|
19611
19611
|
function stripTrailingCRLF(value) {
|
|
19612
19612
|
return value.replace(/\r\n$|\r$|\n$/, "");
|
|
19613
19613
|
}
|
|
19614
|
+
function countCaptureGroups(source) {
|
|
19615
|
+
let count = 0;
|
|
19616
|
+
let inClass = false;
|
|
19617
|
+
for (let i = 0; i < source.length; i += 1) {
|
|
19618
|
+
const ch = source[i];
|
|
19619
|
+
if (ch === "\\") {
|
|
19620
|
+
i += 1;
|
|
19621
|
+
continue;
|
|
19622
|
+
}
|
|
19623
|
+
if (inClass) {
|
|
19624
|
+
if (ch === "]") inClass = false;
|
|
19625
|
+
continue;
|
|
19626
|
+
}
|
|
19627
|
+
if (ch === "[") {
|
|
19628
|
+
inClass = true;
|
|
19629
|
+
continue;
|
|
19630
|
+
}
|
|
19631
|
+
if (ch !== "(") continue;
|
|
19632
|
+
if (source[i + 1] !== "?") {
|
|
19633
|
+
count += 1;
|
|
19634
|
+
continue;
|
|
19635
|
+
}
|
|
19636
|
+
if (source[i + 2] === "<" && source[i + 3] !== "=" && source[i + 3] !== "!") count += 1;
|
|
19637
|
+
}
|
|
19638
|
+
return count;
|
|
19639
|
+
}
|
|
19640
|
+
function compileExtractRegex(source) {
|
|
19641
|
+
let re;
|
|
19642
|
+
try {
|
|
19643
|
+
re = new RegExp(source);
|
|
19644
|
+
} catch {
|
|
19645
|
+
return { ok: false, reason: "syntax" };
|
|
19646
|
+
}
|
|
19647
|
+
if (countCaptureGroups(source) !== 1) return { ok: false, reason: "capture-groups" };
|
|
19648
|
+
return { ok: true, re };
|
|
19649
|
+
}
|
|
19650
|
+
function extractSingleMatch(text, re) {
|
|
19651
|
+
const flags = re.flags.includes("g") ? re.flags : `${re.flags}g`;
|
|
19652
|
+
const all = [...text.matchAll(new RegExp(re.source, flags))];
|
|
19653
|
+
if (all.length !== 1) return { ok: false, count: all.length };
|
|
19654
|
+
return { ok: true, value: all[0][1] ?? "" };
|
|
19655
|
+
}
|
|
19614
19656
|
var ORG_WIDE_SLUGS = /* @__PURE__ */ new Set([ORG_INFRA_SLUG, "shared", "cloudflare", "docs", "mmi-hub"]);
|
|
19615
19657
|
function classifyTier(slug, _key) {
|
|
19616
19658
|
return ORG_WIDE_SLUGS.has(slug) ? "org" : "project";
|
|
@@ -21231,6 +21273,64 @@ async function secretsSet(deps, key, opts) {
|
|
|
21231
21273
|
}
|
|
21232
21274
|
return putSecret(deps, key, value, opts);
|
|
21233
21275
|
}
|
|
21276
|
+
async function secretsSetFromClipboard(deps, key, opts) {
|
|
21277
|
+
let value;
|
|
21278
|
+
try {
|
|
21279
|
+
if (!isValidSecretKey(key)) {
|
|
21280
|
+
deps.err(`invalid secret key ${JSON.stringify(key)}`);
|
|
21281
|
+
return false;
|
|
21282
|
+
}
|
|
21283
|
+
let re;
|
|
21284
|
+
if (opts.extract !== void 0) {
|
|
21285
|
+
const compiled = compileExtractRegex(opts.extract);
|
|
21286
|
+
if (!compiled.ok) {
|
|
21287
|
+
deps.err(
|
|
21288
|
+
compiled.reason === "syntax" ? "secrets set: --extract is not a valid regular expression \u2014 aborted (nothing written)" : "secrets set: --extract must contain exactly one capture group, e.g. '--token\\s+(\\S+)' \u2014 aborted (nothing written)"
|
|
21289
|
+
);
|
|
21290
|
+
return false;
|
|
21291
|
+
}
|
|
21292
|
+
re = compiled.re;
|
|
21293
|
+
}
|
|
21294
|
+
if (!deps.readClipboard) {
|
|
21295
|
+
deps.err("secrets set: --from-clipboard is not available in this build \u2014 aborted (nothing written)");
|
|
21296
|
+
return false;
|
|
21297
|
+
}
|
|
21298
|
+
let text;
|
|
21299
|
+
try {
|
|
21300
|
+
text = await deps.readClipboard();
|
|
21301
|
+
} catch (e) {
|
|
21302
|
+
deps.err(`secrets set: --from-clipboard: ${e.message}`);
|
|
21303
|
+
return false;
|
|
21304
|
+
}
|
|
21305
|
+
if (re) {
|
|
21306
|
+
const matched = extractSingleMatch(text, re);
|
|
21307
|
+
if (!matched.ok) {
|
|
21308
|
+
deps.err(
|
|
21309
|
+
matched.count === 0 ? "secrets set: --from-clipboard: --extract found no match (0 matches) \u2014 aborted (nothing written)" : `secrets set: --from-clipboard: --extract matched ${matched.count} times \u2014 need exactly one; aborted (nothing written)`
|
|
21310
|
+
);
|
|
21311
|
+
return false;
|
|
21312
|
+
}
|
|
21313
|
+
value = stripTrailingCRLF(matched.value);
|
|
21314
|
+
} else {
|
|
21315
|
+
value = stripTrailingCRLF(text);
|
|
21316
|
+
}
|
|
21317
|
+
if (!value) {
|
|
21318
|
+
deps.err(`secrets set: --from-clipboard: empty value for ${key} \u2014 aborted (nothing written)`);
|
|
21319
|
+
return false;
|
|
21320
|
+
}
|
|
21321
|
+
const ok = await putSecret(deps, key, value, opts);
|
|
21322
|
+
if (ok) deps.log(`set ${key} (${value.length} chars)`);
|
|
21323
|
+
return ok;
|
|
21324
|
+
} finally {
|
|
21325
|
+
if (deps.writeClipboard) {
|
|
21326
|
+
try {
|
|
21327
|
+
await deps.writeClipboard("");
|
|
21328
|
+
} catch (e) {
|
|
21329
|
+
deps.err(`secrets set: warning: could not clear the clipboard \u2014 ${e.message}`);
|
|
21330
|
+
}
|
|
21331
|
+
}
|
|
21332
|
+
}
|
|
21333
|
+
}
|
|
21234
21334
|
var DECLARE_KEY_RE = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
21235
21335
|
var DECLARE_STAGES = /* @__PURE__ */ new Set(["dev", "rc", "main"]);
|
|
21236
21336
|
var DECLARE_CONSUMERS = /* @__PURE__ */ new Set(["runtime", "build", "lambda", "actions", "agent", "box"]);
|
|
@@ -22469,7 +22569,10 @@ async function boardDoctor(options, deps = {}) {
|
|
|
22469
22569
|
const holderProvenDead = Boolean(
|
|
22470
22570
|
evidence.marker && evidence.sessionState === "dead" && isHostSessionId(evidence.marker.session) && !evidence.openPr && !evidence.branch
|
|
22471
22571
|
);
|
|
22472
|
-
const freshMarker = evidence.
|
|
22572
|
+
const freshMarker = evidence.marker ? !claimStampStaleness(evidence.marker, {
|
|
22573
|
+
activityAt: [evidence.lastCommentAt],
|
|
22574
|
+
sessionState: evidence.sessionState
|
|
22575
|
+
}).stale : false;
|
|
22473
22576
|
const bits = [
|
|
22474
22577
|
evidence.marker ? `claim marker ${describeClaimMarker(evidence.marker)} ${formatClaimAge(evidence.markerAgeMs)} old` + (evidence.sessionState ? `; local session ${evidence.sessionState}` : "") : evidence.failed.includes("comments") ? "claim marker unreadable" : "no claim marker",
|
|
22475
22578
|
evidence.openPr,
|
|
@@ -23709,6 +23812,9 @@ function parseClaimReleases(body) {
|
|
|
23709
23812
|
}
|
|
23710
23813
|
return out;
|
|
23711
23814
|
}
|
|
23815
|
+
function isClaimStampComment(body) {
|
|
23816
|
+
return parseClaimMarkers(body).length > 0 || parseClaimReleases(body).length > 0;
|
|
23817
|
+
}
|
|
23712
23818
|
function renderClaimReleaseBody(release) {
|
|
23713
23819
|
return `Released by \`${formatSessionIdentity(release)}\` at ${release.ts}.
|
|
23714
23820
|
|
|
@@ -23759,19 +23865,27 @@ function boardItemClaim(item) {
|
|
|
23759
23865
|
function claimStampStaleness(marker, evidence = {}, now = Date.now()) {
|
|
23760
23866
|
const times = [marker.ts, ...evidence.activityAt ?? []].map((t) => t ? Date.parse(t) : Number.NaN);
|
|
23761
23867
|
const idleMs = now - Math.max(...times.filter(Number.isFinite));
|
|
23762
|
-
return { stale:
|
|
23868
|
+
if (evidence.sessionState === "live") return { stale: false, idleMs };
|
|
23869
|
+
if (evidence.linkedWork) return { stale: false, idleMs };
|
|
23870
|
+
return { stale: evidence.sessionState === "dead" || idleMs >= CLAIM_STAMP_IDLE_MS, idleMs };
|
|
23763
23871
|
}
|
|
23764
23872
|
function workIsLive(at, now = Date.now()) {
|
|
23765
23873
|
const idle = now - Date.parse(at ?? "");
|
|
23766
23874
|
return !Number.isFinite(idle) || idle < CLAIM_STAMP_IDLE_MS;
|
|
23767
23875
|
}
|
|
23768
23876
|
function claimFromMarker(item, marker, linked = {}, now = Date.now()) {
|
|
23877
|
+
const sessionState = linked.sessionState ?? probeLocalClaimSession(marker);
|
|
23769
23878
|
return {
|
|
23770
23879
|
marker,
|
|
23771
23880
|
holder: describeClaimMarker(marker),
|
|
23772
23881
|
ageMs: now - Date.parse(marker.ts),
|
|
23773
23882
|
currentlyClaimed: item.assignees.length > 0 && item.status === "In Progress",
|
|
23774
|
-
...
|
|
23883
|
+
...sessionState ? { sessionState } : {},
|
|
23884
|
+
...claimStampStaleness(marker, {
|
|
23885
|
+
activityAt: [...linked.activityAt ?? []],
|
|
23886
|
+
linkedWork: linked.linkedWork,
|
|
23887
|
+
...sessionState ? { sessionState } : {}
|
|
23888
|
+
}, now)
|
|
23775
23889
|
};
|
|
23776
23890
|
}
|
|
23777
23891
|
function latestClaimMarkerAuthor(comments) {
|
|
@@ -23783,14 +23897,15 @@ function latestClaimMarkerAuthor(comments) {
|
|
|
23783
23897
|
}
|
|
23784
23898
|
return void 0;
|
|
23785
23899
|
}
|
|
23786
|
-
function classifyClaimableMarker(comments, actor, now = Date.now(), activityAt = [], viewerLogin) {
|
|
23900
|
+
function classifyClaimableMarker(comments, actor, now = Date.now(), activityAt = [], viewerLogin, sessionState) {
|
|
23787
23901
|
const marker = comments ? latestClaimMarker(comments) : void 0;
|
|
23788
23902
|
if (!marker) return { verdict: "claimable" };
|
|
23789
23903
|
const markerBy = comments ? latestClaimMarkerAuthor(comments) : void 0;
|
|
23790
|
-
|
|
23904
|
+
const state = sessionState ?? probeLocalClaimSession(marker);
|
|
23905
|
+
if (isSeatClaimMarker(marker, actor, { viewerLogin: viewerLogin ?? markerBy, markerBy, now, sessionState: state })) {
|
|
23791
23906
|
return { verdict: "owned", holder: describeClaimMarker(marker) };
|
|
23792
23907
|
}
|
|
23793
|
-
if (!claimStampStaleness(marker, { activityAt }, now).stale) {
|
|
23908
|
+
if (!claimStampStaleness(marker, { activityAt, sessionState: state }, now).stale) {
|
|
23794
23909
|
return { verdict: "taken", holder: describeClaimMarker(marker) };
|
|
23795
23910
|
}
|
|
23796
23911
|
return { verdict: "claimable" };
|
|
@@ -23845,10 +23960,12 @@ async function markStaleClaimStamps(scope, readComments, options = {}) {
|
|
|
23845
23960
|
markerBy: markerBy ?? (bucket === "userOwned" ? item.assignees[0] : void 0),
|
|
23846
23961
|
now
|
|
23847
23962
|
});
|
|
23963
|
+
const sessionState = (options.probeSessionState ?? probeLocalClaimSession)(marker);
|
|
23848
23964
|
const prs = (options.pullRequests ?? []).filter((pr) => pr.closesIssues.some((ref) => ref.toLowerCase() === item.ref.toLowerCase()));
|
|
23849
23965
|
item.claim = claimFromMarker(item, marker, {
|
|
23850
23966
|
activityAt: prs.map((pr) => pr.updatedAt),
|
|
23851
|
-
linkedWork: prs.some((pr) => !pr.updatedAt)
|
|
23967
|
+
linkedWork: prs.some((pr) => !pr.updatedAt),
|
|
23968
|
+
...sessionState ? { sessionState } : {}
|
|
23852
23969
|
}, now);
|
|
23853
23970
|
if (ownSeat && bucket !== "userOwned" && bucket !== "claimable") {
|
|
23854
23971
|
kept.pop();
|
|
@@ -23920,9 +24037,25 @@ async function demoteLiveClaimedClaimables(scope, client, actor = describeSessio
|
|
|
23920
24037
|
var CLAIM_SESSION_ACTIVITY_MS = 30 * 6e4;
|
|
23921
24038
|
var CLAIM_SESSION_PROBE_CACHE_MS = 6e4;
|
|
23922
24039
|
var claimSessionProbeCache = /* @__PURE__ */ new Map();
|
|
23923
|
-
function
|
|
24040
|
+
function scanSessionTranscripts(root, matches, now) {
|
|
24041
|
+
const pending = [root];
|
|
24042
|
+
while (pending.length) {
|
|
24043
|
+
const dir = pending.pop();
|
|
24044
|
+
for (const entry of (0, import_node_fs18.readdirSync)(dir, { withFileTypes: true })) {
|
|
24045
|
+
const path2 = (0, import_node_path15.join)(dir, entry.name);
|
|
24046
|
+
if (entry.isDirectory()) pending.push(path2);
|
|
24047
|
+
else if (entry.isFile() && matches(entry.name.toLowerCase())) {
|
|
24048
|
+
return now - (0, import_node_fs18.statSync)(path2).mtimeMs <= CLAIM_SESSION_ACTIVITY_MS ? "live" : "dead";
|
|
24049
|
+
}
|
|
24050
|
+
}
|
|
24051
|
+
}
|
|
24052
|
+
return "dead";
|
|
24053
|
+
}
|
|
24054
|
+
function probeLocalClaimSession(marker, now = Date.now(), roots = {}) {
|
|
23924
24055
|
if (!isHostSessionId(marker.session) || !marker.host || marker.host.toLowerCase() !== (0, import_node_os11.hostname)().toLowerCase()) return void 0;
|
|
23925
|
-
|
|
24056
|
+
const surface = marker.surface?.toLowerCase() ?? "";
|
|
24057
|
+
const kind = surface.startsWith("claude") ? "claude" : surface.startsWith("jerv") || surface.startsWith("pi") ? "jerv" : void 0;
|
|
24058
|
+
if (!kind) return void 0;
|
|
23926
24059
|
const cacheKey = `${marker.host.toLowerCase()}/${marker.session}`;
|
|
23927
24060
|
const cached = claimSessionProbeCache.get(cacheKey);
|
|
23928
24061
|
if (cached && now - cached.checkedAt <= CLAIM_SESSION_PROBE_CACHE_MS) return cached.state;
|
|
@@ -23930,21 +24063,10 @@ function probeLocalClaimSession(marker, now = Date.now()) {
|
|
|
23930
24063
|
claimSessionProbeCache.set(cacheKey, { checkedAt: now, state });
|
|
23931
24064
|
return state;
|
|
23932
24065
|
};
|
|
23933
|
-
|
|
23934
|
-
|
|
23935
|
-
const
|
|
23936
|
-
|
|
23937
|
-
while (pending.length) {
|
|
23938
|
-
const dir = pending.pop();
|
|
23939
|
-
for (const entry of (0, import_node_fs18.readdirSync)(dir, { withFileTypes: true })) {
|
|
23940
|
-
const path2 = (0, import_node_path15.join)(dir, entry.name);
|
|
23941
|
-
if (entry.isDirectory()) pending.push(path2);
|
|
23942
|
-
else if (entry.isFile() && entry.name.toLowerCase() === wanted) {
|
|
23943
|
-
return remember(now - (0, import_node_fs18.statSync)(path2).mtimeMs <= CLAIM_SESSION_ACTIVITY_MS ? "live" : "dead");
|
|
23944
|
-
}
|
|
23945
|
-
}
|
|
23946
|
-
}
|
|
23947
|
-
return remember("dead");
|
|
24066
|
+
try {
|
|
24067
|
+
const session = marker.session.toLowerCase();
|
|
24068
|
+
const state = kind === "claude" ? scanSessionTranscripts(roots.claude ?? (0, import_node_path15.join)((0, import_node_os11.homedir)(), ".claude", "projects"), (name) => name === `${session}.jsonl`, now) : scanSessionTranscripts(roots.jerv ?? (0, import_node_path15.join)((0, import_node_os11.homedir)(), ".jerv", "agent", "sessions"), (name) => name.endsWith(`_${session}.jsonl`), now);
|
|
24069
|
+
return remember(state);
|
|
23948
24070
|
} catch {
|
|
23949
24071
|
return remember("unverifiable");
|
|
23950
24072
|
}
|
|
@@ -23992,7 +24114,7 @@ async function gatherClaimLiveness(client, repo, number, fetchOpenPulls) {
|
|
|
23992
24114
|
out.marker = latestClaimMarker(rows);
|
|
23993
24115
|
if (!out.marker) out.releasedAt = latestClaimRelease(rows)?.ts;
|
|
23994
24116
|
for (let i = comments.length - 1; i >= 0; i -= 1) {
|
|
23995
|
-
if (comments[i].created_at && !
|
|
24117
|
+
if (comments[i].created_at && !isClaimStampComment(rows[i].body)) {
|
|
23996
24118
|
out.lastCommentAt = comments[i].created_at;
|
|
23997
24119
|
break;
|
|
23998
24120
|
}
|
|
@@ -24067,7 +24189,7 @@ function liveEvidenceLines(evidence, repo) {
|
|
|
24067
24189
|
if (evidence.marker && evidence.sessionState === "live") {
|
|
24068
24190
|
live.push(`claim session ${describeClaimMarker(evidence.marker)} has recent local transcript activity`);
|
|
24069
24191
|
} else if (evidence.marker && evidence.sessionState !== "dead") {
|
|
24070
|
-
const { stale, idleMs } = claimStampStaleness(evidence.marker, { activityAt: [evidence.lastCommentAt] });
|
|
24192
|
+
const { stale, idleMs } = claimStampStaleness(evidence.marker, { activityAt: [evidence.lastCommentAt], sessionState: evidence.sessionState });
|
|
24071
24193
|
const marker = describeClaimMarker(evidence.marker);
|
|
24072
24194
|
if (!stale) {
|
|
24073
24195
|
live.push(evidence.lastCommentAt && Date.parse(evidence.lastCommentAt) > Date.parse(evidence.marker.ts) ? `claim marker from ${marker} is ${formatClaimAge(evidence.markerAgeMs)} old but the issue was commented ${formatClaimAge(idleMs)} ago (session not locally probeable)` : `claim marker from ${marker} is only ${formatClaimAge(evidence.markerAgeMs)} old (session not locally probeable)`);
|
|
@@ -24161,7 +24283,7 @@ async function checkLaneContest(client, item, actor = describeSessionIdentity(),
|
|
|
24161
24283
|
}
|
|
24162
24284
|
}
|
|
24163
24285
|
const carry = staleWorkLines(evidence);
|
|
24164
|
-
const staleStamp = !contested && !resume && !ownSeat && evidence.marker ? `stale claim stamp ${describeClaimMarker(evidence.marker)} (idle ${formatClaimAge(claimStampStaleness(evidence.marker, { activityAt: [evidence.lastCommentAt] }).idleMs)})${carry.length ? `; continue its ${carry.join(" and ")}` : ""}` : void 0;
|
|
24286
|
+
const staleStamp = !contested && !resume && !ownSeat && evidence.marker ? `stale claim stamp ${describeClaimMarker(evidence.marker)} (idle ${formatClaimAge(claimStampStaleness(evidence.marker, { activityAt: [evidence.lastCommentAt], sessionState: evidence.sessionState }).idleMs)})${carry.length ? `; continue its ${carry.join(" and ")}` : ""}` : void 0;
|
|
24165
24287
|
return {
|
|
24166
24288
|
contested,
|
|
24167
24289
|
live,
|
|
@@ -28405,10 +28527,10 @@ var rollout_plan_default = {
|
|
|
28405
28527
|
note: "The v4.0.0 stamp happens at cut time (D6e #4463); until then the candidate is the origin/development head artifacts (built cli/dist + npm pack), identity proven by dist content hash (D6a)."
|
|
28406
28528
|
},
|
|
28407
28529
|
baseline: {
|
|
28408
|
-
version: "4.6.
|
|
28409
|
-
tag: "v4.6.
|
|
28410
|
-
commit: "
|
|
28411
|
-
npm: "@mutmutco/cli@4.6.
|
|
28530
|
+
version: "4.6.41",
|
|
28531
|
+
tag: "v4.6.41",
|
|
28532
|
+
commit: "2cf5b22abb64",
|
|
28533
|
+
npm: "@mutmutco/cli@4.6.41"
|
|
28412
28534
|
},
|
|
28413
28535
|
exitCriterion: "fleet-n-of-n",
|
|
28414
28536
|
hubOnlyShortcut: "forbidden",
|
|
@@ -28425,14 +28547,14 @@ var rollout_plan_default = {
|
|
|
28425
28547
|
repo: "mutmutco/mmi-hub",
|
|
28426
28548
|
role: "canary",
|
|
28427
28549
|
schedule: "train",
|
|
28428
|
-
v3Target: "v4.6.
|
|
28550
|
+
v3Target: "v4.6.41"
|
|
28429
28551
|
}
|
|
28430
28552
|
],
|
|
28431
28553
|
rollbackTrigger: "Any red inside the post-contract soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a pre-v4 client admitted instead of receiving actionable HTTP 426, or npm consumer install/doctor failure on the v4-only dist.",
|
|
28432
28554
|
rollback: {
|
|
28433
28555
|
independent: true,
|
|
28434
|
-
mechanism: "npm dist-tag latest -> 4.6.
|
|
28435
|
-
v3Target: "v4.6.
|
|
28556
|
+
mechanism: "npm dist-tag latest -> 4.6.41 and redeploy the Hub Lambda from tag v4.6.41 (2cf5b22abb64); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
28557
|
+
v3Target: "v4.6.41 (@mutmutco/cli@4.6.41, tag commit 2cf5b22abb64 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
28436
28558
|
}
|
|
28437
28559
|
},
|
|
28438
28560
|
{
|
|
@@ -47190,7 +47312,7 @@ async function assignPersistedPortRange(repo, slug, reg, opts) {
|
|
|
47190
47312
|
|
|
47191
47313
|
// src/box-commands.ts
|
|
47192
47314
|
var import_node_fs39 = require("node:fs");
|
|
47193
|
-
var
|
|
47315
|
+
var import_node_child_process13 = require("node:child_process");
|
|
47194
47316
|
var import_node_os20 = require("node:os");
|
|
47195
47317
|
var import_node_path36 = require("node:path");
|
|
47196
47318
|
|
|
@@ -47418,6 +47540,7 @@ init_cli_shared();
|
|
|
47418
47540
|
|
|
47419
47541
|
// src/secrets-commands.ts
|
|
47420
47542
|
var import_node_fs37 = require("node:fs");
|
|
47543
|
+
var import_node_child_process12 = require("node:child_process");
|
|
47421
47544
|
var import_node_path34 = require("node:path");
|
|
47422
47545
|
var import_node_os19 = require("node:os");
|
|
47423
47546
|
init_cli_shared();
|
|
@@ -48684,9 +48807,122 @@ function makeSecretsDeps(cfg) {
|
|
|
48684
48807
|
slug: async () => (await repoProject(cfg)).toLowerCase(),
|
|
48685
48808
|
readSecretValue: () => readSecretStdin(),
|
|
48686
48809
|
log: (m) => console.log(m),
|
|
48687
|
-
err: (m) => console.error(m)
|
|
48810
|
+
err: (m) => console.error(m),
|
|
48811
|
+
// #10056: the sanctioned clipboard handoff — read/write the OS clipboard directly, never through a
|
|
48812
|
+
// shell, so a pasted value cannot be re-parsed by cmd.exe/PowerShell.
|
|
48813
|
+
readClipboard: () => readClipboardText(),
|
|
48814
|
+
writeClipboard: (value) => clearClipboard(value)
|
|
48688
48815
|
};
|
|
48689
48816
|
}
|
|
48817
|
+
var CLIPBOARD_TIMEOUT_MS = 1e4;
|
|
48818
|
+
function clipboardReadCommands(platform2) {
|
|
48819
|
+
if (platform2 === "win32") return [{ cmd: "powershell", args: ["-NoProfile", "-Command", "Get-Clipboard -Raw"] }];
|
|
48820
|
+
if (platform2 === "darwin") return [{ cmd: "pbpaste", args: [] }];
|
|
48821
|
+
return [
|
|
48822
|
+
{ cmd: "wl-paste", args: ["-n"] },
|
|
48823
|
+
{ cmd: "xclip", args: ["-selection", "clipboard", "-o"] }
|
|
48824
|
+
];
|
|
48825
|
+
}
|
|
48826
|
+
function clipboardClearCommands(platform2) {
|
|
48827
|
+
if (platform2 === "win32") return [{ cmd: "powershell", args: ["-NoProfile", "-Command", "Set-Clipboard -Value ' '"] }];
|
|
48828
|
+
if (platform2 === "darwin") return [{ cmd: "pbcopy", args: [], input: "" }];
|
|
48829
|
+
return [
|
|
48830
|
+
{ cmd: "wl-copy", args: ["--clear"] },
|
|
48831
|
+
{ cmd: "xclip", args: ["-selection", "clipboard"], input: "" }
|
|
48832
|
+
];
|
|
48833
|
+
}
|
|
48834
|
+
function clipboardFailure(command, error) {
|
|
48835
|
+
const code = error.code;
|
|
48836
|
+
if (code === "ENOENT") return `${command.cmd}: not found`;
|
|
48837
|
+
if (typeof code === "number") return `${command.cmd}: exit ${code}`;
|
|
48838
|
+
return `${command.cmd}: could not run`;
|
|
48839
|
+
}
|
|
48840
|
+
function runClipboardCommand(command) {
|
|
48841
|
+
return new Promise((resolveRun, rejectRun) => {
|
|
48842
|
+
const child2 = (0, import_node_child_process12.spawn)(command.cmd, command.args, {
|
|
48843
|
+
shell: false,
|
|
48844
|
+
windowsHide: true,
|
|
48845
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
48846
|
+
});
|
|
48847
|
+
const out = [];
|
|
48848
|
+
let settled2 = false;
|
|
48849
|
+
const settle = (error, value) => {
|
|
48850
|
+
if (settled2) return;
|
|
48851
|
+
settled2 = true;
|
|
48852
|
+
clearTimeout(timer);
|
|
48853
|
+
if (error) rejectRun(error);
|
|
48854
|
+
else resolveRun(value ?? "");
|
|
48855
|
+
};
|
|
48856
|
+
const timer = setTimeout(() => {
|
|
48857
|
+
child2.kill();
|
|
48858
|
+
settle(new Error(`${command.cmd}: timed out`));
|
|
48859
|
+
}, CLIPBOARD_TIMEOUT_MS);
|
|
48860
|
+
timer.unref?.();
|
|
48861
|
+
child2.stdout?.on("data", (chunk) => out.push(chunk));
|
|
48862
|
+
child2.stderr?.on("data", () => {
|
|
48863
|
+
});
|
|
48864
|
+
child2.on("error", (e) => settle(e instanceof Error ? e : new Error(String(e))));
|
|
48865
|
+
child2.on("close", (code) => {
|
|
48866
|
+
if (code === 0) settle(void 0, Buffer.concat(out).toString("utf8"));
|
|
48867
|
+
else settle(Object.assign(new Error(`${command.cmd}: exit ${code}`), { code }));
|
|
48868
|
+
});
|
|
48869
|
+
child2.stdin?.on("error", () => {
|
|
48870
|
+
});
|
|
48871
|
+
child2.stdin?.end(command.input ?? "");
|
|
48872
|
+
});
|
|
48873
|
+
}
|
|
48874
|
+
async function readClipboardText(platform2 = process.platform) {
|
|
48875
|
+
const failures = [];
|
|
48876
|
+
for (const command of clipboardReadCommands(platform2)) {
|
|
48877
|
+
try {
|
|
48878
|
+
return await runClipboardCommand(command);
|
|
48879
|
+
} catch (e) {
|
|
48880
|
+
failures.push(clipboardFailure(command, e));
|
|
48881
|
+
}
|
|
48882
|
+
}
|
|
48883
|
+
throw new Error(`could not read the clipboard (${failures.join(", ")})`);
|
|
48884
|
+
}
|
|
48885
|
+
async function clearClipboard(value, platform2 = process.platform) {
|
|
48886
|
+
const failures = [];
|
|
48887
|
+
for (const command of clipboardClearCommands(platform2)) {
|
|
48888
|
+
try {
|
|
48889
|
+
await runClipboardCommand({ ...command, ...command.input !== void 0 ? { input: value } : {} });
|
|
48890
|
+
return;
|
|
48891
|
+
} catch (e) {
|
|
48892
|
+
failures.push(clipboardFailure(command, e));
|
|
48893
|
+
}
|
|
48894
|
+
}
|
|
48895
|
+
throw new Error(`${failures.join(", ")}`);
|
|
48896
|
+
}
|
|
48897
|
+
function clipboardSourceRefusal(fromClipboard, stdinHasData) {
|
|
48898
|
+
if (!fromClipboard || !stdinHasData) return null;
|
|
48899
|
+
return "secrets set: --from-clipboard conflicts with piped stdin \u2014 remove the pipe (the value comes from the clipboard), or drop --from-clipboard and pipe it";
|
|
48900
|
+
}
|
|
48901
|
+
async function stdinCarriesData(timeoutMs = 50) {
|
|
48902
|
+
const stdin = process.stdin;
|
|
48903
|
+
if (stdin.isTTY) return false;
|
|
48904
|
+
if (stdin.readableLength > 0) return true;
|
|
48905
|
+
return new Promise((resolveProbe) => {
|
|
48906
|
+
let settled2 = false;
|
|
48907
|
+
const finish = (value) => {
|
|
48908
|
+
if (settled2) return;
|
|
48909
|
+
settled2 = true;
|
|
48910
|
+
clearTimeout(timer);
|
|
48911
|
+
stdin.off("readable", onReadable);
|
|
48912
|
+
stdin.off("end", onEnd);
|
|
48913
|
+
resolveProbe(value);
|
|
48914
|
+
};
|
|
48915
|
+
const onReadable = () => {
|
|
48916
|
+
if (stdin.readableLength > 0) finish(true);
|
|
48917
|
+
};
|
|
48918
|
+
const onEnd = () => finish(false);
|
|
48919
|
+
const timer = setTimeout(() => finish(stdin.readableLength > 0), timeoutMs);
|
|
48920
|
+
timer.unref?.();
|
|
48921
|
+
stdin.once("readable", onReadable);
|
|
48922
|
+
stdin.once("end", onEnd);
|
|
48923
|
+
stdin.once("error", () => finish(false));
|
|
48924
|
+
});
|
|
48925
|
+
}
|
|
48690
48926
|
async function withSecrets(run) {
|
|
48691
48927
|
const cfg = await loadConfig();
|
|
48692
48928
|
if (!cfg.sagaApiUrl) {
|
|
@@ -48833,10 +49069,22 @@ function registerSecretsCommands(program3) {
|
|
|
48833
49069
|
if (!ok) process.exitCode = 1;
|
|
48834
49070
|
}));
|
|
48835
49071
|
const setHandler = (key, o) => withSecrets(async (d) => {
|
|
49072
|
+
if (o.fromClipboard) {
|
|
49073
|
+
const refusal = clipboardSourceRefusal(true, await stdinCarriesData());
|
|
49074
|
+
if (refusal) return fail(refusal);
|
|
49075
|
+
const ok2 = await secretsSetFromClipboard(d, key, {
|
|
49076
|
+
...o.repo !== void 0 ? { repo: o.repo } : {},
|
|
49077
|
+
...o.slug !== void 0 ? { slug: o.slug } : {},
|
|
49078
|
+
...o.extract !== void 0 ? { extract: o.extract } : {}
|
|
49079
|
+
});
|
|
49080
|
+
if (!ok2) process.exitCode = 1;
|
|
49081
|
+
return;
|
|
49082
|
+
}
|
|
49083
|
+
if (o.extract !== void 0) return fail("secrets set: --extract needs --from-clipboard (it isolates the value inside copied text)");
|
|
48836
49084
|
const ok = await secretsSet(d, key, o);
|
|
48837
49085
|
if (!ok) process.exitCode = 1;
|
|
48838
49086
|
});
|
|
48839
|
-
secrets.command("set <key>").description("write/rotate a secret; value from stdin (never an argument). DECLARE-FIRST (#2528): the key must be a declared catalog coordinate \u2014 bare <KEY> = the stageless canonical, <stage>/<KEY> = a declared per-stage override; undeclared writes are rejected with the fix. --slug _org writes an org-infra <provider>/<KEY> coordinate (#3298) \u2014 master or an exact grant, declare-first enforced server-side").option("--repo <owner/repo>", "target repo (defaults to the current repo)").option("--slug <slug>", "org-infra namespace (e.g. _org) for the value write \u2014 master or an exact grant (#3298)").action(setHandler);
|
|
49087
|
+
secrets.command("set <key>").description("write/rotate a secret; value from stdin (never an argument). DECLARE-FIRST (#2528): the key must be a declared catalog coordinate \u2014 bare <KEY> = the stageless canonical, <stage>/<KEY> = a declared per-stage override; undeclared writes are rejected with the fix. --slug _org writes an org-infra <provider>/<KEY> coordinate (#3298) \u2014 master or an exact grant, declare-first enforced server-side. --from-clipboard takes the value from the OS clipboard instead of stdin, extracts it with --extract, and CLEARS the clipboard afterwards \u2014 the sanctioned handoff for a secret embedded in copied text (#10056)").option("--repo <owner/repo>", "target repo (defaults to the current repo)").option("--slug <slug>", "org-infra namespace (e.g. _org) for the value write \u2014 master or an exact grant (#3298)").option("--from-clipboard", "read the value from the OS clipboard instead of stdin: powershell Get-Clipboard / pbpaste / wl-paste (xclip fallback). The clipboard is overwritten on EVERY path (success, no match, failed write). Conflicts with piped stdin").option("--extract <regex>", "with --from-clipboard: a regex with EXACTLY ONE capture group whose single match inside the copied text is the value, e.g. --extract '--token\\s+(\\S+)'. Zero or 2+ matches are refused (the count is reported, the text never is). Without --extract the whole clipboard, minus one trailing newline, is the value").action(setHandler);
|
|
48840
49088
|
secrets.command("copy").description("copy provider keys between stages in your own project vault (audit-logged; encryption keys blocked)").requiredOption("--from <stage>", "source tier: dev, rc, or main").requiredOption("--to <stage>", "destination tier: dev, rc, or main").requiredOption("--keys <names>", "comma-separated secret names (encryption keys blocked)").option("--dry-run", "report copies without writing").option("--repo <owner/repo>", "target repo (defaults to the current repo)").action((o) => withSecrets(async (d) => {
|
|
48841
49089
|
const stages = ["dev", "rc", "main"];
|
|
48842
49090
|
if (!stages.includes(o.from) || !stages.includes(o.to)) {
|
|
@@ -49662,7 +49910,7 @@ var UsageError = class extends Error {
|
|
|
49662
49910
|
var UnreadableError = class extends Error {
|
|
49663
49911
|
};
|
|
49664
49912
|
function hubGitShow(ref) {
|
|
49665
|
-
const git3 = (args) => (0,
|
|
49913
|
+
const git3 = (args) => (0, import_node_child_process13.execFileSync)("git", args, { maxBuffer: 64 * 1024 * 1024, stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
|
|
49666
49914
|
try {
|
|
49667
49915
|
git3(["cat-file", "-e", `HEAD:${MANIFEST_PATH}`]);
|
|
49668
49916
|
} catch {
|
|
@@ -49676,7 +49924,7 @@ function runOnBox(found, script) {
|
|
|
49676
49924
|
try {
|
|
49677
49925
|
const recipe = (0, import_node_path36.join)(dir, "recipe.sh");
|
|
49678
49926
|
(0, import_node_fs39.writeFileSync)(recipe, sshRecipeScript(found, "sh -s"), "utf8");
|
|
49679
|
-
const r = (0,
|
|
49927
|
+
const r = (0, import_node_child_process13.spawnSync)("bash", [recipe], { input: script, encoding: "utf8", maxBuffer: 16 * 1024 * 1024, timeout: 18e4, windowsHide: true });
|
|
49680
49928
|
if (r.status !== 0) {
|
|
49681
49929
|
throw new UnreadableError(`box control: the ssh session to ${found.name} failed (exit ${r.status ?? r.signal}): ${(r.stderr || "").trim().split("\n").slice(-3).join(" | ")}`);
|
|
49682
49930
|
}
|
|
@@ -54433,7 +54681,7 @@ async function runRcDataSwitch(deps, opts) {
|
|
|
54433
54681
|
}
|
|
54434
54682
|
|
|
54435
54683
|
// src/suite-train-io.ts
|
|
54436
|
-
var
|
|
54684
|
+
var import_node_child_process20 = require("node:child_process");
|
|
54437
54685
|
var import_node_path52 = require("node:path");
|
|
54438
54686
|
var import_node_fs55 = require("node:fs");
|
|
54439
54687
|
var import_node_path53 = require("node:path");
|
|
@@ -56022,13 +56270,13 @@ async function findInFlightHotfixVersion(deps, ctx, latestMainTag, workflows = H
|
|
|
56022
56270
|
}
|
|
56023
56271
|
|
|
56024
56272
|
// src/hotfix-coverage.ts
|
|
56025
|
-
var
|
|
56273
|
+
var import_node_child_process14 = require("node:child_process");
|
|
56026
56274
|
var CHERRY_TRAILER = /\(cherry picked from commit ([0-9a-f]{7,40})\)/g;
|
|
56027
56275
|
var GIT_MAX_BUFFER = 512 * 1024 * 1024;
|
|
56028
56276
|
function checkHotfixCoverage(options = {}) {
|
|
56029
56277
|
const { cwd = process.cwd(), mainRef = "origin/main", rcRef = "origin/rc", manifestPaths = [] } = options;
|
|
56030
56278
|
const ack = (options.ack ?? []).filter(Boolean);
|
|
56031
|
-
const git3 = options.git ?? ((args, opts) => (0,
|
|
56279
|
+
const git3 = options.git ?? ((args, opts) => (0, import_node_child_process14.execFileSync)("git", args, { cwd, encoding: "utf8", input: opts?.input, stdio: ["pipe", "pipe", "pipe"], maxBuffer: GIT_MAX_BUFFER }));
|
|
56032
56280
|
const revList = (range) => {
|
|
56033
56281
|
const out = git3(["rev-list", "--no-merges", range]).trim();
|
|
56034
56282
|
return out ? out.split("\n") : [];
|
|
@@ -56096,7 +56344,7 @@ function checkHotfixCoverage(options = {}) {
|
|
|
56096
56344
|
}
|
|
56097
56345
|
function checkHotfixCarries(options) {
|
|
56098
56346
|
const { cwd = process.cwd(), branch, baseRef, targets } = options;
|
|
56099
|
-
const git3 = options.git ?? ((args, opts) => (0,
|
|
56347
|
+
const git3 = options.git ?? ((args, opts) => (0, import_node_child_process14.execFileSync)("git", args, { cwd, encoding: "utf8", input: opts?.input, stdio: ["pipe", "pipe", "pipe"], maxBuffer: GIT_MAX_BUFFER }));
|
|
56100
56348
|
const isAncestor = (sha, ref) => {
|
|
56101
56349
|
try {
|
|
56102
56350
|
git3(["merge-base", "--is-ancestor", sha, ref]);
|
|
@@ -57983,7 +58231,7 @@ function prTitleRefusal(title) {
|
|
|
57983
58231
|
}
|
|
57984
58232
|
|
|
57985
58233
|
// src/command-register-collaboration.ts
|
|
57986
|
-
var
|
|
58234
|
+
var import_node_child_process19 = require("node:child_process");
|
|
57987
58235
|
var import_node_fs54 = require("node:fs");
|
|
57988
58236
|
var import_promises9 = require("node:fs/promises");
|
|
57989
58237
|
init_clean_exit();
|
|
@@ -59521,7 +59769,7 @@ async function readAppApi(path2, runner = apiReadRunner) {
|
|
|
59521
59769
|
return log ? Buffer.from(body, "latin1").toString("utf8") : out;
|
|
59522
59770
|
}
|
|
59523
59771
|
function registerApiReadCommands(program3, overrides) {
|
|
59524
|
-
const
|
|
59772
|
+
const spawn8 = overrides?.runner ?? apiReadRunner;
|
|
59525
59773
|
const jqRun = overrides?.jqRunner ?? systemJqRunner;
|
|
59526
59774
|
let bindings = [];
|
|
59527
59775
|
const runGet = async (req, o) => {
|
|
@@ -59541,7 +59789,7 @@ function registerApiReadCommands(program3, overrides) {
|
|
|
59541
59789
|
let body;
|
|
59542
59790
|
try {
|
|
59543
59791
|
body = await runApiGet(
|
|
59544
|
-
async (args, timeoutMs) => zip ?
|
|
59792
|
+
async (args, timeoutMs) => zip ? spawn8(args, ZIP_TIMEOUT_MS, env, true) : spawn8(args, timeoutMs, env),
|
|
59545
59793
|
req.path,
|
|
59546
59794
|
o.accept
|
|
59547
59795
|
);
|
|
@@ -59787,7 +60035,7 @@ function registerRunLogRead(run, runner) {
|
|
|
59787
60035
|
|
|
59788
60036
|
// src/app-read-broker.ts
|
|
59789
60037
|
init_cli_shared();
|
|
59790
|
-
var
|
|
60038
|
+
var import_node_child_process15 = require("node:child_process");
|
|
59791
60039
|
var OWNER_REPO_RE = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
59792
60040
|
var JSON_FIELD_RE = /^[A-Za-z0-9_,]+$/;
|
|
59793
60041
|
var ID_RE = /^\d+$/;
|
|
@@ -59873,7 +60121,7 @@ function formatJqFailureMessage(code, stderr) {
|
|
|
59873
60121
|
return `${base} \u2014 the expression is handed to jq verbatim (mmi-cli never re-quotes it), so if a shell or seat layer collapsed a backslash, use an escape-free form such as \`test("bundle[.]css")\` or \`contains("bundle.css")\`, or drop --jq and filter the JSON locally`;
|
|
59874
60122
|
}
|
|
59875
60123
|
var systemJqRunner = (expr, input, env, bindings) => new Promise((resolveOut, reject2) => {
|
|
59876
|
-
const child2 = (0,
|
|
60124
|
+
const child2 = (0, import_node_child_process15.spawn)("jq", [...process.platform === "win32" ? ["--binary"] : [], "-r", "-c", ...(bindings ?? []).flatMap((b) => [b.kind, b.name, b.value]), expr], { env, stdio: ["pipe", "pipe", "pipe"], windowsHide: true });
|
|
59877
60125
|
let stdout = "";
|
|
59878
60126
|
let stderr = "";
|
|
59879
60127
|
child2.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
@@ -61088,7 +61336,7 @@ function registerPrLifecycleCommands(program3) {
|
|
|
61088
61336
|
}
|
|
61089
61337
|
|
|
61090
61338
|
// src/review-verdict.ts
|
|
61091
|
-
var
|
|
61339
|
+
var import_node_child_process16 = require("node:child_process");
|
|
61092
61340
|
var import_node_fs49 = require("node:fs");
|
|
61093
61341
|
var import_node_os25 = require("node:os");
|
|
61094
61342
|
var import_node_path46 = require("node:path");
|
|
@@ -61188,8 +61436,8 @@ async function checkPrReview(number, repo, head, deps = {
|
|
|
61188
61436
|
}
|
|
61189
61437
|
function computePrPatchId(number, repo) {
|
|
61190
61438
|
return new Promise((resolve8, reject2) => {
|
|
61191
|
-
const gh2 = (0,
|
|
61192
|
-
const git3 = (0,
|
|
61439
|
+
const gh2 = (0, import_node_child_process16.spawn)("gh", ["pr", "diff", number, "--repo", repo], { windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
|
|
61440
|
+
const git3 = (0, import_node_child_process16.spawn)("git", ["patch-id", "--stable"], { windowsHide: true, stdio: ["pipe", "pipe", "pipe"] });
|
|
61193
61441
|
let out = "";
|
|
61194
61442
|
let ghErr = "";
|
|
61195
61443
|
let gitErr = "";
|
|
@@ -61414,7 +61662,7 @@ async function observePrCreateClaims(body, repoOption, deps = {}) {
|
|
|
61414
61662
|
}
|
|
61415
61663
|
|
|
61416
61664
|
// src/pr-create-docs-check.ts
|
|
61417
|
-
var
|
|
61665
|
+
var import_node_child_process17 = require("node:child_process");
|
|
61418
61666
|
init_cli_shared();
|
|
61419
61667
|
var GIT_TIMEOUT_MS2 = 15e3;
|
|
61420
61668
|
function catFileBatch(root, ref, paths) {
|
|
@@ -61422,7 +61670,7 @@ function catFileBatch(root, ref, paths) {
|
|
|
61422
61670
|
return new Promise((resolve8) => {
|
|
61423
61671
|
const chunks = [];
|
|
61424
61672
|
let settled2 = false;
|
|
61425
|
-
const child2 = (0,
|
|
61673
|
+
const child2 = (0, import_node_child_process17.spawn)("git", ["-C", root, "cat-file", "--batch", "--buffer"], { windowsHide: true });
|
|
61426
61674
|
const finish = (ok = false) => {
|
|
61427
61675
|
if (settled2) return;
|
|
61428
61676
|
settled2 = true;
|
|
@@ -61761,7 +62009,7 @@ var import_node_path49 = require("node:path");
|
|
|
61761
62009
|
init_cli_shared();
|
|
61762
62010
|
|
|
61763
62011
|
// src/stage-runner.ts
|
|
61764
|
-
var
|
|
62012
|
+
var import_node_child_process18 = require("node:child_process");
|
|
61765
62013
|
var import_node_fs51 = require("node:fs");
|
|
61766
62014
|
var import_node_path48 = require("node:path");
|
|
61767
62015
|
var import_node_net = require("node:net");
|
|
@@ -61932,7 +62180,7 @@ function stageComposeFileEnv(files) {
|
|
|
61932
62180
|
}
|
|
61933
62181
|
|
|
61934
62182
|
// src/stage-runner.ts
|
|
61935
|
-
var execFileP3 = (0, import_node_util5.promisify)(
|
|
62183
|
+
var execFileP3 = (0, import_node_util5.promisify)(import_node_child_process18.execFile);
|
|
61936
62184
|
var DOCKER_TIMEOUT_MS = 15e3;
|
|
61937
62185
|
function stageBash() {
|
|
61938
62186
|
if (process.platform !== "win32") return "bash";
|
|
@@ -62576,7 +62824,7 @@ async function startStage(config = {}, opts = {}) {
|
|
|
62576
62824
|
let up = sub(config.up.trim());
|
|
62577
62825
|
if (opts.forceRecreate) up = appendForceRecreate(up);
|
|
62578
62826
|
const identity = await resolveStageIdentity(cwd);
|
|
62579
|
-
const child2 = (0,
|
|
62827
|
+
const child2 = (0, import_node_child_process18.spawn)(bash, ["-c", up], {
|
|
62580
62828
|
cwd,
|
|
62581
62829
|
// POSIX-only: the process group exists for the group-kill in stopStage. On win32 teardown is
|
|
62582
62830
|
// `taskkill /T /F` (no group needed), and detached+shell defeats windowsHide — every spawn would
|
|
@@ -63709,7 +63957,7 @@ function scheduleRelatedDiscovery(o) {
|
|
|
63709
63957
|
try {
|
|
63710
63958
|
const args = ["issue", "discover-related", "--number", String(o.number), "--title", o.title, "--body", o.body, "--fail-soft"];
|
|
63711
63959
|
if (o.repo) args.push("--repo", o.repo);
|
|
63712
|
-
spawnDetachedSelf(args, { spawn:
|
|
63960
|
+
spawnDetachedSelf(args, { spawn: import_node_child_process19.spawn, execPath: process.execPath, scriptPath: process.argv[1] }, { cwd: process.cwd() });
|
|
63713
63961
|
} catch {
|
|
63714
63962
|
}
|
|
63715
63963
|
}
|
|
@@ -66693,7 +66941,7 @@ function suiteTrainIo(root, summaryFile, memberSummaryFiles = {}, summaryFileTr,
|
|
|
66693
66941
|
if (repo === SUITE_REPO) return inTrain(repo, (deps) => rcandInCheckout(repo, deps, previousRc, rcWasAbsent));
|
|
66694
66942
|
const target = await checkout(repo);
|
|
66695
66943
|
return new Promise((resolveResult, reject2) => {
|
|
66696
|
-
const child2 = (0,
|
|
66944
|
+
const child2 = (0, import_node_child_process20.fork)((0, import_node_path52.resolve)(process.argv[1]), ["devops", "suite", "member-rcand-internal", repo, previousRc ?? "", ...rcWasAbsent ? ["--rc-was-absent"] : []], {
|
|
66697
66945
|
cwd: target,
|
|
66698
66946
|
stdio: ["ignore", "inherit", "inherit", "ipc"],
|
|
66699
66947
|
execArgv: []
|
|
@@ -67314,7 +67562,7 @@ function registerJevCommands(program3) {
|
|
|
67314
67562
|
}
|
|
67315
67563
|
|
|
67316
67564
|
// src/packages-adopt-export.ts
|
|
67317
|
-
var
|
|
67565
|
+
var import_node_child_process21 = require("node:child_process");
|
|
67318
67566
|
var import_node_fs57 = require("node:fs");
|
|
67319
67567
|
var import_node_os26 = require("node:os");
|
|
67320
67568
|
var import_node_path54 = require("node:path");
|
|
@@ -67971,7 +68219,7 @@ async function adoptExport(opts, deps) {
|
|
|
67971
68219
|
(0, import_node_fs57.rmSync)(work, { recursive: true, force: true });
|
|
67972
68220
|
}
|
|
67973
68221
|
}
|
|
67974
|
-
var execFileBuffer = (0, import_node_util6.promisify)(
|
|
68222
|
+
var execFileBuffer = (0, import_node_util6.promisify)(import_node_child_process21.execFile);
|
|
67975
68223
|
var MAX_OUTPUT = 200 * 1024 * 1024;
|
|
67976
68224
|
async function findPython() {
|
|
67977
68225
|
for (const bin of ["python3", "python"]) {
|
|
@@ -72537,7 +72785,7 @@ async function resolveWhoami(deps) {
|
|
|
72537
72785
|
var import_node_path64 = require("node:path");
|
|
72538
72786
|
|
|
72539
72787
|
// src/doc-refs-command-source.ts
|
|
72540
|
-
var
|
|
72788
|
+
var import_node_child_process22 = require("node:child_process");
|
|
72541
72789
|
var import_node_fs62 = require("node:fs");
|
|
72542
72790
|
var import_node_path58 = require("node:path");
|
|
72543
72791
|
var IN_PROCESS_SOURCE = "in-process";
|
|
@@ -72558,7 +72806,7 @@ function inventoryFromManifest(manifest, source) {
|
|
|
72558
72806
|
collect(body?.tree);
|
|
72559
72807
|
return { commandPaths, commandOptions, source };
|
|
72560
72808
|
}
|
|
72561
|
-
function readBundleManifest(bundle, exec3 =
|
|
72809
|
+
function readBundleManifest(bundle, exec3 = import_node_child_process22.execFileSync) {
|
|
72562
72810
|
try {
|
|
72563
72811
|
const text = exec3(process.execPath, [bundle, "commands", "--all", "--json"], {
|
|
72564
72812
|
cwd: (0, import_node_path58.dirname)(bundle),
|
|
@@ -72727,7 +72975,7 @@ async function executeWaveLand(plan, deps) {
|
|
|
72727
72975
|
}
|
|
72728
72976
|
|
|
72729
72977
|
// src/dist-drift.ts
|
|
72730
|
-
var
|
|
72978
|
+
var import_node_child_process23 = require("node:child_process");
|
|
72731
72979
|
var import_node_crypto26 = require("node:crypto");
|
|
72732
72980
|
var import_node_fs64 = require("node:fs");
|
|
72733
72981
|
var import_node_os28 = require("node:os");
|
|
@@ -72873,7 +73121,7 @@ function bomPathFor(root) {
|
|
|
72873
73121
|
}
|
|
72874
73122
|
}
|
|
72875
73123
|
function rebuildTo(packageRoot, outDir) {
|
|
72876
|
-
(0,
|
|
73124
|
+
(0, import_node_child_process23.execFileSync)(process.execPath, ["build.mjs"], {
|
|
72877
73125
|
cwd: packageRoot,
|
|
72878
73126
|
env: { ...process.env, MMI_DIST_OUTDIR: outDir },
|
|
72879
73127
|
windowsHide: true,
|
|
@@ -72997,9 +73245,9 @@ async function runLiveDocRefs(root, deps, live) {
|
|
|
72997
73245
|
}
|
|
72998
73246
|
|
|
72999
73247
|
// src/doc-refs-live-io.ts
|
|
73000
|
-
var
|
|
73248
|
+
var import_node_child_process24 = require("node:child_process");
|
|
73001
73249
|
var import_node_util7 = require("node:util");
|
|
73002
|
-
var exec2 = (0, import_node_util7.promisify)(
|
|
73250
|
+
var exec2 = (0, import_node_util7.promisify)(import_node_child_process24.execFile);
|
|
73003
73251
|
function createRunbookLiveDeps(cliBin) {
|
|
73004
73252
|
const json = async (args) => {
|
|
73005
73253
|
const { stdout } = await exec2(process.execPath, [cliBin, ...args, "--json"], { windowsHide: true, timeout: 3e4, maxBuffer: 4 * 1024 * 1024 });
|
|
@@ -73310,7 +73558,7 @@ function registerSchedulesLiftCommand(program3, deps = {}) {
|
|
|
73310
73558
|
}
|
|
73311
73559
|
|
|
73312
73560
|
// src/spawn-policy-core.ts
|
|
73313
|
-
var
|
|
73561
|
+
var import_node_child_process25 = require("node:child_process");
|
|
73314
73562
|
var import_node_fs65 = require("node:fs");
|
|
73315
73563
|
var import_node_path63 = require("node:path");
|
|
73316
73564
|
var SPAWNERS = ["spawn", "spawnSync", "exec", "execSync", "execFile", "execFileSync"];
|
|
@@ -73381,7 +73629,7 @@ function findViolationsInSource(raw) {
|
|
|
73381
73629
|
return found;
|
|
73382
73630
|
}
|
|
73383
73631
|
function policedFiles(root) {
|
|
73384
|
-
const r = (0,
|
|
73632
|
+
const r = (0, import_node_child_process25.spawnSync)("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard"], {
|
|
73385
73633
|
cwd: root,
|
|
73386
73634
|
encoding: "utf8",
|
|
73387
73635
|
windowsHide: true,
|
package/cli/package.json
CHANGED
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@ The server exposes `/health` and `/module.js`. Register the module's bundle URL,
|
|
|
15
15
|
1. **Single source of truth:** the source folder of `packages/mmwork-ds` in `mutmutco/MM-Work`, owned by the MM-Work Design Lead (tokens, layers, component bundle, component docs, `DESIGN.md` and its `design.json` sidecar). Never edit the kit or its copies here; a missing piece or variant is built there first, or requested via kit MCP `request_piece`.
|
|
16
16
|
2. **MM Artifact on Live Docs:** Live Docs (`Canlı belgeler / MM-Work`) displays document `3a5c79df-5274-40ad-a1b5-a75e67a74dac` (ATOMIC, module `mm-work-kit`), an MM Artifact in the `design-system` format rebuilt from the kit source on every kit release: Overview, Guide (kit README + `DESIGN.md`), Tokens, Atoms, Molecules, Organisms, Templates and Files. Browse it to see every piece live.
|
|
17
17
|
3. **Impeccable knows Atomic Design at boot:** `impeccable context` loads `PRODUCT.md`, `DESIGN.md` and the `design.json` sidecar in `.impeccable`, which carry the Atomic Design contract 1.1.0: `Atoms -> Molecules -> Organisms -> Templates -> Pages`, upward-only composition enforced by `npm --prefix module run lint` (or `npm run lint` inside `module/`; `mmwork-check-ui` and `mmwork-check-i18n` are bins of `@mutmutco/mmwork-ds`, so a bare `npx mmwork-check-ui` outside that project's installed `node_modules` is resolved as a package name and 404s). Pages arrange exported `@mutmutco/mmwork-ds` pieces around one template and never paint custom controls, raw `<button>`/`<input>`, `mw-*` classes, inline visual styles or raw hex/px values.
|
|
18
|
-
4. **Automatic propagation:** on every kit release the Hub kit-adopt workflow opens an adoption PR here that bumps `@mutmutco/mmwork-ds`, runs `mmwork-sync-impeccable`, and writes `DESIGN.md`, the `.impeccable` design manifest and `.impeccable/config.json` (`hook.enabled: true`) at the repository root, and deletes any stale copies under `module/`. These files are kit-owned: do not hand-edit them, and keep them committed even if `.impeccable/` is ignored (the adoption PR force-stages them).
|
|
18
|
+
4. **Automatic propagation:** on every kit release the Hub kit-adopt workflow opens an adoption PR here that bumps `@mutmutco/mmwork-ds`, runs `mmwork-sync-impeccable`, and writes `DESIGN.md`, the `.impeccable` design manifest and `.impeccable/config.json` (`hook.enabled: true`) at the repository root, and deletes any stale copies under `module/`. These files are kit-owned: do not hand-edit them, and keep them committed even if `.impeccable/` is ignored (the adoption PR force-stages them). The adoption PR and any `kit-adopt` failure issue are Hub-owned — merge the PR or leave it for the Hub's scheduled reconcile, and leave failure issues open and unedited; a hand-closed unmerged adoption PR strands the operation until an explicit `--recover-closed-pr` dispatch retires it.
|
|
19
19
|
5. **Root only:** `PRODUCT.md`, `DESIGN.md`, the `.impeccable` design manifest and `.impeccable/config.json` live only at this repository's root, never duplicated under `module/`; a copy there makes Impeccable treat `module/` as a separate root without `PRODUCT.md` and the config. Run `impeccable context` from the root. Any suite-wide propagation of these files needs an explicit intercom ACK handshake with the MM-Work Design Lead naming the files written and removed, `impeccable context` + `impeccable doctor --json` verification, and the issue/PR reference.
|
|
20
20
|
6. **Front-loaded harmony (owner, 2026-10-25; Hub#8837 / MM-Work#7668):** design work runs one workflow — Front-Loaded Impeccable v4.7.0 + MM Artifacts + Live Docs (`Canlı belgeler`, `3a5c79df-5274-40ad-a1b5-a75e67a74dac`) + Atomic Design Kit (`@mutmutco/mmwork-ds`). The former local stage skill is retired; preview and verify through these tools only.
|
|
21
21
|
|