opencode-snippets 1.4.3 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +110 -25
- package/dist/index.js.map +1 -1
- package/dist/src/config.d.ts +41 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +150 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/constants.d.ts +9 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +13 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/loader.d.ts.map +1 -1
- package/dist/src/loader.js +4 -3
- package/dist/src/loader.js.map +1 -1
- package/dist/src/logger.d.ts +2 -2
- package/dist/src/logger.d.ts.map +1 -1
- package/dist/src/logger.js +5 -12
- package/dist/src/logger.js.map +1 -1
- package/package.json +4 -3
- package/skill/snippets/SKILL.md +148 -0
package/README.md
CHANGED
|
@@ -281,18 +281,34 @@ Be extremely concise. No explanations unless asked.
|
|
|
281
281
|
|
|
282
282
|
## Configuration
|
|
283
283
|
|
|
284
|
-
|
|
284
|
+
The plugin can be configured via `config.jsonc` files:
|
|
285
285
|
|
|
286
|
-
|
|
286
|
+
- **Global**: `~/.config/opencode/snippet/config.jsonc`
|
|
287
|
+
- **Project**: `.opencode/snippet/config.jsonc` (overrides global settings)
|
|
287
288
|
|
|
288
|
-
|
|
289
|
-
|
|
289
|
+
A default config file is created automatically on first run.
|
|
290
|
+
|
|
291
|
+
### Full Configuration Example
|
|
292
|
+
|
|
293
|
+
```jsonc
|
|
294
|
+
{
|
|
295
|
+
"$schema": "https://raw.githubusercontent.com/JosXa/opencode-snippets/main/schema/config.schema.json",
|
|
296
|
+
"logging": {
|
|
297
|
+
"debug": false // Enable debug logging (logs: ~/.config/opencode/logs/snippets/daily/)
|
|
298
|
+
},
|
|
299
|
+
"installSkill": true // Auto-install SKILL.md to ~/.config/opencode/skill/snippets/
|
|
300
|
+
}
|
|
290
301
|
```
|
|
291
302
|
|
|
292
|
-
|
|
303
|
+
All boolean settings accept: `true`, `false`, `"enabled"`, `"disabled"`
|
|
304
|
+
|
|
305
|
+
### Debug Logging
|
|
306
|
+
|
|
307
|
+
Logs are written to `~/.config/opencode/logs/snippets/daily/` when enabled.
|
|
293
308
|
|
|
294
309
|
## Behavior Notes
|
|
295
310
|
|
|
311
|
+
- Snippets expand everywhere: regular chat, question responses, skills, and slash commands
|
|
296
312
|
- Snippets are loaded once at plugin startup
|
|
297
313
|
- Hashtag matching is **case-insensitive** (`#Hello` = `#hello`)
|
|
298
314
|
- Unknown hashtags are left unchanged
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA8ClD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,MAoH5B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,46 @@
|
|
|
1
|
+
import { mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
1
4
|
import { createCommandExecuteHandler } from "./src/commands.js";
|
|
5
|
+
import { loadConfig } from "./src/config.js";
|
|
2
6
|
import { assembleMessage, expandHashtags } from "./src/expander.js";
|
|
3
7
|
import { loadSnippets } from "./src/loader.js";
|
|
4
8
|
import { logger } from "./src/logger.js";
|
|
5
9
|
import { executeShellCommands } from "./src/shell.js";
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
const PLUGIN_ROOT = join(__dirname, "..");
|
|
13
|
+
const SKILL_DIR = join(PLUGIN_ROOT, "skill");
|
|
14
|
+
// Install skill to global config directory
|
|
15
|
+
async function installSkillToGlobal() {
|
|
16
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
17
|
+
const globalSkillDir = join(home, ".config", "opencode", "skill", "snippets");
|
|
18
|
+
const globalSkillPath = join(globalSkillDir, "SKILL.md");
|
|
19
|
+
const sourceSkillPath = join(SKILL_DIR, "snippets", "SKILL.md");
|
|
20
|
+
try {
|
|
21
|
+
const sourceFile = Bun.file(sourceSkillPath);
|
|
22
|
+
if (!(await sourceFile.exists())) {
|
|
23
|
+
logger.debug("Source skill not found", { path: sourceSkillPath });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Check if already installed with same content
|
|
27
|
+
const globalFile = Bun.file(globalSkillPath);
|
|
28
|
+
if (await globalFile.exists()) {
|
|
29
|
+
const existing = await globalFile.text();
|
|
30
|
+
const source = await sourceFile.text();
|
|
31
|
+
if (existing === source) {
|
|
32
|
+
logger.debug("Skill already installed", { path: globalSkillPath });
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
mkdirSync(globalSkillDir, { recursive: true });
|
|
37
|
+
await Bun.write(globalSkillPath, sourceFile);
|
|
38
|
+
logger.debug("Installed snippets skill", { path: globalSkillPath });
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
logger.debug("Failed to install skill", { error: String(err) });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
6
44
|
/**
|
|
7
45
|
* Snippets Plugin for OpenCode
|
|
8
46
|
*
|
|
@@ -12,6 +50,14 @@ import { executeShellCommands } from "./src/shell.js";
|
|
|
12
50
|
* @see https://github.com/JosXa/opencode-snippets for full documentation
|
|
13
51
|
*/
|
|
14
52
|
export const SnippetsPlugin = async (ctx) => {
|
|
53
|
+
// Load configuration (global + project-local override)
|
|
54
|
+
const config = loadConfig(ctx.directory);
|
|
55
|
+
// Apply config settings
|
|
56
|
+
logger.debugEnabled = config.logging.debug;
|
|
57
|
+
// Install skill to global config so OpenCode discovers it (if enabled)
|
|
58
|
+
if (config.installSkill) {
|
|
59
|
+
await installSkillToGlobal();
|
|
60
|
+
}
|
|
15
61
|
// Load all snippets at startup (global + project directory)
|
|
16
62
|
const startupStart = performance.now();
|
|
17
63
|
const snippets = await loadSnippets(ctx.directory);
|
|
@@ -19,9 +65,45 @@ export const SnippetsPlugin = async (ctx) => {
|
|
|
19
65
|
logger.debug("Plugin startup complete", {
|
|
20
66
|
startupTimeMs: startupTime.toFixed(2),
|
|
21
67
|
snippetCount: snippets.size,
|
|
68
|
+
installSkill: config.installSkill,
|
|
69
|
+
debugLogging: config.logging.debug,
|
|
22
70
|
});
|
|
23
71
|
// Create command handler
|
|
24
72
|
const commandHandler = createCommandExecuteHandler(ctx.client, snippets, ctx.directory);
|
|
73
|
+
/**
|
|
74
|
+
* Processes text parts for snippet expansion and shell command execution
|
|
75
|
+
*/
|
|
76
|
+
const processTextParts = async (parts) => {
|
|
77
|
+
const messageStart = performance.now();
|
|
78
|
+
let expandTimeTotal = 0;
|
|
79
|
+
let shellTimeTotal = 0;
|
|
80
|
+
let processedParts = 0;
|
|
81
|
+
for (const part of parts) {
|
|
82
|
+
if (part.type === "text" && part.text) {
|
|
83
|
+
// 1. Expand hashtags recursively with loop detection
|
|
84
|
+
const expandStart = performance.now();
|
|
85
|
+
const expansionResult = expandHashtags(part.text, snippets);
|
|
86
|
+
part.text = assembleMessage(expansionResult);
|
|
87
|
+
const expandTime = performance.now() - expandStart;
|
|
88
|
+
expandTimeTotal += expandTime;
|
|
89
|
+
// 2. Execute shell commands: !`command`
|
|
90
|
+
const shellStart = performance.now();
|
|
91
|
+
part.text = await executeShellCommands(part.text, ctx);
|
|
92
|
+
const shellTime = performance.now() - shellStart;
|
|
93
|
+
shellTimeTotal += shellTime;
|
|
94
|
+
processedParts += 1;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const totalTime = performance.now() - messageStart;
|
|
98
|
+
if (processedParts > 0) {
|
|
99
|
+
logger.debug("Text parts processing complete", {
|
|
100
|
+
totalTimeMs: totalTime.toFixed(2),
|
|
101
|
+
snippetExpandTimeMs: expandTimeTotal.toFixed(2),
|
|
102
|
+
shellTimeMs: shellTimeTotal.toFixed(2),
|
|
103
|
+
processedParts,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
};
|
|
25
107
|
return {
|
|
26
108
|
// Register /snippet command
|
|
27
109
|
config: async (opencodeConfig) => {
|
|
@@ -37,33 +119,36 @@ export const SnippetsPlugin = async (ctx) => {
|
|
|
37
119
|
// Only process user messages, never assistant messages
|
|
38
120
|
if (output.message.role !== "user")
|
|
39
121
|
return;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
part.text = await executeShellCommands(part.text, ctx);
|
|
55
|
-
const shellTime = performance.now() - shellStart;
|
|
56
|
-
shellTimeTotal += shellTime;
|
|
57
|
-
processedParts += 1;
|
|
122
|
+
// Skip processing if any part is marked as ignored (e.g., command output)
|
|
123
|
+
if (output.parts.some((part) => "ignored" in part && part.ignored))
|
|
124
|
+
return;
|
|
125
|
+
await processTextParts(output.parts);
|
|
126
|
+
},
|
|
127
|
+
// Process all messages including question tool responses
|
|
128
|
+
"experimental.chat.messages.transform": async (_input, output) => {
|
|
129
|
+
for (const message of output.messages) {
|
|
130
|
+
// Only process user messages
|
|
131
|
+
if (message.info.role === "user") {
|
|
132
|
+
// Skip processing if any part is marked as ignored (e.g., command output)
|
|
133
|
+
if (message.parts.some((part) => "ignored" in part && part.ignored))
|
|
134
|
+
continue;
|
|
135
|
+
await processTextParts(message.parts);
|
|
58
136
|
}
|
|
59
137
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
138
|
+
},
|
|
139
|
+
// Process skill tool output to expand snippets in skill content
|
|
140
|
+
"tool.execute.after": async (input, output) => {
|
|
141
|
+
// Only process the skill tool
|
|
142
|
+
if (input.tool !== "skill")
|
|
143
|
+
return;
|
|
144
|
+
// The skill tool returns markdown content in its output
|
|
145
|
+
// Expand hashtags in the skill content
|
|
146
|
+
if (typeof output.output === "string" && output.output.trim()) {
|
|
147
|
+
const expansionResult = expandHashtags(output.output, snippets);
|
|
148
|
+
output.output = assembleMessage(expansionResult);
|
|
149
|
+
logger.debug("Skill content expanded", {
|
|
150
|
+
tool: input.tool,
|
|
151
|
+
callID: input.callID,
|
|
67
152
|
});
|
|
68
153
|
}
|
|
69
154
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boolean setting that can be true/false or "enabled"/"disabled" for flexibility
|
|
3
|
+
*/
|
|
4
|
+
export type BooleanSetting = boolean | "enabled" | "disabled";
|
|
5
|
+
/**
|
|
6
|
+
* Logging configuration
|
|
7
|
+
*/
|
|
8
|
+
export interface LoggingConfig {
|
|
9
|
+
/** Enable debug logging to file */
|
|
10
|
+
debug: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Configuration schema for the snippets plugin
|
|
14
|
+
*/
|
|
15
|
+
export interface SnippetsConfig {
|
|
16
|
+
/** Logging settings */
|
|
17
|
+
logging: LoggingConfig;
|
|
18
|
+
/** Automatically install SKILL.md to global skill directory */
|
|
19
|
+
installSkill: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Load and merge configuration from global and project-specific config files
|
|
23
|
+
*
|
|
24
|
+
* Configuration priority (highest to lowest):
|
|
25
|
+
* 1. Project-specific config (.opencode/snippet/config.jsonc)
|
|
26
|
+
* 2. Global config (~/.config/opencode/snippet/config.jsonc)
|
|
27
|
+
* 3. Default values
|
|
28
|
+
*
|
|
29
|
+
* @param projectDir - Optional project directory to check for project-specific config
|
|
30
|
+
* @returns Merged configuration object
|
|
31
|
+
*/
|
|
32
|
+
export declare function loadConfig(projectDir?: string): SnippetsConfig;
|
|
33
|
+
/**
|
|
34
|
+
* Get the path to the global config file
|
|
35
|
+
*/
|
|
36
|
+
export declare function getGlobalConfigPath(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Get the path to the project config file
|
|
39
|
+
*/
|
|
40
|
+
export declare function getProjectConfigPath(projectDir: string): string;
|
|
41
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,OAAO,EAAE,aAAa,CAAC;IAEvB,+DAA+D;IAC/D,YAAY,EAAE,OAAO,CAAC;CACvB;AAkGD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CA8B9D;AAiBD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { parse as parseJsonc } from "jsonc-parser";
|
|
3
|
+
import { getProjectPaths, PATHS } from "./constants.js";
|
|
4
|
+
import { logger } from "./logger.js";
|
|
5
|
+
/**
|
|
6
|
+
* Default configuration values
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULT_CONFIG = {
|
|
9
|
+
logging: {
|
|
10
|
+
debug: false,
|
|
11
|
+
},
|
|
12
|
+
installSkill: true,
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Default config file content with comments explaining all options
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_CONFIG_CONTENT = `{
|
|
18
|
+
// JSON Schema for editor autocompletion
|
|
19
|
+
"$schema": "https://raw.githubusercontent.com/JosXa/opencode-snippets/main/schema/config.schema.json",
|
|
20
|
+
|
|
21
|
+
// Logging settings
|
|
22
|
+
"logging": {
|
|
23
|
+
// Enable debug logging to file
|
|
24
|
+
// Logs are written to ~/.config/opencode/logs/snippets/daily/
|
|
25
|
+
// Values: true, false, "enabled", "disabled"
|
|
26
|
+
// Default: false
|
|
27
|
+
"debug": false
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
// Automatically install SKILL.md to global skill directory
|
|
31
|
+
// When enabled, the snippets skill is copied to ~/.config/opencode/skill/snippets/
|
|
32
|
+
// This enables the LLM to understand how to use snippets
|
|
33
|
+
// Values: true, false, "enabled", "disabled"
|
|
34
|
+
// Default: true
|
|
35
|
+
"installSkill": true
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
/**
|
|
39
|
+
* Normalize boolean setting to boolean
|
|
40
|
+
*/
|
|
41
|
+
function normalizeBooleanSetting(value) {
|
|
42
|
+
if (value === undefined)
|
|
43
|
+
return undefined;
|
|
44
|
+
if (typeof value === "boolean")
|
|
45
|
+
return value;
|
|
46
|
+
if (value === "enabled")
|
|
47
|
+
return true;
|
|
48
|
+
if (value === "disabled")
|
|
49
|
+
return false;
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Parse a JSONC file and return the parsed object
|
|
54
|
+
*/
|
|
55
|
+
function parseJsoncFile(filePath) {
|
|
56
|
+
try {
|
|
57
|
+
const content = readFileSync(filePath, "utf-8");
|
|
58
|
+
const parsed = parseJsonc(content);
|
|
59
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
60
|
+
return parsed;
|
|
61
|
+
}
|
|
62
|
+
logger.warn("Config file has invalid structure, using defaults", { filePath });
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
logger.warn("Failed to parse config file", {
|
|
67
|
+
filePath,
|
|
68
|
+
error: error instanceof Error ? error.message : String(error),
|
|
69
|
+
});
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Ensure the global snippets directory and config file exist
|
|
75
|
+
*/
|
|
76
|
+
function ensureGlobalConfigExists() {
|
|
77
|
+
// Create snippets directory if it doesn't exist
|
|
78
|
+
if (!existsSync(PATHS.SNIPPETS_DIR)) {
|
|
79
|
+
mkdirSync(PATHS.SNIPPETS_DIR, { recursive: true });
|
|
80
|
+
logger.debug("Created global snippets directory", { path: PATHS.SNIPPETS_DIR });
|
|
81
|
+
}
|
|
82
|
+
// Create default config file if it doesn't exist
|
|
83
|
+
if (!existsSync(PATHS.CONFIG_FILE_GLOBAL)) {
|
|
84
|
+
writeFileSync(PATHS.CONFIG_FILE_GLOBAL, DEFAULT_CONFIG_CONTENT, "utf-8");
|
|
85
|
+
logger.debug("Created default config file", { path: PATHS.CONFIG_FILE_GLOBAL });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Load and merge configuration from global and project-specific config files
|
|
90
|
+
*
|
|
91
|
+
* Configuration priority (highest to lowest):
|
|
92
|
+
* 1. Project-specific config (.opencode/snippet/config.jsonc)
|
|
93
|
+
* 2. Global config (~/.config/opencode/snippet/config.jsonc)
|
|
94
|
+
* 3. Default values
|
|
95
|
+
*
|
|
96
|
+
* @param projectDir - Optional project directory to check for project-specific config
|
|
97
|
+
* @returns Merged configuration object
|
|
98
|
+
*/
|
|
99
|
+
export function loadConfig(projectDir) {
|
|
100
|
+
// Ensure global directory and config file exist
|
|
101
|
+
ensureGlobalConfigExists();
|
|
102
|
+
// Start with defaults
|
|
103
|
+
let config = structuredClone(DEFAULT_CONFIG);
|
|
104
|
+
// Load global config
|
|
105
|
+
if (existsSync(PATHS.CONFIG_FILE_GLOBAL)) {
|
|
106
|
+
const globalConfig = parseJsoncFile(PATHS.CONFIG_FILE_GLOBAL);
|
|
107
|
+
config = mergeConfig(config, globalConfig);
|
|
108
|
+
logger.debug("Loaded global config", { path: PATHS.CONFIG_FILE_GLOBAL });
|
|
109
|
+
}
|
|
110
|
+
// Load project config if project directory is provided
|
|
111
|
+
if (projectDir) {
|
|
112
|
+
const projectPaths = getProjectPaths(projectDir);
|
|
113
|
+
if (existsSync(projectPaths.CONFIG_FILE)) {
|
|
114
|
+
const projectConfig = parseJsoncFile(projectPaths.CONFIG_FILE);
|
|
115
|
+
config = mergeConfig(config, projectConfig);
|
|
116
|
+
logger.debug("Loaded project config", { path: projectPaths.CONFIG_FILE });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
logger.debug("Final config", {
|
|
120
|
+
loggingDebug: config.logging.debug,
|
|
121
|
+
installSkill: config.installSkill,
|
|
122
|
+
});
|
|
123
|
+
return config;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Merge raw config into base config
|
|
127
|
+
*/
|
|
128
|
+
function mergeConfig(base, raw) {
|
|
129
|
+
const debugValue = normalizeBooleanSetting(raw.logging?.debug);
|
|
130
|
+
const installSkillValue = normalizeBooleanSetting(raw.installSkill);
|
|
131
|
+
return {
|
|
132
|
+
logging: {
|
|
133
|
+
debug: debugValue !== undefined ? debugValue : base.logging.debug,
|
|
134
|
+
},
|
|
135
|
+
installSkill: installSkillValue !== undefined ? installSkillValue : base.installSkill,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get the path to the global config file
|
|
140
|
+
*/
|
|
141
|
+
export function getGlobalConfigPath() {
|
|
142
|
+
return PATHS.CONFIG_FILE_GLOBAL;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get the path to the project config file
|
|
146
|
+
*/
|
|
147
|
+
export function getProjectConfigPath(projectDir) {
|
|
148
|
+
return getProjectPaths(projectDir).CONFIG_FILE;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -15,6 +15,15 @@ export declare const PATHS: {
|
|
|
15
15
|
readonly CONFIG_DIR: string;
|
|
16
16
|
/** Snippets directory */
|
|
17
17
|
readonly SNIPPETS_DIR: string;
|
|
18
|
+
/** Global config file */
|
|
19
|
+
readonly CONFIG_FILE_GLOBAL: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Get project-specific paths based on project directory
|
|
23
|
+
*/
|
|
24
|
+
export declare function getProjectPaths(projectDir: string): {
|
|
25
|
+
SNIPPETS_DIR: string;
|
|
26
|
+
CONFIG_FILE: string;
|
|
18
27
|
};
|
|
19
28
|
/**
|
|
20
29
|
* Plugin configuration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,QAAQ;IACnB,0CAA0C;;IAG1C,6CAA6C;;CAErC,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,KAAK;IAChB,uCAAuC;;IAGvC,yBAAyB;;CAEjB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,MAAM;IACjB,uCAAuC;;CAE/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,QAAQ;IACnB,0CAA0C;;IAG1C,6CAA6C;;CAErC,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,KAAK;IAChB,uCAAuC;;IAGvC,yBAAyB;;IAGzB,yBAAyB;;CAEjB,CAAC;AAEX;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM;;;EAMjD;AAED;;GAEG;AACH,eAAO,MAAM,MAAM;IACjB,uCAAuC;;CAE/B,CAAC"}
|
package/dist/src/constants.js
CHANGED
|
@@ -16,8 +16,20 @@ export const PATHS = {
|
|
|
16
16
|
/** OpenCode configuration directory */
|
|
17
17
|
CONFIG_DIR: join(homedir(), ".config", "opencode"),
|
|
18
18
|
/** Snippets directory */
|
|
19
|
-
SNIPPETS_DIR: join(
|
|
19
|
+
SNIPPETS_DIR: join(homedir(), ".config", "opencode", "snippet"),
|
|
20
|
+
/** Global config file */
|
|
21
|
+
CONFIG_FILE_GLOBAL: join(homedir(), ".config", "opencode", "snippet", "config.jsonc"),
|
|
20
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Get project-specific paths based on project directory
|
|
25
|
+
*/
|
|
26
|
+
export function getProjectPaths(projectDir) {
|
|
27
|
+
const snippetDir = join(projectDir, ".opencode", "snippet");
|
|
28
|
+
return {
|
|
29
|
+
SNIPPETS_DIR: snippetDir,
|
|
30
|
+
CONFIG_FILE: join(snippetDir, "config.jsonc"),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
21
33
|
/**
|
|
22
34
|
* Plugin configuration
|
|
23
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,0CAA0C;IAC1C,OAAO,EAAE,mBAAmB;IAE5B,6CAA6C;IAC7C,aAAa,EAAE,aAAa;CACpB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,uCAAuC;IACvC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC;IAElD,yBAAyB;IACzB,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,0CAA0C;IAC1C,OAAO,EAAE,mBAAmB;IAE5B,6CAA6C;IAC7C,aAAa,EAAE,aAAa;CACpB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,uCAAuC;IACvC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC;IAElD,yBAAyB;IACzB,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC;IAE/D,yBAAyB;IACzB,kBAAkB,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC;CAC7E,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IAC5D,OAAO;QACL,YAAY,EAAE,UAAU;QACxB,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,uCAAuC;IACvC,iBAAiB,EAAE,KAAK;CAChB,CAAC"}
|
package/dist/src/loader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAsB,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnF;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC,CAc1B;AAqHD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,WAAW,EAAE,CAYrE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAsB,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnF;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC,CAc1B;AAqHD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,WAAW,EAAE,CAYrE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK5E;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,EAC1D,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4B7F;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,eAAe,EACzB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
package/dist/src/loader.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readdir, unlink } from "node:fs/promises";
|
|
2
2
|
import { basename, join } from "node:path";
|
|
3
3
|
import matter from "gray-matter";
|
|
4
4
|
import { CONFIG, PATHS } from "./constants.js";
|
|
@@ -65,7 +65,7 @@ async function loadSnippetFile(dir, filename, source) {
|
|
|
65
65
|
try {
|
|
66
66
|
const name = basename(filename, CONFIG.SNIPPET_EXTENSION);
|
|
67
67
|
const filePath = join(dir, filename);
|
|
68
|
-
const fileContent = await
|
|
68
|
+
const fileContent = await Bun.file(filePath).text();
|
|
69
69
|
const parsed = matter(fileContent);
|
|
70
70
|
const content = parsed.content.trim();
|
|
71
71
|
const frontmatter = parsed.data;
|
|
@@ -143,6 +143,7 @@ export function listSnippets(registry) {
|
|
|
143
143
|
*/
|
|
144
144
|
export async function ensureSnippetsDir(projectDir) {
|
|
145
145
|
const dir = projectDir ? join(projectDir, ".opencode", "snippet") : PATHS.SNIPPETS_DIR;
|
|
146
|
+
const { mkdir } = await import("node:fs/promises");
|
|
146
147
|
await mkdir(dir, { recursive: true });
|
|
147
148
|
return dir;
|
|
148
149
|
}
|
|
@@ -174,7 +175,7 @@ export async function createSnippet(name, content, options = {}, projectDir) {
|
|
|
174
175
|
else {
|
|
175
176
|
fileContent = content;
|
|
176
177
|
}
|
|
177
|
-
await
|
|
178
|
+
await Bun.write(filePath, fileContent);
|
|
178
179
|
logger.info("Created snippet", { name, path: filePath });
|
|
179
180
|
return filePath;
|
|
180
181
|
}
|
package/dist/src/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":"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"}
|
package/dist/src/logger.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare class Logger {
|
|
2
2
|
private logDir;
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
debugEnabled: boolean;
|
|
4
|
+
constructor(logDirOverride?: string, debugEnabled?: boolean);
|
|
5
5
|
private ensureLogDir;
|
|
6
6
|
private formatData;
|
|
7
7
|
private getCallerFile;
|
package/dist/src/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAIA,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAS;IACvB,YAAY,EAAE,OAAO,CAAC;gBAEV,cAAc,CAAC,EAAE,MAAM,EAAE,YAAY,UAAQ;IAKzD,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,UAAU;IAyBlB,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,KAAK;IAwBb,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAKpD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAKrD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAKpD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAItD;AAGD,eAAO,MAAM,MAAM,QAAe,CAAC"}
|
package/dist/src/logger.js
CHANGED
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
3
|
import { PATHS } from "./constants.js";
|
|
4
|
-
/**
|
|
5
|
-
* Check if debug logging is enabled via environment variable
|
|
6
|
-
*/
|
|
7
|
-
function isDebugEnabled() {
|
|
8
|
-
const value = process.env.DEBUG_SNIPPETS;
|
|
9
|
-
return value === "1" || value === "true";
|
|
10
|
-
}
|
|
11
4
|
export class Logger {
|
|
12
5
|
logDir;
|
|
13
|
-
|
|
6
|
+
debugEnabled;
|
|
7
|
+
constructor(logDirOverride, debugEnabled = false) {
|
|
14
8
|
this.logDir = logDirOverride ?? join(PATHS.CONFIG_DIR, "logs", "snippets");
|
|
15
|
-
|
|
16
|
-
get enabled() {
|
|
17
|
-
return isDebugEnabled();
|
|
9
|
+
this.debugEnabled = debugEnabled;
|
|
18
10
|
}
|
|
19
11
|
ensureLogDir() {
|
|
20
12
|
if (!existsSync(this.logDir)) {
|
|
@@ -67,7 +59,8 @@ export class Logger {
|
|
|
67
59
|
}
|
|
68
60
|
}
|
|
69
61
|
write(level, component, message, data) {
|
|
70
|
-
|
|
62
|
+
// Only write debug logs when debugEnabled, but always write other levels
|
|
63
|
+
if (level === "DEBUG" && !this.debugEnabled)
|
|
71
64
|
return;
|
|
72
65
|
try {
|
|
73
66
|
this.ensureLogDir();
|
package/dist/src/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-snippets",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Hashtag-based snippet expansion plugin for OpenCode - instant inline text shortcuts",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/JosXa/opencode-snippets#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"gray-matter": "^4.0.3"
|
|
32
|
+
"gray-matter": "^4.0.3",
|
|
33
|
+
"jsonc-parser": "^3.3.1"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
|
35
36
|
"@opencode-ai/plugin": ">=1.0.0"
|
|
@@ -51,5 +52,5 @@
|
|
|
51
52
|
"prepare": "husky",
|
|
52
53
|
"prepublishOnly": "bun run build"
|
|
53
54
|
},
|
|
54
|
-
"files": ["dist"]
|
|
55
|
+
"files": ["dist", "skill"]
|
|
55
56
|
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: snippets
|
|
3
|
+
description: MUST use when user asks to create, edit, manage, or share snippets, or asks how snippets work
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Snippets
|
|
7
|
+
|
|
8
|
+
Reusable text blocks expanded via `#hashtag` in messages.
|
|
9
|
+
|
|
10
|
+
## Locations
|
|
11
|
+
|
|
12
|
+
### Snippets
|
|
13
|
+
- **Global**: `~/.config/opencode/snippet/*.md`
|
|
14
|
+
- **Project**: `.opencode/snippet/*.md` (overrides global)
|
|
15
|
+
|
|
16
|
+
### Configuration
|
|
17
|
+
- **Global**: `~/.config/opencode/snippet/config.jsonc`
|
|
18
|
+
- **Project**: `.opencode/snippet/config.jsonc` (merges with global, project takes priority)
|
|
19
|
+
|
|
20
|
+
### Logs
|
|
21
|
+
- **Debug logs**: `~/.config/opencode/logs/snippets/daily/YYYY-MM-DD.log`
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
All boolean settings accept: `true`, `false`, `"enabled"`, `"disabled"`
|
|
26
|
+
|
|
27
|
+
Full config example with all options:
|
|
28
|
+
|
|
29
|
+
```jsonc
|
|
30
|
+
{
|
|
31
|
+
// JSON Schema for editor autocompletion
|
|
32
|
+
"$schema": "https://raw.githubusercontent.com/JosXa/opencode-snippets/main/schema/config.schema.json",
|
|
33
|
+
|
|
34
|
+
// Logging settings
|
|
35
|
+
"logging": {
|
|
36
|
+
// Enable debug logging to file
|
|
37
|
+
// Logs are written to ~/.config/opencode/logs/snippets/daily/
|
|
38
|
+
// Default: false
|
|
39
|
+
"debug": false
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
// Automatically install SKILL.md to global skill directory
|
|
43
|
+
// When enabled, the snippets skill is copied to ~/.config/opencode/skill/snippets/
|
|
44
|
+
// This enables the LLM to understand how to use snippets
|
|
45
|
+
// Default: true
|
|
46
|
+
"installSkill": true
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Snippet Format
|
|
51
|
+
|
|
52
|
+
```md
|
|
53
|
+
---
|
|
54
|
+
aliases:
|
|
55
|
+
- short
|
|
56
|
+
- alt
|
|
57
|
+
description: Optional
|
|
58
|
+
---
|
|
59
|
+
Content here
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Frontmatter optional. Filename (minus .md) = primary hashtag.
|
|
63
|
+
|
|
64
|
+
## Features
|
|
65
|
+
|
|
66
|
+
- `#other` - include another snippet (recursive, max 15 depth)
|
|
67
|
+
- `` !`cmd` `` - shell substitution, output injected
|
|
68
|
+
|
|
69
|
+
### Prepend/Append Blocks
|
|
70
|
+
|
|
71
|
+
Move content to message start/end instead of inline. Best for long reference material that breaks writing flow.
|
|
72
|
+
|
|
73
|
+
```md
|
|
74
|
+
---
|
|
75
|
+
aliases: jira
|
|
76
|
+
---
|
|
77
|
+
Jira MCP
|
|
78
|
+
<prepend>
|
|
79
|
+
## Jira Field Mappings
|
|
80
|
+
|
|
81
|
+
- customfield_16570 => Acceptance Criteria
|
|
82
|
+
- customfield_11401 => Team
|
|
83
|
+
</prepend>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Input: `Create bug in #jira about leak`
|
|
87
|
+
Output: Prepended section at top + `Create bug in Jira MCP about leak`.
|
|
88
|
+
|
|
89
|
+
Use `<append>` for reference material at end. Content inside blocks should use `##` headings.
|
|
90
|
+
|
|
91
|
+
## Commands
|
|
92
|
+
|
|
93
|
+
- `/snippet add <name> [content]` - create global snippet
|
|
94
|
+
- `/snippet add --project <name>` - create project snippet
|
|
95
|
+
- `/snippet list` - show all available
|
|
96
|
+
- `/snippet delete <name>` - remove snippet
|
|
97
|
+
|
|
98
|
+
## Good Snippets
|
|
99
|
+
|
|
100
|
+
Short, focused, single-purpose. Examples:
|
|
101
|
+
|
|
102
|
+
```md
|
|
103
|
+
# careful.md
|
|
104
|
+
---
|
|
105
|
+
aliases: safe
|
|
106
|
+
---
|
|
107
|
+
Be careful, autonomous, and ONLY do what I asked.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```md
|
|
111
|
+
# context.md
|
|
112
|
+
---
|
|
113
|
+
aliases: ctx
|
|
114
|
+
---
|
|
115
|
+
Project: !`basename $(pwd)`
|
|
116
|
+
Branch: !`git branch --show-current`
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Compose via includes: `#base-rules` inside `#project-config`.
|
|
120
|
+
|
|
121
|
+
## Sharing Snippets
|
|
122
|
+
|
|
123
|
+
Share to GitHub Discussions: https://github.com/JosXa/opencode-snippets/discussions/categories/snippets
|
|
124
|
+
|
|
125
|
+
When user wants to share:
|
|
126
|
+
|
|
127
|
+
1. Check `gh --version` works
|
|
128
|
+
2. **If gh available**: MUST use question tool to ask user to confirm posting + ask "When do you use it?". Then:
|
|
129
|
+
```bash
|
|
130
|
+
gh api graphql -f query='mutation($repoId: ID!, $catId: ID!, $title: String!, $body: String!) { createDiscussion(input: {repositoryId: $repoId, categoryId: $catId, title: $title, body: $body}) { discussion { url } } }' -f repoId="R_kgDOQ968oA" -f catId="DIC_kwDOQ968oM4C1Qcv" -f title="filename.md" -f body="<body>"
|
|
131
|
+
```
|
|
132
|
+
Body format:
|
|
133
|
+
```
|
|
134
|
+
## Snippet Content
|
|
135
|
+
|
|
136
|
+
\`\`\`markdown
|
|
137
|
+
<full snippet file content>
|
|
138
|
+
\`\`\`
|
|
139
|
+
|
|
140
|
+
## When do you use it?
|
|
141
|
+
|
|
142
|
+
<user's answer>
|
|
143
|
+
```
|
|
144
|
+
3. **If gh unavailable**: Open browser:
|
|
145
|
+
```
|
|
146
|
+
https://github.com/JosXa/opencode-snippets/discussions/new?category=snippets&title=<url-encoded-filename>.md
|
|
147
|
+
```
|
|
148
|
+
Ask user (without question tool) for "When do you use it?" info. Tell them to paste snippet in markdown fence.
|