@seanyao/roll 4.702.3 → 4.702.4
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/CHANGELOG.md +5 -0
- package/README.md +1 -1
- package/dist/roll.mjs +278 -97
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -201,7 +201,7 @@ with `roll loop resume` when ready.
|
|
|
201
201
|
| `roll agent [migrate\|list\|cast]` | Agent Scope, installed-agent inventory, and role casting |
|
|
202
202
|
| `roll backlog [sync\|block\|defer\|lint\|…]` | View, manage, lint, and sync pending tasks |
|
|
203
203
|
| `roll config [lang\|prices\|tune\|…]` | Read/write configuration, model prices, and suggest-only tuning |
|
|
204
|
-
| `roll design [--from-file <path>] [--agent <name>]` | Launch `$roll-design`
|
|
204
|
+
| `roll design [--from-file <path>] [--agent <name>] [--verbose\|--raw]` | Launch `$roll-design` with bounded live progress, card-created events, quiet heartbeats, raw transcript capture, and a final handoff |
|
|
205
205
|
| `roll doctor [skills\|tools\|language]` | Diagnose install health, skills, tools, permissions, and language drift |
|
|
206
206
|
| `roll help [--lang en\|zh] [name]` | View built-in Charter / guide docs; `roll --help` prints CLI usage |
|
|
207
207
|
| `roll idea "<one-sentence description>"` | Capture and classify a new backlog card |
|
package/dist/roll.mjs
CHANGED
|
@@ -2240,8 +2240,8 @@ var init_catalog_v3 = __esm({
|
|
|
2240
2240
|
// `design.*` — explicit `roll design` entry point (US-ONBOARD-NUDGE-004 / FIX-1055).
|
|
2241
2241
|
// Thin wrapper that launches the existing $roll-design skill interactively.
|
|
2242
2242
|
"design.usage": {
|
|
2243
|
-
en: 'Usage: roll design [--from-file <path> | "<requirement>"] [--agent <name>] [--verbose|--raw]\n Launch the $roll-design skill in an interactive agent conversation.\n `--from-file` binds a PRD/brief file as the design input.\n `"<requirement>"` binds a free-text design target; it cannot be combined with `--from-file`.\n `--agent` and `ROLL_DESIGN_AGENT` override only this design session; scoped roles live in ~/.roll/agents.yaml and .roll/agents.yaml.\n `--verbose`
|
|
2244
|
-
zh: '\u7528\u6CD5\uFF1Aroll design [--from-file <path> | "<requirement>"] [--agent <name>] [--verbose|--raw]\n \u5728\u4EA4\u4E92\u5F0F agent \u5BF9\u8BDD\u4E2D\u542F\u52A8 $roll-design skill\u3002\n `--from-file` \u4F1A\u628A PRD/brief \u6587\u4EF6\u7ED1\u5B9A\u4E3A\u8BBE\u8BA1\u8F93\u5165\u3002\n `"<requirement>"` \u4F1A\u7ED1\u5B9A\u81EA\u7531\u6587\u672C\u8BBE\u8BA1\u76EE\u6807\uFF1B\u4E0D\u80FD\u4E0E `--from-file` \u6DF7\u7528\u3002\n `--agent` \u4E0E `ROLL_DESIGN_AGENT` \u53EA\u8986\u76D6\u672C\u6B21 design session\uFF1Bscoped roles \u4F4D\u4E8E ~/.roll/agents.yaml \u548C .roll/agents.yaml\u3002\n `--verbose` \u663E\u793A
|
|
2243
|
+
en: 'Usage: roll design [--from-file <path> | "<requirement>"] [--agent <name>] [--verbose|--raw]\n Launch the $roll-design skill in an interactive agent conversation.\n Default output streams bounded live progress, card-created events, quiet heartbeats, and the final handoff while preserving the raw transcript.\n `--from-file` binds a PRD/brief file as the design input.\n `"<requirement>"` binds a free-text design target; it cannot be combined with `--from-file`.\n `--agent` and `ROLL_DESIGN_AGENT` override only this design session; scoped roles live in ~/.roll/agents.yaml and .roll/agents.yaml.\n `--verbose` streams lower-priority normalized activity; `--raw` streams the raw child output live.\n Unlike `roll init`, this command runs an LLM \u2014 run it only when you want to design.',
|
|
2244
|
+
zh: '\u7528\u6CD5\uFF1Aroll design [--from-file <path> | "<requirement>"] [--agent <name>] [--verbose|--raw]\n \u5728\u4EA4\u4E92\u5F0F agent \u5BF9\u8BDD\u4E2D\u542F\u52A8 $roll-design skill\u3002\n \u9ED8\u8BA4\u8F93\u51FA\u4F1A\u5B9E\u65F6\u663E\u793A\u6709\u754C\u8FDB\u5C55\u3001\u5EFA\u5361\u4E8B\u4EF6\u3001\u9759\u9ED8\u5FC3\u8DF3\u548C\u6700\u7EC8\u4EA4\u4ED8\uFF0C\u540C\u65F6\u4FDD\u7559\u5B8C\u6574\u539F\u59CB\u8BB0\u5F55\u3002\n `--from-file` \u4F1A\u628A PRD/brief \u6587\u4EF6\u7ED1\u5B9A\u4E3A\u8BBE\u8BA1\u8F93\u5165\u3002\n `"<requirement>"` \u4F1A\u7ED1\u5B9A\u81EA\u7531\u6587\u672C\u8BBE\u8BA1\u76EE\u6807\uFF1B\u4E0D\u80FD\u4E0E `--from-file` \u6DF7\u7528\u3002\n `--agent` \u4E0E `ROLL_DESIGN_AGENT` \u53EA\u8986\u76D6\u672C\u6B21 design session\uFF1Bscoped roles \u4F4D\u4E8E ~/.roll/agents.yaml \u548C .roll/agents.yaml\u3002\n `--verbose` \u5B9E\u65F6\u663E\u793A\u8F83\u4F4E\u4F18\u5148\u7EA7\u7684\u89C4\u8303\u5316\u6D3B\u52A8\uFF1B`--raw` \u5B9E\u65F6\u8F93\u51FA\u5B50\u8FDB\u7A0B\u539F\u59CB\u6D41\u3002\n \u4E0E `roll init` \u4E0D\u540C\uFF0C\u672C\u547D\u4EE4\u4F1A\u8FD0\u884C LLM\u2014\u2014\u53EA\u5728\u9700\u8981\u8BBE\u8BA1\u65F6\u6267\u884C\u3002'
|
|
2245
2245
|
},
|
|
2246
2246
|
"design.not_roll_project": {
|
|
2247
2247
|
en: "This directory is not a Roll project (no .roll/). Run `roll init` first.",
|
|
@@ -233650,7 +233650,7 @@ __export(showcase_exports, {
|
|
|
233650
233650
|
resetSandbox: () => resetSandbox,
|
|
233651
233651
|
showcaseCommand: () => showcaseCommand
|
|
233652
233652
|
});
|
|
233653
|
-
import { spawnSync as
|
|
233653
|
+
import { spawnSync as spawnSync15 } from "node:child_process";
|
|
233654
233654
|
import { cpSync as cpSync2, existsSync as existsSync105, mkdirSync as mkdirSync51, mkdtempSync as mkdtempSync8, readdirSync as readdirSync41, readFileSync as readFileSync99, rmSync as rmSync18, statSync as statSync35, writeFileSync as writeFileSync54 } from "node:fs";
|
|
233655
233655
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
233656
233656
|
import { dirname as dirname49, join as join109 } from "node:path";
|
|
@@ -233722,7 +233722,7 @@ function runRoll(sandbox, rollHome4, args, opts = {}) {
|
|
|
233722
233722
|
}
|
|
233723
233723
|
const bin = rollBin3();
|
|
233724
233724
|
const [cmd, cmdArgs] = bin === "roll" ? [bin, args] : [process.execPath, [bin, ...args]];
|
|
233725
|
-
const r =
|
|
233725
|
+
const r = spawnSync15(cmd, cmdArgs, {
|
|
233726
233726
|
cwd: sandbox,
|
|
233727
233727
|
env,
|
|
233728
233728
|
encoding: "utf8",
|
|
@@ -262247,8 +262247,8 @@ function nextCommand(args) {
|
|
|
262247
262247
|
// packages/cli/dist/commands/design.js
|
|
262248
262248
|
init_dist();
|
|
262249
262249
|
init_dist2();
|
|
262250
|
-
import {
|
|
262251
|
-
import { existsSync as existsSync85, mkdirSync as mkdirSync37, readFileSync as readFileSync78, renameSync as renameSync16, statSync as statSync31, writeFileSync as writeFileSync39 } from "node:fs";
|
|
262250
|
+
import { spawn as spawnChild } from "node:child_process";
|
|
262251
|
+
import { appendFileSync as appendFileSync13, existsSync as existsSync85, mkdirSync as mkdirSync37, readFileSync as readFileSync78, renameSync as renameSync16, statSync as statSync31, writeFileSync as writeFileSync39 } from "node:fs";
|
|
262252
262252
|
import { dirname as dirname39, join as join88, relative as relative6, resolve as resolve9 } from "node:path";
|
|
262253
262253
|
|
|
262254
262254
|
// packages/cli/dist/lib/review-page.js
|
|
@@ -262635,7 +262635,7 @@ function lookupEpic(target, cwd) {
|
|
|
262635
262635
|
function readBacklogItems(cwd) {
|
|
262636
262636
|
try {
|
|
262637
262637
|
const content = readFileSync78(join88(cwd, ".roll", "backlog.md"), "utf8");
|
|
262638
|
-
return parseBacklog(content).map((row2) => ({ id: row2.id }));
|
|
262638
|
+
return parseBacklog(content).map((row2) => ({ id: row2.id, desc: row2.desc }));
|
|
262639
262639
|
} catch {
|
|
262640
262640
|
return [];
|
|
262641
262641
|
}
|
|
@@ -262691,37 +262691,203 @@ function formatSignal(sig) {
|
|
|
262691
262691
|
const detail = sig.detail !== void 0 && sig.detail !== "" ? ` ${sig.detail}` : "";
|
|
262692
262692
|
return `${fmtHhmmss(sig.ts)} ${sig.summary}${detail}`.trimEnd();
|
|
262693
262693
|
}
|
|
262694
|
-
function
|
|
262695
|
-
|
|
262694
|
+
function isPromiseLike(value) {
|
|
262695
|
+
return typeof value.then === "function";
|
|
262696
|
+
}
|
|
262697
|
+
function isDesignNoise(text2) {
|
|
262698
|
+
const s = text2.trim();
|
|
262699
|
+
if (s === "")
|
|
262700
|
+
return true;
|
|
262701
|
+
if (/^\?\?\s/.test(s))
|
|
262702
|
+
return true;
|
|
262703
|
+
if (/^\s*-\s*\[\s*\]\s+/.test(s))
|
|
262704
|
+
return true;
|
|
262705
|
+
return /\$roll-design|roll-design contract|ID generation algorithm|Who writes the data|encrypted reasoning/i.test(s);
|
|
262706
|
+
}
|
|
262707
|
+
function isMeaningfulDesignSay(summary) {
|
|
262708
|
+
return /\b(reading|planning|designing|writing|validating|recovering|handoff|backlog|spec|artifact|context|contexts|created|card)\b/i.test(summary);
|
|
262709
|
+
}
|
|
262710
|
+
function shouldShowSignal(sig, verbose) {
|
|
262711
|
+
const joined = `${sig.summary} ${sig.detail ?? ""}`;
|
|
262712
|
+
if (isDesignNoise(joined))
|
|
262713
|
+
return false;
|
|
262714
|
+
if (verbose)
|
|
262715
|
+
return true;
|
|
262716
|
+
if (sig.tier === "A" || sig.tier === "B")
|
|
262717
|
+
return true;
|
|
262718
|
+
if (sig.kind === "say" && isMeaningfulDesignSay(sig.summary))
|
|
262719
|
+
return true;
|
|
262720
|
+
return sig.kind === "say" && isQuestionLike(sig.summary);
|
|
262721
|
+
}
|
|
262722
|
+
function formatDuration(ms) {
|
|
262723
|
+
const total = Math.max(0, Math.round(ms / 1e3));
|
|
262724
|
+
const m7 = Math.floor(total / 60);
|
|
262725
|
+
const s = total % 60;
|
|
262726
|
+
if (m7 === 0)
|
|
262727
|
+
return `${s}s`;
|
|
262728
|
+
return `${m7}m ${String(s).padStart(2, "0")}s`;
|
|
262729
|
+
}
|
|
262730
|
+
function formatBytes(bytes) {
|
|
262731
|
+
if (bytes < 1024)
|
|
262732
|
+
return `${bytes} B`;
|
|
262733
|
+
if (bytes < 1024 * 1024)
|
|
262734
|
+
return `${Math.round(bytes / 1024)} KB`;
|
|
262735
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
262736
|
+
}
|
|
262737
|
+
function transcriptSize(path) {
|
|
262738
|
+
try {
|
|
262739
|
+
return statSync31(path).size;
|
|
262740
|
+
} catch {
|
|
262741
|
+
return 0;
|
|
262742
|
+
}
|
|
262743
|
+
}
|
|
262744
|
+
function splitCardDescription(desc) {
|
|
262745
|
+
const clean3 = desc.replace(/\s+/g, " ").trim();
|
|
262746
|
+
const solves = /\s+·\s+solves\s+/i.exec(clean3);
|
|
262747
|
+
if (solves !== null) {
|
|
262748
|
+
const title = clean3.slice(0, solves.index).trim();
|
|
262749
|
+
const problem = clean3.slice(solves.index + solves[0].length).trim();
|
|
262750
|
+
return { title: title || clean3, problem: problem || title || clean3 };
|
|
262751
|
+
}
|
|
262752
|
+
return { title: clean3 || "Untitled card", problem: clean3 || "the design gap" };
|
|
262753
|
+
}
|
|
262754
|
+
function createLiveProgress(ctx, deps, opts) {
|
|
262755
|
+
const normalizer = normalizerFor(ctx.agent);
|
|
262696
262756
|
const state = newNormalizerState();
|
|
262697
|
-
const
|
|
262698
|
-
const
|
|
262699
|
-
|
|
262700
|
-
|
|
262701
|
-
|
|
262702
|
-
|
|
262757
|
+
const emittedCards = /* @__PURE__ */ new Set();
|
|
262758
|
+
const knownBefore = new Set(ctx.beforeBacklog.map((row2) => row2.id));
|
|
262759
|
+
let stdoutBuffer = "";
|
|
262760
|
+
let stderrBuffer = "";
|
|
262761
|
+
let rawTranscript = "";
|
|
262762
|
+
let sawLiveOutput = false;
|
|
262763
|
+
let lastPrintedTs = ctx.startTs;
|
|
262764
|
+
let heartbeat;
|
|
262765
|
+
const scanCards = () => {
|
|
262766
|
+
if (opts.raw)
|
|
262767
|
+
return;
|
|
262768
|
+
for (const item of readBacklogItems(ctx.cwd)) {
|
|
262769
|
+
if (knownBefore.has(item.id) || emittedCards.has(item.id))
|
|
262770
|
+
continue;
|
|
262771
|
+
emittedCards.add(item.id);
|
|
262772
|
+
const { title, problem } = splitCardDescription(item.desc);
|
|
262773
|
+
const ts2 = deps.now();
|
|
262774
|
+
lastPrintedTs = ts2;
|
|
262775
|
+
emit4(`${fmtHhmmss(ts2)} card created: ${item.id} \u2014 ${title} \xB7 solves ${problem}`);
|
|
262776
|
+
}
|
|
262777
|
+
};
|
|
262778
|
+
const processLine = (line) => {
|
|
262779
|
+
if (opts.raw)
|
|
262780
|
+
return;
|
|
262781
|
+
const ts2 = deps.now();
|
|
262782
|
+
const signals = normalizer.normalize(line, state, ts2);
|
|
262703
262783
|
for (const sig of signals) {
|
|
262704
|
-
|
|
262705
|
-
|
|
262706
|
-
|
|
262784
|
+
if (!shouldShowSignal(sig, opts.verbose))
|
|
262785
|
+
continue;
|
|
262786
|
+
lastPrintedTs = sig.ts;
|
|
262787
|
+
emit4(formatSignal(sig));
|
|
262788
|
+
}
|
|
262789
|
+
};
|
|
262790
|
+
const ingest = (chunk, stream) => {
|
|
262791
|
+
if (chunk === "")
|
|
262792
|
+
return;
|
|
262793
|
+
sawLiveOutput = true;
|
|
262794
|
+
rawTranscript += chunk;
|
|
262795
|
+
appendFileSync13(ctx.transcriptPath, chunk, "utf8");
|
|
262796
|
+
if (opts.raw) {
|
|
262797
|
+
process.stderr.write(chunk);
|
|
262798
|
+
return;
|
|
262799
|
+
}
|
|
262800
|
+
const next = (stream === "stdout" ? stdoutBuffer : stderrBuffer) + chunk;
|
|
262801
|
+
const parts = next.split(/\n/);
|
|
262802
|
+
const complete = parts.slice(0, -1);
|
|
262803
|
+
for (const line of complete)
|
|
262804
|
+
processLine(line);
|
|
262805
|
+
if (stream === "stdout")
|
|
262806
|
+
stdoutBuffer = parts[parts.length - 1] ?? "";
|
|
262807
|
+
else
|
|
262808
|
+
stderrBuffer = parts[parts.length - 1] ?? "";
|
|
262809
|
+
scanCards();
|
|
262810
|
+
};
|
|
262811
|
+
const emitHeartbeat = () => {
|
|
262812
|
+
if (opts.raw)
|
|
262813
|
+
return;
|
|
262814
|
+
const ts2 = deps.now();
|
|
262815
|
+
if (ts2 - lastPrintedTs < deps.heartbeatMs)
|
|
262816
|
+
return;
|
|
262817
|
+
lastPrintedTs = ts2;
|
|
262818
|
+
emit4(`${fmtHhmmss(ts2)} heartbeat: still designing \xB7 elapsed ${formatDuration(ts2 - ctx.startTs)} \xB7 transcript ${formatBytes(transcriptSize(ctx.transcriptPath))} \xB7 cards observed ${emittedCards.size}`);
|
|
262819
|
+
};
|
|
262820
|
+
return {
|
|
262821
|
+
get sawLiveOutput() {
|
|
262822
|
+
return sawLiveOutput;
|
|
262823
|
+
},
|
|
262824
|
+
get rawTranscript() {
|
|
262825
|
+
return rawTranscript;
|
|
262826
|
+
},
|
|
262827
|
+
startHeartbeat: () => {
|
|
262828
|
+
if (opts.raw)
|
|
262829
|
+
return;
|
|
262830
|
+
heartbeat = setInterval(emitHeartbeat, deps.heartbeatMs);
|
|
262831
|
+
heartbeat.unref?.();
|
|
262832
|
+
},
|
|
262833
|
+
stopHeartbeat: () => {
|
|
262834
|
+
if (heartbeat !== void 0)
|
|
262835
|
+
clearInterval(heartbeat);
|
|
262836
|
+
},
|
|
262837
|
+
ingestStdout: (chunk) => ingest(chunk, "stdout"),
|
|
262838
|
+
ingestStderr: (chunk) => ingest(chunk, "stderr"),
|
|
262839
|
+
flush: () => {
|
|
262840
|
+
if (stdoutBuffer !== "") {
|
|
262841
|
+
processLine(stdoutBuffer);
|
|
262842
|
+
stdoutBuffer = "";
|
|
262843
|
+
}
|
|
262844
|
+
if (stderrBuffer !== "") {
|
|
262845
|
+
processLine(stderrBuffer);
|
|
262846
|
+
stderrBuffer = "";
|
|
262707
262847
|
}
|
|
262848
|
+
scanCards();
|
|
262708
262849
|
}
|
|
262709
|
-
}
|
|
262710
|
-
return out3;
|
|
262850
|
+
};
|
|
262711
262851
|
}
|
|
262712
262852
|
var defaultDeps = {
|
|
262713
262853
|
cwd: process.cwd(),
|
|
262714
262854
|
env: process.env,
|
|
262715
262855
|
readLine: readLineFromStdin,
|
|
262716
262856
|
now: () => Date.now(),
|
|
262717
|
-
|
|
262718
|
-
|
|
262719
|
-
return {
|
|
262720
|
-
|
|
262721
|
-
|
|
262722
|
-
|
|
262723
|
-
|
|
262724
|
-
|
|
262857
|
+
heartbeatMs: 6e4,
|
|
262858
|
+
spawn: (bin, args, opts, live) => {
|
|
262859
|
+
return new Promise((resolveSpawn) => {
|
|
262860
|
+
const child = spawnChild(bin, args, { ...opts, stdio: ["inherit", "pipe", "pipe"] });
|
|
262861
|
+
let stdout = "";
|
|
262862
|
+
let stderr = "";
|
|
262863
|
+
let settled = false;
|
|
262864
|
+
const finish = (result) => {
|
|
262865
|
+
if (settled)
|
|
262866
|
+
return;
|
|
262867
|
+
settled = true;
|
|
262868
|
+
resolveSpawn(result);
|
|
262869
|
+
};
|
|
262870
|
+
child.stdout?.setEncoding("utf8");
|
|
262871
|
+
child.stderr?.setEncoding("utf8");
|
|
262872
|
+
child.stdout?.on("data", (chunk) => {
|
|
262873
|
+
stdout += chunk;
|
|
262874
|
+
live?.onStdout(chunk);
|
|
262875
|
+
});
|
|
262876
|
+
child.stderr?.on("data", (chunk) => {
|
|
262877
|
+
stderr += chunk;
|
|
262878
|
+
live?.onStderr(chunk);
|
|
262879
|
+
});
|
|
262880
|
+
child.on("error", (err16) => {
|
|
262881
|
+
const message = `${err16 instanceof Error ? err16.message : String(err16)}
|
|
262882
|
+
`;
|
|
262883
|
+
stderr += message;
|
|
262884
|
+
live?.onStderr(message);
|
|
262885
|
+
finish({ status: 1, signal: null, stdout, stderr });
|
|
262886
|
+
});
|
|
262887
|
+
child.on("close", (code, signal) => {
|
|
262888
|
+
finish({ status: code, signal, stdout, stderr });
|
|
262889
|
+
});
|
|
262890
|
+
});
|
|
262725
262891
|
}
|
|
262726
262892
|
};
|
|
262727
262893
|
function selectAgent(installed, forced, envAgent, primary, readLine) {
|
|
@@ -262909,20 +263075,35 @@ function designCommand(args, deps = {}) {
|
|
|
262909
263075
|
beforeBacklog: readBacklogItems(d.cwd)
|
|
262910
263076
|
};
|
|
262911
263077
|
printStartBlock(ctx);
|
|
262912
|
-
const
|
|
262913
|
-
|
|
262914
|
-
|
|
262915
|
-
|
|
262916
|
-
|
|
262917
|
-
|
|
262918
|
-
|
|
262919
|
-
|
|
262920
|
-
|
|
262921
|
-
|
|
263078
|
+
const live = createLiveProgress(ctx, d, { raw: rawMode, verbose });
|
|
263079
|
+
live.startHeartbeat();
|
|
263080
|
+
const finish = (result) => {
|
|
263081
|
+
if (!live.sawLiveOutput) {
|
|
263082
|
+
live.ingestStdout(result.stdout ?? "");
|
|
263083
|
+
live.ingestStderr(result.stderr ?? "");
|
|
263084
|
+
} else {
|
|
263085
|
+
const stdout = result.stdout ?? "";
|
|
263086
|
+
const stderr = result.stderr ?? "";
|
|
263087
|
+
if (stdout !== "" && !live.rawTranscript.includes(stdout))
|
|
263088
|
+
live.ingestStdout(stdout);
|
|
263089
|
+
if (stderr !== "" && !live.rawTranscript.includes(stderr))
|
|
263090
|
+
live.ingestStderr(stderr);
|
|
263091
|
+
}
|
|
263092
|
+
live.stopHeartbeat();
|
|
263093
|
+
live.flush();
|
|
263094
|
+
const statusCode = result.status ?? (result.signal === null ? 1 : 130);
|
|
263095
|
+
printHandoff(ctx, statusCode, live.rawTranscript);
|
|
263096
|
+
return statusCode;
|
|
263097
|
+
};
|
|
263098
|
+
const spawned = d.spawn(cmd.bin, cmd.args, { cwd: d.cwd, env: d.env }, { onStdout: live.ingestStdout, onStderr: live.ingestStderr });
|
|
263099
|
+
if (isPromiseLike(spawned)) {
|
|
263100
|
+
return spawned.then(finish, (err16) => {
|
|
263101
|
+
live.ingestStderr(`${err16 instanceof Error ? err16.message : String(err16)}
|
|
263102
|
+
`);
|
|
263103
|
+
return finish({ status: 1, signal: null });
|
|
263104
|
+
});
|
|
262922
263105
|
}
|
|
262923
|
-
|
|
262924
|
-
printHandoff(ctx, statusCode, rawTranscript);
|
|
262925
|
-
return statusCode;
|
|
263106
|
+
return finish(spawned);
|
|
262926
263107
|
}
|
|
262927
263108
|
|
|
262928
263109
|
// packages/cli/dist/commands/loop-watch.js
|
|
@@ -262930,7 +263111,7 @@ init_dist();
|
|
|
262930
263111
|
init_dist2();
|
|
262931
263112
|
init_dist3();
|
|
262932
263113
|
init_render();
|
|
262933
|
-
import { spawn as spawn8, spawnSync as
|
|
263114
|
+
import { spawn as spawn8, spawnSync as spawnSync12 } from "node:child_process";
|
|
262934
263115
|
import { existsSync as existsSync86, readFileSync as readFileSync79 } from "node:fs";
|
|
262935
263116
|
import { join as join89 } from "node:path";
|
|
262936
263117
|
import { createInterface as createInterface4 } from "node:readline";
|
|
@@ -263091,13 +263272,13 @@ function realDeps7() {
|
|
|
263091
263272
|
render: (input, opts) => streamThroughRenderer(input, process.stdout, opts),
|
|
263092
263273
|
renderEvents: streamEvents,
|
|
263093
263274
|
tmuxState: probeWatchTmuxState,
|
|
263094
|
-
tmuxRun: (argv) =>
|
|
263275
|
+
tmuxRun: (argv) => spawnSync12("tmux", argv, { stdio: "ignore" }).status === 0,
|
|
263095
263276
|
tmuxAttach: (session) => {
|
|
263096
|
-
|
|
263277
|
+
spawnSync12("tmux", ["attach-session", "-r", "-t", session], { stdio: "inherit" });
|
|
263097
263278
|
},
|
|
263098
263279
|
hasTmux: () => {
|
|
263099
263280
|
try {
|
|
263100
|
-
return
|
|
263281
|
+
return spawnSync12("tmux", ["-V"], { stdio: "ignore" }).status === 0;
|
|
263101
263282
|
} catch {
|
|
263102
263283
|
return false;
|
|
263103
263284
|
}
|
|
@@ -263108,10 +263289,10 @@ function realDeps7() {
|
|
|
263108
263289
|
}
|
|
263109
263290
|
function probeWatchTmuxState(slug3) {
|
|
263110
263291
|
const session = watchSessionName(slug3);
|
|
263111
|
-
const sessionExists =
|
|
263292
|
+
const sessionExists = spawnSync12("tmux", ["has-session", "-t", session], { stdio: "ignore" }).status === 0;
|
|
263112
263293
|
if (!sessionExists)
|
|
263113
263294
|
return { sessionExists: false, watchWindowExists: false };
|
|
263114
|
-
const listed =
|
|
263295
|
+
const listed = spawnSync12("tmux", ["list-windows", "-t", session, "-F", "#{window_name}"], { encoding: "utf8" });
|
|
263115
263296
|
const windows = listed.status === 0 ? String(listed.stdout ?? "").split("\n").map((w) => w.trim()) : [];
|
|
263116
263297
|
return { sessionExists: true, watchWindowExists: windows.includes("watch") };
|
|
263117
263298
|
}
|
|
@@ -263488,14 +263669,14 @@ ${RECONCILE_PENDING_USAGE}
|
|
|
263488
263669
|
|
|
263489
263670
|
// packages/cli/dist/commands/loop-review-resize.js
|
|
263490
263671
|
init_dist2();
|
|
263491
|
-
import { appendFileSync as
|
|
263672
|
+
import { appendFileSync as appendFileSync15, mkdirSync as mkdirSync39 } from "node:fs";
|
|
263492
263673
|
import { dirname as dirname41, join as join92 } from "node:path";
|
|
263493
263674
|
init_dist2();
|
|
263494
263675
|
|
|
263495
263676
|
// packages/cli/dist/commands/loop-self-downgrade.js
|
|
263496
263677
|
init_dist2();
|
|
263497
263678
|
init_dist3();
|
|
263498
|
-
import { appendFileSync as
|
|
263679
|
+
import { appendFileSync as appendFileSync14, existsSync as existsSync87, mkdirSync as mkdirSync38, readFileSync as readFileSync80, readdirSync as readdirSync32 } from "node:fs";
|
|
263499
263680
|
import { dirname as dirname40, join as join91 } from "node:path";
|
|
263500
263681
|
function realSelfDowngradeDeps() {
|
|
263501
263682
|
return {
|
|
@@ -263610,7 +263791,7 @@ async function loopSelfDowngradeCommand(argv, deps = realSelfDowngradeDeps()) {
|
|
|
263610
263791
|
const headline = plan.capReason === "chain-cap" ? `${parentId} hit the self-downgrade chain cap (chain_depth=${plan.chainDepth} \u2265 ${CHAIN_DEPTH_CAP}) \u2014 held for human triage` : `${parentId} could not be split into \u22652 sub-stories (irreducible) \u2014 held for human triage`;
|
|
263611
263792
|
try {
|
|
263612
263793
|
mkdirSync38(dirname40(alertsPath), { recursive: true });
|
|
263613
|
-
|
|
263794
|
+
appendFileSync14(alertsPath, `[${isoUtc(ts2)}] ALERT ${headline}
|
|
263614
263795
|
`, "utf8");
|
|
263615
263796
|
} catch {
|
|
263616
263797
|
}
|
|
@@ -263713,7 +263894,7 @@ For each sub-story create its .roll/features/<epic>/<id>/spec.md. Do NOT edit th
|
|
|
263713
263894
|
const alertsPath = (process.env["ROLL_LOOP_ALERT"] ?? "").trim() || join92(rt, `ALERT-${projectSlug3(projectPath3)}.md`);
|
|
263714
263895
|
try {
|
|
263715
263896
|
mkdirSync39(dirname41(alertsPath), { recursive: true });
|
|
263716
|
-
|
|
263897
|
+
appendFileSync15(alertsPath, `[${new Date(ts2).toISOString()}] ALERT ${message}
|
|
263717
263898
|
`, "utf8");
|
|
263718
263899
|
} catch {
|
|
263719
263900
|
}
|
|
@@ -263813,7 +263994,7 @@ async function loopExhaustionSplitCommand(argv, deps = realExhaustionSplitDeps()
|
|
|
263813
263994
|
init_dist2();
|
|
263814
263995
|
init_dist();
|
|
263815
263996
|
init_dist3();
|
|
263816
|
-
import { appendFileSync as
|
|
263997
|
+
import { appendFileSync as appendFileSync19, existsSync as existsSync99, mkdirSync as mkdirSync47, readFileSync as readFileSync93, writeFileSync as writeFileSync49 } from "node:fs";
|
|
263817
263998
|
import { dirname as dirname46, join as join103 } from "node:path";
|
|
263818
263999
|
|
|
263819
264000
|
// packages/cli/dist/runner/executor.js
|
|
@@ -263862,7 +264043,7 @@ function writeCycleRoleSummaryBestEffort(cycleId, eventsPath3, cycleLogDir) {
|
|
|
263862
264043
|
|
|
263863
264044
|
// packages/cli/dist/runner/executor.js
|
|
263864
264045
|
import { execFile as execFile10, execFileSync as execFileSync22 } from "node:child_process";
|
|
263865
|
-
import { appendFileSync as
|
|
264046
|
+
import { appendFileSync as appendFileSync17, existsSync as existsSync95, lstatSync as lstatSync5, mkdirSync as mkdirSync44, readdirSync as readdirSync36, readFileSync as readFileSync89, realpathSync as realpathSync13, renameSync as renameSync17, rmSync as rmSync16, statSync as statSync33, symlinkSync as symlinkSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync46 } from "node:fs";
|
|
263866
264047
|
import { homedir as homedir27 } from "node:os";
|
|
263867
264048
|
import { dirname as dirname43, join as join100 } from "node:path";
|
|
263868
264049
|
import { promisify as promisify10 } from "node:util";
|
|
@@ -264515,7 +264696,7 @@ function autoAttachScreenshotToAcMap(worktreeCwd, storyId, runDir) {
|
|
|
264515
264696
|
// packages/cli/dist/runner/correction-actuator.js
|
|
264516
264697
|
init_dist2();
|
|
264517
264698
|
init_dist();
|
|
264518
|
-
import { appendFileSync as
|
|
264699
|
+
import { appendFileSync as appendFileSync16, existsSync as existsSync93, mkdirSync as mkdirSync42, readFileSync as readFileSync87, readdirSync as readdirSync35, writeFileSync as writeFileSync44 } from "node:fs";
|
|
264519
264700
|
import { dirname as dirname42, join as join98 } from "node:path";
|
|
264520
264701
|
function readMode(projectPath3) {
|
|
264521
264702
|
try {
|
|
@@ -264537,7 +264718,7 @@ function readEvents4(eventsPath3) {
|
|
|
264537
264718
|
function appendEvent(eventsPath3, event) {
|
|
264538
264719
|
try {
|
|
264539
264720
|
mkdirSync42(dirname42(eventsPath3), { recursive: true });
|
|
264540
|
-
|
|
264721
|
+
appendFileSync16(eventsPath3, `${JSON.stringify(event)}
|
|
264541
264722
|
`, "utf8");
|
|
264542
264723
|
} catch {
|
|
264543
264724
|
}
|
|
@@ -264545,7 +264726,7 @@ function appendEvent(eventsPath3, event) {
|
|
|
264545
264726
|
function appendAlert2(alertsPath, msg6) {
|
|
264546
264727
|
try {
|
|
264547
264728
|
mkdirSync42(dirname42(alertsPath), { recursive: true });
|
|
264548
|
-
|
|
264729
|
+
appendFileSync16(alertsPath, `${msg6}
|
|
264549
264730
|
`, "utf8");
|
|
264550
264731
|
} catch {
|
|
264551
264732
|
}
|
|
@@ -265333,7 +265514,7 @@ var ActivitySignalRecorder = class {
|
|
|
265333
265514
|
}
|
|
265334
265515
|
append(signals) {
|
|
265335
265516
|
try {
|
|
265336
|
-
|
|
265517
|
+
appendFileSync17(this.signalPath, signals.map((sig) => JSON.stringify(sig)).join("\n") + "\n", "utf8");
|
|
265337
265518
|
} catch {
|
|
265338
265519
|
}
|
|
265339
265520
|
}
|
|
@@ -265702,7 +265883,7 @@ function createCaptureMarkerSink(runDir, capture) {
|
|
|
265702
265883
|
const record = (marker, result) => {
|
|
265703
265884
|
try {
|
|
265704
265885
|
mkdirSync44(dirname43(logPath), { recursive: true });
|
|
265705
|
-
|
|
265886
|
+
appendFileSync17(logPath, JSON.stringify({ marker, result }) + "\n", "utf8");
|
|
265706
265887
|
} catch {
|
|
265707
265888
|
}
|
|
265708
265889
|
};
|
|
@@ -265948,7 +266129,7 @@ ${skillBodyForSpawn}` : skillBodyForSpawn;
|
|
|
265948
266129
|
stallDetector.markProgress();
|
|
265949
266130
|
captureSink?.onChunk(d);
|
|
265950
266131
|
try {
|
|
265951
|
-
|
|
266132
|
+
appendFileSync17(livePath, d);
|
|
265952
266133
|
} catch {
|
|
265953
266134
|
}
|
|
265954
266135
|
signalRecorder.accept(d);
|
|
@@ -267546,7 +267727,7 @@ async function linkRollIntoWorktree(repoCwd, worktreePath) {
|
|
|
267546
267727
|
const cur = existsSync95(exclude) ? readFileSync89(exclude, "utf8") : "";
|
|
267547
267728
|
if (!/^\.roll$/m.test(cur)) {
|
|
267548
267729
|
mkdirSync44(dirname43(exclude), { recursive: true });
|
|
267549
|
-
|
|
267730
|
+
appendFileSync17(exclude, `${cur === "" || cur.endsWith("\n") ? "" : "\n"}.roll
|
|
267550
267731
|
`, "utf8");
|
|
267551
267732
|
}
|
|
267552
267733
|
} catch {
|
|
@@ -268120,7 +268301,7 @@ function nodePorts(opts) {
|
|
|
268120
268301
|
}
|
|
268121
268302
|
function appendAlertLine(alertsPath, message) {
|
|
268122
268303
|
mkdirSync44(dirname43(alertsPath), { recursive: true });
|
|
268123
|
-
|
|
268304
|
+
appendFileSync17(alertsPath, `${message}
|
|
268124
268305
|
`, "utf8");
|
|
268125
268306
|
}
|
|
268126
268307
|
|
|
@@ -268463,7 +268644,7 @@ async function warnIfBinaryStale(rollHomeDir2, runningVersion, appendAlert3) {
|
|
|
268463
268644
|
// packages/cli/dist/runner/correction-circuit.js
|
|
268464
268645
|
init_dist2();
|
|
268465
268646
|
init_dist();
|
|
268466
|
-
import { appendFileSync as
|
|
268647
|
+
import { appendFileSync as appendFileSync18, existsSync as existsSync98, mkdirSync as mkdirSync46, readFileSync as readFileSync92, writeFileSync as writeFileSync48 } from "node:fs";
|
|
268467
268648
|
import { dirname as dirname45, join as join102 } from "node:path";
|
|
268468
268649
|
function readLoopSafety(projectPath3) {
|
|
268469
268650
|
try {
|
|
@@ -268487,7 +268668,7 @@ function alreadyTripped(events, verdict) {
|
|
|
268487
268668
|
}
|
|
268488
268669
|
function appendEvent2(eventsPath3, event) {
|
|
268489
268670
|
mkdirSync46(dirname45(eventsPath3), { recursive: true });
|
|
268490
|
-
|
|
268671
|
+
appendFileSync18(eventsPath3, `${JSON.stringify(event)}
|
|
268491
268672
|
`, "utf8");
|
|
268492
268673
|
}
|
|
268493
268674
|
function applyCorrectionCircuitBreaker(projectPath3, slug3, eventsPath3, alertsPath, nowSec2 = Math.floor(Date.now() / 1e3)) {
|
|
@@ -268513,7 +268694,7 @@ function applyCorrectionCircuitBreaker(projectPath3, slug3, eventsPath3, alertsP
|
|
|
268513
268694
|
if (pauseWritten)
|
|
268514
268695
|
writeFileSync48(pauseMarker, alertMsg, "utf8");
|
|
268515
268696
|
mkdirSync46(dirname45(alertsPath), { recursive: true });
|
|
268516
|
-
|
|
268697
|
+
appendFileSync18(alertsPath, `${alertMsg}
|
|
268517
268698
|
`, "utf8");
|
|
268518
268699
|
appendEvent2(eventsPath3, {
|
|
268519
268700
|
type: "correction:circuit_breaker",
|
|
@@ -268533,7 +268714,7 @@ function applyCorrectionCircuitBreaker(projectPath3, slug3, eventsPath3, alertsP
|
|
|
268533
268714
|
|
|
268534
268715
|
// packages/cli/dist/commands/loop-run-once.js
|
|
268535
268716
|
init_dist();
|
|
268536
|
-
import { execFileSync as execFileSync23, spawn as spawn9, spawnSync as
|
|
268717
|
+
import { execFileSync as execFileSync23, spawn as spawn9, spawnSync as spawnSync13 } from "node:child_process";
|
|
268537
268718
|
import { lookup as lookup2 } from "node:dns/promises";
|
|
268538
268719
|
function announceReport(projectPath3, slug3, storyId, opener = (p) => {
|
|
268539
268720
|
try {
|
|
@@ -268679,7 +268860,7 @@ function writeCardSkipAlert(alertsPath, eventsPath3, cycleId, storyId, count) {
|
|
|
268679
268860
|
**Action**: investigate ${storyId} (it likely needs a smaller split, a spec fix, or manual delivery). Once addressed, remove it from \`.roll/loop/skip-cards.json\` (or just fix the card) to re-arm it.
|
|
268680
268861
|
`;
|
|
268681
268862
|
try {
|
|
268682
|
-
|
|
268863
|
+
appendFileSync19(alertsPath, `${msg6}
|
|
268683
268864
|
`, "utf8");
|
|
268684
268865
|
} catch {
|
|
268685
268866
|
}
|
|
@@ -268726,7 +268907,7 @@ function incrementConsecutiveFails(projectPath3, slug3, alertsPath, eventsPath3,
|
|
|
268726
268907
|
`;
|
|
268727
268908
|
try {
|
|
268728
268909
|
writeFileSync49(pauseMarker, alertMsg, "utf8");
|
|
268729
|
-
|
|
268910
|
+
appendFileSync19(alertsPath, `${alertMsg}
|
|
268730
268911
|
`, "utf8");
|
|
268731
268912
|
const ts2 = Date.now();
|
|
268732
268913
|
const bus = new EventBus();
|
|
@@ -268893,7 +269074,7 @@ function writeReviewerBlockedAlert(projectPath3, slug3, alertsPath, eventsPath3,
|
|
|
268893
269074
|
` : "") + `**Action**: ${fix}
|
|
268894
269075
|
`;
|
|
268895
269076
|
try {
|
|
268896
|
-
|
|
269077
|
+
appendFileSync19(alertsPath, `${msg6}
|
|
268897
269078
|
`, "utf8");
|
|
268898
269079
|
} catch {
|
|
268899
269080
|
}
|
|
@@ -269044,10 +269225,10 @@ async function loopRunOnceCommand(args) {
|
|
|
269044
269225
|
const headline = t(v3Catalog, lang10, "loop.egress_blocked", cycleId);
|
|
269045
269226
|
try {
|
|
269046
269227
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
269047
|
-
|
|
269228
|
+
appendFileSync19(alertsPath, `[${ts2}] ALERT ${headline}
|
|
269048
269229
|
`, "utf8");
|
|
269049
269230
|
for (const line of guardLines)
|
|
269050
|
-
|
|
269231
|
+
appendFileSync19(alertsPath, `[${ts2}] ALERT ${line}
|
|
269051
269232
|
`, "utf8");
|
|
269052
269233
|
} catch {
|
|
269053
269234
|
}
|
|
@@ -269072,7 +269253,7 @@ loop run-once: ${repoCheck.detail !== "" ? `(${repoCheck.detail})` : ""}
|
|
|
269072
269253
|
if (skillBody === null) {
|
|
269073
269254
|
const msg6 = `[${(/* @__PURE__ */ new Date()).toISOString()}] ALERT loop run-once: roll-loop SKILL.md not found (checked ROLL_LOOP_SKILL, .roll/skills/, skills/) \u2014 cycle ${cycleId} refused to start`;
|
|
269074
269255
|
try {
|
|
269075
|
-
|
|
269256
|
+
appendFileSync19(alertsPath, `${msg6}
|
|
269076
269257
|
`, "utf8");
|
|
269077
269258
|
} catch {
|
|
269078
269259
|
}
|
|
@@ -269106,7 +269287,7 @@ loop run-once: \u627E\u4E0D\u5230 roll-loop SKILL.md \u2014 \u62D2\u7EDD\u76F2\u
|
|
|
269106
269287
|
try {
|
|
269107
269288
|
await warnIfBinaryStale(rollHome(), rollVersion(), (msg6) => {
|
|
269108
269289
|
try {
|
|
269109
|
-
|
|
269290
|
+
appendFileSync19(alertsPath, `${msg6}
|
|
269110
269291
|
`, "utf8");
|
|
269111
269292
|
} catch {
|
|
269112
269293
|
}
|
|
@@ -269344,7 +269525,7 @@ function isLoopPaused(projectPath3, slug3) {
|
|
|
269344
269525
|
}
|
|
269345
269526
|
function checkRepoPushable(projectPath3) {
|
|
269346
269527
|
const git4 = (args) => {
|
|
269347
|
-
const r =
|
|
269528
|
+
const r = spawnSync13("git", args, { cwd: projectPath3, encoding: "utf8" });
|
|
269348
269529
|
return { code: r.status ?? 1, stderr: r.stderr ?? "" };
|
|
269349
269530
|
};
|
|
269350
269531
|
const inside = git4(["rev-parse", "--git-dir"]);
|
|
@@ -269376,7 +269557,7 @@ function writeRepoAlert(alertsPath, eventsPath3, cycleId, result) {
|
|
|
269376
269557
|
**Action**: ${t(v3Catalog, lang10, "loop.no_remote")}
|
|
269377
269558
|
`;
|
|
269378
269559
|
try {
|
|
269379
|
-
|
|
269560
|
+
appendFileSync19(alertsPath, `${msg6}
|
|
269380
269561
|
`, "utf8");
|
|
269381
269562
|
} catch {
|
|
269382
269563
|
}
|
|
@@ -269393,7 +269574,7 @@ function writeRepoAlert(alertsPath, eventsPath3, cycleId, result) {
|
|
|
269393
269574
|
|
|
269394
269575
|
// packages/cli/dist/commands/offboard.js
|
|
269395
269576
|
init_dist();
|
|
269396
|
-
import { spawnSync as
|
|
269577
|
+
import { spawnSync as spawnSync14 } from "node:child_process";
|
|
269397
269578
|
import { existsSync as existsSync100, readFileSync as readFileSync94, realpathSync as realpathSync14, renameSync as renameSync18, rmSync as rmSync17, writeFileSync as writeFileSync50 } from "node:fs";
|
|
269398
269579
|
import { homedir as homedir28 } from "node:os";
|
|
269399
269580
|
import { join as join104, resolve as resolve10 } from "node:path";
|
|
@@ -269442,13 +269623,13 @@ function loopInCycle2() {
|
|
|
269442
269623
|
function runLaunchctl(args) {
|
|
269443
269624
|
const readOnly = /* @__PURE__ */ new Set(["print", "print-disabled", "list", "version", "dumpstate", "examine"]);
|
|
269444
269625
|
if (args[0] !== void 0 && readOnly.has(args[0])) {
|
|
269445
|
-
return
|
|
269626
|
+
return spawnSync14("launchctl", args, { stdio: "inherit" }).status ?? 1;
|
|
269446
269627
|
}
|
|
269447
269628
|
const canonical = join104(homedir28(), "Library", "LaunchAgents");
|
|
269448
269629
|
const launchdDir = process.env["_LAUNCHD_DIR"] ?? canonical;
|
|
269449
269630
|
if (launchdDir !== canonical)
|
|
269450
269631
|
return 0;
|
|
269451
|
-
return
|
|
269632
|
+
return spawnSync14("launchctl", args, { stdio: "inherit" }).status ?? 1;
|
|
269452
269633
|
}
|
|
269453
269634
|
var SECTIONS = ["files_merged", "files_created", "dirs_created", "gitignore_entries_added", "launchd_plists_installed"];
|
|
269454
269635
|
function parseChangeset(text2) {
|
|
@@ -271991,7 +272172,7 @@ ${c("dim", "\u2192 Running the golden-path showcase (real models; its verdict do
|
|
|
271991
272172
|
// packages/cli/dist/commands/setup.js
|
|
271992
272173
|
init_dist();
|
|
271993
272174
|
init_render();
|
|
271994
|
-
import { spawnSync as
|
|
272175
|
+
import { spawnSync as spawnSync16 } from "node:child_process";
|
|
271995
272176
|
import { existsSync as existsSync107, lstatSync as lstatSync6, mkdirSync as mkdirSync52, readFileSync as readFileSync101, readdirSync as readdirSync42, readlinkSync as readlinkSync3, statSync as statSync36 } from "node:fs";
|
|
271996
272177
|
import { join as join111 } from "node:path";
|
|
271997
272178
|
function err13(line) {
|
|
@@ -272098,13 +272279,13 @@ function runSetupStep(watch, fn) {
|
|
|
272098
272279
|
return before === after ? "unchanged" : "changed";
|
|
272099
272280
|
}
|
|
272100
272281
|
function ensureHooksPath(repoPath) {
|
|
272101
|
-
const inRepo =
|
|
272282
|
+
const inRepo = spawnSync16("git", ["-C", repoPath, "rev-parse", "--git-dir"], { stdio: "ignore" }).status === 0;
|
|
272102
272283
|
if (!inRepo)
|
|
272103
272284
|
return;
|
|
272104
|
-
const cur =
|
|
272285
|
+
const cur = spawnSync16("git", ["-C", repoPath, "config", "core.hooksPath"], { encoding: "utf8" });
|
|
272105
272286
|
const current = cur.status === 0 ? (cur.stdout ?? "").trim() : "";
|
|
272106
272287
|
if (current === "" || current === ".git/hooks") {
|
|
272107
|
-
|
|
272288
|
+
spawnSync16("git", ["-C", repoPath, "config", "core.hooksPath", "hooks"], { stdio: "ignore" });
|
|
272108
272289
|
}
|
|
272109
272290
|
}
|
|
272110
272291
|
function peerEnsureStateDir() {
|
|
@@ -272127,7 +272308,7 @@ function submoduleGuard() {
|
|
|
272127
272308
|
empty = true;
|
|
272128
272309
|
}
|
|
272129
272310
|
if (hasGit && hasMods && empty) {
|
|
272130
|
-
|
|
272311
|
+
spawnSync16("git", ["submodule", "update", "--init", "--recursive", "--quiet"], {
|
|
272131
272312
|
cwd: pkg,
|
|
272132
272313
|
stdio: "ignore"
|
|
272133
272314
|
});
|
|
@@ -272308,8 +272489,8 @@ function setupCommand(args) {
|
|
|
272308
272489
|
init_showcase2();
|
|
272309
272490
|
|
|
272310
272491
|
// packages/cli/dist/commands/test.js
|
|
272311
|
-
import { spawnSync as
|
|
272312
|
-
import { appendFileSync as
|
|
272492
|
+
import { spawnSync as spawnSync17 } from "node:child_process";
|
|
272493
|
+
import { appendFileSync as appendFileSync20, existsSync as existsSync108, mkdirSync as mkdirSync53, readFileSync as readFileSync102, rmSync as rmSync19, writeFileSync as writeFileSync56 } from "node:fs";
|
|
272313
272494
|
import { dirname as dirname50, join as join112, resolve as resolve11 } from "node:path";
|
|
272314
272495
|
function pal7() {
|
|
272315
272496
|
const noColor2 = (process.env["NO_COLOR"] ?? "") !== "";
|
|
@@ -272367,7 +272548,7 @@ function appendRollTestEvidence(frame, cmd, argv, status2, stdout, stderr) {
|
|
|
272367
272548
|
try {
|
|
272368
272549
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
272369
272550
|
const command = [cmd, ...argv];
|
|
272370
|
-
|
|
272551
|
+
appendFileSync20(join112(frame.evidenceDir, "roll-test-output.log"), [
|
|
272371
272552
|
`===== roll test ${ts2} exit=${status2} =====`,
|
|
272372
272553
|
`$ ${command.join(" ")}`,
|
|
272373
272554
|
"--- stdout ---",
|
|
@@ -272376,7 +272557,7 @@ function appendRollTestEvidence(frame, cmd, argv, status2, stdout, stderr) {
|
|
|
272376
272557
|
stderr,
|
|
272377
272558
|
""
|
|
272378
272559
|
].join("\n"), "utf8");
|
|
272379
|
-
|
|
272560
|
+
appendFileSync20(join112(frame.evidenceDir, "roll-test-summary.txt"), JSON.stringify({
|
|
272380
272561
|
ts: ts2,
|
|
272381
272562
|
command,
|
|
272382
272563
|
exitCode: status2,
|
|
@@ -272456,7 +272637,7 @@ function resetReleaseLock() {
|
|
|
272456
272637
|
}
|
|
272457
272638
|
function runForward(cmd, argv) {
|
|
272458
272639
|
const frame = currentEvidenceFrame();
|
|
272459
|
-
const r =
|
|
272640
|
+
const r = spawnSync17(cmd, argv, { encoding: "utf8", env: childEnvForEvidence(frame) });
|
|
272460
272641
|
const stdout = typeof r.stdout === "string" ? r.stdout : "";
|
|
272461
272642
|
const stderr = typeof r.stderr === "string" ? r.stderr : "";
|
|
272462
272643
|
const status2 = r.status ?? 1;
|
|
@@ -272474,7 +272655,7 @@ function ensureSkillsSubmoduleReady() {
|
|
|
272474
272655
|
if (existsSync108(required2))
|
|
272475
272656
|
return true;
|
|
272476
272657
|
if (existsSync108(join112(pkg, ".git")) && existsSync108(join112(pkg, ".gitmodules"))) {
|
|
272477
|
-
|
|
272658
|
+
spawnSync17("git", ["submodule", "update", "--init", "--recursive", "--quiet", "skills"], {
|
|
272478
272659
|
cwd: pkg,
|
|
272479
272660
|
stdio: "ignore"
|
|
272480
272661
|
});
|
|
@@ -272980,7 +273161,7 @@ function tuneCommand(argv) {
|
|
|
272980
273161
|
|
|
272981
273162
|
// packages/cli/dist/commands/update.js
|
|
272982
273163
|
init_dist();
|
|
272983
|
-
import { spawnSync as
|
|
273164
|
+
import { spawnSync as spawnSync18 } from "node:child_process";
|
|
272984
273165
|
import { existsSync as existsSync111, mkdtempSync as mkdtempSync9, readFileSync as readFileSync105, rmSync as rmSync20 } from "node:fs";
|
|
272985
273166
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
272986
273167
|
import { join as join116 } from "node:path";
|
|
@@ -273021,7 +273202,7 @@ function m6(key, ...args) {
|
|
|
273021
273202
|
return t(v2Catalog, msgLang10(), key, ...args);
|
|
273022
273203
|
}
|
|
273023
273204
|
function runForward2(cmd, argv) {
|
|
273024
|
-
const r =
|
|
273205
|
+
const r = spawnSync18(cmd, argv, { encoding: "utf8" });
|
|
273025
273206
|
if (typeof r.stdout === "string" && r.stdout !== "")
|
|
273026
273207
|
process.stdout.write(r.stdout);
|
|
273027
273208
|
if (typeof r.stderr === "string" && r.stderr !== "")
|
|
@@ -273032,7 +273213,7 @@ function resolveRemoteVersion() {
|
|
|
273032
273213
|
const pinned = process.env["ROLL_VERSION"];
|
|
273033
273214
|
if (pinned !== void 0 && pinned !== "")
|
|
273034
273215
|
return pinned;
|
|
273035
|
-
const r =
|
|
273216
|
+
const r = spawnSync18("curl", ["-fsSL", "-H", "Accept: application/vnd.github+json", "https://api.github.com/repos/seanyao/roll/releases/latest"], { encoding: "utf8" });
|
|
273036
273217
|
let latest = "";
|
|
273037
273218
|
if (r.status === 0 && typeof r.stdout === "string") {
|
|
273038
273219
|
const mm = /"tag_name"\s*:\s*"([^"]*)"/.exec(r.stdout);
|
|
@@ -273057,7 +273238,7 @@ function downloadAndInstallCurl(tag) {
|
|
|
273057
273238
|
}
|
|
273058
273239
|
info5("[roll] Extracting ...");
|
|
273059
273240
|
const extractDir = join116(tmpDir, "extract");
|
|
273060
|
-
|
|
273241
|
+
spawnSync18("mkdir", ["-p", extractDir], { stdio: "ignore" });
|
|
273061
273242
|
const ex = runForward2("tar", [
|
|
273062
273243
|
"-xzf",
|
|
273063
273244
|
join116(tmpDir, "roll.tar.gz"),
|
|
@@ -273075,16 +273256,16 @@ function downloadAndInstallCurl(tag) {
|
|
|
273075
273256
|
}
|
|
273076
273257
|
}
|
|
273077
273258
|
function checkInstalledVersionOrRetry() {
|
|
273078
|
-
const expected = (
|
|
273079
|
-
const pkgRoot = (
|
|
273259
|
+
const expected = (spawnSync18("npm", ["view", "@seanyao/roll", "version"], { encoding: "utf8" }).stdout ?? "").trim();
|
|
273260
|
+
const pkgRoot = (spawnSync18("npm", ["root", "-g"], { encoding: "utf8" }).stdout ?? "").trim();
|
|
273080
273261
|
const installedTree = join116(pkgRoot, "@seanyao", "roll");
|
|
273081
273262
|
const installed = treeVersion(installedTree);
|
|
273082
273263
|
if (expected === "" || installed === "")
|
|
273083
273264
|
return;
|
|
273084
273265
|
if (installed !== expected) {
|
|
273085
273266
|
warn5(m6("update.version_mismatch", installed, expected));
|
|
273086
|
-
|
|
273087
|
-
|
|
273267
|
+
spawnSync18("npm", ["cache", "clean", "--force"], { stdio: "ignore" });
|
|
273268
|
+
spawnSync18("npm", ["install", "-g", "@seanyao/roll@latest"], { stdio: "ignore" });
|
|
273088
273269
|
const after = treeVersion(installedTree);
|
|
273089
273270
|
if (after !== "" && after !== expected)
|
|
273090
273271
|
warn5(m6("update.still_mismatch", after));
|
|
@@ -273294,7 +273475,7 @@ function registerAll() {
|
|
|
273294
273475
|
});
|
|
273295
273476
|
registerPorted("init", initCommand, { help: "Usage: roll init [--auto|--repair|--apply]\n Diagnose this project and route to scaffold, PRD design, existing-codebase onboard, repair, migration, or roll status.\n --auto: apply deterministic fresh-project scaffolding in non-interactive runs.\n --repair: repair partial Roll markers only.\n --apply: validate and apply a reviewed existing-codebase onboard plan.\n\u8BCA\u65AD\u9879\u76EE\u5E76\u8DEF\u7531\u5230\u9AA8\u67B6\u3001PRD \u8BBE\u8BA1\u3001\u5DF2\u6709\u4EE3\u7801\u5E93\u63A5\u5165\u3001\u4FEE\u590D\u3001\u8FC1\u79FB\u6216 roll status\u3002\n --apply\uFF1A\u6821\u9A8C\u5E76\u5E94\u7528\u5DF2\u5BA1\u9605\u7684\u5DF2\u6709\u4EE3\u7801\u5E93\u63A5\u5165\u8BA1\u5212\u3002" });
|
|
273296
273477
|
registerPorted("next", nextCommand, { help: NEXT_USAGE });
|
|
273297
|
-
registerPorted("design", designCommand, { help: 'Usage: roll design [--from-file <path> | "<requirement>"] [--agent <name>] [--verbose|--raw]\n Launch $roll-design interactively
|
|
273478
|
+
registerPorted("design", designCommand, { help: 'Usage: roll design [--from-file <path> | "<requirement>"] [--agent <name>] [--verbose|--raw]\n Launch $roll-design interactively with bounded live progress, card-created events, quiet heartbeats, and final handoff; --verbose streams lower-priority normalized activity; --raw streams raw child output live.\n\u4EA4\u4E92\u5F0F\u542F\u52A8 $roll-design\uFF1B\u9ED8\u8BA4\u5B9E\u65F6\u663E\u793A\u6709\u754C\u8FDB\u5C55\u3001\u5EFA\u5361\u4E8B\u4EF6\u3001\u9759\u9ED8\u5FC3\u8DF3\u548C\u6700\u7EC8\u4EA4\u4ED8\uFF1B--verbose \u663E\u793A\u66F4\u591A\u89C4\u8303\u5316\u6D3B\u52A8\uFF1B--raw \u5B9E\u65F6\u8F93\u51FA\u539F\u59CB\u6D41\u3002' });
|
|
273298
273479
|
registerPorted("offboard", removedTopLevel("offboard"));
|
|
273299
273480
|
registerPorted("setup", (args) => {
|
|
273300
273481
|
if (args[0] === "skills") {
|