@maskweaver/plugin 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -17
- package/src/hooks/sessionCreated.ts +0 -40
- package/src/index.ts +0 -26
- package/src/tools/listMasks.ts +0 -87
- package/src/tools/selectMask.ts +0 -80
package/package.json
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maskweaver/plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Maskweaver plugin for opencode - Expert AI personas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
7
|
"files": [
|
|
9
|
-
"dist"
|
|
10
|
-
"src"
|
|
8
|
+
"dist"
|
|
11
9
|
],
|
|
12
10
|
"exports": {
|
|
13
|
-
".":
|
|
14
|
-
"import": "./dist/index.js",
|
|
15
|
-
"types": "./dist/index.d.ts"
|
|
16
|
-
}
|
|
11
|
+
".": "./dist/index.js"
|
|
17
12
|
},
|
|
18
13
|
"scripts": {
|
|
19
|
-
"build": "bun build ./src/index.ts --outdir dist --target node
|
|
14
|
+
"build": "bun build ./src/index.ts --outdir dist --target node",
|
|
20
15
|
"dev": "bun run --watch ./src/index.ts",
|
|
21
16
|
"test": "bun test"
|
|
22
17
|
},
|
|
@@ -42,13 +37,5 @@
|
|
|
42
37
|
},
|
|
43
38
|
"publishConfig": {
|
|
44
39
|
"access": "public"
|
|
45
|
-
},
|
|
46
|
-
"peerDependencies": {
|
|
47
|
-
"@opencode-ai/plugin": ">=0.1.0"
|
|
48
|
-
},
|
|
49
|
-
"peerDependenciesMeta": {
|
|
50
|
-
"@opencode-ai/plugin": {
|
|
51
|
-
"optional": true
|
|
52
|
-
}
|
|
53
40
|
}
|
|
54
41
|
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session Created Hook
|
|
3
|
-
*
|
|
4
|
-
* Handles initialization when a new session is created.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { MaskweaverState } from '../index';
|
|
8
|
-
|
|
9
|
-
export async function handleSessionCreated(
|
|
10
|
-
session: any,
|
|
11
|
-
state: MaskweaverState,
|
|
12
|
-
client: any
|
|
13
|
-
): Promise<void> {
|
|
14
|
-
try {
|
|
15
|
-
const categories = await state.maskLoader.listCategories();
|
|
16
|
-
const masks = await state.maskLoader.listAll();
|
|
17
|
-
|
|
18
|
-
// Log available masks
|
|
19
|
-
await client.app.log({
|
|
20
|
-
service: 'maskweaver',
|
|
21
|
-
level: 'info',
|
|
22
|
-
message: 'Session created - masks available',
|
|
23
|
-
extra: {
|
|
24
|
-
categories: categories.length,
|
|
25
|
-
masks: masks.length,
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// If there's a default mask configured, apply it
|
|
30
|
-
// For now, just notify that masks are available
|
|
31
|
-
|
|
32
|
-
} catch (error) {
|
|
33
|
-
await client.app.log({
|
|
34
|
-
service: 'maskweaver',
|
|
35
|
-
level: 'error',
|
|
36
|
-
message: 'Failed to initialize masks for session',
|
|
37
|
-
extra: { error: String(error) },
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Maskweaver Plugin for opencode
|
|
3
|
-
*
|
|
4
|
-
* Minimal version for debugging
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Plugin } from '@opencode-ai/plugin';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Maskweaver Plugin - Minimal
|
|
11
|
-
*/
|
|
12
|
-
export const MaskweaverPlugin: Plugin = async (ctx) => {
|
|
13
|
-
const { client } = ctx;
|
|
14
|
-
|
|
15
|
-
await client.app.log({
|
|
16
|
-
service: 'maskweaver',
|
|
17
|
-
level: 'info',
|
|
18
|
-
message: 'Maskweaver plugin loaded (minimal version)',
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
// Empty for now - just testing if plugin loads
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export default MaskweaverPlugin;
|
package/src/tools/listMasks.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* List Masks Tool
|
|
3
|
-
*
|
|
4
|
-
* Lists all available expert persona masks.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { tool } from '@opencode-ai/plugin';
|
|
8
|
-
import type { MaskweaverState } from '../index';
|
|
9
|
-
|
|
10
|
-
export function createListMasksTool(state: MaskweaverState) {
|
|
11
|
-
return tool({
|
|
12
|
-
description: `List all available expert persona masks.
|
|
13
|
-
Returns masks grouped by category with their expertise areas.
|
|
14
|
-
|
|
15
|
-
Use this to discover which expert personas are available before applying one with select_mask.`,
|
|
16
|
-
|
|
17
|
-
args: {
|
|
18
|
-
category: tool.schema.string().optional().describe(
|
|
19
|
-
'Filter by category (e.g., "software-engineering", "ai-ml")'
|
|
20
|
-
),
|
|
21
|
-
tag: tool.schema.string().optional().describe(
|
|
22
|
-
'Filter by tag (e.g., "tdd", "architecture", "systems")'
|
|
23
|
-
),
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
async execute(args, context) {
|
|
27
|
-
const { category, tag } = args;
|
|
28
|
-
const { maskLoader } = state;
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const allMasks = await maskLoader.listAll();
|
|
32
|
-
const categories = await maskLoader.listCategories();
|
|
33
|
-
|
|
34
|
-
// Filter by category if specified
|
|
35
|
-
let filtered = allMasks;
|
|
36
|
-
if (category) {
|
|
37
|
-
filtered = allMasks.filter(m => m.category === category);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Filter by tag if specified
|
|
41
|
-
if (tag) {
|
|
42
|
-
filtered = filtered.filter(m => m.tags.includes(tag));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Group by category
|
|
46
|
-
const grouped: Record<string, Array<{
|
|
47
|
-
id: string;
|
|
48
|
-
name: string;
|
|
49
|
-
tags: string[];
|
|
50
|
-
}>> = {};
|
|
51
|
-
|
|
52
|
-
for (const mask of filtered) {
|
|
53
|
-
if (!grouped[mask.category]) {
|
|
54
|
-
grouped[mask.category] = [];
|
|
55
|
-
}
|
|
56
|
-
grouped[mask.category].push({
|
|
57
|
-
id: mask.id,
|
|
58
|
-
name: mask.name,
|
|
59
|
-
tags: mask.tags,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Format summary
|
|
64
|
-
const summary = categories.map(cat =>
|
|
65
|
-
`${cat.name} (${cat.count} masks): ${cat.description}`
|
|
66
|
-
).join('\n');
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
success: true,
|
|
70
|
-
summary: `Found ${filtered.length} masks across ${Object.keys(grouped).length} categories`,
|
|
71
|
-
categories: summary,
|
|
72
|
-
masks: grouped,
|
|
73
|
-
activeMask: state.activeMask ? {
|
|
74
|
-
id: state.activeMask.metadata.id,
|
|
75
|
-
name: state.activeMask.profile.name,
|
|
76
|
-
} : null,
|
|
77
|
-
hint: 'Use select_mask with a mask ID to apply a persona (e.g., select_mask("linus-torvalds"))',
|
|
78
|
-
};
|
|
79
|
-
} catch (error) {
|
|
80
|
-
return {
|
|
81
|
-
success: false,
|
|
82
|
-
message: `Failed to list masks: ${error}`,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
}
|
package/src/tools/selectMask.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Select Mask Tool
|
|
3
|
-
*
|
|
4
|
-
* Allows users to apply an expert persona (mask) to the AI.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { tool } from '@opencode-ai/plugin';
|
|
8
|
-
import { promptBuilder } from '@maskweaver/core';
|
|
9
|
-
import type { MaskweaverState } from '../index';
|
|
10
|
-
|
|
11
|
-
export function createSelectMaskTool(state: MaskweaverState) {
|
|
12
|
-
return tool({
|
|
13
|
-
description: `Apply an expert persona (mask) to the AI assistant.
|
|
14
|
-
This transforms how the AI thinks, communicates, and approaches problems.
|
|
15
|
-
|
|
16
|
-
Example personas: linus-torvalds (systems programming), martin-fowler (architecture), kent-beck (TDD)
|
|
17
|
-
|
|
18
|
-
Use list_masks first to see all available masks.`,
|
|
19
|
-
|
|
20
|
-
args: {
|
|
21
|
-
maskId: tool.schema.string().describe(
|
|
22
|
-
'ID of the mask to apply (e.g., "linus-torvalds")'
|
|
23
|
-
),
|
|
24
|
-
mode: tool.schema.enum(['minimal', 'standard', 'rich']).optional().describe(
|
|
25
|
-
'Prompt richness: minimal (core only), standard (default), rich (full context)'
|
|
26
|
-
),
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
async execute(args, context) {
|
|
30
|
-
const { maskId, mode = 'standard' } = args;
|
|
31
|
-
const { maskLoader } = state;
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
const mask = await maskLoader.load(maskId);
|
|
35
|
-
|
|
36
|
-
if (!mask) {
|
|
37
|
-
return {
|
|
38
|
-
success: false,
|
|
39
|
-
message: `Mask '${maskId}' not found. Use list_masks to see available options.`,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Build system prompt based on mode
|
|
44
|
-
let systemPrompt: string;
|
|
45
|
-
switch (mode) {
|
|
46
|
-
case 'minimal':
|
|
47
|
-
systemPrompt = promptBuilder.minimal(mask);
|
|
48
|
-
break;
|
|
49
|
-
case 'rich':
|
|
50
|
-
systemPrompt = promptBuilder.rich(mask);
|
|
51
|
-
break;
|
|
52
|
-
default:
|
|
53
|
-
systemPrompt = promptBuilder.build(mask);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Store active mask
|
|
57
|
-
state.activeMask = mask;
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
success: true,
|
|
61
|
-
message: `🎭 Mask '${mask.profile.name}' applied.\n\n> ${mask.profile.tagline}`,
|
|
62
|
-
mask: {
|
|
63
|
-
id: mask.metadata.id,
|
|
64
|
-
name: mask.profile.name,
|
|
65
|
-
category: mask.category,
|
|
66
|
-
expertise: mask.profile.expertise,
|
|
67
|
-
tone: mask.behavior.communicationStyle.tone,
|
|
68
|
-
},
|
|
69
|
-
systemPrompt,
|
|
70
|
-
instruction: 'The system prompt above has been applied. The AI will now respond as this persona.',
|
|
71
|
-
};
|
|
72
|
-
} catch (error) {
|
|
73
|
-
return {
|
|
74
|
-
success: false,
|
|
75
|
-
message: `Failed to load mask: ${error}`,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
}
|