rig-opencode 0.1.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 ADDED
@@ -0,0 +1,63 @@
1
+ # rig-opencode
2
+
3
+ OpenCode plugin that records skill usage to a local JSONL file for Rig.
4
+
5
+ ## Install
6
+
7
+ Add the npm package to your OpenCode config.
8
+
9
+ ```json
10
+ {
11
+ "$schema": "https://opencode.ai/config.json",
12
+ "plugin": ["rig-opencode"]
13
+ }
14
+ ```
15
+
16
+ OpenCode installs npm plugins automatically with Bun at startup.
17
+
18
+ ## What It Records
19
+
20
+ When OpenCode executes the native `skill` tool, the plugin appends one JSON line:
21
+
22
+ ```json
23
+ {"source":"opencode","skillName":"typescript-fix-null-safety","usedAt":"2026-05-30T01:12:00.000Z"}
24
+ ```
25
+
26
+ Default log path:
27
+
28
+ ```txt
29
+ ~/.rig/usage.jsonl
30
+ ```
31
+
32
+ Rig reads this file to show skill usage counts and dashboard summaries.
33
+
34
+ ## Environment Variables
35
+
36
+ The plugin works without any environment variables. Use these only when you want
37
+ to customize where logs are written or temporarily disable tracking.
38
+
39
+ | Name | Default | Description |
40
+ | --- | --- | --- |
41
+ | `RIG_USAGE_LOG_PATH` | `~/.rig/usage.jsonl` | JSONL file path to append usage events to. |
42
+ | `RIG_USAGE_SOURCE` | `opencode` | Source value written into each event. |
43
+ | `RIG_USAGE_DISABLED` | unset | Set to `1` or `true` to disable recording. |
44
+
45
+ Examples:
46
+
47
+ ```bash
48
+ # Write usage logs somewhere else
49
+ RIG_USAGE_LOG_PATH=./.rig/usage/rig-usage.jsonl opencode
50
+
51
+ # Override the source field
52
+ RIG_USAGE_SOURCE=opencode-local opencode
53
+
54
+ # Temporarily disable tracking
55
+ RIG_USAGE_DISABLED=1 opencode
56
+ ```
57
+
58
+ ## Local Development
59
+
60
+ ```bash
61
+ pnpm --filter rig-opencode check-ts
62
+ pnpm --filter rig-opencode build
63
+ ```
@@ -0,0 +1,10 @@
1
+ import { Plugin } from '@opencode-ai/plugin';
2
+
3
+ interface RigSkillUsageLogEntry {
4
+ source: string;
5
+ skillName: string;
6
+ usedAt: string;
7
+ }
8
+ declare const RigSkillUsagePlugin: Plugin;
9
+
10
+ export { type RigSkillUsageLogEntry, RigSkillUsagePlugin };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import{appendFile as a,mkdir as g}from"node:fs/promises";import{homedir as c}from"node:os";import{dirname as f,resolve as u}from"node:path";var k="~/.rig/usage.jsonl",p="opencode",E=async()=>({"tool.execute.after":async(n,r)=>{if(d()||!S(n))return;let e=y(n,r);e&&await m({source:process.env.RIG_USAGE_SOURCE||p,skillName:e,usedAt:new Date().toISOString()})}}),m=async n=>{let r=w(process.env.RIG_USAGE_LOG_PATH||k);await g(f(r),{recursive:!0}),await a(r,`${JSON.stringify(n)}
2
+ `,"utf8")},d=()=>{let n=process.env.RIG_USAGE_DISABLED?.toLowerCase();return n==="1"||n==="true"},S=n=>t(n,"tool")==="skill",y=(n,r)=>{let e=[n,r,s(n,"args"),s(r,"args"),s(n,"input"),s(r,"input")];for(let o of e){let l=t(o,"skillName")??t(o,"skill_name")??t(o,"name")??t(o,"skill");if(l)return l}return null},s=(n,r)=>{if(!i(n))return null;let e=n[r];return i(e)?e:null},t=(n,r)=>{if(!i(n))return null;let e=n[r];return typeof e=="string"&&e.trim().length>0?e:null},i=n=>typeof n=="object"&&n!==null,w=n=>n==="~"?c():n.startsWith("~/")?u(c(),n.slice(2)):u(n);export{E as RigSkillUsagePlugin};
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { appendFile, mkdir } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, resolve } from 'node:path';\nimport type { Plugin } from '@opencode-ai/plugin';\n\nconst DEFAULT_LOG_PATH = '~/.rig/usage.jsonl';\nconst DEFAULT_SOURCE = 'opencode';\n\nexport interface RigSkillUsageLogEntry {\n source: string;\n skillName: string;\n usedAt: string;\n}\n\nexport const RigSkillUsagePlugin: Plugin = async () => {\n return {\n 'tool.execute.after': async (input, output) => {\n if (isDisabled()) {\n return;\n }\n\n if (!isSkillTool(input)) {\n return;\n }\n\n const skillName = getSkillName(input, output);\n\n if (!skillName) {\n return;\n }\n\n await appendUsage({\n source: process.env.RIG_USAGE_SOURCE || DEFAULT_SOURCE,\n skillName,\n usedAt: new Date().toISOString(),\n });\n },\n };\n};\n\nconst appendUsage = async (entry: RigSkillUsageLogEntry) => {\n const logPath = expandPath(\n process.env.RIG_USAGE_LOG_PATH || DEFAULT_LOG_PATH,\n );\n\n await mkdir(dirname(logPath), { recursive: true });\n await appendFile(logPath, `${JSON.stringify(entry)}\\n`, 'utf8');\n};\n\nconst isDisabled = () => {\n const value = process.env.RIG_USAGE_DISABLED?.toLowerCase();\n\n return value === '1' || value === 'true';\n};\n\nconst isSkillTool = (input: unknown) => {\n return getStringProperty(input, 'tool') === 'skill';\n};\n\nconst getSkillName = (input: unknown, output: unknown) => {\n const candidates = [\n input,\n output,\n getObjectProperty(input, 'args'),\n getObjectProperty(output, 'args'),\n getObjectProperty(input, 'input'),\n getObjectProperty(output, 'input'),\n ];\n\n for (const candidate of candidates) {\n const skillName =\n getStringProperty(candidate, 'skillName') ??\n getStringProperty(candidate, 'skill_name') ??\n getStringProperty(candidate, 'name') ??\n getStringProperty(candidate, 'skill');\n\n if (skillName) {\n return skillName;\n }\n }\n\n return null;\n};\n\nconst getObjectProperty = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return null;\n }\n\n const property = value[key];\n\n return isRecord(property) ? property : null;\n};\n\nconst getStringProperty = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return null;\n }\n\n const property = value[key];\n\n return typeof property === 'string' && property.trim().length > 0\n ? property\n : null;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst expandPath = (path: string) => {\n if (path === '~') {\n return homedir();\n }\n\n if (path.startsWith('~/')) {\n return resolve(homedir(), path.slice(2));\n }\n\n return resolve(path);\n};\n"],"mappings":"AAAA,OAAS,cAAAA,EAAY,SAAAC,MAAa,mBAClC,OAAS,WAAAC,MAAe,UACxB,OAAS,WAAAC,EAAS,WAAAC,MAAe,YAGjC,IAAMC,EAAmB,qBACnBC,EAAiB,WAQVC,EAA8B,UAClC,CACL,qBAAsB,MAAOC,EAAOC,IAAW,CAK7C,GAJIC,EAAW,GAIX,CAACC,EAAYH,CAAK,EACpB,OAGF,IAAMI,EAAYC,EAAaL,EAAOC,CAAM,EAEvCG,GAIL,MAAME,EAAY,CAChB,OAAQ,QAAQ,IAAI,kBAAoBR,EACxC,UAAAM,EACA,OAAQ,IAAI,KAAK,EAAE,YAAY,CACjC,CAAC,CACH,CACF,GAGIE,EAAc,MAAOC,GAAiC,CAC1D,IAAMC,EAAUC,EACd,QAAQ,IAAI,oBAAsBZ,CACpC,EAEA,MAAMJ,EAAME,EAAQa,CAAO,EAAG,CAAE,UAAW,EAAK,CAAC,EACjD,MAAMhB,EAAWgB,EAAS,GAAG,KAAK,UAAUD,CAAK,CAAC;AAAA,EAAM,MAAM,CAChE,EAEML,EAAa,IAAM,CACvB,IAAMQ,EAAQ,QAAQ,IAAI,oBAAoB,YAAY,EAE1D,OAAOA,IAAU,KAAOA,IAAU,MACpC,EAEMP,EAAeH,GACZW,EAAkBX,EAAO,MAAM,IAAM,QAGxCK,EAAe,CAACL,EAAgBC,IAAoB,CACxD,IAAMW,EAAa,CACjBZ,EACAC,EACAY,EAAkBb,EAAO,MAAM,EAC/Ba,EAAkBZ,EAAQ,MAAM,EAChCY,EAAkBb,EAAO,OAAO,EAChCa,EAAkBZ,EAAQ,OAAO,CACnC,EAEA,QAAWa,KAAaF,EAAY,CAClC,IAAMR,EACJO,EAAkBG,EAAW,WAAW,GACxCH,EAAkBG,EAAW,YAAY,GACzCH,EAAkBG,EAAW,MAAM,GACnCH,EAAkBG,EAAW,OAAO,EAEtC,GAAIV,EACF,OAAOA,CAEX,CAEA,OAAO,IACT,EAEMS,EAAoB,CAACH,EAAgBK,IAAgB,CACzD,GAAI,CAACC,EAASN,CAAK,EACjB,OAAO,KAGT,IAAMO,EAAWP,EAAMK,CAAG,EAE1B,OAAOC,EAASC,CAAQ,EAAIA,EAAW,IACzC,EAEMN,EAAoB,CAACD,EAAgBK,IAAgB,CACzD,GAAI,CAACC,EAASN,CAAK,EACjB,OAAO,KAGT,IAAMO,EAAWP,EAAMK,CAAG,EAE1B,OAAO,OAAOE,GAAa,UAAYA,EAAS,KAAK,EAAE,OAAS,EAC5DA,EACA,IACN,EAEMD,EAAYN,GACT,OAAOA,GAAU,UAAYA,IAAU,KAG1CD,EAAcS,GACdA,IAAS,IACJxB,EAAQ,EAGbwB,EAAK,WAAW,IAAI,EACftB,EAAQF,EAAQ,EAAGwB,EAAK,MAAM,CAAC,CAAC,EAGlCtB,EAAQsB,CAAI","names":["appendFile","mkdir","homedir","dirname","resolve","DEFAULT_LOG_PATH","DEFAULT_SOURCE","RigSkillUsagePlugin","input","output","isDisabled","isSkillTool","skillName","getSkillName","appendUsage","entry","logPath","expandPath","value","getStringProperty","candidates","getObjectProperty","candidate","key","isRecord","property","path"]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "rig-opencode",
3
+ "version": "0.1.1",
4
+ "private": false,
5
+ "description": "OpenCode plugin for tracking Rig skill usage locally",
6
+ "type": "module",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "import": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
17
+ }
18
+ },
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "check-ts": "tsc --noEmit",
24
+ "prepublishOnly": "pnpm build"
25
+ },
26
+ "keywords": [
27
+ "opencode",
28
+ "opencode-plugin",
29
+ "rig",
30
+ "skills",
31
+ "usage-tracking"
32
+ ],
33
+ "license": "MIT",
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "devDependencies": {
38
+ "@opencode-ai/plugin": "^1.15.13",
39
+ "@types/node": "catalog:types",
40
+ "tsup": "catalog:build",
41
+ "typescript": "catalog:types"
42
+ }
43
+ }