Publish built kitchen-sink and hello-world example plugins

This commit is contained in:
Claude committed 2026-09-26 21:22:49 +02:00
commit 8ac2b8542b
7 files changed
+115

No files matched your search

+24
View File
@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org/>
+8
View File
@@ -0,0 +1,8 @@
# VRCNext example plugins
Built bundles of the example plugins from
[vrcnext-plugin-system](https://github.com/vrcnext-plugins/vrcnext-plugin-system/tree/main/examples),
published so they can be installed from the Plugins tab by pasting this repository's URL.
Sources live in the plugin-system repository; this repository only carries `vrcnext-plugins.json`
and the `dist/` output of `./scripts/build.sh`.
+2
View File
@@ -0,0 +1,2 @@
var s={greetOnFriendOnline:{kind:"boolean",label:"Log a line when a friend comes online",description:"Writes to the plugin log, not to VRChat.",default:!0},tone:{kind:"select",label:"Greeting tone",default:"friendly",options:[{value:"friendly",label:"Friendly"},{value:"terse",label:"Terse"}]}},z={id:"hello-world",settings:s,activate(e){e.logger.info(`Hello from v${e.version}.`);let t=e.settings.get("tone")==="terse"?"Online:":"Welcome back,";e.events.on("friendTimelineEvent",n=>{e.settings.get("greetOnFriendOnline")&&n.type==="online"&&e.logger.info(`${t} ${n.friendName}`)}),e.ui.addSettingsCard({title:"Hello World",icon:"back_hand",render:n=>{n.appendChild(e.ui.createToggleRow("Show a toast right now",!1,i=>{i&&e.ui.toast({message:"Hello from a VRCNext plugin."})}))}})},deactivate(){}};export{z as default};
//# sourceMappingURL=hello-world.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/index.ts"],
"sourcesContent": ["/**\n * Minimal VRCNext plugin.\n *\n * Demonstrates the four things every plugin has available: typed settings, the host event\n * stream, UI injection using VRCNext's own markup, and disposal.\n */\n\nimport { definePlugin, type PluginId, type SettingsSchema } from '@vrcnext/plugin-api';\n\nconst settings = {\n greetOnFriendOnline: {\n kind: 'boolean',\n label: 'Log a line when a friend comes online',\n description: 'Writes to the plugin log, not to VRChat.',\n default: true,\n },\n tone: {\n kind: 'select',\n label: 'Greeting tone',\n default: 'friendly',\n options: [\n { value: 'friendly', label: 'Friendly' },\n { value: 'terse', label: 'Terse' },\n ],\n },\n} as const satisfies SettingsSchema;\n\nexport default definePlugin({\n id: 'hello-world' as PluginId,\n settings,\n\n activate(ctx) {\n ctx.logger.info(`Hello from v${ctx.version}.`);\n\n // `tone` is the literal union 'friendly' | 'terse', not a bare string.\n const greeting = ctx.settings.get('tone') === 'terse' ? 'Online:' : 'Welcome back,';\n\n ctx.events.on('friendTimelineEvent', (payload) => {\n if (!ctx.settings.get('greetOnFriendOnline')) return;\n if (payload.type !== 'online') return;\n ctx.logger.info(`${greeting} ${payload.friendName}`);\n });\n\n ctx.ui.addSettingsCard({\n title: 'Hello World',\n icon: 'back_hand',\n render: (card) => {\n card.appendChild(\n ctx.ui.createToggleRow(\n 'Show a toast right now',\n false,\n (checked) => {\n if (checked) ctx.ui.toast({ message: 'Hello from a VRCNext plugin.' });\n },\n ),\n );\n },\n });\n },\n\n deactivate() {\n // Listeners and panels registered through `ctx` are torn down by the host; only\n // plugin-owned resources created outside it need cleaning up here.\n },\n});\n"],
"mappings": "AASA,IAAMA,EAAW,CACf,oBAAqB,CACnB,KAAM,UACN,MAAO,wCACP,YAAa,2CACb,QAAS,EACX,EACA,KAAM,CACJ,KAAM,SACN,MAAO,gBACP,QAAS,WACT,QAAS,CACP,CAAE,MAAO,WAAY,MAAO,UAAW,EACvC,CAAE,MAAO,QAAS,MAAO,OAAQ,CACnC,CACF,CACF,EAEOC,EAAqB,CAC1B,GAAI,cACJ,SAAAD,EAEA,SAASE,EAAK,CACZA,EAAI,OAAO,KAAK,eAAeA,EAAI,OAAO,GAAG,EAG7C,IAAMC,EAAWD,EAAI,SAAS,IAAI,MAAM,IAAM,QAAU,UAAY,gBAEpEA,EAAI,OAAO,GAAG,sBAAwBE,GAAY,CAC3CF,EAAI,SAAS,IAAI,qBAAqB,GACvCE,EAAQ,OAAS,UACrBF,EAAI,OAAO,KAAK,GAAGC,CAAQ,IAAIC,EAAQ,UAAU,EAAE,CACrD,CAAC,EAEDF,EAAI,GAAG,gBAAgB,CACrB,MAAO,cACP,KAAM,YACN,OAASG,GAAS,CAChBA,EAAK,YACHH,EAAI,GAAG,gBACL,yBACA,GACCI,GAAY,CACPA,GAASJ,EAAI,GAAG,MAAM,CAAE,QAAS,8BAA+B,CAAC,CACvE,CACF,CACF,CACF,CACF,CAAC,CACH,EAEA,YAAa,CAGb,CACF",
"names": ["settings", "index_default", "ctx", "greeting", "payload", "card", "checked"]
}
+41
View File
@@ -0,0 +1,41 @@
var a=`
.ks-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
padding: 10px 0;
}
.ks-stat {
background: var(--bg-input);
border-radius: 10px;
padding: 12px 14px;
}
.ks-stat-label {
font-size: calc(11px + var(--fs-off, 0px));
color: var(--tx3);
}
.ks-stat-value {
font-size: calc(20px + var(--fs-off, 0px));
font-weight: 600;
color: var(--tx0);
font-variant-numeric: tabular-nums;
}
.ks-log {
max-height: 220px;
overflow-y: auto;
font-family: ui-monospace, monospace;
font-size: calc(11px + var(--fs-off, 0px));
color: var(--tx2);
background: var(--bg-input);
border-radius: 8px;
padding: 8px 10px;
}
.ks-log-line { white-space: pre-wrap; word-break: break-word; }
.ks-log-line + .ks-log-line { margin-top: 3px; }
`;function d(e){let t=document.createElement("div");return t.className="ks-log",e.appendChild(t),{append(n){let i=document.createElement("div");i.className="ks-log-line";let o=new Date().toLocaleTimeString();for(i.textContent=`${o} ${n}`,t.appendChild(i);t.childElementCount>200;)t.firstElementChild?.remove();t.scrollHeight-t.scrollTop-t.clientHeight<40&&(t.scrollTop=t.scrollHeight)},clear(){t.replaceChildren()}}}var u={watchGameLog:{kind:"boolean",label:"Follow the VRChat game log",description:"Streams player joins and world changes into the panel below.",default:!0},oscParameter:{kind:"string",label:"OSC parameter to pulse",description:"Sent to /avatar/parameters/<name> by the dashboard button.",default:"VRCEmote",placeholder:"VRCEmote"},oscValue:{kind:"number",label:"OSC value",default:1,min:0,max:255,step:1},verbosity:{kind:"select",label:"Log verbosity",default:"normal",options:[{value:"quiet",label:"Quiet"},{value:"normal",label:"Normal"},{value:"loud",label:"Everything"}]}},pe={id:"kitchen-sink",settings:u,activate(e){let t={gameLogCount:0,oscParamCount:0,panel:void 0,log:n=>{e.settings.get("verbosity")!=="quiet"&&(e.logger.info(n),t.panel?.append(n))}};e.ui.injectCss(a),p(e),h(e,t),v(e,t),b(e,t),y(e,t),S(e,t),C(e,t),w(e,t),k(e,t),N(e,t),e.logger.info(`Kitchen Sink v${e.version} ready.`)},deactivate(){}};function p(e){e.disposables.add(e.settings.onChange(t=>{e.logger.debug(`Settings changed; verbosity is now ${t.verbosity}.`)}))}function h(e,t){e.events.on("friendTimelineEvent",n=>{t.log(`[friend] ${n.friendName} \u2192 ${n.type}`)}),e.events.on("vrcCurrentInstance",n=>{if(typeof n!="object"||n===null)return;let i=n.worldName;typeof i=="string"&&t.log(`[instance] now in ${i}`)}),e.events.onAny(n=>{e.settings.get("verbosity")==="loud"&&e.logger.debug(`event ${n.type}`)})}function v(e,t){e.gameLog.on(n=>{e.settings.get("watchGameLog")&&(t.gameLogCount+=1,t.log(`[gamelog] ${n.type}: ${n.message}`))}),e.gameLog.onType("OnPlayerJoined",n=>{t.log(`[join] ${n.detail||n.message}`)}),e.gameLog.history(e.signal).then(n=>{e.logger.info(`Game log backlog: ${String(n.length)} entries.`)}).catch(n=>{e.signal.aborted||e.logger.warn(`Could not read the game log: ${String(n)}`)})}function b(e,t){if(!e.osc.available){t.log("[osc] OSC is Windows-only in VRCNext; skipping.");return}e.osc.connect(),e.osc.onParam(n=>{t.oscParamCount+=1,e.settings.get("verbosity")==="loud"&&t.log(`[osc] ${n.name} = ${String(n.value)}`)}),e.osc.onAvatarChange(n=>{t.log(`[osc] avatar ${n.avatarId} with ${String(n.parameters.length)} parameters`)})}function c(e){if(!e.osc.available)return"OSC unavailable (Windows only)";let t=e.settings.get("oscParameter"),n=e.settings.get("oscValue");return e.osc.send(t,"int",n),`${t} = ${String(n)}`}function y(e,t){e.deepLinks.onPrefix("wrld",n=>{t.log(`[link] world ${n.id}`)}),e.deepLinks.on(n=>{t.log(`[link] ${n.prefix}:${n.id}${n.action?` (${n.action})`:""}`)})}function S(e,t){e.router.get("stats",()=>Response.json({gameLogEvents:t.gameLogCount,oscParams:t.oscParamCount,verbosity:e.settings.get("verbosity")})),e.router.get("greet/:name",n=>Response.json({hello:n.params.name??"world"})),e.router.post("osc/pulse",()=>Response.json({sent:c(e)})),e.logger.info(`Routes mounted at ${e.router.base.pathname}`)}function C(e,t){e.contextMenu.contribute(n=>{let i=[{kind:"divider"},{kind:"item",icon:"auto_awesome",label:"Kitchen Sink: log this element",onSelect:()=>{t.log(`[ctx] ${n.element.tagName.toLowerCase()}`)}},{kind:"submenu",icon:"tune",label:"Kitchen Sink: verbosity",items:()=>u.verbosity.options.map(o=>({kind:"item",icon:"adjust",label:o.label,checked:e.settings.get("verbosity")===o.value,onSelect:()=>{e.settings.set("verbosity",o.value)}}))}];if(n.entity!==void 0){let o=n.entity;i.push({kind:"item",icon:"content_copy",label:`Copy ${o.type} id`,onSelect:()=>{navigator.clipboard.writeText(o.id)}})}return i})}function w(e,t){e.gameLog.onType("OnPlayerJoined",n=>{let i=n.detail||n.message;e.notifications.toast({message:`${i} joined.`}),e.notifications.desktopAvailable?e.notifications.desktop({title:"Player joined",subtitle:i,accent:"info"}):t.log("[notify] desktop/VR notifications are Windows-only.")}),e.events.on("friendTimelineEvent",n=>{n.type==="online"&&e.notifications.notifToast({kind:"notification",sender:n.friendName,message:"came online"})})}async function k(e,t){if(!await e.native.ready){t.log(`[native] no companion at ${e.native.endpoint}; VR targets unavailable.`);return}let n=await e.native.targets();t.log(`[native] targets: ${n.map(o=>o.name).join(", ")||"none"}`),e.gameLog.onType("OnPlayerJoined",o=>{let s=o.detail||o.message;e.native.notify({title:"Player joined",content:s,timeoutSecs:4,icon:"user-available",overrides:{wayvr:{content:`${s} joined the instance`,height:200,opacity:.85,alwaysShow:!0}}})}),e.events.on("friendTimelineEvent",o=>{o.type==="online"&&e.native.notify({title:o.friendName,content:"came online",sinks:["wayvr"],timeoutSecs:3,opacity:.7})});let i=await e.native.describe(); Line truncated
//# sourceMappingURL=kitchen-sink.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/styles.ts", "../src/log-panel.ts", "../src/index.ts"],
"sourcesContent": ["/**\n * Stylesheet injected by the plugin.\n *\n * Colours come from VRCNext's CSS custom properties rather than literals, so the plugin follows\n * the user's theme \u2014 including custom themes \u2014 instead of fighting it.\n */\n\nexport const PLUGIN_CSS = `\n.ks-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 10px;\n padding: 10px 0;\n}\n\n.ks-stat {\n background: var(--bg-input);\n border-radius: 10px;\n padding: 12px 14px;\n}\n\n.ks-stat-label {\n font-size: calc(11px + var(--fs-off, 0px));\n color: var(--tx3);\n}\n\n.ks-stat-value {\n font-size: calc(20px + var(--fs-off, 0px));\n font-weight: 600;\n color: var(--tx0);\n font-variant-numeric: tabular-nums;\n}\n\n.ks-log {\n max-height: 220px;\n overflow-y: auto;\n font-family: ui-monospace, monospace;\n font-size: calc(11px + var(--fs-off, 0px));\n color: var(--tx2);\n background: var(--bg-input);\n border-radius: 8px;\n padding: 8px 10px;\n}\n\n.ks-log-line { white-space: pre-wrap; word-break: break-word; }\n.ks-log-line + .ks-log-line { margin-top: 3px; }\n`;\n", "/**\n * Small scrolling log view used by the Kitchen Sink tab.\n *\n * Kept in its own module to show the normal pattern: UI helpers separate from the plugin's\n * lifecycle wiring, so `index.ts` stays readable.\n */\n\nconst MAX_LINES = 200;\n\nexport interface LogPanel {\n append(message: string): void;\n clear(): void;\n}\n\nexport function createLogPanel(parent: HTMLElement): LogPanel {\n const list = document.createElement('div');\n list.className = 'ks-log';\n parent.appendChild(list);\n\n return {\n append(message: string): void {\n const line = document.createElement('div');\n line.className = 'ks-log-line';\n const time = new Date().toLocaleTimeString();\n line.textContent = `${time} ${message}`;\n list.appendChild(line);\n\n while (list.childElementCount > MAX_LINES) list.firstElementChild?.remove();\n\n // Only chase the tail when the user has not scrolled up to read history.\n const atBottom = list.scrollHeight - list.scrollTop - list.clientHeight < 40;\n if (atBottom) list.scrollTop = list.scrollHeight;\n },\n\n clear(): void {\n list.replaceChildren();\n },\n };\n}\n", "/**\n * Kitchen Sink \u2014 the reference VRCNext plugin.\n *\n * Exercises every capability the host provides, in the order a plugin author is likely to need\n * them. Each section is small and commented so it can be copied out on its own.\n */\n\nimport {\n definePlugin,\n type ContextMenuEntry,\n type PluginContext,\n type PluginId,\n type SettingsSchema,\n} from '@vrcnext/plugin-api';\n\nimport { PLUGIN_CSS } from './styles.js';\nimport { createLogPanel, type LogPanel } from './log-panel.js';\n\nconst settings = {\n watchGameLog: {\n kind: 'boolean',\n label: 'Follow the VRChat game log',\n description: 'Streams player joins and world changes into the panel below.',\n default: true,\n },\n oscParameter: {\n kind: 'string',\n label: 'OSC parameter to pulse',\n description: 'Sent to /avatar/parameters/<name> by the dashboard button.',\n default: 'VRCEmote',\n placeholder: 'VRCEmote',\n },\n oscValue: {\n kind: 'number',\n label: 'OSC value',\n default: 1,\n min: 0,\n max: 255,\n step: 1,\n },\n verbosity: {\n kind: 'select',\n label: 'Log verbosity',\n default: 'normal',\n options: [\n { value: 'quiet', label: 'Quiet' },\n { value: 'normal', label: 'Normal' },\n { value: 'loud', label: 'Everything' },\n ],\n },\n} as const satisfies SettingsSchema;\n\ntype Ctx = PluginContext<typeof settings>;\n\n/** Shared mutable state for the session. Reset each activation. */\ninterface State {\n gameLogCount: number;\n oscParamCount: number;\n panel: LogPanel | undefined;\n /** Writes to both the plugin logger and the on-screen panel, honouring `verbosity`. */\n log(message: string): void;\n}\n\nexport default definePlugin({\n id: 'kitchen-sink' as PluginId,\n settings,\n\n activate(ctx) {\n const state: State = {\n gameLogCount: 0,\n oscParamCount: 0,\n panel: undefined,\n log: (message) => {\n if (ctx.settings.get('verbosity') === 'quiet') return;\n ctx.logger.info(message);\n state.panel?.append(message);\n },\n };\n\n // 1. Custom CSS, removed automatically on deactivate.\n ctx.ui.injectCss(PLUGIN_CSS);\n\n installSettingsWatch(ctx);\n installEvents(ctx, state);\n installGameLog(ctx, state);\n installOsc(ctx, state);\n installDeepLinks(ctx, state);\n installRoutes(ctx, state);\n installContextMenu(ctx, state);\n installNotifications(ctx, state);\n // Fire-and-forget: the companion probe must not hold up the rest of activation.\n void installNative(ctx, state);\n installUi(ctx, state);\n\n ctx.logger.info(`Kitchen Sink v${ctx.version} ready.`);\n },\n\n deactivate() {\nLine truncated
"mappings": "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 truncated
"names": ["PLUGIN_CSS", "createLogPanel", "parent", "list", "message", "line", "time", "settings", "index_default", "ctx", "state", "message", "PLUGIN_CSS", "installSettingsWatch", "installEvents", "installGameLog", "installOsc", "installDeepLinks", "installRoutes", "installContextMenu", "installNotifications", "installNative", "installUi", "values", "payload", "worldName", "envelope", "entry", "entries", "error", "event", "pulseOsc", "name", "value", "request", "target", "option", "entity", "who", "targets", "t", "description", "card", "grid", "statTile", "pulse", "installNavTab", "checked", "reset", "confirmed", "tab", "k", "activity", "createLogPanel", "output", "next", "response", "label", "read", "tile", "labelEl", "valueEl"]
}
+26
View File
@@ -0,0 +1,26 @@
{
"formatVersion": 1,
"name": "VRCNext Example Plugins",
"plugins": [
{
"id": "kitchen-sink",
"name": "Kitchen Sink",
"version": "1.0.0",
"description": "Reference plugin exercising every host capability.",
"entry": "dist/kitchen-sink.js",
"apiVersion": "^0.1.0",
"author": "vrcnext-plugins",
"homepage": "https://github.com/vrcnext-plugins/vrcnext-plugin-system"
},
{
"id": "hello-world",
"name": "Hello World",
"version": "1.0.0",
"description": "Minimal plugin showing settings, events and UI injection.",
"entry": "dist/hello-world.js",
"apiVersion": "^0.1.0",
"author": "vrcnext-plugins",
"homepage": "https://github.com/vrcnext-plugins/vrcnext-plugin-system"
}
]
}