pulse-coder-engine 0.0.1-alpha.11 → 0.0.1-alpha.13
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/built-in/index.cjs +550 -97
- package/dist/built-in/index.cjs.map +1 -1
- package/dist/built-in/index.d.cts +1 -1
- package/dist/built-in/index.d.ts +1 -1
- package/dist/built-in/index.js +537 -86
- package/dist/built-in/index.js.map +1 -1
- package/dist/{index-BeWyLfso.d.cts → index-CPgs_IXY.d.cts} +84 -2
- package/dist/{index-BeWyLfso.d.ts → index-CPgs_IXY.d.ts} +84 -2
- package/dist/index.cjs +479 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +477 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/built-in/index.js
CHANGED
|
@@ -159,16 +159,44 @@ var BuiltInSkillRegistry = class {
|
|
|
159
159
|
return Array.from(this.skills.values());
|
|
160
160
|
}
|
|
161
161
|
/**
|
|
162
|
-
*
|
|
162
|
+
* 注册或更新一个技能(支持插件在运行期追加技能)
|
|
163
|
+
*/
|
|
164
|
+
registerSkill(skill) {
|
|
165
|
+
const name = skill.name?.trim();
|
|
166
|
+
if (!name) {
|
|
167
|
+
throw new Error("Skill name is required");
|
|
168
|
+
}
|
|
169
|
+
const existingKey = Array.from(this.skills.keys()).find((key) => key.toLowerCase() === name.toLowerCase());
|
|
170
|
+
const replaced = existingKey !== void 0;
|
|
171
|
+
if (existingKey && existingKey !== name) {
|
|
172
|
+
this.skills.delete(existingKey);
|
|
173
|
+
}
|
|
174
|
+
this.skills.set(name, {
|
|
175
|
+
...skill,
|
|
176
|
+
name
|
|
177
|
+
});
|
|
178
|
+
return {
|
|
179
|
+
skillName: name,
|
|
180
|
+
replaced,
|
|
181
|
+
total: this.skills.size
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 根据名称获取技能(大小写不敏感)
|
|
163
186
|
*/
|
|
164
187
|
get(name) {
|
|
165
|
-
|
|
188
|
+
const exact = this.skills.get(name);
|
|
189
|
+
if (exact) {
|
|
190
|
+
return exact;
|
|
191
|
+
}
|
|
192
|
+
const target = name.toLowerCase();
|
|
193
|
+
return this.getAll().find((skill) => skill.name.toLowerCase() === target);
|
|
166
194
|
}
|
|
167
195
|
/**
|
|
168
196
|
* 检查技能是否存在
|
|
169
197
|
*/
|
|
170
198
|
has(name) {
|
|
171
|
-
return this.
|
|
199
|
+
return !!this.get(name);
|
|
172
200
|
}
|
|
173
201
|
/**
|
|
174
202
|
* 搜索技能(模糊匹配)
|
|
@@ -183,7 +211,7 @@ var BuiltInSkillRegistry = class {
|
|
|
183
211
|
var skillToolSchema = z.object({
|
|
184
212
|
name: z.string().describe("The name of the skill to execute")
|
|
185
213
|
});
|
|
186
|
-
function generateSkillTool(
|
|
214
|
+
function generateSkillTool(registry) {
|
|
187
215
|
const getSkillsPrompt = (availableSkills) => {
|
|
188
216
|
return [
|
|
189
217
|
"If query matches an available skill's description or instruction [use skill], use the skill tool to get detailed instructions.",
|
|
@@ -204,10 +232,10 @@ function generateSkillTool(skills) {
|
|
|
204
232
|
};
|
|
205
233
|
return {
|
|
206
234
|
name: "skill",
|
|
207
|
-
description: getSkillsPrompt(
|
|
235
|
+
description: getSkillsPrompt(registry.getAll()),
|
|
208
236
|
inputSchema: skillToolSchema,
|
|
209
237
|
execute: async ({ name }) => {
|
|
210
|
-
const skill =
|
|
238
|
+
const skill = registry.get(name);
|
|
211
239
|
if (!skill) {
|
|
212
240
|
throw new Error(`Skill ${name} not found`);
|
|
213
241
|
}
|
|
@@ -221,14 +249,21 @@ var builtInSkillsPlugin = {
|
|
|
221
249
|
async initialize(context) {
|
|
222
250
|
const registry = new BuiltInSkillRegistry();
|
|
223
251
|
await registry.initialize(process.cwd());
|
|
252
|
+
context.registerService("skillRegistry", registry);
|
|
253
|
+
context.registerTool("skill", generateSkillTool(registry));
|
|
254
|
+
context.registerHook("beforeRun", ({ tools }) => {
|
|
255
|
+
return {
|
|
256
|
+
tools: {
|
|
257
|
+
...tools,
|
|
258
|
+
skill: generateSkillTool(registry)
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
});
|
|
224
262
|
const skills = registry.getAll();
|
|
225
263
|
if (skills.length === 0) {
|
|
226
264
|
console.log("[Skills] No skills found");
|
|
227
265
|
return;
|
|
228
266
|
}
|
|
229
|
-
const skillTool = generateSkillTool(skills);
|
|
230
|
-
context.registerTool("skill", skillTool);
|
|
231
|
-
context.registerService("skillRegistry", registry);
|
|
232
267
|
console.log(`[Skills] Registered ${skills.length} skill(s)`);
|
|
233
268
|
}
|
|
234
269
|
};
|
|
@@ -339,6 +374,26 @@ var KNOWN_TOOL_META = {
|
|
|
339
374
|
category: "other",
|
|
340
375
|
risk: "low",
|
|
341
376
|
description: "Ask the user a targeted clarification question."
|
|
377
|
+
},
|
|
378
|
+
task_create: {
|
|
379
|
+
category: "other",
|
|
380
|
+
risk: "low",
|
|
381
|
+
description: "Create tracked task entries for planning and execution visibility."
|
|
382
|
+
},
|
|
383
|
+
task_get: {
|
|
384
|
+
category: "other",
|
|
385
|
+
risk: "low",
|
|
386
|
+
description: "Inspect a task entry by ID."
|
|
387
|
+
},
|
|
388
|
+
task_list: {
|
|
389
|
+
category: "other",
|
|
390
|
+
risk: "low",
|
|
391
|
+
description: "List task tracking entries and status summary."
|
|
392
|
+
},
|
|
393
|
+
task_update: {
|
|
394
|
+
category: "other",
|
|
395
|
+
risk: "low",
|
|
396
|
+
description: "Update task tracking fields and status."
|
|
342
397
|
}
|
|
343
398
|
};
|
|
344
399
|
var BuiltInPlanModeService = class {
|
|
@@ -618,10 +673,397 @@ var builtInPlanModePlugin = {
|
|
|
618
673
|
}
|
|
619
674
|
};
|
|
620
675
|
|
|
676
|
+
// src/built-in/task-tracking-plugin/index.ts
|
|
677
|
+
import { promises as fs } from "fs";
|
|
678
|
+
import path2 from "path";
|
|
679
|
+
import { homedir as homedir2 } from "os";
|
|
680
|
+
import { randomUUID } from "crypto";
|
|
681
|
+
import { z as z2 } from "zod";
|
|
682
|
+
var TASK_STATUSES = ["pending", "in_progress", "completed", "blocked"];
|
|
683
|
+
var CREATE_TASK_ITEM_SCHEMA = z2.object({
|
|
684
|
+
title: z2.string().min(1).describe("Task title"),
|
|
685
|
+
details: z2.string().optional().describe("Task details / acceptance notes"),
|
|
686
|
+
status: z2.enum(TASK_STATUSES).optional().describe("Initial status; defaults to pending"),
|
|
687
|
+
dependencies: z2.array(z2.string()).optional().describe("Task IDs that must be completed first"),
|
|
688
|
+
blockedReason: z2.string().optional().describe("Reason when status is blocked"),
|
|
689
|
+
metadata: z2.record(z2.string(), z2.any()).optional().describe("Additional machine-readable metadata")
|
|
690
|
+
});
|
|
691
|
+
var TASK_CREATE_INPUT_SCHEMA = z2.object({
|
|
692
|
+
title: z2.string().min(1).optional().describe("Task title (single-task mode)"),
|
|
693
|
+
details: z2.string().optional().describe("Task details (single-task mode)"),
|
|
694
|
+
status: z2.enum(TASK_STATUSES).optional().describe("Initial status (single-task mode)"),
|
|
695
|
+
dependencies: z2.array(z2.string()).optional().describe("Dependencies (single-task mode)"),
|
|
696
|
+
blockedReason: z2.string().optional().describe("Blocked reason (single-task mode)"),
|
|
697
|
+
metadata: z2.record(z2.string(), z2.any()).optional().describe("Metadata (single-task mode)"),
|
|
698
|
+
tasks: z2.array(CREATE_TASK_ITEM_SCHEMA).min(1).optional().describe("Batch create mode")
|
|
699
|
+
}).refine((value) => !!value.tasks?.length || !!value.title, {
|
|
700
|
+
message: "Either provide `tasks` or `title` for single-task mode."
|
|
701
|
+
});
|
|
702
|
+
var TASK_GET_INPUT_SCHEMA = z2.object({
|
|
703
|
+
id: z2.string().min(1).describe("Task ID to retrieve")
|
|
704
|
+
});
|
|
705
|
+
var TASK_LIST_INPUT_SCHEMA = z2.object({
|
|
706
|
+
statuses: z2.array(z2.enum(TASK_STATUSES)).optional().describe("Filter by statuses"),
|
|
707
|
+
includeCompleted: z2.boolean().optional().describe("Set false to hide completed tasks"),
|
|
708
|
+
limit: z2.number().int().positive().max(500).optional().describe("Maximum tasks to return")
|
|
709
|
+
});
|
|
710
|
+
var TASK_TRACKING_SKILL = {
|
|
711
|
+
name: "task-tracking-workflow",
|
|
712
|
+
description: "Track complex execution with task tools and proceed directly without confirmation unless the user explicitly asks for confirmation.",
|
|
713
|
+
location: "pulse-coder-engine/built-in/task-tracking-plugin",
|
|
714
|
+
content: `# Task Tracking Workflow
|
|
715
|
+
|
|
716
|
+
## When to use
|
|
717
|
+
- The request has multiple phases or deliverables.
|
|
718
|
+
- Work may span multiple tool calls or sessions.
|
|
719
|
+
- You need explicit progress visibility and blocker management.
|
|
720
|
+
|
|
721
|
+
## Execution autonomy
|
|
722
|
+
- Default behavior: execute directly and call tools without asking for confirmation.
|
|
723
|
+
- Only ask for confirmation when the user explicitly requires confirmation.
|
|
724
|
+
- If critical information is missing, ask only the minimum clarifying question needed to continue.
|
|
725
|
+
|
|
726
|
+
## Required flow
|
|
727
|
+
1. Start by reviewing existing tasks with \`task_list\`.
|
|
728
|
+
2. If no suitable tasks exist, create focused tasks with \`task_create\` (prefer batch mode).
|
|
729
|
+
3. Keep exactly one primary task in \`in_progress\` where possible.
|
|
730
|
+
4. Update status with \`task_update\` after meaningful progress.
|
|
731
|
+
5. Mark blockers with \`status=blocked\` and a concrete \`blockedReason\`.
|
|
732
|
+
6. Mark done tasks as \`completed\` and move to the next actionable item.
|
|
733
|
+
|
|
734
|
+
## Quality rules
|
|
735
|
+
- Keep tasks atomic and verifiable.
|
|
736
|
+
- Avoid single oversized umbrella tasks.
|
|
737
|
+
- Reuse existing in-progress tasks instead of duplicating.
|
|
738
|
+
- Keep dependency links explicit when order matters.`
|
|
739
|
+
};
|
|
740
|
+
var TASK_UPDATE_INPUT_SCHEMA = z2.object({
|
|
741
|
+
id: z2.string().min(1).describe("Task ID to update"),
|
|
742
|
+
title: z2.string().min(1).optional().describe("New title"),
|
|
743
|
+
details: z2.string().optional().describe("New details"),
|
|
744
|
+
status: z2.enum(TASK_STATUSES).optional().describe("New status"),
|
|
745
|
+
dependencies: z2.array(z2.string()).optional().describe("Replace dependencies with this list"),
|
|
746
|
+
blockedReason: z2.string().optional().describe("Blocked reason, used with status=blocked"),
|
|
747
|
+
metadata: z2.record(z2.string(), z2.any()).optional().describe("Replace metadata object"),
|
|
748
|
+
delete: z2.boolean().optional().describe("Delete this task")
|
|
749
|
+
});
|
|
750
|
+
function normalizeTaskListId(raw) {
|
|
751
|
+
const trimmed = raw.trim();
|
|
752
|
+
if (!trimmed) {
|
|
753
|
+
return "default";
|
|
754
|
+
}
|
|
755
|
+
return trimmed.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 120) || "default";
|
|
756
|
+
}
|
|
757
|
+
function now() {
|
|
758
|
+
return Date.now();
|
|
759
|
+
}
|
|
760
|
+
function dedupeStrings(values) {
|
|
761
|
+
if (!values?.length) {
|
|
762
|
+
return [];
|
|
763
|
+
}
|
|
764
|
+
return Array.from(new Set(values.map((value) => String(value).trim()).filter(Boolean)));
|
|
765
|
+
}
|
|
766
|
+
var TaskListService = class _TaskListService {
|
|
767
|
+
taskListId;
|
|
768
|
+
storagePath;
|
|
769
|
+
storageDir;
|
|
770
|
+
initialized = false;
|
|
771
|
+
createdAt = now();
|
|
772
|
+
updatedAt = now();
|
|
773
|
+
tasks = /* @__PURE__ */ new Map();
|
|
774
|
+
constructor(taskListId = _TaskListService.resolveTaskListId(), storageDir = _TaskListService.resolveStorageDir()) {
|
|
775
|
+
const normalized = normalizeTaskListId(taskListId);
|
|
776
|
+
this.storageDir = storageDir;
|
|
777
|
+
this.taskListId = normalized;
|
|
778
|
+
this.storagePath = path2.join(this.storageDir, `${normalized}.json`);
|
|
779
|
+
}
|
|
780
|
+
static resolveTaskListId() {
|
|
781
|
+
return process.env.PULSE_CODER_TASK_LIST_ID || process.env.CLAUDE_CODE_TASK_LIST_ID || "default";
|
|
782
|
+
}
|
|
783
|
+
static resolveStorageDir() {
|
|
784
|
+
return process.env.PULSE_CODER_TASKS_DIR || path2.join(homedir2(), ".pulse-coder", "tasks");
|
|
785
|
+
}
|
|
786
|
+
async initialize() {
|
|
787
|
+
if (this.initialized) {
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
await this.loadTaskList(this.taskListId);
|
|
791
|
+
}
|
|
792
|
+
async setTaskListId(taskListId) {
|
|
793
|
+
await this.initialize();
|
|
794
|
+
const normalized = normalizeTaskListId(taskListId);
|
|
795
|
+
if (normalized === this.taskListId) {
|
|
796
|
+
return {
|
|
797
|
+
switched: false,
|
|
798
|
+
taskListId: this.taskListId,
|
|
799
|
+
storagePath: this.storagePath
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
await this.loadTaskList(normalized);
|
|
803
|
+
return {
|
|
804
|
+
switched: true,
|
|
805
|
+
taskListId: this.taskListId,
|
|
806
|
+
storagePath: this.storagePath
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
async createTask(input) {
|
|
810
|
+
await this.initialize();
|
|
811
|
+
const timestamp = now();
|
|
812
|
+
const status = input.status ?? "pending";
|
|
813
|
+
const task = {
|
|
814
|
+
id: randomUUID(),
|
|
815
|
+
title: input.title.trim(),
|
|
816
|
+
details: input.details,
|
|
817
|
+
status,
|
|
818
|
+
dependencies: dedupeStrings(input.dependencies),
|
|
819
|
+
blockedReason: status === "blocked" ? input.blockedReason ?? "Blocked without reason" : void 0,
|
|
820
|
+
metadata: input.metadata,
|
|
821
|
+
createdAt: timestamp,
|
|
822
|
+
updatedAt: timestamp,
|
|
823
|
+
completedAt: status === "completed" ? timestamp : void 0
|
|
824
|
+
};
|
|
825
|
+
this.tasks.set(task.id, task);
|
|
826
|
+
this.updatedAt = timestamp;
|
|
827
|
+
await this.persist();
|
|
828
|
+
return task;
|
|
829
|
+
}
|
|
830
|
+
async createTasks(inputs) {
|
|
831
|
+
const created = [];
|
|
832
|
+
for (const input of inputs) {
|
|
833
|
+
created.push(await this.createTask(input));
|
|
834
|
+
}
|
|
835
|
+
return created;
|
|
836
|
+
}
|
|
837
|
+
async listTasks(options) {
|
|
838
|
+
await this.initialize();
|
|
839
|
+
const statuses = options?.statuses?.length ? new Set(options.statuses) : null;
|
|
840
|
+
const includeCompleted = options?.includeCompleted ?? true;
|
|
841
|
+
let tasks = Array.from(this.tasks.values()).filter((task) => {
|
|
842
|
+
if (!includeCompleted && task.status === "completed") {
|
|
843
|
+
return false;
|
|
844
|
+
}
|
|
845
|
+
if (statuses && !statuses.has(task.status)) {
|
|
846
|
+
return false;
|
|
847
|
+
}
|
|
848
|
+
return true;
|
|
849
|
+
});
|
|
850
|
+
tasks = tasks.sort((a, b) => a.createdAt - b.createdAt);
|
|
851
|
+
if (options?.limit && options.limit > 0) {
|
|
852
|
+
tasks = tasks.slice(0, options.limit);
|
|
853
|
+
}
|
|
854
|
+
return tasks;
|
|
855
|
+
}
|
|
856
|
+
async getTask(id) {
|
|
857
|
+
await this.initialize();
|
|
858
|
+
return this.tasks.get(id) ?? null;
|
|
859
|
+
}
|
|
860
|
+
async updateTask(input) {
|
|
861
|
+
await this.initialize();
|
|
862
|
+
if (input.delete) {
|
|
863
|
+
const deleted = this.tasks.delete(input.id);
|
|
864
|
+
if (!deleted) {
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
this.updatedAt = now();
|
|
868
|
+
await this.persist();
|
|
869
|
+
return null;
|
|
870
|
+
}
|
|
871
|
+
const existing = this.tasks.get(input.id);
|
|
872
|
+
if (!existing) {
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
const timestamp = now();
|
|
876
|
+
const nextStatus = input.status ?? existing.status;
|
|
877
|
+
const next = {
|
|
878
|
+
...existing,
|
|
879
|
+
title: input.title !== void 0 ? input.title : existing.title,
|
|
880
|
+
details: input.details !== void 0 ? input.details : existing.details,
|
|
881
|
+
status: nextStatus,
|
|
882
|
+
dependencies: input.dependencies !== void 0 ? dedupeStrings(input.dependencies) : existing.dependencies,
|
|
883
|
+
metadata: input.metadata !== void 0 ? input.metadata : existing.metadata,
|
|
884
|
+
blockedReason: this.resolveBlockedReason(nextStatus, input.blockedReason, existing.blockedReason),
|
|
885
|
+
updatedAt: timestamp,
|
|
886
|
+
completedAt: nextStatus === "completed" ? existing.completedAt ?? timestamp : void 0
|
|
887
|
+
};
|
|
888
|
+
this.tasks.set(input.id, next);
|
|
889
|
+
this.updatedAt = timestamp;
|
|
890
|
+
await this.persist();
|
|
891
|
+
return next;
|
|
892
|
+
}
|
|
893
|
+
async snapshot(options) {
|
|
894
|
+
const tasks = await this.listTasks(options);
|
|
895
|
+
return {
|
|
896
|
+
taskListId: this.taskListId,
|
|
897
|
+
storagePath: this.storagePath,
|
|
898
|
+
createdAt: this.createdAt,
|
|
899
|
+
updatedAt: this.updatedAt,
|
|
900
|
+
total: tasks.length,
|
|
901
|
+
tasks
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
resolveBlockedReason(status, blockedReasonInput, previous) {
|
|
905
|
+
if (status !== "blocked") {
|
|
906
|
+
return void 0;
|
|
907
|
+
}
|
|
908
|
+
if (blockedReasonInput !== void 0) {
|
|
909
|
+
return blockedReasonInput || "Blocked without reason";
|
|
910
|
+
}
|
|
911
|
+
return previous ?? "Blocked without reason";
|
|
912
|
+
}
|
|
913
|
+
async loadTaskList(taskListId) {
|
|
914
|
+
const normalized = normalizeTaskListId(taskListId);
|
|
915
|
+
this.taskListId = normalized;
|
|
916
|
+
this.storagePath = path2.join(this.storageDir, `${normalized}.json`);
|
|
917
|
+
await fs.mkdir(this.storageDir, { recursive: true });
|
|
918
|
+
try {
|
|
919
|
+
const raw = await fs.readFile(this.storagePath, "utf-8");
|
|
920
|
+
const parsed = JSON.parse(raw);
|
|
921
|
+
const parsedTasks = Array.isArray(parsed.tasks) ? parsed.tasks : [];
|
|
922
|
+
this.tasks = new Map(parsedTasks.filter((task) => !!task?.id).map((task) => [task.id, task]));
|
|
923
|
+
this.createdAt = typeof parsed.createdAt === "number" ? parsed.createdAt : now();
|
|
924
|
+
this.updatedAt = typeof parsed.updatedAt === "number" ? parsed.updatedAt : now();
|
|
925
|
+
} catch (error) {
|
|
926
|
+
if (error?.code !== "ENOENT") {
|
|
927
|
+
throw error;
|
|
928
|
+
}
|
|
929
|
+
const timestamp = now();
|
|
930
|
+
this.tasks = /* @__PURE__ */ new Map();
|
|
931
|
+
this.createdAt = timestamp;
|
|
932
|
+
this.updatedAt = timestamp;
|
|
933
|
+
await this.persist();
|
|
934
|
+
}
|
|
935
|
+
this.initialized = true;
|
|
936
|
+
}
|
|
937
|
+
async persist() {
|
|
938
|
+
const payload = {
|
|
939
|
+
taskListId: this.taskListId,
|
|
940
|
+
createdAt: this.createdAt,
|
|
941
|
+
updatedAt: this.updatedAt,
|
|
942
|
+
tasks: Array.from(this.tasks.values()).sort((a, b) => a.createdAt - b.createdAt)
|
|
943
|
+
};
|
|
944
|
+
await fs.writeFile(this.storagePath, JSON.stringify(payload, null, 2), "utf-8");
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
function buildTaskCreateTool(service) {
|
|
948
|
+
return {
|
|
949
|
+
name: "task_create",
|
|
950
|
+
description: "Create one or more tracked tasks for complex work. Use this when work has multiple steps, dependencies, or blockers.",
|
|
951
|
+
inputSchema: TASK_CREATE_INPUT_SCHEMA,
|
|
952
|
+
execute: async ({ tasks, title, details, status, dependencies, blockedReason, metadata }) => {
|
|
953
|
+
const items = tasks?.length ? tasks : [{ title, details, status, dependencies, blockedReason, metadata }];
|
|
954
|
+
const created = await service.createTasks(items);
|
|
955
|
+
return {
|
|
956
|
+
taskListId: service.taskListId,
|
|
957
|
+
storagePath: service.storagePath,
|
|
958
|
+
createdCount: created.length,
|
|
959
|
+
tasks: created
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
function buildTaskGetTool(service) {
|
|
965
|
+
return {
|
|
966
|
+
name: "task_get",
|
|
967
|
+
description: "Get full details for a single task by task ID.",
|
|
968
|
+
inputSchema: TASK_GET_INPUT_SCHEMA,
|
|
969
|
+
execute: async ({ id }) => {
|
|
970
|
+
const task = await service.getTask(id);
|
|
971
|
+
if (!task) {
|
|
972
|
+
throw new Error(`Task not found: ${id}`);
|
|
973
|
+
}
|
|
974
|
+
return {
|
|
975
|
+
taskListId: service.taskListId,
|
|
976
|
+
storagePath: service.storagePath,
|
|
977
|
+
task
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function buildTaskListTool(service) {
|
|
983
|
+
return {
|
|
984
|
+
name: "task_list",
|
|
985
|
+
description: "List tasks and their current status. Use this to check progress before and after major changes.",
|
|
986
|
+
inputSchema: TASK_LIST_INPUT_SCHEMA,
|
|
987
|
+
execute: async ({ statuses, includeCompleted, limit }) => {
|
|
988
|
+
const snapshot = await service.snapshot({ statuses, includeCompleted, limit });
|
|
989
|
+
const completed = snapshot.tasks.filter((task) => task.status === "completed").length;
|
|
990
|
+
const inProgress = snapshot.tasks.filter((task) => task.status === "in_progress").length;
|
|
991
|
+
const pending = snapshot.tasks.filter((task) => task.status === "pending").length;
|
|
992
|
+
const blocked = snapshot.tasks.filter((task) => task.status === "blocked").length;
|
|
993
|
+
return {
|
|
994
|
+
...snapshot,
|
|
995
|
+
summary: {
|
|
996
|
+
total: snapshot.total,
|
|
997
|
+
completed,
|
|
998
|
+
inProgress,
|
|
999
|
+
pending,
|
|
1000
|
+
blocked
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
function buildTaskUpdateTool(service) {
|
|
1007
|
+
return {
|
|
1008
|
+
name: "task_update",
|
|
1009
|
+
description: "Update task fields, move status (pending/in_progress/completed/blocked), or delete tasks.",
|
|
1010
|
+
inputSchema: TASK_UPDATE_INPUT_SCHEMA,
|
|
1011
|
+
execute: async (input) => {
|
|
1012
|
+
const task = await service.updateTask(input);
|
|
1013
|
+
if (input.delete) {
|
|
1014
|
+
return {
|
|
1015
|
+
taskListId: service.taskListId,
|
|
1016
|
+
storagePath: service.storagePath,
|
|
1017
|
+
deleted: true,
|
|
1018
|
+
id: input.id
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
if (!task) {
|
|
1022
|
+
throw new Error(`Task not found: ${input.id}`);
|
|
1023
|
+
}
|
|
1024
|
+
return {
|
|
1025
|
+
taskListId: service.taskListId,
|
|
1026
|
+
storagePath: service.storagePath,
|
|
1027
|
+
deleted: false,
|
|
1028
|
+
task
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
var builtInTaskTrackingPlugin = {
|
|
1034
|
+
name: "pulse-coder-engine/built-in-task-tracking",
|
|
1035
|
+
version: "1.0.0",
|
|
1036
|
+
dependencies: ["pulse-coder-engine/built-in-skills"],
|
|
1037
|
+
async initialize(context) {
|
|
1038
|
+
const service = new TaskListService();
|
|
1039
|
+
await service.initialize();
|
|
1040
|
+
context.registerService("taskListService", service);
|
|
1041
|
+
context.registerService("taskTracking", service);
|
|
1042
|
+
const skillRegistry = context.getService("skillRegistry");
|
|
1043
|
+
if (skillRegistry) {
|
|
1044
|
+
const registration = skillRegistry.registerSkill(TASK_TRACKING_SKILL);
|
|
1045
|
+
context.logger.info("[TaskTracking] Registered built-in task tracking skill", registration);
|
|
1046
|
+
} else {
|
|
1047
|
+
context.logger.warn("[TaskTracking] skillRegistry service unavailable; skipped task tracking skill registration");
|
|
1048
|
+
}
|
|
1049
|
+
context.registerTools({
|
|
1050
|
+
task_create: buildTaskCreateTool(service),
|
|
1051
|
+
task_get: buildTaskGetTool(service),
|
|
1052
|
+
task_list: buildTaskListTool(service),
|
|
1053
|
+
task_update: buildTaskUpdateTool(service)
|
|
1054
|
+
});
|
|
1055
|
+
context.logger.info("[TaskTracking] Registered task tools", {
|
|
1056
|
+
taskListId: service.taskListId,
|
|
1057
|
+
storagePath: service.storagePath,
|
|
1058
|
+
skillRegistryAvailable: !!skillRegistry
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
|
|
621
1063
|
// src/built-in/sub-agent-plugin/index.ts
|
|
622
|
-
import { z as
|
|
623
|
-
import { promises as
|
|
624
|
-
import
|
|
1064
|
+
import { z as z11 } from "zod";
|
|
1065
|
+
import { promises as fs3 } from "fs";
|
|
1066
|
+
import path4 from "path";
|
|
625
1067
|
|
|
626
1068
|
// src/ai/index.ts
|
|
627
1069
|
import { generateText, streamText } from "ai";
|
|
@@ -653,8 +1095,8 @@ var CLARIFICATION_TIMEOUT = Number(process.env.CLARIFICATION_TIMEOUT ?? 3e5);
|
|
|
653
1095
|
var CLARIFICATION_ENABLED = process.env.CLARIFICATION_ENABLED !== "false";
|
|
654
1096
|
|
|
655
1097
|
// src/prompt/system.ts
|
|
656
|
-
import
|
|
657
|
-
import
|
|
1098
|
+
import fs2 from "fs";
|
|
1099
|
+
import path3 from "path";
|
|
658
1100
|
var DEFAULT_PROMPT = `
|
|
659
1101
|
You are Pulse Coder, the best coding agent on the planet.
|
|
660
1102
|
|
|
@@ -790,13 +1232,13 @@ var AGENTS_FILE_REGEX = /^agents\.md$/i;
|
|
|
790
1232
|
var loadAgentsPrompt = () => {
|
|
791
1233
|
try {
|
|
792
1234
|
const cwd = process.cwd();
|
|
793
|
-
const entries =
|
|
1235
|
+
const entries = fs2.readdirSync(cwd, { withFileTypes: true });
|
|
794
1236
|
const target = entries.find((entry) => entry.isFile() && AGENTS_FILE_REGEX.test(entry.name));
|
|
795
1237
|
if (!target) {
|
|
796
1238
|
return null;
|
|
797
1239
|
}
|
|
798
|
-
const filePath =
|
|
799
|
-
const content =
|
|
1240
|
+
const filePath = path3.join(cwd, target.name);
|
|
1241
|
+
const content = fs2.readFileSync(filePath, "utf8").trim();
|
|
800
1242
|
return content.length > 0 ? content : null;
|
|
801
1243
|
} catch {
|
|
802
1244
|
return null;
|
|
@@ -1092,6 +1534,9 @@ async function loop(context, options) {
|
|
|
1092
1534
|
}
|
|
1093
1535
|
}
|
|
1094
1536
|
if (finishReason === "stop") {
|
|
1537
|
+
if (!text) {
|
|
1538
|
+
continue;
|
|
1539
|
+
}
|
|
1095
1540
|
return text || "Task completed.";
|
|
1096
1541
|
}
|
|
1097
1542
|
if (finishReason === "length") {
|
|
@@ -1123,6 +1568,9 @@ async function loop(context, options) {
|
|
|
1123
1568
|
}
|
|
1124
1569
|
continue;
|
|
1125
1570
|
}
|
|
1571
|
+
if (!text) {
|
|
1572
|
+
continue;
|
|
1573
|
+
}
|
|
1126
1574
|
return text || "Task completed.";
|
|
1127
1575
|
} catch (error) {
|
|
1128
1576
|
if (options?.abortSignal?.aborted || error?.name === "AbortError") {
|
|
@@ -1150,8 +1598,8 @@ function sleep(ms) {
|
|
|
1150
1598
|
}
|
|
1151
1599
|
|
|
1152
1600
|
// src/tools/read.ts
|
|
1153
|
-
import
|
|
1154
|
-
import { readFileSync as readFileSync3, existsSync as
|
|
1601
|
+
import z3 from "zod";
|
|
1602
|
+
import { readFileSync as readFileSync3, existsSync as existsSync2, statSync } from "fs";
|
|
1155
1603
|
|
|
1156
1604
|
// src/tools/utils.ts
|
|
1157
1605
|
var truncateOutput = (output) => {
|
|
@@ -1171,13 +1619,13 @@ var truncateOutput = (output) => {
|
|
|
1171
1619
|
var ReadTool = {
|
|
1172
1620
|
name: "read",
|
|
1173
1621
|
description: "Read the contents of a file. Supports reading specific line ranges with offset and limit.",
|
|
1174
|
-
inputSchema:
|
|
1175
|
-
filePath:
|
|
1176
|
-
offset:
|
|
1177
|
-
limit:
|
|
1622
|
+
inputSchema: z3.object({
|
|
1623
|
+
filePath: z3.string().describe("The absolute path to the file to read"),
|
|
1624
|
+
offset: z3.number().optional().describe("The line number to start reading from (0-based). Only provide if the file is too large to read at once."),
|
|
1625
|
+
limit: z3.number().optional().describe("The number of lines to read. Only provide if the file is too large to read at once.")
|
|
1178
1626
|
}),
|
|
1179
1627
|
execute: async ({ filePath, offset, limit }) => {
|
|
1180
|
-
if (!
|
|
1628
|
+
if (!existsSync2(filePath)) {
|
|
1181
1629
|
throw new Error(`File does not exist: ${filePath}`);
|
|
1182
1630
|
}
|
|
1183
1631
|
const stats = statSync(filePath);
|
|
@@ -1211,20 +1659,20 @@ var ReadTool = {
|
|
|
1211
1659
|
};
|
|
1212
1660
|
|
|
1213
1661
|
// src/tools/write.ts
|
|
1214
|
-
import
|
|
1215
|
-
import { writeFileSync, mkdirSync, existsSync as
|
|
1662
|
+
import z4 from "zod";
|
|
1663
|
+
import { writeFileSync, mkdirSync, existsSync as existsSync3 } from "fs";
|
|
1216
1664
|
import { dirname } from "path";
|
|
1217
1665
|
var WriteTool = {
|
|
1218
1666
|
name: "write",
|
|
1219
1667
|
description: "Write contents to a file. Automatically creates parent directories if they do not exist. Will overwrite existing files.",
|
|
1220
|
-
inputSchema:
|
|
1221
|
-
filePath:
|
|
1222
|
-
content:
|
|
1668
|
+
inputSchema: z4.object({
|
|
1669
|
+
filePath: z4.string().describe("The absolute path to the file to write (must be absolute, not relative)"),
|
|
1670
|
+
content: z4.string().describe("The content to write to the file")
|
|
1223
1671
|
}),
|
|
1224
1672
|
execute: async ({ filePath, content }) => {
|
|
1225
|
-
const fileExists =
|
|
1673
|
+
const fileExists = existsSync3(filePath);
|
|
1226
1674
|
const dir = dirname(filePath);
|
|
1227
|
-
if (!
|
|
1675
|
+
if (!existsSync3(dir)) {
|
|
1228
1676
|
mkdirSync(dir, { recursive: true });
|
|
1229
1677
|
}
|
|
1230
1678
|
writeFileSync(filePath, content, "utf-8");
|
|
@@ -1238,16 +1686,16 @@ var WriteTool = {
|
|
|
1238
1686
|
};
|
|
1239
1687
|
|
|
1240
1688
|
// src/tools/edit.ts
|
|
1241
|
-
import
|
|
1689
|
+
import z5 from "zod";
|
|
1242
1690
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
1243
1691
|
var EditTool = {
|
|
1244
1692
|
name: "edit",
|
|
1245
1693
|
description: "Performs exact string replacements in files. Use this to edit existing files by replacing old_string with new_string.",
|
|
1246
|
-
inputSchema:
|
|
1247
|
-
filePath:
|
|
1248
|
-
oldString:
|
|
1249
|
-
newString:
|
|
1250
|
-
replaceAll:
|
|
1694
|
+
inputSchema: z5.object({
|
|
1695
|
+
filePath: z5.string().describe("The absolute path to the file to modify"),
|
|
1696
|
+
oldString: z5.string().describe("The exact text to replace (must match exactly)"),
|
|
1697
|
+
newString: z5.string().describe("The text to replace it with (must be different from old_string)"),
|
|
1698
|
+
replaceAll: z5.boolean().optional().default(false).describe("Replace all occurrences of old_string (default false)")
|
|
1251
1699
|
}),
|
|
1252
1700
|
execute: async ({ filePath, oldString, newString, replaceAll = false }) => {
|
|
1253
1701
|
if (oldString === newString) {
|
|
@@ -1294,27 +1742,27 @@ var EditTool = {
|
|
|
1294
1742
|
};
|
|
1295
1743
|
|
|
1296
1744
|
// src/tools/grep.ts
|
|
1297
|
-
import
|
|
1745
|
+
import z6 from "zod";
|
|
1298
1746
|
import { execSync } from "child_process";
|
|
1299
|
-
import { existsSync as
|
|
1747
|
+
import { existsSync as existsSync4 } from "fs";
|
|
1300
1748
|
var GrepTool = {
|
|
1301
1749
|
name: "grep",
|
|
1302
1750
|
description: "A powerful search tool built on ripgrep. Supports regex patterns, file filtering, and multiple output modes.",
|
|
1303
|
-
inputSchema:
|
|
1304
|
-
pattern:
|
|
1305
|
-
path:
|
|
1306
|
-
glob:
|
|
1307
|
-
type:
|
|
1308
|
-
outputMode:
|
|
1309
|
-
context:
|
|
1310
|
-
caseInsensitive:
|
|
1311
|
-
headLimit:
|
|
1312
|
-
offset:
|
|
1313
|
-
multiline:
|
|
1751
|
+
inputSchema: z6.object({
|
|
1752
|
+
pattern: z6.string().describe("The regular expression pattern to search for in file contents"),
|
|
1753
|
+
path: z6.string().optional().describe("File or directory to search in. Defaults to current working directory."),
|
|
1754
|
+
glob: z6.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}")'),
|
|
1755
|
+
type: z6.string().optional().describe("File type to search (e.g., js, py, rust, go, java, ts, tsx, json, md)"),
|
|
1756
|
+
outputMode: z6.enum(["content", "files_with_matches", "count"]).optional().default("files_with_matches").describe('Output mode: "content" shows matching lines, "files_with_matches" shows file paths, "count" shows match counts'),
|
|
1757
|
+
context: z6.number().optional().describe('Number of lines to show before and after each match (only with output_mode: "content")'),
|
|
1758
|
+
caseInsensitive: z6.boolean().optional().default(false).describe("Case insensitive search"),
|
|
1759
|
+
headLimit: z6.number().optional().default(0).describe("Limit output to first N lines/entries. 0 means unlimited."),
|
|
1760
|
+
offset: z6.number().optional().default(0).describe("Skip first N lines/entries before applying head_limit"),
|
|
1761
|
+
multiline: z6.boolean().optional().default(false).describe("Enable multiline mode where patterns can span lines")
|
|
1314
1762
|
}),
|
|
1315
1763
|
execute: async ({
|
|
1316
1764
|
pattern,
|
|
1317
|
-
path:
|
|
1765
|
+
path: path5 = ".",
|
|
1318
1766
|
glob,
|
|
1319
1767
|
type,
|
|
1320
1768
|
outputMode = "files_with_matches",
|
|
@@ -1349,11 +1797,11 @@ var GrepTool = {
|
|
|
1349
1797
|
if (type) {
|
|
1350
1798
|
args.push("--type", type);
|
|
1351
1799
|
}
|
|
1352
|
-
if (
|
|
1353
|
-
if (!
|
|
1354
|
-
throw new Error(`Path does not exist: ${
|
|
1800
|
+
if (path5 && path5 !== ".") {
|
|
1801
|
+
if (!existsSync4(path5)) {
|
|
1802
|
+
throw new Error(`Path does not exist: ${path5}`);
|
|
1355
1803
|
}
|
|
1356
|
-
args.push(
|
|
1804
|
+
args.push(path5);
|
|
1357
1805
|
}
|
|
1358
1806
|
let command = args.map((arg) => {
|
|
1359
1807
|
if (arg.includes(" ") || arg.includes("$") || arg.includes("*")) {
|
|
@@ -1400,31 +1848,31 @@ Command: ${command}`
|
|
|
1400
1848
|
};
|
|
1401
1849
|
|
|
1402
1850
|
// src/tools/ls.ts
|
|
1403
|
-
import
|
|
1851
|
+
import z7 from "zod";
|
|
1404
1852
|
import { readdirSync } from "fs";
|
|
1405
1853
|
var LsTool = {
|
|
1406
1854
|
name: "ls",
|
|
1407
1855
|
description: "List files and directories in a given path",
|
|
1408
|
-
inputSchema:
|
|
1409
|
-
path:
|
|
1856
|
+
inputSchema: z7.object({
|
|
1857
|
+
path: z7.string().optional().describe("The path to list files from (defaults to current directory)")
|
|
1410
1858
|
}),
|
|
1411
|
-
execute: async ({ path:
|
|
1412
|
-
const files = readdirSync(
|
|
1859
|
+
execute: async ({ path: path5 = "." }) => {
|
|
1860
|
+
const files = readdirSync(path5);
|
|
1413
1861
|
return { files };
|
|
1414
1862
|
}
|
|
1415
1863
|
};
|
|
1416
1864
|
|
|
1417
1865
|
// src/tools/bash.ts
|
|
1418
|
-
import
|
|
1866
|
+
import z8 from "zod";
|
|
1419
1867
|
import { execSync as execSync2 } from "child_process";
|
|
1420
1868
|
var BashTool = {
|
|
1421
1869
|
name: "bash",
|
|
1422
1870
|
description: "Execute a bash command and return the output. Supports timeout and working directory configuration.",
|
|
1423
|
-
inputSchema:
|
|
1424
|
-
command:
|
|
1425
|
-
timeout:
|
|
1426
|
-
cwd:
|
|
1427
|
-
description:
|
|
1871
|
+
inputSchema: z8.object({
|
|
1872
|
+
command: z8.string().describe("The bash command to execute"),
|
|
1873
|
+
timeout: z8.number().optional().describe("Optional timeout in milliseconds (max 600000ms / 10 minutes). Defaults to 120000ms (2 minutes)."),
|
|
1874
|
+
cwd: z8.string().optional().describe("Optional working directory for command execution. Defaults to current directory."),
|
|
1875
|
+
description: z8.string().optional().describe("Optional description of what this command does (for logging/debugging)")
|
|
1428
1876
|
}),
|
|
1429
1877
|
execute: async ({ command, timeout = 12e4, cwd, description }) => {
|
|
1430
1878
|
if (timeout && (timeout < 0 || timeout > 6e5)) {
|
|
@@ -1465,13 +1913,13 @@ ${stderr}`),
|
|
|
1465
1913
|
};
|
|
1466
1914
|
|
|
1467
1915
|
// src/tools/tavily.ts
|
|
1468
|
-
import
|
|
1916
|
+
import z9 from "zod";
|
|
1469
1917
|
var TavilyTool = {
|
|
1470
1918
|
name: "tavily",
|
|
1471
1919
|
description: "Search the web using Tavily API",
|
|
1472
|
-
inputSchema:
|
|
1473
|
-
query:
|
|
1474
|
-
maxResults:
|
|
1920
|
+
inputSchema: z9.object({
|
|
1921
|
+
query: z9.string().describe("The search query"),
|
|
1922
|
+
maxResults: z9.number().optional().default(5).describe("Maximum number of results to return")
|
|
1475
1923
|
}),
|
|
1476
1924
|
execute: async ({ query, maxResults = 5 }) => {
|
|
1477
1925
|
const apiKey = process.env.TAVILY_API_KEY;
|
|
@@ -1509,23 +1957,23 @@ var TavilyTool = {
|
|
|
1509
1957
|
};
|
|
1510
1958
|
|
|
1511
1959
|
// src/tools/clarify.ts
|
|
1512
|
-
import
|
|
1513
|
-
import { randomUUID } from "crypto";
|
|
1960
|
+
import z10 from "zod";
|
|
1961
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
1514
1962
|
var ClarifyTool = {
|
|
1515
1963
|
name: "clarify",
|
|
1516
1964
|
description: "Ask the user a clarifying question and wait for their response. Use this when you need information from the user to proceed with the task.",
|
|
1517
|
-
inputSchema:
|
|
1518
|
-
question:
|
|
1519
|
-
context:
|
|
1520
|
-
defaultAnswer:
|
|
1521
|
-
timeout:
|
|
1965
|
+
inputSchema: z10.object({
|
|
1966
|
+
question: z10.string().describe("The question to ask the user"),
|
|
1967
|
+
context: z10.string().optional().describe("Additional context to help the user answer"),
|
|
1968
|
+
defaultAnswer: z10.string().optional().describe("Default answer if user does not respond within timeout"),
|
|
1969
|
+
timeout: z10.number().optional().describe("Timeout in milliseconds (default: 5 minutes)")
|
|
1522
1970
|
}),
|
|
1523
1971
|
execute: async (input, toolContext) => {
|
|
1524
1972
|
if (!toolContext?.onClarificationRequest) {
|
|
1525
1973
|
throw new Error("Clarification is not supported in this context. The clarify tool requires a CLI interface with user interaction.");
|
|
1526
1974
|
}
|
|
1527
1975
|
const timeout = input.timeout ?? CLARIFICATION_TIMEOUT;
|
|
1528
|
-
const requestId =
|
|
1976
|
+
const requestId = randomUUID2();
|
|
1529
1977
|
try {
|
|
1530
1978
|
const timeoutPromise = new Promise((_, reject) => {
|
|
1531
1979
|
setTimeout(() => {
|
|
@@ -1580,8 +2028,8 @@ var ConfigLoader = class {
|
|
|
1580
2028
|
const fileInfos = [];
|
|
1581
2029
|
for (let configDir of configDirs) {
|
|
1582
2030
|
try {
|
|
1583
|
-
await
|
|
1584
|
-
const files = await
|
|
2031
|
+
await fs3.access(configDir);
|
|
2032
|
+
const files = await fs3.readdir(configDir);
|
|
1585
2033
|
fileInfos.push({ files, configDir });
|
|
1586
2034
|
} catch {
|
|
1587
2035
|
continue;
|
|
@@ -1598,7 +2046,7 @@ var ConfigLoader = class {
|
|
|
1598
2046
|
const files = fileInfo.files;
|
|
1599
2047
|
for (const file of files) {
|
|
1600
2048
|
if (file.endsWith(".md")) {
|
|
1601
|
-
const config = await this.parseConfig(
|
|
2049
|
+
const config = await this.parseConfig(path4.join(fileInfo.configDir, file));
|
|
1602
2050
|
if (config) configs.push(config);
|
|
1603
2051
|
}
|
|
1604
2052
|
}
|
|
@@ -1610,7 +2058,7 @@ var ConfigLoader = class {
|
|
|
1610
2058
|
}
|
|
1611
2059
|
async parseConfig(filePath) {
|
|
1612
2060
|
try {
|
|
1613
|
-
const content = await
|
|
2061
|
+
const content = await fs3.readFile(filePath, "utf-8");
|
|
1614
2062
|
const lines = content.split("\n");
|
|
1615
2063
|
let name = "";
|
|
1616
2064
|
let description = "";
|
|
@@ -1639,7 +2087,7 @@ var ConfigLoader = class {
|
|
|
1639
2087
|
}
|
|
1640
2088
|
}
|
|
1641
2089
|
if (!name) {
|
|
1642
|
-
name =
|
|
2090
|
+
name = path4.basename(filePath, ".md");
|
|
1643
2091
|
}
|
|
1644
2092
|
return {
|
|
1645
2093
|
name: name.trim(),
|
|
@@ -1690,9 +2138,9 @@ var SubAgentPlugin = class {
|
|
|
1690
2138
|
const toolName = `${config.name}_agent`;
|
|
1691
2139
|
const tool2 = {
|
|
1692
2140
|
description: config.description,
|
|
1693
|
-
inputSchema:
|
|
1694
|
-
task:
|
|
1695
|
-
context:
|
|
2141
|
+
inputSchema: z11.object({
|
|
2142
|
+
task: z11.string().describe("\u8981\u6267\u884C\u7684\u4EFB\u52A1\u63CF\u8FF0"),
|
|
2143
|
+
context: z11.any().optional().describe("\u4EFB\u52A1\u4E0A\u4E0B\u6587\u4FE1\u606F")
|
|
1696
2144
|
}),
|
|
1697
2145
|
execute: async ({ task, context: taskContext }) => {
|
|
1698
2146
|
const tools = { ...BuiltinToolsMap, ...context.getTools() };
|
|
@@ -1719,6 +2167,7 @@ var builtInPlugins = [
|
|
|
1719
2167
|
builtInMCPPlugin,
|
|
1720
2168
|
builtInSkillsPlugin,
|
|
1721
2169
|
builtInPlanModePlugin,
|
|
2170
|
+
builtInTaskTrackingPlugin,
|
|
1722
2171
|
new SubAgentPlugin()
|
|
1723
2172
|
];
|
|
1724
2173
|
var built_in_default = builtInPlugins;
|
|
@@ -1726,10 +2175,12 @@ export {
|
|
|
1726
2175
|
BuiltInPlanModeService,
|
|
1727
2176
|
BuiltInSkillRegistry,
|
|
1728
2177
|
SubAgentPlugin,
|
|
2178
|
+
TaskListService,
|
|
1729
2179
|
builtInMCPPlugin,
|
|
1730
2180
|
builtInPlanModePlugin,
|
|
1731
2181
|
builtInPlugins,
|
|
1732
2182
|
builtInSkillsPlugin,
|
|
2183
|
+
builtInTaskTrackingPlugin,
|
|
1733
2184
|
built_in_default as default
|
|
1734
2185
|
};
|
|
1735
2186
|
//# sourceMappingURL=index.js.map
|