@open-tomato/rafa 0.9.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/SKILL.md +21 -0
- package/dist/cli.js +1987 -1018
- package/dist/effort/store/index.js +1 -1
- package/dist/{index-eqsm86n7.js → index-srdtw7w1.js} +68 -2
- package/dist/index.js +794 -48
- package/dist/plan-prompt.md +4 -0
- package/package.json +1 -1
|
@@ -840,6 +840,33 @@ function parseSpecReview(output) {
|
|
|
840
840
|
return judged(verdict, readGaps(document, issues), block, issues);
|
|
841
841
|
}
|
|
842
842
|
|
|
843
|
+
// src/cli/command.ts
|
|
844
|
+
var MAX_EXIT_CODE = 255;
|
|
845
|
+
|
|
846
|
+
class CommandExit extends Error {
|
|
847
|
+
exitCode;
|
|
848
|
+
constructor(exitCode, message = "") {
|
|
849
|
+
super(message);
|
|
850
|
+
if (!Number.isInteger(exitCode) || exitCode < 0 || exitCode > MAX_EXIT_CODE) {
|
|
851
|
+
throw new TypeError(`CommandExit: exit code is ${describeValue(exitCode)}, expected a whole number from 0 to ${MAX_EXIT_CODE}`);
|
|
852
|
+
}
|
|
853
|
+
this.name = "CommandExit";
|
|
854
|
+
this.exitCode = exitCode;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
function isTopLevel(command) {
|
|
858
|
+
return command.subject === command.action;
|
|
859
|
+
}
|
|
860
|
+
function commandSpelling(command) {
|
|
861
|
+
return isTopLevel(command) ? command.subject : `${command.subject} ${command.action}`;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// src/cli/running.ts
|
|
865
|
+
var running = null;
|
|
866
|
+
function runningCommand() {
|
|
867
|
+
return running;
|
|
868
|
+
}
|
|
869
|
+
|
|
843
870
|
// src/utils/claude.ts
|
|
844
871
|
async function getClaudeUsagePercent() {
|
|
845
872
|
const envPct = process.env["CLAUDE_USAGE_PERCENT"];
|
|
@@ -891,9 +918,44 @@ function claudeSessionEnv() {
|
|
|
891
918
|
CLAUDE_CODE_ENTRYPOINT: "cli"
|
|
892
919
|
};
|
|
893
920
|
}
|
|
921
|
+
|
|
922
|
+
class UndeclaredSpendError extends Error {
|
|
923
|
+
name = "UndeclaredSpendError";
|
|
924
|
+
}
|
|
925
|
+
function carriesFlag(flags, flag) {
|
|
926
|
+
const name = flag.replace(/^--/, "");
|
|
927
|
+
const value = flags[name];
|
|
928
|
+
if (value !== undefined && value !== false)
|
|
929
|
+
return true;
|
|
930
|
+
return name.startsWith("no-") && flags[name.slice(3)] === false;
|
|
931
|
+
}
|
|
932
|
+
function spendRefusal(running2) {
|
|
933
|
+
if (running2 === null)
|
|
934
|
+
return null;
|
|
935
|
+
const { command, flags } = running2;
|
|
936
|
+
const spend = command.spends;
|
|
937
|
+
const named = `rafa ${commandSpelling(command)}`;
|
|
938
|
+
const remedy = "declare spends on the command to cover this run";
|
|
939
|
+
if (spend === undefined) {
|
|
940
|
+
return `${named} started a Claude session but declares no spends: ${remedy}`;
|
|
941
|
+
}
|
|
942
|
+
if (spend.when === "with" && !carriesFlag(flags, spend.flag)) {
|
|
943
|
+
return `${named} started a Claude session without ${spend.flag}, and its spends covers only a run with ${spend.flag}: ${remedy}`;
|
|
944
|
+
}
|
|
945
|
+
if (spend.when === "unless" && carriesFlag(flags, spend.flag)) {
|
|
946
|
+
return `${named} started a Claude session with ${spend.flag}, and its spends covers no run with ${spend.flag}: ${remedy}`;
|
|
947
|
+
}
|
|
948
|
+
return null;
|
|
949
|
+
}
|
|
950
|
+
function guardSpend() {
|
|
951
|
+
const refusal = spendRefusal(runningCommand());
|
|
952
|
+
if (refusal !== null)
|
|
953
|
+
throw new UndeclaredSpendError(refusal);
|
|
954
|
+
}
|
|
894
955
|
async function spawnClaude(args, prompt) {
|
|
956
|
+
guardSpend();
|
|
895
957
|
if (activeOutputMode() === "json") {
|
|
896
|
-
const { exitCode } = await
|
|
958
|
+
const { exitCode } = await spawnCaptured(args, prompt);
|
|
897
959
|
return exitCode;
|
|
898
960
|
}
|
|
899
961
|
const proc = Bun.spawn([CLAUDE_BIN, ...args], {
|
|
@@ -945,6 +1007,10 @@ async function teeToOperator(stream) {
|
|
|
945
1007
|
return text + tail;
|
|
946
1008
|
}
|
|
947
1009
|
async function spawnClaudeCaptured(args, prompt) {
|
|
1010
|
+
guardSpend();
|
|
1011
|
+
return spawnCaptured(args, prompt);
|
|
1012
|
+
}
|
|
1013
|
+
async function spawnCaptured(args, prompt) {
|
|
948
1014
|
const proc = Bun.spawn([CLAUDE_BIN, ...args], {
|
|
949
1015
|
stdin: new TextEncoder().encode(prompt),
|
|
950
1016
|
stdout: "pipe",
|
|
@@ -1771,4 +1837,4 @@ function selectEffortStore(repoRoot, config) {
|
|
|
1771
1837
|
return adapter.create({ repoRoot });
|
|
1772
1838
|
}
|
|
1773
1839
|
|
|
1774
|
-
export { EFFORT_KEY_PROJECTIONS, openNdjsonStore, sqliteStorePath, LONE_SURROGATE, withSqliteStore, writeSqliteStore, openSqliteStore, getClaudeUsagePercent, checkUsage, interruptClaudeSessions, runClaude, runClaudeCaptured, planFilePath, ClaudePlannerError, createGhRunner, createLocalTracker, PORT_VERSIONS, createAdapterRegistry, CORE_ADAPTER_REGISTRY, selectEffortStore };
|
|
1840
|
+
export { EFFORT_KEY_PROJECTIONS, openNdjsonStore, sqliteStorePath, LONE_SURROGATE, withSqliteStore, writeSqliteStore, openSqliteStore, CommandExit, commandSpelling, getClaudeUsagePercent, checkUsage, interruptClaudeSessions, runClaude, runClaudeCaptured, planFilePath, ClaudePlannerError, createGhRunner, createLocalTracker, PORT_VERSIONS, createAdapterRegistry, CORE_ADAPTER_REGISTRY, selectEffortStore };
|