[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M754GAEQQPCE5AC058MY8KGS":3,"skill-same:01M754GAEQQPCE5AC058MY8KGS":49},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":29,"commitSha":30,"skillDirectory":5,"forksCount":14,"repositoryHtmlUrl":31,"repositoryHomepageUrl":6,"ownerHtmlUrl":32,"ownerBlogUrl":33,"ownerDescription":6,"updatedAt":34,"install":35,"resources":48},"01M754GAEQQPCE5AC058MY8KGS","obsidian-hello-world",null,"Create a minimal working Obsidian plugin with commands and settings.\nUse when building your first plugin feature, testing your setup,\nor learning basic Obsidian plugin patterns.\nTrigger with phrases like \"obsidian hello world\", \"first obsidian plugin\",\n\"obsidian quick start\", \"simple obsidian plugin\".","SamuelChien\u002Fmega-skills-collection","SamuelChien","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F4652114?v=4","01M74KK34WVHA0P5ZYSJRDDFMG","Samuel Chien","01M74KK35FQN1N9VZ9EPTH3P2S",0,"MIT","https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection\u002Fblob\u002Fmain\u002Fobsidian-hello-world\u002FSKILL.md",[],[],"2026-11-12 13:55:43",false,"---\nname: obsidian-hello-world\ndescription: |\n  Create a minimal working Obsidian plugin with commands and settings.\n  Use when building your first plugin feature, testing your setup,\n  or learning basic Obsidian plugin patterns.\n  Trigger with phrases like \"obsidian hello world\", \"first obsidian plugin\",\n  \"obsidian quick start\", \"simple obsidian plugin\".\nallowed-tools: Read, Write, Edit\nversion: 1.0.0\nlicense: MIT\nauthor: Jeremy Longshore \u003Cjeremy@intentsolutions.io>\ncompatible-with: claude-code, codex, openclaw\n---\n# Obsidian Hello World\n\n## Overview\nBuild a minimal working Obsidian plugin demonstrating core features: commands, settings, and ribbon icons.\n\n## Prerequisites\n- Completed `obsidian-install-auth` setup\n- Development vault configured\n- Build pipeline working\n\n## Instructions\n\n### Step 1: Create Main Plugin Class\n```typescript\n\u002F\u002F src\u002Fmain.ts\nimport { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';\n\ninterface MyPluginSettings {\n  greeting: string;\n}\n\nconst DEFAULT_SETTINGS: MyPluginSettings = {\n  greeting: 'Hello, Obsidian!'\n}\n\nexport default class MyPlugin extends Plugin {\n  settings: MyPluginSettings;\n\n  async onload() {\n    await this.loadSettings();\n\n    \u002F\u002F Add ribbon icon\n    this.addRibbonIcon('dice', 'Greet Me', (evt: MouseEvent) => {\n      new Notice(this.settings.greeting);\n    });\n\n    \u002F\u002F Add command to command palette\n    this.addCommand({\n      id: 'show-greeting',\n      name: 'Show Greeting',\n      callback: () => {\n        new Notice(this.settings.greeting);\n      }\n    });\n\n    \u002F\u002F Add command with editor context\n    this.addCommand({\n      id: 'insert-greeting',\n      name: 'Insert Greeting at Cursor',\n      editorCallback: (editor: Editor, view: MarkdownView) => {\n        editor.replaceSelection(this.settings.greeting);\n      }\n    });\n\n    \u002F\u002F Add settings tab\n    this.addSettingTab(new MySettingTab(this.app, this));\n  }\n\n  onunload() {\n    console.log('Goodbye from My Plugin!');\n  }\n\n  async loadSettings() {\n    this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());\n  }\n\n  async saveSettings() {\n    await this.saveData(this.settings);\n  }\n}\n```\n\n### Step 2: Create Settings Tab\n```typescript\n\u002F\u002F Add to src\u002Fmain.ts\nclass MySettingTab extends PluginSettingTab {\n  plugin: MyPlugin;\n\n  constructor(app: App, plugin: MyPlugin) {\n    super(app, plugin);\n    this.plugin = plugin;\n  }\n\n  display(): void {\n    const { containerEl } = this;\n    containerEl.empty();\n\n    containerEl.createEl('h2', { text: 'My Plugin Settings' });\n\n    new Setting(containerEl)\n      .setName('Greeting')\n      .setDesc('The message to display when greeting')\n      .addText(text => text\n        .setPlaceholder('Enter your greeting')\n        .setValue(this.plugin.settings.greeting)\n        .onChange(async (value) => {\n          this.plugin.settings.greeting = value;\n          await this.plugin.saveSettings();\n        }));\n  }\n}\n```\n\n### Step 3: Create a Modal\n```typescript\n\u002F\u002F Add to src\u002Fmain.ts\nclass GreetingModal extends Modal {\n  greeting: string;\n\n  constructor(app: App, greeting: string) {\n    super(app);\n    this.greeting = greeting;\n  }\n\n  onOpen() {\n    const { contentEl } = this;\n    contentEl.createEl('h1', { text: this.greeting });\n    contentEl.createEl('p', { text: 'Click outside or press Escape to close.' });\n  }\n\n  onClose() {\n    const { contentEl } = this;\n    contentEl.empty();\n  }\n}\n\n\u002F\u002F Add to onload():\nthis.addCommand({\n  id: 'show-greeting-modal',\n  name: 'Show Greeting Modal',\n  callback: () => {\n    new GreetingModal(this.app, this.settings.greeting).open();\n  }\n});\n```\n\n### Step 4: Build and Test\n```bash\nset -euo pipefail\n# Build the plugin\nnpm run build\n\n# In Obsidian:\n# 1. Open Settings > Community plugins\n# 2. Enable \"My Plugin\"\n# 3. Click the dice icon in ribbon\n# 4. Open command palette (Ctrl\u002FCmd+P) and search \"Show Greeting\"\n```\n\n## Output\n- Working plugin with:\n  - Ribbon icon that shows a notice\n  - Commands in command palette\n  - Editor command to insert text\n  - Settings tab to configure greeting\n  - Modal for displaying content\n\n## Error Handling\n| Error | Cause | Solution |\n|-------|-------|----------|\n| Plugin not loading | Build errors | Check console for TypeScript errors |\n| Settings not saving | Missing loadData\u002FsaveData | Verify async\u002Fawait usage |\n| Command not showing | Plugin not enabled | Enable in Community Plugins |\n| Ribbon icon missing | Wrong icon name | Use valid Lucide icon name |\n\n## Examples\n\n### Available Icon Names\nObsidian uses Lucide icons. Common examples:\n- `file-text`, `folder`, `search`, `settings`\n- `star`, `heart`, `bookmark`, `tag`\n- `edit`, `trash`, `copy`, `clipboard`\n- `link`, `external-link`, `globe`\n- `dice`, `bot`, `sparkles`, `wand`\n\n### Status Bar Item\n```typescript\n\u002F\u002F Add to onload():\nconst statusBarItem = this.addStatusBarItem();\nstatusBarItem.setText('Plugin Active');\n```\n\n### Register Event Listeners\n```typescript\n\u002F\u002F Listen to file open\nthis.registerEvent(\n  this.app.workspace.on('file-open', (file) => {\n    if (file) {\n      console.log('Opened:', file.path);\n    }\n  })\n);\n```\n\n## Resources\n- [Obsidian Plugin API](https:\u002F\u002Fdocs.obsidian.md\u002FReference\u002FTypeScript+API)\n- [Lucide Icons](https:\u002F\u002Flucide.dev\u002Ficons\u002F)\n- [Obsidian Hub](https:\u002F\u002Fpublish.obsidian.md\u002Fhub\u002F)\n\n## Next Steps\nProceed to `obsidian-local-dev-loop` for hot-reload development workflow.","# Obsidian Hello World\n\n## Overview\nBuild a minimal working Obsidian plugin demonstrating core features: commands, settings, and ribbon icons.\n\n## Prerequisites\n- Completed `obsidian-install-auth` setup\n- Development vault configured\n- Build pipeline working\n\n## Instructions\n\n### Step 1: Create Main Plugin Class\n```typescript\n\u002F\u002F src\u002Fmain.ts\nimport { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';\n\ninterface MyPluginSettings {\n  greeting: string;\n}\n\nconst DEFAULT_SETTINGS: MyPluginSettings = {\n  greeting: 'Hello, Obsidian!'\n}\n\nexport default class MyPlugin extends Plugin {\n  settings: MyPluginSettings;\n\n  async onload() {\n    await this.loadSettings();\n\n    \u002F\u002F Add ribbon icon\n    this.addRibbonIcon('dice', 'Greet Me', (evt: MouseEvent) => {\n      new Notice(this.settings.greeting);\n    });\n\n    \u002F\u002F Add command to command palette\n    this.addCommand({\n      id: 'show-greeting',\n      name: 'Show Greeting',\n      callback: () => {\n        new Notice(this.settings.greeting);\n      }\n    });\n\n    \u002F\u002F Add command with editor context\n    this.addCommand({\n      id: 'insert-greeting',\n      name: 'Insert Greeting at Cursor',\n      editorCallback: (editor: Editor, view: MarkdownView) => {\n        editor.replaceSelection(this.settings.greeting);\n      }\n    });\n\n    \u002F\u002F Add settings tab\n    this.addSettingTab(new MySettingTab(this.app, this));\n  }\n\n  onunload() {\n    console.log('Goodbye from My Plugin!');\n  }\n\n  async loadSettings() {\n    this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());\n  }\n\n  async saveSettings() {\n    await this.saveData(this.settings);\n  }\n}\n```\n\n### Step 2: Create Settings Tab\n```typescript\n\u002F\u002F Add to src\u002Fmain.ts\nclass MySettingTab extends PluginSettingTab {\n  plugin: MyPlugin;\n\n  constructor(app: App, plugin: MyPlugin) {\n    super(app, plugin);\n    this.plugin = plugin;\n  }\n\n  display(): void {\n    const { containerEl } = this;\n    containerEl.empty();\n\n    containerEl.createEl('h2', { text: 'My Plugin Settings' });\n\n    new Setting(containerEl)\n      .setName('Greeting')\n      .setDesc('The message to display when greeting')\n      .addText(text => text\n        .setPlaceholder('Enter your greeting')\n        .setValue(this.plugin.settings.greeting)\n        .onChange(async (value) => {\n          this.plugin.settings.greeting = value;\n          await this.plugin.saveSettings();\n        }));\n  }\n}\n```\n\n### Step 3: Create a Modal\n```typescript\n\u002F\u002F Add to src\u002Fmain.ts\nclass GreetingModal extends Modal {\n  greeting: string;\n\n  constructor(app: App, greeting: string) {\n    super(app);\n    this.greeting = greeting;\n  }\n\n  onOpen() {\n    const { contentEl } = this;\n    contentEl.createEl('h1', { text: this.greeting });\n    contentEl.createEl('p', { text: 'Click outside or press Escape to close.' });\n  }\n\n  onClose() {\n    const { contentEl } = this;\n    contentEl.empty();\n  }\n}\n\n\u002F\u002F Add to onload():\nthis.addCommand({\n  id: 'show-greeting-modal',\n  name: 'Show Greeting Modal',\n  callback: () => {\n    new GreetingModal(this.app, this.settings.greeting).open();\n  }\n});\n```\n\n### Step 4: Build and Test\n```bash\nset -euo pipefail\n# Build the plugin\nnpm run build\n\n# In Obsidian:\n# 1. Open Settings > Community plugins\n# 2. Enable \"My Plugin\"\n# 3. Click the dice icon in ribbon\n# 4. Open command palette (Ctrl\u002FCmd+P) and search \"Show Greeting\"\n```\n\n## Output\n- Working plugin with:\n  - Ribbon icon that shows a notice\n  - Commands in command palette\n  - Editor command to insert text\n  - Settings tab to configure greeting\n  - Modal for displaying content\n\n## Error Handling\n| Error | Cause | Solution |\n|-------|-------|----------|\n| Plugin not loading | Build errors | Check console for TypeScript errors |\n| Settings not saving | Missing loadData\u002FsaveData | Verify async\u002Fawait usage |\n| Command not showing | Plugin not enabled | Enable in Community Plugins |\n| Ribbon icon missing | Wrong icon name | Use valid Lucide icon name |\n\n## Examples\n\n### Available Icon Names\nObsidian uses Lucide icons. Common examples:\n- `file-text`, `folder`, `search`, `settings`\n- `star`, `heart`, `bookmark`, `tag`\n- `edit`, `trash`, `copy`, `clipboard`\n- `link`, `external-link`, `globe`\n- `dice`, `bot`, `sparkles`, `wand`\n\n### Status Bar Item\n```typescript\n\u002F\u002F Add to onload():\nconst statusBarItem = this.addStatusBarItem();\nstatusBarItem.setText('Plugin Active');\n```\n\n### Register Event Listeners\n```typescript\n\u002F\u002F Listen to file open\nthis.registerEvent(\n  this.app.workspace.on('file-open', (file) => {\n    if (file) {\n      console.log('Opened:', file.path);\n    }\n  })\n);\n```\n\n## Resources\n- [Obsidian Plugin API](https:\u002F\u002Fdocs.obsidian.md\u002FReference\u002FTypeScript+API)\n- [Lucide Icons](https:\u002F\u002Flucide.dev\u002Ficons\u002F)\n- [Obsidian Hub](https:\u002F\u002Fpublish.obsidian.md\u002Fhub\u002F)\n\n## Next Steps\nProceed to `obsidian-local-dev-loop` for hot-reload development workflow.",{"name":5,"author":24,"license":15,"version":25,"description":26,"allowed-tools":27,"compatible-with":28},"Jeremy Longshore \u003Cjeremy@intentsolutions.io>","1.0.0","Create a minimal working Obsidian plugin with commands and settings.\nUse when building your first plugin feature, testing your setup,\nor learning basic Obsidian plugin patterns.\nTrigger with phrases like \"obsidian hello world\", \"first obsidian plugin\",\n\"obsidian quick start\", \"simple obsidian plugin\".\n","Read, Write, Edit","claude-code, codex, openclaw","main","c2b1fdccc779e99ac814e55fb69ca8d71215dd0f","https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection","https:\u002F\u002Fgithub.com\u002FSamuelChien","http:\u002F\u002Fsamuelchien.com\u002F","2026-05-26 08:27:14",{"source":8,"skillName":5,"commands":36,"prompt":46,"zipAvailable":47},[37,40,43],{"tool":38,"command":39},"npx","npx skills add SamuelChien\u002Fmega-skills-collection --skill obsidian-hello-world",{"tool":41,"command":42},"bunx","bunx skills add SamuelChien\u002Fmega-skills-collection --skill obsidian-hello-world",{"tool":44,"command":45},"pnpm","pnpm dlx skills add SamuelChien\u002Fmega-skills-collection --skill obsidian-hello-world","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection\u002Fblob\u002Fmain\u002Fobsidian-hello-world\u002FSKILL.md",true,[],[50,57,64,71,78,86],{"skillNo":51,"name":52,"nameZh":6,"description":53,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":54,"categories":55,"keywords":56,"publishedAt":19},"01M76R4WZQZAXGGXMQCA0FZ716","zustand-store-ts","Create Zustand stores with TypeScript, subscribeWithSelector middleware, and proper state\u002Faction separation. Use when building React state management, creating global stores, or implementing reactive state patterns with Zustand.","https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection\u002Fblob\u002Fmain\u002Fzustand-store-ts\u002FSKILL.md",[],[],{"skillNo":58,"name":59,"nameZh":6,"description":60,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":61,"categories":62,"keywords":63,"publishedAt":19},"01M76R4T9KENDH7FENGZQHBW4G","zustand-store-creator","Zustand Store Creator - Auto-activating skill for Frontend Development.\nTriggers on: zustand store creator, zustand store creator\nPart of the Frontend Development skill category.","https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection\u002Fblob\u002Fmain\u002Fzustand-store-creator\u002FSKILL.md",[],[],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":19},"01M76R3YWN84B7SANJ52X799ZE","zero-trust-config-helper","Zero Trust Config Helper - Auto-activating skill for Security Advanced.\nTriggers on: zero trust config helper, zero trust config helper\nPart of the Security Advanced skill category.","https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection\u002Fblob\u002Fmain\u002Fzero-trust-config-helper\u002FSKILL.md",[],[],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M76R3HNSV2AEYSKHM915GJ58","zapier-integration-helper","Zapier Integration Helper - Auto-activating skill for Business Automation.\nTriggers on: zapier integration helper, zapier integration helper\nPart of the Business Automation skill category.","https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection\u002Fblob\u002Fmain\u002Fzapier-integration-helper\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":82,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":85,"publishedAt":19},"01M76R3DJSKAT4FA7DV4BF3GCE","zai-cli","Execute z.AI CLI providing vision, search, reader, and GitHub exploration via CLI and MCP.\nUse when user needs image\u002Fvideo analysis, OCR, UI-to-code conversion, error diagnosis,\nreal-time web search, web page to markdown extraction, or GitHub code exploration.\nTrigger with phrases like \"analyze this image\", \"search the web for\", \"read this page\",\n\"explore this repo\", or \"use zai\". Requires Z_AI_API_KEY.","Apache-2.0","https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection\u002Fblob\u002Fmain\u002Fzai-cli\u002FSKILL.md",[],[],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":92,"publishedAt":19},"01M76R2KAM699XE9AJVAWE4H2E","yt-research","Research competitor YouTube channels, niches, and trending topics for your content strategy.\nUse this skill whenever the user says \"research channels\", \"analyze competitors\", \"find trending topics\",\n\"niche analysis\", \"competitive research\", \"what are other creators doing\", \"scrape YouTube channels\",\nor wants to understand the competitive landscape for a specific tool or topic area. Use when working with yt research. Trigger with 'yt', 'research'.","https:\u002F\u002Fgithub.com\u002FSamuelChien\u002Fmega-skills-collection\u002Fblob\u002Fmain\u002Fyt-research\u002FSKILL.md",[],[]]