@frenchtoastman/oh-my-groundcontrol 0.0.19 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +6 -1
- package/dist/config/schema.d.ts +9 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/langfuse-headers/index.d.ts +31 -0
- package/dist/index.js +60 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -13772,6 +13772,10 @@ var HashlineEditConfigSchema = exports_external.object({
|
|
|
13772
13772
|
var DoubleConfirmationConfigSchema = exports_external.object({
|
|
13773
13773
|
enabled: exports_external.boolean().default(false)
|
|
13774
13774
|
});
|
|
13775
|
+
var LangfuseHeadersConfigSchema = exports_external.object({
|
|
13776
|
+
enabled: exports_external.boolean().default(false),
|
|
13777
|
+
customHeaders: exports_external.record(exports_external.string(), exports_external.string()).default({})
|
|
13778
|
+
});
|
|
13775
13779
|
var PluginConfigSchema = exports_external.object({
|
|
13776
13780
|
preset: exports_external.string().optional(),
|
|
13777
13781
|
scoringEngineVersion: exports_external.enum(["v1", "v2-shadow", "v2"]).optional(),
|
|
@@ -13786,7 +13790,8 @@ var PluginConfigSchema = exports_external.object({
|
|
|
13786
13790
|
allowedProviders: exports_external.array(exports_external.string()).optional(),
|
|
13787
13791
|
sessionExport: SessionExportConfigSchema.optional(),
|
|
13788
13792
|
hashline_edit: HashlineEditConfigSchema.optional(),
|
|
13789
|
-
double_confirmation: DoubleConfirmationConfigSchema.optional()
|
|
13793
|
+
double_confirmation: DoubleConfirmationConfigSchema.optional(),
|
|
13794
|
+
langfuse_headers: LangfuseHeadersConfigSchema.optional()
|
|
13790
13795
|
});
|
|
13791
13796
|
// src/config/agent-mcps.ts
|
|
13792
13797
|
var DEFAULT_AGENT_MCPS = {
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -165,6 +165,11 @@ export declare const DoubleConfirmationConfigSchema: z.ZodObject<{
|
|
|
165
165
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
166
166
|
}, z.core.$strip>;
|
|
167
167
|
export type DoubleConfirmationConfig = z.infer<typeof DoubleConfirmationConfigSchema>;
|
|
168
|
+
export declare const LangfuseHeadersConfigSchema: z.ZodObject<{
|
|
169
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
170
|
+
customHeaders: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
171
|
+
}, z.core.$strip>;
|
|
172
|
+
export type LangfuseHeadersConfig = z.infer<typeof LangfuseHeadersConfigSchema>;
|
|
168
173
|
export declare const PluginConfigSchema: z.ZodObject<{
|
|
169
174
|
preset: z.ZodOptional<z.ZodString>;
|
|
170
175
|
scoringEngineVersion: z.ZodOptional<z.ZodEnum<{
|
|
@@ -298,6 +303,10 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
298
303
|
double_confirmation: z.ZodOptional<z.ZodObject<{
|
|
299
304
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
300
305
|
}, z.core.$strip>>;
|
|
306
|
+
langfuse_headers: z.ZodOptional<z.ZodObject<{
|
|
307
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
308
|
+
customHeaders: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
309
|
+
}, z.core.$strip>>;
|
|
301
310
|
}, z.core.$strip>;
|
|
302
311
|
export type PluginConfig = z.infer<typeof PluginConfigSchema>;
|
|
303
312
|
export type { AgentName } from './constants';
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { createDoubleConfirmationHook } from './double-confirmation';
|
|
|
6
6
|
export { createEditErrorRecoveryHook } from './edit-error-recovery';
|
|
7
7
|
export { createHashlineReadEnhancerHook } from './hashline-read-enhancer';
|
|
8
8
|
export { createJsonErrorRecoveryHook } from './json-error-recovery';
|
|
9
|
+
export { createLangfuseHeadersHook } from './langfuse-headers';
|
|
9
10
|
export { createPhaseReminderHook } from './phase-reminder';
|
|
10
11
|
export { createPostReadNudgeHook } from './post-read-nudge';
|
|
11
12
|
export { createQuestionRouterHook } from './question-router';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LangfuseHeadersConfig } from '../../config/schema';
|
|
2
|
+
interface ChatHeadersInput {
|
|
3
|
+
sessionID: string;
|
|
4
|
+
agent: string;
|
|
5
|
+
model: {
|
|
6
|
+
id: string;
|
|
7
|
+
providerID: string;
|
|
8
|
+
};
|
|
9
|
+
provider: {
|
|
10
|
+
source: string;
|
|
11
|
+
info: unknown;
|
|
12
|
+
options: Record<string, unknown>;
|
|
13
|
+
};
|
|
14
|
+
message: unknown;
|
|
15
|
+
}
|
|
16
|
+
interface ChatHeadersOutput {
|
|
17
|
+
headers: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates the Langfuse trace enrichment headers hook.
|
|
21
|
+
*
|
|
22
|
+
* Injects dynamic `X-OC-*` HTTP headers into every LLM API request,
|
|
23
|
+
* providing rich OpenCode context for Langfuse trace enrichment and
|
|
24
|
+
* training data tagging.
|
|
25
|
+
*
|
|
26
|
+
* Ships disabled by default — enable via config.langfuse_headers.enabled.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createLangfuseHeadersHook(config?: Partial<LangfuseHeadersConfig>): {
|
|
29
|
+
'chat.headers': (input: ChatHeadersInput, output: ChatHeadersOutput) => Promise<void>;
|
|
30
|
+
};
|
|
31
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -17104,6 +17104,10 @@ var HashlineEditConfigSchema = exports_external.object({
|
|
|
17104
17104
|
var DoubleConfirmationConfigSchema = exports_external.object({
|
|
17105
17105
|
enabled: exports_external.boolean().default(false)
|
|
17106
17106
|
});
|
|
17107
|
+
var LangfuseHeadersConfigSchema = exports_external.object({
|
|
17108
|
+
enabled: exports_external.boolean().default(false),
|
|
17109
|
+
customHeaders: exports_external.record(exports_external.string(), exports_external.string()).default({})
|
|
17110
|
+
});
|
|
17107
17111
|
var PluginConfigSchema = exports_external.object({
|
|
17108
17112
|
preset: exports_external.string().optional(),
|
|
17109
17113
|
scoringEngineVersion: exports_external.enum(["v1", "v2-shadow", "v2"]).optional(),
|
|
@@ -17118,7 +17122,8 @@ var PluginConfigSchema = exports_external.object({
|
|
|
17118
17122
|
allowedProviders: exports_external.array(exports_external.string()).optional(),
|
|
17119
17123
|
sessionExport: SessionExportConfigSchema.optional(),
|
|
17120
17124
|
hashline_edit: HashlineEditConfigSchema.optional(),
|
|
17121
|
-
double_confirmation: DoubleConfirmationConfigSchema.optional()
|
|
17125
|
+
double_confirmation: DoubleConfirmationConfigSchema.optional(),
|
|
17126
|
+
langfuse_headers: LangfuseHeadersConfigSchema.optional()
|
|
17122
17127
|
});
|
|
17123
17128
|
|
|
17124
17129
|
// src/config/loader.ts
|
|
@@ -23144,6 +23149,58 @@ ${JSON_ERROR_REMINDER}`;
|
|
|
23144
23149
|
}
|
|
23145
23150
|
};
|
|
23146
23151
|
}
|
|
23152
|
+
// src/hooks/langfuse-headers/index.ts
|
|
23153
|
+
var AGENT_TASK_MAP = {
|
|
23154
|
+
orchestrator: "planning",
|
|
23155
|
+
explorer: "research",
|
|
23156
|
+
fixer: "coding",
|
|
23157
|
+
designer: "design",
|
|
23158
|
+
librarian: "research",
|
|
23159
|
+
oracle: "analysis",
|
|
23160
|
+
build: "coding",
|
|
23161
|
+
verification: "verification",
|
|
23162
|
+
"pre-flight": "planning",
|
|
23163
|
+
contractor: "planning",
|
|
23164
|
+
groundcontrol: "planning",
|
|
23165
|
+
"power-slap-red": "coding",
|
|
23166
|
+
"power-slap-blue": "coding",
|
|
23167
|
+
"power-slap-green": "coding"
|
|
23168
|
+
};
|
|
23169
|
+
function createLangfuseHeadersHook(config2) {
|
|
23170
|
+
const enabled = config2?.enabled ?? false;
|
|
23171
|
+
const customHeaders = config2?.customHeaders ?? {};
|
|
23172
|
+
const pluginVersion = getCachedVersion() ?? "unknown";
|
|
23173
|
+
return {
|
|
23174
|
+
"chat.headers": async (input, output) => {
|
|
23175
|
+
if (!enabled)
|
|
23176
|
+
return;
|
|
23177
|
+
try {
|
|
23178
|
+
const dynamic = {
|
|
23179
|
+
"X-OC-App": "opencode",
|
|
23180
|
+
"X-OC-Agent": input.agent || undefined,
|
|
23181
|
+
"X-OC-Task": input.agent && AGENT_TASK_MAP[input.agent] || (input.agent ? "general" : undefined),
|
|
23182
|
+
"X-OC-Session-Id": input.sessionID || undefined,
|
|
23183
|
+
"X-OC-Model": input.model?.id || undefined,
|
|
23184
|
+
"X-OC-Provider": input.model?.providerID || undefined,
|
|
23185
|
+
"X-OC-Plugin-Version": pluginVersion || undefined,
|
|
23186
|
+
"X-OC-Prompt-Version": "opencode-default"
|
|
23187
|
+
};
|
|
23188
|
+
for (const [key, value] of Object.entries(dynamic)) {
|
|
23189
|
+
if (value) {
|
|
23190
|
+
output.headers[key] = value;
|
|
23191
|
+
}
|
|
23192
|
+
}
|
|
23193
|
+
for (const [key, value] of Object.entries(customHeaders)) {
|
|
23194
|
+
if (value) {
|
|
23195
|
+
output.headers[key] = value;
|
|
23196
|
+
}
|
|
23197
|
+
}
|
|
23198
|
+
} catch (err) {
|
|
23199
|
+
log("[langfuse-headers] Error injecting headers:", err);
|
|
23200
|
+
}
|
|
23201
|
+
}
|
|
23202
|
+
};
|
|
23203
|
+
}
|
|
23147
23204
|
// src/hooks/phase-reminder/index.ts
|
|
23148
23205
|
var PHASE_REMINDER = `<reminder>Recall Workflow Rules:
|
|
23149
23206
|
Before acting: <think> \u2014 analyze what you see, what's been accomplished, what still needs to be done.
|
|
@@ -39359,6 +39416,7 @@ var OhMyGroundControl = async (ctx) => {
|
|
|
39359
39416
|
const hashlineReadEnhancerHook = createHashlineReadEnhancerHook(config3.hashline_edit);
|
|
39360
39417
|
const editErrorRecoveryHook = createEditErrorRecoveryHook();
|
|
39361
39418
|
const doubleConfirmationHook = createDoubleConfirmationHook(config3.double_confirmation);
|
|
39419
|
+
const langfuseHeadersHook = createLangfuseHeadersHook(config3.langfuse_headers);
|
|
39362
39420
|
const hashlineEditEnabled = config3.hashline_edit?.enabled !== false;
|
|
39363
39421
|
const hashlineEditTool = hashlineEditEnabled ? createHashlineEditTool() : undefined;
|
|
39364
39422
|
return {
|
|
@@ -39463,6 +39521,7 @@ var OhMyGroundControl = async (ctx) => {
|
|
|
39463
39521
|
"experimental.chat.messages.transform": phaseReminderHook["experimental.chat.messages.transform"],
|
|
39464
39522
|
"chat.message": questionRouterHook["chat.message"],
|
|
39465
39523
|
"command.execute.before": analyzeCommandHook["command.execute.before"],
|
|
39524
|
+
"chat.headers": langfuseHeadersHook["chat.headers"],
|
|
39466
39525
|
"tool.execute.after": async (input, output) => {
|
|
39467
39526
|
await delegateTaskRetryHook["tool.execute.after"](input, output);
|
|
39468
39527
|
await jsonErrorRecoveryHook["tool.execute.after"](input, output);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frenchtoastman/oh-my-groundcontrol",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"description": "An OpenCode plugin for multi-agent orchestration for structured planning with NASA-style guardrails.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|