maskweaver 0.8.6 → 0.8.8

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 (45) hide show
  1. package/README.ko.md +217 -217
  2. package/README.md +235 -235
  3. package/assets/agents/squad-operator.md +56 -56
  4. package/assets/commands/weave-approve-plan.md +57 -57
  5. package/assets/commands/weave-craft.md +43 -43
  6. package/assets/commands/weave-design.md +64 -64
  7. package/assets/commands/weave-flow.md +48 -48
  8. package/assets/commands/weave-help.md +101 -101
  9. package/assets/commands/weave-init.md +23 -23
  10. package/assets/commands/weave-plan.md +15 -15
  11. package/assets/commands/weave-prepare.md +69 -69
  12. package/assets/commands/weave-refine-plan.md +59 -59
  13. package/assets/commands/weave-repair.md +70 -70
  14. package/assets/commands/weave-research.md +51 -51
  15. package/assets/commands/weave-spec.md +227 -227
  16. package/assets/commands/weave-status.md +2 -2
  17. package/assets/commands/weave-verify.md +44 -44
  18. package/assets/commands/weave-worktree.md +69 -69
  19. package/dist/cli/doctor.d.ts +16 -0
  20. package/dist/cli/doctor.d.ts.map +1 -0
  21. package/dist/cli/doctor.js +355 -0
  22. package/dist/cli/doctor.js.map +1 -0
  23. package/dist/cli/install.js +9 -0
  24. package/dist/cli/install.js.map +1 -1
  25. package/dist/plugin/config/index.d.ts +3 -10
  26. package/dist/plugin/config/index.d.ts.map +1 -1
  27. package/dist/plugin/config/index.js +12 -15
  28. package/dist/plugin/config/index.js.map +1 -1
  29. package/dist/plugin/index.d.ts +1 -27
  30. package/dist/plugin/index.d.ts.map +1 -1
  31. package/dist/plugin/index.js +113 -240
  32. package/dist/plugin/index.js.map +1 -1
  33. package/dist/plugin/tools/slashcommand.js +59 -59
  34. package/dist/plugin/tools/squad.js +3 -3
  35. package/dist/plugin/tools/weave.js +111 -111
  36. package/dist/plugin/types.d.ts +10 -8
  37. package/dist/plugin/types.d.ts.map +1 -1
  38. package/dist/plugin/types.js +2 -0
  39. package/dist/plugin/types.js.map +1 -1
  40. package/dist/version.d.ts +1 -1
  41. package/dist/version.d.ts.map +1 -1
  42. package/dist/version.js +1 -1
  43. package/dist/version.js.map +1 -1
  44. package/package.json +4 -2
  45. package/postinstall.mjs +97 -0
@@ -12,6 +12,15 @@ import { parse as parseJsonc } from 'jsonc-parser';
12
12
  import * as fs from 'node:fs';
13
13
  import * as path from 'node:path';
14
14
  import * as os from 'node:os';
15
+ function pluginLog(ctx, level, message) {
16
+ ctx.client.app.log({
17
+ body: {
18
+ service: 'maskweaver',
19
+ level,
20
+ message,
21
+ },
22
+ });
23
+ }
15
24
  // ============================================================================
16
25
  // Configuration Loader
17
26
  // ============================================================================
@@ -66,33 +75,21 @@ export function loadPluginConfig(directory, ctx) {
66
75
  const config = parseJsoncContent(content);
67
76
  // Log successful config load
68
77
  if (ctx?.verbose) {
69
- ctx.client.app.log({
70
- service: 'maskweaver',
71
- level: 'info',
72
- message: `Loaded config from: ${location}`,
73
- });
78
+ pluginLog(ctx, 'info', `Loaded config from: ${location}`);
74
79
  }
75
80
  return config;
76
81
  }
77
82
  catch (error) {
78
83
  // Log error but continue searching
79
84
  if (ctx) {
80
- ctx.client.app.log({
81
- service: 'maskweaver',
82
- level: 'warn',
83
- message: `Failed to load config from ${location}: ${error}`,
84
- });
85
+ pluginLog(ctx, 'warn', `Failed to load config from ${location}: ${error}`);
85
86
  }
86
87
  }
87
88
  }
88
89
  }
89
90
  // No configuration found - return empty config
90
91
  if (ctx?.verbose) {
91
- ctx.client.app.log({
92
- service: 'maskweaver',
93
- level: 'info',
94
- message: 'No maskweaver.json found, using defaults',
95
- });
92
+ pluginLog(ctx, 'info', 'No maskweaver.json found, using defaults');
96
93
  }
97
94
  return {};
98
95
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugin/config/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugin/config/index.ts"],"names":[],"mappings":"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"}
@@ -11,33 +11,7 @@
11
11
  *
12
12
  * Based on oh-my-opencode plugin development patterns.
13
13
  */
14
- interface PluginContext {
15
- client: {
16
- app: {
17
- log(entry: {
18
- service: string;
19
- level: 'debug' | 'info' | 'warn' | 'error';
20
- message: string;
21
- }): void;
22
- };
23
- };
24
- directory: string;
25
- }
26
- interface PluginEvent {
27
- type: string;
28
- [key: string]: unknown;
29
- }
30
- type Plugin = (context: PluginContext) => Promise<{
31
- agent?: Record<string, unknown>;
32
- 'experimental.chat.system.transform'?: (input: unknown, output: {
33
- system?: string[];
34
- }) => Promise<void>;
35
- tool?: Record<string, unknown>;
36
- event?: (context: {
37
- event: PluginEvent;
38
- }) => Promise<void>;
39
- config?: (config: unknown) => Promise<void>;
40
- }>;
14
+ import { type Plugin } from '@opencode-ai/plugin';
41
15
  export declare const MaskweaverPlugin: Plugin;
42
16
  export default MaskweaverPlugin;
43
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;EAYE;AASF,UAAU,aAAa;IACrB,MAAM,EAAE;QACN,GAAG,EAAE;YACH,GAAG,CAAC,KAAK,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAA;aAAE,GAAG,IAAI,CAAC;SACpG,CAAC;KACH,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,KAAK,MAAM,GAAG,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,oCAAoC,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxG,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C,CAAC,CAAC;AA81BH,eAAO,MAAM,gBAAgB,EAAE,MAyd9B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;EAYE;AAGF,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAu1BxD,eAAO,MAAM,gBAAgB,EAAE,MA0V9B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -12,17 +12,13 @@
12
12
  * Based on oh-my-opencode plugin development patterns.
13
13
  */
14
14
  import { z } from 'zod';
15
- // Inline shim: tool() is just an identity function in @opencode-ai/plugin
16
- // We inline it to avoid bundler resolution bugs with the upstream package
17
- const tool = (input) => input;
18
15
  import * as fs from 'node:fs';
19
16
  import * as path from 'node:path';
20
17
  import * as os from 'node:os';
21
18
  import { spawnSync } from 'node:child_process';
22
19
  import { fileURLToPath } from 'node:url';
23
- import { parse as parseYaml } from 'yaml';
24
20
  import { VERSION } from '../version.js';
25
- import { loadPluginConfig, isMaskEnabled, isToolEnabled, getDefaultMask, isAutoActivateEnabled, getAgentOverride, isVerboseLoggingEnabled, isCompletionSoundEnabled, validateConfig, } from './config/index.js';
21
+ import { loadPluginConfig, isMaskEnabled, isToolEnabled, getDefaultMask, isAutoActivateEnabled, isVerboseLoggingEnabled, isCompletionSoundEnabled, validateConfig, } from './config/index.js';
26
22
  // New tool imports
27
23
  import { createMemorySearchTool } from './tools/memorySearch.js';
28
24
  import { createMemoryWriteTool } from './tools/memoryWrite.js';
@@ -34,6 +30,7 @@ import { createMaskSaveTool } from './tools/maskSave.js';
34
30
  import { createSquadTool } from './tools/squad.js';
35
31
  import { createWeaveTool } from './tools/weave.js';
36
32
  import { createSlashcommandTool } from './tools/slashcommand.js';
33
+ import { loadRuntimeConfig, normalizeDummyHumansConfig } from '../shared/config.js';
37
34
  const REMOVED_WEAVE_COMMAND_FILES = [
38
35
  'weave-task.md',
39
36
  'weave-task-auto.md',
@@ -145,6 +142,70 @@ function installAssets(projectDir) {
145
142
  return result;
146
143
  }
147
144
  // ============================================================================
145
+ // Pool Agent Generator
146
+ // ============================================================================
147
+ /**
148
+ * Generate dummy-human agent .md files from maskweaver.config.json's dummyHumans.pool.
149
+ *
150
+ * For each entry in the pool, creates .opencode/agents/dummy-{id}.md with the
151
+ * model field set to the pool entry's model. This ensures the squad system's
152
+ * model pool and the actual agent files stay in sync.
153
+ *
154
+ * Skips existing files to protect user customizations.
155
+ */
156
+ function generatePoolAgents(projectDir) {
157
+ const generated = [];
158
+ // Read runtime config
159
+ const config = loadRuntimeConfig(projectDir);
160
+ if (!config.dummyHumans) {
161
+ return generated; // No pool configured, nothing to generate
162
+ }
163
+ const pool = normalizeDummyHumansConfig(config.dummyHumans);
164
+ if (pool.length === 0) {
165
+ return generated;
166
+ }
167
+ const agentsDest = path.join(projectDir, '.opencode', 'agents');
168
+ if (!fs.existsSync(agentsDest)) {
169
+ try {
170
+ fs.mkdirSync(agentsDest, { recursive: true });
171
+ }
172
+ catch {
173
+ return generated; // Cannot create directory, skip silently
174
+ }
175
+ }
176
+ for (const entry of pool) {
177
+ const agentName = `dummy-${entry.id}`;
178
+ const agentPath = path.join(agentsDest, `${agentName}.md`);
179
+ // Skip if already exists (protect user customizations)
180
+ if (fs.existsSync(agentPath)) {
181
+ continue;
182
+ }
183
+ const content = [
184
+ '---',
185
+ `description: "Dummy-Human (${entry.id}) - Auto-generated from maskweaver.config.json pool"`,
186
+ `model: ${entry.model}`,
187
+ 'mode: subagent',
188
+ 'temperature: 0.2',
189
+ 'permission:',
190
+ ' edit: allow',
191
+ ' bash: allow',
192
+ ' webfetch: allow',
193
+ '---',
194
+ '',
195
+ 'Faithfully executes instructions from Mask Weaver.',
196
+ '',
197
+ ].join('\n');
198
+ try {
199
+ fs.writeFileSync(agentPath, content, 'utf-8');
200
+ generated.push(agentPath);
201
+ }
202
+ catch (e) {
203
+ // Skip files that fail to write
204
+ }
205
+ }
206
+ return generated;
207
+ }
208
+ // ============================================================================
148
209
  // Simple YAML Parser
149
210
  // ============================================================================
150
211
  function parseSimpleYaml(content) {
@@ -425,8 +486,17 @@ function buildRichPrompt(mask) {
425
486
  }
426
487
  return parts.join('\n');
427
488
  }
489
+ function pluginLog(client, level, message) {
490
+ client.app.log({
491
+ body: {
492
+ service: 'maskweaver',
493
+ level,
494
+ message,
495
+ },
496
+ });
497
+ }
428
498
  // ============================================================================
429
- // Tool Factory Functions (oh-my-opencode pattern)
499
+ // Helper functions for tool factories
430
500
  // ============================================================================
431
501
  function createListMasksTool(maskLoader, activeMask) {
432
502
  return {
@@ -602,81 +672,8 @@ function playCompletionSound(config) {
602
672
  }
603
673
  }
604
674
  let state = null;
605
- function parseAgentMarkdown(content) {
606
- const parts = content.split('---');
607
- if (parts.length < 3) {
608
- return { prompt: content.trim() };
609
- }
610
- try {
611
- const frontmatter = parseYaml(parts[1]);
612
- const prompt = parts.slice(2).join('---').trim();
613
- return { ...frontmatter, prompt };
614
- }
615
- catch (e) {
616
- return { prompt: content.trim() };
617
- }
618
- }
619
- // ============================================================================
620
- // Default Embedded Agents (ensures first-run works without restart)
621
675
  // ============================================================================
622
- const DEFAULT_AGENTS = {
623
- 'dummy-human': {
624
- description: 'Dummy-Human - Pure execution agent that performs tasks with masks assigned by Mask Weaver',
625
- mode: 'subagent',
626
- temperature: 0.2,
627
- permission: {
628
- edit: 'allow',
629
- bash: 'allow',
630
- webfetch: 'allow',
631
- },
632
- prompt: `# Dummy-Human
633
-
634
- You are a **Dummy-Human**.
635
-
636
- ## Identity
637
-
638
- You are a pure execution agent. You accurately perform work instructions received from the Mask Weaver.
639
-
640
- ## Behavior Principles
641
-
642
- 1. If the Mask Weaver provides a **mask (persona)**, become that expert and work accordingly
643
- 2. If no mask is provided, work as a competent software engineer
644
- 3. Complete assigned tasks accurately
645
- 4. Report results clearly
646
-
647
- ## Result Reporting
648
-
649
- When work is complete:
650
- - Summary of work performed
651
- - Generated outputs
652
- - Additional considerations (if any)`,
653
- },
654
- };
655
- function loadAgentAssets(...assetsDirs) {
656
- // Start with default embedded agents (always available)
657
- const agents = { ...DEFAULT_AGENTS };
658
- // Load from each directory in order (later directories override earlier ones)
659
- for (const assetsDir of assetsDirs) {
660
- const agentsDir = path.join(assetsDir, 'agents');
661
- if (!fs.existsSync(agentsDir))
662
- continue;
663
- try {
664
- const files = fs.readdirSync(agentsDir);
665
- for (const file of files) {
666
- if (file.endsWith('.md') && file !== 'dummy-template.md') {
667
- const agentId = path.basename(file, '.md');
668
- const content = fs.readFileSync(path.join(agentsDir, file), 'utf-8');
669
- agents[agentId] = parseAgentMarkdown(content);
670
- }
671
- }
672
- }
673
- catch (e) {
674
- // Ignore errors - default agents still available
675
- }
676
- }
677
- return agents;
678
- }
679
- export const MaskweaverPlugin = async ({ client, directory }) => {
676
+ export const MaskweaverPlugin = async ({ client, directory, project, worktree, $, serverUrl }) => {
680
677
  // ==========================================================================
681
678
  // 1. Load Configuration (oh-my-opencode pattern)
682
679
  // ==========================================================================
@@ -684,11 +681,7 @@ export const MaskweaverPlugin = async ({ client, directory }) => {
684
681
  // Validate configuration
685
682
  const configErrors = validateConfig(pluginConfig);
686
683
  if (configErrors.length > 0) {
687
- client.app.log({
688
- service: 'maskweaver',
689
- level: 'warn',
690
- message: `Configuration validation errors: ${configErrors.join(', ')}`,
691
- });
684
+ pluginLog(client, 'warn', `Configuration validation errors: ${configErrors.join(', ')}`);
692
685
  }
693
686
  const verbose = isVerboseLoggingEnabled(pluginConfig);
694
687
  // ==========================================================================
@@ -698,24 +691,20 @@ export const MaskweaverPlugin = async ({ client, directory }) => {
698
691
  // Track if this is a first-time installation
699
692
  const isFirstInstall = installResult.installed.length > 0;
700
693
  if (isFirstInstall) {
701
- client.app.log({
702
- service: 'maskweaver',
703
- level: 'info',
704
- message: `Installed ${installResult.installed.length} files to .opencode/ (agents, masks)`,
705
- });
694
+ pluginLog(client, 'info', `Installed ${installResult.installed.length} files to .opencode/ (agents, masks)`);
706
695
  // Show prominent restart message for first-time installation
707
- client.app.log({
708
- service: 'maskweaver',
709
- level: 'warn',
710
- message: `⚠️ RESTART REQUIRED: Please restart OpenCode to activate all Maskweaver features (agents, masks, commands).`,
711
- });
696
+ pluginLog(client, 'warn', `⚠️ RESTART REQUIRED: Please restart OpenCode to activate all Maskweaver features (agents, masks, commands).`);
712
697
  }
713
698
  if (installResult.errors.length > 0) {
714
- client.app.log({
715
- service: 'maskweaver',
716
- level: 'warn',
717
- message: `Asset errors: ${installResult.errors.join(', ')}`,
718
- });
699
+ pluginLog(client, 'warn', `Asset errors: ${installResult.errors.join(', ')}`);
700
+ }
701
+ // ==========================================================================
702
+ // 2b. Generate pool agents from maskweaver.config.json (dummyHumans.pool)
703
+ // ==========================================================================
704
+ const generatedAgents = generatePoolAgents(directory);
705
+ if (generatedAgents.length > 0) {
706
+ pluginLog(client, 'info', `Generated ${generatedAgents.length} pool agent files from maskweaver.config.json: ${generatedAgents.map(p => path.basename(p)).join(', ')}`);
707
+ pluginLog(client, 'warn', `⚠️ RESTART REQUIRED: Please restart OpenCode to activate the new pool agent files.`);
719
708
  }
720
709
  // ==========================================================================
721
710
  // 3. Initialize masks
@@ -734,29 +723,17 @@ export const MaskweaverPlugin = async ({ client, directory }) => {
734
723
  };
735
724
  state = pluginState;
736
725
  // Log plugin loaded
737
- client.app.log({
738
- service: 'maskweaver',
739
- level: 'info',
740
- message: `Maskweaver plugin loaded v${VERSION}`,
741
- });
726
+ pluginLog(client, 'info', `Maskweaver plugin loaded v${VERSION}`);
742
727
  if (fs.existsSync(masksDir)) {
743
728
  pluginState.maskLoader = new MaskLoader(masksDir, pluginConfig);
744
729
  try {
745
730
  await pluginState.maskLoader.loadCatalog();
746
731
  if (verbose) {
747
- client.app.log({
748
- service: 'maskweaver',
749
- level: 'info',
750
- message: `Masks found at: ${masksDir}`,
751
- });
732
+ pluginLog(client, 'info', `Masks found at: ${masksDir}`);
752
733
  }
753
734
  }
754
735
  catch (e) {
755
- client.app.log({
756
- service: 'maskweaver',
757
- level: 'warn',
758
- message: `Failed to load masks: ${e}`,
759
- });
736
+ pluginLog(client, 'warn', `Failed to load masks: ${e}`);
760
737
  pluginState.maskLoader = null;
761
738
  }
762
739
  }
@@ -770,26 +747,14 @@ export const MaskweaverPlugin = async ({ client, directory }) => {
770
747
  const defaultMask = await pluginState.maskLoader.load(defaultMaskId);
771
748
  if (defaultMask) {
772
749
  pluginState.activeMask = defaultMask;
773
- client.app.log({
774
- service: 'maskweaver',
775
- level: 'info',
776
- message: `Auto-activated default mask: ${defaultMaskId} (${defaultMask.profile.name})`,
777
- });
750
+ pluginLog(client, 'info', `Auto-activated default mask: ${defaultMaskId} (${defaultMask.profile.name})`);
778
751
  }
779
752
  else {
780
- client.app.log({
781
- service: 'maskweaver',
782
- level: 'warn',
783
- message: `Default mask "${defaultMaskId}" not found or disabled`,
784
- });
753
+ pluginLog(client, 'warn', `Default mask "${defaultMaskId}" not found or disabled`);
785
754
  }
786
755
  }
787
756
  catch (e) {
788
- client.app.log({
789
- service: 'maskweaver',
790
- level: 'warn',
791
- message: `Failed to auto-activate default mask: ${e}`,
792
- });
757
+ pluginLog(client, 'warn', `Failed to auto-activate default mask: ${e}`);
793
758
  }
794
759
  }
795
760
  // ==========================================================================
@@ -805,14 +770,15 @@ export const MaskweaverPlugin = async ({ client, directory }) => {
805
770
  const isToolActive = (toolName) => isToolEnabled(pluginConfig, toolName);
806
771
  // Helper to ensure tool arguments are compatible with opencode's expected format.
807
772
  // opencode expects a ZodRawShape (raw object), NOT a ZodObject instance.
773
+ // Zod 4: schema.def.shape, Zod 3: schema._def.shape()
808
774
  const wrapSchema = (schema) => {
809
775
  if (!schema || typeof schema !== 'object')
810
776
  return schema;
811
- // If it's a ZodObject (Zod 4), extract its shape
812
- if (schema.def && typeof schema.def === 'object' && schema.type === 'object') {
777
+ // Zod 4 def.shape is a plain object
778
+ if (schema.def && typeof schema.def === 'object' && schema.type === 'object' && schema.def.shape && typeof schema.def.shape === 'object') {
813
779
  return schema.def.shape;
814
780
  }
815
- // If it's a ZodObject (Zod 3), extract its shape
781
+ // Zod 3 _def.shape() returns a plain object
816
782
  if (schema._def && typeof schema._def.shape === 'function') {
817
783
  return schema._def.shape();
818
784
  }
@@ -934,104 +900,20 @@ export const MaskweaverPlugin = async ({ client, directory }) => {
934
900
  };
935
901
  }
936
902
  // ==========================================================================
937
- // 8. Load and register agents
903
+ // 8. Agents are loaded from .opencode/agents/*.md files by OpenCode's
904
+ // filesystem-based agent loader (see config/agent.ts:110-140).
905
+ // installAssets() in step 2 copies agent .md files so they are picked up.
906
+ // The 'agent' property in Hooks is NOT consumed by OpenCode — confirmed
907
+ // by source analysis (packages/opencode/src/plugin/index.ts:92-103).
938
908
  // ==========================================================================
939
- const assetsDir = getAssetsDir();
940
- const projectOpencodeDir = path.join(directory, '.opencode');
941
- // Load from package assets first, then project .opencode (project overrides package)
942
- const loadedAgents = loadAgentAssets(assetsDir, projectOpencodeDir);
943
- // ==========================================================================
944
- // 8b. Generate agents from model pool (or legacy fallback)
945
- // ==========================================================================
946
- {
947
- const { loadRuntimeConfig, normalizeDummyHumansConfig } = await import('../shared/config.js');
948
- const { createModelRegistry } = await import('../shared/model-registry.js');
949
- const runtimeConfig = loadRuntimeConfig(directory);
950
- if (runtimeConfig.dummyHumans) {
951
- const pool = normalizeDummyHumansConfig(runtimeConfig.dummyHumans);
952
- // Initialize the global model registry
953
- createModelRegistry(pool);
954
- if (loadedAgents['dummy-human']) {
955
- // Generate agent variants from pool entries
956
- for (const entry of pool) {
957
- const agentName = `dummy-${entry.id}`;
958
- if (!loadedAgents[agentName]) {
959
- const tierLabel = entry.tier === 'flash' ? 'Flash' : entry.tier === 'premium' ? 'Premium' : 'Standard';
960
- const capStr = entry.capabilities.slice(0, 3).join(', ');
961
- loadedAgents[agentName] = {
962
- ...loadedAgents['dummy-human'],
963
- description: `Dummy-Human (${entry.id}) - ${tierLabel}. ${entry.description || capStr}. [max ${entry.maxConcurrent} concurrent]`,
964
- model: entry.model,
965
- };
966
- }
967
- }
968
- // Also ensure legacy dummy-flash / dummy-premium aliases exist (for backward compat)
969
- const flashEntry = pool.find(e => e.tier === 'flash');
970
- const humanEntry = pool.find(e => e.tier === 'human');
971
- const premiumEntry = pool.find(e => e.tier === 'premium');
972
- if (flashEntry && !loadedAgents['dummy-flash']) {
973
- loadedAgents['dummy-flash'] = loadedAgents[`dummy-${flashEntry.id}`];
974
- }
975
- if (humanEntry) {
976
- // dummy-human already exists as the base agent; just update its model from pool
977
- loadedAgents['dummy-human'].model = humanEntry.model;
978
- }
979
- if (premiumEntry && !loadedAgents['dummy-premium']) {
980
- loadedAgents['dummy-premium'] = loadedAgents[`dummy-${premiumEntry.id}`];
981
- }
982
- // Fallback: if no tier mapping found, use defaults
983
- if (!loadedAgents['dummy-flash']) {
984
- loadedAgents['dummy-flash'] = {
985
- ...loadedAgents['dummy-human'],
986
- description: 'Dummy-Human (Flash) - Fast and cheap',
987
- model: 'google/gemini-2.0-flash',
988
- };
989
- }
990
- if (!loadedAgents['dummy-premium']) {
991
- loadedAgents['dummy-premium'] = {
992
- ...loadedAgents['dummy-human'],
993
- description: 'Dummy-Human (Premium) - Powerful and reasoning',
994
- model: 'google/gemini-2.0-pro-exp-02-05',
995
- };
996
- }
997
- }
998
- }
999
- else {
1000
- // No pool config → legacy hardcoded defaults
1001
- if (loadedAgents['dummy-human']) {
1002
- if (!loadedAgents['dummy-flash']) {
1003
- loadedAgents['dummy-flash'] = {
1004
- ...loadedAgents['dummy-human'],
1005
- description: 'Dummy-Human (Flash) - Fast and cheap',
1006
- model: 'google/gemini-2.0-flash',
1007
- };
1008
- }
1009
- if (!loadedAgents['dummy-premium']) {
1010
- loadedAgents['dummy-premium'] = {
1011
- ...loadedAgents['dummy-human'],
1012
- description: 'Dummy-Human (Premium) - Powerful and reasoning',
1013
- model: 'google/gemini-2.0-pro-exp-02-05',
1014
- };
1015
- }
1016
- }
1017
- }
1018
- }
1019
- // Apply config overrides to agents
1020
- for (const agentId of Object.keys(loadedAgents)) {
1021
- const override = getAgentOverride(pluginConfig, agentId);
1022
- if (override) {
1023
- if (override.model)
1024
- loadedAgents[agentId].model = override.model;
1025
- if (override.systemPrompt)
1026
- loadedAgents[agentId].prompt = override.systemPrompt;
1027
- }
1028
- }
1029
909
  // ==========================================================================
1030
- // 9. Return plugin hooks
910
+ // 9. Return plugin hooks (official OpenCode Hooks interface only)
911
+ // Note: Agents are registered via .opencode/agents/*.md files (installed by
912
+ // installAssets()), NOT via the plugin return. The Hooks type does not
913
+ // include 'agent' — OpenCode loads agents from the filesystem exclusively.
1031
914
  // ==========================================================================
1032
915
  return {
1033
- // Agent registration
1034
- agent: loadedAgents,
916
+ // Agent registration handled via .opencode/agents/*.md files (see installAssets)
1035
917
  // System prompt transform - inject active mask
1036
918
  'experimental.chat.system.transform': async (_input, output) => {
1037
919
  if (state?.activeMask) {
@@ -1054,11 +936,7 @@ ${buildRichPrompt(state.activeMask)}
1054
936
  try {
1055
937
  const masks = await pluginState.maskLoader.listAll();
1056
938
  const categories = await pluginState.maskLoader.listCategories();
1057
- client.app.log({
1058
- service: 'maskweaver',
1059
- level: 'info',
1060
- message: `Session started - ${masks.length} masks available across ${categories.length} categories`,
1061
- });
939
+ pluginLog(client, 'info', `Session started - ${masks.length} masks available across ${categories.length} categories`);
1062
940
  }
1063
941
  catch (_e) {
1064
942
  // Ignore errors
@@ -1085,19 +963,14 @@ ${buildRichPrompt(state.activeMask)}
1085
963
  const wasActive = pluginState.activeMask !== null;
1086
964
  pluginState.activeMask = null;
1087
965
  if (wasActive) {
1088
- client.app.log({
1089
- service: 'maskweaver',
1090
- level: 'info',
1091
- message: 'Session ended - active mask cleared',
1092
- });
966
+ pluginLog(client, 'info', 'Session ended - active mask cleared');
1093
967
  }
1094
968
  }
1095
969
  }
1096
970
  },
1097
- // Config hook - (oh-my-opencode pattern)
971
+ // Config hook - allows plugins to modify opencode configuration
1098
972
  config: async (config) => {
1099
- // NOTE: Current opencode version expects config to be a function, not an object.
1100
- // Agent overrides are currently not supported via this hook in opencode core.
973
+ // Reserved for future configuration injection (model, provider, etc.)
1101
974
  return;
1102
975
  },
1103
976
  };