@litfamily/litopencode 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ are tracked separately from this product history.
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## 1.0.6
9
+
10
+ - Ask about competing visual directions the brief leaves open instead of silently applying an announced default.
11
+ - Show the link target, its resolved directory, and any same-named shadowing skill for the shared native skills root in install and doctor output.
12
+ - Show the robot cover as a visible image under the motion hero in both READMEs instead of behind a hidden link, and remove the duplicate copy that repeated near the LITFAMILY illustration.
13
+
8
14
  ## 1.0.5
9
15
 
10
16
  - Add README Studio decoration patterns and the bounded multi-round design interview.
package/README-Ko-KR.md CHANGED
@@ -1,7 +1,7 @@
1
- <p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/cover-motion.webp" width="100%" alt="LITOPENCODE 워드마크 위 궤도를 라임 신호가 지나가는 표지입니다. 움직임 줄이기를 선호하면 이 표지의 정지 프레임을 표시합니다." /></picture></p>
2
- <p align="center"><a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/cover.webp">정지 표지 보기</a></p>
1
+ <p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/cover-motion.webp" width="100%" alt="LITOPENCODE 워드마크 위 궤도를 라임 신호가 지나가는 표지입니다. 움직임 줄이기를 선호하면 이 표지의 정지 프레임을 표시합니다." /></picture></p>
2
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/cover.webp" width="100%" alt="LITFAMILY와 KEEP THE WORK LIT. 문구 아래에 모인 다섯 로봇 크루." /></p>
3
3
 
4
- <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ascii-readme.svg" width="480" alt="LIT ASCII B 마크" /></p>
4
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ascii-readme.svg" width="480" alt="LIT ASCII B 마크" /></p>
5
5
 
6
6
  <details>
7
7
  <summary>ASCII 로고 복사</summary>
@@ -33,21 +33,21 @@
33
33
 
34
34
  # LitOpenCode
35
35
 
36
- [English](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/README.md) · [한국어](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/README-Ko-KR.md)
36
+ [English](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/README.md) · [한국어](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/README-Ko-KR.md)
37
37
 
38
38
  > **불씨를 건네받았다.**<br>
39
39
  > **이제, 당신의 작업에 옮길 차례다.**
40
40
 
41
- <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/litopencode-wordmark.svg" width="480" alt="LITOPENCODE 디스플레이 타입" /></p>
42
- <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/litopencode-clay-icon.png" width="160" alt="LitOpenCode 클레이 마크" /></p>
41
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/litopencode-wordmark.svg" width="480" alt="LITOPENCODE 디스플레이 타입" /></p>
42
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/litopencode-clay-icon.png" width="160" alt="LitOpenCode 클레이 마크" /></p>
43
43
 
44
44
  <p align="center">
45
- <a href="#설치"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/badge-version.svg" alt="1.0.5" /></a>
46
- <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/badge-license.svg" alt="MIT 라이선스" /></a>
45
+ <a href="#설치"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/badge-version.svg" alt="1.0.6" /></a>
46
+ <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/badge-license.svg" alt="MIT 라이선스" /></a>
47
47
  </p>
48
48
 
49
49
  <p align="center">
50
- <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference-Ko-KR.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/lucide-book-open.svg" width="16" alt="" /> 문서</a> &nbsp; <a href="#설치">설치</a> &nbsp; <a href="#ignition-motion"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/lucide-play.svg" width="16" alt="" /> Ignition</a> &nbsp; <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/lucide-shield-check.svg" width="16" alt="" /> MIT</a>
50
+ <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference-Ko-KR.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/lucide-book-open.svg" width="16" alt="" /> 문서</a> &nbsp; <a href="#설치">설치</a> &nbsp; <a href="#ignition-motion"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/lucide-play.svg" width="16" alt="" /> Ignition</a> &nbsp; <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/lucide-shield-check.svg" width="16" alt="" /> MIT</a>
51
51
  </p>
52
52
 
53
53
  ## LitOpenCode란
@@ -79,9 +79,9 @@ npm exec --package @litfamily/litopencode@latest -- litopencode install --yes
79
79
  설치 도구는 OpenCode 설정 루트에 플러그인과 native 명령·스킬 파일을 등록합니다.
80
80
  route 파일은 `~/.config/opencode/litopencode.json`이며 `XDG_CONFIG_HOME`을 지정하면
81
81
  설정 루트가 달라집니다. 기존 custom route는 사용자 소유로 유지됩니다.
82
- custom root, 모델 선택, 터미널 정책, 무인 설치는 [상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference-Ko-KR.md#설치)를 참고하세요.
82
+ custom root, 모델 선택, 터미널 정책, 무인 설치는 [상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference-Ko-KR.md#설치)를 참고하세요.
83
83
 
84
- 이 checkout의 패키지는 `@litfamily/litopencode@1.0.5`입니다. registry의 `@latest`는 다를 수 있으므로
84
+ 이 checkout의 패키지는 `@litfamily/litopencode@1.0.6`입니다. registry의 `@latest`는 다를 수 있으므로
85
85
  정확한 버전이 필요하면 `npm view @litfamily/litopencode version`으로 확인하세요.
86
86
 
87
87
  ## 처음 사용하기
@@ -136,9 +136,9 @@ primitive가 없으므로 이 프로젝트별 로컬 기록으로 작업을 재
136
136
 
137
137
  Lit 경로가 활성화되면 답변이 굵은 점화 문구로 시작합니다. 플러그인은 글리프를 지원하는 환경에서 다섯 줄의 micro 로고와 마지막 `🔥 LIT IGNITED · <discipline> 🔥` 문구를 6초 동안 경고 토스트로 표시하도록 요청합니다. 글리프를 지원하지 않으면 문구만 표시합니다.
138
138
 
139
- <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/litopencode-ignition-1600.webp" width="48%" alt="LitOpenCode 점화 장치" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/litopencode-continuity-1600.webp" width="48%" alt="LitOpenCode 연속 장치" /></p>
139
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/litopencode-ignition-1600.webp" width="48%" alt="LitOpenCode 점화 장치" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/litopencode-continuity-1600.webp" width="48%" alt="LitOpenCode 연속 장치" /></p>
140
140
 
141
- <p align="center"><a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/poster.png" width="720" alt="Ignition 모션 포스터" /></a></p>
141
+ <p align="center"><a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/poster.png" width="720" alt="Ignition 모션 포스터" /></a></p>
142
142
 
143
143
  포스터를 선택하면 선택형 영상을 엽니다. README에서 자동 재생하지 않습니다.
144
144
 
@@ -210,9 +210,9 @@ canonical 경로를 사용합니다. 번호가 붙은 license·provenance 파일
210
210
  | `/lit-korean` | 의미를 유지하며 한국어 문장 다듬기 |
211
211
  | `/lit-scientific-visualization` | 패키지에 포함된 과학 시각화 워크플로 |
212
212
 
213
- Autoresearch, Autoconference, Wikify, UI/UX는 [전체 경로 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference-Ko-KR.md#주요-명령)에,
214
- 두 가지 rule 처리 경로는 [규칙 엔진 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md#safety-and-updates)에서 확인하세요.
215
- 이전 스킬 이름은 한 릴리스 동안 별칭으로 연결됩니다. [마이그레이션 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/migration.md#skill-id-renames)를 확인하세요.
213
+ Autoresearch, Autoconference, Wikify, UI/UX는 [전체 경로 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference-Ko-KR.md#주요-명령)에,
214
+ 두 가지 rule 처리 경로는 [규칙 엔진 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md#safety-and-updates)에서 확인하세요.
215
+ 이전 스킬 이름은 한 릴리스 동안 별칭으로 연결됩니다. [마이그레이션 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/migration.md#skill-id-renames)를 확인하세요.
216
216
 
217
217
  ## 안전과 업데이트
218
218
 
@@ -223,7 +223,7 @@ Autoresearch, Autoconference, Wikify, UI/UX는 [전체 경로 안내](https://cd
223
223
  `--no-auto-update` 또는 `LITOPENCODE_NO_AUTO_UPDATE=1`로 자동 업데이트를 끌 수 있습니다.
224
224
  - 스킬 학습 결과는 명시적인 apply 명령이 있어야 반영됩니다. 학습의 review·변경·rollback·curator는
225
225
  POSIX를 지원하며 Windows에서는 해당 경계를 차단합니다. 설치, doctor, 수동 조회에는
226
- 이 제한이 적용되지 않습니다. [학습 루프 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md#skill-learning-loop).
226
+ 이 제한이 적용되지 않습니다. [학습 루프 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md#skill-learning-loop).
227
227
 
228
228
  ## 문제 해결
229
229
 
@@ -235,7 +235,13 @@ Autoresearch, Autoconference, Wikify, UI/UX는 [전체 경로 안내](https://cd
235
235
  npm exec --package @litfamily/litopencode@latest -- litopencode doctor
236
236
  ```
237
237
 
238
- [설치와 모델 설정 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference-Ko-KR.md#설치)를 참고하세요.
238
+ [설치와 모델 설정 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference-Ko-KR.md#설치)를 참고하세요.
239
+
240
+ `install`과 `doctor`는 `<root>/skills`가 심볼릭 링크일 때 그 사실과 git 저장소 경고를
241
+ 보고하며, `~/.agents/skills`, `~/.claude/skills`, 프로젝트 스킬 디렉토리에 같은 이름의
242
+ 스킬이 있으면 함께 알려줍니다. 자세한 내용은
243
+ [심볼릭 링크된 native 스킬 루트와 다른 위치의 같은 이름 스킬](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference-Ko-KR.md#심볼릭-링크된-native-스킬-루트와-다른-위치의-같은-이름-스킬)을
244
+ 참고하세요.
239
245
 
240
246
  ## 제거
241
247
 
@@ -250,7 +256,7 @@ npm uninstall -g @litfamily/litopencode
250
256
  설치된 명령·스킬 파일은 소유 관계를 확인한 뒤 설치 도구가 관리하는 복사본만 제거하세요.
251
257
  사용자가 만든 파일과 수정 내용은 보존합니다. route가 필요하면 `litopencode.json`을,
252
258
  작업을 재개할 계획이라면 프로젝트의 `.litopencode/` 기록을 남기세요. 제거 후 OpenCode를
253
- 재시작합니다. [제거 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference-Ko-KR.md#제거).
259
+ 재시작합니다. [제거 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference-Ko-KR.md#제거).
254
260
 
255
261
  ## 라이선스
256
262
 
@@ -260,27 +266,25 @@ MIT
260
266
 
261
267
  ### 문서
262
268
 
263
- - [워크플로 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference-Ko-KR.md): 모델, 권한, host 연결, 명령, 검증 방법
264
- - [English reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md): 전체 스킬 목록, 학습 루프, 규칙 엔진 포함
265
- - [마이그레이션 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/migration.md)
266
- - [터미널 마크와 활성화 확인 문구](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/lit-mark.md)
267
- - [Changelog](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/CHANGELOG.md)
269
+ - [워크플로 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference-Ko-KR.md): 모델, 권한, host 연결, 명령, 검증 방법
270
+ - [English reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md): 전체 스킬 목록, 학습 루프, 규칙 엔진 포함
271
+ - [마이그레이션 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/migration.md)
272
+ - [터미널 마크와 활성화 확인 문구](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/lit-mark.md)
273
+ - [Changelog](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/CHANGELOG.md)
268
274
  - 출시 담당자 체크리스트 (저장소 전용)
269
275
 
270
- - [기여 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/CONTRIBUTING.md) · [지원](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/SUPPORT.md) · [보안 제보](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/SECURITY.md)
271
- - [행동 규범](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/CODE_OF_CONDUCT.md) · [개인정보와 네트워크 동작](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/privacy.md)
276
+ - [기여 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/CONTRIBUTING.md) · [지원](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/SUPPORT.md) · [보안 제보](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/SECURITY.md)
277
+ - [행동 규범](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/CODE_OF_CONDUCT.md) · [개인정보와 네트워크 동작](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/privacy.md)
272
278
 
273
279
  ### LITFAMILY
274
280
 
275
- ![LitClaude, LitHermes, LitCodex, LitOpenCode, LitGrok을 표현한 다섯 중장갑 머신](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/litfamily-machines.png)
281
+ ![LitClaude, LitHermes, LitCodex, LitOpenCode, LitGrok을 표현한 다섯 중장갑 머신](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/litfamily-machines.png)
276
282
 
277
283
  LitClaude · LitHermes · LitCodex · LitOpenCode · LitGrok.
278
284
  다섯 중장갑 머신으로 다섯 제품을 표현한 일러스트입니다. 각 제품은 자신이 지원하는 도구에서 독립적으로 동작합니다.
279
285
 
280
- ![LITFAMILY와 KEEP THE WORK LIT. 문구 아래에 모인 다섯 로봇 크루.](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/cover.webp)
281
-
282
286
  ### Ignition motion
283
287
 
284
- [![Ignition 모션 그래픽 포스터](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/poster.png)](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ignition-film.mp4)
288
+ [![Ignition 모션 그래픽 포스터](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/poster.png)](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ignition-film.mp4)
285
289
 
286
- [10초 영상 보기](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ignition-film.mp4) · [애니메이션 GIF](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ignition-readme.gif) · [Lucide 아이콘 라이선스](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/Lucide-LICENSE.txt) · [ASCII 글꼴 라이선스](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/JetBrainsMono-OFL.txt)
290
+ [10초 영상 보기](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ignition-film.mp4) · [애니메이션 GIF](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ignition-readme.gif) · [Lucide 아이콘 라이선스](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/Lucide-LICENSE.txt) · [ASCII 글꼴 라이선스](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/JetBrainsMono-OFL.txt)
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
- <p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/cover-motion.webp" width="100%" alt="LitOpenCode cover art. A lime signal traces orbital paths above the OPENCODE wordmark. Reduced-motion users see a still frame from this cover." /></picture></p>
2
- <p align="center"><a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/cover.webp">View the static cover</a></p>
1
+ <p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/cover-motion.webp" width="100%" alt="LitOpenCode cover art. A lime signal traces orbital paths above the OPENCODE wordmark. Reduced-motion users see a still frame from this cover." /></picture></p>
2
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/cover.webp" width="100%" alt="Five robots beneath the LITFAMILY and KEEP THE WORK LIT. lettering." /></p>
3
3
 
4
- <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ascii-readme.svg" width="480" alt="LIT ASCII B mark" /></p>
4
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ascii-readme.svg" width="480" alt="LIT ASCII B mark" /></p>
5
5
 
6
6
  <details>
7
7
  <summary>Copy ASCII logo</summary>
@@ -33,20 +33,20 @@
33
33
 
34
34
  # LitOpenCode
35
35
 
36
- [English](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/README.md) · [한국어](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/README-Ko-KR.md)
36
+ [English](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/README.md) · [한국어](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/README-Ko-KR.md)
37
37
 
38
38
  **Keep the work lit.**
39
39
 
40
- <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/litopencode-wordmark.svg" width="480" alt="LITOPENCODE display type" /></p>
41
- <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/litopencode-clay-icon.png" width="160" alt="LitOpenCode clay mark" /></p>
40
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/litopencode-wordmark.svg" width="480" alt="LITOPENCODE display type" /></p>
41
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/litopencode-clay-icon.png" width="160" alt="LitOpenCode clay mark" /></p>
42
42
 
43
43
  <p align="center">
44
- <a href="#install"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/badge-version.svg" alt="1.0.5" /></a>
45
- <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/badge-license.svg" alt="MIT license" /></a>
44
+ <a href="#install"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/badge-version.svg" alt="1.0.6" /></a>
45
+ <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/badge-license.svg" alt="MIT license" /></a>
46
46
  </p>
47
47
 
48
48
  <p align="center">
49
- <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/lucide-book-open.svg" width="16" alt="" /> Docs</a> &nbsp; <a href="#install">Install</a> &nbsp; <a href="#ignition-motion"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/lucide-play.svg" width="16" alt="" /> Ignition</a> &nbsp; <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/lucide-shield-check.svg" width="16" alt="" /> MIT</a>
49
+ <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/lucide-book-open.svg" width="16" alt="" /> Docs</a> &nbsp; <a href="#install">Install</a> &nbsp; <a href="#ignition-motion"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/lucide-play.svg" width="16" alt="" /> Ignition</a> &nbsp; <a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/lucide-shield-check.svg" width="16" alt="" /> MIT</a>
50
50
  </p>
51
51
 
52
52
  ## What is LitOpenCode
@@ -76,10 +76,10 @@ npm exec --package @litfamily/litopencode@latest -- litopencode install --yes
76
76
  Installation registers the plugin and native command/skill files under your OpenCode
77
77
  config root. Routes live in `~/.config/opencode/litopencode.json`; `XDG_CONFIG_HOME`
78
78
  changes that root. Existing custom routes remain user-owned. See the
79
- [installation and model reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md#install) for custom roots,
79
+ [installation and model reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md#install) for custom roots,
80
80
  provider choices, terminal policy, and unattended setup.
81
81
 
82
- This checkout is `@litfamily/litopencode@1.0.5`. Registry `@latest` can differ; inspect it with
82
+ This checkout is `@litfamily/litopencode@1.0.6`. Registry `@latest` can differ; inspect it with
83
83
  `npm view @litfamily/litopencode version` when an exact version matters.
84
84
 
85
85
  ## First use
@@ -134,9 +134,9 @@ Use `lit` or `/lit` to start a bounded task; `handoff` or `/lit-handoff` carries
134
134
 
135
135
  When a Lit route activates, the reply starts with a bold ignition line. The plugin requests a six-second warning toast with five micro-logo rows and a final `🔥 LIT IGNITED · <discipline> 🔥` line when the environment supports mark glyphs; otherwise, it shows only that line.
136
136
 
137
- <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/litopencode-ignition-1600.webp" width="48%" alt="LitOpenCode ignition apparatus" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/litopencode-continuity-1600.webp" width="48%" alt="LitOpenCode continuity apparatus" /></p>
137
+ <p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/litopencode-ignition-1600.webp" width="48%" alt="LitOpenCode ignition apparatus" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/litopencode-continuity-1600.webp" width="48%" alt="LitOpenCode continuity apparatus" /></p>
138
138
 
139
- <p align="center"><a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/poster.png" width="720" alt="Ignition motion poster" /></a></p>
139
+ <p align="center"><a href="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/poster.png" width="720" alt="Ignition motion poster" /></a></p>
140
140
 
141
141
  The poster opens the optional film; this README keeps motion opt-in.
142
142
 
@@ -206,9 +206,9 @@ remain source-attribution records.
206
206
  | `/lit-korean` | Improve Korean prose without changing its meaning. |
207
207
  | `/lit-scientific-visualization` | Use the packaged scientific-visualization workflow. |
208
208
 
209
- The [full route and skill reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md#core-commands) covers
209
+ The [full route and skill reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md#core-commands) covers
210
210
  Autoresearch, Autoconference, Wikify, UI/UX, and the two-lane repository rules engine.
211
- [Migration notes](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/migration.md#skill-id-renames) explain the one-release skill aliases.
211
+ [Migration notes](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/migration.md#skill-id-renames) explain the one-release skill aliases.
212
212
 
213
213
  ## Safety and updates
214
214
 
@@ -219,7 +219,7 @@ Autoresearch, Autoconference, Wikify, UI/UX, and the two-lane repository rules e
219
219
  check. Use `--no-auto-update` or `LITOPENCODE_NO_AUTO_UPDATE=1` to disable automatic updates.
220
220
  - Skill learning requires an explicit apply command. Its review, mutation, rollback, and
221
221
  curator boundaries support POSIX; on Windows those boundaries fail closed. Install,
222
- doctor, and passive surfaces remain available. [Learning-loop details](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md#skill-learning-loop).
222
+ doctor, and passive surfaces remain available. [Learning-loop details](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md#skill-learning-loop).
223
223
 
224
224
  ## Troubleshooting
225
225
 
@@ -231,7 +231,12 @@ Inspect package and configuration health with:
231
231
  npm exec --package @litfamily/litopencode@latest -- litopencode doctor
232
232
  ```
233
233
 
234
- See the [installation and model reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md#install).
234
+ See the [installation and model reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md#install).
235
+
236
+ Install and `doctor` report when `<root>/skills` is a symlink (and its git-repository
237
+ warning) and any same-named skill shadowing it in `~/.agents/skills`, `~/.claude/skills`,
238
+ or a project skills directory. See
239
+ [symlinked native skills root and shadow copies](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md#symlinked-native-skills-root-and-shadow-copies).
235
240
 
236
241
  ## Uninstall
237
242
 
@@ -247,7 +252,7 @@ npm uninstall -g @litfamily/litopencode
247
252
  Review installed command/skill files before removing installer-owned copies; preserve
248
253
  user-created files and edits. Keep `litopencode.json` if you still need its routes, and
249
254
  keep project `.litopencode/` ledgers if you plan to resume. Restart OpenCode after removal.
250
- See the [removal reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md#remove).
255
+ See the [removal reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md#remove).
251
256
 
252
257
  ## License
253
258
 
@@ -257,27 +262,25 @@ MIT
257
262
 
258
263
  ### Documentation
259
264
 
260
- - [Workflow reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference.md): models, permissions, host hooks, all skills, learning loop, and reproducible verification.
261
- - [한국어 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/reference-Ko-KR.md)
262
- - [Migration notes](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/migration.md)
263
- - [Terminal mark and activation probes](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/lit-mark.md)
264
- - [Changelog](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/CHANGELOG.md)
265
+ - [Workflow reference](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference.md): models, permissions, host hooks, all skills, learning loop, and reproducible verification.
266
+ - [한국어 상세 안내](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/reference-Ko-KR.md)
267
+ - [Migration notes](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/migration.md)
268
+ - [Terminal mark and activation probes](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/lit-mark.md)
269
+ - [Changelog](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/CHANGELOG.md)
265
270
  - Maintainer release checklist (repository only)
266
271
 
267
- - [Contributing](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/CONTRIBUTING.md) · [Support](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/SUPPORT.md) · [Security](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/SECURITY.md)
268
- - [Code of conduct](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/CODE_OF_CONDUCT.md) · [Privacy and network behavior](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/privacy.md)
272
+ - [Contributing](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/CONTRIBUTING.md) · [Support](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/SUPPORT.md) · [Security](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/SECURITY.md)
273
+ - [Code of conduct](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/CODE_OF_CONDUCT.md) · [Privacy and network behavior](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/privacy.md)
269
274
 
270
275
  ### LITFAMILY
271
276
 
272
- ![Five armored machines representing LitClaude, LitHermes, LitCodex, LitOpenCode and LitGrok](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/litfamily-machines.png)
277
+ ![Five armored machines representing LitClaude, LitHermes, LitCodex, LitOpenCode and LitGrok](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/litfamily-machines.png)
273
278
 
274
279
  LitClaude · LitHermes · LitCodex · LitOpenCode · LitGrok.
275
280
  Five armored machines for five independent products, each working in its own host.
276
281
 
277
- ![Five robots beneath the LITFAMILY and KEEP THE WORK LIT. lettering.](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/cover.webp)
278
-
279
282
  ### Ignition motion
280
283
 
281
- [![Ignition motion graphic poster](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/poster.png)](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ignition-film.mp4)
284
+ [![Ignition motion graphic poster](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/poster.png)](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ignition-film.mp4)
282
285
 
283
- [Watch the 10-second film](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ignition-film.mp4) · [Animated GIF](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/ignition-readme.gif) · [Lucide icon license](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/Lucide-LICENSE.txt) · [ASCII font license](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.5/docs/assets/readme/JetBrainsMono-OFL.txt)
286
+ [Watch the 10-second film](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ignition-film.mp4) · [Animated GIF](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/ignition-readme.gif) · [Lucide icon license](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/Lucide-LICENSE.txt) · [ASCII font license](https://cdn.jsdelivr.net/npm/@litfamily/litopencode@1.0.6/docs/assets/readme/JetBrainsMono-OFL.txt)
@@ -127,6 +127,21 @@ function actionLines(report) {
127
127
  function progressLine(label) {
128
128
  return " " + tint("[ok]", green) + " " + label;
129
129
  }
130
+ // A symlinked <root>/skills is intentional and install still succeeds; these lines only make the
131
+ // resolved destination visible, and warn when that destination is a git work tree a managed install
132
+ // would write dozens of skill directories into (see the ~/skills incident this guards against).
133
+ function nativeSkillsLinkLines(report) {
134
+ const link = report.nativeSkills.link;
135
+ if (link === undefined)
136
+ return [];
137
+ const lines = [line("Native skills link", link.path + " -> " + link.target + " (linked directory)")];
138
+ if (link.gitRepositoryRoot !== undefined) {
139
+ lines.push(line("Warning", "linked native skills target is inside git repository " +
140
+ link.gitRepositoryRoot +
141
+ "; managed skills will appear inside that repository"));
142
+ }
143
+ return lines;
144
+ }
130
145
  function headerLine(label, code) {
131
146
  return "| " + tint(label.padEnd(58, " "), code) + " |";
132
147
  }
@@ -168,6 +183,7 @@ export function renderInstallReport(report) {
168
183
  line("LitOpenCode config", report.litopencodeConfig.path),
169
184
  line("Command aliases", report.commandAliases.write.length + " managed / " + report.commandAliases.preserve.length + " preserved"),
170
185
  line("Native skills", report.nativeSkills.write.length + " managed / " + report.nativeSkills.preserve.length + " preserved"),
186
+ ...nativeSkillsLinkLines(report),
171
187
  line("Plugin entries", report.plugin.currentCount + " -> " + report.plugin.resultCount),
172
188
  ...section("Progress"),
173
189
  progressLine("Resolve package"),
@@ -14,6 +14,22 @@ export type DestinationState = {
14
14
  readonly reason: string;
15
15
  };
16
16
  export declare function nativeSkillsRoot(root: string): Promise<string>;
17
+ export type NativeSkillsRootLink = {
18
+ readonly path: string;
19
+ readonly target: string;
20
+ readonly gitRepositoryRoot?: string;
21
+ };
22
+ export declare function nativeSkillsRootLink(root: string, homeDir?: string): Promise<NativeSkillsRootLink | undefined>;
23
+ export type ShadowSkillLocationId = "user-agents" | "user-claude" | "project-opencode" | "project-claude" | "project-agents";
24
+ export type ShadowSkillLocation = {
25
+ readonly id: ShadowSkillLocationId;
26
+ readonly root: string;
27
+ };
28
+ export type ShadowedSkill = {
29
+ readonly id: string;
30
+ readonly locations: readonly ShadowSkillLocation[];
31
+ };
32
+ export declare function detectShadowedSkills(skillIds: readonly string[], managedSkillsRoot: string, homeDir?: string, workDir?: string): Promise<readonly ShadowedSkill[]>;
17
33
  export declare function sourceSkillDir(metadata: PackageMetadata, id: string): string;
18
34
  export declare function nativeSkillContent(metadata: PackageMetadata, skill: RuntimeSkill): Promise<string>;
19
35
  export declare function validateManagedSkillSource(metadata: PackageMetadata, id: ManagedSkillId): Promise<void>;
@@ -1,5 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import fs from "node:fs/promises";
3
+ import os from "node:os";
3
4
  import path from "node:path";
4
5
  import { litOpenCodeRuntimeSkills } from "../skills.js";
5
6
  import { hasLitOpenCodeGeneratedFileMarker, litOpenCodeGeneratedFrontmatterMarker, stripUserFacingHtmlCommentLines } from "../user-facing-markdown.js";
@@ -9,6 +10,85 @@ import { inspectCanonicalTree } from "./native-canonical-cache.js";
9
10
  export async function nativeSkillsRoot(root) {
10
11
  return resolveSafeDirectory(root, path.join(root, "skills"), "Native skills destination");
11
12
  }
13
+ // Walks upward from `startDir` looking for a `.git` entry (directory or the gitdir-pointer file a
14
+ // worktree/submodule uses), stopping once it reaches `homeDir` or the filesystem root so an
15
+ // unrelated ancestor repository is never reported as the destination.
16
+ async function gitRepositoryRootFor(startDir, homeDir) {
17
+ const home = path.resolve(homeDir);
18
+ const fsRoot = path.parse(startDir).root;
19
+ let current = path.resolve(startDir);
20
+ while (true) {
21
+ if ((await lstatIfPresent(path.join(current, ".git"))) !== null)
22
+ return current;
23
+ if (current === home || current === fsRoot)
24
+ return undefined;
25
+ const parent = path.dirname(current);
26
+ if (parent === current)
27
+ return undefined;
28
+ current = parent;
29
+ }
30
+ }
31
+ // Reports the same symlink LitOpenCode intentionally follows for install (resolveSafeDirectory),
32
+ // so users can see where their managed skills actually landed and whether that is a git work tree.
33
+ export async function nativeSkillsRootLink(root, homeDir = os.homedir()) {
34
+ const skillsPath = path.join(path.resolve(root), "skills");
35
+ const stat = await lstatIfPresent(skillsPath);
36
+ if (stat === null || !stat.isSymbolicLink())
37
+ return undefined;
38
+ const target = await fs.realpath(skillsPath);
39
+ const gitRepositoryRoot = await gitRepositoryRootFor(target, homeDir);
40
+ return { path: skillsPath, target, ...(gitRepositoryRoot === undefined ? {} : { gitRepositoryRoot }) };
41
+ }
42
+ function shadowSkillCandidateRoots(homeDir, workDir) {
43
+ return [
44
+ { id: "user-agents", root: path.join(homeDir, ".agents", "skills") },
45
+ { id: "user-claude", root: path.join(homeDir, ".claude", "skills") },
46
+ { id: "project-opencode", root: path.join(workDir, ".opencode", "skills") },
47
+ { id: "project-claude", root: path.join(workDir, ".claude", "skills") },
48
+ { id: "project-agents", root: path.join(workDir, ".agents", "skills") }
49
+ ];
50
+ }
51
+ async function statIfPresent(filePath) {
52
+ try {
53
+ return await fs.stat(filePath);
54
+ }
55
+ catch (error) {
56
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
57
+ return null;
58
+ throw error;
59
+ }
60
+ }
61
+ async function realpathOrResolved(candidate) {
62
+ try {
63
+ return await fs.realpath(candidate);
64
+ }
65
+ catch {
66
+ return path.resolve(candidate);
67
+ }
68
+ }
69
+ // OpenCode also reads skills from these other, unmanaged roots; a same-named skill there can be
70
+ // loaded instead of (or alongside) LitOpenCode's managed copy. This is informational only: it never
71
+ // changes `ok`, because LitOpenCode does not own those directories.
72
+ export async function detectShadowedSkills(skillIds, managedSkillsRoot, homeDir = os.homedir(), workDir = process.cwd()) {
73
+ const managedRealpath = await realpathOrResolved(managedSkillsRoot);
74
+ const candidates = shadowSkillCandidateRoots(homeDir, workDir);
75
+ const shadowed = [];
76
+ for (const id of skillIds) {
77
+ const locations = [];
78
+ for (const candidate of candidates) {
79
+ const entrypoint = path.join(candidate.root, id, "SKILL.md");
80
+ const stat = await statIfPresent(entrypoint);
81
+ if (stat === null || !stat.isFile())
82
+ continue;
83
+ if ((await realpathOrResolved(candidate.root)) === managedRealpath)
84
+ continue;
85
+ locations.push(candidate);
86
+ }
87
+ if (locations.length > 0)
88
+ shadowed.push({ id, locations });
89
+ }
90
+ return shadowed;
91
+ }
12
92
  export function sourceSkillDir(metadata, id) {
13
93
  return path.join(metadata.packageRoot, "skills", id);
14
94
  }
@@ -1,7 +1,9 @@
1
+ import { type NativeSkillsRootLink, type ShadowedSkill } from "./native-skill-integrity.ts";
1
2
  import { inspectScientificVisualizationDependencies } from "./scientific-visualization-dependencies.ts";
2
3
  import type { InstallReport, PackageMetadata } from "./types.ts";
3
4
  export { validateManagedSkillSource } from "./native-skill-integrity.ts";
4
5
  export { ensureNativeSkills } from "./native-skill-install.ts";
6
+ export type { NativeSkillsRootLink, ShadowedSkill, ShadowSkillLocation, ShadowSkillLocationId } from "./native-skill-integrity.ts";
5
7
  export declare function describeNativeSkillMutation(root: string, metadata: PackageMetadata): Promise<InstallReport["nativeSkills"]>;
6
8
  export type NativeSkillInspection = {
7
9
  readonly path: string;
@@ -17,6 +19,12 @@ export type NativeSkillInspection = {
17
19
  readonly dependencies: {
18
20
  readonly "lit-scientific-visualization": ReturnType<typeof inspectScientificVisualizationDependencies>;
19
21
  };
22
+ readonly link?: NativeSkillsRootLink;
23
+ readonly shadowedSkills: readonly ShadowedSkill[];
20
24
  readonly ok: boolean;
21
25
  };
22
- export declare function inspectNativeSkills(root: string, metadata: PackageMetadata): Promise<NativeSkillInspection>;
26
+ export type InspectNativeSkillsOptions = {
27
+ readonly homeDir?: string;
28
+ readonly workDir?: string;
29
+ };
30
+ export declare function inspectNativeSkills(root: string, metadata: PackageMetadata, options?: InspectNativeSkillsOptions): Promise<NativeSkillInspection>;
@@ -1,9 +1,19 @@
1
1
  import path from "node:path";
2
2
  import { litOpenCodeRuntimeSkills } from "../skills.js";
3
- import { destinationState, assertInstalledCanonicalOwnership, invalidInstalledAssets, validateSkillSource } from "./native-skill-integrity.js";
3
+ import { destinationState, assertInstalledCanonicalOwnership, detectShadowedSkills, invalidInstalledAssets, nativeSkillsRoot, nativeSkillsRootLink, validateSkillSource } from "./native-skill-integrity.js";
4
4
  import { inspectScientificVisualizationDependencies } from "./scientific-visualization-dependencies.js";
5
5
  export { validateManagedSkillSource } from "./native-skill-integrity.js";
6
6
  export { ensureNativeSkills } from "./native-skill-install.js";
7
+ // nativeSkillsRoot() follows the same intentional-symlink resolution install uses; if it fails,
8
+ // fall back to the unresolved path so link/shadow reporting stays best-effort instead of throwing.
9
+ async function bestEffortNativeSkillsRoot(root) {
10
+ try {
11
+ return await nativeSkillsRoot(root);
12
+ }
13
+ catch {
14
+ return path.join(root, "skills");
15
+ }
16
+ }
7
17
  export async function describeNativeSkillMutation(root, metadata) {
8
18
  const write = [];
9
19
  const preserve = [];
@@ -21,15 +31,17 @@ export async function describeNativeSkillMutation(root, metadata) {
21
31
  collisions.push(skill.id);
22
32
  }
23
33
  }
34
+ const link = await nativeSkillsRootLink(root);
24
35
  return {
25
36
  path: path.join(root, "skills"),
26
37
  changed: write.length > 0,
27
38
  write,
28
39
  preserve,
29
- collisions
40
+ collisions,
41
+ ...(link === undefined ? {} : { link })
30
42
  };
31
43
  }
32
- export async function inspectNativeSkills(root, metadata) {
44
+ export async function inspectNativeSkills(root, metadata, options = {}) {
33
45
  const present = [];
34
46
  const missing = [];
35
47
  const managed = [];
@@ -88,6 +100,8 @@ export async function inspectNativeSkills(root, metadata) {
88
100
  }
89
101
  }
90
102
  const uniqueInvalid = [...new Set(invalid)];
103
+ const link = await nativeSkillsRootLink(root, options.homeDir);
104
+ const shadowedSkills = await detectShadowedSkills(litOpenCodeRuntimeSkills.map((skill) => skill.id), await bestEffortNativeSkillsRoot(root), options.homeDir, options.workDir);
91
105
  return {
92
106
  path: path.join(root, "skills"),
93
107
  expected: litOpenCodeRuntimeSkills.map((skill) => skill.id),
@@ -100,6 +114,8 @@ export async function inspectNativeSkills(root, metadata) {
100
114
  sourceInvalid,
101
115
  canonicalCacheFiles,
102
116
  dependencies: { "lit-scientific-visualization": inspectScientificVisualizationDependencies() },
117
+ ...(link === undefined ? {} : { link }),
118
+ shadowedSkills,
103
119
  ok: missing.length === 0 && uniqueInvalid.length === 0
104
120
  };
105
121
  }
@@ -167,6 +167,11 @@ export type InstallReport = {
167
167
  readonly write: readonly string[];
168
168
  readonly preserve: readonly string[];
169
169
  readonly collisions: readonly string[];
170
+ readonly link?: {
171
+ readonly path: string;
172
+ readonly target: string;
173
+ readonly gitRepositoryRoot?: string;
174
+ };
170
175
  };
171
176
  readonly hostLimits: {
172
177
  readonly path: string;
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="146" height="20" role="img" aria-label="release: 1.0.5"><title>release: 1.0.5</title><g shape-rendering="crispEdges"><rect width="49" height="20" fill="#080d14"/><rect x="49" width="97" height="20" fill="#ff6337"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text x="255" y="140" textLength="390" transform="scale(.1)">release</text><text x="965" y="140" textLength="870" transform="scale(.1)" fill="#080D14">1.0.5</text></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="146" height="20" role="img" aria-label="release: 1.0.6"><title>release: 1.0.6</title><g shape-rendering="crispEdges"><rect width="49" height="20" fill="#080d14"/><rect x="49" width="97" height="20" fill="#ff6337"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text x="255" y="140" textLength="390" transform="scale(.1)">release</text><text x="965" y="140" textLength="870" transform="scale(.1)" fill="#080D14">1.0.6</text></g></svg>
@@ -319,6 +319,28 @@ wrapper 이전에는 보관 사본이 필요하지 않습니다. 교체나 안
319
319
  이 검사는 일반적인 사용과 감지한 경로 변경을 다루며, 적대적인 동시 파일 변경까지
320
320
  막는다는 보장은 아닙니다.
321
321
 
322
+ ## 심볼릭 링크된 native 스킬 루트와 다른 위치의 같은 이름 스킬
323
+
324
+ Install은 `<root>/skills`가 심볼릭 링크여도(예: `~/.config/opencode/skills`가 다른
325
+ 디렉토리를 가리키는 경우) 의도적으로 그 링크를 따라가며, 이 경우에도 설치는
326
+ 성공합니다. `install`과 `doctor` 모두 이제 이 링크를 보고하므로 조용히 다른 곳에
327
+ 쓰는 일이 없습니다: 링크 경로, 실제로 해석된 대상 경로, 그리고 그 대상이 git
328
+ 작업 트리 안에 있다면 저장소 루트까지 알려줍니다. 관리 대상 스킬 디렉토리가 그
329
+ 저장소 안에 나타나기 때문입니다. 스킬 디렉토리가 개인 git 저장소를 가리키는
330
+ 사용자라면 설치 후 그 저장소 안에 수십 개의 새 디렉토리가 생기는 것을 예상해야
331
+ 합니다. 이 경고는 설치 실패가 아니라 링크를 다시 정리하라는 안내로 받아들이세요.
332
+
333
+ `doctor`는 이에 더해 `install.nativeSkills.shadowedSkills`를 보고합니다. 관리 대상
334
+ 스킬 id마다, OpenCode가 함께 읽는 다른 스킬 루트에 같은 이름의 `<id>/SKILL.md`
335
+ 사본이 있는지 확인합니다 — 사용자 수준의 `~/.agents/skills`, `~/.claude/skills`,
336
+ 그리고 현재 작업 디렉토리 기준 프로젝트 수준의 `.opencode/skills`, `.claude/skills`,
337
+ `.agents/skills`가 대상입니다. OpenCode는 둘 중 어느 사본이든 불러올 수 있으며, 이
338
+ 문서는 어느 쪽이 우선하는지 단정하지 않습니다. 해석한 경로가 관리 대상 native
339
+ 스킬 루트와 같으면 같은 트리이므로 shadow로 표시하지 않고 제외합니다. Shadow
340
+ 표시는 안내용이며 `nativeSkills.ok`나 doctor 전체의 `install.ok`를 바꾸지 않습니다.
341
+ 보고된 shadow를 해결하려면 관리되지 않는 사본을 지우거나 이름을 바꾸세요. 그대로
342
+ 두면 OpenCode가 LitOpenCode가 관리하는 사본 대신 그 사본을 불러올 수 있습니다.
343
+
322
344
  ## 디자인 제작과 README
323
345
 
324
346
  OpenCode 네이티브 스킬 `frontend-ui-ux`는 충분한 구현 요청을 받으면 작업 화면을 만들고 렌더링을 확인합니다. 중요한 방향이 모호할 때만 질문하며 답변을 보존합니다. 검토·계획 요청은 읽기 전용입니다.
package/docs/reference.md CHANGED
@@ -414,6 +414,27 @@ need no retained backup. If replacement or safe rollback fails, preserve the rep
414
414
  recovery paths and inspect them; do not assume installation succeeded. These checks
415
415
  cover ordinary use and detected path changes, not hostile concurrent filesystem mutation.
416
416
 
417
+ ## Symlinked native skills root and shadow copies
418
+
419
+ Install intentionally follows a symlinked `<root>/skills` (for example, when a host's
420
+ `~/.config/opencode/skills` is a symlink into another directory) and still succeeds. Both
421
+ `install` and `doctor` now report the link so that is never a silent write: the report
422
+ names the link path, its resolved target, and, if that target sits inside a git work
423
+ tree, the repository root, because managed skill directories will appear inside that
424
+ repository. A user whose skills directory points at a personal git repo should expect to
425
+ see dozens of new directories appear there after install; treat the warning as a prompt
426
+ to redirect the link, not as an install failure.
427
+
428
+ `doctor` additionally lists `install.nativeSkills.shadowedSkills`: for each managed skill
429
+ id, other skill roots OpenCode also reads that contain a same-named `<id>/SKILL.md`
430
+ copy — user-level `~/.agents/skills` and `~/.claude/skills`, and project-level
431
+ `.opencode/skills`, `.claude/skills`, and `.agents/skills` under the working directory.
432
+ OpenCode can load either copy; which one wins is not asserted here. A root whose
433
+ resolved path is identical to the managed native skills root is the same tree, not a
434
+ shadow, and is excluded. Shadowing is informational: it never flips `nativeSkills.ok` or
435
+ doctor's overall `install.ok`. To resolve a reported shadow, remove or rename the
436
+ unmanaged copy, or accept that OpenCode may prefer it over the LitOpenCode-managed one.
437
+
417
438
  ## Design production and README Studio
418
439
 
419
440
  The native `frontend-ui-ux` skill takes an adequate authorized build request through working implementation and rendered inspection. It asks only material design choices and retains answers; review and plan requests remain read-only.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litfamily/litopencode",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "LitOpenCode OpenCode plugin bootstrap package.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -34,7 +34,7 @@ Inspect only the task surface and selected skill resources; do not scout harness
34
34
  ## #contract.procedure
35
35
 
36
36
  1. Record a short direction and finite route/state/viewport/theme/input inventory before coding. Reuse existing primitives; explicit user direction wins. Otherwise load `references/production.md` and `references/default-editorial-pixel.json` for the authored default.
37
- 2. Resolve material ambiguity via `references/production.md`: ask one high-impact choice per turn, retain prior answers, and continue only for unresolved choices. For a bounded brief, state the default and build. Action intent is not delegated choice; no routine re-approval.
37
+ 2. Resolve material ambiguity via `references/production.md`: ask one high-impact choice per turn, retain prior answers, and continue only for unresolved choices. Open competing directions: ask before choosing. For a bounded brief, state the default and build. Action intent is not delegated choice; no routine re-approval.
38
38
  3. Evolve `litfamily.design-contract/v1beta2` alongside implementation. Validate before acceptance; a full schema is not a prerequisite to begin a sufficiently specified build. Keep prior rationale when answers change.
39
39
  4. Implement real actions, keyboard/focus, loading/empty/error/recovery states, Korean/Latin readability, contrast and reduced motion. Label-only success is not an action. Inspect 320/390/1440px and verify hidden-state toggles in a browser.
40
40
  5. Capture the running surface through an available authorized driver. Tests and markup cannot establish visual quality. Separate local inspection from the independent `visual-qa` verdict.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Use this authored reference for production and interview decisions; canonical library text remains inert. Start by reading the source and current brief. Record purpose, audience, target, constraints, each answer across rounds, and unresolved choices in a short authorized project note. There is no mandatory interview: a sufficient brief permits the requested build now.
4
4
 
5
- Ask only when at least two plausible answers would materially change scope, architecture, permissions or data behavior, accessibility, or visual direction. Ask one high-impact question per user turn, state the consequence of each choice, then wait before selecting or editing. After each reply, retain the answer alongside earlier answers, update the unresolved-choice note, and ask only the next material question. Continue for as many rounds as materially necessary while an important choice remains open; never re-ask a settled choice, including in new wording. On resume, read the note before deciding whether to ask again. For a bounded brief, state the default direction and continue without an interview or routine approval. Review-only and plan-only requests remain read-only; a keyword or bare target does not authorize edits. Standalone deep-interview's planning-only handoff does not govern this build workflow.
5
+ Ask only when at least two plausible answers would materially change scope, architecture, permissions or data behavior, accessibility, or visual direction. Ask one high-impact question per user turn, state the consequence of each choice, then wait before selecting or editing. After each reply, retain the answer alongside earlier answers, update the unresolved-choice note, and ask only the next material question. Continue for as many rounds as materially necessary while an important choice remains open; never re-ask a settled choice, including in new wording. On resume, read the note before deciding whether to ask again. When a brief names competing visual directions and leaves them undecided, that axis stays unresolved even if the brief calls every option acceptable: acceptance is not a selection or a delegation. Give it its own round once higher-impact choices are answered; you may recommend one option inside the question, but do not announce a default for it or implement before the user picks. A default applies only to choices the brief settles, choices it delegates ("your call", "pick one"), and details that do not materially change the result. A brief with no visual direction at all is not an open choice: apply the authored pixel profile without asking. For a bounded brief, state the default direction and continue without an interview or routine approval. Review-only and plan-only requests remain read-only; a keyword or bare target does not authorize edits. Standalone deep-interview's planning-only handoff does not govern this build workflow.
6
6
 
7
7
  The default is an original editorial/pixel composition: large headlines with intentional line breaks, small terminal labels, generous section gaps, fine rules, atmospheric color fields and asymmetric focal placement. Pixel imagery must contain visibly discrete grid-aligned cells, limited palette and intentional silhouettes. Smooth vector decoration alone is not the pixel component. Never name or imitate a reference brand, copy its prose or acquire its proprietary fonts/assets. Existing brand constraints override these defaults.
8
8
 
@@ -789,7 +789,7 @@
789
789
  },
790
790
  {
791
791
  "path": "references/production.md",
792
- "sha256": "23d7210027848acc8f9fdeacd8f994ba1d4533d66fc707db689ec4ae90d5c5f1"
792
+ "sha256": "467a9e54c4f9c9dd18e03144b34f576249c2a85086065819191d119955114e23"
793
793
  },
794
794
  {
795
795
  "path": "references/redesign-playbook.md",
@@ -1388,7 +1388,7 @@
1388
1388
  },
1389
1389
  {
1390
1390
  "path": "references/production.md",
1391
- "sha256": "375af9d6637322cebfb065d7ca86ebe79abc242d5aa7a2389a2b95cbf5ca4e4b"
1391
+ "sha256": "4a4a813c80825ad039d4d4aaead8a0d45483f73b8e7d0b2978a0aa0b890b3d0a"
1392
1392
  },
1393
1393
  {
1394
1394
  "path": "references/typography.md",
@@ -4,7 +4,7 @@ Find the real package root, including monorepo boundaries. Read package metadata
4
4
 
5
5
  The `scripts/check-facts.mjs` helper is read-only. It rejects unknown fields, duplicate claim ids, empty sources, escaping/symlink/missing source paths and malformed badge URLs. Its success is only structure/path validation. Manually compare each claim to source content and each badge to its real status endpoint. Omit uncertain popularity, coverage, affiliation and supported-platform assertions. Do not invent a badge URL; a syntactically valid URL does not establish that it exists.
6
6
 
7
- First read the brief, current README, project identity and supplied assets. No interview is mandatory. Ask only when at least two plausible answers would materially change README scope or structure, architecture, permissions or data behavior, accessibility, or visual direction. For those choices, ask one high-impact question per user turn, state the consequence, and wait before choosing or editing. Retain every answer in a task-local decision note across rounds; after each reply, ask only about an unresolved material choice. Continue for as many rounds as materially necessary, then proceed without repeated approval. Never re-ask a settled choice, including in new wording; read the note on resume. For a bounded brief, state the default direction and continue. Review-only and plan-only requests remain read-only; a keyword or bare repository name does not authorize writes.
7
+ First read the brief, current README, project identity and supplied assets. No interview is mandatory. Ask only when at least two plausible answers would materially change README scope or structure, architecture, permissions or data behavior, accessibility, or visual direction. For those choices, ask one high-impact question per user turn, state the consequence, and wait before choosing or editing. Retain every answer in a task-local decision note across rounds; after each reply, ask only about an unresolved material choice. Continue for as many rounds as materially necessary, then proceed without repeated approval. Never re-ask a settled choice, including in new wording; read the note on resume. When a brief names competing visual directions and leaves them undecided, that axis stays unresolved even if the brief calls every option acceptable: acceptance is not a selection or a delegation. Give it its own round once higher-impact choices are answered; you may recommend one option inside the question, but do not announce a default for it or implement before the user picks. A default applies only to choices the brief settles, choices it delegates ("your call", "pick one"), and details that do not materially change the result. A brief with no visual direction at all is not an open choice: apply the default cover direction without asking. For a bounded brief, state the default direction and continue. Review-only and plan-only requests remain read-only; a keyword or bare repository name does not authorize writes.
8
8
 
9
9
  Choose alignment (left/center), tone and theme from the project's identity or the user's direction. A useful reading order is one distinctive cover, small relevant badge/logo row, purpose in plain text, copyable quick start, features or real demo, and navigation for longer documentation. Keep emoji restrained. Preserve current anchors and accurate instructions. Do not flatten prose, installation commands or critical instructions into images.
10
10
 
@@ -44,12 +44,6 @@
44
44
  "occurrences": 1,
45
45
  "why": "This package manifest is the source of truth used by the lockstep guard."
46
46
  },
47
- {
48
- "path": "skills/readme-studio/templates/remotion/package-lock.json",
49
- "kind": "derived",
50
- "occurrences": 3,
51
- "why": "The Remotion template lockfile has 3 occurrence(s) of an unrelated dependency version matching this package release by coincidence; it is not release metadata, and the count follows the current package version."
52
- },
53
47
  {
54
48
  "path": "test/docs.test.mjs",
55
49
  "kind": "pinned",