@cydm/pie 1.0.5 → 1.0.7
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 +162 -9
- package/dist/builtin/extensions/ask-user/index.js +10 -2911
- package/dist/builtin/extensions/changelog/index.js +3 -8
- package/dist/builtin/extensions/deploy/index.js +1 -1
- package/dist/builtin/extensions/document-attachments/index.js +1 -0
- package/dist/builtin/extensions/files/index.js +1 -1
- package/dist/builtin/extensions/init/index.js +1 -3
- package/dist/builtin/extensions/kimi-attachments/index.js +4 -3
- package/dist/builtin/extensions/plan-mode/index.js +96 -165
- package/dist/builtin/extensions/subagent/index.js +88 -10991
- package/dist/builtin/extensions/todo/index.js +55 -2734
- package/dist/builtin/skills/browser-tools/CHANGELOG.md +2 -44
- package/dist/builtin/skills/browser-tools/README.md +10 -99
- package/dist/builtin/skills/browser-tools/SKILL.md +21 -174
- package/dist/builtin/skills/browser-tools/package.json +6 -13
- package/dist/builtin/skills/browser-tools/playwright-cli.js +24 -0
- package/dist/builtin/skills/pie-unity-rpc/SKILL.md +121 -0
- package/dist/builtin/skills/pie-unity-rpc/pie-unity-rpc.js +417 -0
- package/dist/builtin/skills/skill-creator/SKILL.md +17 -17
- package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.mjs +285 -0
- package/dist/builtin/skills/skill-creator/eval-viewer/viewer.html +1 -1
- package/dist/builtin/skills/skill-creator/scripts/aggregate_benchmark.mjs +271 -0
- package/dist/builtin/skills/skill-creator/scripts/claude_cli.mjs +115 -0
- package/dist/builtin/skills/skill-creator/scripts/generate_report.mjs +224 -0
- package/dist/builtin/skills/skill-creator/scripts/improve_description.mjs +198 -0
- package/dist/builtin/skills/skill-creator/scripts/package_skill.mjs +132 -0
- package/dist/builtin/skills/skill-creator/scripts/pie_runner.mjs +115 -0
- package/dist/builtin/skills/skill-creator/scripts/quick_validate.mjs +44 -0
- package/dist/builtin/skills/skill-creator/scripts/run_eval.mjs +169 -0
- package/dist/builtin/skills/skill-creator/scripts/run_loop.mjs +297 -0
- package/dist/builtin/skills/skill-creator/scripts/skill_metadata.mjs +134 -0
- package/dist/chunks/chunk-A5JSJAPK.js +9994 -0
- package/dist/chunks/chunk-BHNULR7U.js +7991 -0
- package/dist/chunks/chunk-GDTN4UPJ.js +701 -0
- package/dist/chunks/chunk-TG2EQLX2.js +43 -0
- package/dist/chunks/src-3X3HBT2G.js +12 -0
- package/dist/chunks/typescript-GSKWJIO4.js +210747 -0
- package/dist/cli.js +21519 -33379
- package/models.schema.json +238 -0
- package/package.json +36 -11
- package/dist/builtin/extensions/questionnaire/index.js +0 -2753
- package/dist/builtin/skills/browser-tools/browser-content.js +0 -103
- package/dist/builtin/skills/browser-tools/browser-cookies.js +0 -35
- package/dist/builtin/skills/browser-tools/browser-eval.js +0 -49
- package/dist/builtin/skills/browser-tools/browser-hn-scraper.js +0 -108
- package/dist/builtin/skills/browser-tools/browser-nav.js +0 -44
- package/dist/builtin/skills/browser-tools/browser-pick.js +0 -162
- package/dist/builtin/skills/browser-tools/browser-screenshot.js +0 -34
- package/dist/builtin/skills/browser-tools/browser-start.js +0 -86
- package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.py +0 -471
- package/dist/builtin/skills/skill-creator/scripts/__init__.py +0 -0
- package/dist/builtin/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
- package/dist/builtin/skills/skill-creator/scripts/generate_report.py +0 -326
- package/dist/builtin/skills/skill-creator/scripts/improve_description.py +0 -247
- package/dist/builtin/skills/skill-creator/scripts/package_skill.py +0 -136
- package/dist/builtin/skills/skill-creator/scripts/quick_validate.py +0 -103
- package/dist/builtin/skills/skill-creator/scripts/run_eval.py +0 -310
- package/dist/builtin/skills/skill-creator/scripts/run_loop.py +0 -328
- package/dist/builtin/skills/skill-creator/scripts/utils.py +0 -47
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
-
});
|
|
2
|
+
import {
|
|
3
|
+
__require
|
|
4
|
+
} from "../../../chunks/chunk-TG2EQLX2.js";
|
|
8
5
|
|
|
9
6
|
// builtin/extensions/changelog/index.ts
|
|
10
7
|
function getRecentCommits(cwd, count = 10) {
|
|
@@ -47,7 +44,6 @@ async function readChangelog(cwd) {
|
|
|
47
44
|
}
|
|
48
45
|
function changelogExtension(ctx) {
|
|
49
46
|
ctx.log("Changelog extension loaded");
|
|
50
|
-
ctx.ui.notify("\u{1F4DD} Changelog extension loaded", "info");
|
|
51
47
|
ctx.registerCommand({
|
|
52
48
|
path: ["tools", "changelog"],
|
|
53
49
|
description: "Smart changelog management with gap detection",
|
|
@@ -193,7 +189,6 @@ ${changelog ? "\n```\n" + changelog.slice(0, 2e3) + "\n...\n```" : "(\u6587\u4EF
|
|
|
193
189
|
}
|
|
194
190
|
});
|
|
195
191
|
ctx.log("Changelog extension ready");
|
|
196
|
-
ctx.ui.notify(" Changelog extension loaded", "info");
|
|
197
192
|
}
|
|
198
193
|
export {
|
|
199
194
|
changelogExtension as default
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
+
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
2
3
|
|
|
3
4
|
// builtin/extensions/deploy/index.ts
|
|
4
5
|
function deployExtension(ctx) {
|
|
5
6
|
ctx.log("Deploy extension loaded");
|
|
6
|
-
ctx.ui.notify("\u{1F680} Deploy extension loaded", "info");
|
|
7
7
|
ctx.log("Deploy extension ready");
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
+
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
2
3
|
|
|
3
4
|
// builtin/extensions/files/index.ts
|
|
4
5
|
function filesExtension(ctx) {
|
|
5
6
|
ctx.log("Files extension loaded");
|
|
6
|
-
ctx.ui.notify("\u{1F4C1} Files extension loaded", "info");
|
|
7
7
|
}
|
|
8
8
|
export {
|
|
9
9
|
filesExtension as default
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
+
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
2
3
|
|
|
3
4
|
// builtin/extensions/init/index.ts
|
|
4
5
|
async function loadExistingKnowledge(cwd) {
|
|
@@ -100,14 +101,11 @@ async function initExtension(ctx) {
|
|
|
100
101
|
if (cachedKnowledge) {
|
|
101
102
|
const firstLine = cachedKnowledge.split("\n")[0] || "";
|
|
102
103
|
const projectName = firstLine.replace(/^#\s*/, "").trim() || "\u9879\u76EE";
|
|
103
|
-
ctx.ui.notify(`\u{1F4DA} \u5DF2\u52A0\u8F7D ${projectName} \u77E5\u8BC6\u6587\u6863`, "info");
|
|
104
104
|
ctx.log(`Pre-loaded agents.md (${cachedKnowledge.length} chars)`);
|
|
105
105
|
} else {
|
|
106
|
-
ctx.ui.notify("\u{1F4DA} Init extension loaded (no existing knowledge)", "info");
|
|
107
106
|
ctx.log("No existing agents.md found");
|
|
108
107
|
}
|
|
109
108
|
} catch (err) {
|
|
110
|
-
ctx.ui.notify("\u{1F4DA} Init extension loaded", "info");
|
|
111
109
|
ctx.log(`Failed to pre-load agents.md: ${err}`);
|
|
112
110
|
}
|
|
113
111
|
ctx.registerCommand({
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
+
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
2
3
|
|
|
3
4
|
// builtin/extensions/kimi-attachments/index.ts
|
|
4
|
-
function
|
|
5
|
-
return
|
|
5
|
+
function isKimiAttachmentPlatform(model) {
|
|
6
|
+
return model.attachmentPlatform === "kimi" || model.filePlatform === "kimi";
|
|
6
7
|
}
|
|
7
8
|
function getModality(mimeType) {
|
|
8
9
|
if (mimeType.startsWith("image/")) return "image";
|
|
@@ -15,7 +16,7 @@ function kimiAttachmentsExtension(ctx) {
|
|
|
15
16
|
name: "kimi-native-attachments",
|
|
16
17
|
priority: 100,
|
|
17
18
|
matches(model, attachment) {
|
|
18
|
-
return
|
|
19
|
+
return isKimiAttachmentPlatform(model) && Boolean(attachment.fileId) && getModality(attachment.mimeType) !== "file";
|
|
19
20
|
},
|
|
20
21
|
async prepare(_model, attachment, prepareCtx) {
|
|
21
22
|
const fileId = attachment.fileId;
|
|
@@ -1,139 +1,74 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
buildExecutionReminder,
|
|
4
|
+
createExecutionStateFromPlan,
|
|
5
|
+
createPlanCapability,
|
|
6
|
+
extractPlanTodoItems,
|
|
7
|
+
isPlanModeSafeCommand,
|
|
8
|
+
markCompletedPlanSteps,
|
|
9
|
+
restoreExecutionState
|
|
10
|
+
} from "../../../chunks/chunk-BHNULR7U.js";
|
|
11
|
+
import "../../../chunks/chunk-A5JSJAPK.js";
|
|
12
|
+
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
2
13
|
|
|
3
14
|
// builtin/extensions/plan-mode/index.ts
|
|
4
|
-
function extractTodoItems(text) {
|
|
5
|
-
const items = [];
|
|
6
|
-
const planMatch = text.match(/Plan:\s*\n?([\s\S]*?)(?=\n\n|\n[A-Z]|$)/i);
|
|
7
|
-
if (!planMatch) return items;
|
|
8
|
-
const planSection = planMatch[1];
|
|
9
|
-
const lines = planSection.split("\n");
|
|
10
|
-
for (const line of lines) {
|
|
11
|
-
const trimmed = line.trim();
|
|
12
|
-
const match = trimmed.match(/^(?:\d+[.):\s]+|[\-*]\s+)(.+)$/);
|
|
13
|
-
if (match) {
|
|
14
|
-
items.push({
|
|
15
|
-
step: items.length + 1,
|
|
16
|
-
text: match[1].trim(),
|
|
17
|
-
completed: false
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return items;
|
|
22
|
-
}
|
|
23
|
-
function isSafeCommand(command) {
|
|
24
|
-
const trimmed = command.trim();
|
|
25
|
-
const safePrefixes = [
|
|
26
|
-
"cat ",
|
|
27
|
-
"ls ",
|
|
28
|
-
"find ",
|
|
29
|
-
"grep ",
|
|
30
|
-
"head ",
|
|
31
|
-
"tail ",
|
|
32
|
-
"echo ",
|
|
33
|
-
"pwd",
|
|
34
|
-
"cd ",
|
|
35
|
-
"which ",
|
|
36
|
-
"git status",
|
|
37
|
-
"git log",
|
|
38
|
-
"git diff",
|
|
39
|
-
"git show",
|
|
40
|
-
"git branch -a",
|
|
41
|
-
"git remote -v",
|
|
42
|
-
"git config --list",
|
|
43
|
-
"npm list",
|
|
44
|
-
"npm view"
|
|
45
|
-
];
|
|
46
|
-
const dangerousPatterns = [
|
|
47
|
-
/\brm\s+-[rf]*/i,
|
|
48
|
-
/>[\s]*\/dev\//,
|
|
49
|
-
/\|.*\brm\b/,
|
|
50
|
-
/git\s+push/i,
|
|
51
|
-
/git\s+reset/i,
|
|
52
|
-
/git\s+checkout\s+-/,
|
|
53
|
-
/git\s+revert/i,
|
|
54
|
-
/npm\s+publish/i,
|
|
55
|
-
/npm\s+uninstall/i,
|
|
56
|
-
/npm\s+rm/i
|
|
57
|
-
];
|
|
58
|
-
for (const pattern of dangerousPatterns) {
|
|
59
|
-
if (pattern.test(trimmed)) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
for (const prefix of safePrefixes) {
|
|
64
|
-
if (trimmed.startsWith(prefix)) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (/^[a-z]+$/.test(trimmed)) {
|
|
69
|
-
return ["pwd", "ls", "clear", "whoami"].includes(trimmed);
|
|
70
|
-
}
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
function markCompletedSteps(text, todoItems2) {
|
|
74
|
-
let markedCount = 0;
|
|
75
|
-
const doneMatches = text.matchAll(/\[DONE:\s*(\d+)\]/gi);
|
|
76
|
-
for (const match of doneMatches) {
|
|
77
|
-
const stepNum = parseInt(match[1], 10);
|
|
78
|
-
const item = todoItems2.find((t) => t.step === stepNum);
|
|
79
|
-
if (item && !item.completed) {
|
|
80
|
-
item.completed = true;
|
|
81
|
-
markedCount++;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return markedCount;
|
|
85
|
-
}
|
|
86
|
-
var PLAN_MODE_TOOLS = ["read", "bash", "grep", "find", "ls", "questionnaire"];
|
|
87
|
-
var NORMAL_MODE_TOOLS = ["read", "bash", "edit", "write", "grep", "find", "ls", "questionnaire"];
|
|
88
15
|
var SESSION_METADATA_KEY = "planModeEnabled";
|
|
16
|
+
var EXECUTION_METADATA_KEY = "executionState";
|
|
89
17
|
var planModeEnabled = false;
|
|
90
18
|
var executionMode = false;
|
|
91
|
-
|
|
19
|
+
function toPlanTodoItems(state) {
|
|
20
|
+
return state.steps.map((step) => ({
|
|
21
|
+
step: step.id,
|
|
22
|
+
text: step.title,
|
|
23
|
+
completed: step.status === "completed"
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
92
26
|
function planModeExtension(ctx) {
|
|
93
|
-
|
|
27
|
+
const capability = createPlanCapability();
|
|
94
28
|
function readPersistedPlanMode() {
|
|
95
29
|
return ctx.getSessionMetadata()?.[SESSION_METADATA_KEY] === true;
|
|
96
30
|
}
|
|
31
|
+
function readExecutionState() {
|
|
32
|
+
return restoreExecutionState(ctx.getSessionMetadata()?.[EXECUTION_METADATA_KEY] ?? ctx.getExecutionState());
|
|
33
|
+
}
|
|
34
|
+
function writeExecutionState(state) {
|
|
35
|
+
const next = state ?? restoreExecutionState(null);
|
|
36
|
+
ctx.setSessionMetadata(EXECUTION_METADATA_KEY, next);
|
|
37
|
+
ctx.setExecutionState(next);
|
|
38
|
+
ctx.setExecutionReminder(buildExecutionReminder(next) ?? void 0);
|
|
39
|
+
return next;
|
|
40
|
+
}
|
|
97
41
|
function updateStatus() {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
42
|
+
const state = readExecutionState();
|
|
43
|
+
if (executionMode && state.steps.length > 0) {
|
|
44
|
+
const completed = state.steps.filter((step) => step.status === "completed").length;
|
|
45
|
+
ctx.ui.notify(`\u{1F4CB} Plan: ${completed}/${state.steps.length} completed`, "info");
|
|
101
46
|
} else if (planModeEnabled) {
|
|
102
47
|
ctx.ui.notify("\u23F8\uFE0F Plan mode active (read-only)", "info");
|
|
103
48
|
}
|
|
104
49
|
}
|
|
50
|
+
function applyPlanModeState(enabled, forcePromptInjection = false) {
|
|
51
|
+
planModeEnabled = enabled;
|
|
52
|
+
if (!enabled) {
|
|
53
|
+
executionMode = false;
|
|
54
|
+
}
|
|
55
|
+
ctx.setPlanMode(enabled, { forcePromptInjection });
|
|
56
|
+
}
|
|
105
57
|
function togglePlanMode() {
|
|
106
58
|
planModeEnabled = !planModeEnabled;
|
|
107
59
|
executionMode = false;
|
|
108
|
-
|
|
60
|
+
writeExecutionState(null);
|
|
109
61
|
ctx.setSessionMetadata(SESSION_METADATA_KEY, planModeEnabled);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
ctx.
|
|
113
|
-
|
|
114
|
-
} else {
|
|
115
|
-
ctx.setActiveTools(NORMAL_MODE_TOOLS);
|
|
116
|
-
ctx.ui.notify("Plan mode disabled. Full access restored.");
|
|
117
|
-
}
|
|
118
|
-
updateStatus();
|
|
119
|
-
}
|
|
120
|
-
function applyPlanModeState(enabled, options = {}) {
|
|
121
|
-
planModeEnabled = enabled;
|
|
122
|
-
executionMode = false;
|
|
123
|
-
todoItems = [];
|
|
124
|
-
ctx.setPlanMode(enabled, { forcePromptInjection: options.forcePromptInjection });
|
|
125
|
-
ctx.setActiveTools(enabled ? PLAN_MODE_TOOLS : NORMAL_MODE_TOOLS);
|
|
126
|
-
if (options.notify) {
|
|
127
|
-
ctx.ui.notify(
|
|
128
|
-
enabled ? `Plan mode enabled. Available tools: ${PLAN_MODE_TOOLS.join(", ")}` : "Plan mode disabled. Full access restored."
|
|
129
|
-
);
|
|
130
|
-
}
|
|
62
|
+
applyPlanModeState(planModeEnabled, true);
|
|
63
|
+
ctx.ui.notify(
|
|
64
|
+
planModeEnabled ? `Plan mode enabled. Available tools: ${ctx.getActiveTools().join(", ")}` : "Plan mode disabled. Full access restored."
|
|
65
|
+
);
|
|
131
66
|
updateStatus();
|
|
132
67
|
}
|
|
133
68
|
ctx.registerCommand({
|
|
134
|
-
path: ["tools", "plan"],
|
|
135
|
-
description: "Toggle plan mode (read-only exploration)",
|
|
136
|
-
handler: async (
|
|
69
|
+
path: capability.commands?.[0]?.path ?? ["tools", "plan"],
|
|
70
|
+
description: capability.commands?.[0]?.description ?? "Toggle plan mode (read-only exploration)",
|
|
71
|
+
handler: async () => {
|
|
137
72
|
togglePlanMode();
|
|
138
73
|
}
|
|
139
74
|
});
|
|
@@ -146,7 +81,7 @@ function planModeExtension(ctx) {
|
|
|
146
81
|
ctx.on("tool:call", async (event) => {
|
|
147
82
|
if (!planModeEnabled || event.toolName !== "bash") return;
|
|
148
83
|
const command = event.args?.command;
|
|
149
|
-
if (command && !
|
|
84
|
+
if (command && !isPlanModeSafeCommand(command)) {
|
|
150
85
|
ctx.ui.notify(
|
|
151
86
|
`Plan mode: Command blocked (not allowlisted). Use /plan to disable plan mode first.
|
|
152
87
|
Command: ${command}`,
|
|
@@ -157,79 +92,75 @@ Command: ${command}`,
|
|
|
157
92
|
});
|
|
158
93
|
ctx.on("agent:start", async () => {
|
|
159
94
|
const persisted = readPersistedPlanMode();
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
if (planModeEnabled) {
|
|
164
|
-
ctx.log("[plan-mode] Injecting plan mode context");
|
|
165
|
-
}
|
|
95
|
+
applyPlanModeState(persisted);
|
|
96
|
+
writeExecutionState(readExecutionState());
|
|
166
97
|
});
|
|
167
98
|
ctx.on("session:changed", async () => {
|
|
168
99
|
const enabled = readPersistedPlanMode();
|
|
169
|
-
applyPlanModeState(enabled,
|
|
100
|
+
applyPlanModeState(enabled, enabled);
|
|
101
|
+
writeExecutionState(readExecutionState());
|
|
170
102
|
});
|
|
171
103
|
ctx.on("turn:end", async (event) => {
|
|
172
|
-
|
|
104
|
+
const state = readExecutionState();
|
|
105
|
+
if (!executionMode || state.steps.length === 0) return;
|
|
173
106
|
const message = event.message;
|
|
174
|
-
if (message?.role
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
107
|
+
if (message?.role !== "assistant" || !Array.isArray(message.content)) return;
|
|
108
|
+
const text = message.content.filter((item) => item.type === "text").map((item) => item.text).join("\n");
|
|
109
|
+
const todoItems = toPlanTodoItems(state);
|
|
110
|
+
if (markCompletedPlanSteps(text, todoItems) <= 0) return;
|
|
111
|
+
const nextState = createExecutionStateFromPlan(todoItems);
|
|
112
|
+
writeExecutionState(nextState);
|
|
113
|
+
updateStatus();
|
|
180
114
|
});
|
|
181
115
|
ctx.on("agent:end", async (event) => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
116
|
+
const state = readExecutionState();
|
|
117
|
+
if (executionMode && state.steps.length > 0) {
|
|
118
|
+
if (state.steps.every((step) => step.status === "completed")) {
|
|
119
|
+
const completedList = state.steps.map((step) => `\u2713 ${step.title}`).join("\n");
|
|
185
120
|
ctx.ui.notify(`**Plan Complete!** \u2713
|
|
186
121
|
|
|
187
122
|
${completedList}`, "info");
|
|
188
123
|
executionMode = false;
|
|
189
|
-
|
|
190
|
-
ctx.setActiveTools(NORMAL_MODE_TOOLS);
|
|
124
|
+
writeExecutionState(null);
|
|
191
125
|
}
|
|
192
126
|
return;
|
|
193
127
|
}
|
|
194
128
|
if (!planModeEnabled || !ctx.hasUI) return;
|
|
195
129
|
const messages = event.messages || [];
|
|
196
130
|
const lastAssistant = [...messages].reverse().find(
|
|
197
|
-
(
|
|
131
|
+
(message) => message.role === "assistant" && Array.isArray(message.content)
|
|
198
132
|
);
|
|
199
|
-
if (lastAssistant)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
if (todoItems.length > 0) {
|
|
207
|
-
const todoListText = todoItems.map((t) => `${t.step}. \u2610 ${t.text}`).join("\n");
|
|
208
|
-
ctx.ui.notify(`**Plan Steps (${todoItems.length}):**
|
|
133
|
+
if (!lastAssistant) return;
|
|
134
|
+
const text = lastAssistant.content.filter((item) => item.type === "text").map((item) => item.text).join("\n");
|
|
135
|
+
const extracted = extractPlanTodoItems(text);
|
|
136
|
+
if (extracted.length === 0) return;
|
|
137
|
+
const extractedState = writeExecutionState(createExecutionStateFromPlan(extracted));
|
|
138
|
+
const todoListText = extractedState.steps.map((step) => `${step.id}. \u2610 ${step.title}`).join("\n");
|
|
139
|
+
ctx.ui.notify(`**Plan Steps (${extractedState.steps.length}):**
|
|
209
140
|
${todoListText}`, "info");
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
141
|
+
const choice = await ctx.ui.select("Plan mode - what next?", [
|
|
142
|
+
"Execute the plan (track progress)",
|
|
143
|
+
"Stay in plan mode",
|
|
144
|
+
"Refine the plan"
|
|
145
|
+
]);
|
|
146
|
+
if (choice?.startsWith("Execute")) {
|
|
147
|
+
planModeEnabled = false;
|
|
148
|
+
executionMode = extractedState.steps.length > 0;
|
|
149
|
+
ctx.setSessionMetadata(SESSION_METADATA_KEY, false);
|
|
150
|
+
ctx.setPlanMode(false);
|
|
151
|
+
updateStatus();
|
|
152
|
+
const execMessage = extractedState.steps.length > 0 ? `Execute the plan. Start with: ${extractedState.steps[0].title}. Mark completed steps with [DONE:n] in your response.` : "Execute the plan you just created.";
|
|
153
|
+
ctx.sendUserMessage(execMessage);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (choice === "Refine the plan") {
|
|
157
|
+
const refinement = await ctx.ui.editor("Refine the plan:", "");
|
|
158
|
+
if (refinement?.trim()) {
|
|
159
|
+
ctx.sendUserMessage(refinement.trim());
|
|
229
160
|
}
|
|
230
161
|
}
|
|
231
162
|
});
|
|
232
|
-
ctx.
|
|
163
|
+
ctx.log("Plan mode extension loaded");
|
|
233
164
|
}
|
|
234
165
|
export {
|
|
235
166
|
planModeExtension as default
|