@openclaw/lobster 2026.9.5 → 2026.9.6
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/node_modules/@clawdbot/lobster/README.md +20 -133
- package/node_modules/@clawdbot/lobster/VISION.md +15 -238
- package/node_modules/@clawdbot/lobster/bin/clawd.invoke.js +2 -21
- package/node_modules/@clawdbot/lobster/bin/invoke.js +19 -0
- package/node_modules/@clawdbot/lobster/bin/lobster.js +2 -21
- package/node_modules/@clawdbot/lobster/bin/openclaw.invoke.js +2 -24
- package/node_modules/@clawdbot/lobster/dist/src/cli.js +32 -48
- package/node_modules/@clawdbot/lobster/dist/src/cli.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/command_tokens.js +81 -0
- package/node_modules/@clawdbot/lobster/dist/src/command_tokens.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/dedupe.js +1 -12
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/dedupe.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/group_by.js +2 -14
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/group_by.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/llm_invoke.js +1 -337
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/llm_invoke.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/map.js +2 -13
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/map.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/sort.js +4 -21
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/sort.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/state.js +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/state.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/template.js +2 -13
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/template.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/workflows/workflows_run.js +0 -18
- package/node_modules/@clawdbot/lobster/dist/src/commands/workflows/workflows_run.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/core/llm_accounting.js +304 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/llm_accounting.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/value_path.js +11 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/value_path.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/parser.js +2 -67
- package/node_modules/@clawdbot/lobster/dist/src/parser.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/index.js +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/pr-monitor.js +5 -64
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/pr-monitor.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/read_pr.js +45 -0
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/read_pr.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/snapshot.js +45 -0
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/snapshot.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/stages/pr-view.js +9 -47
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/stages/pr-view.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/Lobster.js +18 -135
- package/node_modules/@clawdbot/lobster/dist/src/sdk/Lobster.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/index.js +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/approve.js +1 -2
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/approve.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/diff.js +2 -8
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/diff.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/exec.js +15 -81
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/exec.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/state.js +3 -9
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/state.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/runtime.js +0 -12
- package/node_modules/@clawdbot/lobster/dist/src/sdk/runtime.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/state_env.js +6 -0
- package/node_modules/@clawdbot/lobster/dist/src/sdk/state_env.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/state/atomic_file.js +192 -0
- package/node_modules/@clawdbot/lobster/dist/src/state/atomic_file.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/state/store.js +2 -188
- package/node_modules/@clawdbot/lobster/dist/src/state/store.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/workflows/dry_run.js +262 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/dry_run.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/expressions.js +345 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/expressions.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/file.js +21 -1036
- package/node_modules/@clawdbot/lobster/dist/src/workflows/file.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/workflows/github_pr_monitor.js +8 -77
- package/node_modules/@clawdbot/lobster/dist/src/workflows/github_pr_monitor.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/workflows/graph.js +1 -7
- package/node_modules/@clawdbot/lobster/dist/src/workflows/graph.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/workflows/load.js +347 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/load.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/types.js +2 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/types.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/values.js +93 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/values.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/cancellation.test.js +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/cancellation.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/cli_run_errors.test.js +53 -0
- package/node_modules/@clawdbot/lobster/dist/test/cli_run_errors.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/command_arguments.test.js +82 -0
- package/node_modules/@clawdbot/lobster/dist/test/command_arguments.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/cost_tracker.test.js +49 -19
- package/node_modules/@clawdbot/lobster/dist/test/cost_tracker.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/helpers/node_shell_fixture.js +17 -0
- package/node_modules/@clawdbot/lobster/dist/test/helpers/node_shell_fixture.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/llm_invoke.test.js +2 -0
- package/node_modules/@clawdbot/lobster/dist/test/llm_invoke.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/pipeline_resume_state.test.js +65 -0
- package/node_modules/@clawdbot/lobster/dist/test/pipeline_resume_state.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/process_output_limit.test.js +5 -3
- package/node_modules/@clawdbot/lobster/dist/test/process_output_limit.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/sdk_exec.test.js +72 -25
- package/node_modules/@clawdbot/lobster/dist/test/sdk_exec.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/workflow_graph.test.js +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/workflow_graph.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/package.json +6 -8
- package/package.json +5 -5
- package/node_modules/@clawdbot/lobster/dist/src/sdk/token.js +0 -9
- package/node_modules/@clawdbot/lobster/dist/src/sdk/token.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../src/commands/stdlib/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../src/commands/stdlib/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,gGAAgG;AAChG,+FAA+F;AAC/F,kGAAkG;AAClG,+FAA+F;AAC/F,2FAA2F;AAC3F,MAAM,WAAW,GAAG,IAAI,GAAG,EAA4C,CAAC;AACxE,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC,SAAS,aAAa,CAAC,QAAgB,EAAE,IAAY,EAAE,KAAc;IACpE,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3C,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,IAAI,WAAW,CAAC,IAAI,IAAI,qBAAqB;YAAE,MAAM;QACrD,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;AACF,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE;IACtD,MAAM,QAAQ,GAAG,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;QACvB,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAI,OAAO,EAAE,IAAI,KAAK,IAAI;gBAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACrE,OAAO,KAAK,CAAC;QACd,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YACnB,IAAI,GAAG,EAAE,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACxC,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC,CAAC;IAEF,IAAI,CAAC;QACJ,OAAO,MAAM,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QACnB,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QACpE,MAAM,GAAG,CAAC;IACX,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC9B,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE;QACL,WAAW,EAAE,sCAAsC;QACnD,UAAU,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACX,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;aACnE;YACD,QAAQ,EAAE,CAAC,GAAG,CAAC;SACf;QACD,WAAW,EAAE,CAAC,aAAa,CAAC;KAC5B;IACD,IAAI;QACH,OAAO,0IAA0I,CAAC;IACnJ,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAEtD,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAEnF,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;IACtC,CAAC;CACD,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC9B,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE;QACL,WAAW,EAAE,qCAAqC;QAClD,UAAU,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACX,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;aACnE;YACD,QAAQ,EAAE,CAAC,GAAG,CAAC;SACf;QACD,WAAW,EAAE,CAAC,cAAc,CAAC;KAC7B;IACD,IAAI;QACH,OAAO,uKAAuK,CAAC;IAChL,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAEtD,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEjD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAEpD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;QACnD,MAAM,cAAc,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,MAAM,QAAQ,GAAG,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QAC1D,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAErC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;IACtC,CAAC;CACD,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,MAAM,IAAI,CAAC;AACtC,CAAC"}
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
+
import { getByPath } from "../../core/value_path.js";
|
|
1
2
|
import fs from "node:fs/promises";
|
|
2
3
|
import { applyFilters } from "../../core/filters.js";
|
|
3
|
-
function getByPath(obj, path) {
|
|
4
|
-
if (path === "." || path === "this")
|
|
5
|
-
return obj;
|
|
6
|
-
const parts = path.split(".").filter(Boolean);
|
|
7
|
-
let cur = obj;
|
|
8
|
-
for (const p of parts) {
|
|
9
|
-
if (cur == null)
|
|
10
|
-
return undefined;
|
|
11
|
-
cur = cur[p];
|
|
12
|
-
}
|
|
13
|
-
return cur;
|
|
14
|
-
}
|
|
15
4
|
function splitFilterChain(expr) {
|
|
16
5
|
const parts = [];
|
|
17
6
|
let current = "";
|
|
@@ -55,7 +44,7 @@ function renderTemplate(tpl, ctx) {
|
|
|
55
44
|
const rawExpr = String(expr ?? "").trim();
|
|
56
45
|
const parts = splitFilterChain(rawExpr);
|
|
57
46
|
const key = parts[0];
|
|
58
|
-
let val = getByPath(ctx, key);
|
|
47
|
+
let val = key === "." || key === "this" ? ctx : getByPath(ctx, key);
|
|
59
48
|
if (parts.length > 1) {
|
|
60
49
|
val = applyFilters(val, parts.slice(1));
|
|
61
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/commands/stdlib/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/commands/stdlib/template.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,8 +4,6 @@ const runners = {
|
|
|
4
4
|
"github.pr.monitor": runGithubPrMonitorWorkflow,
|
|
5
5
|
"github.pr.monitor.notify": runGithubPrMonitorNotifyWorkflow,
|
|
6
6
|
};
|
|
7
|
-
// Recipe runners - adapt SDK recipes to workflow runner interface
|
|
8
|
-
const recipeRunners = {};
|
|
9
7
|
export const workflowsRunCommand = {
|
|
10
8
|
name: "workflows.run",
|
|
11
9
|
meta: {
|
|
@@ -32,22 +30,6 @@ export const workflowsRunCommand = {
|
|
|
32
30
|
const name = args.name ?? args._[0];
|
|
33
31
|
if (!name)
|
|
34
32
|
throw new Error("workflows.run requires --name");
|
|
35
|
-
// Check for recipe-based workflow first
|
|
36
|
-
const recipeRunner = recipeRunners[name];
|
|
37
|
-
if (recipeRunner) {
|
|
38
|
-
let workflowArgs = {};
|
|
39
|
-
if (args["args-json"]) {
|
|
40
|
-
try {
|
|
41
|
-
workflowArgs = JSON.parse(String(args["args-json"]));
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
throw new Error("workflows.run --args-json must be valid JSON");
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const result = await recipeRunner({ args: workflowArgs, ctx });
|
|
48
|
-
return { output: asStream([result]) };
|
|
49
|
-
}
|
|
50
|
-
// Fall back to legacy workflow registry
|
|
51
33
|
const meta = workflowRegistry[name];
|
|
52
34
|
if (!meta)
|
|
53
35
|
throw new Error(`Unknown workflow: ${name}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflows_run.js","sourceRoot":"","sources":["../../../../src/commands/workflows/workflows_run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EACN,0BAA0B,EAC1B,gCAAgC,GAChC,MAAM,sCAAsC,CAAC;AAE9C,MAAM,OAAO,GAAG;IACf,mBAAmB,EAAE,0BAA0B;IAC/C,0BAA0B,EAAE,gCAAgC;CAC5D,CAAC;AAEF,
|
|
1
|
+
{"version":3,"file":"workflows_run.js","sourceRoot":"","sources":["../../../../src/commands/workflows/workflows_run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EACN,0BAA0B,EAC1B,gCAAgC,GAChC,MAAM,sCAAsC,CAAC;AAE9C,MAAM,OAAO,GAAG;IACf,mBAAmB,EAAE,0BAA0B;IAC/C,0BAA0B,EAAE,gCAAgC;CAC5D,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IAClC,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE;QACL,WAAW,EAAE,8BAA8B;QAC3C,UAAU,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACX,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE;gBACtD,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;gBAC5E,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;aAC/C;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SAClB;QACD,WAAW,EAAE,EAAE;KACf;IACD,IAAI;QACH,OAAO,qOAAqO,CAAC;IAC9O,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE;QAC7B,eAAe;QACf,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;YACjC,QAAQ;QACT,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAE5D,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC;QAEzE,IAAI,YAAY,GAAG,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC;gBACJ,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YACtD,CAAC;YAAC,MAAM,CAAC;gBACR,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YACjE,CAAC;QACF,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;QACzD,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IACvC,CAAC;CACD,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,MAAM,IAAI,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { billableTokens } from "./cost_tracker.js";
|
|
2
|
+
// Only in-process objects carry this symbol. JSON fields cannot grant a replay exemption.
|
|
3
|
+
const LLM_PROVENANCE = Symbol("lobster.llm.provenance");
|
|
4
|
+
// Object spreads share this private identity; WeakSet tracking also works for frozen items.
|
|
5
|
+
const replayedCalls = new WeakSet();
|
|
6
|
+
/**
|
|
7
|
+
* Stamps provenance on a value this module is emitting. The property is enumerable so a
|
|
8
|
+
* downstream `{ ...value }` keeps it, and `JSON.stringify` ignores symbol keys, so serialized
|
|
9
|
+
* output — including what is written to the cache — is unchanged.
|
|
10
|
+
*/
|
|
11
|
+
function markProvenance(value, provenance) {
|
|
12
|
+
return Object.defineProperty(value, LLM_PROVENANCE, {
|
|
13
|
+
value: provenance,
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/** Mark both the item and usage so projections such as `pick model,usage` preserve provenance. */
|
|
19
|
+
export function markLlmItem(item, provenance) {
|
|
20
|
+
if (item.usage && typeof item.usage === "object") {
|
|
21
|
+
markProvenance(item.usage, provenance);
|
|
22
|
+
}
|
|
23
|
+
return markProvenance(item, provenance);
|
|
24
|
+
}
|
|
25
|
+
/** Public cache keys and `replayed` fields are not trusted as billing provenance. */
|
|
26
|
+
export function llmProvenanceOf(value) {
|
|
27
|
+
if (!value || typeof value !== "object")
|
|
28
|
+
return null;
|
|
29
|
+
const provenance = value[LLM_PROVENANCE];
|
|
30
|
+
if (!provenance || typeof provenance !== "object")
|
|
31
|
+
return null;
|
|
32
|
+
const { cacheKey, replayed } = provenance;
|
|
33
|
+
if (typeof cacheKey !== "string" || typeof replayed !== "boolean")
|
|
34
|
+
return null;
|
|
35
|
+
return { cacheKey, replayed: replayed || replayedCalls.has(provenance) };
|
|
36
|
+
}
|
|
37
|
+
/** A billed live result becomes a replay wherever that same call identity is re-emitted. */
|
|
38
|
+
export function markLlmProvenanceReplayed(value) {
|
|
39
|
+
if (!llmProvenanceOf(value))
|
|
40
|
+
return;
|
|
41
|
+
replayedCalls.add(value[LLM_PROVENANCE]);
|
|
42
|
+
}
|
|
43
|
+
/** Carry provenance only across a JSON round trip whose source is still held in-process. */
|
|
44
|
+
export function carryLlmProvenance(source, target) {
|
|
45
|
+
if (!source || typeof source !== "object" || !target || typeof target !== "object")
|
|
46
|
+
return;
|
|
47
|
+
const provenance = llmProvenanceOf(source);
|
|
48
|
+
if (provenance)
|
|
49
|
+
markProvenance(target, { cacheKey: provenance.cacheKey, replayed: true });
|
|
50
|
+
if (Array.isArray(source) || Array.isArray(target)) {
|
|
51
|
+
if (!Array.isArray(source) || !Array.isArray(target))
|
|
52
|
+
return;
|
|
53
|
+
for (let index = 0; index < Math.min(source.length, target.length); index++) {
|
|
54
|
+
carryLlmProvenance(source[index], target[index]);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
for (const key of Object.keys(source)) {
|
|
59
|
+
carryLlmProvenance(source[key], target[key]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Restores private replay provenance on completed step results loaded from Lobster's own
|
|
64
|
+
* workflow-resume state. Resume state is the narrow trusted boundary: ordinary command JSON
|
|
65
|
+
* never reaches this helper, so copying a public cache key cannot suppress its usage record.
|
|
66
|
+
*/
|
|
67
|
+
export function restoreLlmProvenance(target, charges) {
|
|
68
|
+
if (!target || typeof target !== "object" || !Array.isArray(charges))
|
|
69
|
+
return;
|
|
70
|
+
const settled = charges.filter((charge) => charge &&
|
|
71
|
+
typeof charge === "object" &&
|
|
72
|
+
typeof charge.cacheKey === "string" &&
|
|
73
|
+
charge.cacheKey &&
|
|
74
|
+
charge.usage &&
|
|
75
|
+
typeof charge.usage === "object");
|
|
76
|
+
if (!settled.length)
|
|
77
|
+
return;
|
|
78
|
+
const visit = (value) => {
|
|
79
|
+
if (!value || typeof value !== "object")
|
|
80
|
+
return;
|
|
81
|
+
if (Array.isArray(value)) {
|
|
82
|
+
for (const item of value)
|
|
83
|
+
visit(item);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const record = value;
|
|
87
|
+
const cacheKey = typeof record.cacheKey === "string" ? record.cacheKey : null;
|
|
88
|
+
const model = typeof record.model === "string" ? record.model : null;
|
|
89
|
+
const usage = record.usage;
|
|
90
|
+
if (cacheKey && usage && typeof usage === "object") {
|
|
91
|
+
const matches = settled.some((charge) => charge.cacheKey === cacheKey &&
|
|
92
|
+
(charge.model ?? null) === model &&
|
|
93
|
+
sameBillableUsage(charge.usage, usage));
|
|
94
|
+
if (matches) {
|
|
95
|
+
const provenance = { cacheKey, replayed: true };
|
|
96
|
+
markProvenance(usage, provenance);
|
|
97
|
+
markProvenance(record, provenance);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const child of Object.values(record))
|
|
101
|
+
visit(child);
|
|
102
|
+
};
|
|
103
|
+
visit(target);
|
|
104
|
+
}
|
|
105
|
+
// A call nothing ever bills — a step that failed outright — leaves its key behind, so the
|
|
106
|
+
// oldest are dropped to keep a long run's ledger bounded.
|
|
107
|
+
const MAX_UNBILLED_LIVE_INVOCATIONS = 256;
|
|
108
|
+
/** Each run settles its own charges once; composed runs also record charges in their parent. */
|
|
109
|
+
export function createLlmSpendLedger(parent) {
|
|
110
|
+
// Outstanding charges per cache key, held one entry per call rather than as a count: two
|
|
111
|
+
// identical calls that race on a cold cache are two provider charges under one key, the
|
|
112
|
+
// replays that later stand in for them have to be able to settle both, and each carries the
|
|
113
|
+
// cost of the call that opened it.
|
|
114
|
+
const unbilled = new Map();
|
|
115
|
+
// Charges this run has already accounted for. A copy of an item that lost its mark can turn
|
|
116
|
+
// up in any later step, and the only way to tell it from a call nobody has billed yet is to
|
|
117
|
+
// remember what has been billed. Bounded like the open charges, oldest key first.
|
|
118
|
+
const billed = new Map();
|
|
119
|
+
function settle(cacheKey, charge) {
|
|
120
|
+
const seen = billed.get(cacheKey) ?? [];
|
|
121
|
+
seen.push(charge ?? {});
|
|
122
|
+
billed.set(cacheKey, seen);
|
|
123
|
+
for (const oldest of billed.keys()) {
|
|
124
|
+
if (billed.size <= MAX_UNBILLED_LIVE_INVOCATIONS)
|
|
125
|
+
break;
|
|
126
|
+
billed.delete(oldest);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
record(cacheKey, charge) {
|
|
131
|
+
if (!cacheKey)
|
|
132
|
+
return;
|
|
133
|
+
parent?.record(cacheKey, charge);
|
|
134
|
+
const open = unbilled.get(cacheKey) ?? [];
|
|
135
|
+
open.push({ ...charge });
|
|
136
|
+
unbilled.set(cacheKey, open);
|
|
137
|
+
for (const oldest of unbilled.keys()) {
|
|
138
|
+
if (unbilled.size <= MAX_UNBILLED_LIVE_INVOCATIONS)
|
|
139
|
+
break;
|
|
140
|
+
unbilled.delete(oldest);
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
/**
|
|
144
|
+
* Settles one outstanding charge and hands back what that call cost, or null for the
|
|
145
|
+
* caller that must not bill anything. A live item and every replay of it draw on the same
|
|
146
|
+
* charges, so a provider call is billed exactly once however many steps re-emit its
|
|
147
|
+
* answer — and N calls under one key can be billed N times, never fewer.
|
|
148
|
+
*
|
|
149
|
+
* The cost comes back because a replay is not a reliable witness of it: identical calls
|
|
150
|
+
* that raced on a cold cache each paid their own way, and every replay of them carries
|
|
151
|
+
* whichever single answer was stored.
|
|
152
|
+
*/
|
|
153
|
+
claim(cacheKey, cost) {
|
|
154
|
+
const open = unbilled.get(cacheKey);
|
|
155
|
+
if (!open?.length)
|
|
156
|
+
return null;
|
|
157
|
+
// A caller that knows what its own call cost settles that call's charge. A step
|
|
158
|
+
// retried after an attempt that failed *after* paying has more than one charge under
|
|
159
|
+
// the key, and they did not cost the same: settling the wrong one leaves the other to
|
|
160
|
+
// be billed at this call's price instead of its own.
|
|
161
|
+
const own = cost
|
|
162
|
+
? open.findIndex((charge) => (charge.model ?? null) === (cost.model ?? null) &&
|
|
163
|
+
sameBillableUsage(charge.usage, cost.usage))
|
|
164
|
+
: -1;
|
|
165
|
+
// Otherwise: a charge that records no cost settles nothing anyone can bill, so it
|
|
166
|
+
// must not be the one handed to a caller with a real call to account for. Charges
|
|
167
|
+
// restored from resume state written before they carried a cost are the ones this
|
|
168
|
+
// can be.
|
|
169
|
+
const index = own >= 0
|
|
170
|
+
? own
|
|
171
|
+
: Math.max(open.findIndex((charge) => charge.usage !== undefined), 0);
|
|
172
|
+
const [charge] = open.splice(index, 1);
|
|
173
|
+
if (!open.length)
|
|
174
|
+
unbilled.delete(cacheKey);
|
|
175
|
+
settle(cacheKey, charge);
|
|
176
|
+
return charge ?? {};
|
|
177
|
+
},
|
|
178
|
+
/**
|
|
179
|
+
* Whether an item carrying a call's numbers but not its in-process mark should be billed.
|
|
180
|
+
* A matching open charge is settled so the same provider call is not recorded again by
|
|
181
|
+
* end-of-step cleanup. Once no charge is open, however, public fields can never suppress
|
|
182
|
+
* usage: only the private provenance symbol can prove an item is a replay.
|
|
183
|
+
*/
|
|
184
|
+
billCopy(cacheKey, model, usage) {
|
|
185
|
+
const isSameCall = (charge) => (charge.model ?? null) === model && sameBillableUsage(charge.usage, usage);
|
|
186
|
+
// A copy that still names a cache key is read against that key alone: the key is
|
|
187
|
+
// evidence of which call it came from, and honoring it keeps one call's copy from
|
|
188
|
+
// settling another call's charge. A transform can emit `{ model, usage }` and drop
|
|
189
|
+
// the key with the symbols, leaving the cost as the only evidence there is.
|
|
190
|
+
for (const key of cacheKey === null ? [...unbilled.keys()] : [cacheKey]) {
|
|
191
|
+
const open = unbilled.get(key);
|
|
192
|
+
const index = open?.findIndex(isSameCall) ?? -1;
|
|
193
|
+
if (!open || index < 0)
|
|
194
|
+
continue;
|
|
195
|
+
settle(key, open.splice(index, 1)[0]);
|
|
196
|
+
if (!open.length)
|
|
197
|
+
unbilled.delete(key);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
return true;
|
|
201
|
+
},
|
|
202
|
+
outstanding() {
|
|
203
|
+
const charges = [];
|
|
204
|
+
for (const [cacheKey, open] of unbilled) {
|
|
205
|
+
for (const charge of open)
|
|
206
|
+
charges.push({ cacheKey, count: 1, ...charge });
|
|
207
|
+
}
|
|
208
|
+
return charges;
|
|
209
|
+
},
|
|
210
|
+
/**
|
|
211
|
+
* Reopens charges a paused run had not billed. A pipeline can suspend mid-step — at an
|
|
212
|
+
* `ask` gate — after its LLM call has been paid for but before the step succeeded, so
|
|
213
|
+
* without this the charge would exist in no run: the paused one never billed it, and the
|
|
214
|
+
* resumed one would exempt the replay that stands in for it.
|
|
215
|
+
*/
|
|
216
|
+
restore(charges) {
|
|
217
|
+
if (!Array.isArray(charges))
|
|
218
|
+
return;
|
|
219
|
+
for (const charge of charges) {
|
|
220
|
+
if (!charge || typeof charge !== "object")
|
|
221
|
+
continue;
|
|
222
|
+
if (typeof charge.cacheKey !== "string" || !charge.cacheKey)
|
|
223
|
+
continue;
|
|
224
|
+
const count = Math.floor(Number(charge.count ?? 0));
|
|
225
|
+
if (!Number.isFinite(count) || count < 1)
|
|
226
|
+
continue;
|
|
227
|
+
// State written before this field existed carries no cost, and a hand-edited file
|
|
228
|
+
// should not be able to invent one: only a plain object of numbers is taken.
|
|
229
|
+
const { cacheKey, count: _count, ...cost } = charge;
|
|
230
|
+
const restored = sanitizeChargeCost(cost);
|
|
231
|
+
for (let i = 0; i < count; i++)
|
|
232
|
+
this.record(cacheKey, restored);
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
/**
|
|
236
|
+
* The calls this run has already billed. A run that pauses carries this the way it carries
|
|
237
|
+
* what it spent: the total says how much, and this says which calls it was for.
|
|
238
|
+
*/
|
|
239
|
+
settled() {
|
|
240
|
+
const charges = [];
|
|
241
|
+
for (const [cacheKey, seen] of billed) {
|
|
242
|
+
for (const charge of seen)
|
|
243
|
+
charges.push({ cacheKey, count: 1, ...charge });
|
|
244
|
+
}
|
|
245
|
+
return charges;
|
|
246
|
+
},
|
|
247
|
+
/**
|
|
248
|
+
* Restores what a paused run had billed, so the two halves of its accounting agree after
|
|
249
|
+
* the pause. `cost` brings the money back; without this the run that resumes has no record
|
|
250
|
+
* of what the money was for, and a later step that re-emits a completed LLM output — `head`
|
|
251
|
+
* over `$live.json` — hands on a copy the fresh ledger has never heard of. It is billed on
|
|
252
|
+
* top of the restored total: one provider call, twice in `_meta.cost` and against
|
|
253
|
+
* `cost_limit`.
|
|
254
|
+
*
|
|
255
|
+
* A settled charge is only ever read against a cache key, so what this restores can excuse
|
|
256
|
+
* a copy of a named call and nothing else. It cannot touch a live call — those settle out
|
|
257
|
+
* of the open charges — and the spend it is reconstructing is already in the `cost` this
|
|
258
|
+
* same state carries.
|
|
259
|
+
*/
|
|
260
|
+
restoreSettled(charges) {
|
|
261
|
+
if (!Array.isArray(charges))
|
|
262
|
+
return;
|
|
263
|
+
for (const charge of charges) {
|
|
264
|
+
if (!charge || typeof charge !== "object")
|
|
265
|
+
continue;
|
|
266
|
+
if (typeof charge.cacheKey !== "string" || !charge.cacheKey)
|
|
267
|
+
continue;
|
|
268
|
+
const count = Math.floor(Number(charge.count ?? 0));
|
|
269
|
+
if (!Number.isFinite(count) || count < 1)
|
|
270
|
+
continue;
|
|
271
|
+
const { cacheKey, count: _count, ...cost } = charge;
|
|
272
|
+
const restored = sanitizeChargeCost(cost);
|
|
273
|
+
for (let i = 0; i < count; i++)
|
|
274
|
+
settle(cacheKey, restored);
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/** Compare billable token counts, ignoring provenance and unbilled response metadata. */
|
|
280
|
+
function sameBillableUsage(left, right) {
|
|
281
|
+
if (!left || typeof left !== "object" || !right || typeof right !== "object")
|
|
282
|
+
return false;
|
|
283
|
+
const billed = billableTokens(left);
|
|
284
|
+
const other = billableTokens(right);
|
|
285
|
+
return billed.inputTokens === other.inputTokens && billed.outputTokens === other.outputTokens;
|
|
286
|
+
}
|
|
287
|
+
function sanitizeChargeCost(cost) {
|
|
288
|
+
const usage = cost.usage;
|
|
289
|
+
if (!usage || typeof usage !== "object" || Array.isArray(usage))
|
|
290
|
+
return {};
|
|
291
|
+
const numbers = {};
|
|
292
|
+
for (const [key, value] of Object.entries(usage)) {
|
|
293
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
294
|
+
numbers[key] = value;
|
|
295
|
+
}
|
|
296
|
+
if (!Object.keys(numbers).length)
|
|
297
|
+
return {};
|
|
298
|
+
return {
|
|
299
|
+
...(typeof cost.stepId === "string" ? { stepId: cost.stepId } : null),
|
|
300
|
+
model: typeof cost.model === "string" ? cost.model : null,
|
|
301
|
+
usage: numbers,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=llm_accounting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm_accounting.js","sourceRoot":"","sources":["../../../src/core/llm_accounting.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Resolve command dot paths, ignoring empty segments and stopping at nullish values. */
|
|
2
|
+
export function getByPath(value, path) {
|
|
3
|
+
let current = value;
|
|
4
|
+
for (const field of path.split(".").filter(Boolean)) {
|
|
5
|
+
if (current == null)
|
|
6
|
+
return undefined;
|
|
7
|
+
current = current[field];
|
|
8
|
+
}
|
|
9
|
+
return current;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=value_path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value_path.js","sourceRoot":"","sources":["../../../src/core/value_path.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,IAAY;IACrD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,SAAS,CAAC;QACtC,OAAO,GAAI,OAAmC,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
return ch === " " || ch === "\t" || ch === "\n" || ch === "\r";
|
|
3
|
-
}
|
|
1
|
+
import { tokenizeCommand } from "./command_tokens.js";
|
|
4
2
|
function splitPipes(input) {
|
|
5
3
|
const parts = [];
|
|
6
4
|
let current = "";
|
|
@@ -40,69 +38,6 @@ function splitPipes(input) {
|
|
|
40
38
|
parts.push(current.trim());
|
|
41
39
|
return parts;
|
|
42
40
|
}
|
|
43
|
-
function tokenizeCommand(input) {
|
|
44
|
-
const tokens = [];
|
|
45
|
-
let current = "";
|
|
46
|
-
let quote = null;
|
|
47
|
-
const push = () => {
|
|
48
|
-
if (current.length > 0)
|
|
49
|
-
tokens.push(current);
|
|
50
|
-
current = "";
|
|
51
|
-
};
|
|
52
|
-
for (let i = 0; i < input.length; i++) {
|
|
53
|
-
const ch = input[i];
|
|
54
|
-
if (quote) {
|
|
55
|
-
if (quote === "'") {
|
|
56
|
-
if (ch === "\\" && input[i + 1] === quote) {
|
|
57
|
-
current += quote;
|
|
58
|
-
i++;
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (ch === quote) {
|
|
62
|
-
quote = null;
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
current += ch;
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
// Double-quoted mode: preserve unknown escapes (\n, \t, etc) while
|
|
69
|
-
// unescaping only shell-like quote/backslash escapes.
|
|
70
|
-
if (ch === "\\") {
|
|
71
|
-
const next = input[i + 1];
|
|
72
|
-
if (next === '"' || next === "\\" || next === "$" || next === "`") {
|
|
73
|
-
current += next;
|
|
74
|
-
i++;
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
if (next === "\n") {
|
|
78
|
-
i++;
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
current += ch;
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
if (ch === quote) {
|
|
85
|
-
quote = null;
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
current += ch;
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
if (ch === '"' || ch === "'") {
|
|
92
|
-
quote = ch;
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (isWhitespace(ch)) {
|
|
96
|
-
push();
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
current += ch;
|
|
100
|
-
}
|
|
101
|
-
if (quote)
|
|
102
|
-
throw new Error("Unclosed quote");
|
|
103
|
-
push();
|
|
104
|
-
return tokens;
|
|
105
|
-
}
|
|
106
41
|
function parseArgs(tokens, booleanFlags = []) {
|
|
107
42
|
const args = { _: [] };
|
|
108
43
|
for (let i = 0; i < tokens.length; i++) {
|
|
@@ -117,7 +52,7 @@ function parseArgs(tokens, booleanFlags = []) {
|
|
|
117
52
|
}
|
|
118
53
|
const key = tok.slice(2);
|
|
119
54
|
const next = tokens[i + 1];
|
|
120
|
-
if (booleanFlags.includes(key) ||
|
|
55
|
+
if (booleanFlags.includes(key) || next === undefined || next.startsWith("--")) {
|
|
121
56
|
args[key] = true;
|
|
122
57
|
continue;
|
|
123
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* GitHub Recipes
|
|
3
3
|
*
|
|
4
4
|
* @example
|
|
5
|
-
* import { prMonitor, prMonitorNotify } from 'lobster/recipes/github';
|
|
5
|
+
* import { prMonitor, prMonitorNotify } from '@clawdbot/lobster/recipes/github';
|
|
6
6
|
*
|
|
7
7
|
* const result = await prMonitor({ repo: 'owner/repo', pr: 123 }).run();
|
|
8
8
|
*/
|