@open-mercato/cli 0.6.6-develop.6483.1.b623f50e2b → 0.6.6-develop.6485.1.6021282db1

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 (86) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/dist/agentic/guides/module-facts.json +53 -53
  3. package/dist/agentic/guides/modules/ai_assistant.md +1 -1
  4. package/dist/agentic/guides/modules/api_docs.md +1 -1
  5. package/dist/agentic/guides/modules/api_keys.md +1 -1
  6. package/dist/agentic/guides/modules/attachments.md +1 -1
  7. package/dist/agentic/guides/modules/audit_logs.md +1 -1
  8. package/dist/agentic/guides/modules/auth.md +1 -1
  9. package/dist/agentic/guides/modules/business_rules.md +1 -1
  10. package/dist/agentic/guides/modules/catalog.md +1 -1
  11. package/dist/agentic/guides/modules/channel_gmail.md +1 -1
  12. package/dist/agentic/guides/modules/channel_imap.md +1 -1
  13. package/dist/agentic/guides/modules/checkout.md +1 -1
  14. package/dist/agentic/guides/modules/communication_channels.md +1 -1
  15. package/dist/agentic/guides/modules/configs.md +1 -1
  16. package/dist/agentic/guides/modules/content.md +1 -1
  17. package/dist/agentic/guides/modules/currencies.md +1 -1
  18. package/dist/agentic/guides/modules/customer_accounts.md +1 -1
  19. package/dist/agentic/guides/modules/customers.md +1 -1
  20. package/dist/agentic/guides/modules/dashboards.md +1 -1
  21. package/dist/agentic/guides/modules/data_sync.md +1 -1
  22. package/dist/agentic/guides/modules/dictionaries.md +1 -1
  23. package/dist/agentic/guides/modules/directory.md +1 -1
  24. package/dist/agentic/guides/modules/entities.md +1 -1
  25. package/dist/agentic/guides/modules/events.md +1 -1
  26. package/dist/agentic/guides/modules/feature_toggles.md +1 -1
  27. package/dist/agentic/guides/modules/gateway_stripe.md +1 -1
  28. package/dist/agentic/guides/modules/generators.md +1 -1
  29. package/dist/agentic/guides/modules/inbox_ops.md +1 -1
  30. package/dist/agentic/guides/modules/integrations.md +1 -1
  31. package/dist/agentic/guides/modules/messages.md +1 -1
  32. package/dist/agentic/guides/modules/notifications.md +1 -1
  33. package/dist/agentic/guides/modules/onboarding.md +1 -1
  34. package/dist/agentic/guides/modules/payment_gateways.md +1 -1
  35. package/dist/agentic/guides/modules/perspectives.md +1 -1
  36. package/dist/agentic/guides/modules/planner.md +1 -1
  37. package/dist/agentic/guides/modules/portal.md +1 -1
  38. package/dist/agentic/guides/modules/progress.md +1 -1
  39. package/dist/agentic/guides/modules/query_index.md +1 -1
  40. package/dist/agentic/guides/modules/record_locks.md +1 -1
  41. package/dist/agentic/guides/modules/resources.md +1 -1
  42. package/dist/agentic/guides/modules/sales.md +1 -1
  43. package/dist/agentic/guides/modules/scheduler.md +1 -1
  44. package/dist/agentic/guides/modules/search.md +1 -1
  45. package/dist/agentic/guides/modules/security.md +1 -1
  46. package/dist/agentic/guides/modules/shipping_carriers.md +1 -1
  47. package/dist/agentic/guides/modules/sso.md +1 -1
  48. package/dist/agentic/guides/modules/staff.md +1 -1
  49. package/dist/agentic/guides/modules/storage_s3.md +1 -1
  50. package/dist/agentic/guides/modules/sync_akeneo.md +1 -1
  51. package/dist/agentic/guides/modules/sync_excel.md +1 -1
  52. package/dist/agentic/guides/modules/system_status_overlays.md +1 -1
  53. package/dist/agentic/guides/modules/translations.md +1 -1
  54. package/dist/agentic/guides/modules/webhooks.md +1 -1
  55. package/dist/agentic/guides/modules/workflows.md +1 -1
  56. package/dist/agentic/shared/AGENTS.md.template +16 -10
  57. package/dist/agentic/shared/ai/agentic.config.json +61 -0
  58. package/dist/agentic/shared/ai/skills/om-auto-continue-pr/SKILL.md +16 -318
  59. package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/SKILL.md +16 -581
  60. package/dist/agentic/shared/ai/skills/om-auto-create-pr/SKILL.md +16 -397
  61. package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/SKILL.md +16 -738
  62. package/dist/agentic/shared/ai/skills/om-auto-fix-issue/SKILL.md +27 -0
  63. package/dist/agentic/shared/ai/skills/om-auto-review-pr/SKILL.md +16 -565
  64. package/dist/agentic/shared/ai/skills/om-help/references/skills-catalog.md +1 -1
  65. package/dist/agentic/shared/ai/skills/tiers.json +47 -0
  66. package/dist/agentic/shared/ai/skills/tiers.schema.json +73 -0
  67. package/dist/agentic/shared/ai/trackers/github.md +376 -0
  68. package/dist/agentic/shared/scripts/install-skills.sh +488 -0
  69. package/dist/lib/agentic-setup.js +9 -40
  70. package/dist/lib/agentic-setup.js.map +2 -2
  71. package/package.json +5 -5
  72. package/src/lib/agentic-setup.ts +19 -42
  73. package/dist/agentic/shared/ai/skills/om-auto-continue-pr/STANDALONE.md +0 -98
  74. package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/STANDALONE.md +0 -96
  75. package/dist/agentic/shared/ai/skills/om-auto-create-pr/STANDALONE.md +0 -98
  76. package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/STANDALONE.md +0 -96
  77. package/dist/agentic/shared/ai/skills/om-auto-fix-github/SKILL.md +0 -419
  78. package/dist/agentic/shared/ai/skills/om-auto-fix-github/STANDALONE.md +0 -98
  79. package/dist/agentic/shared/ai/skills/om-auto-review-pr/STANDALONE.md +0 -98
  80. package/dist/agentic/shared/ai/skills/om-code-review/SKILL.md +0 -108
  81. package/dist/agentic/shared/ai/skills/om-code-review/references/review-checklist.md +0 -83
  82. package/dist/agentic/shared/ai/skills/om-integration-tests/SKILL.md +0 -279
  83. package/dist/agentic/shared/ai/skills/om-prepare-issue/SKILL.md +0 -202
  84. package/dist/agentic/shared/ai/skills/om-spec-writing/SKILL.md +0 -85
  85. package/dist/agentic/shared/ai/skills/om-spec-writing/references/spec-checklist.md +0 -67
  86. package/dist/agentic/shared/ai/skills/om-spec-writing/references/spec-template.md +0 -86
@@ -0,0 +1,488 @@
1
+ #!/bin/sh
2
+ set -eu
3
+
4
+ # Skill installer for a standalone Open Mercato app (Claude Code + Codex).
5
+ # Two sources are mixed in:
6
+ #
7
+ # 1. Local tiered skills: reads .ai/skills/tiers.json and creates per-skill
8
+ # symlinks under .claude/skills/ and .codex/skills/. If a legacy
9
+ # directory-level symlink (e.g. .claude/skills -> ../.ai/skills) is found,
10
+ # it is replaced with a real directory of per-skill symlinks.
11
+ # 2. External shared skills: installs the subset this app ships from the
12
+ # open-mercato/skills collection via `npx skills add` into .agents/skills/
13
+ # (read natively by Codex; the CLI also symlinks .claude/skills/<name>),
14
+ # then `npx skills update` so a re-run refreshes them to the latest
15
+ # published versions. The external source + explicit skill list live under
16
+ # `external` in tiers.json. A folder under .ai/skills/ matching an external
17
+ # skill name is a repo-local override the external skill reads in place; it
18
+ # is never symlinked into the harness directories.
19
+ #
20
+ # The scaffold is offline: `npx skills add`/`update` only run when you invoke
21
+ # this script (yarn install-skills). Pass --no-external (or set
22
+ # OM_SKIP_EXTERNAL_SKILLS=1) to skip the network step entirely.
23
+ #
24
+ # Usage:
25
+ # install-skills.sh # default tier set (core) + install/update external skills
26
+ # install-skills.sh --with <csv> # default + extra tiers (additive)
27
+ # install-skills.sh --tiers <csv> # exactly the listed tiers (replaces default)
28
+ # install-skills.sh --all # every tier
29
+ # install-skills.sh --no-external # skip the npx external-skills install/update step (offline)
30
+ # install-skills.sh --list # print tier table and exit
31
+ # install-skills.sh --clean # remove all skill symlinks and exit
32
+ # install-skills.sh --help | -h # show usage and exit
33
+
34
+ usage() {
35
+ cat <<'EOF'
36
+ Usage: install-skills.sh [options]
37
+
38
+ Options:
39
+ (no options) Install the default tier set from .ai/skills/tiers.json
40
+ plus the external open-mercato/skills subset this app ships.
41
+ --with <csv> Install default tiers plus the given tier names (additive).
42
+ --tiers <csv> Install exactly the given tier names (replaces default).
43
+ --all Install every tier defined in tiers.json.
44
+ --no-external Skip the external-collection step — `npx skills add` on
45
+ first run and `npx skills update` on re-runs (also:
46
+ OM_SKIP_EXTERNAL_SKILLS=1). Use when offline.
47
+ --list Print the tier table and exit without installing.
48
+ --clean Remove all skill symlinks (local and external) and exit.
49
+ --help, -h Show this message.
50
+
51
+ --with, --tiers, and --all are mutually exclusive.
52
+ EOF
53
+ }
54
+
55
+ if ! command -v jq >/dev/null 2>&1; then
56
+ echo "install-skills: jq is required but not installed." >&2
57
+ echo "Install jq (e.g. 'sudo apt-get install jq' or 'brew install jq') and re-run." >&2
58
+ exit 1
59
+ fi
60
+
61
+ # Resolve the app root from this script's own location (scripts/install-skills.sh),
62
+ # falling back to git and finally the current directory. A freshly scaffolded app
63
+ # may not be a git checkout yet, so git is optional here.
64
+ script_path="$0"
65
+ case "${script_path}" in
66
+ /*) : ;;
67
+ *) script_path="$(pwd)/${script_path}" ;;
68
+ esac
69
+ script_dir=$(CDPATH= cd -- "$(dirname -- "${script_path}")" && pwd)
70
+ repo_root=$(CDPATH= cd -- "${script_dir}/.." && pwd)
71
+ if [ ! -f "${repo_root}/.ai/skills/tiers.json" ]; then
72
+ git_root=$(git rev-parse --show-toplevel 2>/dev/null || true)
73
+ if [ -n "${git_root}" ] && [ -f "${git_root}/.ai/skills/tiers.json" ]; then
74
+ repo_root="${git_root}"
75
+ elif [ -f "$(pwd)/.ai/skills/tiers.json" ]; then
76
+ repo_root="$(pwd)"
77
+ fi
78
+ fi
79
+
80
+ manifest="${repo_root}/.ai/skills/tiers.json"
81
+ skills_dir="${repo_root}/.ai/skills"
82
+
83
+ if [ ! -f "${manifest}" ]; then
84
+ echo "install-skills: missing manifest ${manifest}" >&2
85
+ echo " Run this from your app root (yarn install-skills)." >&2
86
+ exit 1
87
+ fi
88
+
89
+ mode=""
90
+ with_csv=""
91
+ tiers_csv=""
92
+ list_only=0
93
+ clean_only=0
94
+ # Any non-empty value other than "0" skips the external npx step.
95
+ case "${OM_SKIP_EXTERNAL_SKILLS:-0}" in
96
+ ""|0) no_external=0 ;;
97
+ *) no_external=1 ;;
98
+ esac
99
+
100
+ set_mode() {
101
+ new_mode="$1"
102
+ if [ -n "${mode}" ] && [ "${mode}" != "${new_mode}" ]; then
103
+ echo "install-skills: --with, --tiers, and --all are mutually exclusive." >&2
104
+ usage >&2
105
+ exit 1
106
+ fi
107
+ mode="${new_mode}"
108
+ }
109
+
110
+ while [ $# -gt 0 ]; do
111
+ case "$1" in
112
+ --help|-h)
113
+ usage
114
+ exit 0
115
+ ;;
116
+ --list)
117
+ list_only=1
118
+ shift
119
+ ;;
120
+ --clean)
121
+ clean_only=1
122
+ shift
123
+ ;;
124
+ --no-external)
125
+ no_external=1
126
+ shift
127
+ ;;
128
+ --all)
129
+ set_mode all
130
+ shift
131
+ ;;
132
+ --with)
133
+ set_mode with
134
+ if [ $# -lt 2 ]; then
135
+ echo "install-skills: --with requires a comma-separated list of tier names." >&2
136
+ exit 1
137
+ fi
138
+ with_csv="$2"
139
+ shift 2
140
+ ;;
141
+ --with=*)
142
+ set_mode with
143
+ with_csv="${1#--with=}"
144
+ shift
145
+ ;;
146
+ --tiers)
147
+ set_mode tiers
148
+ if [ $# -lt 2 ]; then
149
+ echo "install-skills: --tiers requires a comma-separated list of tier names." >&2
150
+ exit 1
151
+ fi
152
+ tiers_csv="$2"
153
+ shift 2
154
+ ;;
155
+ --tiers=*)
156
+ set_mode tiers
157
+ tiers_csv="${1#--tiers=}"
158
+ shift
159
+ ;;
160
+ *)
161
+ echo "install-skills: unknown option '$1'" >&2
162
+ usage >&2
163
+ exit 1
164
+ ;;
165
+ esac
166
+ done
167
+
168
+ split_csv() {
169
+ printf '%s' "$1" | tr ',' '\n' | sed 's/^ *//; s/ *$//' | grep -v '^$' || true
170
+ }
171
+
172
+ all_tier_names=$(jq -r '.tiers | keys[]' "${manifest}")
173
+ default_tier_names=$(jq -r '.default[]' "${manifest}")
174
+
175
+ tier_defined() {
176
+ needle="$1"
177
+ for candidate in ${all_tier_names}; do
178
+ if [ "${candidate}" = "${needle}" ]; then
179
+ return 0
180
+ fi
181
+ done
182
+ return 1
183
+ }
184
+
185
+ tier_skills() {
186
+ jq -r --arg t "$1" '.tiers[$t].skills[]' "${manifest}"
187
+ }
188
+
189
+ tier_skill_count() {
190
+ jq -r --arg t "$1" '.tiers[$t].skills | length' "${manifest}"
191
+ }
192
+
193
+ is_default_tier() {
194
+ needle="$1"
195
+ for candidate in ${default_tier_names}; do
196
+ if [ "${candidate}" = "${needle}" ]; then
197
+ return 0
198
+ fi
199
+ done
200
+ return 1
201
+ }
202
+
203
+ dedup_lines() {
204
+ awk 'NF && !seen[$0]++'
205
+ }
206
+
207
+ agents_dir="${repo_root}/.agents/skills"
208
+
209
+ resolves_into_skills_dir() {
210
+ link_path="$1"
211
+ resolved=$(readlink -f -- "${link_path}" 2>/dev/null || true)
212
+ if [ -z "${resolved}" ]; then
213
+ return 1
214
+ fi
215
+ case "${resolved}" in
216
+ "${skills_dir}"/*)
217
+ return 0
218
+ ;;
219
+ esac
220
+ return 1
221
+ }
222
+
223
+ resolves_into_agents_dir() {
224
+ link_path="$1"
225
+ resolved=$(readlink -f -- "${link_path}" 2>/dev/null || true)
226
+ if [ -z "${resolved}" ]; then
227
+ return 1
228
+ fi
229
+ case "${resolved}" in
230
+ "${agents_dir}"/*)
231
+ return 0
232
+ ;;
233
+ esac
234
+ return 1
235
+ }
236
+
237
+ clean_harness() {
238
+ harness_dir="$1"
239
+ if [ ! -d "${harness_dir}" ] && [ ! -L "${harness_dir}" ]; then
240
+ return 0
241
+ fi
242
+ if [ -L "${harness_dir}" ]; then
243
+ rm -f "${harness_dir}"
244
+ return 0
245
+ fi
246
+ for entry in "${harness_dir}"/* "${harness_dir}"/.[!.]* "${harness_dir}"/..?*; do
247
+ [ -e "${entry}" ] || [ -L "${entry}" ] || continue
248
+ if [ -L "${entry}" ] && { resolves_into_skills_dir "${entry}" || resolves_into_agents_dir "${entry}"; }; then
249
+ rm -f "${entry}"
250
+ fi
251
+ done
252
+ if [ -d "${harness_dir}" ]; then
253
+ rmdir "${harness_dir}" 2>/dev/null || true
254
+ fi
255
+ }
256
+
257
+ # Replace any legacy directory-level symlink (.claude/skills -> ../.ai/skills)
258
+ # with a real directory holding per-skill symlinks.
259
+ prepare_harness_dir() {
260
+ harness_dir="$1"
261
+ parent_dir=$(dirname "${harness_dir}")
262
+ mkdir -p "${parent_dir}"
263
+ if [ -L "${harness_dir}" ]; then
264
+ rm -f "${harness_dir}"
265
+ fi
266
+ if [ ! -d "${harness_dir}" ]; then
267
+ mkdir -p "${harness_dir}"
268
+ fi
269
+ }
270
+
271
+ sweep_harness() {
272
+ harness_dir="$1"
273
+ selected_list="$2"
274
+ [ -d "${harness_dir}" ] || return 0
275
+ for entry in "${harness_dir}"/*; do
276
+ [ -L "${entry}" ] || continue
277
+ base=$(basename "${entry}")
278
+ keep=0
279
+ for skill in ${selected_list}; do
280
+ if [ "${skill}" = "${base}" ]; then
281
+ keep=1
282
+ break
283
+ fi
284
+ done
285
+ if [ "${keep}" -eq 0 ] && resolves_into_skills_dir "${entry}"; then
286
+ rm -f "${entry}"
287
+ fi
288
+ done
289
+ }
290
+
291
+ print_list() {
292
+ for tier in ${all_tier_names}; do
293
+ count=$(tier_skill_count "${tier}")
294
+ if is_default_tier "${tier}"; then
295
+ label="default"
296
+ else
297
+ label="opt-in"
298
+ fi
299
+ printf '%-12s (%s skills, %s):\n' "${tier}" "${count}" "${label}"
300
+ skills=$(tier_skills "${tier}" | tr '\n' ',' | sed 's/,$//' | sed 's/,/, /g')
301
+ printf ' %s\n' "${skills}"
302
+ done
303
+
304
+ external_source=$(jq -r '.external.source // empty' "${manifest}")
305
+ if [ -n "${external_source}" ]; then
306
+ printf '\n'
307
+ printf 'external (from %s):\n' "${external_source}"
308
+ ext=$(jq -r '.external.skills[]?' "${manifest}" | tr '\n' ',' | sed 's/,$//' | sed 's/,/, /g')
309
+ printf ' %s\n' "${ext}"
310
+ fi
311
+ }
312
+
313
+ if [ "${list_only}" -eq 1 ]; then
314
+ print_list
315
+ exit 0
316
+ fi
317
+
318
+ if [ "${clean_only}" -eq 1 ]; then
319
+ clean_harness "${repo_root}/.claude/skills"
320
+ clean_harness "${repo_root}/.codex/skills"
321
+ if [ -d "${agents_dir}" ]; then
322
+ rm -rf "${agents_dir}"
323
+ echo "info: removed external skill copies under .agents/skills/."
324
+ fi
325
+ echo "info: removed all skill symlinks under .claude/skills/ and .codex/skills/."
326
+ exit 0
327
+ fi
328
+
329
+ selected_tiers=""
330
+
331
+ case "${mode}" in
332
+ ""|"with")
333
+ for tier in ${default_tier_names}; do
334
+ selected_tiers="${selected_tiers}
335
+ ${tier}"
336
+ done
337
+ if [ "${mode}" = "with" ]; then
338
+ extra_tiers=$(split_csv "${with_csv}")
339
+ if [ -z "${extra_tiers}" ]; then
340
+ echo "install-skills: --with requires at least one tier name." >&2
341
+ exit 1
342
+ fi
343
+ for tier in ${extra_tiers}; do
344
+ if ! tier_defined "${tier}"; then
345
+ echo "install-skills: unknown tier '${tier}'." >&2
346
+ echo " Valid tiers: $(printf '%s\n' ${all_tier_names} | tr '\n' ' ' | sed 's/ $//')" >&2
347
+ exit 1
348
+ fi
349
+ selected_tiers="${selected_tiers}
350
+ ${tier}"
351
+ done
352
+ fi
353
+ ;;
354
+ "tiers")
355
+ requested_tiers=$(split_csv "${tiers_csv}")
356
+ if [ -z "${requested_tiers}" ]; then
357
+ echo "install-skills: --tiers requires at least one tier name." >&2
358
+ exit 1
359
+ fi
360
+ for tier in ${requested_tiers}; do
361
+ if ! tier_defined "${tier}"; then
362
+ echo "install-skills: unknown tier '${tier}'." >&2
363
+ echo " Valid tiers: $(printf '%s\n' ${all_tier_names} | tr '\n' ' ' | sed 's/ $//')" >&2
364
+ exit 1
365
+ fi
366
+ selected_tiers="${selected_tiers}
367
+ ${tier}"
368
+ done
369
+ ;;
370
+ "all")
371
+ for tier in ${all_tier_names}; do
372
+ selected_tiers="${selected_tiers}
373
+ ${tier}"
374
+ done
375
+ ;;
376
+ esac
377
+
378
+ selected_tiers=$(printf '%s\n' "${selected_tiers}" | dedup_lines)
379
+
380
+ selected_skills=""
381
+ for tier in ${selected_tiers}; do
382
+ for skill in $(tier_skills "${tier}"); do
383
+ selected_skills="${selected_skills}
384
+ ${skill}"
385
+ done
386
+ done
387
+ selected_skills=$(printf '%s\n' "${selected_skills}" | dedup_lines)
388
+
389
+ if [ -z "${selected_skills}" ]; then
390
+ echo "install-skills: no skills selected for installation." >&2
391
+ exit 1
392
+ fi
393
+
394
+ external_skills_list=$(jq -r '.external.skills[]?' "${manifest}")
395
+
396
+ is_external_skill() {
397
+ needle="$1"
398
+ for candidate in ${external_skills_list}; do
399
+ if [ "${candidate}" = "${needle}" ]; then
400
+ return 0
401
+ fi
402
+ done
403
+ return 1
404
+ }
405
+
406
+ install_into_harness() {
407
+ harness_dir="$1"
408
+ prepare_harness_dir "${harness_dir}"
409
+ for skill in ${selected_skills}; do
410
+ if is_external_skill "${skill}"; then
411
+ # Owned by the external collection; a same-named .ai/skills/ folder is a
412
+ # repo-local override and must not shadow the npx-installed skill.
413
+ echo "install-skills: warning: '${skill}' is an external skill; skipping local symlink." >&2
414
+ continue
415
+ fi
416
+ skill_target="${skills_dir}/${skill}"
417
+ if [ ! -d "${skill_target}" ]; then
418
+ echo "install-skills: skill folder '${skill_target}' is missing on disk." >&2
419
+ exit 1
420
+ fi
421
+ link_path="${harness_dir}/${skill}"
422
+ ln -sfn "../../.ai/skills/${skill}" "${link_path}"
423
+ done
424
+ sweep_harness "${harness_dir}" "${selected_skills}"
425
+ }
426
+
427
+ install_into_harness "${repo_root}/.claude/skills"
428
+ install_into_harness "${repo_root}/.codex/skills"
429
+
430
+ # Mix in the external shared collection (open-mercato/skills). Only the explicit
431
+ # subset this app ships (external.skills) is installed — never the whole
432
+ # collection. The npx CLI copies each skill into .agents/skills/ and symlinks
433
+ # .claude/skills/<name> because that directory exists.
434
+ external_source=$(jq -r '.external.source // empty' "${manifest}")
435
+ external_status="none"
436
+ # The skills CLI matches each --skill value against skill names verbatim (no
437
+ # comma splitting), so the subset must be passed as repeated --skill flags.
438
+ external_skill_args=""
439
+ for external_skill in $(printf '%s\n' "${external_skills_list}" | dedup_lines); do
440
+ external_skill_args="${external_skill_args} --skill ${external_skill}"
441
+ done
442
+ if [ -n "${external_source}" ] && [ -n "${external_skill_args}" ]; then
443
+ if [ "${no_external}" = "1" ]; then
444
+ external_status="skipped (--no-external)"
445
+ elif ! command -v npx >/dev/null 2>&1; then
446
+ external_status="skipped (npx not found)"
447
+ echo "install-skills: warning: npx not found; skipping external skills from ${external_source}." >&2
448
+ elif (cd "${repo_root}" && npx -y skills add "${external_source}" ${external_skill_args} --agent claude-code --agent codex -y); then
449
+ external_status="installed from ${external_source}"
450
+ # `add` seeds the subset; a follow-up `update` bumps already-installed skills
451
+ # to the latest published versions on a re-run. Non-fatal when offline mid-run.
452
+ if (cd "${repo_root}" && npx -y skills update --project -y); then
453
+ external_status="updated to latest from ${external_source}"
454
+ else
455
+ echo "install-skills: warning: could not update external skills to latest;" >&2
456
+ echo " the installed versions are kept. Re-run when online to refresh." >&2
457
+ fi
458
+ # The npx CLI symlinks .claude/skills/<name> itself and expects Codex to read
459
+ # .agents/skills/ natively; mirror the symlinks into .codex/skills/ too.
460
+ if [ -d "${agents_dir}" ]; then
461
+ mkdir -p "${repo_root}/.codex/skills"
462
+ for external_entry in "${agents_dir}"/*; do
463
+ [ -d "${external_entry}" ] || continue
464
+ ln -sfn "../../.agents/skills/$(basename "${external_entry}")" "${repo_root}/.codex/skills/$(basename "${external_entry}")"
465
+ done
466
+ fi
467
+ else
468
+ external_status="FAILED"
469
+ echo "install-skills: warning: installing external skills from ${external_source} failed;" >&2
470
+ echo " local tier skills are installed. Re-run when online, or pass --no-external to silence this." >&2
471
+ fi
472
+ fi
473
+
474
+ skill_count=$(printf '%s\n' "${selected_skills}" | grep -c '.' || true)
475
+ tier_count=$(printf '%s\n' "${selected_tiers}" | grep -c '.' || true)
476
+ tier_summary=$(printf '%s\n' "${selected_tiers}" | tr '\n' ',' | sed 's/,$//' | sed 's/,/, /g')
477
+
478
+ printf 'Installed %s local skills across %s tiers: %s.\n' "${skill_count}" "${tier_count}" "${tier_summary}"
479
+ if [ "${external_status}" != "none" ]; then
480
+ printf 'External skills: %s.\n' "${external_status}"
481
+ fi
482
+
483
+ if [ -z "${mode}" ]; then
484
+ cat <<'EOF'
485
+ Tip: opt into more skills with `yarn install-skills --with automation` or `--all`.
486
+ See `yarn install-skills --list` for the full catalog.
487
+ EOF
488
+ fi
@@ -104,22 +104,11 @@ function generateShared(config) {
104
104
  writeTemplate(srcDir, "ai/specs/README.md", join(targetDir, ".ai", "specs", "README.md"), config);
105
105
  copyFile(srcDir, "ai/specs/SPEC-000-template.md", join(targetDir, ".ai", "specs", "SPEC-000-template.md"));
106
106
  copyFile(srcDir, "ai/lessons.md", join(targetDir, ".ai", "lessons.md"));
107
- writeTemplate(
108
- srcDir,
109
- "ai/skills/om-spec-writing/SKILL.md",
110
- join(targetDir, ".ai", "skills", "om-spec-writing", "SKILL.md"),
111
- config
112
- );
113
- copyFile(
114
- srcDir,
115
- "ai/skills/om-spec-writing/references/spec-template.md",
116
- join(targetDir, ".ai", "skills", "om-spec-writing", "references", "spec-template.md")
117
- );
118
- copyFile(
119
- srcDir,
120
- "ai/skills/om-spec-writing/references/spec-checklist.md",
121
- join(targetDir, ".ai", "skills", "om-spec-writing", "references", "spec-checklist.md")
122
- );
107
+ copyFile(srcDir, "ai/skills/tiers.json", join(targetDir, ".ai", "skills", "tiers.json"));
108
+ copyFile(srcDir, "ai/skills/tiers.schema.json", join(targetDir, ".ai", "skills", "tiers.schema.json"));
109
+ copyFile(srcDir, "ai/agentic.config.json", join(targetDir, ".ai", "agentic.config.json"));
110
+ copyFile(srcDir, "ai/trackers/github.md", join(targetDir, ".ai", "trackers", "github.md"));
111
+ copyFile(srcDir, "scripts/install-skills.sh", join(targetDir, "scripts", "install-skills.sh"));
123
112
  copyFile(
124
113
  srcDir,
125
114
  "ai/skills/om-backend-ui-design/SKILL.md",
@@ -130,16 +119,6 @@ function generateShared(config) {
130
119
  "ai/skills/om-backend-ui-design/references/ui-components.md",
131
120
  join(targetDir, ".ai", "skills", "om-backend-ui-design", "references", "ui-components.md")
132
121
  );
133
- copyFile(
134
- srcDir,
135
- "ai/skills/om-code-review/SKILL.md",
136
- join(targetDir, ".ai", "skills", "om-code-review", "SKILL.md")
137
- );
138
- copyFile(
139
- srcDir,
140
- "ai/skills/om-code-review/references/review-checklist.md",
141
- join(targetDir, ".ai", "skills", "om-code-review", "references", "review-checklist.md")
142
- );
143
122
  copyFile(srcDir, "ai/skills/om-integration-builder/SKILL.md", join(targetDir, ".ai", "skills", "om-integration-builder", "SKILL.md"));
144
123
  if (existsSync(join(srcDir, "ai", "skills", "om-integration-builder", "STANDALONE.md"))) {
145
124
  copyFile(
@@ -215,11 +194,6 @@ function generateShared(config) {
215
194
  "ai/skills/om-implement-spec/SKILL.md",
216
195
  join(targetDir, ".ai", "skills", "om-implement-spec", "SKILL.md")
217
196
  );
218
- copyFile(
219
- srcDir,
220
- "ai/skills/om-integration-tests/SKILL.md",
221
- join(targetDir, ".ai", "skills", "om-integration-tests", "SKILL.md")
222
- );
223
197
  copyFile(
224
198
  srcDir,
225
199
  "ai/skills/om-help/SKILL.md",
@@ -246,21 +220,16 @@ function generateShared(config) {
246
220
  "om-auto-create-pr-loop",
247
221
  "om-auto-continue-pr-loop",
248
222
  "om-auto-review-pr",
249
- "om-auto-fix-github",
250
- "om-prepare-issue"
223
+ "om-auto-fix-issue"
251
224
  ]) {
225
+ if (!existsSync(join(srcDir, "ai", "skills", autoSkill, "SKILL.md"))) {
226
+ continue;
227
+ }
252
228
  copyFile(
253
229
  srcDir,
254
230
  `ai/skills/${autoSkill}/SKILL.md`,
255
231
  join(targetDir, ".ai", "skills", autoSkill, "SKILL.md")
256
232
  );
257
- if (existsSync(join(srcDir, "ai", "skills", autoSkill, "STANDALONE.md"))) {
258
- copyFile(
259
- srcDir,
260
- `ai/skills/${autoSkill}/STANDALONE.md`,
261
- join(targetDir, ".ai", "skills", autoSkill, "STANDALONE.md")
262
- );
263
- }
264
233
  }
265
234
  copyFile(
266
235
  srcDir,