opencodekit 0.20.7 → 0.21.0

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.
Files changed (82) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/template/.opencode/AGENTS.md +60 -0
  3. package/dist/template/.opencode/agent/build.md +3 -2
  4. package/dist/template/.opencode/agent/explore.md +14 -14
  5. package/dist/template/.opencode/agent/general.md +1 -1
  6. package/dist/template/.opencode/agent/plan.md +1 -1
  7. package/dist/template/.opencode/agent/review.md +1 -1
  8. package/dist/template/.opencode/agent/vision.md +0 -9
  9. package/dist/template/.opencode/memory.db +0 -0
  10. package/dist/template/.opencode/memory.db-shm +0 -0
  11. package/dist/template/.opencode/memory.db-wal +0 -0
  12. package/dist/template/.opencode/opencode.json +83 -614
  13. package/dist/template/.opencode/opencodex-fast.jsonc +1 -1
  14. package/dist/template/.opencode/package.json +1 -1
  15. package/dist/template/.opencode/plugin/copilot-auth.ts +27 -12
  16. package/dist/template/.opencode/plugin/prompt-leverage.ts +193 -0
  17. package/dist/template/.opencode/plugin/prompt-leverage.ts.bak +228 -0
  18. package/dist/template/.opencode/plugin/sdk/copilot/copilot-provider.ts +14 -2
  19. package/dist/template/.opencode/plugin/sdk/copilot/index.ts +2 -2
  20. package/dist/template/.opencode/plugin/sdk/copilot/responses/convert-to-openai-responses-input.ts +335 -0
  21. package/dist/template/.opencode/plugin/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
  22. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-config.ts +18 -0
  23. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-error.ts +22 -0
  24. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-api-types.ts +214 -0
  25. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-language-model.ts +1770 -0
  26. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-prepare-tools.ts +173 -0
  27. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-settings.ts +1 -0
  28. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/code-interpreter.ts +87 -0
  29. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/file-search.ts +127 -0
  30. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/image-generation.ts +114 -0
  31. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/local-shell.ts +64 -0
  32. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search-preview.ts +103 -0
  33. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search.ts +102 -0
  34. package/dist/template/.opencode/pnpm-lock.yaml +791 -9
  35. package/dist/template/.opencode/skill/api-and-interface-design/SKILL.md +162 -0
  36. package/dist/template/.opencode/skill/beads/SKILL.md +10 -9
  37. package/dist/template/.opencode/skill/beads/references/MULTI_AGENT.md +10 -10
  38. package/dist/template/.opencode/skill/ci-cd-and-automation/SKILL.md +202 -0
  39. package/dist/template/.opencode/skill/code-search-patterns/SKILL.md +253 -0
  40. package/dist/template/.opencode/skill/code-simplification/SKILL.md +211 -0
  41. package/dist/template/.opencode/skill/condition-based-waiting/SKILL.md +12 -0
  42. package/dist/template/.opencode/skill/defense-in-depth/SKILL.md +16 -6
  43. package/dist/template/.opencode/skill/deprecation-and-migration/SKILL.md +189 -0
  44. package/dist/template/.opencode/skill/development-lifecycle/SKILL.md +12 -48
  45. package/dist/template/.opencode/skill/documentation-and-adrs/SKILL.md +220 -0
  46. package/dist/template/.opencode/skill/gh-address-comments/SKILL.md +29 -0
  47. package/dist/template/.opencode/skill/gh-address-comments/scripts/fetch_comments.py +237 -0
  48. package/dist/template/.opencode/skill/gh-fix-ci/SKILL.md +38 -0
  49. package/dist/template/.opencode/skill/gh-fix-ci/scripts/inspect_pr_checks.py +509 -0
  50. package/dist/template/.opencode/skill/incremental-implementation/SKILL.md +191 -0
  51. package/dist/template/.opencode/skill/performance-optimization/SKILL.md +236 -0
  52. package/dist/template/.opencode/skill/prompt-leverage/SKILL.md +90 -0
  53. package/dist/template/.opencode/skill/prompt-leverage/references/framework.md +91 -0
  54. package/dist/template/.opencode/skill/prompt-leverage/scripts/augment_prompt.py +157 -0
  55. package/dist/template/.opencode/skill/receiving-code-review/SKILL.md +11 -0
  56. package/dist/template/.opencode/skill/screenshot/SKILL.md +48 -0
  57. package/dist/template/.opencode/skill/screenshot/scripts/ensure_macos_permissions.sh +54 -0
  58. package/dist/template/.opencode/skill/screenshot/scripts/macos_display_info.swift +22 -0
  59. package/dist/template/.opencode/skill/screenshot/scripts/macos_permissions.swift +40 -0
  60. package/dist/template/.opencode/skill/screenshot/scripts/macos_window_info.swift +126 -0
  61. package/dist/template/.opencode/skill/screenshot/scripts/take_screenshot.ps1 +163 -0
  62. package/dist/template/.opencode/skill/screenshot/scripts/take_screenshot.py +585 -0
  63. package/dist/template/.opencode/skill/security-and-hardening/SKILL.md +296 -0
  64. package/dist/template/.opencode/skill/security-threat-model/SKILL.md +36 -0
  65. package/dist/template/.opencode/skill/security-threat-model/references/prompt-template.md +255 -0
  66. package/dist/template/.opencode/skill/security-threat-model/references/security-controls-and-assets.md +32 -0
  67. package/dist/template/.opencode/skill/skill-installer/SKILL.md +58 -0
  68. package/dist/template/.opencode/skill/skill-installer/scripts/github_utils.py +21 -0
  69. package/dist/template/.opencode/skill/skill-installer/scripts/install-skill-from-github.py +313 -0
  70. package/dist/template/.opencode/skill/skill-installer/scripts/list-skills.py +106 -0
  71. package/dist/template/.opencode/skill/structured-edit/SKILL.md +10 -0
  72. package/dist/template/.opencode/skill/swarm-coordination/SKILL.md +66 -1
  73. package/package.json +1 -1
  74. package/dist/template/.opencode/skill/beads-bridge/SKILL.md +0 -321
  75. package/dist/template/.opencode/skill/code-navigation/SKILL.md +0 -130
  76. package/dist/template/.opencode/skill/mqdh/SKILL.md +0 -171
  77. package/dist/template/.opencode/skill/obsidian/SKILL.md +0 -192
  78. package/dist/template/.opencode/skill/obsidian/mcp.json +0 -22
  79. package/dist/template/.opencode/skill/pencil/SKILL.md +0 -72
  80. package/dist/template/.opencode/skill/ralph/SKILL.md +0 -296
  81. package/dist/template/.opencode/skill/tilth-cli/SKILL.md +0 -207
  82. package/dist/template/.opencode/skill/tool-priority/SKILL.md +0 -299
@@ -1,3 +1,3 @@
1
1
  {
2
- "enabled": true
2
+ "enabled": false
3
3
  }
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@google/stitch-sdk": "^0.0.3",
15
- "@opencode-ai/plugin": "1.4.0"
15
+ "@opencode-ai/plugin": "1.4.6"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/node": "^25.3.0",
@@ -11,6 +11,8 @@
11
11
  * these fields to AI SDK's reasoning content parts.
12
12
  */
13
13
 
14
+ import path from "node:path";
15
+ import { pathToFileURL } from "node:url";
14
16
  import type { Plugin } from "@opencode-ai/plugin";
15
17
 
16
18
  const CLIENT_ID = "Ov23li8tweQw6odWQebz";
@@ -43,10 +45,7 @@ function setLogger(client: any) {
43
45
  const OAUTH_POLLING_SAFETY_MARGIN_MS = 3000; // 3 seconds
44
46
 
45
47
  const HEADERS = {
46
- "User-Agent": "GitHubCopilotChat/0.35.0",
47
- "Editor-Version": "vscode/1.107.0",
48
- "Editor-Plugin-Version": "copilot-chat/0.35.0",
49
- "Copilot-Integration-Id": "vscode-chat",
48
+ "User-Agent": "opencode/1.3.17",
50
49
  };
51
50
 
52
51
  const RESPONSES_API_ALTERNATE_INPUT_TYPES = [
@@ -544,10 +543,14 @@ function sanitizeResponseInputIds(input: any[]): any[] {
544
543
  });
545
544
  }
546
545
 
547
- export const CopilotAuthPlugin: Plugin = async ({ client: sdk }) => {
546
+ export const CopilotAuthPlugin: Plugin = async ({ client: sdk, directory }) => {
548
547
  // Initialize logger with the SDK client
549
548
  setLogger(sdk);
550
549
 
550
+ const localCopilotSdk = pathToFileURL(
551
+ path.join(directory, ".opencode", "plugin", "sdk", "copilot", "index.ts"),
552
+ ).toString();
553
+
551
554
  return {
552
555
  auth: {
553
556
  provider: "github-copilot",
@@ -572,11 +575,10 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk }) => {
572
575
  },
573
576
  };
574
577
 
575
- // All models use the standard github-copilot SDK
576
- // Reasoning support for Claude models is handled via:
577
- // 1. The fetch wrapper adds thinking_budget to request body
578
- // 2. The fetch wrapper strips invalid thinking blocks from messages
579
- model.api.npm = "@ai-sdk/github-copilot";
578
+ // Route all Copilot models through the local file-based SDK.
579
+ // OpenCode's built-in github-copilot model loader will automatically
580
+ // choose sdk.responses(model) for GPT-5+ and sdk.chat(model) otherwise.
581
+ model.api.npm = localCopilotSdk;
580
582
  }
581
583
  }
582
584
 
@@ -1053,7 +1055,7 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk }) => {
1053
1055
  headers: {
1054
1056
  Accept: "application/json",
1055
1057
  "Content-Type": "application/json",
1056
- "User-Agent": "GitHubCopilotChat/0.35.0",
1058
+ "User-Agent": "opencode/1.3.17",
1057
1059
  },
1058
1060
  body: JSON.stringify({
1059
1061
  client_id: CLIENT_ID,
@@ -1078,7 +1080,7 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk }) => {
1078
1080
  headers: {
1079
1081
  Accept: "application/json",
1080
1082
  "Content-Type": "application/json",
1081
- "User-Agent": "GitHubCopilotChat/0.35.0",
1083
+ "User-Agent": "opencode/1.3.17",
1082
1084
  },
1083
1085
  body: JSON.stringify({
1084
1086
  client_id: CLIENT_ID,
@@ -1162,6 +1164,10 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk }) => {
1162
1164
  output.headers["anthropic-beta"] = "interleaved-thinking-2025-05-14";
1163
1165
  }
1164
1166
 
1167
+ // When using the local Copilot SDK, let the SDK/message pipeline decide
1168
+ // initiator semantics. Overriding x-initiator here can break Responses routing.
1169
+ if (input.model?.api?.npm === localCopilotSdk) return;
1170
+
1165
1171
  // Mark subagent sessions as agent-initiated (matching standard Copilot tools)
1166
1172
  try {
1167
1173
  const session = await sdk.session
@@ -1179,5 +1185,14 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk }) => {
1179
1185
  // Ignore errors from session lookup
1180
1186
  }
1181
1187
  },
1188
+ // Hook to strip maxOutputTokens for GPT models (matches upstream Copilot CLI behavior)
1189
+ "chat.params": async (input: any, output: any) => {
1190
+ if (!input.model?.providerID?.includes("github-copilot")) return;
1191
+
1192
+ // GPT models don't support maxOutputTokens through the Copilot proxy
1193
+ if (input.model?.api?.id?.includes("gpt")) {
1194
+ output.maxOutputTokens = undefined;
1195
+ }
1196
+ },
1182
1197
  };
1183
1198
  };
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Prompt Leverage Plugin
3
+ *
4
+ * Automatically upgrades every user prompt with the seven-block framework before the AI processes it.
5
+ * Uses chat.message hook — safely inspects input structure before accessing properties.
6
+ */
7
+
8
+ import type { Plugin } from "@opencode-ai/plugin";
9
+
10
+ const TASK_KEYWORDS: Record<string, string[]> = {
11
+ coding: [
12
+ "code",
13
+ "bug",
14
+ "repo",
15
+ "refactor",
16
+ "test",
17
+ "implement",
18
+ "fix",
19
+ "function",
20
+ "api",
21
+ "add",
22
+ "update",
23
+ "remove",
24
+ ],
25
+ research: [
26
+ "research",
27
+ "compare",
28
+ "find",
29
+ "latest",
30
+ "sources",
31
+ "analyze",
32
+ "look up",
33
+ ],
34
+ writing: [
35
+ "write",
36
+ "rewrite",
37
+ "draft",
38
+ "email",
39
+ "memo",
40
+ "blog",
41
+ "copy",
42
+ "tone",
43
+ ],
44
+ review: ["review", "audit", "critique", "inspect", "evaluate", "assess"],
45
+ planning: ["plan", "roadmap", "strategy", "framework", "outline"],
46
+ analysis: ["analyze", "explain", "break down", "diagnose", "root cause"],
47
+ };
48
+
49
+ function detectTask(prompt: string): string {
50
+ const lowered = prompt.toLowerCase();
51
+ const scores: Record<string, number> = {};
52
+ for (const [task, keywords] of Object.entries(TASK_KEYWORDS)) {
53
+ scores[task] = keywords.filter((k) => lowered.includes(k)).length;
54
+ }
55
+ const best = Object.entries(scores).sort((a, b) => b[1] - a[1]);
56
+ return best[0]?.[1] ? best[0][0] : "analysis";
57
+ }
58
+
59
+ function inferIntensity(prompt: string, task: string): string {
60
+ const lowered = prompt.toLowerCase();
61
+ if (
62
+ ["careful", "deep", "thorough", "critical", "production"].some((t) =>
63
+ lowered.includes(t),
64
+ )
65
+ ) {
66
+ return "Deep";
67
+ }
68
+ if (task === "coding" || task === "research" || task === "review") {
69
+ return "Standard";
70
+ }
71
+ return "Light";
72
+ }
73
+
74
+ function buildToolRules(task: string): string {
75
+ const rules: Record<string, string> = {
76
+ coding:
77
+ "Inspect the relevant files and dependencies first. Validate the final change with the narrowest useful checks before broadening scope.",
78
+ research:
79
+ "Retrieve evidence from reliable sources before concluding. Do not guess facts that can be checked.",
80
+ review:
81
+ "Read enough surrounding context to understand intent before critiquing. Distinguish confirmed issues from plausible risks.",
82
+ };
83
+ return (
84
+ rules[task] ||
85
+ "Use tools or extra context only when they materially improve correctness or completeness."
86
+ );
87
+ }
88
+
89
+ function buildOutputContract(task: string): string {
90
+ const contracts: Record<string, string> = {
91
+ coding:
92
+ "Return the result in a practical execution format: concise summary, concrete changes or code, validation notes, and any remaining risks.",
93
+ research:
94
+ "Return a structured synthesis with key findings, supporting evidence, uncertainty where relevant, and a concise bottom line.",
95
+ writing:
96
+ "Return polished final copy in the requested tone and format. If useful, include a short rationale for major editorial choices.",
97
+ review:
98
+ "Return findings grouped by severity or importance, explain why each matters, and suggest the smallest credible next step.",
99
+ };
100
+ return (
101
+ contracts[task] ||
102
+ "Return a clear, well-structured response matched to the task, with no unnecessary verbosity."
103
+ );
104
+ }
105
+
106
+ function upgradePrompt(userPrompt: string): string {
107
+ const normalized = userPrompt.trim().replace(/\s+/g, " ");
108
+ const task = detectTask(normalized);
109
+ const intensity = inferIntensity(normalized, task);
110
+ const toolRules = buildToolRules(task);
111
+ const outputContract = buildOutputContract(task);
112
+
113
+ if (normalized.includes("Objective:") && normalized.includes("Context:")) {
114
+ return userPrompt;
115
+ }
116
+ if (normalized.length < 15 || normalized.split(" ").length < 3) {
117
+ return userPrompt;
118
+ }
119
+
120
+ return `Objective:
121
+ - Complete this task: ${normalized}
122
+ - Optimize for a correct, useful result rather than a merely plausible one.
123
+
124
+ Context:
125
+ - Preserve the user's original intent and constraints.
126
+ - Surface any key assumptions if required information is missing.
127
+
128
+ Work Style:
129
+ - Task type: ${task}
130
+ - Effort level: ${intensity}
131
+ - Understand the problem broadly enough to avoid narrow mistakes, then go deep where the risk or complexity is highest.
132
+ - Use first-principles reasoning before proposing changes.
133
+ - For non-trivial work, review the result once with fresh eyes before finalizing.
134
+
135
+ Tool Rules:
136
+ - ${toolRules}
137
+
138
+ Output Contract:
139
+ - ${outputContract}
140
+
141
+ Verification:
142
+ - Check correctness, completeness, and edge cases.
143
+ - Improve obvious weaknesses if a better approach is available within scope.
144
+
145
+ Done Criteria:
146
+ - Stop only when the response satisfies the task, matches the requested format, and passes the verification step.`;
147
+ }
148
+
149
+ export const PromptLeverage: Plugin = async ({ client }) => {
150
+ console.log("PromptLeverage: Initializing...");
151
+
152
+ const showToast = async (message: string) => {
153
+ try {
154
+ await client.tui.showToast({
155
+ body: {
156
+ title: "PromptLeverage",
157
+ message,
158
+ variant: "info",
159
+ duration: 3000,
160
+ },
161
+ });
162
+ } catch {
163
+ /* Toast API unavailable */
164
+ }
165
+ };
166
+
167
+ return {
168
+ "experimental.chat.messages.transform": async (input: any, output: any) => {
169
+ try {
170
+ const msgs = output.messages || input.messages || [];
171
+
172
+ // Find the last message with parts (user message)
173
+ for (let i = msgs.length - 1; i >= 0; i--) {
174
+ const msg = msgs[i];
175
+ if (msg?.parts) {
176
+ for (const part of msg.parts) {
177
+ if (part.type === "text" && part.text) {
178
+ const upgraded = upgradePrompt(part.text);
179
+ if (upgraded !== part.text) {
180
+ part.text = upgraded;
181
+ showToast("Upgraded prompt!");
182
+ }
183
+ }
184
+ }
185
+ break; // Only upgrade the most recent message
186
+ }
187
+ }
188
+ } catch (e: any) {
189
+ showToast(`Error: ${e.message}`);
190
+ }
191
+ },
192
+ };
193
+ };
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Prompt Leverage Plugin
3
+ *
4
+ * Automatically upgrades every user prompt with the seven-block framework before the AI processes it.
5
+ * This enforces prompt-leverage on ALL user input without relying on the AI to remember the rule.
6
+ *
7
+ * Hooks used:
8
+ * - chat.message: Upgrades user message as it arrives
9
+ */
10
+
11
+ import type { Plugin } from "@opencode-ai/plugin";
12
+
13
+ interface PromptFramework {
14
+ objective: string;
15
+ context: string;
16
+ workStyle: string;
17
+ toolRules: string;
18
+ outputContract: string;
19
+ verification: string;
20
+ doneCriteria: string;
21
+ }
22
+
23
+ const TASK_KEYWORDS: Record<string, string[]> = {
24
+ coding: [
25
+ "code",
26
+ "bug",
27
+ "repo",
28
+ "refactor",
29
+ "test",
30
+ "implement",
31
+ "fix",
32
+ "function",
33
+ "api",
34
+ "add",
35
+ "update",
36
+ "remove",
37
+ ],
38
+ research: [
39
+ "research",
40
+ "compare",
41
+ "find",
42
+ "latest",
43
+ "sources",
44
+ "analyze",
45
+ "look up",
46
+ ],
47
+ writing: [
48
+ "write",
49
+ "rewrite",
50
+ "draft",
51
+ "email",
52
+ "memo",
53
+ "blog",
54
+ "copy",
55
+ "tone",
56
+ ],
57
+ review: ["review", "audit", "critique", "inspect", "evaluate", "assess"],
58
+ planning: ["plan", "roadmap", "strategy", "framework", "outline"],
59
+ analysis: ["analyze", "explain", "break down", "diagnose", "root cause"],
60
+ };
61
+
62
+ function detectTask(prompt: string): string {
63
+ const lowered = prompt.toLowerCase();
64
+ const scores: Record<string, number> = {};
65
+
66
+ for (const [task, keywords] of Object.entries(TASK_KEYWORDS)) {
67
+ scores[task] = keywords.filter((k) => lowered.includes(k)).length;
68
+ }
69
+
70
+ const best = Object.entries(scores).sort((a, b) => b[1] - a[1]);
71
+ return best[0]?.[1] ? best[0][0] : "analysis";
72
+ }
73
+
74
+ function inferIntensity(prompt: string, task: string): string {
75
+ const lowered = prompt.toLowerCase();
76
+ if (
77
+ lowered.includes("careful") ||
78
+ lowered.includes("deep") ||
79
+ lowered.includes("thorough") ||
80
+ lowered.includes("critical") ||
81
+ lowered.includes("production")
82
+ ) {
83
+ return "Deep";
84
+ }
85
+ if (task === "coding" || task === "research" || task === "review") {
86
+ return "Standard";
87
+ }
88
+ return "Light";
89
+ }
90
+
91
+ function buildToolRules(task: string): string {
92
+ const rules: Record<string, string> = {
93
+ coding:
94
+ "Inspect the relevant files and dependencies first. Validate the final change with the narrowest useful checks before broadening scope.",
95
+ research:
96
+ "Retrieve evidence from reliable sources before concluding. Do not guess facts that can be checked.",
97
+ review:
98
+ "Read enough surrounding context to understand intent before critiquing. Distinguish confirmed issues from plausible risks.",
99
+ };
100
+ return (
101
+ rules[task] ||
102
+ "Use tools or extra context only when they materially improve correctness or completeness."
103
+ );
104
+ }
105
+
106
+ function buildOutputContract(task: string): string {
107
+ const contracts: Record<string, string> = {
108
+ coding:
109
+ "Return the result in a practical execution format: concise summary, concrete changes or code, validation notes, and any remaining risks.",
110
+ research:
111
+ "Return a structured synthesis with key findings, supporting evidence, uncertainty where relevant, and a concise bottom line.",
112
+ writing:
113
+ "Return polished final copy in the requested tone and format. If useful, include a short rationale for major editorial choices.",
114
+ review:
115
+ "Return findings grouped by severity or importance, explain why each matters, and suggest the smallest credible next step.",
116
+ };
117
+ return (
118
+ contracts[task] ||
119
+ "Return a clear, well-structured response matched to the task, with no unnecessary verbosity."
120
+ );
121
+ }
122
+
123
+ function upgradePrompt(userPrompt: string): string {
124
+ const normalized = userPrompt.trim().replace(/\s+/g, " ");
125
+ const task = detectTask(normalized);
126
+ const intensity = inferIntensity(normalized, task);
127
+ const toolRules = buildToolRules(task);
128
+ const outputContract = buildOutputContract(task);
129
+
130
+ // If prompt is already upgraded (contains framework blocks), skip
131
+ if (normalized.includes("Objective:") && normalized.includes("Context:")) {
132
+ return userPrompt;
133
+ }
134
+
135
+ // Simple prompts don't need full framework
136
+ if (normalized.length < 15 || normalized.split(" ").length < 3) {
137
+ return userPrompt;
138
+ }
139
+
140
+ return `Objective:
141
+ - Complete this task: ${normalized}
142
+ - Optimize for a correct, useful result rather than a merely plausible one.
143
+
144
+ Context:
145
+ - Preserve the user's original intent and constraints.
146
+ - Surface any key assumptions if required information is missing.
147
+
148
+ Work Style:
149
+ - Task type: ${task}
150
+ - Effort level: ${intensity}
151
+ - Understand the problem broadly enough to avoid narrow mistakes, then go deep where the risk or complexity is highest.
152
+ - Use first-principles reasoning before proposing changes.
153
+ - For non-trivial work, review the result once with fresh eyes before finalizing.
154
+
155
+ Tool Rules:
156
+ - ${toolRules}
157
+
158
+ Output Contract:
159
+ - ${outputContract}
160
+
161
+ Verification:
162
+ - Check correctness, completeness, and edge cases.
163
+ - Improve obvious weaknesses if a better approach is available within scope.
164
+
165
+ Done Criteria:
166
+ - Stop only when the response satisfies the task, matches the requested format, and passes the verification step.`;
167
+ }
168
+
169
+ export const PromptLeverage: Plugin = async ({ client }) => {
170
+ console.log("PromptLeverage: Initializing...");
171
+
172
+ const showToast = async (message: string) => {
173
+ try {
174
+ await client.tui.showToast({
175
+ body: {
176
+ title: "PromptLeverage",
177
+ message,
178
+ variant: "info",
179
+ duration: 3000,
180
+ },
181
+ });
182
+ } catch {
183
+ /* Toast API unavailable */
184
+ }
185
+ };
186
+
187
+ return {
188
+ "chat.message": async (input, output) => {
189
+ // Upgrade user message - check different structures
190
+ showToast(
191
+ `Hook fired, msg: ${JSON.stringify(input.message).slice(0, 100)}`,
192
+ );
193
+
194
+ // Try parts array
195
+ if (input.message?.parts) {
196
+ for (const part of input.message.parts) {
197
+ if (part.type === "text" && part.text) {
198
+ const upgraded = upgradePrompt(part.text);
199
+ if (upgraded !== part.text) {
200
+ part.text = upgraded;
201
+ showToast("Upgraded user prompt");
202
+ }
203
+ }
204
+ }
205
+ }
206
+ // Try direct text field
207
+ else if (input.message?.text) {
208
+ const upgraded = upgradePrompt(input.message.text);
209
+ if (upgraded !== input.message.text) {
210
+ input.message.text = upgraded;
211
+ showToast("Upgraded user prompt");
212
+ }
213
+ }
214
+ // Try content array
215
+ else if (input.message?.content) {
216
+ for (const part of input.message.content) {
217
+ if (part.type === "text" && part.text) {
218
+ const upgraded = upgradePrompt(part.text);
219
+ if (upgraded !== part.text) {
220
+ part.text = upgraded;
221
+ showToast("Upgraded user prompt");
222
+ }
223
+ }
224
+ }
225
+ }
226
+ },
227
+ };
228
+ };
@@ -1,10 +1,11 @@
1
1
  import type { LanguageModelV2 } from "@ai-sdk/provider";
2
2
  import {
3
3
  type FetchFunction,
4
- withUserAgentSuffix,
5
4
  withoutTrailingSlash,
5
+ withUserAgentSuffix,
6
6
  } from "@ai-sdk/provider-utils";
7
- import { OpenAICompatibleChatLanguageModel } from "./chat/openai-compatible-chat-language-model";
7
+ import { OpenAICompatibleChatLanguageModel } from "./chat/openai-compatible-chat-language-model.js";
8
+ import { OpenAIResponsesLanguageModel } from "./responses/openai-responses-language-model.js";
8
9
 
9
10
  // Import the version or define it
10
11
  const VERSION = "0.1.0";
@@ -41,6 +42,7 @@ export interface OpenaiCompatibleProviderSettings {
41
42
  export interface OpenaiCompatibleProvider {
42
43
  (modelId: OpenaiCompatibleModelId): LanguageModelV2;
43
44
  chat(modelId: OpenaiCompatibleModelId): LanguageModelV2;
45
+ responses(modelId: OpenaiCompatibleModelId): LanguageModelV2;
44
46
  languageModel(modelId: OpenaiCompatibleModelId): LanguageModelV2;
45
47
  }
46
48
 
@@ -78,6 +80,15 @@ export function createOpenaiCompatible(
78
80
  });
79
81
  };
80
82
 
83
+ const createResponsesModel = (modelId: OpenaiCompatibleModelId) => {
84
+ return new OpenAIResponsesLanguageModel(modelId, {
85
+ provider: `${options.name ?? "openai-compatible"}.responses`,
86
+ headers: getHeaders,
87
+ url: ({ path, modelId: _modelId }) => `${baseURL}${path}`,
88
+ fetch: options.fetch,
89
+ });
90
+ };
91
+
81
92
  const createLanguageModel = (modelId: OpenaiCompatibleModelId) =>
82
93
  createChatModel(modelId);
83
94
 
@@ -86,6 +97,7 @@ export function createOpenaiCompatible(
86
97
 
87
98
  provider.languageModel = createLanguageModel;
88
99
  provider.chat = createChatModel;
100
+ provider.responses = createResponsesModel;
89
101
 
90
102
  return provider as OpenaiCompatibleProvider;
91
103
  }
@@ -1,5 +1,5 @@
1
- export { createOpenaiCompatible, openaiCompatible } from "./copilot-provider";
1
+ export { createOpenaiCompatible, openaiCompatible } from "./copilot-provider.js";
2
2
  export type {
3
3
  OpenaiCompatibleProvider,
4
4
  OpenaiCompatibleProviderSettings,
5
- } from "./copilot-provider";
5
+ } from "./copilot-provider.js";