@code-yeongyu/senpi 0.74.0 → 2026.5.13-3
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/CHANGELOG.md +17 -1
- package/README.md +4 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +3 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/anthropic-web-search/index.js +25 -14
- package/dist/core/extensions/builtin/anthropic-web-search/index.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.js +56 -7
- package/dist/core/extensions/builtin/gpt-apply-patch/preview-format.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts +7 -3
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +12 -4
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/runtime.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/runtime.js +7 -10
- package/dist/core/extensions/builtin/todotools/continuation/runtime.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/index.d.ts +2 -2
- package/dist/core/extensions/builtin/todotools/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/index.js +2 -2
- package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/settings.d.ts +6 -0
- package/dist/core/extensions/builtin/todotools/settings.d.ts.map +1 -0
- package/dist/core/extensions/builtin/todotools/settings.js +58 -0
- package/dist/core/extensions/builtin/todotools/settings.js.map +1 -0
- package/dist/core/extensions/builtin/todotools/system-messages.d.ts +34 -0
- package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -0
- package/dist/core/extensions/builtin/todotools/system-messages.js +82 -0
- package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -0
- package/dist/core/extensions/builtin/todotools/tools/todoread.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/tools/todoread.js +3 -1
- package/dist/core/extensions/builtin/todotools/tools/todoread.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/tools/todowrite.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/tools/todowrite.js +3 -1
- package/dist/core/extensions/builtin/todotools/tools/todowrite.js.map +1 -1
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +10 -3
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +8 -3
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/resource-loader.d.ts +8 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +168 -17
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -4
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +11 -3
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/favorite-models-selector.d.ts +10 -4
- package/dist/modes/interactive/components/favorite-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/favorite-models-selector.js +56 -78
- package/dist/modes/interactive/components/favorite-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/model-favorites.d.ts +10 -0
- package/dist/modes/interactive/components/model-favorites.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-favorites.js +53 -0
- package/dist/modes/interactive/components/model-favorites.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +9 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +52 -10
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +83 -94
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/models.md +26 -1
- package/docs/settings.md +14 -0
- package/package.json +7 -10
- package/dist/core/extensions/builtin/agent-system/agent-types.d.ts +0 -25
- package/dist/core/extensions/builtin/agent-system/agent-types.d.ts.map +0 -1
- package/dist/core/extensions/builtin/agent-system/agent-types.js +0 -38
- package/dist/core/extensions/builtin/agent-system/agent-types.js.map +0 -1
- package/dist/core/extensions/builtin/agent-system/builtin-agents.d.ts +0 -3
- package/dist/core/extensions/builtin/agent-system/builtin-agents.d.ts.map +0 -1
- package/dist/core/extensions/builtin/agent-system/builtin-agents.js +0 -32
- package/dist/core/extensions/builtin/agent-system/builtin-agents.js.map +0 -1
- package/dist/core/extensions/builtin/agent-system/index.d.ts +0 -3
- package/dist/core/extensions/builtin/agent-system/index.d.ts.map +0 -1
- package/dist/core/extensions/builtin/agent-system/index.js +0 -42
- package/dist/core/extensions/builtin/agent-system/index.js.map +0 -1
- package/dist/core/extensions/builtin/agent-system/loader.d.ts +0 -4
- package/dist/core/extensions/builtin/agent-system/loader.d.ts.map +0 -1
- package/dist/core/extensions/builtin/agent-system/loader.js +0 -59
- package/dist/core/extensions/builtin/agent-system/loader.js.map +0 -1
- package/dist/core/extensions/builtin/agent-system/permission.d.ts +0 -11
- package/dist/core/extensions/builtin/agent-system/permission.d.ts.map +0 -1
- package/dist/core/extensions/builtin/agent-system/permission.js +0 -24
- package/dist/core/extensions/builtin/agent-system/permission.js.map +0 -1
- package/dist/core/extensions/builtin/agent-system/registry.d.ts +0 -10
- package/dist/core/extensions/builtin/agent-system/registry.d.ts.map +0 -1
- package/dist/core/extensions/builtin/agent-system/registry.js +0 -50
- package/dist/core/extensions/builtin/agent-system/registry.js.map +0 -1
- package/dist/core/extensions/builtin/agent-system/types.d.ts +0 -9
- package/dist/core/extensions/builtin/agent-system/types.d.ts.map +0 -1
- package/dist/core/extensions/builtin/agent-system/types.js +0 -2
- package/dist/core/extensions/builtin/agent-system/types.js.map +0 -1
- package/dist/core/extensions/builtin/agent-system/wildcard.d.ts +0 -4
- package/dist/core/extensions/builtin/agent-system/wildcard.d.ts.map +0 -1
- package/dist/core/extensions/builtin/agent-system/wildcard.js +0 -58
- package/dist/core/extensions/builtin/agent-system/wildcard.js.map +0 -1
- package/dist/core/extensions/builtin/anthropic-web-fetch/index.d.ts +0 -7
- package/dist/core/extensions/builtin/anthropic-web-fetch/index.d.ts.map +0 -1
- package/dist/core/extensions/builtin/anthropic-web-fetch/index.js +0 -112
- package/dist/core/extensions/builtin/anthropic-web-fetch/index.js.map +0 -1
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
2
2
|
import type { BuildDynamicSystemPromptOptions } from "../../../dynamic-prompt/build.js";
|
|
3
|
-
import type
|
|
3
|
+
import { type PromptPresetName, type PromptPresetSettings } from "./settings.js";
|
|
4
4
|
export type { PromptPresetSettings } from "./settings.js";
|
|
5
5
|
type ResolvedPresetName = Exclude<PromptPresetName, "auto">;
|
|
6
|
+
type ModelWithPromptPresetMetadata = Pick<Model<Api>, "id" | "provider"> & {
|
|
7
|
+
name?: string;
|
|
8
|
+
promptPreset?: string;
|
|
9
|
+
};
|
|
6
10
|
export interface ResolvedPromptPreset {
|
|
7
11
|
name: ResolvedPresetName;
|
|
8
12
|
prompt: string;
|
|
9
13
|
}
|
|
10
|
-
export declare function resolvePresetName(model:
|
|
11
|
-
export declare function resolvePreset(model:
|
|
14
|
+
export declare function resolvePresetName(model: ModelWithPromptPresetMetadata, settings: PromptPresetSettings): ResolvedPresetName | undefined;
|
|
15
|
+
export declare function resolvePreset(model: ModelWithPromptPresetMetadata, settings: PromptPresetSettings, options?: Partial<BuildDynamicSystemPromptOptions>): ResolvedPromptPreset | undefined;
|
|
12
16
|
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAUxF,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAUxF,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAqB,MAAM,eAAe,CAAC;AAEpG,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,KAAK,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAC5D,KAAK,6BAA6B,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,UAAU,CAAC,GAAG;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CACf;AAiDD,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,6BAA6B,EACpC,QAAQ,EAAE,oBAAoB,GAC5B,kBAAkB,GAAG,SAAS,CAsBhC;AAoCD,wBAAgB,aAAa,CAC5B,KAAK,EAAE,6BAA6B,EACpC,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,CAAC,EAAE,OAAO,CAAC,+BAA+B,CAAC,GAChD,oBAAoB,GAAG,SAAS,CAMlC","sourcesContent":["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport type { BuildDynamicSystemPromptOptions } from \"../../../dynamic-prompt/build.js\";\nimport { buildClaudeOpus45Prompt } from \"./claude-opus-4-5.js\";\nimport { buildClaudeOpus46Prompt } from \"./claude-opus-4-6.js\";\nimport { buildClaudeOpus47Prompt } from \"./claude-opus-4-7.js\";\nimport { buildGpt52Prompt } from \"./gpt-5.2.js\";\nimport { buildGpt53CodexPrompt } from \"./gpt-5.3-codex.js\";\nimport { buildGpt54Prompt } from \"./gpt-5.4.js\";\nimport { buildGpt55Prompt } from \"./gpt-5.5.js\";\nimport { buildGpt5Prompt } from \"./gpt-5.js\";\nimport { buildKimiK26Prompt } from \"./kimi-k2-6.js\";\nimport { type PromptPresetName, type PromptPresetSettings, parsePromptPreset } from \"./settings.js\";\n\nexport type { PromptPresetSettings } from \"./settings.js\";\n\ntype ResolvedPresetName = Exclude<PromptPresetName, \"auto\">;\ntype ModelWithPromptPresetMetadata = Pick<Model<Api>, \"id\" | \"provider\"> & {\n\tname?: string;\n\tpromptPreset?: string;\n};\n\nexport interface ResolvedPromptPreset {\n\tname: ResolvedPresetName;\n\tprompt: string;\n}\n\nfunction normalizeModelId(modelId: string): string {\n\treturn modelId.toLowerCase().replace(/\\s+/g, \"-\");\n}\n\ntype Gpt5Version = \"gpt-5.2\" | \"gpt-5.3-codex\" | \"gpt-5.4\" | \"gpt-5.5\";\n\nfunction extractGpt5Version(modelId: string): Gpt5Version | undefined {\n\tconst normalized = normalizeModelId(modelId);\n\tif (normalized.includes(\"gpt-5.5\")) {\n\t\treturn \"gpt-5.5\";\n\t}\n\tif (normalized.includes(\"gpt-5.4\")) {\n\t\treturn \"gpt-5.4\";\n\t}\n\tif (normalized.includes(\"gpt-5.3\")) {\n\t\treturn \"gpt-5.3-codex\";\n\t}\n\tif (normalized.includes(\"gpt-5.2\")) {\n\t\treturn \"gpt-5.2\";\n\t}\n\treturn undefined;\n}\n\nfunction hasKimiK26Signal(value: string): boolean {\n\treturn /(?:^|[/@._-])kimi-k2(?:[._-]|p)6(?:$|[/@._-])/.test(normalizeModelId(value));\n}\n\nfunction isKimiK26Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasKimiK26Signal(model.id) || (model.name !== undefined && hasKimiK26Signal(model.name));\n}\n\ntype ClaudeOpusVersion = \"claude-opus-4-7\" | \"claude-opus-4-6\" | \"claude-opus-4-5\";\n\nfunction extractClaudeOpusVersion(modelId: string): ClaudeOpusVersion | undefined {\n\tconst normalized = normalizeModelId(modelId);\n\tif (normalized.includes(\"opus-4-7\")) {\n\t\treturn \"claude-opus-4-7\";\n\t}\n\tif (normalized.includes(\"opus-4-6\")) {\n\t\treturn \"claude-opus-4-6\";\n\t}\n\tif (normalized.includes(\"opus-4-5\") || normalized.includes(\"opus-4.5\")) {\n\t\treturn \"claude-opus-4-5\";\n\t}\n\treturn undefined;\n}\n\nexport function resolvePresetName(\n\tmodel: ModelWithPromptPresetMetadata,\n\tsettings: PromptPresetSettings,\n): ResolvedPresetName | undefined {\n\tif (settings.promptPreset !== \"auto\") {\n\t\treturn settings.promptPreset;\n\t}\n\n\tconst modelPromptPreset = parsePromptPreset(model.promptPreset);\n\tif (modelPromptPreset && modelPromptPreset !== \"auto\") {\n\t\treturn modelPromptPreset;\n\t}\n\n\tconst gpt5Version = extractGpt5Version(model.id);\n\tif (gpt5Version) {\n\t\treturn gpt5Version;\n\t}\n\tif (isKimiK26Model(model)) {\n\t\treturn \"kimi-k2-6\";\n\t}\n\tconst claudeVersion = extractClaudeOpusVersion(model.id);\n\tif (claudeVersion) {\n\t\treturn claudeVersion;\n\t}\n\treturn undefined;\n}\n\nfunction buildPreset(name: ResolvedPresetName, options: BuildDynamicSystemPromptOptions): ResolvedPromptPreset {\n\tswitch (name) {\n\t\tcase \"gpt-5.5\":\n\t\t\treturn { name, prompt: buildGpt55Prompt(options) };\n\t\tcase \"gpt-5.4\":\n\t\t\treturn { name, prompt: buildGpt54Prompt(options) };\n\t\tcase \"gpt-5.3-codex\":\n\t\t\treturn { name, prompt: buildGpt53CodexPrompt(options) };\n\t\tcase \"gpt-5.2\":\n\t\t\treturn { name, prompt: buildGpt52Prompt(options) };\n\t\tcase \"gpt-5\":\n\t\t\treturn { name, prompt: buildGpt5Prompt(options) };\n\t\tcase \"kimi-k2-6\":\n\t\t\treturn { name, prompt: buildKimiK26Prompt(options) };\n\t\tcase \"claude-opus-4-7\":\n\t\t\treturn { name, prompt: buildClaudeOpus47Prompt(options) };\n\t\tcase \"claude-opus-4-6\":\n\t\t\treturn { name, prompt: buildClaudeOpus46Prompt(options) };\n\t\tcase \"claude-opus-4-5\":\n\t\t\treturn { name, prompt: buildClaudeOpus45Prompt(options) };\n\t}\n}\n\nfunction withDefaults(options: Partial<BuildDynamicSystemPromptOptions> = {}): BuildDynamicSystemPromptOptions {\n\treturn {\n\t\tcwd: options.cwd ?? \"\",\n\t\tselectedTools: options.selectedTools ?? [],\n\t\ttoolSnippets: options.toolSnippets ?? {},\n\t\tpromptGuidelines: options.promptGuidelines ?? [],\n\t\tcontextFiles: options.contextFiles ?? [],\n\t\tskills: options.skills ?? [],\n\t};\n}\n\nexport function resolvePreset(\n\tmodel: ModelWithPromptPresetMetadata,\n\tsettings: PromptPresetSettings,\n\toptions?: Partial<BuildDynamicSystemPromptOptions>,\n): ResolvedPromptPreset | undefined {\n\tconst name = resolvePresetName(model, settings);\n\tif (!name) {\n\t\treturn undefined;\n\t}\n\treturn buildPreset(name, withDefaults(options));\n}\n"]}
|
|
@@ -7,8 +7,9 @@ import { buildGpt54Prompt } from "./gpt-5.4.js";
|
|
|
7
7
|
import { buildGpt55Prompt } from "./gpt-5.5.js";
|
|
8
8
|
import { buildGpt5Prompt } from "./gpt-5.js";
|
|
9
9
|
import { buildKimiK26Prompt } from "./kimi-k2-6.js";
|
|
10
|
+
import { parsePromptPreset } from "./settings.js";
|
|
10
11
|
function normalizeModelId(modelId) {
|
|
11
|
-
return modelId.toLowerCase();
|
|
12
|
+
return modelId.toLowerCase().replace(/\s+/g, "-");
|
|
12
13
|
}
|
|
13
14
|
function extractGpt5Version(modelId) {
|
|
14
15
|
const normalized = normalizeModelId(modelId);
|
|
@@ -26,8 +27,11 @@ function extractGpt5Version(modelId) {
|
|
|
26
27
|
}
|
|
27
28
|
return undefined;
|
|
28
29
|
}
|
|
29
|
-
function
|
|
30
|
-
return
|
|
30
|
+
function hasKimiK26Signal(value) {
|
|
31
|
+
return /(?:^|[/@._-])kimi-k2(?:[._-]|p)6(?:$|[/@._-])/.test(normalizeModelId(value));
|
|
32
|
+
}
|
|
33
|
+
function isKimiK26Model(model) {
|
|
34
|
+
return hasKimiK26Signal(model.id) || (model.name !== undefined && hasKimiK26Signal(model.name));
|
|
31
35
|
}
|
|
32
36
|
function extractClaudeOpusVersion(modelId) {
|
|
33
37
|
const normalized = normalizeModelId(modelId);
|
|
@@ -46,11 +50,15 @@ export function resolvePresetName(model, settings) {
|
|
|
46
50
|
if (settings.promptPreset !== "auto") {
|
|
47
51
|
return settings.promptPreset;
|
|
48
52
|
}
|
|
53
|
+
const modelPromptPreset = parsePromptPreset(model.promptPreset);
|
|
54
|
+
if (modelPromptPreset && modelPromptPreset !== "auto") {
|
|
55
|
+
return modelPromptPreset;
|
|
56
|
+
}
|
|
49
57
|
const gpt5Version = extractGpt5Version(model.id);
|
|
50
58
|
if (gpt5Version) {
|
|
51
59
|
return gpt5Version;
|
|
52
60
|
}
|
|
53
|
-
if (isKimiK26Model(model
|
|
61
|
+
if (isKimiK26Model(model)) {
|
|
54
62
|
return "kimi-k2-6";
|
|
55
63
|
}
|
|
56
64
|
const claudeVersion = extractClaudeOpusVersion(model.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/presets.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/presets.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport type { BuildDynamicSystemPromptOptions } from \"../../../dynamic-prompt/build.js\";\nimport { buildClaudeOpus45Prompt } from \"./claude-opus-4-5.js\";\nimport { buildClaudeOpus46Prompt } from \"./claude-opus-4-6.js\";\nimport { buildClaudeOpus47Prompt } from \"./claude-opus-4-7.js\";\nimport { buildGpt52Prompt } from \"./gpt-5.2.js\";\nimport { buildGpt53CodexPrompt } from \"./gpt-5.3-codex.js\";\nimport { buildGpt54Prompt } from \"./gpt-5.4.js\";\nimport { buildGpt55Prompt } from \"./gpt-5.5.js\";\nimport { buildGpt5Prompt } from \"./gpt-5.js\";\nimport { buildKimiK26Prompt } from \"./kimi-k2-6.js\";\nimport { type PromptPresetName, type PromptPresetSettings, parsePromptPreset } from \"./settings.js\";\n\nexport type { PromptPresetSettings } from \"./settings.js\";\n\ntype ResolvedPresetName = Exclude<PromptPresetName, \"auto\">;\ntype ModelWithPromptPresetMetadata = Pick<Model<Api>, \"id\" | \"provider\"> & {\n\tname?: string;\n\tpromptPreset?: string;\n};\n\nexport interface ResolvedPromptPreset {\n\tname: ResolvedPresetName;\n\tprompt: string;\n}\n\nfunction normalizeModelId(modelId: string): string {\n\treturn modelId.toLowerCase().replace(/\\s+/g, \"-\");\n}\n\ntype Gpt5Version = \"gpt-5.2\" | \"gpt-5.3-codex\" | \"gpt-5.4\" | \"gpt-5.5\";\n\nfunction extractGpt5Version(modelId: string): Gpt5Version | undefined {\n\tconst normalized = normalizeModelId(modelId);\n\tif (normalized.includes(\"gpt-5.5\")) {\n\t\treturn \"gpt-5.5\";\n\t}\n\tif (normalized.includes(\"gpt-5.4\")) {\n\t\treturn \"gpt-5.4\";\n\t}\n\tif (normalized.includes(\"gpt-5.3\")) {\n\t\treturn \"gpt-5.3-codex\";\n\t}\n\tif (normalized.includes(\"gpt-5.2\")) {\n\t\treturn \"gpt-5.2\";\n\t}\n\treturn undefined;\n}\n\nfunction hasKimiK26Signal(value: string): boolean {\n\treturn /(?:^|[/@._-])kimi-k2(?:[._-]|p)6(?:$|[/@._-])/.test(normalizeModelId(value));\n}\n\nfunction isKimiK26Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasKimiK26Signal(model.id) || (model.name !== undefined && hasKimiK26Signal(model.name));\n}\n\ntype ClaudeOpusVersion = \"claude-opus-4-7\" | \"claude-opus-4-6\" | \"claude-opus-4-5\";\n\nfunction extractClaudeOpusVersion(modelId: string): ClaudeOpusVersion | undefined {\n\tconst normalized = normalizeModelId(modelId);\n\tif (normalized.includes(\"opus-4-7\")) {\n\t\treturn \"claude-opus-4-7\";\n\t}\n\tif (normalized.includes(\"opus-4-6\")) {\n\t\treturn \"claude-opus-4-6\";\n\t}\n\tif (normalized.includes(\"opus-4-5\") || normalized.includes(\"opus-4.5\")) {\n\t\treturn \"claude-opus-4-5\";\n\t}\n\treturn undefined;\n}\n\nexport function resolvePresetName(\n\tmodel: ModelWithPromptPresetMetadata,\n\tsettings: PromptPresetSettings,\n): ResolvedPresetName | undefined {\n\tif (settings.promptPreset !== \"auto\") {\n\t\treturn settings.promptPreset;\n\t}\n\n\tconst modelPromptPreset = parsePromptPreset(model.promptPreset);\n\tif (modelPromptPreset && modelPromptPreset !== \"auto\") {\n\t\treturn modelPromptPreset;\n\t}\n\n\tconst gpt5Version = extractGpt5Version(model.id);\n\tif (gpt5Version) {\n\t\treturn gpt5Version;\n\t}\n\tif (isKimiK26Model(model)) {\n\t\treturn \"kimi-k2-6\";\n\t}\n\tconst claudeVersion = extractClaudeOpusVersion(model.id);\n\tif (claudeVersion) {\n\t\treturn claudeVersion;\n\t}\n\treturn undefined;\n}\n\nfunction buildPreset(name: ResolvedPresetName, options: BuildDynamicSystemPromptOptions): ResolvedPromptPreset {\n\tswitch (name) {\n\t\tcase \"gpt-5.5\":\n\t\t\treturn { name, prompt: buildGpt55Prompt(options) };\n\t\tcase \"gpt-5.4\":\n\t\t\treturn { name, prompt: buildGpt54Prompt(options) };\n\t\tcase \"gpt-5.3-codex\":\n\t\t\treturn { name, prompt: buildGpt53CodexPrompt(options) };\n\t\tcase \"gpt-5.2\":\n\t\t\treturn { name, prompt: buildGpt52Prompt(options) };\n\t\tcase \"gpt-5\":\n\t\t\treturn { name, prompt: buildGpt5Prompt(options) };\n\t\tcase \"kimi-k2-6\":\n\t\t\treturn { name, prompt: buildKimiK26Prompt(options) };\n\t\tcase \"claude-opus-4-7\":\n\t\t\treturn { name, prompt: buildClaudeOpus47Prompt(options) };\n\t\tcase \"claude-opus-4-6\":\n\t\t\treturn { name, prompt: buildClaudeOpus46Prompt(options) };\n\t\tcase \"claude-opus-4-5\":\n\t\t\treturn { name, prompt: buildClaudeOpus45Prompt(options) };\n\t}\n}\n\nfunction withDefaults(options: Partial<BuildDynamicSystemPromptOptions> = {}): BuildDynamicSystemPromptOptions {\n\treturn {\n\t\tcwd: options.cwd ?? \"\",\n\t\tselectedTools: options.selectedTools ?? [],\n\t\ttoolSnippets: options.toolSnippets ?? {},\n\t\tpromptGuidelines: options.promptGuidelines ?? [],\n\t\tcontextFiles: options.contextFiles ?? [],\n\t\tskills: options.skills ?? [],\n\t};\n}\n\nexport function resolvePreset(\n\tmodel: ModelWithPromptPresetMetadata,\n\tsettings: PromptPresetSettings,\n\toptions?: Partial<BuildDynamicSystemPromptOptions>,\n): ResolvedPromptPreset | undefined {\n\tconst name = resolvePresetName(model, settings);\n\tif (!name) {\n\t\treturn undefined;\n\t}\n\treturn buildPreset(name, withDefaults(options));\n}\n"]}
|
|
@@ -3,5 +3,6 @@ export type PromptPresetName = "auto" | "claude-opus-4-7" | "claude-opus-4-6" |
|
|
|
3
3
|
export interface PromptPresetSettings {
|
|
4
4
|
promptPreset: PromptPresetName;
|
|
5
5
|
}
|
|
6
|
+
export declare function parsePromptPreset(value: string | undefined): PromptPresetName | undefined;
|
|
6
7
|
export declare function loadPromptPresetSettings(settingsManager: SettingsManager): PromptPresetSettings;
|
|
7
8
|
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GACzB,MAAM,GACN,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,WAAW,GACX,OAAO,GACP,SAAS,GACT,eAAe,GACf,SAAS,GACT,SAAS,CAAC;AAEb,MAAM,WAAW,oBAAoB;IACpC,YAAY,EAAE,gBAAgB,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GACzB,MAAM,GACN,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,WAAW,GACX,OAAO,GACP,SAAS,GACT,eAAe,GACf,SAAS,GACT,SAAS,CAAC;AAEb,MAAM,WAAW,oBAAoB;IACpC,YAAY,EAAE,gBAAgB,CAAC;CAC/B;AAiBD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,CAKzF;AAED,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,eAAe,GAAG,oBAAoB,CAQ/F","sourcesContent":["import type { Settings, SettingsManager } from \"../../../settings-manager.js\";\n\nexport type PromptPresetName =\n\t| \"auto\"\n\t| \"claude-opus-4-7\"\n\t| \"claude-opus-4-6\"\n\t| \"claude-opus-4-5\"\n\t| \"kimi-k2-6\"\n\t| \"gpt-5\"\n\t| \"gpt-5.2\"\n\t| \"gpt-5.3-codex\"\n\t| \"gpt-5.4\"\n\t| \"gpt-5.5\";\n\nexport interface PromptPresetSettings {\n\tpromptPreset: PromptPresetName;\n}\n\ntype SettingsWithPromptPreset = Settings & { promptPreset?: string };\n\nconst VALID_PRESETS: ReadonlySet<string> = new Set<PromptPresetName>([\n\t\"auto\",\n\t\"claude-opus-4-7\",\n\t\"claude-opus-4-6\",\n\t\"claude-opus-4-5\",\n\t\"kimi-k2-6\",\n\t\"gpt-5\",\n\t\"gpt-5.2\",\n\t\"gpt-5.3-codex\",\n\t\"gpt-5.4\",\n\t\"gpt-5.5\",\n]);\n\nexport function parsePromptPreset(value: string | undefined): PromptPresetName | undefined {\n\tif (value && VALID_PRESETS.has(value)) {\n\t\treturn value as PromptPresetName;\n\t}\n\treturn undefined;\n}\n\nexport function loadPromptPresetSettings(settingsManager: SettingsManager): PromptPresetSettings {\n\tconst globalSettings = settingsManager.getGlobalSettings() as SettingsWithPromptPreset;\n\tconst projectSettings = settingsManager.getProjectSettings() as SettingsWithPromptPreset;\n\n\treturn {\n\t\tpromptPreset:\n\t\t\tparsePromptPreset(projectSettings.promptPreset) ?? parsePromptPreset(globalSettings.promptPreset) ?? \"auto\",\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/settings.ts"],"names":[],"mappings":"AAoBA,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAmB;IACpE,MAAM;IACN,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,WAAW;IACX,OAAO;IACP,SAAS;IACT,eAAe;IACf,SAAS;IACT,SAAS;CACT,CAAC,CAAC;AAEH,
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/settings.ts"],"names":[],"mappings":"AAoBA,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAmB;IACpE,MAAM;IACN,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,WAAW;IACX,OAAO;IACP,SAAS;IACT,eAAe;IACf,SAAS;IACT,SAAS;CACT,CAAC,CAAC;AAEH,MAAM,UAAU,iBAAiB,CAAC,KAAyB,EAAgC;IAC1F,IAAI,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,KAAyB,CAAC;IAClC,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,MAAM,UAAU,wBAAwB,CAAC,eAAgC,EAAwB;IAChG,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,EAA8B,CAAC;IACvF,MAAM,eAAe,GAAG,eAAe,CAAC,kBAAkB,EAA8B,CAAC;IAEzF,OAAO;QACN,YAAY,EACX,iBAAiB,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,iBAAiB,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,MAAM;KAC5G,CAAC;AAAA,CACF","sourcesContent":["import type { Settings, SettingsManager } from \"../../../settings-manager.js\";\n\nexport type PromptPresetName =\n\t| \"auto\"\n\t| \"claude-opus-4-7\"\n\t| \"claude-opus-4-6\"\n\t| \"claude-opus-4-5\"\n\t| \"kimi-k2-6\"\n\t| \"gpt-5\"\n\t| \"gpt-5.2\"\n\t| \"gpt-5.3-codex\"\n\t| \"gpt-5.4\"\n\t| \"gpt-5.5\";\n\nexport interface PromptPresetSettings {\n\tpromptPreset: PromptPresetName;\n}\n\ntype SettingsWithPromptPreset = Settings & { promptPreset?: string };\n\nconst VALID_PRESETS: ReadonlySet<string> = new Set<PromptPresetName>([\n\t\"auto\",\n\t\"claude-opus-4-7\",\n\t\"claude-opus-4-6\",\n\t\"claude-opus-4-5\",\n\t\"kimi-k2-6\",\n\t\"gpt-5\",\n\t\"gpt-5.2\",\n\t\"gpt-5.3-codex\",\n\t\"gpt-5.4\",\n\t\"gpt-5.5\",\n]);\n\nexport function parsePromptPreset(value: string | undefined): PromptPresetName | undefined {\n\tif (value && VALID_PRESETS.has(value)) {\n\t\treturn value as PromptPresetName;\n\t}\n\treturn undefined;\n}\n\nexport function loadPromptPresetSettings(settingsManager: SettingsManager): PromptPresetSettings {\n\tconst globalSettings = settingsManager.getGlobalSettings() as SettingsWithPromptPreset;\n\tconst projectSettings = settingsManager.getProjectSettings() as SettingsWithPromptPreset;\n\n\treturn {\n\t\tpromptPreset:\n\t\t\tparsePromptPreset(projectSettings.promptPreset) ?? parsePromptPreset(globalSettings.promptPreset) ?? \"auto\",\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAuC,MAAM,mBAAmB,CAAC;AAE3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAW5C,KAAK,gBAAgB,GAAG;IACvB,eAAe,EAAE,MAAM,QAAQ,EAAE,CAAC;CAClC,CAAC;AAGF,eAAO,MAAM,sBAAsB,KAAK,CAAC;AA0BzC,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEzE;AAqGD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAkGlF","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionContext, SessionStartEvent } from \"../../../types.js\";\nimport { readTodoSettings } from \"../settings.js\";\nimport type { TodoItem } from \"../state.js\";\nimport { emitTodoSystemMessageFailure, sendTodoUserMessage } from \"../system-messages.js\";\nimport { resolveContinuationConfig } from \"./config.js\";\nimport { buildContinuationPrompt, CONTINUATION_DIRECTIVE, countIncomplete } from \"./prompt.js\";\n\ntype ContinuationState = {\n\treEntryFlag: boolean;\n\tchainCount: number;\n\tpendingDispatchAbortController?: AbortController;\n};\n\ntype ContinuationDeps = {\n\tgetCurrentTodos: () => TodoItem[];\n};\n\nconst CLEAN_STOP_REASONS = new Set([\"stop\", \"toolUse\", \"endTurn\", \"end_turn\"]);\nexport const CONTINUATION_CHAIN_CAP = 10;\nconst IDLE_POLL_INTERVAL_MS = 50;\nconst IDLE_WAIT_TIMEOUT_MS = 10_000;\n\nfunction isAssistantMessage(message: unknown): message is AssistantMessage {\n\tif (!message || typeof message !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst role = (message as { role?: unknown }).role;\n\treturn role === \"assistant\";\n}\n\nfunction getLastAssistantStopReason(messages: unknown[]): string | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (!isAssistantMessage(message)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn message.stopReason;\n\t}\n\n\treturn undefined;\n}\n\nexport function isContinuationFollowUpPrompt(prompt: string): boolean {\n\treturn prompt.includes(CONTINUATION_DIRECTIVE);\n}\n\nexport function isCleanStopReason(stopReason: string | undefined): boolean {\n\treturn typeof stopReason === \"string\" && CLEAN_STOP_REASONS.has(stopReason);\n}\n\nfunction createInitialState(): ContinuationState {\n\treturn {\n\t\treEntryFlag: false,\n\t\tchainCount: 0,\n\t};\n}\n\nfunction abortPendingDispatch(state: ContinuationState): void {\n\tstate.pendingDispatchAbortController?.abort();\n\tstate.pendingDispatchAbortController = undefined;\n}\n\nfunction getSessionState(sessionStates: Map<string, ContinuationState>, sessionId: string): ContinuationState {\n\tconst existingState = sessionStates.get(sessionId);\n\tif (existingState) {\n\t\treturn existingState;\n\t}\n\n\tconst nextState = createInitialState();\n\tsessionStates.set(sessionId, nextState);\n\treturn nextState;\n}\n\nfunction getSessionId(ctx: ExtensionContext): string {\n\treturn ctx.sessionManager.getSessionId();\n}\n\nfunction isNonInteractiveContext(ctx: ExtensionContext): boolean {\n\treturn !ctx.hasUI;\n}\n\nfunction shouldResetForSessionStart(event: SessionStartEvent): boolean {\n\tconst reason = event.reason as string;\n\treturn reason === \"reload\" || reason === \"resume\" || reason === \"compact\";\n}\n\nfunction reportContinuationError(pi: ExtensionAPI, ctx: ExtensionContext, error: unknown, prompt?: string): void {\n\tconst message = error instanceof Error ? error.message : String(error);\n\temitTodoSystemMessageFailure(pi, {\n\t\troute: \"todotools.continuation\",\n\t\tsessionId: getSessionId(ctx),\n\t\tcontent: prompt ?? \"\",\n\t\terrorMessage: message,\n\t});\n\tpi.events.emit(\"todotools:continuation_error\", {\n\t\tsessionId: getSessionId(ctx),\n\t\tmessage,\n\t});\n\tif (ctx.hasUI) {\n\t\tctx.ui.notify(`Todo continuation failed: ${message}`, \"error\");\n\t\treturn;\n\t}\n\tprocess.stderr.write(`[todotools continuation] ${message}\\n`);\n}\n\nfunction wait(ms: number): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, ms);\n\t});\n}\n\nasync function dispatchContinuationWhenIdle(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tprompt: string,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tconst startedAt = Date.now();\n\n\tif (signal.aborted) {\n\t\treturn;\n\t}\n\n\twhile (Date.now() - startedAt < IDLE_WAIT_TIMEOUT_MS) {\n\t\tif (signal.aborted) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (ctx.isIdle()) {\n\t\t\tif (signal.aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendTodoUserMessage(pi, \"todotools.continuation\", prompt, {\n\t\t\t\tsessionId: getSessionId(ctx),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tawait wait(IDLE_POLL_INTERVAL_MS);\n\n\t\tif (signal.aborted) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tconsole.warn(\"[todotools continuation] Timed out waiting for idle state; skipping auto-dispatch.\");\n}\n\nexport function installContinuation(pi: ExtensionAPI, deps: ContinuationDeps): void {\n\tconst sessionStates = new Map<string, ContinuationState>();\n\n\tpi.registerFlag(\"disable-todo-continuation\", {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable todo continuation — automatic follow-up when incomplete todos remain in the list\",\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tconst sessionState = getSessionState(sessionStates, getSessionId(ctx));\n\t\tsessionState.reEntryFlag = false;\n\t\tif (!isContinuationFollowUpPrompt(event.prompt)) {\n\t\t\tsessionState.chainCount = 0;\n\t\t\tabortPendingDispatch(sessionState);\n\t\t}\n\t});\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tif (!shouldResetForSessionStart(event)) {\n\t\t\treturn;\n\t\t}\n\t\tconst sessionId = getSessionId(ctx);\n\t\tconst existingState = sessionStates.get(sessionId);\n\t\tif (existingState) {\n\t\t\tabortPendingDispatch(existingState);\n\t\t}\n\t\tsessionStates.set(sessionId, createInitialState());\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tconst sessionId = getSessionId(ctx);\n\t\tconst existingState = sessionStates.get(sessionId);\n\t\tif (existingState) {\n\t\t\tabortPendingDispatch(existingState);\n\t\t}\n\t\tsessionStates.delete(sessionId);\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\ttry {\n\t\t\tif (isNonInteractiveContext(ctx)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst stopReason = getLastAssistantStopReason(event.messages);\n\t\t\tif (!isCleanStopReason(stopReason)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst settings = readTodoSettings(ctx.cwd);\n\t\t\tconst config = resolveContinuationConfig({\n\t\t\t\tglobalSettings: settings.globalSettings,\n\t\t\t\tprojectSettings: settings.projectSettings,\n\t\t\t\tcliFlag: pi.getFlag(\"disable-todo-continuation\"),\n\t\t\t});\n\t\t\tif (!config.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst todos = deps.getCurrentTodos();\n\t\t\tif (countIncomplete(todos) === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sessionId = getSessionId(ctx);\n\t\t\tconst sessionState = getSessionState(sessionStates, sessionId);\n\t\t\tif (sessionState.reEntryFlag) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (sessionState.chainCount >= CONTINUATION_CHAIN_CAP) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prompt = buildContinuationPrompt(todos);\n\t\t\tabortPendingDispatch(sessionState);\n\t\t\tconst pendingDispatchAbortController = new AbortController();\n\t\t\tsessionState.pendingDispatchAbortController = pendingDispatchAbortController;\n\t\t\tsessionState.reEntryFlag = true;\n\t\t\tsessionState.chainCount += 1;\n\t\t\tsetTimeout(() => {\n\t\t\t\tvoid (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait dispatchContinuationWhenIdle(pi, ctx, prompt, pendingDispatchAbortController.signal);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treportContinuationError(pi, ctx, error, prompt);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tconst currentState = sessionStates.get(sessionId);\n\t\t\t\t\t\tif (currentState?.pendingDispatchAbortController === pendingDispatchAbortController) {\n\t\t\t\t\t\t\tcurrentState.pendingDispatchAbortController = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}, 0);\n\t\t} catch (error) {\n\t\t\treportContinuationError(pi, ctx, error);\n\t\t}\n\t});\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { readTodoSettings } from "../settings.js";
|
|
2
|
+
import { emitTodoSystemMessageFailure, sendTodoUserMessage } from "../system-messages.js";
|
|
3
3
|
import { resolveContinuationConfig } from "./config.js";
|
|
4
4
|
import { buildContinuationPrompt, CONTINUATION_DIRECTIVE, countIncomplete } from "./prompt.js";
|
|
5
5
|
const CLEAN_STOP_REASONS = new Set(["stop", "toolUse", "endTurn", "end_turn"]);
|
|
@@ -52,8 +52,6 @@ function getSessionId(ctx) {
|
|
|
52
52
|
return ctx.sessionManager.getSessionId();
|
|
53
53
|
}
|
|
54
54
|
function isNonInteractiveContext(ctx) {
|
|
55
|
-
// ExtensionContext does not expose a dedicated mode flag. The documented
|
|
56
|
-
// signal for print/RPC mode is `hasUI === false`.
|
|
57
55
|
return !ctx.hasUI;
|
|
58
56
|
}
|
|
59
57
|
function shouldResetForSessionStart(event) {
|
|
@@ -62,10 +60,9 @@ function shouldResetForSessionStart(event) {
|
|
|
62
60
|
}
|
|
63
61
|
function reportContinuationError(pi, ctx, error, prompt) {
|
|
64
62
|
const message = error instanceof Error ? error.message : String(error);
|
|
65
|
-
|
|
63
|
+
emitTodoSystemMessageFailure(pi, {
|
|
66
64
|
route: "todotools.continuation",
|
|
67
65
|
sessionId: getSessionId(ctx),
|
|
68
|
-
kind: "user_message",
|
|
69
66
|
content: prompt ?? "",
|
|
70
67
|
errorMessage: message,
|
|
71
68
|
});
|
|
@@ -97,7 +94,7 @@ async function dispatchContinuationWhenIdle(pi, ctx, prompt, signal) {
|
|
|
97
94
|
if (signal.aborted) {
|
|
98
95
|
return;
|
|
99
96
|
}
|
|
100
|
-
|
|
97
|
+
sendTodoUserMessage(pi, "todotools.continuation", prompt, {
|
|
101
98
|
sessionId: getSessionId(ctx),
|
|
102
99
|
});
|
|
103
100
|
return;
|
|
@@ -152,10 +149,10 @@ export function installContinuation(pi, deps) {
|
|
|
152
149
|
if (!isCleanStopReason(stopReason)) {
|
|
153
150
|
return;
|
|
154
151
|
}
|
|
155
|
-
const
|
|
152
|
+
const settings = readTodoSettings(ctx.cwd);
|
|
156
153
|
const config = resolveContinuationConfig({
|
|
157
|
-
globalSettings:
|
|
158
|
-
projectSettings:
|
|
154
|
+
globalSettings: settings.globalSettings,
|
|
155
|
+
projectSettings: settings.projectSettings,
|
|
159
156
|
cliFlag: pi.getFlag("disable-todo-continuation"),
|
|
160
157
|
});
|
|
161
158
|
if (!config.enabled) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport { SettingsManager } from \"../../../../settings-manager.js\";\nimport type { ExtensionAPI, ExtensionContext, SessionStartEvent } from \"../../../types.js\";\nimport { emitBuiltinSystemMessageFailure, sendBuiltinUserMessage } from \"../../system-messages.js\";\nimport type { TodoItem } from \"../state.js\";\nimport { resolveContinuationConfig } from \"./config.js\";\nimport { buildContinuationPrompt, CONTINUATION_DIRECTIVE, countIncomplete } from \"./prompt.js\";\n\ntype ContinuationState = {\n\treEntryFlag: boolean;\n\tchainCount: number;\n\tpendingDispatchAbortController?: AbortController;\n};\n\ntype ContinuationDeps = {\n\tgetCurrentTodos: () => TodoItem[];\n};\n\nconst CLEAN_STOP_REASONS = new Set([\"stop\", \"toolUse\", \"endTurn\", \"end_turn\"]);\nexport const CONTINUATION_CHAIN_CAP = 10;\nconst IDLE_POLL_INTERVAL_MS = 50;\nconst IDLE_WAIT_TIMEOUT_MS = 10_000;\n\nfunction isAssistantMessage(message: unknown): message is AssistantMessage {\n\tif (!message || typeof message !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst role = (message as { role?: unknown }).role;\n\treturn role === \"assistant\";\n}\n\nfunction getLastAssistantStopReason(messages: unknown[]): string | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (!isAssistantMessage(message)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn message.stopReason;\n\t}\n\n\treturn undefined;\n}\n\nexport function isContinuationFollowUpPrompt(prompt: string): boolean {\n\treturn prompt.includes(CONTINUATION_DIRECTIVE);\n}\n\nexport function isCleanStopReason(stopReason: string | undefined): boolean {\n\treturn typeof stopReason === \"string\" && CLEAN_STOP_REASONS.has(stopReason);\n}\n\nfunction createInitialState(): ContinuationState {\n\treturn {\n\t\treEntryFlag: false,\n\t\tchainCount: 0,\n\t};\n}\n\nfunction abortPendingDispatch(state: ContinuationState): void {\n\tstate.pendingDispatchAbortController?.abort();\n\tstate.pendingDispatchAbortController = undefined;\n}\n\nfunction getSessionState(sessionStates: Map<string, ContinuationState>, sessionId: string): ContinuationState {\n\tconst existingState = sessionStates.get(sessionId);\n\tif (existingState) {\n\t\treturn existingState;\n\t}\n\n\tconst nextState = createInitialState();\n\tsessionStates.set(sessionId, nextState);\n\treturn nextState;\n}\n\nfunction getSessionId(ctx: ExtensionContext): string {\n\treturn ctx.sessionManager.getSessionId();\n}\n\nfunction isNonInteractiveContext(ctx: ExtensionContext): boolean {\n\t// ExtensionContext does not expose a dedicated mode flag. The documented\n\t// signal for print/RPC mode is `hasUI === false`.\n\treturn !ctx.hasUI;\n}\n\nfunction shouldResetForSessionStart(event: SessionStartEvent): boolean {\n\tconst reason = event.reason as string;\n\treturn reason === \"reload\" || reason === \"resume\" || reason === \"compact\";\n}\n\nfunction reportContinuationError(pi: ExtensionAPI, ctx: ExtensionContext, error: unknown, prompt?: string): void {\n\tconst message = error instanceof Error ? error.message : String(error);\n\temitBuiltinSystemMessageFailure(pi, {\n\t\troute: \"todotools.continuation\",\n\t\tsessionId: getSessionId(ctx),\n\t\tkind: \"user_message\",\n\t\tcontent: prompt ?? \"\",\n\t\terrorMessage: message,\n\t});\n\tpi.events.emit(\"todotools:continuation_error\", {\n\t\tsessionId: getSessionId(ctx),\n\t\tmessage,\n\t});\n\tif (ctx.hasUI) {\n\t\tctx.ui.notify(`Todo continuation failed: ${message}`, \"error\");\n\t\treturn;\n\t}\n\tprocess.stderr.write(`[todotools continuation] ${message}\\n`);\n}\n\nfunction wait(ms: number): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, ms);\n\t});\n}\n\nasync function dispatchContinuationWhenIdle(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tprompt: string,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tconst startedAt = Date.now();\n\n\tif (signal.aborted) {\n\t\treturn;\n\t}\n\n\twhile (Date.now() - startedAt < IDLE_WAIT_TIMEOUT_MS) {\n\t\tif (signal.aborted) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (ctx.isIdle()) {\n\t\t\tif (signal.aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendBuiltinUserMessage(pi, \"todotools.continuation\", prompt, {\n\t\t\t\tsessionId: getSessionId(ctx),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tawait wait(IDLE_POLL_INTERVAL_MS);\n\n\t\tif (signal.aborted) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tconsole.warn(\"[todotools continuation] Timed out waiting for idle state; skipping auto-dispatch.\");\n}\n\nexport function installContinuation(pi: ExtensionAPI, deps: ContinuationDeps): void {\n\tconst sessionStates = new Map<string, ContinuationState>();\n\n\tpi.registerFlag(\"disable-todo-continuation\", {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable todo continuation — automatic follow-up when incomplete todos remain in the list\",\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tconst sessionState = getSessionState(sessionStates, getSessionId(ctx));\n\t\tsessionState.reEntryFlag = false;\n\t\tif (!isContinuationFollowUpPrompt(event.prompt)) {\n\t\t\tsessionState.chainCount = 0;\n\t\t\tabortPendingDispatch(sessionState);\n\t\t}\n\t});\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tif (!shouldResetForSessionStart(event)) {\n\t\t\treturn;\n\t\t}\n\t\tconst sessionId = getSessionId(ctx);\n\t\tconst existingState = sessionStates.get(sessionId);\n\t\tif (existingState) {\n\t\t\tabortPendingDispatch(existingState);\n\t\t}\n\t\tsessionStates.set(sessionId, createInitialState());\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tconst sessionId = getSessionId(ctx);\n\t\tconst existingState = sessionStates.get(sessionId);\n\t\tif (existingState) {\n\t\t\tabortPendingDispatch(existingState);\n\t\t}\n\t\tsessionStates.delete(sessionId);\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\ttry {\n\t\t\tif (isNonInteractiveContext(ctx)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst stopReason = getLastAssistantStopReason(event.messages);\n\t\t\tif (!isCleanStopReason(stopReason)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst settingsManager = SettingsManager.create(ctx.cwd);\n\t\t\tconst config = resolveContinuationConfig({\n\t\t\t\tglobalSettings: settingsManager.getGlobalSettings() as Record<string, unknown>,\n\t\t\t\tprojectSettings: settingsManager.getProjectSettings() as Record<string, unknown>,\n\t\t\t\tcliFlag: pi.getFlag(\"disable-todo-continuation\"),\n\t\t\t});\n\t\t\tif (!config.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst todos = deps.getCurrentTodos();\n\t\t\tif (countIncomplete(todos) === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sessionId = getSessionId(ctx);\n\t\t\tconst sessionState = getSessionState(sessionStates, sessionId);\n\t\t\tif (sessionState.reEntryFlag) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (sessionState.chainCount >= CONTINUATION_CHAIN_CAP) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prompt = buildContinuationPrompt(todos);\n\t\t\tabortPendingDispatch(sessionState);\n\t\t\tconst pendingDispatchAbortController = new AbortController();\n\t\t\tsessionState.pendingDispatchAbortController = pendingDispatchAbortController;\n\t\t\tsessionState.reEntryFlag = true;\n\t\t\tsessionState.chainCount += 1;\n\t\t\tsetTimeout(() => {\n\t\t\t\tvoid (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait dispatchContinuationWhenIdle(pi, ctx, prompt, pendingDispatchAbortController.signal);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treportContinuationError(pi, ctx, error, prompt);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tconst currentState = sessionStates.get(sessionId);\n\t\t\t\t\t\tif (currentState?.pendingDispatchAbortController === pendingDispatchAbortController) {\n\t\t\t\t\t\t\tcurrentState.pendingDispatchAbortController = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}, 0);\n\t\t} catch (error) {\n\t\t\treportContinuationError(pi, ctx, error);\n\t\t}\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionContext, SessionStartEvent } from \"../../../types.js\";\nimport { readTodoSettings } from \"../settings.js\";\nimport type { TodoItem } from \"../state.js\";\nimport { emitTodoSystemMessageFailure, sendTodoUserMessage } from \"../system-messages.js\";\nimport { resolveContinuationConfig } from \"./config.js\";\nimport { buildContinuationPrompt, CONTINUATION_DIRECTIVE, countIncomplete } from \"./prompt.js\";\n\ntype ContinuationState = {\n\treEntryFlag: boolean;\n\tchainCount: number;\n\tpendingDispatchAbortController?: AbortController;\n};\n\ntype ContinuationDeps = {\n\tgetCurrentTodos: () => TodoItem[];\n};\n\nconst CLEAN_STOP_REASONS = new Set([\"stop\", \"toolUse\", \"endTurn\", \"end_turn\"]);\nexport const CONTINUATION_CHAIN_CAP = 10;\nconst IDLE_POLL_INTERVAL_MS = 50;\nconst IDLE_WAIT_TIMEOUT_MS = 10_000;\n\nfunction isAssistantMessage(message: unknown): message is AssistantMessage {\n\tif (!message || typeof message !== \"object\") {\n\t\treturn false;\n\t}\n\n\tconst role = (message as { role?: unknown }).role;\n\treturn role === \"assistant\";\n}\n\nfunction getLastAssistantStopReason(messages: unknown[]): string | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (!isAssistantMessage(message)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn message.stopReason;\n\t}\n\n\treturn undefined;\n}\n\nexport function isContinuationFollowUpPrompt(prompt: string): boolean {\n\treturn prompt.includes(CONTINUATION_DIRECTIVE);\n}\n\nexport function isCleanStopReason(stopReason: string | undefined): boolean {\n\treturn typeof stopReason === \"string\" && CLEAN_STOP_REASONS.has(stopReason);\n}\n\nfunction createInitialState(): ContinuationState {\n\treturn {\n\t\treEntryFlag: false,\n\t\tchainCount: 0,\n\t};\n}\n\nfunction abortPendingDispatch(state: ContinuationState): void {\n\tstate.pendingDispatchAbortController?.abort();\n\tstate.pendingDispatchAbortController = undefined;\n}\n\nfunction getSessionState(sessionStates: Map<string, ContinuationState>, sessionId: string): ContinuationState {\n\tconst existingState = sessionStates.get(sessionId);\n\tif (existingState) {\n\t\treturn existingState;\n\t}\n\n\tconst nextState = createInitialState();\n\tsessionStates.set(sessionId, nextState);\n\treturn nextState;\n}\n\nfunction getSessionId(ctx: ExtensionContext): string {\n\treturn ctx.sessionManager.getSessionId();\n}\n\nfunction isNonInteractiveContext(ctx: ExtensionContext): boolean {\n\treturn !ctx.hasUI;\n}\n\nfunction shouldResetForSessionStart(event: SessionStartEvent): boolean {\n\tconst reason = event.reason as string;\n\treturn reason === \"reload\" || reason === \"resume\" || reason === \"compact\";\n}\n\nfunction reportContinuationError(pi: ExtensionAPI, ctx: ExtensionContext, error: unknown, prompt?: string): void {\n\tconst message = error instanceof Error ? error.message : String(error);\n\temitTodoSystemMessageFailure(pi, {\n\t\troute: \"todotools.continuation\",\n\t\tsessionId: getSessionId(ctx),\n\t\tcontent: prompt ?? \"\",\n\t\terrorMessage: message,\n\t});\n\tpi.events.emit(\"todotools:continuation_error\", {\n\t\tsessionId: getSessionId(ctx),\n\t\tmessage,\n\t});\n\tif (ctx.hasUI) {\n\t\tctx.ui.notify(`Todo continuation failed: ${message}`, \"error\");\n\t\treturn;\n\t}\n\tprocess.stderr.write(`[todotools continuation] ${message}\\n`);\n}\n\nfunction wait(ms: number): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, ms);\n\t});\n}\n\nasync function dispatchContinuationWhenIdle(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tprompt: string,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tconst startedAt = Date.now();\n\n\tif (signal.aborted) {\n\t\treturn;\n\t}\n\n\twhile (Date.now() - startedAt < IDLE_WAIT_TIMEOUT_MS) {\n\t\tif (signal.aborted) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (ctx.isIdle()) {\n\t\t\tif (signal.aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendTodoUserMessage(pi, \"todotools.continuation\", prompt, {\n\t\t\t\tsessionId: getSessionId(ctx),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tawait wait(IDLE_POLL_INTERVAL_MS);\n\n\t\tif (signal.aborted) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tconsole.warn(\"[todotools continuation] Timed out waiting for idle state; skipping auto-dispatch.\");\n}\n\nexport function installContinuation(pi: ExtensionAPI, deps: ContinuationDeps): void {\n\tconst sessionStates = new Map<string, ContinuationState>();\n\n\tpi.registerFlag(\"disable-todo-continuation\", {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable todo continuation — automatic follow-up when incomplete todos remain in the list\",\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tconst sessionState = getSessionState(sessionStates, getSessionId(ctx));\n\t\tsessionState.reEntryFlag = false;\n\t\tif (!isContinuationFollowUpPrompt(event.prompt)) {\n\t\t\tsessionState.chainCount = 0;\n\t\t\tabortPendingDispatch(sessionState);\n\t\t}\n\t});\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tif (!shouldResetForSessionStart(event)) {\n\t\t\treturn;\n\t\t}\n\t\tconst sessionId = getSessionId(ctx);\n\t\tconst existingState = sessionStates.get(sessionId);\n\t\tif (existingState) {\n\t\t\tabortPendingDispatch(existingState);\n\t\t}\n\t\tsessionStates.set(sessionId, createInitialState());\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tconst sessionId = getSessionId(ctx);\n\t\tconst existingState = sessionStates.get(sessionId);\n\t\tif (existingState) {\n\t\t\tabortPendingDispatch(existingState);\n\t\t}\n\t\tsessionStates.delete(sessionId);\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\ttry {\n\t\t\tif (isNonInteractiveContext(ctx)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst stopReason = getLastAssistantStopReason(event.messages);\n\t\t\tif (!isCleanStopReason(stopReason)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst settings = readTodoSettings(ctx.cwd);\n\t\t\tconst config = resolveContinuationConfig({\n\t\t\t\tglobalSettings: settings.globalSettings,\n\t\t\t\tprojectSettings: settings.projectSettings,\n\t\t\t\tcliFlag: pi.getFlag(\"disable-todo-continuation\"),\n\t\t\t});\n\t\t\tif (!config.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst todos = deps.getCurrentTodos();\n\t\t\tif (countIncomplete(todos) === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sessionId = getSessionId(ctx);\n\t\t\tconst sessionState = getSessionState(sessionStates, sessionId);\n\t\t\tif (sessionState.reEntryFlag) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (sessionState.chainCount >= CONTINUATION_CHAIN_CAP) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prompt = buildContinuationPrompt(todos);\n\t\t\tabortPendingDispatch(sessionState);\n\t\t\tconst pendingDispatchAbortController = new AbortController();\n\t\t\tsessionState.pendingDispatchAbortController = pendingDispatchAbortController;\n\t\t\tsessionState.reEntryFlag = true;\n\t\t\tsessionState.chainCount += 1;\n\t\t\tsetTimeout(() => {\n\t\t\t\tvoid (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait dispatchContinuationWhenIdle(pi, ctx, prompt, pendingDispatchAbortController.signal);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treportContinuationError(pi, ctx, error, prompt);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tconst currentState = sessionStates.get(sessionId);\n\t\t\t\t\t\tif (currentState?.pendingDispatchAbortController === pendingDispatchAbortController) {\n\t\t\t\t\t\t\tcurrentState.pendingDispatchAbortController = undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}, 0);\n\t\t} catch (error) {\n\t\t\treportContinuationError(pi, ctx, error);\n\t\t}\n\t});\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "../../types.js";
|
|
2
|
-
export default function
|
|
2
|
+
export default function todotoolsExtension(pi: ExtensionAPI): void;
|
|
3
3
|
export { TASK_MANAGEMENT_SECTION } from "./prompt.js";
|
|
4
|
-
export { getLatestTodosFromBranchEntries, getTodoMarker, getTodoResultLines, getTodoWidgetLines, isTodoItem, isTodoItemArray, sanitizeTodoText, TODO_STATE_ENTRY_TYPE, type TodoItem, } from "./state.js";
|
|
4
|
+
export { getLatestTodosFromBranchEntries, getTodoMarker, getTodoResultLines, getTodoWidgetLines, isIncompleteTodo, isTerminalTodoStatus, isTodoItem, isTodoItemArray, sanitizeTodoText, TODO_STATE_ENTRY_TYPE, type TodoItem, } from "./state.js";
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAWrE,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAoCjE;AAED,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACN,+BAA+B,EAC/B,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,QAAQ,GACb,MAAM,YAAY,CAAC","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.js\";\nimport { installContinuation } from \"./continuation/index.js\";\nimport { TASK_MANAGEMENT_SECTION } from \"./prompt.js\";\nimport { getLatestTodosFromBranchEntries, getTodoWidgetLines, type TodoItem } from \"./state.js\";\nimport { registerTodoReadTool } from \"./tools/todoread.js\";\nimport { registerTodoWriteTool } from \"./tools/todowrite.js\";\n\nfunction getLatestTodos(ctx: ExtensionContext): TodoItem[] {\n\treturn getLatestTodosFromBranchEntries(ctx.sessionManager.getBranch());\n}\n\nexport default function
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAWrE,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAoCjE;AAED,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACN,+BAA+B,EAC/B,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,QAAQ,GACb,MAAM,YAAY,CAAC","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.js\";\nimport { installContinuation } from \"./continuation/index.js\";\nimport { TASK_MANAGEMENT_SECTION } from \"./prompt.js\";\nimport { getLatestTodosFromBranchEntries, getTodoWidgetLines, type TodoItem } from \"./state.js\";\nimport { registerTodoReadTool } from \"./tools/todoread.js\";\nimport { registerTodoWriteTool } from \"./tools/todowrite.js\";\n\nfunction getLatestTodos(ctx: ExtensionContext): TodoItem[] {\n\treturn getLatestTodosFromBranchEntries(ctx.sessionManager.getBranch());\n}\n\nexport default function todotoolsExtension(pi: ExtensionAPI): void {\n\tlet currentTodos: TodoItem[] = [];\n\n\tconst getCurrentTodos = (): TodoItem[] => currentTodos;\n\n\tconst setCurrentTodos = (todos: TodoItem[]): void => {\n\t\tcurrentTodos = todos;\n\t};\n\n\tconst syncWidget = (ctx: ExtensionContext): void => {\n\t\tctx.ui.setWidget(\"todo-sidebar\", getTodoWidgetLines(currentTodos));\n\t};\n\n\tconst syncFromSession = (ctx: ExtensionContext): void => {\n\t\tcurrentTodos = getLatestTodos(ctx);\n\t\tsyncWidget(ctx);\n\t};\n\n\tinstallContinuation(pi, { getCurrentTodos });\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"session_tree\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n${TASK_MANAGEMENT_SECTION}`,\n\t\t};\n\t});\n\n\tregisterTodoWriteTool(pi, { getCurrentTodos, setCurrentTodos, syncWidget });\n\tregisterTodoReadTool(pi, getCurrentTodos);\n}\n\nexport { TASK_MANAGEMENT_SECTION } from \"./prompt.js\";\nexport {\n\tgetLatestTodosFromBranchEntries,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tgetTodoWidgetLines,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tisTodoItem,\n\tisTodoItemArray,\n\tsanitizeTodoText,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoItem,\n} from \"./state.js\";\n"]}
|
|
@@ -6,7 +6,7 @@ import { registerTodoWriteTool } from "./tools/todowrite.js";
|
|
|
6
6
|
function getLatestTodos(ctx) {
|
|
7
7
|
return getLatestTodosFromBranchEntries(ctx.sessionManager.getBranch());
|
|
8
8
|
}
|
|
9
|
-
export default function
|
|
9
|
+
export default function todotoolsExtension(pi) {
|
|
10
10
|
let currentTodos = [];
|
|
11
11
|
const getCurrentTodos = () => currentTodos;
|
|
12
12
|
const setCurrentTodos = (todos) => {
|
|
@@ -35,5 +35,5 @@ export default function todowriteExtension(pi) {
|
|
|
35
35
|
registerTodoReadTool(pi, getCurrentTodos);
|
|
36
36
|
}
|
|
37
37
|
export { TASK_MANAGEMENT_SECTION } from "./prompt.js";
|
|
38
|
-
export { getLatestTodosFromBranchEntries, getTodoMarker, getTodoResultLines, getTodoWidgetLines, isTodoItem, isTodoItemArray, sanitizeTodoText, TODO_STATE_ENTRY_TYPE, } from "./state.js";
|
|
38
|
+
export { getLatestTodosFromBranchEntries, getTodoMarker, getTodoResultLines, getTodoWidgetLines, isIncompleteTodo, isTerminalTodoStatus, isTodoItem, isTodoItemArray, sanitizeTodoText, TODO_STATE_ENTRY_TYPE, } from "./state.js";
|
|
39
39
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,+BAA+B,EAAE,kBAAkB,EAAiB,MAAM,YAAY,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,SAAS,cAAc,CAAC,GAAqB,EAAc;IAC1D,OAAO,+BAA+B,CAAC,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC;AAAA,CACvE;AAED,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAgB,EAAQ;IAClE,IAAI,YAAY,GAAe,EAAE,CAAC;IAElC,MAAM,eAAe,GAAG,GAAe,EAAE,CAAC,YAAY,CAAC;IAEvD,MAAM,eAAe,GAAG,CAAC,KAAiB,EAAQ,EAAE,CAAC;QACpD,YAAY,GAAG,KAAK,CAAC;IAAA,CACrB,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,GAAqB,EAAQ,EAAE,CAAC;QACnD,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IAAA,CACnE,CAAC;IAEF,MAAM,eAAe,GAAG,CAAC,GAAqB,EAAQ,EAAE,CAAC;QACxD,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACnC,UAAU,CAAC,GAAG,CAAC,CAAC;IAAA,CAChB,CAAC;IAEF,mBAAmB,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;IAE7C,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QAC7C,eAAe,CAAC,GAAG,CAAC,CAAC;IAAA,CACrB,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QAC5C,eAAe,CAAC,GAAG,CAAC,CAAC;IAAA,CACrB,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,oBAAoB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5C,OAAO;YACN,YAAY,EAAE,GAAG,KAAK,CAAC,YAAY,KAAK,uBAAuB,EAAE;SACjE,CAAC;IAAA,CACF,CAAC,CAAC;IAEH,qBAAqB,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5E,oBAAoB,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;AAAA,CAC1C;AAED,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACN,+BAA+B,EAC/B,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,qBAAqB,GAErB,MAAM,YAAY,CAAC","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.js\";\nimport { installContinuation } from \"./continuation/index.js\";\nimport { TASK_MANAGEMENT_SECTION } from \"./prompt.js\";\nimport { getLatestTodosFromBranchEntries, getTodoWidgetLines, type TodoItem } from \"./state.js\";\nimport { registerTodoReadTool } from \"./tools/todoread.js\";\nimport { registerTodoWriteTool } from \"./tools/todowrite.js\";\n\nfunction getLatestTodos(ctx: ExtensionContext): TodoItem[] {\n\treturn getLatestTodosFromBranchEntries(ctx.sessionManager.getBranch());\n}\n\nexport default function
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,+BAA+B,EAAE,kBAAkB,EAAiB,MAAM,YAAY,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,SAAS,cAAc,CAAC,GAAqB,EAAc;IAC1D,OAAO,+BAA+B,CAAC,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC;AAAA,CACvE;AAED,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAgB,EAAQ;IAClE,IAAI,YAAY,GAAe,EAAE,CAAC;IAElC,MAAM,eAAe,GAAG,GAAe,EAAE,CAAC,YAAY,CAAC;IAEvD,MAAM,eAAe,GAAG,CAAC,KAAiB,EAAQ,EAAE,CAAC;QACpD,YAAY,GAAG,KAAK,CAAC;IAAA,CACrB,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,GAAqB,EAAQ,EAAE,CAAC;QACnD,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IAAA,CACnE,CAAC;IAEF,MAAM,eAAe,GAAG,CAAC,GAAqB,EAAQ,EAAE,CAAC;QACxD,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACnC,UAAU,CAAC,GAAG,CAAC,CAAC;IAAA,CAChB,CAAC;IAEF,mBAAmB,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;IAE7C,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QAC7C,eAAe,CAAC,GAAG,CAAC,CAAC;IAAA,CACrB,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QAC5C,eAAe,CAAC,GAAG,CAAC,CAAC;IAAA,CACrB,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,oBAAoB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5C,OAAO;YACN,YAAY,EAAE,GAAG,KAAK,CAAC,YAAY,KAAK,uBAAuB,EAAE;SACjE,CAAC;IAAA,CACF,CAAC,CAAC;IAEH,qBAAqB,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5E,oBAAoB,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;AAAA,CAC1C;AAED,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACN,+BAA+B,EAC/B,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,qBAAqB,GAErB,MAAM,YAAY,CAAC","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.js\";\nimport { installContinuation } from \"./continuation/index.js\";\nimport { TASK_MANAGEMENT_SECTION } from \"./prompt.js\";\nimport { getLatestTodosFromBranchEntries, getTodoWidgetLines, type TodoItem } from \"./state.js\";\nimport { registerTodoReadTool } from \"./tools/todoread.js\";\nimport { registerTodoWriteTool } from \"./tools/todowrite.js\";\n\nfunction getLatestTodos(ctx: ExtensionContext): TodoItem[] {\n\treturn getLatestTodosFromBranchEntries(ctx.sessionManager.getBranch());\n}\n\nexport default function todotoolsExtension(pi: ExtensionAPI): void {\n\tlet currentTodos: TodoItem[] = [];\n\n\tconst getCurrentTodos = (): TodoItem[] => currentTodos;\n\n\tconst setCurrentTodos = (todos: TodoItem[]): void => {\n\t\tcurrentTodos = todos;\n\t};\n\n\tconst syncWidget = (ctx: ExtensionContext): void => {\n\t\tctx.ui.setWidget(\"todo-sidebar\", getTodoWidgetLines(currentTodos));\n\t};\n\n\tconst syncFromSession = (ctx: ExtensionContext): void => {\n\t\tcurrentTodos = getLatestTodos(ctx);\n\t\tsyncWidget(ctx);\n\t};\n\n\tinstallContinuation(pi, { getCurrentTodos });\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"session_tree\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n${TASK_MANAGEMENT_SECTION}`,\n\t\t};\n\t});\n\n\tregisterTodoWriteTool(pi, { getCurrentTodos, setCurrentTodos, syncWidget });\n\tregisterTodoReadTool(pi, getCurrentTodos);\n}\n\nexport { TASK_MANAGEMENT_SECTION } from \"./prompt.js\";\nexport {\n\tgetLatestTodosFromBranchEntries,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tgetTodoWidgetLines,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tisTodoItem,\n\tisTodoItemArray,\n\tsanitizeTodoText,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoItem,\n} from \"./state.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/settings.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAChC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAuDD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAK9D","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface TodoSettingsPair {\n\tglobalSettings: Record<string, unknown>;\n\tprojectSettings: Record<string, unknown>;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readJsonObject(path: string): Record<string, unknown> {\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(path, \"utf-8\"));\n\t\treturn isRecord(parsed) ? parsed : {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction mergeSettings(base: Record<string, unknown>, override: Record<string, unknown>): Record<string, unknown> {\n\tconst merged: Record<string, unknown> = { ...base };\n\tfor (const [key, value] of Object.entries(override)) {\n\t\tconst current = merged[key];\n\t\tif (isRecord(current) && isRecord(value)) {\n\t\t\tmerged[key] = mergeSettings(current, value);\n\t\t\tcontinue;\n\t\t}\n\t\tmerged[key] = value;\n\t}\n\treturn merged;\n}\n\nfunction unique(paths: string[]): string[] {\n\treturn [...new Set(paths)];\n}\n\nfunction getGlobalSettingsPaths(): string[] {\n\tconst paths: string[] = [];\n\tconst piAgentDir = process.env.PI_CODING_AGENT_DIR;\n\tconst senpiAgentDir = process.env.SENPI_CODING_AGENT_DIR;\n\tif (piAgentDir) paths.push(join(piAgentDir, \"settings.json\"));\n\tif (senpiAgentDir) paths.push(join(senpiAgentDir, \"settings.json\"));\n\tpaths.push(join(homedir(), \".pi\", \"agent\", \"settings.json\"));\n\tpaths.push(join(homedir(), \".senpi\", \"agent\", \"settings.json\"));\n\treturn unique(paths);\n}\n\nfunction getProjectSettingsPaths(cwd: string): string[] {\n\treturn [join(cwd, \".pi\", \"settings.json\"), join(cwd, \".senpi\", \"settings.json\")];\n}\n\nfunction readMergedSettings(paths: string[]): Record<string, unknown> {\n\treturn paths.reduce<Record<string, unknown>>((settings, path) => mergeSettings(settings, readJsonObject(path)), {});\n}\n\nexport function readTodoSettings(cwd: string): TodoSettingsPair {\n\treturn {\n\t\tglobalSettings: readMergedSettings(getGlobalSettingsPaths()),\n\t\tprojectSettings: readMergedSettings(getProjectSettingsPaths(cwd)),\n\t};\n}\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function readJsonObject(path) {
|
|
8
|
+
if (!existsSync(path)) {
|
|
9
|
+
return {};
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
13
|
+
return isRecord(parsed) ? parsed : {};
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function mergeSettings(base, override) {
|
|
20
|
+
const merged = { ...base };
|
|
21
|
+
for (const [key, value] of Object.entries(override)) {
|
|
22
|
+
const current = merged[key];
|
|
23
|
+
if (isRecord(current) && isRecord(value)) {
|
|
24
|
+
merged[key] = mergeSettings(current, value);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
merged[key] = value;
|
|
28
|
+
}
|
|
29
|
+
return merged;
|
|
30
|
+
}
|
|
31
|
+
function unique(paths) {
|
|
32
|
+
return [...new Set(paths)];
|
|
33
|
+
}
|
|
34
|
+
function getGlobalSettingsPaths() {
|
|
35
|
+
const paths = [];
|
|
36
|
+
const piAgentDir = process.env.PI_CODING_AGENT_DIR;
|
|
37
|
+
const senpiAgentDir = process.env.SENPI_CODING_AGENT_DIR;
|
|
38
|
+
if (piAgentDir)
|
|
39
|
+
paths.push(join(piAgentDir, "settings.json"));
|
|
40
|
+
if (senpiAgentDir)
|
|
41
|
+
paths.push(join(senpiAgentDir, "settings.json"));
|
|
42
|
+
paths.push(join(homedir(), ".pi", "agent", "settings.json"));
|
|
43
|
+
paths.push(join(homedir(), ".senpi", "agent", "settings.json"));
|
|
44
|
+
return unique(paths);
|
|
45
|
+
}
|
|
46
|
+
function getProjectSettingsPaths(cwd) {
|
|
47
|
+
return [join(cwd, ".pi", "settings.json"), join(cwd, ".senpi", "settings.json")];
|
|
48
|
+
}
|
|
49
|
+
function readMergedSettings(paths) {
|
|
50
|
+
return paths.reduce((settings, path) => mergeSettings(settings, readJsonObject(path)), {});
|
|
51
|
+
}
|
|
52
|
+
export function readTodoSettings(cwd) {
|
|
53
|
+
return {
|
|
54
|
+
globalSettings: readMergedSettings(getGlobalSettingsPaths()),
|
|
55
|
+
projectSettings: readMergedSettings(getProjectSettingsPaths(cwd)),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/settings.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface TodoSettingsPair {\n\tglobalSettings: Record<string, unknown>;\n\tprojectSettings: Record<string, unknown>;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readJsonObject(path: string): Record<string, unknown> {\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(path, \"utf-8\"));\n\t\treturn isRecord(parsed) ? parsed : {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction mergeSettings(base: Record<string, unknown>, override: Record<string, unknown>): Record<string, unknown> {\n\tconst merged: Record<string, unknown> = { ...base };\n\tfor (const [key, value] of Object.entries(override)) {\n\t\tconst current = merged[key];\n\t\tif (isRecord(current) && isRecord(value)) {\n\t\t\tmerged[key] = mergeSettings(current, value);\n\t\t\tcontinue;\n\t\t}\n\t\tmerged[key] = value;\n\t}\n\treturn merged;\n}\n\nfunction unique(paths: string[]): string[] {\n\treturn [...new Set(paths)];\n}\n\nfunction getGlobalSettingsPaths(): string[] {\n\tconst paths: string[] = [];\n\tconst piAgentDir = process.env.PI_CODING_AGENT_DIR;\n\tconst senpiAgentDir = process.env.SENPI_CODING_AGENT_DIR;\n\tif (piAgentDir) paths.push(join(piAgentDir, \"settings.json\"));\n\tif (senpiAgentDir) paths.push(join(senpiAgentDir, \"settings.json\"));\n\tpaths.push(join(homedir(), \".pi\", \"agent\", \"settings.json\"));\n\tpaths.push(join(homedir(), \".senpi\", \"agent\", \"settings.json\"));\n\treturn unique(paths);\n}\n\nfunction getProjectSettingsPaths(cwd: string): string[] {\n\treturn [join(cwd, \".pi\", \"settings.json\"), join(cwd, \".senpi\", \"settings.json\")];\n}\n\nfunction readMergedSettings(paths: string[]): Record<string, unknown> {\n\treturn paths.reduce<Record<string, unknown>>((settings, path) => mergeSettings(settings, readJsonObject(path)), {});\n}\n\nexport function readTodoSettings(cwd: string): TodoSettingsPair {\n\treturn {\n\t\tglobalSettings: readMergedSettings(getGlobalSettingsPaths()),\n\t\tprojectSettings: readMergedSettings(getProjectSettingsPaths(cwd)),\n\t};\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { ExtensionAPI } from "../../types.js";
|
|
3
|
+
export declare const SANEPI_SYSTEM_PREFIX = "[system:sanepi]";
|
|
4
|
+
export declare const SANEPI_CONVERSATION_EVENT = "sanepi:conversation";
|
|
5
|
+
export type TodoSystemMessageRoute = "todotools.continuation";
|
|
6
|
+
export type TodoConversationAction = "injected" | "failed";
|
|
7
|
+
export interface TodoConversationEvent {
|
|
8
|
+
version: 1;
|
|
9
|
+
source: "builtin";
|
|
10
|
+
action: TodoConversationAction;
|
|
11
|
+
route: TodoSystemMessageRoute;
|
|
12
|
+
sessionId?: string;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
conversation: {
|
|
15
|
+
prefix: typeof SANEPI_SYSTEM_PREFIX;
|
|
16
|
+
kind: "user_message";
|
|
17
|
+
deliverAs?: "steer" | "followUp";
|
|
18
|
+
};
|
|
19
|
+
text: string;
|
|
20
|
+
errorMessage?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface TodoUserMessageOptions {
|
|
23
|
+
sessionId?: string;
|
|
24
|
+
deliverAs?: "steer" | "followUp";
|
|
25
|
+
}
|
|
26
|
+
export declare function sendTodoUserMessage(pi: ExtensionAPI, route: TodoSystemMessageRoute, content: string | (TextContent | ImageContent)[], options?: TodoUserMessageOptions): void;
|
|
27
|
+
export declare function emitTodoSystemMessageFailure(pi: ExtensionAPI, args: {
|
|
28
|
+
route: TodoSystemMessageRoute;
|
|
29
|
+
sessionId?: string;
|
|
30
|
+
content: string | (TextContent | ImageContent)[];
|
|
31
|
+
deliverAs?: "steer" | "followUp";
|
|
32
|
+
errorMessage: string;
|
|
33
|
+
}): void;
|
|
34
|
+
//# sourceMappingURL=system-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AACtD,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAC9D,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE;QACb,MAAM,EAAE,OAAO,oBAAoB,CAAC;QACpC,IAAI,EAAE,cAAc,CAAC;QACrB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;KACjC,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CACjC;AA0ED,wBAAgB,mBAAmB,CAClC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,sBAAsB,EAC7B,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,sBAAsB,GAC9B,IAAI,CAoBN;AAED,wBAAgB,4BAA4B,CAC3C,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE;IACL,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;CACrB,GACC,IAAI,CAcN","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI } from \"../../types.js\";\n\nexport const SANEPI_SYSTEM_PREFIX = \"[system:sanepi]\";\nexport const SANEPI_CONVERSATION_EVENT = \"sanepi:conversation\";\n\nexport type TodoSystemMessageRoute = \"todotools.continuation\";\nexport type TodoConversationAction = \"injected\" | \"failed\";\n\nexport interface TodoConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SANEPI_SYSTEM_PREFIX;\n\t\tkind: \"user_message\";\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\nexport interface TodoUserMessageOptions {\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n}\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SANEPI_SYSTEM_PREFIX) ? text : `${SANEPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SANEPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitTodoConversationEvent(pi: ExtensionAPI, event: TodoConversationEvent): void {\n\tpi.events.emit(SANEPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttext: string;\n\terrorMessage?: string;\n}): TodoConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SANEPI_SYSTEM_PREFIX,\n\t\t\tkind: \"user_message\",\n\t\t\tdeliverAs: args.deliverAs,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: TodoUserMessageOptions | undefined,\n): options is TodoUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nexport function sendTodoUserMessage(\n\tpi: ExtensionAPI,\n\troute: TodoSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: TodoUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function emitTodoSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: TodoSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
|