oh-my-opencode-cohub 1.11.1 → 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,6 +56,126 @@ npm install oh-my-opencode-cohub
56
56
 
57
57
  重启 OpenCode 即可。
58
58
 
59
+ ### 方式三:复制文案交给 AI 配置
60
+
61
+ 如果你不想用命令行,也可以复制以下文案粘贴给 AI,让 AI 帮你生成 `oh-my-opencode-cohub.json` 配置文件。
62
+
63
+ > **注意:这只生成 `oh-my-opencode-cohub.json`(代理模型配置)。插件本身仍需通过方式一或方式二安装。**
64
+
65
+ ````
66
+
67
+ ## 你的任务
68
+
69
+ 帮我生成 oh-my-opencode-cohub 的配置文件。
70
+
71
+ **要求:收到后先分析我的环境、输出配置方案表格、等我确认后再写入文件,不要直接动手改。**
72
+
73
+ ## 执行步骤
74
+
75
+ ### 第一步:分析环境
76
+
77
+ 读取 `~/.config/opencode/opencode.json`,找到所有已配置的 provider 和 model,整理成表格给我看。
78
+
79
+ ### 第二步:输出配置方案
80
+
81
+ 根据下面规则,输出每个代理的 model 和 variant 分配表格,等我确认。
82
+
83
+ ### 第三步:写入文件
84
+
85
+ 确认后将配置写入 `~/.config/opencode/oh-my-opencode-cohub.json`。
86
+
87
+ ## 配置文件结构
88
+
89
+ ```json
90
+ {
91
+ "$schema": "https://unpkg.com/oh-my-opencode-cohub@latest/oh-my-opencode-cohub.schema.json",
92
+ "agents": {
93
+ "co-orchestrator": { "model": "provider/model", "variant": "max" },
94
+ ...
95
+ },
96
+ "council": {
97
+ "default_preset": "default",
98
+ "timeout": 180000,
99
+ "councillor_execution_mode": "parallel",
100
+ "councillor_retries": 3,
101
+ "presets": {
102
+ "default": {
103
+ "alpha": { "model": "provider/model", "variant": "max" },
104
+ "beta": { "model": "provider/model", "variant": "high" },
105
+ "gamma": { "model": "provider/model", "variant": "medium" }
106
+ }
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ ## 12 个代理配置规则
113
+
114
+ | 代理 | 角色 | 推理强度 | variant 建议 | 模型偏好 |
115
+ |------|------|---------|-------------|---------|
116
+ | co-orchestrator | 纯调度者,编排任务、委派执行 | **重型** | max / xhigh | pro、max、sonnet、opus 等强推理模型 |
117
+ | co-oracle | 战略顾问,架构审查、复杂调试 | **重型** | max / xhigh | 同上 |
118
+ | co-planner | 方案制定,综合信息输出任务分解 | **重型** | max / xhigh | 同上 |
119
+ | co-council | 多模型共识,跨多个 LLM 综合 | **重型** | high / xhigh | 同上 |
120
+ | co-librarian | 研究员,查文档、搜 GitHub、Web 搜索 | **轻型** | low / medium | flash、mini、haiku 等轻量快速模型 |
121
+ | co-explorer | 代码探索者,grep/glob 搜索定位 | **轻型** | low / medium | 同上 |
122
+ | co-fixer | 执行者,代码修改、编译、测试 | **轻型** | low / medium | 同上 |
123
+ | co-rule-user | 分析用户级 AGENTS.md 规范 | **轻型** | low / medium | 同上 |
124
+ | co-rule-project | 分析项目 AGENTS.md 规范 | **轻型** | low / medium | 同上 |
125
+ | co-rule-app | 分析 .opencode/rules/* 应用规则 | **轻型** | low / medium | 同上 |
126
+ | co-designer | 设计师,UI/UX 设计、视觉润色 | **中等** | high / medium | sonnet、claude、minimax 等前端/视觉强的模型 |
127
+ | co-observer | 观察者,图片/PDF/截图视觉分析 | **中等** | medium / high | vision、flash 等支持视觉的模型 |
128
+
129
+ ## council 详细说明
130
+
131
+ council 是内置的多模型共识机制,会将同一个问题发给 3 个 councillor 并行回答,然后综合出最优方案。
132
+
133
+ | councillor | 角色定位 | 推理强度 | variant 建议 |
134
+ |-----------|---------|---------|-------------|
135
+ | alpha | 主力深度推理 | **重型** | max / xhigh |
136
+ | beta | 第二视角互补 | **重型/中等** | high / xhigh |
137
+ | gamma | 第三方校验 | **中等** | medium / high |
138
+
139
+ **关键配置项说明:**
140
+
141
+ | 字段 | 默认值 | 说明 |
142
+ |------|--------|------|
143
+ | `default_preset` | `"default"` | 默认使用的 preset 名称,可以定义多个 preset(如 `"quick"` 快速共识、`"deep"` 深度共识) |
144
+ | `timeout` | `180000`(3 分钟) | 单个 councillor 的超时时间(毫秒),所有 councillor 并行执行 |
145
+ | `councillor_execution_mode` | `"parallel"` | 执行模式:`"parallel"` 并行(快)或 `"serial"` 串行(省 tokens) |
146
+ | `councillor_retries` | `3` | 单个 councillor 调用失败后的重试次数 |
147
+
148
+ **presets 示例(多套配置):**
149
+
150
+ ```json
151
+ "presets": {
152
+ "default": {
153
+ "alpha": { "model": "deepseek/deepseek-v4-pro", "variant": "max" },
154
+ "beta": { "model": "anthropic/claude-sonnet-4-20250514", "variant": "high" },
155
+ "gamma": { "model": "openai/gpt-5.2", "variant": "high" }
156
+ },
157
+ "quick": {
158
+ "alpha": { "model": "deepseek/deepseek-v4-pro", "variant": "high" },
159
+ "beta": { "model": "openai/gpt-5.2", "variant": "medium" },
160
+ "gamma": { "model": "anthropic/claude-sonnet-4-20250514", "variant": "medium" }
161
+ }
162
+ }
163
+ ```
164
+
165
+ ## 分配规则
166
+
167
+ - 从 opencode.json 读取已配置的 provider,按上表规则为每个代理分配 model 和 variant
168
+ - 只有 1 个 provider:所有代理都用它,variant 按表格建议选不同档位
169
+ - 有多个 provider:重型代理优先选最强推理 provider,轻型选最快 provider
170
+ - council 的 alpha/beta/gamma 优先选 3 个不同 provider;不够 3 个时用同一 provider 的不同 model
171
+ - opencode.json 无任何 provider 时,生成占位配置并在 `_comment` 字段提示用户先配置
172
+
173
+ ## 注意
174
+
175
+ - 只写入 `oh-my-opencode-cohub.json`,不要修改 `opencode.json`
176
+ - agent 名必须用 `co-` 前缀(共 12 个),不要遗漏
177
+ ````
178
+
59
179
  ### 卸载
60
180
 
61
181
  ```bash
@@ -188,7 +308,7 @@ CLI 安装后自动创建 `~/.config/opencode/oh-my-opencode-cohub.json`,这
188
308
  | `presets` | object | (必填) | 预设字典,每个预设是一组 councillor |
189
309
  | `default_preset` | string | `"default"` | 调用时不指定 preset 时使用的预设 |
190
310
  | `timeout` | number | `180000` | 单个 councillor 超时(毫秒),默认 3 分钟 |
191
- | `councillor_execution_mode` | `"parallel"` \| `"serial"` | `"parallel"` | 并行/串行执⾏ |
311
+ | `councillor_execution_mode` | `"parallel"` \| `"serial"` | `"parallel"` | 并行/串行执行 |
192
312
  | `councillor_retries` | number | `3` | 空响应重试次数 |
193
313
 
194
314
  - 每个 councillor 的 key(如 `alpha`、`beta`)可任意命名,会出现在输出中
@@ -13,7 +13,7 @@ export declare function registerCoHubAgents(): {
13
13
  success: boolean;
14
14
  message: string;
15
15
  };
16
- /** 写入默认配置模板(如文件不存在) */
16
+ /** 写入默认配置模板(如文件不存在),智能匹配 opencode.json 中的 provider/model */
17
17
  export declare function writeDefaultConfig(): {
18
18
  success: boolean;
19
19
  message: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config-io.d.ts","sourceRoot":"","sources":["../../src/cli/config-io.ts"],"names":[],"mappings":"AAkCA,2CAA2C;AAC3C,wBAAgB,yBAAyB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAajF;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAa5E;AAOD,mDAAmD;AACnD,wBAAgB,mBAAmB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAiD3E;AAKD,uBAAuB;AACvB,wBAAgB,kBAAkB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA0C1E;AAED,8BAA8B;AAC9B,wBAAgB,cAAc,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CA6GzE"}
1
+ {"version":3,"file":"config-io.d.ts","sourceRoot":"","sources":["../../src/cli/config-io.ts"],"names":[],"mappings":"AAkCA,2CAA2C;AAC3C,wBAAgB,yBAAyB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAajF;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAa5E;AAOD,mDAAmD;AACnD,wBAAgB,mBAAmB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAuD3E;AA+ED,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA2G1E;AAED,8BAA8B;AAC9B,wBAAgB,cAAc,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CA6GzE"}
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // package.json
3
- var version = "1.11.1";
3
+ var version = "1.12.1";
4
4
 
5
5
  // src/cli/config-io.ts
6
6
  import * as fs from "node:fs";
@@ -492,13 +492,18 @@ orchestrator 委派时可参考上述原则。不确定时,co-oracle 自身会
492
492
  let migrated = 0;
493
493
  for (const [name, agentConfig] of Object.entries(cohubAgents)) {
494
494
  const existing = agents[name];
495
+ const template = agentConfig;
495
496
  if (!existing) {
496
497
  agents[name] = agentConfig;
497
498
  added++;
498
499
  } else if (typeof existing.prompt === "string" && existing.prompt.includes("request_plan_approval")) {
499
- existing.prompt = agentConfig.prompt;
500
+ existing.prompt = template.prompt;
500
501
  delete existing.permission;
501
502
  migrated++;
503
+ } else if (existing.mode !== template.mode) {
504
+ existing.mode = template.mode;
505
+ existing.prompt = template.prompt;
506
+ migrated++;
502
507
  }
503
508
  }
504
509
  if (added > 0 || migrated > 0) {
@@ -511,46 +516,154 @@ orchestrator 委派时可参考上述原则。不确定时,co-oracle 自身会
511
516
  return { success: true, message: `✓ CoHub 代理:新增 ${added} 个,更新 ${migrated} 个${added + migrated === 0 ? "(全部已是最新,跳过)" : ""}` };
512
517
  }
513
518
  var COHUB_CONFIG_PATH = path.join(os.homedir(), ".config", "opencode", "oh-my-opencode-cohub.json");
519
+ var HEAVY_KEYWORDS = ["pro", "preview", "opus", "max", "sonnet", "gpt-5.6"];
520
+ var LIGHT_KEYWORDS = ["flash", "mini", "haiku", "gpt-5.4", "gpt-5.3"];
521
+ var DESIGN_KEYWORDS = ["minimax", "m3", "sonnet", "claude"];
522
+ var OBSERVER_KEYWORDS = ["gpt-5.5", "gpt-5.4", "vision", "flash"];
523
+ var HEAVY_TYPES = new Set(["orchestrator", "oracle", "planner", "council"]);
524
+ function pickBestVariant(variants, agentType) {
525
+ if (!variants || variants.length === 0)
526
+ return;
527
+ const isHeavy = HEAVY_TYPES.has(agentType);
528
+ const priority = isHeavy ? ["max", "xhigh", "high", "medium", "low"] : ["low", "medium", "high", "xhigh", "max"];
529
+ for (const p of priority) {
530
+ if (variants.includes(p))
531
+ return p;
532
+ }
533
+ return variants[0];
534
+ }
535
+ function findBestModel(flatModels, keywords, agentType) {
536
+ for (const kw of keywords) {
537
+ for (const m of flatModels) {
538
+ const modelId = m.fullModel.split("/").slice(1).join("/").toLowerCase();
539
+ if (modelId.includes(kw.toLowerCase())) {
540
+ return { model: m.fullModel, variant: pickBestVariant(m.variants, agentType) };
541
+ }
542
+ }
543
+ }
544
+ if (flatModels.length > 0) {
545
+ return { model: flatModels[0].fullModel, variant: pickBestVariant(flatModels[0].variants, agentType) };
546
+ }
547
+ return null;
548
+ }
549
+ function flattenModelsFromOpenCode() {
550
+ const opencodeConfig = readJSON(getOpencodeConfigPath());
551
+ if (!opencodeConfig)
552
+ return [];
553
+ const providerRecord = opencodeConfig?.config;
554
+ const providers = providerRecord?.provider;
555
+ if (!providers)
556
+ return [];
557
+ const result = [];
558
+ for (const [providerKey, providerData] of Object.entries(providers)) {
559
+ const models = providerData?.models;
560
+ if (!models)
561
+ continue;
562
+ for (const [modelId, modelData] of Object.entries(models)) {
563
+ result.push({
564
+ fullModel: `${providerKey}/${modelId}`,
565
+ variants: modelData?.variants ?? []
566
+ });
567
+ }
568
+ }
569
+ return result;
570
+ }
514
571
  function writeDefaultConfig() {
515
572
  if (fs.existsSync(COHUB_CONFIG_PATH)) {
516
573
  return { success: true, message: "oh-my-opencode-cohub.json 已存在,跳过" };
517
574
  }
575
+ const flatModels = flattenModelsFromOpenCode();
576
+ if (flatModels.length === 0) {
577
+ const fallbackConfig = {
578
+ $schema: "https://unpkg.com/oh-my-opencode-cohub@latest/oh-my-opencode-cohub.schema.json",
579
+ agents: {},
580
+ council: { presets: {} },
581
+ _comment: "未找到可用供应商。请在 opencode.json 中配置 provider 后重新运行 install,或手动在此文件中配置 model 和 variant。"
582
+ };
583
+ try {
584
+ const dir = path.dirname(COHUB_CONFIG_PATH);
585
+ if (!fs.existsSync(dir))
586
+ fs.mkdirSync(dir, { recursive: true });
587
+ fs.writeFileSync(COHUB_CONFIG_PATH, JSON.stringify(fallbackConfig, null, 2), "utf-8");
588
+ return { success: true, message: "✓ 已创建 oh-my-opencode-cohub.json(无可用 provider,请手动配置模型)" };
589
+ } catch {
590
+ return { success: false, message: "⚠ 无法创建配置文件" };
591
+ }
592
+ }
593
+ const agentSpecs = [
594
+ { name: "co-orchestrator", keywords: HEAVY_KEYWORDS, agentType: "orchestrator" },
595
+ { name: "co-oracle", keywords: HEAVY_KEYWORDS, agentType: "oracle" },
596
+ { name: "co-librarian", keywords: LIGHT_KEYWORDS, agentType: "librarian" },
597
+ { name: "co-explorer", keywords: LIGHT_KEYWORDS, agentType: "explorer" },
598
+ { name: "co-designer", keywords: DESIGN_KEYWORDS, agentType: "designer" },
599
+ { name: "co-fixer", keywords: LIGHT_KEYWORDS, agentType: "fixer" },
600
+ { name: "co-observer", keywords: OBSERVER_KEYWORDS, agentType: "observer" },
601
+ { name: "co-council", keywords: HEAVY_KEYWORDS, agentType: "council" },
602
+ { name: "co-rule-user", keywords: LIGHT_KEYWORDS, agentType: "rule-user" },
603
+ { name: "co-rule-project", keywords: LIGHT_KEYWORDS, agentType: "rule-project" },
604
+ { name: "co-rule-app", keywords: LIGHT_KEYWORDS, agentType: "rule-app" },
605
+ { name: "co-planner", keywords: HEAVY_KEYWORDS, agentType: "planner" }
606
+ ];
607
+ const agents = {};
608
+ let matched = 0;
609
+ for (const spec of agentSpecs) {
610
+ const best = findBestModel(flatModels, spec.keywords, spec.agentType);
611
+ if (best) {
612
+ agents[spec.name] = { model: best.model, ...best.variant ? { variant: best.variant } : {} };
613
+ matched++;
614
+ }
615
+ }
616
+ const usedProviders = new Set;
617
+ const councilSlots = [
618
+ { key: "alpha", keywords: HEAVY_KEYWORDS, agentType: "council" },
619
+ { key: "beta", keywords: LIGHT_KEYWORDS, agentType: "council" },
620
+ { key: "gamma", keywords: DESIGN_KEYWORDS, agentType: "council" }
621
+ ];
622
+ const presets = {};
623
+ let councilCount = 0;
624
+ for (const slot of councilSlots) {
625
+ const candidates = flatModels.filter((m) => !usedProviders.has(m.fullModel.split("/")[0]));
626
+ const pool = candidates.length > 0 ? candidates : flatModels;
627
+ const best = findBestModel(pool, slot.keywords, slot.agentType);
628
+ if (best && !usedProviders.has(best.model.split("/")[0])) {
629
+ presets[slot.key] = { model: best.model, ...best.variant ? { variant: best.variant } : {} };
630
+ usedProviders.add(best.model.split("/")[0]);
631
+ councilCount++;
632
+ }
633
+ }
634
+ if (councilCount < 3 && councilCount < flatModels.length) {
635
+ const reservedSlots = ["alpha", "beta", "gamma"];
636
+ for (const m of flatModels) {
637
+ if (councilCount >= 3)
638
+ break;
639
+ const provider = m.fullModel.split("/")[0];
640
+ if (!usedProviders.has(provider)) {
641
+ const slot = reservedSlots[councilCount];
642
+ presets[slot] = { model: m.fullModel, ...pickBestVariant(m.variants, "council") ? { variant: pickBestVariant(m.variants, "council") } : {} };
643
+ usedProviders.add(provider);
644
+ councilCount++;
645
+ }
646
+ }
647
+ }
518
648
  const defaultConfig = {
519
649
  $schema: "https://unpkg.com/oh-my-opencode-cohub@latest/oh-my-opencode-cohub.schema.json",
520
- agents: {
521
- "co-orchestrator": { model: "deepseek/deepseek-v4-pro", variant: "max" },
522
- "co-oracle": { model: "deepseek/deepseek-v4-pro", variant: "max" },
523
- "co-librarian": { model: "deepseek/deepseek-v4-flash", variant: "low" },
524
- "co-explorer": { model: "deepseek/deepseek-v4-flash", variant: "low" },
525
- "co-designer": { model: "minimax/MiniMax-M3", variant: "medium" },
526
- "co-fixer": { model: "deepseek/deepseek-v4-flash", variant: "high" },
527
- "co-observer": { model: "codermxtest/gpt-5.5", variant: "low" },
528
- "co-council": { model: "deepseek/deepseek-v4-pro", variant: "high" },
529
- "co-rule-user": { model: "deepseek/deepseek-v4-flash", variant: "medium" },
530
- "co-rule-project": { model: "deepseek/deepseek-v4-flash", variant: "medium" },
531
- "co-rule-app": { model: "deepseek/deepseek-v4-flash", variant: "medium" },
532
- "co-planner": { model: "deepseek/deepseek-v4-pro", variant: "high" }
533
- },
534
- council: {
650
+ agents,
651
+ council: councilCount > 0 ? {
535
652
  default_preset: "default",
536
653
  timeout: 180000,
537
654
  councillor_execution_mode: "parallel",
538
655
  councillor_retries: 3,
539
656
  presets: {
540
- default: {
541
- alpha: { model: "deepseek/deepseek-v4-pro", variant: "max" },
542
- beta: { model: "deepseek/deepseek-v4-flash", variant: "high" },
543
- gamma: { model: "minimax/MiniMax-M3", variant: "medium" }
544
- }
657
+ default: presets
545
658
  }
546
- }
659
+ } : { presets: {} }
547
660
  };
548
661
  try {
549
662
  const dir = path.dirname(COHUB_CONFIG_PATH);
550
663
  if (!fs.existsSync(dir))
551
664
  fs.mkdirSync(dir, { recursive: true });
552
665
  fs.writeFileSync(COHUB_CONFIG_PATH, JSON.stringify(defaultConfig, null, 2), "utf-8");
553
- return { success: true, message: "✓ 已创建 oh-my-opencode-cohub.json 配置模板" };
666
+ return { success: true, message: `✓ 已智能匹配 ${matched}/12 个代理的模型,生成 oh-my-opencode-cohub.json` };
554
667
  } catch {
555
668
  return { success: false, message: "⚠ 无法创建配置文件" };
556
669
  }
@@ -680,7 +793,131 @@ async function main() {
680
793
  console.log(`
681
794
  ✅ CoHub 安装完成!`);
682
795
  console.log(' 重启 OpenCode 后,TAB 选择 "co-orchestrator" 开始纯调度模式。');
683
- console.log(" 已注册 13 个 co-* 代理到 opencode.json 的 agent 字段。");
796
+ console.log(" 已注册 12 个 co-* 代理到 opencode.json 的 agent 字段。");
797
+ console.log(`
798
+ ${"=".repeat(60)}`);
799
+ console.log("\uD83D\uDCCB 已自动生成默认代理模型配置。如需自定义,可复制以下文案让 AI 帮你优化:");
800
+ console.log(`${"=".repeat(60)}
801
+ `);
802
+ const aiPrompt = `
803
+ ## 你的任务
804
+
805
+ 帮我生成 oh-my-opencode-cohub 的配置文件。
806
+
807
+ **要求:收到后先分析我的环境、输出配置方案表格、等我确认后再写入文件,不要直接动手改。**
808
+
809
+ ## 执行步骤
810
+
811
+ ### 第一步:分析环境
812
+
813
+ 读取 \`~/.config/opencode/opencode.json\`,找到所有已配置的 provider 和 model,整理成表格给我看。
814
+
815
+ ### 第二步:输出配置方案
816
+
817
+ 根据下面规则,输出每个代理的 model 和 variant 分配表格,等我确认。
818
+
819
+ ### 第三步:写入文件
820
+
821
+ 确认后将配置写入 \`~/.config/opencode/oh-my-opencode-cohub.json\`。
822
+
823
+ ## 配置文件结构
824
+
825
+ \`\`\`json
826
+ {
827
+ "$schema": "https://unpkg.com/oh-my-opencode-cohub@latest/oh-my-opencode-cohub.schema.json",
828
+ "agents": {
829
+ "co-orchestrator": { "model": "provider/model", "variant": "max" },
830
+ ...
831
+ },
832
+ "council": {
833
+ "default_preset": "default",
834
+ "timeout": 180000,
835
+ "councillor_execution_mode": "parallel",
836
+ "councillor_retries": 3,
837
+ "presets": {
838
+ "default": {
839
+ "alpha": { "model": "provider/model", "variant": "max" },
840
+ "beta": { "model": "provider/model", "variant": "high" },
841
+ "gamma": { "model": "provider/model", "variant": "medium" }
842
+ }
843
+ }
844
+ }
845
+ }
846
+ \`\`\`
847
+
848
+ ## 12 个代理配置规则
849
+
850
+ | 代理 | 角色 | 推理强度 | variant 建议 | 模型偏好 |
851
+ |------|------|---------|-------------|---------|
852
+ | co-orchestrator | 纯调度者,编排任务、委派执行 | **重型** | max / xhigh | pro、max、sonnet、opus 等强推理模型 |
853
+ | co-oracle | 战略顾问,架构审查、复杂调试 | **重型** | max / xhigh | 同上 |
854
+ | co-planner | 方案制定,综合信息输出任务分解 | **重型** | max / xhigh | 同上 |
855
+ | co-council | 多模型共识,跨多个 LLM 综合 | **重型** | high / xhigh | 同上 |
856
+ | co-librarian | 研究员,查文档、搜 GitHub、Web 搜索 | **轻型** | low / medium | flash、mini、haiku 等轻量快速模型 |
857
+ | co-explorer | 代码探索者,grep/glob 搜索定位 | **轻型** | low / medium | 同上 |
858
+ | co-fixer | 执行者,代码修改、编译、测试 | **轻型** | low / medium | 同上 |
859
+ | co-rule-user | 分析用户级 AGENTS.md 规范 | **轻型** | low / medium | 同上 |
860
+ | co-rule-project | 分析项目 AGENTS.md 规范 | **轻型** | low / medium | 同上 |
861
+ | co-rule-app | 分析 .opencode/rules/* 应用规则 | **轻型** | low / medium | 同上 |
862
+ | co-designer | 设计师,UI/UX 设计、视觉润色 | **中等** | high / medium | sonnet、claude、minimax 等前端/视觉强的模型 |
863
+ | co-observer | 观察者,图片/PDF/截图视觉分析 | **中等** | medium / high | vision、flash 等支持视觉的模型 |
864
+
865
+ ## council 详细说明
866
+
867
+ council 是内置的多模型共识机制,会将同一个问题发给 3 个 councillor 并行回答,然后综合出最优方案。
868
+
869
+ | councillor | 角色定位 | 推理强度 | variant 建议 |
870
+ |-----------|---------|---------|-------------|
871
+ | alpha | 主力深度推理 | **重型** | max / xhigh |
872
+ | beta | 第二视角互补 | **轻型/中等** | high |
873
+ | gamma | 第三方校验 | **中等** | medium / high |
874
+
875
+ **关键配置项说明:**
876
+
877
+ | 字段 | 默认值 | 说明 |
878
+ |------|--------|------|
879
+ | \`default_preset\` | \`"default"\` | 默认使用的 preset 名称,可以定义多个 preset(如 \`"quick"\` 快速共识、\`"deep"\` 深度共识) |
880
+ | \`timeout\` | \`180000\`(3 分钟) | 单个 councillor 的超时时间(毫秒),所有 councillor 并行执行 |
881
+ | \`councillor_execution_mode\` | \`"parallel"\` | 执行模式:\`"parallel"\` 并行(快)或 \`"serial"\` 串行(省 tokens) |
882
+ | \`councillor_retries\` | \`3\` | 单个 councillor 调用失败后的重试次数 |
883
+
884
+ **presets 示例(多套配置):**
885
+
886
+ \`\`\`json
887
+ "presets": {
888
+ "default": {
889
+ "alpha": { "model": "deepseek/deepseek-v4-pro", "variant": "max" },
890
+ "beta": { "model": "anthropic/claude-sonnet-4-20250514", "variant": "high" },
891
+ "gamma": { "model": "openai/gpt-5.2", "variant": "high" }
892
+ },
893
+ "quick": {
894
+ "alpha": { "model": "deepseek/deepseek-v4-pro", "variant": "high" },
895
+ "beta": { "model": "openai/gpt-5.2", "variant": "medium" },
896
+ "gamma": { "model": "anthropic/claude-sonnet-4-20250514", "variant": "medium" }
897
+ }
898
+ }
899
+ \`\`\`
900
+
901
+ ## 分配规则
902
+
903
+ - 从 opencode.json 读取已配置的 provider,按上表规则为每个代理分配 model 和 variant
904
+ - 只有 1 个 provider:所有代理都用它,variant 按表格建议选不同档位
905
+ - 有多个 provider:重型代理优先选最强推理 provider,轻型选最快 provider
906
+ - council 的 alpha/beta/gamma 优先选 3 个不同 provider;不够 3 个时用同一 provider 的不同 model
907
+ - opencode.json 无任何 provider 时,生成占位配置并在 \`_comment\` 字段提示用户先配置
908
+
909
+ ## 注意
910
+
911
+ - 只写入 \`oh-my-opencode-cohub.json\`,不要修改 \`opencode.json\`
912
+ - agent 名必须用 \`co-\` 前缀(共 12 个),不要遗漏
913
+ `;
914
+ const lines = aiPrompt.trim().split(`
915
+ `);
916
+ for (const line of lines) {
917
+ console.log(line);
918
+ }
919
+ console.log(`
920
+ ${"=".repeat(60)}`);
684
921
  } else if (command === "uninstall") {
685
922
  console.log(`\uD83E\uDDF9 CoHub 卸载中...
686
923
  `);
@@ -29,7 +29,5 @@ export interface CoHubConfig {
29
29
  }
30
30
  /** 加载用户配置 */
31
31
  export declare function loadCoHubConfig(): CoHubConfig;
32
- /** 示例配置模板 */
33
- export declare const DEFAULT_CONFIG: CoHubConfig;
34
32
  export { DEFAULT_CONTEXT_CONFIG };
35
33
  //# sourceMappingURL=loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,uBAAuB;AACvB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,cAAc,EAAE,MAAM,GAAG,gBAAgB,CAAC;CAC5C;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yBAAyB,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,oBAAoB;AACpB,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAClC;AAKD,aAAa;AACb,wBAAgB,eAAe,IAAI,WAAW,CAQ7C;AAED,aAAa;AACb,eAAO,MAAM,cAAc,EAAE,WAe5B,CAAC;AAEF,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,uBAAuB;AACvB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,cAAc,EAAE,MAAM,GAAG,gBAAgB,CAAC;CAC5C;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yBAAyB,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,oBAAoB;AACpB,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAClC;AAKD,aAAa;AACb,wBAAgB,eAAe,IAAI,WAAW,CAQ7C;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAyIlD,QAAA,MAAM,WAAW,EAAE,MAmclB,CAAC;AAEF,eAAO,MAAM,MAAM,QAAc,CAAC;AAClC,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAyHlD,QAAA,MAAM,WAAW,EAAE,MA6flB,CAAC;AAEF,eAAO,MAAM,MAAM,QAAc,CAAC;AAClC,eAAe,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/prompts/orchestrator.ts
2
2
  var ORCHESTRATOR_PROMPT = `<角色>
3
- 你是纯调度者(Orchestrator)。唯一职责:理解需求 → 委派信息收集 → 制定方案 → 调度子代理执行 → 委派验证。**绝不亲自使用任何文件/代码操作工具**(read、grep、glob、bash、edit、write 等)。可使用的工具是调度工具(task、todowrite)。
3
+ 你是纯调度者(Orchestrator)。唯一职责:理解需求 → 委派信息收集 → 委派方案制定 → 审核方案 → 调度执行 → 委派验证。**绝不亲自使用任何文件/代码操作工具**(read、grep、glob、bash、edit、write 等)。可使用的工具是调度工具(task、todowrite)。
4
4
  </角色>
5
5
 
6
6
  <子代理>
@@ -31,19 +31,19 @@ orchestrator 委派时可参考上述原则。不确定时,co-oracle 自身会
31
31
  纯知识问答直接回,代码需求继续。
32
32
 
33
33
  ## 2. 信息收集(委派子代理)
34
- @co-explorer 搜索定位 → @co-librarian 外部研究 → @co-observer 多媒体。并行启动,不动手。
35
-
36
- ## 3. 制定方案
37
- 综合信息→子任务分解→委派对象→并行策略→todowrite 记录。**方案末尾必须提供选项供用户选择**(如:A. 立即执行 / B. 修改方案 / C. 取消),等待用户回复后再进入调度执行。
38
-
39
- ## 4. 调度执行
40
- 清晰文件范围+背景启动+追踪不重复+协调冲突。委派指令用中文。
34
+ @co-explorer 搜索定位 → @co-librarian 外部研究 → @co-observer 多媒体。并行启动,不动手。收集完成后汇总各子代理结果 → 进入步骤3 委派 @co-planner 制定方案。
41
35
 
42
36
  **规则分析并行策略**:需要对照 \`.opencode/rules/*.md\` 时,不要只派发一个 @co-rule-app。策略如下:
43
37
  1. 先用 \`glob\`(委派 @co-explorer)列出 \`.opencode/rules/\` 下的所有 .md 文件
44
38
  2. 按每 1-2 个文件分一组,并行派发多个 @co-rule-app 实例
45
39
  3. 每个实例的 prompt 中明确指定它负责的规则文件列表(如 \`请分析 rules/A.md 和 rules/B.md\`)
46
- 4. 所有实例完成后,由 Orchestrator 汇总各实例返回的建议,统一纳入方案
40
+ 4. 所有实例完成后,由 Orchestrator 汇总各实例返回的建议,作为 @co-planner 的输入之一。
41
+
42
+ ## 3. 制定方案(委派 @co-planner)
43
+ 将信息收集结果(代码库结构、API文档、规范分析等)汇总后委派给 @co-planner 制定结构化方案。收到 @co-planner 的方案后,orchestrator 审核(检查需求覆盖度、委派对象合理性、并行策略可行性),补充修正后,用 \`todowrite\` 创建正式任务列表。**方案末尾必须提供选项供用户选择**(如:A. 立即执行 / B. 修改方案 / C. 取消),等待用户回复后再进入调度执行。
44
+
45
+ ## 4. 调度执行
46
+ 清晰文件范围+背景启动+追踪不重复+协调冲突。委派指令用中文。
47
47
 
48
48
  ## 5. 验证(全部委派)
49
49
  @co-fixer 编译测试 → @co-oracle 代码审查 → @co-designer UI审查。发现问题重新委派。
@@ -58,9 +58,9 @@ orchestrator 委派时可参考上述原则。不确定时,co-oracle 自身会
58
58
  <rule priority="1" name="先方案后执行">
59
59
  ### 规则 1:理解需求后必须先输出方案
60
60
 
61
- **⚠️ 长会话警告:这是最容易被遗忘的规则。无论会话多长、已经执行了多少步、之前分析过什么,每次收到新需求时,必须重新从头执行:分析需求 → 输出方案 → todowrite → 提供选项供用户选择 → 委派执行。禁止"前面分析过了这次直接改"、"改着改着就忘了"。**
61
+ **⚠️ 长会话警告:这是最容易被遗忘的规则。无论会话多长、已经执行了多少步、之前分析过什么,每次收到新需求时,必须重新从头执行:分析需求 → 委派 @co-planner 制定方案 → 审核 → todowrite → 提供选项供用户选择 → 委派执行。禁止"前面分析过了这次直接改"、"改着改着就忘了"。**
62
62
 
63
- 收到需求后(涉及代码或文件修改时),**禁止立即执行**。必须先分析需求,输出可验证的任务分解方案,**末尾提供选项(如"立即执行 / 修改方案")供用户决定**。方案包含:
63
+ 收到需求后(涉及代码或文件修改时),**禁止立即执行**。必须先分析需求,委派 @co-planner 制定方案,orchestrator 审核后输出可验证的任务分解方案,**末尾提供选项(如"立即执行 / 修改方案")供用户决定**。方案包含:
64
64
  (纯信息性问题可直接回答,无需方案。)
65
65
  - 子任务列表及其依赖关系
66
66
  - 每个子任务的委派对象(@co-explorer / @co-librarian / @co-fixer / @co-designer / @co-oracle / @co-observer)
@@ -1647,7 +1647,7 @@ var CoHubPlugin = async (input, options) => {
1647
1647
  if (!fs3.existsSync(STATE_DIR)) {
1648
1648
  fs3.mkdirSync(STATE_DIR, { recursive: true });
1649
1649
  }
1650
- const configs = agents.map((a) => {
1650
+ const configs = agents.filter((a) => a.config.model).map((a) => {
1651
1651
  const modelStr = a.config.model;
1652
1652
  const parts = modelStr.split("/");
1653
1653
  const provider = parts.length > 1 ? parts[0] : "default";
@@ -1666,42 +1666,40 @@ var CoHubPlugin = async (input, options) => {
1666
1666
  const agents = [
1667
1667
  {
1668
1668
  name: "co-orchestrator",
1669
- config: { mode: "primary", model: "deepseek/deepseek-v4-pro", variant: "max", prompt: ORCHESTRATOR_PROMPT }
1669
+ config: { mode: "primary", prompt: ORCHESTRATOR_PROMPT }
1670
1670
  },
1671
1671
  {
1672
1672
  name: "co-oracle",
1673
- config: { mode: "subagent", model: "deepseek/deepseek-v4-pro", variant: "max", temperature: 0.1, prompt: ORACLE_PROMPT }
1673
+ config: { mode: "subagent", temperature: 0.1, prompt: ORACLE_PROMPT }
1674
1674
  },
1675
1675
  {
1676
1676
  name: "co-librarian",
1677
- config: { mode: "subagent", model: "deepseek/deepseek-v4-flash", prompt: LIBRARIAN_PROMPT }
1677
+ config: { mode: "subagent", prompt: LIBRARIAN_PROMPT }
1678
1678
  },
1679
1679
  {
1680
1680
  name: "co-explorer",
1681
- config: { mode: "subagent", model: "deepseek/deepseek-v4-flash", prompt: EXPLORER_PROMPT }
1681
+ config: { mode: "subagent", prompt: EXPLORER_PROMPT }
1682
1682
  },
1683
1683
  {
1684
1684
  name: "co-designer",
1685
- config: { mode: "subagent", model: "minimax/MiniMax-M3", variant: "medium", prompt: DESIGNER_PROMPT }
1685
+ config: { mode: "subagent", prompt: DESIGNER_PROMPT }
1686
1686
  },
1687
1687
  {
1688
1688
  name: "co-fixer",
1689
1689
  mode: "subagent",
1690
1690
  description: "执行者——代码修改、构建、测试",
1691
- config: { mode: "subagent", model: "deepseek/deepseek-v4-flash", variant: "high", prompt: FIXER_PROMPT }
1691
+ config: { mode: "subagent", prompt: FIXER_PROMPT }
1692
1692
  },
1693
1693
  {
1694
1694
  name: "co-observer",
1695
1695
  description: "观察者——图片/PDF/截图视觉分析",
1696
- config: { mode: "subagent", model: "codermxtest/gpt-5.5", prompt: OBSERVER_PROMPT }
1696
+ config: { mode: "subagent", prompt: OBSERVER_PROMPT }
1697
1697
  },
1698
1698
  {
1699
1699
  name: "co-council",
1700
1700
  description: "多模型共识——并行 LLM 综合",
1701
1701
  config: {
1702
1702
  mode: "subagent",
1703
- model: "deepseek/deepseek-v4-pro",
1704
- variant: "high",
1705
1703
  prompt: COUNCIL_PROMPT,
1706
1704
  permission: { council_session: "allow" }
1707
1705
  }
@@ -1709,22 +1707,22 @@ var CoHubPlugin = async (input, options) => {
1709
1707
  {
1710
1708
  name: "co-rule-user",
1711
1709
  description: "用户规范分析——~/.config/opencode/AGENTS.md",
1712
- config: { mode: "subagent", model: "deepseek/deepseek-v4-flash", prompt: RULE_USER_PROMPT }
1710
+ config: { mode: "subagent", prompt: RULE_USER_PROMPT }
1713
1711
  },
1714
1712
  {
1715
1713
  name: "co-rule-project",
1716
1714
  description: "项目规范分析——项目 AGENTS.md",
1717
- config: { mode: "subagent", model: "deepseek/deepseek-v4-flash", prompt: RULE_PROJECT_PROMPT }
1715
+ config: { mode: "subagent", prompt: RULE_PROJECT_PROMPT }
1718
1716
  },
1719
1717
  {
1720
1718
  name: "co-rule-app",
1721
1719
  description: "应用规则分析——.opencode/rules/*.md",
1722
- config: { mode: "subagent", model: "deepseek/deepseek-v4-flash", prompt: RULE_APP_PROMPT }
1720
+ config: { mode: "subagent", prompt: RULE_APP_PROMPT }
1723
1721
  },
1724
1722
  {
1725
1723
  name: "co-planner",
1726
1724
  description: "方案制定——综合需求+信息+规范输出任务分解",
1727
- config: { mode: "subagent", model: "deepseek/deepseek-v4-pro", variant: "high", prompt: PLANNER_PROMPT }
1725
+ config: { mode: "subagent", prompt: PLANNER_PROMPT }
1728
1726
  }
1729
1727
  ];
1730
1728
  const userConfig = loadCoHubConfig();
@@ -1741,6 +1739,7 @@ var CoHubPlugin = async (input, options) => {
1741
1739
  }
1742
1740
  }
1743
1741
  }
1742
+ syncAgentConfig();
1744
1743
  for (const agent of agents) {
1745
1744
  const override = fileOverrides[agent.name];
1746
1745
  if (override) {
@@ -1760,11 +1759,7 @@ var CoHubPlugin = async (input, options) => {
1760
1759
  councillor_execution_mode: "parallel",
1761
1760
  councillor_retries: 3,
1762
1761
  presets: {
1763
- default: {
1764
- alpha: { model: "deepseek/deepseek-v4-pro", variant: "max" },
1765
- beta: { model: "deepseek/deepseek-v4-flash", variant: "high" },
1766
- gamma: { model: "minimax/MiniMax-M3", variant: "medium" }
1767
- }
1762
+ default: {}
1768
1763
  }
1769
1764
  };
1770
1765
  const contextConfig = userConfig.context ?? {};
@@ -1772,7 +1767,6 @@ var CoHubPlugin = async (input, options) => {
1772
1767
  const councilConfig = userConfig.council ?? DEFAULT_COUNCIL_CONFIG;
1773
1768
  const councilManager = new CouncilManager(input.client, input.directory, councilConfig);
1774
1769
  const councilTools = createCouncilTool(input, councilManager);
1775
- syncAgentConfig();
1776
1770
  function extractChildSessionId(output) {
1777
1771
  if (!output || typeof output !== "object")
1778
1772
  return;
@@ -1873,7 +1867,7 @@ var CoHubPlugin = async (input, options) => {
1873
1867
  ` + "**当前任务**: " + description + `
1874
1868
  `;
1875
1869
  const targetField = typeof output.args.prompt === "string" ? "prompt" : "description";
1876
- output.args[targetField] = (targetField === "prompt" ? output.args.prompt : description) + contextBlock;
1870
+ output.args[targetField] = ((targetField === "prompt" ? output.args.prompt : description) ?? "") + contextBlock;
1877
1871
  await contextEngine.fillContextAsync(contextId, input2.sessionID, {
1878
1872
  strategy
1879
1873
  });
@@ -1958,6 +1952,20 @@ var CoHubPlugin = async (input, options) => {
1958
1952
  try {
1959
1953
  if (!output.messages || !Array.isArray(output.messages))
1960
1954
  return;
1955
+ if (output.messages) {
1956
+ for (let d = 0;d < output.messages.length; d++) {
1957
+ const msg = output.messages[d];
1958
+ const parts = msg.parts;
1959
+ if (!parts || !Array.isArray(parts) || parts.length === 0) {
1960
+ appendLog("messages.transform", `⚠️ 消息[${d}] role=${msg.info?.role ?? "?"} parts为空`);
1961
+ } else {
1962
+ const hasTextPart = parts.some((p) => p.type === "text");
1963
+ if (!hasTextPart && msg.info?.role === "user") {
1964
+ appendLog("messages.transform", `⚠️ 消息[${d}] role=user parts无text类型, types=[${parts.map((p) => p.type).join(",")}]`);
1965
+ }
1966
+ }
1967
+ }
1968
+ }
1961
1969
  let lastUserMsg;
1962
1970
  let sessionID;
1963
1971
  for (let i = output.messages.length - 1;i >= 0; i--) {
@@ -1970,8 +1978,13 @@ var CoHubPlugin = async (input, options) => {
1970
1978
  }
1971
1979
  if (!lastUserMsg)
1972
1980
  return;
1973
- if (!lastUserMsg.parts || !Array.isArray(lastUserMsg.parts))
1974
- return;
1981
+ if (!lastUserMsg.parts || !Array.isArray(lastUserMsg.parts) || lastUserMsg.parts.length === 0) {
1982
+ lastUserMsg.parts = [{ type: "text", text: " " }];
1983
+ appendLog("messages.transform", `⚠️ lastUserMsg parts为空,已推入占位text part (session=${sessionID?.slice(0, 20) ?? "?"})`);
1984
+ } else if (!lastUserMsg.parts.some((p) => p.type === "text")) {
1985
+ lastUserMsg.parts.push({ type: "text", text: " " });
1986
+ appendLog("messages.transform", `⚠️ lastUserMsg parts无text类型,已推入占位text part (session=${sessionID?.slice(0, 20) ?? "?"})`);
1987
+ }
1975
1988
  const board = tracker.getBoardText();
1976
1989
  if (board) {
1977
1990
  for (let j = lastUserMsg.parts.length - 1;j >= 0; j--) {
@@ -1993,6 +2006,45 @@ var CoHubPlugin = async (input, options) => {
1993
2006
  }
1994
2007
  }
1995
2008
  }
2009
+ {
2010
+ let userContent = "";
2011
+ for (const p of lastUserMsg.parts ?? []) {
2012
+ if (p.type === "text")
2013
+ userContent += p.text ?? "";
2014
+ }
2015
+ if (!userContent.trim()) {
2016
+ for (const p of lastUserMsg.parts ?? []) {
2017
+ if (p.type === "text") {
2018
+ p.text = " ";
2019
+ break;
2020
+ }
2021
+ }
2022
+ appendLog("messages.transform", `⚠️ 注入后 content 为空,已设空格占位 (session=${sessionID?.slice(0, 20) ?? "?"})`);
2023
+ }
2024
+ }
2025
+ for (let i = 0;i < output.messages.length; i++) {
2026
+ const msg = output.messages[i];
2027
+ const parts = msg.parts ?? [];
2028
+ let totalText = "";
2029
+ for (const p of parts) {
2030
+ if (p.type === "text" && p.text)
2031
+ totalText += p.text;
2032
+ }
2033
+ if (!totalText.trim() && parts.length > 0) {
2034
+ let found = false;
2035
+ for (const p of parts) {
2036
+ if (p.type === "text") {
2037
+ p.text = " ";
2038
+ found = true;
2039
+ break;
2040
+ }
2041
+ }
2042
+ if (!found) {
2043
+ parts.push({ type: "text", text: " " });
2044
+ }
2045
+ appendLog("messages.transform", `⚠️ 消息[${i}] role=${msg.info?.role ?? "?"} content为空,已设占位 (session=${sessionID?.slice(0, 20) ?? "?"})`);
2046
+ }
2047
+ }
1996
2048
  } catch (err) {
1997
2049
  appendLog("messages.transform", "hook 失败", err);
1998
2050
  }
@@ -1,2 +1,2 @@
1
- export declare const ORCHESTRATOR_PROMPT = "<\u89D2\u8272>\n\u4F60\u662F\u7EAF\u8C03\u5EA6\u8005\uFF08Orchestrator\uFF09\u3002\u552F\u4E00\u804C\u8D23\uFF1A\u7406\u89E3\u9700\u6C42 \u2192 \u59D4\u6D3E\u4FE1\u606F\u6536\u96C6 \u2192 \u5236\u5B9A\u65B9\u6848 \u2192 \u8C03\u5EA6\u5B50\u4EE3\u7406\u6267\u884C \u2192 \u59D4\u6D3E\u9A8C\u8BC1\u3002**\u7EDD\u4E0D\u4EB2\u81EA\u4F7F\u7528\u4EFB\u4F55\u6587\u4EF6/\u4EE3\u7801\u64CD\u4F5C\u5DE5\u5177**\uFF08read\u3001grep\u3001glob\u3001bash\u3001edit\u3001write \u7B49\uFF09\u3002\u53EF\u4F7F\u7528\u7684\u5DE5\u5177\u662F\u8C03\u5EA6\u5DE5\u5177\uFF08task\u3001todowrite\uFF09\u3002\n</\u89D2\u8272>\n\n<\u5B50\u4EE3\u7406>\n\n@co-explorer - \u53EA\u8BFB\u3002Grep/Glob/AST \u641C\u7D22\u5B9A\u4F4D\u3002\u59D4\u6D3E\uFF1A\u53D1\u73B0\u4EE3\u7801\u5E93\u5185\u5BB9\u65F6\u3002\n@co-librarian - \u53EA\u8BFB+Web\u3002\u5B98\u65B9\u6587\u6863/API/GitHub \u7814\u7A76\u3002\u59D4\u6D3E\uFF1A\u4E0D\u719F\u6089\u7684\u5E93/\u8FB9\u7F18\u60C5\u51B5\u3002\n@co-oracle - \u53EA\u8BFB\u3002\u67B6\u6784\u51B3\u7B56/\u4EE3\u7801\u5BA1\u67E5/YAGNI \u7B80\u5316/\u590D\u6742\u8C03\u8BD5\u3002\u59D4\u6D3E\uFF1A\u9AD8\u98CE\u9669\u51B3\u7B56/\u53CD\u590D bug/\u5B89\u5168\u5BA1\u67E5\u3002\n@co-designer - \u8BFB\u5199\u3002UI/UX \u8BBE\u8BA1/\u89C6\u89C9\u6DA6\u8272/\u54CD\u5E94\u5F0F\u5E03\u5C40\u3002\u59D4\u6D3E\uFF1A\u9700\u8981\u6DA6\u8272\u7684\u754C\u9762/UX \u7EC4\u4EF6\u3002\n@co-fixer - \u8BFB\u5199+Bash\u3002\u4EE3\u7801\u4FEE\u6539\u6267\u884C(\u65E0\u8BBA\u591A\u5C0F)\u3002\u59D4\u6D3E\uFF1A\u6240\u6709\u6587\u4EF6\u7F16\u8F91/\u5199\u5165/\u5220\u9664\u3002\n@co-observer - \u53EA\u8BFB\u3002\u56FE\u7247/PDF/\u622A\u56FE\u89C6\u89C9\u5206\u6790\u3002\u59D4\u6D3E\uFF1A\u591A\u5A92\u4F53\u6587\u4EF6\u5206\u6790\u65F6(\u542B\u5B8C\u6574\u8DEF\u5F84)\u3002\n@co-council - \u53EA\u8BFB\u3002\u591A\u6A21\u578B\u5E76\u884C\u5171\u8BC6\u3002\u59D4\u6D3E\uFF1A\u591A\u4E13\u5BB6\u89C6\u89D2/\u4E0D\u53EF\u9006\u51B3\u7B56\uFF08\u6570\u636E\u8FC1\u79FB/API \u53D8\u66F4\uFF09\u3002\u9519\u4E86\u8FD8\u80FD\u6539\u2192@co-oracle\uFF0C\u9519\u4E86\u5C31\u5B8C\u4E86\u2192@co-council\u3002\n@co-rule-user - \u53EA\u8BFB\u3002\u5206\u6790\u7528\u6237\u7EA7 AGENTS.md(~/.config/opencode/AGENTS.md)\u7EA6\u675F\u3002\u59D4\u6D3E\uFF1A\u65B9\u6848\u9700\u5BF9\u7167\u7528\u6237\u89C4\u5219\u65F6\u3002\n@co-rule-project - \u53EA\u8BFB\u3002\u5206\u6790\u9879\u76EE AGENTS.md \u7EA6\u675F\u3002\u59D4\u6D3E\uFF1A\u65B9\u6848\u9700\u5BF9\u7167\u9879\u76EE\u89C4\u5219\u65F6\u3002\n@co-rule-app - \u53EA\u8BFB\u3002\u5206\u6790 .opencode/rules/*.md \u5E94\u7528\u89C4\u5219\u3002**\u5E76\u884C\u7B56\u7565**\uFF1A\u5F53 rules \u76EE\u5F55\u4E0B\u6709 N \u4E2A\u6587\u4EF6\u65F6\uFF0C\u5E76\u884C\u542F\u52A8 N/2\uFF08\u5411\u4E0A\u53D6\u6574\uFF09\u4E2A @co-rule-app \u5B9E\u4F8B\uFF0C\u6BCF\u4E2A\u5B9E\u4F8B\u8D1F\u8D23 1-2 \u4E2A\u89C4\u5219\u6587\u4EF6\uFF08\u5728 prompt \u4E2D\u660E\u786E\u6307\u5B9A\u6587\u4EF6\u5217\u8868\uFF09\u3002\u6240\u6709\u5B9E\u4F8B\u5B8C\u6210\u540E\uFF0COrchestrator \u6C47\u603B\u5EFA\u8BAE\u3002\u59D4\u6D3E\uFF1A\u65B9\u6848\u9700\u5BF9\u7167\u5B89\u5168/\u6D4B\u8BD5/\u6570\u636E\u5E93\u7B49\u5E94\u7528\u89C4\u5219\u65F6\u3002\n@co-planner - \u53EA\u8BFB\u3002\u7EFC\u5408\u9700\u6C42+\u4FE1\u606F+\u89C4\u8303\uFF0C\u8F93\u51FA\u7ED3\u6784\u5316\u4EFB\u52A1\u5206\u89E3\u65B9\u6848\u3002\u59D4\u6D3E\uFF1A\u4FE1\u606F\u6536\u96C6\u548C\u89C4\u8303\u5206\u6790\u5B8C\u6210\u540E\u3002\n\n</\u5B50\u4EE3\u7406>\n\n### @council vs @oracle \u9009\u62E9\u6307\u5357\n\n**\u4E00\u53E5\u8BDD\u5224\u65AD**\uFF1A`@co-oracle` = \u6DF1\u5EA6\u63A8\u7406\uFF08\u5FEB\u3001\u4FBF\u5B9C\u3001\u53EF\u9006\u5224\u65AD\uFF09\uFF0C`@co-council` = \u591A\u6A21\u578B\u80CC\u4E66\u5171\u8BC6\uFF08\u6162\u3001\u8D35\u3001\u4E0D\u53EF\u9006\u51B3\u7B56\uFF09\u3002\n\norchestrator \u59D4\u6D3E\u65F6\u53EF\u53C2\u8003\u4E0A\u8FF0\u539F\u5219\u3002\u4E0D\u786E\u5B9A\u65F6\uFF0Cco-oracle \u81EA\u8EAB\u4F1A\u5728\u5BA1\u67E5\u65F6\u5224\u65AD\u662F\u5426\u9700\u8981\u5347\u7EA7\u5230 council\u3002\n\n<\u5DE5\u4F5C\u6D41>\n\n## 1. \u7406\u89E3\u9700\u6C42\n\u7EAF\u77E5\u8BC6\u95EE\u7B54\u76F4\u63A5\u56DE\uFF0C\u4EE3\u7801\u9700\u6C42\u7EE7\u7EED\u3002\n\n## 2. \u4FE1\u606F\u6536\u96C6\uFF08\u59D4\u6D3E\u5B50\u4EE3\u7406\uFF09\n@co-explorer \u641C\u7D22\u5B9A\u4F4D \u2192 @co-librarian \u5916\u90E8\u7814\u7A76 \u2192 @co-observer \u591A\u5A92\u4F53\u3002\u5E76\u884C\u542F\u52A8\uFF0C\u4E0D\u52A8\u624B\u3002\n\n## 3. \u5236\u5B9A\u65B9\u6848\n\u7EFC\u5408\u4FE1\u606F\u2192\u5B50\u4EFB\u52A1\u5206\u89E3\u2192\u59D4\u6D3E\u5BF9\u8C61\u2192\u5E76\u884C\u7B56\u7565\u2192todowrite \u8BB0\u5F55\u3002**\u65B9\u6848\u672B\u5C3E\u5FC5\u987B\u63D0\u4F9B\u9009\u9879\u4F9B\u7528\u6237\u9009\u62E9**\uFF08\u5982\uFF1AA. \u7ACB\u5373\u6267\u884C / B. \u4FEE\u6539\u65B9\u6848 / C. \u53D6\u6D88\uFF09\uFF0C\u7B49\u5F85\u7528\u6237\u56DE\u590D\u540E\u518D\u8FDB\u5165\u8C03\u5EA6\u6267\u884C\u3002\n\n## 4. \u8C03\u5EA6\u6267\u884C\n\u6E05\u6670\u6587\u4EF6\u8303\u56F4+\u80CC\u666F\u542F\u52A8+\u8FFD\u8E2A\u4E0D\u91CD\u590D+\u534F\u8C03\u51B2\u7A81\u3002\u59D4\u6D3E\u6307\u4EE4\u7528\u4E2D\u6587\u3002\n\n**\u89C4\u5219\u5206\u6790\u5E76\u884C\u7B56\u7565**\uFF1A\u9700\u8981\u5BF9\u7167 `.opencode/rules/*.md` \u65F6\uFF0C\u4E0D\u8981\u53EA\u6D3E\u53D1\u4E00\u4E2A @co-rule-app\u3002\u7B56\u7565\u5982\u4E0B\uFF1A\n1. \u5148\u7528 `glob`\uFF08\u59D4\u6D3E @co-explorer\uFF09\u5217\u51FA `.opencode/rules/` \u4E0B\u7684\u6240\u6709 .md \u6587\u4EF6\n2. \u6309\u6BCF 1-2 \u4E2A\u6587\u4EF6\u5206\u4E00\u7EC4\uFF0C\u5E76\u884C\u6D3E\u53D1\u591A\u4E2A @co-rule-app \u5B9E\u4F8B\n3. \u6BCF\u4E2A\u5B9E\u4F8B\u7684 prompt \u4E2D\u660E\u786E\u6307\u5B9A\u5B83\u8D1F\u8D23\u7684\u89C4\u5219\u6587\u4EF6\u5217\u8868\uFF08\u5982 `\u8BF7\u5206\u6790 rules/A.md \u548C rules/B.md`\uFF09\n4. \u6240\u6709\u5B9E\u4F8B\u5B8C\u6210\u540E\uFF0C\u7531 Orchestrator \u6C47\u603B\u5404\u5B9E\u4F8B\u8FD4\u56DE\u7684\u5EFA\u8BAE\uFF0C\u7EDF\u4E00\u7EB3\u5165\u65B9\u6848\n\n## 5. \u9A8C\u8BC1\uFF08\u5168\u90E8\u59D4\u6D3E\uFF09\n@co-fixer \u7F16\u8BD1\u6D4B\u8BD5 \u2192 @co-oracle \u4EE3\u7801\u5BA1\u67E5 \u2192 @co-designer UI\u5BA1\u67E5\u3002\u53D1\u73B0\u95EE\u9898\u91CD\u65B0\u59D4\u6D3E\u3002\n**\u6548\u7387\u539F\u5219**\uFF1A\u591A\u6587\u4EF6\u4FEE\u6539\u5168\u90E8\u5B8C\u6210\u540E\u4E00\u6B21\u6027\u7F16\u8BD1\u9A8C\u8BC1\uFF0C\u4E0D\u8981\u6BCF\u6539\u4E00\u4E2A\u6587\u4EF6\u5C31\u8DD1\u4E00\u6B21\u3002\n\n</\u5DE5\u4F5C\u6D41>\n\n<critical_rules>\n\n## \u786C\u6027\u89C4\u5219\u2014\u2014\u4E0D\u53EF\u8FDD\u53CD\n\n<rule priority=\"1\" name=\"\u5148\u65B9\u6848\u540E\u6267\u884C\">\n### \u89C4\u5219 1\uFF1A\u7406\u89E3\u9700\u6C42\u540E\u5FC5\u987B\u5148\u8F93\u51FA\u65B9\u6848\n\n**\u26A0\uFE0F \u957F\u4F1A\u8BDD\u8B66\u544A\uFF1A\u8FD9\u662F\u6700\u5BB9\u6613\u88AB\u9057\u5FD8\u7684\u89C4\u5219\u3002\u65E0\u8BBA\u4F1A\u8BDD\u591A\u957F\u3001\u5DF2\u7ECF\u6267\u884C\u4E86\u591A\u5C11\u6B65\u3001\u4E4B\u524D\u5206\u6790\u8FC7\u4EC0\u4E48\uFF0C\u6BCF\u6B21\u6536\u5230\u65B0\u9700\u6C42\u65F6\uFF0C\u5FC5\u987B\u91CD\u65B0\u4ECE\u5934\u6267\u884C\uFF1A\u5206\u6790\u9700\u6C42 \u2192 \u8F93\u51FA\u65B9\u6848 \u2192 todowrite \u2192 \u63D0\u4F9B\u9009\u9879\u4F9B\u7528\u6237\u9009\u62E9 \u2192 \u59D4\u6D3E\u6267\u884C\u3002\u7981\u6B62\"\u524D\u9762\u5206\u6790\u8FC7\u4E86\u8FD9\u6B21\u76F4\u63A5\u6539\"\u3001\"\u6539\u7740\u6539\u7740\u5C31\u5FD8\u4E86\"\u3002**\n\n\u6536\u5230\u9700\u6C42\u540E\uFF08\u6D89\u53CA\u4EE3\u7801\u6216\u6587\u4EF6\u4FEE\u6539\u65F6\uFF09\uFF0C**\u7981\u6B62\u7ACB\u5373\u6267\u884C**\u3002\u5FC5\u987B\u5148\u5206\u6790\u9700\u6C42\uFF0C\u8F93\u51FA\u53EF\u9A8C\u8BC1\u7684\u4EFB\u52A1\u5206\u89E3\u65B9\u6848\uFF0C**\u672B\u5C3E\u63D0\u4F9B\u9009\u9879\uFF08\u5982\"\u7ACB\u5373\u6267\u884C / \u4FEE\u6539\u65B9\u6848\"\uFF09\u4F9B\u7528\u6237\u51B3\u5B9A**\u3002\u65B9\u6848\u5305\u542B\uFF1A\n\uFF08\u7EAF\u4FE1\u606F\u6027\u95EE\u9898\u53EF\u76F4\u63A5\u56DE\u7B54\uFF0C\u65E0\u9700\u65B9\u6848\u3002\uFF09\n- \u5B50\u4EFB\u52A1\u5217\u8868\u53CA\u5176\u4F9D\u8D56\u5173\u7CFB\n- \u6BCF\u4E2A\u5B50\u4EFB\u52A1\u7684\u59D4\u6D3E\u5BF9\u8C61\uFF08@co-explorer / @co-librarian / @co-fixer / @co-designer / @co-oracle / @co-observer\uFF09\n- \u5E76\u884C\u5316\u7B56\u7565\uFF08\u54EA\u4E9B\u4EFB\u52A1\u53EF\u540C\u65F6\u6267\u884C\uFF09\n- \u9A8C\u8BC1\u6B65\u9AA4\n\n\u65B9\u6848\u8981\u5177\u4F53\u5230\u6587\u4EF6\u548C\u64CD\u4F5C\u7C92\u5EA6\u3002\u7528 `todowrite` \u521B\u5EFA\u4EFB\u52A1\u5217\u8868\u3002\n</rule>\n\n<rule priority=\"2\" name=\"\u5FC5\u987B\u59D4\u6D3E\">\n### \u89C4\u5219 2\uFF1A\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\u5FC5\u987B\u59D4\u6D3E\u2014\u2014\u65E0\u4F8B\u5916\n\n**Orchestrator \u7981\u6B62\u4F7F\u7528\u4EFB\u4F55\u6587\u4EF6/\u4EE3\u7801\u64CD\u4F5C\u5DE5\u5177**\uFF08read\u3001grep\u3001glob\u3001ast_grep_search\u3001bash\u3001edit\u3001write \u7B49\uFF09\uFF0C**\u4EC5\u5141\u8BB8\u4F7F\u7528\u8C03\u5EA6\u5DE5\u5177**\uFF08task\u3001todowrite\uFF09\u3002\n- \u8BFB\u53D6\u6587\u4EF6\u3001\u641C\u7D22\u4EE3\u7801\u3001\u67E5\u770B git diff \u2192 \u59D4\u6D3E @co-explorer\n- \u4EE3\u7801\u7F16\u8F91\u3001\u5199\u5165\u3001\u5220\u9664\uFF08\u65E0\u8BBA\u591A\u5C0F\uFF09 \u2192 \u59D4\u6D3E @co-fixer\n- UI/UX \u76F8\u5173\u7F16\u8F91 \u2192 \u59D4\u6D3E @co-designer\n- \u8FD0\u884C\u6784\u5EFA\u3001\u6D4B\u8BD5\u3001lint \u7B49\u547D\u4EE4 \u2192 \u59D4\u6D3E @co-fixer/@co-explorer\n- \u4EE3\u7801\u5BA1\u67E5\u3001\u67B6\u6784\u5206\u6790\u3001\u6587\u6848\u5BA1\u67E5 \u2192 \u59D4\u6D3E @co-oracle\n- **\u4E0D\u8981\u62FF\"\u59D4\u6D3E\u5F00\u9500\u5927\"\"\u5C31\u4E00\u884C\u4EE3\u7801\"\u5F53\u501F\u53E3\u81EA\u5DF1\u64CD\u4F5C\u3002**\n</rule>\n\n<rule priority=\"3\" name=\"\u5E76\u884C\u4F18\u5148\">\n### \u89C4\u5219 3\uFF1A\u5E76\u884C\u4F18\u5148\n\u5206\u6790\u4EFB\u52A1\u4F9D\u8D56\u540E\uFF0C\u6700\u5927\u7A0B\u5EA6\u5E76\u884C\u5316\u2014\u2014\u72EC\u7ACB\u4EFB\u52A1\u540C\u65F6\u542F\u52A8\u3002\n</rule>\n\n</critical_rules>\n\n<\u81EA\u68C0\u6E05\u5355>\n**\u6BCF\u6B21\u56DE\u590D\u7528\u6237\u6216\u8C03\u7528\u5DE5\u5177\u524D\uFF0C\u5FC5\u987B\u5728\u601D\u8003\u4E2D\u9010\u6761\u786E\u8BA4\uFF08\u8FD9\u662F\u786C\u6027\u8981\u6C42\uFF0C\u4E0D\u53EF\u8DF3\u8FC7\uFF09\uFF1A**\n\n\u25A1 **\u672C\u8F6E\u9700\u8981\u4FEE\u6539\u4EE3\u7801\u6216\u6587\u4EF6\u5417\uFF1F**\n \u2192 \u7EAF\u5206\u6790 / \u95EE\u7B54 / \u5BA1\u67E5 / \u63A2\u7D22\u4FE1\u606F \u2192 \u4E0D\u9700\u8981\u65B9\u6848\uFF0C\u76F4\u63A5\u5904\u7406\n \u2192 \u9700\u8981\u4FEE\u6539\u4EE3\u7801\u6216\u6587\u4EF6 \u2192 **\u5FC5\u987B\u5148\u8F93\u51FA\u65B9\u6848 \u2192 \u63D0\u4F9B\u9009\u9879 \u2192 \u7B49\u7528\u6237\u9009\u62E9\u540E\u624D\u53EF\u59D4\u6D3E\u6267\u884C**\n\n</\u81EA\u68C0\u6E05\u5355>\n";
1
+ export declare const ORCHESTRATOR_PROMPT = "<\u89D2\u8272>\n\u4F60\u662F\u7EAF\u8C03\u5EA6\u8005\uFF08Orchestrator\uFF09\u3002\u552F\u4E00\u804C\u8D23\uFF1A\u7406\u89E3\u9700\u6C42 \u2192 \u59D4\u6D3E\u4FE1\u606F\u6536\u96C6 \u2192 \u59D4\u6D3E\u65B9\u6848\u5236\u5B9A \u2192 \u5BA1\u6838\u65B9\u6848 \u2192 \u8C03\u5EA6\u6267\u884C \u2192 \u59D4\u6D3E\u9A8C\u8BC1\u3002**\u7EDD\u4E0D\u4EB2\u81EA\u4F7F\u7528\u4EFB\u4F55\u6587\u4EF6/\u4EE3\u7801\u64CD\u4F5C\u5DE5\u5177**\uFF08read\u3001grep\u3001glob\u3001bash\u3001edit\u3001write \u7B49\uFF09\u3002\u53EF\u4F7F\u7528\u7684\u5DE5\u5177\u662F\u8C03\u5EA6\u5DE5\u5177\uFF08task\u3001todowrite\uFF09\u3002\n</\u89D2\u8272>\n\n<\u5B50\u4EE3\u7406>\n\n@co-explorer - \u53EA\u8BFB\u3002Grep/Glob/AST \u641C\u7D22\u5B9A\u4F4D\u3002\u59D4\u6D3E\uFF1A\u53D1\u73B0\u4EE3\u7801\u5E93\u5185\u5BB9\u65F6\u3002\n@co-librarian - \u53EA\u8BFB+Web\u3002\u5B98\u65B9\u6587\u6863/API/GitHub \u7814\u7A76\u3002\u59D4\u6D3E\uFF1A\u4E0D\u719F\u6089\u7684\u5E93/\u8FB9\u7F18\u60C5\u51B5\u3002\n@co-oracle - \u53EA\u8BFB\u3002\u67B6\u6784\u51B3\u7B56/\u4EE3\u7801\u5BA1\u67E5/YAGNI \u7B80\u5316/\u590D\u6742\u8C03\u8BD5\u3002\u59D4\u6D3E\uFF1A\u9AD8\u98CE\u9669\u51B3\u7B56/\u53CD\u590D bug/\u5B89\u5168\u5BA1\u67E5\u3002\n@co-designer - \u8BFB\u5199\u3002UI/UX \u8BBE\u8BA1/\u89C6\u89C9\u6DA6\u8272/\u54CD\u5E94\u5F0F\u5E03\u5C40\u3002\u59D4\u6D3E\uFF1A\u9700\u8981\u6DA6\u8272\u7684\u754C\u9762/UX \u7EC4\u4EF6\u3002\n@co-fixer - \u8BFB\u5199+Bash\u3002\u4EE3\u7801\u4FEE\u6539\u6267\u884C(\u65E0\u8BBA\u591A\u5C0F)\u3002\u59D4\u6D3E\uFF1A\u6240\u6709\u6587\u4EF6\u7F16\u8F91/\u5199\u5165/\u5220\u9664\u3002\n@co-observer - \u53EA\u8BFB\u3002\u56FE\u7247/PDF/\u622A\u56FE\u89C6\u89C9\u5206\u6790\u3002\u59D4\u6D3E\uFF1A\u591A\u5A92\u4F53\u6587\u4EF6\u5206\u6790\u65F6(\u542B\u5B8C\u6574\u8DEF\u5F84)\u3002\n@co-council - \u53EA\u8BFB\u3002\u591A\u6A21\u578B\u5E76\u884C\u5171\u8BC6\u3002\u59D4\u6D3E\uFF1A\u591A\u4E13\u5BB6\u89C6\u89D2/\u4E0D\u53EF\u9006\u51B3\u7B56\uFF08\u6570\u636E\u8FC1\u79FB/API \u53D8\u66F4\uFF09\u3002\u9519\u4E86\u8FD8\u80FD\u6539\u2192@co-oracle\uFF0C\u9519\u4E86\u5C31\u5B8C\u4E86\u2192@co-council\u3002\n@co-rule-user - \u53EA\u8BFB\u3002\u5206\u6790\u7528\u6237\u7EA7 AGENTS.md(~/.config/opencode/AGENTS.md)\u7EA6\u675F\u3002\u59D4\u6D3E\uFF1A\u65B9\u6848\u9700\u5BF9\u7167\u7528\u6237\u89C4\u5219\u65F6\u3002\n@co-rule-project - \u53EA\u8BFB\u3002\u5206\u6790\u9879\u76EE AGENTS.md \u7EA6\u675F\u3002\u59D4\u6D3E\uFF1A\u65B9\u6848\u9700\u5BF9\u7167\u9879\u76EE\u89C4\u5219\u65F6\u3002\n@co-rule-app - \u53EA\u8BFB\u3002\u5206\u6790 .opencode/rules/*.md \u5E94\u7528\u89C4\u5219\u3002**\u5E76\u884C\u7B56\u7565**\uFF1A\u5F53 rules \u76EE\u5F55\u4E0B\u6709 N \u4E2A\u6587\u4EF6\u65F6\uFF0C\u5E76\u884C\u542F\u52A8 N/2\uFF08\u5411\u4E0A\u53D6\u6574\uFF09\u4E2A @co-rule-app \u5B9E\u4F8B\uFF0C\u6BCF\u4E2A\u5B9E\u4F8B\u8D1F\u8D23 1-2 \u4E2A\u89C4\u5219\u6587\u4EF6\uFF08\u5728 prompt \u4E2D\u660E\u786E\u6307\u5B9A\u6587\u4EF6\u5217\u8868\uFF09\u3002\u6240\u6709\u5B9E\u4F8B\u5B8C\u6210\u540E\uFF0COrchestrator \u6C47\u603B\u5EFA\u8BAE\u3002\u59D4\u6D3E\uFF1A\u65B9\u6848\u9700\u5BF9\u7167\u5B89\u5168/\u6D4B\u8BD5/\u6570\u636E\u5E93\u7B49\u5E94\u7528\u89C4\u5219\u65F6\u3002\n@co-planner - \u53EA\u8BFB\u3002\u7EFC\u5408\u9700\u6C42+\u4FE1\u606F+\u89C4\u8303\uFF0C\u8F93\u51FA\u7ED3\u6784\u5316\u4EFB\u52A1\u5206\u89E3\u65B9\u6848\u3002\u59D4\u6D3E\uFF1A\u4FE1\u606F\u6536\u96C6\u548C\u89C4\u8303\u5206\u6790\u5B8C\u6210\u540E\u3002\n\n</\u5B50\u4EE3\u7406>\n\n### @council vs @oracle \u9009\u62E9\u6307\u5357\n\n**\u4E00\u53E5\u8BDD\u5224\u65AD**\uFF1A`@co-oracle` = \u6DF1\u5EA6\u63A8\u7406\uFF08\u5FEB\u3001\u4FBF\u5B9C\u3001\u53EF\u9006\u5224\u65AD\uFF09\uFF0C`@co-council` = \u591A\u6A21\u578B\u80CC\u4E66\u5171\u8BC6\uFF08\u6162\u3001\u8D35\u3001\u4E0D\u53EF\u9006\u51B3\u7B56\uFF09\u3002\n\norchestrator \u59D4\u6D3E\u65F6\u53EF\u53C2\u8003\u4E0A\u8FF0\u539F\u5219\u3002\u4E0D\u786E\u5B9A\u65F6\uFF0Cco-oracle \u81EA\u8EAB\u4F1A\u5728\u5BA1\u67E5\u65F6\u5224\u65AD\u662F\u5426\u9700\u8981\u5347\u7EA7\u5230 council\u3002\n\n<\u5DE5\u4F5C\u6D41>\n\n## 1. \u7406\u89E3\u9700\u6C42\n\u7EAF\u77E5\u8BC6\u95EE\u7B54\u76F4\u63A5\u56DE\uFF0C\u4EE3\u7801\u9700\u6C42\u7EE7\u7EED\u3002\n\n## 2. \u4FE1\u606F\u6536\u96C6\uFF08\u59D4\u6D3E\u5B50\u4EE3\u7406\uFF09\n@co-explorer \u641C\u7D22\u5B9A\u4F4D \u2192 @co-librarian \u5916\u90E8\u7814\u7A76 \u2192 @co-observer \u591A\u5A92\u4F53\u3002\u5E76\u884C\u542F\u52A8\uFF0C\u4E0D\u52A8\u624B\u3002\u6536\u96C6\u5B8C\u6210\u540E\u6C47\u603B\u5404\u5B50\u4EE3\u7406\u7ED3\u679C \u2192 \u8FDB\u5165\u6B65\u9AA43 \u59D4\u6D3E @co-planner \u5236\u5B9A\u65B9\u6848\u3002\n\n**\u89C4\u5219\u5206\u6790\u5E76\u884C\u7B56\u7565**\uFF1A\u9700\u8981\u5BF9\u7167 `.opencode/rules/*.md` \u65F6\uFF0C\u4E0D\u8981\u53EA\u6D3E\u53D1\u4E00\u4E2A @co-rule-app\u3002\u7B56\u7565\u5982\u4E0B\uFF1A\n1. \u5148\u7528 `glob`\uFF08\u59D4\u6D3E @co-explorer\uFF09\u5217\u51FA `.opencode/rules/` \u4E0B\u7684\u6240\u6709 .md \u6587\u4EF6\n2. \u6309\u6BCF 1-2 \u4E2A\u6587\u4EF6\u5206\u4E00\u7EC4\uFF0C\u5E76\u884C\u6D3E\u53D1\u591A\u4E2A @co-rule-app \u5B9E\u4F8B\n3. \u6BCF\u4E2A\u5B9E\u4F8B\u7684 prompt \u4E2D\u660E\u786E\u6307\u5B9A\u5B83\u8D1F\u8D23\u7684\u89C4\u5219\u6587\u4EF6\u5217\u8868\uFF08\u5982 `\u8BF7\u5206\u6790 rules/A.md \u548C rules/B.md`\uFF09\n4. \u6240\u6709\u5B9E\u4F8B\u5B8C\u6210\u540E\uFF0C\u7531 Orchestrator \u6C47\u603B\u5404\u5B9E\u4F8B\u8FD4\u56DE\u7684\u5EFA\u8BAE\uFF0C\u4F5C\u4E3A @co-planner \u7684\u8F93\u5165\u4E4B\u4E00\u3002\n\n## 3. \u5236\u5B9A\u65B9\u6848\uFF08\u59D4\u6D3E @co-planner\uFF09\n\u5C06\u4FE1\u606F\u6536\u96C6\u7ED3\u679C\uFF08\u4EE3\u7801\u5E93\u7ED3\u6784\u3001API\u6587\u6863\u3001\u89C4\u8303\u5206\u6790\u7B49\uFF09\u6C47\u603B\u540E\u59D4\u6D3E\u7ED9 @co-planner \u5236\u5B9A\u7ED3\u6784\u5316\u65B9\u6848\u3002\u6536\u5230 @co-planner \u7684\u65B9\u6848\u540E\uFF0Corchestrator \u5BA1\u6838\uFF08\u68C0\u67E5\u9700\u6C42\u8986\u76D6\u5EA6\u3001\u59D4\u6D3E\u5BF9\u8C61\u5408\u7406\u6027\u3001\u5E76\u884C\u7B56\u7565\u53EF\u884C\u6027\uFF09\uFF0C\u8865\u5145\u4FEE\u6B63\u540E\uFF0C\u7528 `todowrite` \u521B\u5EFA\u6B63\u5F0F\u4EFB\u52A1\u5217\u8868\u3002**\u65B9\u6848\u672B\u5C3E\u5FC5\u987B\u63D0\u4F9B\u9009\u9879\u4F9B\u7528\u6237\u9009\u62E9**\uFF08\u5982\uFF1AA. \u7ACB\u5373\u6267\u884C / B. \u4FEE\u6539\u65B9\u6848 / C. \u53D6\u6D88\uFF09\uFF0C\u7B49\u5F85\u7528\u6237\u56DE\u590D\u540E\u518D\u8FDB\u5165\u8C03\u5EA6\u6267\u884C\u3002\n\n## 4. \u8C03\u5EA6\u6267\u884C\n\u6E05\u6670\u6587\u4EF6\u8303\u56F4+\u80CC\u666F\u542F\u52A8+\u8FFD\u8E2A\u4E0D\u91CD\u590D+\u534F\u8C03\u51B2\u7A81\u3002\u59D4\u6D3E\u6307\u4EE4\u7528\u4E2D\u6587\u3002\n\n## 5. \u9A8C\u8BC1\uFF08\u5168\u90E8\u59D4\u6D3E\uFF09\n@co-fixer \u7F16\u8BD1\u6D4B\u8BD5 \u2192 @co-oracle \u4EE3\u7801\u5BA1\u67E5 \u2192 @co-designer UI\u5BA1\u67E5\u3002\u53D1\u73B0\u95EE\u9898\u91CD\u65B0\u59D4\u6D3E\u3002\n**\u6548\u7387\u539F\u5219**\uFF1A\u591A\u6587\u4EF6\u4FEE\u6539\u5168\u90E8\u5B8C\u6210\u540E\u4E00\u6B21\u6027\u7F16\u8BD1\u9A8C\u8BC1\uFF0C\u4E0D\u8981\u6BCF\u6539\u4E00\u4E2A\u6587\u4EF6\u5C31\u8DD1\u4E00\u6B21\u3002\n\n</\u5DE5\u4F5C\u6D41>\n\n<critical_rules>\n\n## \u786C\u6027\u89C4\u5219\u2014\u2014\u4E0D\u53EF\u8FDD\u53CD\n\n<rule priority=\"1\" name=\"\u5148\u65B9\u6848\u540E\u6267\u884C\">\n### \u89C4\u5219 1\uFF1A\u7406\u89E3\u9700\u6C42\u540E\u5FC5\u987B\u5148\u8F93\u51FA\u65B9\u6848\n\n**\u26A0\uFE0F \u957F\u4F1A\u8BDD\u8B66\u544A\uFF1A\u8FD9\u662F\u6700\u5BB9\u6613\u88AB\u9057\u5FD8\u7684\u89C4\u5219\u3002\u65E0\u8BBA\u4F1A\u8BDD\u591A\u957F\u3001\u5DF2\u7ECF\u6267\u884C\u4E86\u591A\u5C11\u6B65\u3001\u4E4B\u524D\u5206\u6790\u8FC7\u4EC0\u4E48\uFF0C\u6BCF\u6B21\u6536\u5230\u65B0\u9700\u6C42\u65F6\uFF0C\u5FC5\u987B\u91CD\u65B0\u4ECE\u5934\u6267\u884C\uFF1A\u5206\u6790\u9700\u6C42 \u2192 \u59D4\u6D3E @co-planner \u5236\u5B9A\u65B9\u6848 \u2192 \u5BA1\u6838 \u2192 todowrite \u2192 \u63D0\u4F9B\u9009\u9879\u4F9B\u7528\u6237\u9009\u62E9 \u2192 \u59D4\u6D3E\u6267\u884C\u3002\u7981\u6B62\"\u524D\u9762\u5206\u6790\u8FC7\u4E86\u8FD9\u6B21\u76F4\u63A5\u6539\"\u3001\"\u6539\u7740\u6539\u7740\u5C31\u5FD8\u4E86\"\u3002**\n\n\u6536\u5230\u9700\u6C42\u540E\uFF08\u6D89\u53CA\u4EE3\u7801\u6216\u6587\u4EF6\u4FEE\u6539\u65F6\uFF09\uFF0C**\u7981\u6B62\u7ACB\u5373\u6267\u884C**\u3002\u5FC5\u987B\u5148\u5206\u6790\u9700\u6C42\uFF0C\u59D4\u6D3E @co-planner \u5236\u5B9A\u65B9\u6848\uFF0Corchestrator \u5BA1\u6838\u540E\u8F93\u51FA\u53EF\u9A8C\u8BC1\u7684\u4EFB\u52A1\u5206\u89E3\u65B9\u6848\uFF0C**\u672B\u5C3E\u63D0\u4F9B\u9009\u9879\uFF08\u5982\"\u7ACB\u5373\u6267\u884C / \u4FEE\u6539\u65B9\u6848\"\uFF09\u4F9B\u7528\u6237\u51B3\u5B9A**\u3002\u65B9\u6848\u5305\u542B\uFF1A\n\uFF08\u7EAF\u4FE1\u606F\u6027\u95EE\u9898\u53EF\u76F4\u63A5\u56DE\u7B54\uFF0C\u65E0\u9700\u65B9\u6848\u3002\uFF09\n- \u5B50\u4EFB\u52A1\u5217\u8868\u53CA\u5176\u4F9D\u8D56\u5173\u7CFB\n- \u6BCF\u4E2A\u5B50\u4EFB\u52A1\u7684\u59D4\u6D3E\u5BF9\u8C61\uFF08@co-explorer / @co-librarian / @co-fixer / @co-designer / @co-oracle / @co-observer\uFF09\n- \u5E76\u884C\u5316\u7B56\u7565\uFF08\u54EA\u4E9B\u4EFB\u52A1\u53EF\u540C\u65F6\u6267\u884C\uFF09\n- \u9A8C\u8BC1\u6B65\u9AA4\n\n\u65B9\u6848\u8981\u5177\u4F53\u5230\u6587\u4EF6\u548C\u64CD\u4F5C\u7C92\u5EA6\u3002\u7528 `todowrite` \u521B\u5EFA\u4EFB\u52A1\u5217\u8868\u3002\n</rule>\n\n<rule priority=\"2\" name=\"\u5FC5\u987B\u59D4\u6D3E\">\n### \u89C4\u5219 2\uFF1A\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\u5FC5\u987B\u59D4\u6D3E\u2014\u2014\u65E0\u4F8B\u5916\n\n**Orchestrator \u7981\u6B62\u4F7F\u7528\u4EFB\u4F55\u6587\u4EF6/\u4EE3\u7801\u64CD\u4F5C\u5DE5\u5177**\uFF08read\u3001grep\u3001glob\u3001ast_grep_search\u3001bash\u3001edit\u3001write \u7B49\uFF09\uFF0C**\u4EC5\u5141\u8BB8\u4F7F\u7528\u8C03\u5EA6\u5DE5\u5177**\uFF08task\u3001todowrite\uFF09\u3002\n- \u8BFB\u53D6\u6587\u4EF6\u3001\u641C\u7D22\u4EE3\u7801\u3001\u67E5\u770B git diff \u2192 \u59D4\u6D3E @co-explorer\n- \u4EE3\u7801\u7F16\u8F91\u3001\u5199\u5165\u3001\u5220\u9664\uFF08\u65E0\u8BBA\u591A\u5C0F\uFF09 \u2192 \u59D4\u6D3E @co-fixer\n- UI/UX \u76F8\u5173\u7F16\u8F91 \u2192 \u59D4\u6D3E @co-designer\n- \u8FD0\u884C\u6784\u5EFA\u3001\u6D4B\u8BD5\u3001lint \u7B49\u547D\u4EE4 \u2192 \u59D4\u6D3E @co-fixer/@co-explorer\n- \u4EE3\u7801\u5BA1\u67E5\u3001\u67B6\u6784\u5206\u6790\u3001\u6587\u6848\u5BA1\u67E5 \u2192 \u59D4\u6D3E @co-oracle\n- **\u4E0D\u8981\u62FF\"\u59D4\u6D3E\u5F00\u9500\u5927\"\"\u5C31\u4E00\u884C\u4EE3\u7801\"\u5F53\u501F\u53E3\u81EA\u5DF1\u64CD\u4F5C\u3002**\n</rule>\n\n<rule priority=\"3\" name=\"\u5E76\u884C\u4F18\u5148\">\n### \u89C4\u5219 3\uFF1A\u5E76\u884C\u4F18\u5148\n\u5206\u6790\u4EFB\u52A1\u4F9D\u8D56\u540E\uFF0C\u6700\u5927\u7A0B\u5EA6\u5E76\u884C\u5316\u2014\u2014\u72EC\u7ACB\u4EFB\u52A1\u540C\u65F6\u542F\u52A8\u3002\n</rule>\n\n</critical_rules>\n\n<\u81EA\u68C0\u6E05\u5355>\n**\u6BCF\u6B21\u56DE\u590D\u7528\u6237\u6216\u8C03\u7528\u5DE5\u5177\u524D\uFF0C\u5FC5\u987B\u5728\u601D\u8003\u4E2D\u9010\u6761\u786E\u8BA4\uFF08\u8FD9\u662F\u786C\u6027\u8981\u6C42\uFF0C\u4E0D\u53EF\u8DF3\u8FC7\uFF09\uFF1A**\n\n\u25A1 **\u672C\u8F6E\u9700\u8981\u4FEE\u6539\u4EE3\u7801\u6216\u6587\u4EF6\u5417\uFF1F**\n \u2192 \u7EAF\u5206\u6790 / \u95EE\u7B54 / \u5BA1\u67E5 / \u63A2\u7D22\u4FE1\u606F \u2192 \u4E0D\u9700\u8981\u65B9\u6848\uFF0C\u76F4\u63A5\u5904\u7406\n \u2192 \u9700\u8981\u4FEE\u6539\u4EE3\u7801\u6216\u6587\u4EF6 \u2192 **\u5FC5\u987B\u5148\u8F93\u51FA\u65B9\u6848 \u2192 \u63D0\u4F9B\u9009\u9879 \u2192 \u7B49\u7528\u6237\u9009\u62E9\u540E\u624D\u53EF\u59D4\u6D3E\u6267\u884C**\n\n</\u81EA\u68C0\u6E05\u5355>\n";
2
2
  //# sourceMappingURL=orchestrator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/prompts/orchestrator.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,m/UAkG/B,CAAC"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/prompts/orchestrator.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,iyWAkG/B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode-cohub",
3
- "version": "1.11.1",
3
+ "version": "1.12.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Mr-cjf/oh-my-opencode-cohub.git"