poe-code 4.0.37 → 4.0.39
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/dist/cli/commands/gaslight.js +58 -1
- package/dist/cli/commands/gaslight.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +180 -19
- package/dist/index.js.map +4 -4
- package/dist/metafile.json +1 -1
- package/dist/providers/poe-agent.js.map +1 -1
- package/dist/sdk/gaslight.d.ts +6 -2
- package/dist/sdk/gaslight.js +7 -1
- package/dist/sdk/gaslight.js.map +1 -1
- package/package.json +1 -1
- package/packages/agent-gaslight/dist/daemon.d.ts +26 -0
- package/packages/agent-gaslight/dist/daemon.js +65 -0
- package/packages/agent-gaslight/dist/index.d.ts +2 -0
- package/packages/agent-gaslight/dist/index.js +1 -0
- package/packages/plan-browser/dist/explorer-config.js +30 -2
- package/packages/toolcraft-design/dist/explorer/reducer.js +3 -2
package/dist/sdk/gaslight.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { type GaslightOptions as WorkspaceGaslightOptions, type GaslightResult } from "../../packages/agent-gaslight/dist/index.js";
|
|
1
|
+
import { type GaslightDaemonOptions as WorkspaceGaslightDaemonOptions, type GaslightDaemonResult, type GaslightOptions as WorkspaceGaslightOptions, type GaslightResult } from "../../packages/agent-gaslight/dist/index.js";
|
|
2
2
|
import type { WorktreeExecutionOptions } from "./types.js";
|
|
3
|
-
export { GASLIGHT_CONFIG_EXAMPLE, ingestGaslight, loadGaslightConfig, parseGaslightConfig, type GaslightConfig, type GaslightCollectHumanPrompts, type GaslightEvent, type GaslightFileSystem, type GaslightIngestEvent, type GaslightIngestOptions, type GaslightIngestResult, type GaslightPlanResult, type GaslightResult, type GaslightRound, type GaslightSpawn } from "../../packages/agent-gaslight/dist/index.js";
|
|
3
|
+
export { GASLIGHT_CONFIG_EXAMPLE, ingestGaslight, loadGaslightConfig, parseGaslightConfig, type GaslightConfig, type GaslightDaemonEvent, type GaslightDaemonResult, type GaslightCollectHumanPrompts, type GaslightEvent, type GaslightFileSystem, type GaslightIngestEvent, type GaslightIngestOptions, type GaslightIngestResult, type GaslightPlanResult, type GaslightResult, type GaslightRound, type GaslightSpawn } from "../../packages/agent-gaslight/dist/index.js";
|
|
4
4
|
export type GaslightOptions = WorkspaceGaslightOptions & {
|
|
5
5
|
worktree?: WorktreeExecutionOptions;
|
|
6
6
|
};
|
|
7
|
+
export type GaslightDaemonOptions = Omit<WorkspaceGaslightDaemonOptions, "run"> & {
|
|
8
|
+
worktree?: WorktreeExecutionOptions;
|
|
9
|
+
};
|
|
10
|
+
export declare function runGaslightDaemon(options: GaslightDaemonOptions): Promise<GaslightDaemonResult>;
|
|
7
11
|
export declare function runGaslight(options: GaslightOptions): Promise<GaslightResult>;
|
package/dist/sdk/gaslight.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import { runGaslight as runWorkspaceGaslight } from "@poe-code/agent-gaslight";
|
|
1
|
+
import { runGaslightDaemon as runWorkspaceGaslightDaemon, runGaslight as runWorkspaceGaslight } from "@poe-code/agent-gaslight";
|
|
2
2
|
import { runWithOptionalWorktree } from "./worktree.js";
|
|
3
3
|
export { GASLIGHT_CONFIG_EXAMPLE, ingestGaslight, loadGaslightConfig, parseGaslightConfig } from "@poe-code/agent-gaslight";
|
|
4
|
+
export async function runGaslightDaemon(options) {
|
|
5
|
+
return await runWorkspaceGaslightDaemon({
|
|
6
|
+
...options,
|
|
7
|
+
run: async (gaslightOptions) => await runGaslight({ ...gaslightOptions, worktree: options.worktree })
|
|
8
|
+
});
|
|
9
|
+
}
|
|
4
10
|
export async function runGaslight(options) {
|
|
5
11
|
if (!isWorktreeEnabled(options.worktree)) {
|
|
6
12
|
return await runWorkspaceGaslight(options);
|
package/dist/sdk/gaslight.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaslight.js","sourceRoot":"","sources":["../../src/sdk/gaslight.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,IAAI,oBAAoB,
|
|
1
|
+
{"version":3,"file":"gaslight.js","sourceRoot":"","sources":["../../src/sdk/gaslight.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,IAAI,0BAA0B,EAC/C,WAAW,IAAI,oBAAoB,EAKpC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAGxD,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EAcpB,MAAM,0BAA0B,CAAC;AAUlC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA8B;IAE9B,OAAO,MAAM,0BAA0B,CAAC;QACtC,GAAG,OAAO;QACV,GAAG,EAAE,KAAK,EAAE,eAAyC,EAAE,EAAE,CACvD,MAAM,WAAW,CAAC,EAAE,GAAG,eAAe,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;KACxE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAwB;IACxD,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,OAAO,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAiB;QAC5D,GAAG;QACH,aAAa,EAAE,OAAO,CAAC,KAAK;QAC5B,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;YAC7B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,gBAAgB,EAAE,GAAG,OAAO,CAAC;YAC7D,OAAO,MAAM,oBAAoB,CAAC;gBAChC,GAAG,gBAAgB;gBACnB,GAAG,EAAE,WAAW;aACjB,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,KAAK,CAAC;AACvB,CAAC;AAED,SAAS,iBAAiB,CAAC,QAA8C;IACvE,OAAO,QAAQ,KAAK,IAAI,CAAC;AAC3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { GaslightOptions, GaslightResult } from "./types.js";
|
|
2
|
+
export type GaslightDaemonEvent = {
|
|
3
|
+
type: "scan.finished";
|
|
4
|
+
readyPlans: number;
|
|
5
|
+
} | {
|
|
6
|
+
type: "plan.started";
|
|
7
|
+
planPath: string;
|
|
8
|
+
} | {
|
|
9
|
+
type: "plan.finished";
|
|
10
|
+
planPath: string;
|
|
11
|
+
} | {
|
|
12
|
+
type: "plan.failed";
|
|
13
|
+
planPath: string;
|
|
14
|
+
error: string;
|
|
15
|
+
};
|
|
16
|
+
export interface GaslightDaemonOptions extends Omit<GaslightOptions, "planPaths" | "archive" | "onEvent"> {
|
|
17
|
+
planDirectory: string;
|
|
18
|
+
pollIntervalMs?: number;
|
|
19
|
+
onEvent?: (event: GaslightDaemonEvent) => void;
|
|
20
|
+
wait?: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
|
|
21
|
+
run?: (options: GaslightOptions) => Promise<GaslightResult>;
|
|
22
|
+
}
|
|
23
|
+
export interface GaslightDaemonResult {
|
|
24
|
+
completedPlans: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function runGaslightDaemon(options: GaslightDaemonOptions): Promise<GaslightDaemonResult>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as fsPromises from "node:fs/promises";
|
|
2
|
+
import { discoverPlans } from "@poe-code/agent-harness-tools";
|
|
3
|
+
import { runGaslight } from "./run.js";
|
|
4
|
+
const DEFAULT_POLL_INTERVAL_MS = 5_000;
|
|
5
|
+
function waitForNextScan(milliseconds, signal) {
|
|
6
|
+
if (signal?.aborted)
|
|
7
|
+
return Promise.resolve();
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
const timeout = setTimeout(finish, milliseconds);
|
|
10
|
+
function finish() {
|
|
11
|
+
clearTimeout(timeout);
|
|
12
|
+
signal?.removeEventListener("abort", finish);
|
|
13
|
+
resolve();
|
|
14
|
+
}
|
|
15
|
+
signal?.addEventListener("abort", finish, { once: true });
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export async function runGaslightDaemon(options) {
|
|
19
|
+
const cwd = options.cwd ?? process.cwd();
|
|
20
|
+
const homeDir = options.homeDir ?? process.env.HOME ?? cwd;
|
|
21
|
+
const fs = options.fs ?? fsPromises;
|
|
22
|
+
const run = options.run ?? runGaslight;
|
|
23
|
+
const wait = options.wait ?? waitForNextScan;
|
|
24
|
+
const completed = new Set();
|
|
25
|
+
let completedPlans = 0;
|
|
26
|
+
while (!options.signal?.aborted) {
|
|
27
|
+
const plans = await discoverPlans({
|
|
28
|
+
cwd,
|
|
29
|
+
homeDir,
|
|
30
|
+
planDirectory: options.planDirectory,
|
|
31
|
+
kinds: ["plan"],
|
|
32
|
+
fs: fs
|
|
33
|
+
});
|
|
34
|
+
const readyPlans = plans.filter((plan) => plan.readiness === "ready" && !completed.has(plan.absolutePath));
|
|
35
|
+
options.onEvent?.({ type: "scan.finished", readyPlans: readyPlans.length });
|
|
36
|
+
for (const plan of readyPlans) {
|
|
37
|
+
if (options.signal?.aborted)
|
|
38
|
+
break;
|
|
39
|
+
options.onEvent?.({ type: "plan.started", planPath: plan.displayPath });
|
|
40
|
+
const { run: ignoredRun, wait: ignoredWait, pollIntervalMs: ignoredPollIntervalMs, planDirectory: ignoredPlanDirectory, onEvent: ignoredOnEvent, ...gaslightOptions } = options;
|
|
41
|
+
try {
|
|
42
|
+
await run({
|
|
43
|
+
...gaslightOptions,
|
|
44
|
+
planPaths: [plan.displayPath],
|
|
45
|
+
archive: true,
|
|
46
|
+
fs
|
|
47
|
+
});
|
|
48
|
+
completed.add(plan.absolutePath);
|
|
49
|
+
completedPlans += 1;
|
|
50
|
+
options.onEvent?.({ type: "plan.finished", planPath: plan.displayPath });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
options.onEvent?.({
|
|
54
|
+
type: "plan.failed",
|
|
55
|
+
planPath: plan.displayPath,
|
|
56
|
+
error: error instanceof Error ? error.message : String(error)
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!options.signal?.aborted) {
|
|
61
|
+
await wait(options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS, options.signal);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { completedPlans };
|
|
65
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { GASLIGHT_CONFIG_EXAMPLE, loadGaslightConfig, parseGaslightConfig } from "./config.js";
|
|
2
2
|
export { ingestGaslight } from "./ingest.js";
|
|
3
|
+
export { runGaslightDaemon } from "./daemon.js";
|
|
3
4
|
export { runGaslight } from "./run.js";
|
|
5
|
+
export type { GaslightDaemonEvent, GaslightDaemonOptions, GaslightDaemonResult } from "./daemon.js";
|
|
4
6
|
export type { GaslightArchiveFileSystem, GaslightConfig, GaslightCollectHumanPrompts, GaslightEvent, GaslightFileSystem, GaslightIngestEvent, GaslightIngestOptions, GaslightIngestResult, GaslightOptions, GaslightPlanResult, GaslightResult, GaslightRound, GaslightSpawn } from "./types.js";
|
|
@@ -8,8 +8,11 @@ export function buildPlanExplorerConfig(options) {
|
|
|
8
8
|
let plans = options.plans;
|
|
9
9
|
let rows = toRows(plans);
|
|
10
10
|
let entryByRowId = toEntryMap(plans);
|
|
11
|
+
let preserveOrderOnNextRefresh = false;
|
|
11
12
|
async function refresh() {
|
|
12
|
-
|
|
13
|
+
const refreshedPlans = await options.onRefresh();
|
|
14
|
+
plans = preserveOrderOnNextRefresh ? preservePlanOrder(plans, refreshedPlans) : refreshedPlans;
|
|
15
|
+
preserveOrderOnNextRefresh = false;
|
|
13
16
|
rows = toRows(plans);
|
|
14
17
|
entryByRowId = toEntryMap(plans);
|
|
15
18
|
}
|
|
@@ -22,7 +25,13 @@ export function buildPlanExplorerConfig(options) {
|
|
|
22
25
|
const entry = getEntry(entryByRowId, ctx.row.id);
|
|
23
26
|
const readiness = entry.readiness === "ready" ? "draft" : "ready";
|
|
24
27
|
await setPlanReadiness(entry.absolutePath, readiness, options.fs);
|
|
25
|
-
|
|
28
|
+
preserveOrderOnNextRefresh = true;
|
|
29
|
+
try {
|
|
30
|
+
await ctx.refresh();
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
preserveOrderOnNextRefresh = false;
|
|
34
|
+
}
|
|
26
35
|
ctx.toast(`Marked ${path.basename(entry.path)} ${readiness}`, "info");
|
|
27
36
|
}
|
|
28
37
|
},
|
|
@@ -100,6 +109,7 @@ export function buildPlanExplorerConfig(options) {
|
|
|
100
109
|
},
|
|
101
110
|
{
|
|
102
111
|
id: "delete",
|
|
112
|
+
accelerator: "x",
|
|
103
113
|
label: "Delete",
|
|
104
114
|
destructive: true,
|
|
105
115
|
handler: async (ctx) => {
|
|
@@ -148,6 +158,24 @@ export function buildPlanExplorerConfig(options) {
|
|
|
148
158
|
emptyHint: "No plans found"
|
|
149
159
|
});
|
|
150
160
|
}
|
|
161
|
+
function preservePlanOrder(current, refreshed) {
|
|
162
|
+
const refreshedByPath = new Map();
|
|
163
|
+
for (const entry of refreshed) {
|
|
164
|
+
const matches = refreshedByPath.get(entry.absolutePath) ?? [];
|
|
165
|
+
matches.push(entry);
|
|
166
|
+
refreshedByPath.set(entry.absolutePath, matches);
|
|
167
|
+
}
|
|
168
|
+
const ordered = [];
|
|
169
|
+
for (const entry of current) {
|
|
170
|
+
const matches = refreshedByPath.get(entry.absolutePath);
|
|
171
|
+
const match = matches?.shift();
|
|
172
|
+
if (match !== undefined)
|
|
173
|
+
ordered.push(match);
|
|
174
|
+
}
|
|
175
|
+
const remaining = new Set(ordered);
|
|
176
|
+
ordered.push(...refreshed.filter((entry) => !remaining.has(entry)));
|
|
177
|
+
return ordered;
|
|
178
|
+
}
|
|
151
179
|
function abbreviateHome(filePath, homeDir) {
|
|
152
180
|
if (homeDir === undefined)
|
|
153
181
|
return filePath;
|
|
@@ -786,14 +786,15 @@ function dispatchAction(state, action, confirmed, runtimeHandles, modalRows) {
|
|
|
786
786
|
return mark(state, 0);
|
|
787
787
|
}
|
|
788
788
|
if (action.destructive === true && !confirmed) {
|
|
789
|
+
const actionLabel = typeof action.label === "function" ? action.label() : action.label;
|
|
789
790
|
return {
|
|
790
791
|
state: {
|
|
791
792
|
...state,
|
|
792
793
|
modal: {
|
|
793
794
|
kind: "confirm",
|
|
794
795
|
title: action.destructive ? "Confirm destructive action" : "Confirm action",
|
|
795
|
-
message: `${
|
|
796
|
-
confirmLabel:
|
|
796
|
+
message: `${actionLabel} ${rows.length === 1 ? rows[0].title : `${rows.length} items`}?`,
|
|
797
|
+
confirmLabel: actionLabel,
|
|
797
798
|
cancelLabel: "Cancel",
|
|
798
799
|
destructive: action.destructive === true,
|
|
799
800
|
action,
|