@xiaotianxt/skills 0.1.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.
Files changed (120) hide show
  1. package/EXCLUDED.md +42 -0
  2. package/LICENSE +21 -0
  3. package/README.md +165 -0
  4. package/SECURITY.md +23 -0
  5. package/SOURCES.md +45 -0
  6. package/bin/skills.mjs +241 -0
  7. package/package.json +38 -0
  8. package/skills/1password/SKILL.md +94 -0
  9. package/skills/1password/agents/openai.yaml +4 -0
  10. package/skills/1password/references/item-management.md +80 -0
  11. package/skills/1password/references/op-cli.md +107 -0
  12. package/skills/apple-calendar-event/SKILL.md +81 -0
  13. package/skills/apple-calendar-event/agents/openai.yaml +4 -0
  14. package/skills/apple-calendar-event/scripts/calendar_audit.py +201 -0
  15. package/skills/apple-calendar-event/scripts/calendar_event.py +164 -0
  16. package/skills/bro-browser/SKILL.md +118 -0
  17. package/skills/bro-browser/agents/openai.yaml +4 -0
  18. package/skills/bro-browser/references/tool-map.md +102 -0
  19. package/skills/bro-browser/references/workflows.md +146 -0
  20. package/skills/bro-browser/scripts/bro-call.mjs +189 -0
  21. package/skills/calendar/SKILL.md +182 -0
  22. package/skills/calendar/agents/openai.yaml +4 -0
  23. package/skills/calendar/references/operations.md +255 -0
  24. package/skills/calendar/scripts/calendar_list_review.py +157 -0
  25. package/skills/calendar/scripts/event_dedupe_preview.py +155 -0
  26. package/skills/canvas/SKILL.md +70 -0
  27. package/skills/canvas/agents/openai.yaml +4 -0
  28. package/skills/canvas/references/canvas-api.md +76 -0
  29. package/skills/course-exam-review-planner/SKILL.md +127 -0
  30. package/skills/cx/SKILL.md +25 -0
  31. package/skills/gh-fix-ci/LICENSE.txt +201 -0
  32. package/skills/gh-fix-ci/SKILL.md +81 -0
  33. package/skills/gh-fix-ci/agents/openai.yaml +6 -0
  34. package/skills/gh-fix-ci/assets/github-small.svg +3 -0
  35. package/skills/gh-fix-ci/assets/github.png +0 -0
  36. package/skills/gh-fix-ci/scripts/inspect_pr_checks.py +509 -0
  37. package/skills/gh-review-workflow/SKILL.md +61 -0
  38. package/skills/gh-review-workflow/agents/openai.yaml +4 -0
  39. package/skills/gh-review-workflow/references/workflow.md +48 -0
  40. package/skills/gh-review-workflow/scripts/fetch_review_state.py +222 -0
  41. package/skills/gh-review-workflow/scripts/resolve_review_threads.py +83 -0
  42. package/skills/github/SKILL.md +74 -0
  43. package/skills/github/agents/openai.yaml +6 -0
  44. package/skills/github/assets/github-small.svg +3 -0
  45. package/skills/github/assets/github.png +0 -0
  46. package/skills/gws-calendar/SKILL.md +126 -0
  47. package/skills/gws-calendar-agenda/SKILL.md +52 -0
  48. package/skills/gws-calendar-insert/SKILL.md +66 -0
  49. package/skills/gws-docs/SKILL.md +48 -0
  50. package/skills/gws-docs-write/SKILL.md +49 -0
  51. package/skills/gws-drive/SKILL.md +137 -0
  52. package/skills/gws-drive-upload/SKILL.md +52 -0
  53. package/skills/gws-gmail/SKILL.md +62 -0
  54. package/skills/gws-gmail-forward/SKILL.md +55 -0
  55. package/skills/gws-gmail-reply/SKILL.md +58 -0
  56. package/skills/gws-gmail-reply-all/SKILL.md +62 -0
  57. package/skills/gws-gmail-send/SKILL.md +57 -0
  58. package/skills/gws-gmail-triage/SKILL.md +50 -0
  59. package/skills/gws-gmail-watch/SKILL.md +58 -0
  60. package/skills/gws-shared/SKILL.md +27 -0
  61. package/skills/helium-browser-mcp/SKILL.md +137 -0
  62. package/skills/helium-browser-mcp/agents/openai.yaml +4 -0
  63. package/skills/helium-browser-mcp/scripts/obmcp.mjs +92 -0
  64. package/skills/helium-browser-mcp/scripts/openbrowsermcp-stdio-proxy.mjs +170 -0
  65. package/skills/learn/SKILL.md +122 -0
  66. package/skills/learn/agents/openai.yaml +7 -0
  67. package/skills/learn/assets/AGENTS.template.md +33 -0
  68. package/skills/learn/assets/errorlog.template.typ +61 -0
  69. package/skills/learn/assets/reading-sequence.template.md +23 -0
  70. package/skills/learn/assets/source-index.template.md +17 -0
  71. package/skills/learn/assets/tasklog.template.typ +57 -0
  72. package/skills/learn/assets/workbook.template.typ +60 -0
  73. package/skills/learn/references/learning-science.md +103 -0
  74. package/skills/learn/scripts/init_learning_workspace.py +70 -0
  75. package/skills/macos-messages/SKILL.md +258 -0
  76. package/skills/memory/SKILL.md +33 -0
  77. package/skills/memory/codex.md +186 -0
  78. package/skills/memory/opencode.md +164 -0
  79. package/skills/mimestreamctl/SKILL.md +170 -0
  80. package/skills/mimestreamctl/agents/openai.yaml +4 -0
  81. package/skills/mimestreamctl/scripts/mimestreamctl +33 -0
  82. package/skills/mon/SKILL.md +51 -0
  83. package/skills/mon/scripts/mon_spend_review.py +458 -0
  84. package/skills/ocr/SKILL.md +136 -0
  85. package/skills/ocr/agents/openai.yaml +4 -0
  86. package/skills/ocr/references/local-ocr-best-practices.md +297 -0
  87. package/skills/ocr/references/mineru-api.md +159 -0
  88. package/skills/ocr/scripts/ocr-router +22 -0
  89. package/skills/ocr/scripts/ocr_router.py +741 -0
  90. package/skills/panopto-mp4-bulk-download/SKILL.md +57 -0
  91. package/skills/panopto-mp4-bulk-download/agents/openai.yaml +4 -0
  92. package/skills/panopto-mp4-bulk-download/references/url-patterns.md +26 -0
  93. package/skills/panopto-mp4-bulk-download/scripts/panopto_bulk_mp4.sh +213 -0
  94. package/skills/rust-systems-style/SKILL.md +109 -0
  95. package/skills/rust-systems-style/agents/openai.yaml +4 -0
  96. package/skills/rust-systems-style/references/rust-review-checklist.md +77 -0
  97. package/skills/rust-systems-style/references/style-sources.md +68 -0
  98. package/skills/ship-ai-native-cli/SKILL.md +76 -0
  99. package/skills/ship-ai-native-cli/agents/openai.yaml +4 -0
  100. package/skills/ship-ai-native-cli/references/case-notes.md +83 -0
  101. package/skills/ship-ai-native-cli/references/product-method.md +82 -0
  102. package/skills/ship-ai-native-cli/references/release-checklist.md +147 -0
  103. package/skills/ship-ai-native-cli/references/rust-cli-shape.md +111 -0
  104. package/skills/telegram-mtproto-session/SKILL.md +125 -0
  105. package/skills/telegram-mtproto-session/agents/openai.yaml +4 -0
  106. package/skills/telegram-mtproto-session/scripts/telegram_session.py +687 -0
  107. package/skills/tg/SKILL.md +173 -0
  108. package/skills/things3-manager/SKILL.md +116 -0
  109. package/skills/things3-manager/scripts/things +42 -0
  110. package/skills/things3-manager/scripts/things_cli.py +514 -0
  111. package/skills/web-artifacts-builder/LICENSE.txt +202 -0
  112. package/skills/web-artifacts-builder/SKILL.md +74 -0
  113. package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
  114. package/skills/web-artifacts-builder/scripts/init-artifact.sh +379 -0
  115. package/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  116. package/skills/yeet/LICENSE.txt +201 -0
  117. package/skills/yeet/SKILL.md +71 -0
  118. package/skills/yeet/agents/openai.yaml +6 -0
  119. package/skills/yeet/assets/yeet-small.svg +3 -0
  120. package/skills/yeet/assets/yeet.png +0 -0
package/EXCLUDED.md ADDED
@@ -0,0 +1,42 @@
1
+ # Excluded Content
2
+
3
+ The following content was intentionally not published.
4
+
5
+ ## System and Plugin Skills
6
+
7
+ - `~/.codex/skills/.system`
8
+ - `~/.codex/plugins/cache`
9
+
10
+ These are managed by Codex or plugins and should be installed from their upstream
11
+ sources instead of being re-published here.
12
+
13
+ ## Third-Party Installed Skills
14
+
15
+ The following installed skills were not vendored because they are third-party or
16
+ upstream-owned:
17
+
18
+ - `~/.agents/skills/agent-browser`
19
+ - `~/.agents/skills/find-skills`
20
+ - `~/.agents/skills/frontend-design`
21
+ - `~/.agents/skills/teach-impeccable`
22
+ - `~/.agents/skills/vercel-cli`
23
+ - `~/Develop.localized/agent-browser/skills/*`
24
+
25
+ ## Local Project Data
26
+
27
+ Only skill instructions were extracted from local project repos. The following
28
+ classes of files were excluded:
29
+
30
+ - `.git/`
31
+ - `target/`
32
+ - `decrypted/`
33
+ - `exported/`
34
+ - `all_keys.json`
35
+ - local auth files
36
+ - local session files
37
+ - local databases
38
+ - build artifacts
39
+ - editor and OS metadata
40
+
41
+ In particular, the full `~/dev/tg` tree was not copied because it contained
42
+ local decrypted databases and key material.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 xiaotianxt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # skills
2
+
3
+ Personal Codex and agent skills, collected into one public, source-controlled repo.
4
+
5
+ ## Layout
6
+
7
+ Each skill lives at:
8
+
9
+ ```text
10
+ skills/<skill-name>/SKILL.md
11
+ ```
12
+
13
+ Optional bundled resources live next to `SKILL.md`, for example `scripts/`,
14
+ `references/`, `assets/`, or `agents/openai.yaml`.
15
+
16
+ ## Install One Skill
17
+
18
+ Install exactly the skill you need. The installer intentionally has no
19
+ "install every skill" mode.
20
+
21
+ Before the npm package is published, install from GitHub:
22
+
23
+ ```bash
24
+ npx -y github:xiaotianxt/skills bro-browser
25
+ ```
26
+
27
+ After publishing to npm:
28
+
29
+ ```bash
30
+ npx -y @xiaotianxt/skills bro-browser
31
+ ```
32
+
33
+ Per-project examples:
34
+
35
+ ```bash
36
+ npx -y @xiaotianxt/skills bro-browser
37
+ npx -y @xiaotianxt/skills tg
38
+ npx -y @xiaotianxt/skills cx
39
+ npx -y @xiaotianxt/skills mon
40
+ ```
41
+
42
+ For `tg`, prefer the project binary when it is installed:
43
+
44
+ ```bash
45
+ tg skill install
46
+ ```
47
+
48
+ That command renders the local machine-specific skill from tg's dictionary.
49
+ The NPX command installs the public Telegram-worded central skill template.
50
+
51
+ The default target is Codex: `~/.codex/skills/<skill-name>`. Other targets:
52
+
53
+ ```bash
54
+ npx -y @xiaotianxt/skills bro-browser --target agents
55
+ npx -y @xiaotianxt/skills bro-browser --target claude
56
+ npx -y @xiaotianxt/skills bro-browser --dir ~/.codex/skills
57
+ ```
58
+
59
+ List available packaged skills:
60
+
61
+ ```bash
62
+ npx -y @xiaotianxt/skills list
63
+ ```
64
+
65
+ Restart the target agent after installing or updating a skill.
66
+
67
+ The older Codex skill installer still works when you want to install directly
68
+ from this GitHub repo:
69
+
70
+ ```bash
71
+ python3 ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \
72
+ --repo xiaotianxt/skills \
73
+ --path skills/<skill-name>
74
+ ```
75
+
76
+ ## Development Model
77
+
78
+ For this machine, `~/dev/skills` is the canonical source tree for user-owned
79
+ skills. Treat `~/.codex/skills` and `~/.agents/skills` as runtime install views,
80
+ not as the place to author durable skill changes.
81
+
82
+ When creating or updating a user-owned skill:
83
+
84
+ 1. Edit `~/dev/skills/skills/<skill-name>/...`.
85
+ 2. Commit the change in this repo.
86
+ 3. Link the installed runtime copy back to this checkout.
87
+ 4. Restart Codex or the target agent when a refreshed skill must be loaded.
88
+
89
+ This keeps skill history reviewable, avoids editing generated or installed
90
+ copies directly, and makes local improvements publishable.
91
+
92
+ ## Runtime Links
93
+
94
+ Create or refresh the runtime symlinks with:
95
+
96
+ ```bash
97
+ git clone https://github.com/xiaotianxt/skills.git ~/dev/skills
98
+ ~/dev/skills/scripts/link-local-skills.sh
99
+ ```
100
+
101
+ This maps selected `~/.codex/skills/*` and `~/.agents/skills/*` entries to
102
+ `~/dev/skills/skills/*`. Existing installed directories are backed up before
103
+ being replaced by symlinks.
104
+
105
+ To update installed skills later:
106
+
107
+ ```bash
108
+ git -C ~/dev/skills pull --ff-only
109
+ ~/dev/skills/scripts/link-local-skills.sh
110
+ ```
111
+
112
+ To mirror canonical skill docs into local open source project repos:
113
+
114
+ ```bash
115
+ ~/dev/skills/scripts/sync-project-skills.sh
116
+ ```
117
+
118
+ That script copies:
119
+
120
+ - `~/dev/skills/skills/cx/SKILL.md` -> `~/dev/cx/SKILL.md`
121
+ - `~/dev/skills/skills/tg/SKILL.md` -> `~/dev/tg/SKILL.md`
122
+ - `~/dev/skills/skills/mimestreamctl` -> `~/dev/mimestreamctl/skills/mimestreamctl`
123
+
124
+ Project repos keep real mirrored files rather than symlinks so GitHub can render
125
+ the skill docs normally. Check drift without writing:
126
+
127
+ ```bash
128
+ ~/dev/skills/scripts/sync-project-skills.sh --check
129
+ ```
130
+
131
+ ## Included Skills
132
+
133
+ This repo includes user-owned local skills from `~/.codex/skills`, selected
134
+ generated Google Workspace `gws-*` skills, and lightweight skill wrappers from
135
+ local `~/dev` tools.
136
+
137
+ Notable curation choices:
138
+
139
+ - System skills from `~/.codex/skills/.system` are not re-published here.
140
+ - Third-party installed skills are not vendored here unless they are user-owned.
141
+ - Large local project directories are not copied. For `~/dev/mon`, `~/dev/cx`,
142
+ and `~/dev/tg`, only the skill instructions are included.
143
+ - The public `tg` skill keeps the Telegram-facing wording used by the open
144
+ source tool documentation.
145
+
146
+ See [SOURCES.md](SOURCES.md) for source mapping and [EXCLUDED.md](EXCLUDED.md)
147
+ for what was intentionally left out.
148
+
149
+ ## Skill Evolution
150
+
151
+ Skills are maintained as operational memory, not as project notebooks. After
152
+ real use, promote only durable lessons that improve future triggering,
153
+ workflow, safety, validation, or semantic clarity.
154
+
155
+ See [docs/skill-evolution.md](docs/skill-evolution.md) for the short-term,
156
+ long-term, and far-term maintenance model.
157
+
158
+ See [docs/skill-portfolio-governance.md](docs/skill-portfolio-governance.md)
159
+ for skill roles, boundary rules, and the current portfolio map.
160
+
161
+ ## Safety
162
+
163
+ Before publication this repo was assembled from a clean copy and scanned for
164
+ credentials, local databases, decrypted chat data, generated build output, and
165
+ Git internals. See [SECURITY.md](SECURITY.md) for the policy used here.
package/SECURITY.md ADDED
@@ -0,0 +1,23 @@
1
+ # Security
2
+
3
+ This repository is intended to contain public skill instructions only.
4
+
5
+ Do not commit:
6
+
7
+ - API keys, OAuth tokens, cookies, session files, or password files
8
+ - `auth.json`, `env.conf`, `.env`, `session.json`, or equivalent credential state
9
+ - local email, chat, calendar, document, or finance data
10
+ - decrypted databases, exported chats, media caches, or generated reports
11
+ - build output such as `target/`, `dist/`, or local binaries
12
+ - `.git/`, `.DS_Store`, or tool cache directories
13
+
14
+ Before publishing updates, run a secret scan similar to:
15
+
16
+ ```bash
17
+ rg -n --hidden -i \
18
+ "(api[_-]?key|token|secret|password|credential|authorization|bearer|github_pat|ghp_|gho_|sk-[A-Za-z0-9]|AKIA|AIza|BEGIN [A-Z ]*PRIVATE KEY|auth\\.json|session\\.json|all_keys|decrypted/)" \
19
+ .
20
+ ```
21
+
22
+ Treat matches as blockers unless they are clearly documentation examples or code
23
+ that handles secret values without embedding real values.
package/SOURCES.md ADDED
@@ -0,0 +1,45 @@
1
+ # Sources
2
+
3
+ ## Included
4
+
5
+ | Skill | Source |
6
+ | --- | --- |
7
+ | `1password` | Created in this repo as scoped 1Password import/fallback guidance |
8
+ | `apple-calendar-event` | `~/.codex/skills/apple-calendar-event` |
9
+ | `bro-browser` | Created in this repo for the local bro browser MCP workflow |
10
+ | `calendar` | Created in this repo as personal calendar governance guidance |
11
+ | `canvas` | Created in this repo as the local source of truth |
12
+ | `course-exam-review-planner` | `~/.codex/skills/course-exam-review-planner` |
13
+ | `cx` | `~/dev/cx/SKILL.md` |
14
+ | `gh-fix-ci` | Created in this repo as GitHub Actions PR check workflow guidance |
15
+ | `gh-review-workflow` | `~/.codex/skills/gh-review-workflow` |
16
+ | `github` | Created in this repo as GitHub triage and routing guidance |
17
+ | `gws-*` | `~/.agents/skills/gws-*` |
18
+ | `gws-shared` | Added to make generated `gws-*` skills self-contained |
19
+ | `helium-browser-mcp` | Created in this repo from the local Helium/OpenBrowserMCP workflow |
20
+ | `macos-messages` | Created in this repo as local Messages history guidance |
21
+ | `memory` | Created in this repo as local agent history search guidance |
22
+ | `mimestreamctl` | `~/dev/mimestreamctl/skills/mimestreamctl` |
23
+ | `mon` | `~/dev/mon/SKILL.md` |
24
+ | `panopto-mp4-bulk-download` | `~/.codex/skills/panopto-mp4-bulk-download` |
25
+ | `rust-systems-style` | Created in this repo as the local source of truth |
26
+ | `ship-ai-native-cli` | `~/.codex/skills/ship-ai-native-cli` |
27
+ | `telegram-mtproto-session` | Created in this repo as local Telegram MTProto session guidance |
28
+ | `tg` | `~/dev/tg/SKILL.md` |
29
+ | `things3-manager` | `~/.codex/skills/things3-manager` |
30
+ | `yeet` | Created in this repo as local GitHub publish workflow guidance |
31
+
32
+ ## Normalization
33
+
34
+ - `mon` and `cx` were given standard YAML frontmatter.
35
+ - The public `tg` skill preserves Telegram-facing wording.
36
+ - `agent-browser-hints` was retired in favor of the narrower
37
+ `helium-browser-mcp` skill.
38
+ - Backup files, `.DS_Store`, `.git`, build output, local databases, local keys,
39
+ and generated cache data were excluded.
40
+
41
+ ## Local Linking
42
+
43
+ Use `scripts/link-local-skills.sh` to map installed local skills to this repo.
44
+ Use `scripts/sync-project-skills.sh` to mirror canonical skill docs into local
45
+ project repos while keeping those repos readable on GitHub.
package/bin/skills.mjs ADDED
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs'
3
+ import os from 'node:os'
4
+ import path from 'node:path'
5
+ import process from 'node:process'
6
+ import { fileURLToPath } from 'node:url'
7
+
8
+ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
9
+ const SKILLS_DIR = path.join(ROOT, 'skills')
10
+ const TARGETS = {
11
+ codex: path.join(os.homedir(), '.codex', 'skills'),
12
+ agents: path.join(os.homedir(), '.agents', 'skills'),
13
+ claude: path.join(os.homedir(), '.claude', 'skills'),
14
+ }
15
+
16
+ function main(argv) {
17
+ const [command, ...rest] = argv
18
+ switch (command) {
19
+ case undefined:
20
+ case '-h':
21
+ case '--help':
22
+ case 'help':
23
+ printHelp()
24
+ return
25
+ case 'list':
26
+ listSkills()
27
+ return
28
+ case 'install':
29
+ case 'add':
30
+ install(rest)
31
+ return
32
+ default:
33
+ install(argv)
34
+ }
35
+ }
36
+
37
+ function printHelp() {
38
+ console.log(`xiaotianxt-skills
39
+
40
+ Usage:
41
+ npx @xiaotianxt/skills list
42
+ npx @xiaotianxt/skills bro-browser
43
+ npx @xiaotianxt/skills tg --target agents
44
+ npx @xiaotianxt/skills install cx --target codex
45
+
46
+ Options:
47
+ --target <codex|agents|claude> Install target. Default: codex.
48
+ --dir <path> Override install directory.
49
+ --dry-run Print actions without writing.
50
+ --force Replace existing skill without backup.
51
+
52
+ Installs exactly one named skill. There is intentionally no "install all" mode.
53
+ `)
54
+ }
55
+
56
+ function listSkills() {
57
+ for (const skill of availableSkills()) {
58
+ console.log(skill)
59
+ }
60
+ }
61
+
62
+ function install(args) {
63
+ const options = parseInstallArgs(args)
64
+ if (options.skills.length === 0) {
65
+ fail('install requires exactly one skill name')
66
+ }
67
+ if (options.skills.length > 1) {
68
+ fail('install accepts one skill name; run separate commands for separate skills')
69
+ }
70
+
71
+ const targets = resolveTargets(options)
72
+ for (const skill of options.skills) {
73
+ assertSkillExists(skill)
74
+ }
75
+
76
+ for (const target of targets) {
77
+ for (const skill of options.skills) {
78
+ installSkill(skill, target, options)
79
+ }
80
+ }
81
+ }
82
+
83
+ function parseInstallArgs(args) {
84
+ const options = {
85
+ dryRun: false,
86
+ force: false,
87
+ target: 'codex',
88
+ dir: undefined,
89
+ skills: [],
90
+ }
91
+
92
+ for (let i = 0; i < args.length; i += 1) {
93
+ const arg = args[i]
94
+ if (arg === '--dry-run') {
95
+ options.dryRun = true
96
+ } else if (arg === '--force') {
97
+ options.force = true
98
+ } else if (arg === '--target') {
99
+ options.target = requireValue(args, ++i, '--target')
100
+ } else if (arg.startsWith('--target=')) {
101
+ options.target = arg.slice('--target='.length)
102
+ } else if (arg === '--dir') {
103
+ options.dir = requireValue(args, ++i, '--dir')
104
+ } else if (arg.startsWith('--dir=')) {
105
+ options.dir = arg.slice('--dir='.length)
106
+ } else if (arg.startsWith('-')) {
107
+ fail(`unknown option: ${arg}`)
108
+ } else {
109
+ options.skills.push(arg)
110
+ }
111
+ }
112
+
113
+ return options
114
+ }
115
+
116
+ function requireValue(args, index, option) {
117
+ const value = args[index]
118
+ if (!value || value.startsWith('-')) {
119
+ fail(`${option} requires a value`)
120
+ }
121
+ return value
122
+ }
123
+
124
+ function resolveTargets(options) {
125
+ if (options.dir) {
126
+ return [path.resolve(expandHome(options.dir))]
127
+ }
128
+ const target = TARGETS[options.target]
129
+ if (!target) {
130
+ fail('--target must be codex, agents, or claude')
131
+ }
132
+ return [target]
133
+ }
134
+
135
+ function availableSkills() {
136
+ return fs
137
+ .readdirSync(SKILLS_DIR, { withFileTypes: true })
138
+ .filter((entry) => entry.isDirectory())
139
+ .map((entry) => entry.name)
140
+ .filter((name) => fs.existsSync(path.join(SKILLS_DIR, name, 'SKILL.md')))
141
+ .sort()
142
+ }
143
+
144
+ function assertSkillExists(skill) {
145
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(skill)) {
146
+ fail(`invalid skill name: ${skill}`)
147
+ }
148
+ const src = path.join(SKILLS_DIR, skill)
149
+ if (!fs.existsSync(path.join(src, 'SKILL.md'))) {
150
+ fail(`unknown skill: ${skill}`)
151
+ }
152
+ }
153
+
154
+ function installSkill(skill, targetDir, options) {
155
+ const src = path.join(SKILLS_DIR, skill)
156
+ const dest = path.join(targetDir, skill)
157
+
158
+ if (skill === 'tg') {
159
+ console.error(
160
+ 'note: `tg skill install` renders the local machine-specific tg skill; this installer copies the public Telegram-worded template.',
161
+ )
162
+ }
163
+
164
+ if (fs.existsSync(dest) || isSymlink(dest)) {
165
+ const current = describeExisting(dest)
166
+ if (current === src) {
167
+ console.log(`ok ${dest} -> ${src}`)
168
+ return
169
+ }
170
+
171
+ if (options.force) {
172
+ log(options, `remove ${dest}`)
173
+ if (!options.dryRun) fs.rmSync(dest, { recursive: true, force: true })
174
+ } else {
175
+ const backup = backupPath(targetDir, skill)
176
+ log(options, `backup ${dest} -> ${backup}`)
177
+ if (!options.dryRun) {
178
+ fs.mkdirSync(path.dirname(backup), { recursive: true })
179
+ fs.renameSync(dest, backup)
180
+ }
181
+ }
182
+ }
183
+
184
+ log(options, `copy ${dest} <- ${src}`)
185
+ if (options.dryRun) return
186
+ fs.mkdirSync(targetDir, { recursive: true })
187
+ fs.cpSync(src, dest, {
188
+ recursive: true,
189
+ filter: (source) => !shouldSkip(path.basename(source)),
190
+ })
191
+ }
192
+
193
+ function describeExisting(dest) {
194
+ try {
195
+ const stat = fs.lstatSync(dest)
196
+ if (stat.isSymbolicLink()) {
197
+ return path.resolve(path.dirname(dest), fs.readlinkSync(dest))
198
+ }
199
+ return 'directory'
200
+ } catch {
201
+ return undefined
202
+ }
203
+ }
204
+
205
+ function isSymlink(dest) {
206
+ try {
207
+ return fs.lstatSync(dest).isSymbolicLink()
208
+ } catch {
209
+ return false
210
+ }
211
+ }
212
+
213
+ function backupPath(targetDir, skill) {
214
+ const stamp = new Date()
215
+ .toISOString()
216
+ .replaceAll('-', '')
217
+ .replaceAll(':', '')
218
+ .replace(/\..+$/, '')
219
+ return path.join(targetDir, `.skills-backup-${stamp}`, skill)
220
+ }
221
+
222
+ function shouldSkip(name) {
223
+ return name === '.DS_Store' || name === '__pycache__' || name.endsWith('.pyc')
224
+ }
225
+
226
+ function expandHome(value) {
227
+ if (value === '~') return os.homedir()
228
+ if (value.startsWith('~/')) return path.join(os.homedir(), value.slice(2))
229
+ return value
230
+ }
231
+
232
+ function log(options, message) {
233
+ console.log(options.dryRun ? `dry-run ${message}` : message)
234
+ }
235
+
236
+ function fail(message) {
237
+ console.error(`error: ${message}`)
238
+ process.exit(1)
239
+ }
240
+
241
+ main(process.argv.slice(2))
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@xiaotianxt/skills",
3
+ "version": "0.1.0",
4
+ "description": "Install xiaotianxt agent skills for Codex, OpenCode-style agents, and Claude.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/xiaotianxt/skills.git"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "type": "module",
14
+ "bin": {
15
+ "skills": "bin/skills.mjs"
16
+ },
17
+ "scripts": {
18
+ "check:public": "bash scripts/check-public-redactions.sh",
19
+ "prepack": "npm run check:public",
20
+ "prepublishOnly": "npm run check:public && npm run smoke",
21
+ "smoke": "npm run check:public && node bin/skills.mjs list && node bin/skills.mjs bro-browser --dir /tmp/xiaotianxt-skills-smoke --dry-run"
22
+ },
23
+ "files": [
24
+ "bin/",
25
+ "skills/",
26
+ "!skills/**/__pycache__/",
27
+ "!skills/**/*.pyc",
28
+ "!skills/**/.DS_Store",
29
+ "README.md",
30
+ "LICENSE",
31
+ "SECURITY.md",
32
+ "SOURCES.md",
33
+ "EXCLUDED.md"
34
+ ],
35
+ "engines": {
36
+ "node": ">=18"
37
+ }
38
+ }
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: 1password
3
+ description: "Use when Codex needs to work with 1Password or the `op` CLI: reading a specific secret reference, injecting API keys or credentials into local commands, using `op run` or `op inject`, checking 1Password CLI auth state, handling `API_CREDENTIAL` items, creating or updating 1Password items, or deciding how to keep secrets out of code, logs, shell history, issues, PRs, and final responses."
4
+ ---
5
+
6
+ # 1Password
7
+
8
+ Use the local 1Password CLI only for scoped 1Password work. For local machine-only API keys on this Mac, prefer macOS Keychain through `keychain-secret` and use 1Password as an import/fallback source. Keep workflows local and avoid exposing secret values to chat, logs, files, source control, or command history.
9
+
10
+ ## Default Rules
11
+
12
+ - Use only the specific credential needed for the current task.
13
+ - Prefer `keychain-secret get <service> <account>` for local API-key reads after a secret has been migrated to Keychain.
14
+ - Prefer `keychain-secret import-op <service> <account> <op-ref>` for one-time migration from a known 1Password reference.
15
+ - Prefer a user-provided `op://...` secret reference over searching vaults.
16
+ - Do not enumerate vaults, accounts, or items unless the user asks or the reference is ambiguous.
17
+ - Do not print, summarize, quote, or reveal secret values in chat or final responses.
18
+ - Do not paste plaintext secrets into source files, `.env` files, logs, issues, PRs, commit messages, or shell history.
19
+ - Prefer `op run` only for workflows that cannot use Keychain yet and accept environment variables.
20
+ - Prefer templates with secret references plus `op inject` only when a real config file is required and Keychain is unsuitable; delete resolved files when no longer needed.
21
+ - Avoid `op run --no-masking` and `op item get --reveal` unless the user explicitly asks to display a secret.
22
+ - Treat service account tokens, exported `.env` files, one-time passwords, private keys, cookies, and raw item JSON as sensitive.
23
+
24
+ ## Local Setup
25
+
26
+ - Verify availability with `op --version`.
27
+ - When a command needs to read secrets through the 1Password desktop app integration, request `sandbox_permissions="require_escalated"` by default. The workspace sandbox can block the local app socket and produce misleading errors such as "couldn't connect to the 1Password desktop app" even when 1Password is installed and working.
28
+ - If `op read`, `op run`, or `op signin` fails with a desktop app connection error inside the sandbox, rerun the exact scoped command outside the sandbox with a concise approval request before asking the user to restart 1Password.
29
+ - If auth is missing, use `op signin` and expect the user to approve in 1Password.
30
+ - If multiple accounts are configured, use `--account` or `OP_ACCOUNT` only after identifying the intended account.
31
+ - Do not require `tmux`; this machine may not have it. Use normal serialized shell commands unless an interactive TTY is genuinely needed.
32
+
33
+ ## Common Workflows
34
+
35
+ ### Inject A Secret Into A Command
36
+
37
+ For local API keys, prefer Keychain:
38
+
39
+ ```bash
40
+ API_KEY="$(keychain-secret get codex.service credential)" my-command
41
+ ```
42
+
43
+ When the secret exists only in 1Password, ask for the secret reference, then run the target command without exposing the value:
44
+
45
+ ```bash
46
+ API_KEY='op://Private/Service API/credential' op run -- my-command
47
+ ```
48
+
49
+ For project commands, prefer a template env file containing `op://` references:
50
+
51
+ ```bash
52
+ op run --env-file .env.op -- npm run dev
53
+ ```
54
+
55
+ ### Read A Specific Secret
56
+
57
+ Use `op read` only when the secret is not yet migrated to Keychain and must be passed to a local process that cannot consume `op run` references. Do not echo the value back to the user.
58
+
59
+ ```bash
60
+ op read 'op://Private/Service API/credential'
61
+ ```
62
+
63
+ For `API_CREDENTIAL` items in this setup, the preferred field is `credential`:
64
+
65
+ ```bash
66
+ op read 'op://Private/<title-or-id>/credential'
67
+ ```
68
+
69
+ To migrate that item to Keychain:
70
+
71
+ ```bash
72
+ keychain-secret import-op codex.service credential 'op://Private/<title-or-id>/credential'
73
+ ```
74
+
75
+ ### Create Or Update 1Password Items
76
+
77
+ Do not ask the user to paste secret values into chat. If CLI item creation is required, avoid command-line assignment statements for sensitive values because command arguments can be logged or visible to local processes.
78
+
79
+ Use the 1Password app when practical. If CLI is necessary, use a short-lived local JSON template or stdin flow, set restrictive file permissions, and delete any plaintext temporary file immediately after use.
80
+
81
+ ## When To Load References
82
+
83
+ - Read `references/op-cli.md` for concrete `op read`, `op run`, `op inject`, auth, and account-selection patterns.
84
+ - Read `references/item-management.md` before creating, editing, copying, or exporting 1Password items.
85
+
86
+ ## Stop Conditions
87
+
88
+ Stop and ask the user before:
89
+
90
+ - Listing vaults/items/accounts to discover a credential.
91
+ - Exporting secrets to disk, even temporarily.
92
+ - Creating service accounts, Connect tokens, Kubernetes secrets, or CI secrets.
93
+ - Changing global shell, git, gh, or 1Password plugin configuration.
94
+ - Running any command likely to display secret values.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "1Password"
3
+ short_description: "Use 1Password CLI without leaking secrets"
4
+ default_prompt: "Use $1password to inject an API key from a 1Password secret reference into this local command."