@spectrabrain/eds 0.4.0 → 0.6.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.
- package/AI_CONTEXT.json +2 -2
- package/CHANGELOG.md +16 -0
- package/CONSUMER_AGENT.md +25 -24
- package/FRONTEND_CONVENTIONS.md +1 -1
- package/QUICKSTART.md +4 -4
- package/README.md +5 -4
- package/TAILWIND_V4.md +3 -3
- package/consumer/align-plan.mjs +4 -10
- package/consumer/align.mjs +5 -3
- package/consumer/cli.mjs +6 -6
- package/consumer/css-root.mjs +1 -1
- package/consumer/init.mjs +10 -11
- package/consumer/managed-block.mjs +9 -3
- package/consumer/register-scripts.mjs +39 -37
- package/consumer/sync.mjs +24 -11
- package/consumer/update-agent-context.mjs +2 -2
- package/consumer-postinstall.mjs +73 -15
- package/dist/components/Button/spec.json +1 -1
- package/dist/index.d.mts +6285 -1
- package/dist/index.d.ts +6285 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
package/AI_CONTEXT.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"specifier": "@spectrabrain/eds/CONSUMER_AGENT.md",
|
|
17
17
|
"kind": "setup-contract",
|
|
18
18
|
"required": false,
|
|
19
|
-
"when": "First setup: the consumer AGENTS.md has no <!-- EDS:BEGIN --> block; eds doctor exits 1 or 2, eds sync exits 2, or sync recovery is unclear; EDS
|
|
19
|
+
"when": "First setup: the consumer AGENTS.md has no <!-- EDS:BEGIN --> block; eds doctor exits 1 or 2, eds sync exits 2, or sync recovery is unclear; the EDS version marker is missing or the installed version differs from it; the user asks to reorganize a prototype into the EVA frontend structure (eds align)"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"file": "AI.md",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"specifier": "@spectrabrain/eds/CHANGELOG.md",
|
|
73
73
|
"kind": "changelog",
|
|
74
74
|
"required": false,
|
|
75
|
-
"when": "EDS was upgraded
|
|
75
|
+
"when": "EDS was upgraded, or the AGENTS.md EDS:VERSION marker is missing: read all applicable consumer actions through the installed version"
|
|
76
76
|
}
|
|
77
77
|
],
|
|
78
78
|
"precedence": [
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @spectrabrain/eds
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 458fbde: 소비처 조치: 없습니다.
|
|
8
|
+
|
|
9
|
+
Button 이름 슬롯의 자동완성 응답을 개선하면서 설치된 `lucide-react`의 전체 icon component 이름과 alias 지원을 유지합니다.
|
|
10
|
+
|
|
11
|
+
## 0.5.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 5da0d43: 소비처 조치: `npm install @spectrabrain/eds`로 업데이트합니다. 허용된 postinstall이 첫 sync를 준비하며, EDS 버전 marker가 없거나 설치 버전과 다르면 에이전트가 적용할 changelog 조치를 읽고 UI 작업 시작에 `sync:eds`를 실행합니다. 최종 검증 뒤 커밋 직전에 `eds:doctor`를 실행해 `[EDS] synced with` 줄을 확인합니다.
|
|
16
|
+
|
|
17
|
+
Doctor는 `typecheck`·`build`에서 자동 실행하지 않습니다. `init`·sync·postinstall은 이전 EDS가 등록한 Doctor lifecycle hook과 typecheck·build 명령의 Doctor 접두를 정리합니다.
|
|
18
|
+
|
|
3
19
|
## 0.4.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/CONSUMER_AGENT.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
`npm run sync:eds`는 sync를 실행한 package 디렉터리(`package.json`이 있는 곳)의 `AGENTS.md`에 managed block을 관리합니다.
|
|
8
8
|
|
|
9
9
|
- 파일이 없으면 만들고, block이 없으면 끝에 추가하며, 있으면 같은 위치에서 갱신합니다. marker 밖의 내용은 보존합니다.
|
|
10
|
-
- BEGIN marker 바로 뒤에 설치 버전(`<!-- EDS:VERSION x.y.z -->`)을
|
|
10
|
+
- BEGIN marker 바로 뒤에 설치 버전(`<!-- EDS:VERSION x.y.z -->`)을 기록하고, 해당 package에서 실행 가능한 sync·doctor 명령을 기록합니다. script가 아직 없거나 소비처 소유 script와 충돌하면 CLI 명령을 씁니다.
|
|
11
11
|
- marker가 중복되거나 한쪽만 있으면 파일을 쓰지 않고 실패합니다.
|
|
12
12
|
|
|
13
13
|
```md
|
|
@@ -16,13 +16,14 @@
|
|
|
16
16
|
## EVA Design System 사용 규칙
|
|
17
17
|
|
|
18
18
|
- UI 작업 전에 EDS package root(`require.resolve("@spectrabrain/eds/package.json")`의 디렉터리, 보통 `node_modules/@spectrabrain/eds`)의 `QUICKSTART.md`를 읽고 규칙과 완료 기준을 따릅니다. 조건별 문서는 `AI_CONTEXT.json`의 `readOrder`를 따릅니다.
|
|
19
|
-
-
|
|
20
|
-
-
|
|
19
|
+
- 첫 편집 전에 이 `AGENTS.md`가 있는 디렉터리에서 `npm run sync:eds`를 한 번 실행합니다. sync는 설치 버전과 managed block·생성 파일을 비교해 필요한 파일만 갱신하며, 차이가 없으면 `Already synced`를 출력합니다. 설치 버전이 marker보다 높으면 먼저 해당 버전의 `CHANGELOG.md` 소비처 조치를 읽고 적용합니다. 작업 중 EDS를 설치하거나 업데이트하면 변경 내역을 읽고 다시 실행합니다. typecheck·build 앞에는 실행하지 않습니다.
|
|
20
|
+
- 검증이 끝난 뒤 커밋 직전에 `npm run eds:doctor`를 실행해 `[EDS] synced with` 줄을 확인합니다. 기존 pre-commit hook이 이미 같은 점검을 실행하면 그 결과를 확인하고, 그렇지 않으면 에이전트가 직접 실행합니다. EDS는 typecheck·build lifecycle hook을 등록하지 않습니다.
|
|
21
|
+
- UI 작업의 완료 보고에 변경 파일, 사용한 EDS component·token, typecheck·build 결과와 커밋 전 doctor 결과를 적습니다.
|
|
21
22
|
- 이 block은 `npm run sync:eds`가 다시 씁니다. 소비처 규칙은 block 밖에 적습니다.
|
|
22
23
|
<!-- EDS:END -->
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
첫 설치 postinstall은 직접 설치된 앱에서 scripts와 첫 sync를 수행해 block을 만들 수 있습니다. EDS 버전이 기존 marker와 다르거나 기존 block에 marker가 없으면 postinstall이 block과 파일을 갱신하지 않습니다. 에이전트가 marker가 없을 때는 설치 버전까지의 적용 가능한 changelog 조치를, 버전이 다를 때는 이전 marker 이후의 조치를 읽은 뒤 다음 UI 작업 시작에 sync합니다. 소비처 담당자는 생성된 변경을 저장소의 기존 규칙과 함께 검토합니다.
|
|
26
27
|
|
|
27
28
|
block이 전달되는 지시 파일은 도구마다 다릅니다.
|
|
28
29
|
|
|
@@ -34,15 +35,15 @@ sync와 doctor는 Claude·Gemini 지시 파일이 없거나, `CLAUDE.local.md`
|
|
|
34
35
|
|
|
35
36
|
## 첫 setup 절차
|
|
36
37
|
|
|
37
|
-
소비처
|
|
38
|
+
소비처 담당자는 앱 package에 EDS를 설치하면 됩니다. 직접 앱에서 dependency lifecycle script가 허용되면 postinstall이 scripts와 첫 sync를 준비합니다. pnpm postinstall은 `package.json` script를 수정하지 않으며, 첫 UI 작업 sync가 이를 등록합니다. workspace root나 lifecycle script가 실행되지 않은 경우에는 에이전트가 EDS dependency를 선언한 앱 package에서 `init`을 실행합니다(`npx @spectrabrain/eds init`, `pnpm exec eds init`, `yarn eds init`, `bunx @spectrabrain/eds init`). 이때도 소비처 담당자가 `sync:eds`를 직접 실행할 필요는 없습니다. `init`은 현재 `package.json`이 `@spectrabrain/eds`를 선언하지 않으면 아무것도 쓰지 않고 exit 2로 끝납니다.
|
|
38
39
|
|
|
39
|
-
| 패키지 매니저 |
|
|
40
|
-
| --------------------------------------------------------------------- |
|
|
41
|
-
| npm | `npm install @spectrabrain/eds
|
|
42
|
-
| pnpm | `pnpm add @spectrabrain/eds
|
|
43
|
-
| yarn berry(`.yarnrc.yml`이 있거나 `yarn.lock`이 `__metadata:`로 시작) | `yarn add @spectrabrain/eds
|
|
44
|
-
| yarn classic | `yarn add @spectrabrain/eds
|
|
45
|
-
| bun | `bun add @spectrabrain/eds
|
|
40
|
+
| 패키지 매니저 | 소비처가 실행하는 설치 명령 | 설치 후 자동 동작과 에이전트 초기화 |
|
|
41
|
+
| --------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
42
|
+
| npm | `npm install @spectrabrain/eds` | 허용된 postinstall이 scripts와 첫 sync를 준비합니다. npm 12 이상은 `allowScripts["@spectrabrain/eds"]: true`(이름만, 버전 pin 없음)가 필요할 수 있으며, `init`이 이 설정을 기록합니다. `--no-allow-scripts`로 건너뜁니다. |
|
|
43
|
+
| pnpm | `pnpm add @spectrabrain/eds` | 허용된 postinstall은 소비처 파일을 sync하지만 script 등록은 보류합니다. 첫 UI 작업의 `pnpm exec eds sync`가 scripts를 등록합니다. |
|
|
44
|
+
| yarn berry(`.yarnrc.yml`이 있거나 `yarn.lock`이 `__metadata:`로 시작) | `yarn add @spectrabrain/eds` | dependency script가 허용된 경우 postinstall이 동작합니다. `enableScripts`·`dependenciesMeta` 승인은 사용자가 결정합니다. 실행되지 않으면 에이전트가 `yarn eds init`을 사용합니다. |
|
|
45
|
+
| yarn classic | `yarn add @spectrabrain/eds` | dependency script가 허용된 경우 postinstall이 동작합니다. 실행되지 않으면 에이전트가 `yarn eds init`을 사용합니다. |
|
|
46
|
+
| bun | `bun add @spectrabrain/eds` | dependency script가 허용된 경우 postinstall이 동작합니다. 실행되지 않으면 에이전트가 `bunx @spectrabrain/eds init`을 사용합니다. `trustedDependencies` 승인은 사용자가 결정합니다. |
|
|
46
47
|
|
|
47
48
|
yarn berry의 기본 Plug'n'Play 설치에는 `node_modules/@spectrabrain/eds`가 없으며 지원 여부는 아직 확인되지 않았습니다. sync와 doctor는 `.pnp.cjs`를 발견하면 `note:`로 알리며, 이때 `nodeLinker`를 바꾸기 전에 저장소 담당자에게 확인합니다.
|
|
48
49
|
|
|
@@ -59,27 +60,27 @@ EDS CLI는 가장 가까운 lockfile(현재 디렉터리부터 git 루트까지)
|
|
|
59
60
|
}
|
|
60
61
|
```
|
|
61
62
|
|
|
62
|
-
- `sync:eds`·`eds:doctor`가 없으면 등록합니다. 같은 이름의 script가 `eds sync`·`eds doctor`를 포함하면(예: `EDS_DOCTOR=warn eds doctor`) 그대로 두고, 다른 명령이면 덮어쓰지 않고 안내만 출력하며 `eds doctor`가 `scripts:` 항목으로 보고합니다. 이전 EDS 버전이 등록한 알려진 명령은 새 명령으로 바꿉니다.
|
|
63
|
-
-
|
|
64
|
-
-
|
|
63
|
+
- `sync:eds`·`eds:doctor`가 없으면 `init`·sync·postinstall이 등록합니다. 같은 이름의 script가 `eds sync`·`eds doctor`를 포함하면(예: `EDS_DOCTOR=warn eds doctor`) 그대로 두고, 다른 명령이면 덮어쓰지 않고 안내만 출력하며 `eds doctor`가 `scripts:` 항목으로 보고합니다. 이전 EDS 버전이 등록한 알려진 명령은 새 명령으로 바꿉니다.
|
|
64
|
+
- `init`·sync·postinstall은 Doctor를 typecheck·build lifecycle에 등록하지 않습니다. 이전 EDS가 만든 `pretypecheck`·`prebuild: "eds doctor"`를 제거하고, typecheck·build 또는 해당 pre-hook이 `eds doctor && <기존 명령>`으로 시작하면 Doctor 접두만 제거해 기존 명령을 보존합니다.
|
|
65
|
+
- postinstall은 직접 설치된 앱에서 `sync:eds`·`eds:doctor`를 등록하고 첫 설치 sync로 managed block·생성 CSS·Tailwind import를 준비합니다. 기존 marker와 설치 버전이 다르거나 기존 block에 marker가 없으면 changelog 조치를 보존하기 위해 파일 sync를 미루고 script 정리만 합니다. 소비처 `package.json`에 `workspaces`가 있으면 루트가 앱인지 단정할 수 없어 건너뜁니다. pnpm은 lifecycle 중 `package.json` 편집을 버리므로 파일만 sync하고, 첫 UI 작업의 `pnpm exec eds sync`에서 scripts를 등록합니다.
|
|
65
66
|
- `--no-sync`는 script만 등록하고(npm 12 이상은 `allowScripts`도 기록) sync는 실행하지 않습니다(`npx @spectrabrain/eds init --no-sync`).
|
|
66
67
|
- `init --print-ci github` 또는 `--print-ci gitlab`(예: `npx @spectrabrain/eds init --print-ci github`)은 이 저장소의 패키지 매니저로 install과 `eds doctor`를 실행하는 CI job snippet을 출력합니다. 저장소 루트가 EDS package이면 그대로 붙입니다. workspace package에서는 GitHub Actions의 `working-directory`를 지정하거나 GitLab의 install·doctor 명령 앞에 `cd <앱 package 경로> &&`를 붙입니다. 출력 snippet에는 이 경로가 포함되지 않습니다.
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
에이전트는 첫 편집 전에 한 번 sync하고, 이후 UI 작업 시작과 EDS 설치·업데이트 뒤에도 sync합니다. marker와 생성물이 최신이면 sync는 `Already synced`로 끝납니다. typecheck·build는 Doctor를 실행하지 않습니다. Doctor는 최종 검증 뒤 커밋 직전에 실행하며, 기존 pre-commit hook이 같은 점검을 이미 실행하면 그 결과를 확인하고 그렇지 않으면 에이전트가 직접 실행합니다. 새 hook manager는 설치하지 않습니다. 담당자가 첫 sync 전에 `CLAUDE.md`·`AGENTS.md`에 넣은 EDS 안내 줄(`README.md` 「설치」)이 남아 있으면 block과 겹치므로 지웁니다. 같은 이름의 다른 script를 바꾸거나 marker 밖 기존 내용을 고쳐야 할 때는 쓰기 전에 사용자에게 확인합니다.
|
|
69
70
|
|
|
70
71
|
## Tailwind root 결정
|
|
71
72
|
|
|
72
73
|
`eds sync`와 `eds doctor`는 환경 변수 `EDS_TAILWIND_ROOT`, 소비처 `package.json`의 `eds.tailwindRoot`, 자동 검출 순서로 Tailwind root CSS를 정합니다. 자동 검출은 `@import "tailwindcss"`(`tailwindcss/theme.css`·`tailwindcss/utilities.css`, `@import url("tailwindcss")` 포함)가 있는 CSS 파일 하나를 root로 쓰며, 주석 안의 import와 `node_modules`·`dist`·`build`·`coverage`·`storybook-static`, 점(`.`)으로 시작하는 디렉터리는 제외합니다.
|
|
73
74
|
|
|
74
75
|
- 후보가 2개 이상이면 아무 파일도 쓰지 않고 exit 2로 끝납니다. 사용자에게 root를 확인하고, 후보마다 앱 진입점(예: `src/main.tsx`)이 그 파일을 import하는지 찾아 함께 알립니다.
|
|
75
|
-
- 확인한 root는 `EDS_TAILWIND_ROOT=<root CSS 경로> npm run sync:eds`로 한 번 지정합니다(예: `EDS_TAILWIND_ROOT=src/app/styles/index.css npm run sync:eds`). sync는 이 경로를 소비처 `package.json`의 `"eds": { "tailwindRoot": "…" }`에 저장하므로 이후 doctor·sync
|
|
76
|
+
- 확인한 root는 `EDS_TAILWIND_ROOT=<root CSS 경로> npm run sync:eds`로 한 번 지정합니다(예: `EDS_TAILWIND_ROOT=src/app/styles/index.css npm run sync:eds`). sync는 이 경로를 소비처 `package.json`의 `"eds": { "tailwindRoot": "…" }`에 저장하므로 이후 doctor·sync가 환경 변수 없이 같은 root를 씁니다.
|
|
76
77
|
- `EDS_TAILWIND_ROOT`나 저장된 경로가 없는 파일을 가리키면 exit 2입니다.
|
|
77
78
|
- 후보가 없고 지정도 없으면 Tailwind를 쓰지 않는 저장소로 보고 Tailwind 배선을 건너뜁니다. 이때 sync는 `AGENTS.md` managed block과, 파일이 있을 때 `CLAUDE.md`·`GEMINI.md`의 import만 갱신합니다. doctor는 Tailwind 항목 대신 `note:` 한 줄을 출력하고 EDS font import는 계속 점검합니다. Tailwind를 쓰지 않는 저장소는 앱 진입점(예: `src/main.tsx`)에서 `@spectrabrain/eds/styles.css`를 import합니다.
|
|
78
79
|
- CSS가 `@tailwind` 지시어를 쓰는 Tailwind CSS v3 저장소도 후보가 없는 것으로 보고, sync와 doctor가 `Tailwind CSS v3 detected` note를 출력합니다. 이 저장소에서는 `EDS_TAILWIND_ROOT`를 지정하지 않고(v3 파일을 가리키면 exit 2) 앱 진입점의 `styles.css` import와 `var(--eds-*)`·`cssVar()`를 쓰며, Tailwind CSS v4 업그레이드는 사용자에게 확인한 뒤 진행합니다.
|
|
79
80
|
|
|
80
81
|
## sync가 쓰는 파일
|
|
81
82
|
|
|
82
|
-
sync는
|
|
83
|
+
전체 sync는 `sync:eds`·`eds:doctor` script가 빠졌으면 등록하고, 이전 EDS Doctor lifecycle hook과 typecheck·build 접두를 정리합니다. 소비처가 덧붙인 접미 명령은 보존합니다. `--only` sync는 지정한 대상만 동기화하며 script 등록과 Doctor 정리는 하지 않습니다. 파일 변경은 모두 먼저 계산하고, 계산 중 하나라도 실패하면 어떤 파일도 바꾸지 않습니다. 쓰는 파일은 다음과 같습니다.
|
|
83
84
|
|
|
84
85
|
1. `src/styles/eds-tokens.css`를 생성하고, Tailwind root의 마지막 Tailwind import 바로 다음 줄에 `@import "@spectrabrain/eds/styles.css";`와 생성 CSS의 상대 경로 `@import`를 추가합니다. 이미 있는 import는 다시 추가하지 않습니다. 생성 CSS의 `@theme inline`에는 공개 color alias와 `--font-sans: var(--eds-typography-body1-fontFamily);`가 들어갑니다. Typography utility도 함께 생성됩니다. root CSS 예시는 `TAILWIND_V4.md`에 있습니다.
|
|
85
86
|
2. `src/` 아래 JS·TS 파일에서 `eds-tokens.css`를 import하는 줄을 제거합니다. Tailwind는 JS에서 import한 CSS를 compile하지 않기 때문입니다.
|
|
@@ -88,7 +89,7 @@ sync는 모든 변경을 먼저 계산하고, 계산 중 하나라도 실패하
|
|
|
88
89
|
|
|
89
90
|
`@spectrabrain/eds/styles.css`는 CSS나 JS·TS 소스가 이미 import하고 있으면 다시 추가하지 않습니다. `tokens.css`·`components.css`·`fonts.css`가 모두 import되어 있어도 같으며, `tokens.css`와 `components.css`만 있고 `fonts.css`가 없으면 root에 `@import "@spectrabrain/eds/fonts.css";`를 추가합니다.
|
|
90
91
|
|
|
91
|
-
`npm run sync:eds -- --only tailwind`와 `npm run sync:eds -- --only agents`는 해당 부분만
|
|
92
|
+
`npm run sync:eds -- --only tailwind`와 `npm run sync:eds -- --only agents`는 해당 부분만 동기화하며 script 등록과 Doctor 정리는 하지 않습니다. `--dry-run`은 변경할 `package.json` script와 파일 경로를 출력하고 파일은 쓰지 않습니다. 두 옵션을 써도 Tailwind root 판정과 marker 검사는 모두 수행하므로, root 후보가 2개 이상이면 `--only agents`도 exit 2로 끝납니다. 파일을 쓴 sync는 쓴 파일을 `[EDS] wrote <경로>` 줄로 나열한 뒤 커밋 전에 doctor를 실행하라는 줄로 끝나고, 바꿀 것이 없으면 `Already synced`로 끝납니다.
|
|
92
93
|
|
|
93
94
|
## font 정책
|
|
94
95
|
|
|
@@ -100,9 +101,9 @@ EDS text style은 font family `Pretendard`를 참조하며, 이 family는 `@spec
|
|
|
100
101
|
|
|
101
102
|
`eds doctor`는 `@spectrabrain/eds/styles.css`와 `@spectrabrain/eds/fonts.css`가 CSS·JS·TS 어디에서도 import되지 않으면 `missing:`으로 보고합니다. HTML·CSS에서 EDS import 밖에 `Pretendard`를 언급하는 줄이 있으면 `note:`를 출력하며, 이 줄은 exit code에 영향을 주지 않습니다.
|
|
102
103
|
|
|
103
|
-
## `eds:doctor` 점검
|
|
104
|
+
## 커밋 전 `eds:doctor` 점검
|
|
104
105
|
|
|
105
|
-
`npm run eds:doctor`는 파일을 쓰지 않고 sync 상태, `sync:eds`·`eds:doctor` 등록, EDS font import를 점검합니다. Tailwind CSS v4 root가 있으면 소스의 `eds-*` class 이름도 확인합니다.
|
|
106
|
+
`npm run eds:doctor`는 파일을 쓰지 않고 sync 상태, `sync:eds`·`eds:doctor` 등록, EDS font import를 점검합니다. Tailwind CSS v4 root가 있으면 소스의 `eds-*` class 이름도 확인합니다. typecheck·build 명령에는 연결하지 않으며, 에이전트가 최종 검증을 마친 뒤 커밋 직전에 실행합니다. 기존 pre-commit hook이 Doctor를 실행하면 그 결과를 확인하고, 그렇지 않으면 에이전트가 직접 한 번 실행합니다. `init`·postinstall은 Git hook manager를 설치하거나 만들지 않습니다. `init --print-ci`가 출력하는 CI job은 별도 안전망입니다.
|
|
106
107
|
|
|
107
108
|
| exit | 의미 |
|
|
108
109
|
| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -120,7 +121,7 @@ EDS text style은 font family `Pretendard`를 참조하며, 이 family는 `@spec
|
|
|
120
121
|
| `unknown: <파일:줄> <class>` | 공개 token이 없는 `eds-*` class입니다. Tailwind는 이런 class를 조용히 버리므로 `src/styles/eds-tokens.css`에 있는 class로 고칩니다. EDS class는 color token의 `<utility>-eds-<이름>`과 typography utility `eds-typography-<style>`입니다. padding·margin·gap·radius에는 Tailwind CSS v4 기본 utility를 씁니다. |
|
|
121
122
|
| `invalid:` | `AGENTS.md`의 EDS marker가 중복되거나 한쪽만 있습니다. sync는 이 상태를 고치지 않습니다. 출력에 적힌 줄에서 BEGIN 한 줄과 그 뒤의 END 한 줄만 남기고 나머지 marker 줄을 지운 뒤 sync를 다시 실행합니다. |
|
|
122
123
|
|
|
123
|
-
`npm run eds:doctor -- --warn`과 `EDS_DOCTOR=warn`은 같은 출력에 warn mode 경고를 더하고 exit 0으로 끝나며, `EDS_DOCTOR=off`는 출력 없이 exit 0으로 끝납니다. 이 설정은
|
|
124
|
+
`npm run eds:doctor -- --warn`과 `EDS_DOCTOR=warn`은 같은 출력에 warn mode 경고를 더하고 exit 0으로 끝나며, `EDS_DOCTOR=off`는 출력 없이 exit 0으로 끝납니다. 이 설정은 로컬 진단에만 사용하며, 이 상태의 exit 0은 완료가 아닙니다.
|
|
124
125
|
|
|
125
126
|
`npm run eds:doctor -- --scan`은 Tailwind 기본 팔레트(`text-red-500`), `white`·`black`, 임의 색(`bg-[#…]`) class를 `raw: <파일:줄> <class>` 줄로 나열합니다. 정보 제공용이라 exit code를 바꾸지 않습니다. `unknown:`과 `raw:` 검사는 Tailwind CSS v4 root가 있는 저장소에서 Tailwind class만 봅니다. CSS·inline style의 `var(--eds-*)` 참조는 검사하지 않습니다.
|
|
126
127
|
|
|
@@ -156,7 +157,7 @@ EDS 버전을 올렸으면 다음 순서로 진행합니다.
|
|
|
156
157
|
|
|
157
158
|
1. sync 전에 `AGENTS.md`의 `<!-- EDS:VERSION x.y.z -->` 줄에서 이전 버전을 확인합니다. 이미 sync했다면 `git diff AGENTS.md`의 삭제된 버전 줄에서 확인합니다.
|
|
158
159
|
2. package root의 `CHANGELOG.md`(`@spectrabrain/eds/CHANGELOG.md`)에서 이전 버전보다 높은 절만 읽고, 각 항목이 요구하는 소비처 조치를 모두 적용합니다. 새 항목은 `소비처 조치:`로 시작합니다.
|
|
159
|
-
3. `npm run sync:eds`로 Tailwind root의 import, 공개 token alias, managed block과 버전 줄을
|
|
160
|
+
3. `npm run sync:eds`로 Tailwind root의 import, 공개 token alias, managed block과 버전 줄을 갱신합니다.
|
|
160
161
|
4. 제거되거나 이름이 바뀐 token은 `CHANGELOG.md`에서 이름을 확인하고, Tailwind class는 doctor의 `unknown:` 항목에서, `cssVar()` 호출은 typecheck 오류에서, CSS·inline style의 `var(--eds-<이름>)`은 `tokens.json`의 `cssVariable` mapping과 대조해 고칩니다. dotted public name은 CSS reference에서만 점을 escape합니다. 새로 쓸 수 있는 class는 `src/styles/eds-tokens.css`의 diff에서 확인합니다.
|
|
161
162
|
|
|
162
|
-
생성 CSS의 header나 `AGENTS.md`의 버전 줄이 설치된 버전과 다르면
|
|
163
|
+
생성 CSS의 header나 `AGENTS.md`의 버전 줄이 설치된 버전과 다르면 sync가 해당 파일을 갱신합니다. 에이전트는 UI 작업을 시작할 때 한 번 sync를 실행하고, `Already synced`이면 추가 파일 변경 없이 진행합니다. sync를 빠뜨린 업데이트는 커밋 전 doctor가 `stale:`로 보고합니다. typecheck·build와 다른 최종 검증을 마친 뒤 doctor를 마지막으로 실행하고, 작업 보고에는 올린 EDS 버전, 적용한 소비처 조치, 바뀐 파일, 새로 쓸 수 있는 class, 제거되거나 이름이 바뀐 공개 token, 검증 결과를 남깁니다.
|
package/FRONTEND_CONVENTIONS.md
CHANGED
|
@@ -244,4 +244,4 @@ export function ConfirmDeleteAccountButton({
|
|
|
244
244
|
|
|
245
245
|
## 점검
|
|
246
246
|
|
|
247
|
-
- 프론트엔드 코드를 바꾼 작업은
|
|
247
|
+
- 프론트엔드 코드를 바꾼 작업은 `format:check`·`lint`·`typecheck`·`build` script와 `npx @spectrabrain/eds align --check`가 모두 exit 0이어야 합니다. Doctor는 이 명령에 연결하지 않고 최종 검증 뒤 커밋 직전에 실행해 `[EDS] synced with` 줄을 확인합니다. `npm run`·`npx`는 저장소의 패키지 매니저 형식(예: `pnpm exec eds align --check`)으로 바꿔 실행합니다. `--check`의 출력 종류와 exit code는 `CONSUMER_AGENT.md` 「프로토타입 정렬」에 있습니다.
|
package/QUICKSTART.md
CHANGED
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
|
|
21
21
|
## 완료 기준
|
|
22
22
|
|
|
23
|
-
1.
|
|
24
|
-
2.
|
|
25
|
-
3. 완료 보고에 변경 파일, EDS component·token, typecheck·build
|
|
23
|
+
1. 있는 `typecheck`·`build` script는 exit 0이어야 합니다. Tailwind CSS v4에서는 `eds:doctor -- --scan`의 `raw:`에 바꾼 파일이 없어야 합니다.
|
|
24
|
+
2. 최종 검증 뒤 커밋 직전에 `npm run eds:doctor`를 실행해 `[EDS] synced with`를 확인합니다. 실패하면 `CONSUMER_AGENT.md` Doctor 표(`unknown:` 포함)의 조치를 따릅니다.
|
|
25
|
+
3. 완료 보고에 변경 파일, EDS component·token, typecheck·build 결과와 doctor 결과를 적습니다. script가 없으면 그렇게 밝힙니다.
|
|
26
26
|
|
|
27
27
|
## 명령
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
직접 앱 설치의 허용된 postinstall은 첫 sync를 준비합니다. 에이전트는 UI 작업 시작에 `npm run sync:eds`를 한 번 실행합니다. marker가 없으면 설치 버전까지, 있으면 marker 이후의 `CHANGELOG.md` 소비처 조치를 적용한 뒤 sync합니다. 최신이면 `Already synced`로 끝납니다. 매 typecheck·build 전에는 실행하지 않습니다. Doctor는 읽기 전용이며 최종 검증 뒤 커밋 직전에만 실행합니다. postinstall이 생략되었거나 workspace root에서 설치했다면 소비 앱에서 패키지 매니저에 맞는 `init`을 실행합니다(`npx @spectrabrain/eds init`, `pnpm exec eds init`, `yarn eds init`, `bunx @spectrabrain/eds init`).
|
|
30
30
|
|
|
31
31
|
## 더 읽을 문서
|
|
32
32
|
|
package/README.md
CHANGED
|
@@ -8,14 +8,15 @@ EVA 서비스의 일관된 UI/UX를 위한 React 웹 디자인 시스템입니
|
|
|
8
8
|
|
|
9
9
|
~~~sh
|
|
10
10
|
npm install @spectrabrain/eds
|
|
11
|
-
npx @spectrabrain/eds init
|
|
12
11
|
~~~
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
허용된 postinstall은 직접 설치된 앱에서 첫 sync를 준비합니다. pnpm은 설치 중 `package.json` 변경을 보존하지 않으므로 script 등록은 첫 UI 작업의 sync로 미룹니다. EDS를 업데이트했을 때 설치 버전과 `AGENTS.md` marker가 다르거나 기존 block에 marker가 없으면 postinstall은 block을 보존해 AI 에이전트가 changelog 조치를 먼저 읽고 다음 UI 작업 시작에 sync하게 합니다. postinstall이 실행되지 않거나 dependency가 workspace root에 hoist된 경우에는 에이전트가 소비 앱에서 `init`으로 setup합니다. 소비처 사용자는 별도로 `sync:eds`를 실행하지 않습니다.
|
|
14
|
+
|
|
15
|
+
AI 에이전트는 UI 작업 시작에 한 번 `sync:eds`를 실행해 설치 버전과 managed block·생성 파일을 맞춥니다. 최신이면 파일을 쓰지 않습니다. Doctor는 typecheck·build에 연결하지 않고, 최종 검증 뒤 커밋 직전에 실행합니다. package manager별 fallback은 [CONSUMER_AGENT.md](CONSUMER_AGENT.md) 「첫 setup 절차」를 따릅니다. `npx`에는 항상 `@spectrabrain/eds`를 적습니다. npm의 unscoped `eds`는 다른 패키지입니다.
|
|
15
16
|
|
|
16
17
|
소비처 AI와 자동화 도구는 UI 작업 전에 [QUICKSTART.md](QUICKSTART.md)를 읽습니다. 나머지 문서는 [AI_CONTEXT.json](AI_CONTEXT.json)의 조건에 해당할 때만 읽습니다.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
postinstall이 실행되지 않은 저장소에서 에이전트가 EDS 지시를 읽지 못하면, 사용하는 도구의 루트 지시 파일에 아래 한 줄을 임시로 넣습니다(Codex는 `AGENTS.md`, Claude Code는 `CLAUDE.md`, Gemini CLI는 `GEMINI.md`). 에이전트가 `init`으로 managed block을 추가하면 임시 줄을 지웁니다.
|
|
19
20
|
|
|
20
21
|
> package.json에 `@spectrabrain/eds`가 있으면 UI 작업 전에 EDS package root의 `QUICKSTART.md`를 읽고 규칙과 완료 기준을 따릅니다. package root는 `require.resolve("@spectrabrain/eds/package.json")`로 찾습니다.
|
|
21
22
|
|
|
@@ -113,7 +114,7 @@ EDS는 Tailwind preset·plugin을 제공하지 않습니다. Tailwind CSS v4 저
|
|
|
113
114
|
| `@spectrabrain/eds/TOKEN_CONTEXT.md` | semantic token의 역할과 화면 맥락입니다. |
|
|
114
115
|
| `@spectrabrain/eds/TAILWIND_V4.md` | Tailwind CSS v4에서 공개 token을 연결하는 설치 가이드입니다. |
|
|
115
116
|
| `@spectrabrain/eds/FRONTEND_CONVENTIONS.md` | EVA 프론트엔드의 구조·라이브러리·코드 패턴·개발 규칙입니다. `eds align`의 기준입니다. |
|
|
116
|
-
| `eds` CLI (`npx @spectrabrain/eds init`) | 소비처 setup CLI입니다. `init`은 기본 script
|
|
117
|
+
| `eds` CLI (`npx @spectrabrain/eds init`) | 소비처 setup CLI입니다. `init`은 기본 script를 등록하고 첫 동기화를 실행합니다. 에이전트는 UI 작업 전에 `sync:eds`를 한 번 실행합니다. `eds:doctor`는 커밋 직전에 동기화 상태와 font import를 읽기 전용 점검하고, Tailwind CSS v4 root가 있으면 `eds-*` class 이름도 확인합니다. `npx @spectrabrain/eds align`은 프로토타입 정렬 계획과 점검을 실행합니다. 모듈로 import하지 않습니다. |
|
|
117
118
|
| `@spectrabrain/eds/components/Button/README.md` | Button 개요·사용 맥락·공개 API 문서입니다. |
|
|
118
119
|
| `@spectrabrain/eds/components/Button/spec.json` | Button 공개 API와 접근성 계약을 위한 manifest입니다. |
|
|
119
120
|
| `@spectrabrain/eds/llms.txt` | AI 문서 읽기 순서입니다. |
|
package/TAILWIND_V4.md
CHANGED
|
@@ -10,7 +10,7 @@ CSS 진입점은 `@spectrabrain/eds/styles.css` 하나를 권장합니다. 개
|
|
|
10
10
|
|
|
11
11
|
1. 「adapter 선택」 표에서 저장소에 맞는 행 하나를 골라 설치하고 연결합니다.
|
|
12
12
|
2. 기존 앱 전역 CSS를 Tailwind root로 씁니다. 전체 import 구성은 `@import "tailwindcss";`를, 분할 구성은 `@import "tailwindcss/theme.css";`와 `@import "tailwindcss/utilities.css";`를 같은 파일에 둡니다.
|
|
13
|
-
3. `npm run sync:eds`를 실행합니다. script가 없으면 `npx @spectrabrain/eds init
|
|
13
|
+
3. 직접 앱 설치에서 허용된 postinstall이 첫 sync를 하지 않았다면 AI 에이전트가 `npm run sync:eds`를 실행합니다. script가 없으면 `CONSUMER_AGENT.md` 「첫 setup 절차」의 `init` 명령(예: `npx @spectrabrain/eds init`)을 사용합니다. EDS 업데이트 뒤에는 changelog 조치를 적용하고 UI 작업 시작에 한 번 sync합니다.
|
|
14
14
|
4. 「완료 기준」을 확인합니다.
|
|
15
15
|
|
|
16
16
|
CSS가 `@tailwind` 지시어를 쓰는 Tailwind CSS v3 저장소는 이 절차 대신 `CONSUMER_AGENT.md` 「Tailwind root 결정」을 따릅니다.
|
|
@@ -82,7 +82,7 @@ sync는 설치된 package의 공개 `@spectrabrain/eds/tokens.json`에서 token
|
|
|
82
82
|
- padding·margin·gap·radius에는 Tailwind CSS v4 기본 utility를 씁니다. 예: `p-4`, `m-2`, `gap-3`, `rounded-lg`. EDS token 별칭은 색상과 typography에만 생성합니다. 선택 기준은 `TOKEN_CONTEXT.md`를 따릅니다.
|
|
83
83
|
- `@theme`의 EDS alias는 sync가 생성한 `var(--eds-*)` 참조만 두고, EDS를 업데이트할 때마다 `npm run sync:eds`로 다시 생성합니다.
|
|
84
84
|
- `eds-tokens.css`는 `@theme`·`@utility`를 담으므로 Tailwind root CSS에서만 import합니다. `@spectrabrain/eds/styles.css`와 `eds-tokens.css`는 각각 한 곳에서만 import합니다.
|
|
85
|
-
- `src/styles/eds-tokens.css`는 생성물이지만 저장소에 commit합니다.
|
|
85
|
+
- `src/styles/eds-tokens.css`는 생성물이지만 저장소에 commit합니다. 설치 postinstall이나 에이전트의 UI 작업 시작 sync가 파일을 만듭니다. 커밋 전 doctor나 `--print-ci` CI job은 파일이 없으면 `missing:`으로 실패합니다. Doctor는 typecheck·build에는 연결되지 않습니다.
|
|
86
86
|
|
|
87
87
|
## Tailwind root 지정
|
|
88
88
|
|
|
@@ -94,7 +94,7 @@ EDS_TAILWIND_ROOT=src/app/styles/index.css npm run sync:eds
|
|
|
94
94
|
|
|
95
95
|
## 완료 기준
|
|
96
96
|
|
|
97
|
-
1. `npm run eds:doctor`가 `[EDS] synced with` 줄을 출력하고, 출력에 `No Tailwind root CSS found`·`Tailwind CSS v3 detected` note가 없습니다.
|
|
97
|
+
1. 커밋 직전 `npm run eds:doctor`가 `[EDS] synced with` 줄을 출력하고, 출력에 `No Tailwind root CSS found`·`Tailwind CSS v3 detected` note가 없습니다.
|
|
98
98
|
2. Vite 저장소는 `vite.config.*`의 `plugins`에 `@tailwindcss/vite`의 `tailwindcss()`가 있고, 그 밖의 저장소는 PostCSS 설정에 `@tailwindcss/postcss`가 있습니다. doctor는 이 연결을 점검하지 않습니다.
|
|
99
99
|
3. `@spectrabrain/eds/styles.css`는 Tailwind root CSS나 앱 진입점 가운데 한 곳에서만 import됩니다.
|
|
100
100
|
|
package/consumer/align-plan.mjs
CHANGED
|
@@ -643,8 +643,6 @@ export function renderPlan({
|
|
|
643
643
|
]),
|
|
644
644
|
"",
|
|
645
645
|
"완료 기준: " +
|
|
646
|
-
code(commands.run("eds:doctor")) +
|
|
647
|
-
"가 `[EDS] synced with` 줄을 출력하고 " +
|
|
648
646
|
code(commands.run("build")) +
|
|
649
647
|
"가 exit 0이며, Vite가 " +
|
|
650
648
|
minimumVersions.vite +
|
|
@@ -692,7 +690,7 @@ export function renderPlan({
|
|
|
692
690
|
" - `components.json`: `aliases`와 `tailwind.css`만 템플릿 값으로 바꾸고 `style`·`baseColor`는 유지합니다.",
|
|
693
691
|
" - `package.json` scripts: `package.scripts.json`에서 없는 script만 추가하고, 추가한 뒤 " +
|
|
694
692
|
code(commands.eds("init --no-sync")) +
|
|
695
|
-
"로 `
|
|
693
|
+
"로 `sync:eds`·`eds:doctor`를 등록합니다. typecheck·build script에는 Doctor를 넣지 않습니다. backend를 실행하는 script는 바꾸지 않습니다.",
|
|
696
694
|
" - 이전 lint·format 설정(`.eslintrc*`, `biome.json`, 중복 Prettier 설정)은 규칙을 옮긴 뒤 정리합니다" +
|
|
697
695
|
(replacedCategories.has("lint-format") ? "(패키지 제거는 4단계)." : ".") +
|
|
698
696
|
" 테스트·mock·다국어 파일과 설정은 그대로 둡니다. 기준선에 있던 항목을 바꾸지 않고 적용할 수 없으면 멈추고 사용자에게 확인합니다.",
|
|
@@ -714,11 +712,8 @@ export function renderPlan({
|
|
|
714
712
|
]
|
|
715
713
|
.map(code)
|
|
716
714
|
.join("·") +
|
|
717
|
-
"가 exit 0입니다. 기존 `build.outDir`·`base`·`server.proxy`가 병합 전과 같고, " +
|
|
718
|
-
|
|
719
|
-
? "`typecheck` script가 `eds doctor && `로 시작하며"
|
|
720
|
-
: "`package.json`의 `pretypecheck`가 `eds doctor`를 실행하며") +
|
|
721
|
-
", 「기준선」에 typecheck·lint 결과가 있습니다.",
|
|
715
|
+
"가 exit 0입니다. 기존 `build.outDir`·`base`·`server.proxy`가 병합 전과 같고, typecheck·build script에는 Doctor를 연결하지 않습니다. " +
|
|
716
|
+
"「기준선」에 typecheck·lint 결과가 있습니다.",
|
|
722
717
|
"",
|
|
723
718
|
"### 4. 라이브러리 정렬",
|
|
724
719
|
"",
|
|
@@ -846,12 +841,11 @@ export function renderPlan({
|
|
|
846
841
|
commands.run("lint"),
|
|
847
842
|
commands.run("typecheck"),
|
|
848
843
|
commands.run("build"),
|
|
849
|
-
commands.run("eds:doctor"),
|
|
850
844
|
alignCheck,
|
|
851
845
|
]
|
|
852
846
|
.map(code)
|
|
853
847
|
.join(", ") +
|
|
854
|
-
"을 실행해 모두 exit 0
|
|
848
|
+
"을 실행해 모두 exit 0인지 확인합니다. Doctor는 커밋 직전에 마지막으로 실행해 " +
|
|
855
849
|
code(commands.run("eds:doctor")) +
|
|
856
850
|
"가 `[EDS] synced with` 줄을 출력하는지 확인합니다.",
|
|
857
851
|
backendImportsViteConfig && backendStartScript !== null
|
package/consumer/align.mjs
CHANGED
|
@@ -375,7 +375,7 @@ function conventionsPathFrom(packageDirectory, gitRoot, packageRoot) {
|
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
function verificationCommands(commands) {
|
|
378
|
-
return ["format:check", "lint", "typecheck", "build"
|
|
378
|
+
return ["format:check", "lint", "typecheck", "build"]
|
|
379
379
|
.map((script) => commands.run(script))
|
|
380
380
|
.join(", ");
|
|
381
381
|
}
|
|
@@ -899,10 +899,12 @@ function runCheck({
|
|
|
899
899
|
log(
|
|
900
900
|
"[EDS] Also required: " +
|
|
901
901
|
verificationCommands(commands) +
|
|
902
|
-
" (each must exit 0
|
|
902
|
+
" (each must exit 0). Before committing, run " +
|
|
903
|
+
commands.run("eds:doctor") +
|
|
904
|
+
" and confirm [EDS] synced with" +
|
|
903
905
|
(state === null
|
|
904
906
|
? "."
|
|
905
|
-
: "
|
|
907
|
+
: ". Then complete step 8 of " +
|
|
906
908
|
shown(alignDirectory + "/" + planFileName) +
|
|
907
909
|
".")
|
|
908
910
|
);
|
package/consumer/cli.mjs
CHANGED
|
@@ -8,9 +8,9 @@ const usage = [
|
|
|
8
8
|
"Usage: eds <command> [options]",
|
|
9
9
|
"",
|
|
10
10
|
"Commands:",
|
|
11
|
-
" init Add sync:eds and eds:doctor when missing;
|
|
12
|
-
"
|
|
13
|
-
" sync
|
|
11
|
+
" init Add sync:eds and eds:doctor when missing; remove obsolete Doctor lifecycle commands;",
|
|
12
|
+
" write allowScripts on npm 12+, then sync in the package declaring @spectrabrain/eds",
|
|
13
|
+
" sync Ensure EDS scripts, remove old Doctor lifecycle commands, wire Tailwind CSS and update AGENTS.md",
|
|
14
14
|
" and the @AGENTS.md import in CLAUDE.md (or .claude/CLAUDE.md) and GEMINI.md when they exist",
|
|
15
15
|
" (without a Tailwind root only those change); notes say when an agent may not load the block",
|
|
16
16
|
" doctor Check sync status and the EDS font import; with a Tailwind CSS v4 root, also check that each eds-*",
|
|
@@ -20,8 +20,8 @@ const usage = [
|
|
|
20
20
|
"",
|
|
21
21
|
"Options:",
|
|
22
22
|
" --only tailwind|agents sync: apply only that part",
|
|
23
|
-
" --dry-run Print
|
|
24
|
-
" --no-sync init: register scripts
|
|
23
|
+
" --dry-run Print files and package scripts sync, init or align would change without writing them",
|
|
24
|
+
" --no-sync init: skip file sync but still register and migrate scripts",
|
|
25
25
|
" --no-allow-scripts init: do not write allowScripts to package.json on npm 12+",
|
|
26
26
|
" --print-ci github|gitlab init: print a CI job that runs eds doctor with this repository's package manager",
|
|
27
27
|
" --warn doctor: report findings but exit 0 (same as EDS_DOCTOR=warn)",
|
|
@@ -33,7 +33,7 @@ const usage = [
|
|
|
33
33
|
"",
|
|
34
34
|
"Environment:",
|
|
35
35
|
" EDS_TAILWIND_ROOT=src/index.css Tailwind root CSS when it cannot be detected (needed once: sync records",
|
|
36
|
-
" it in package.json \"eds\": { \"tailwindRoot\" }, which
|
|
36
|
+
" it in package.json \"eds\": { \"tailwindRoot\" }, which sync and doctor reuse)",
|
|
37
37
|
" EDS_DOCTOR=warn|off Downgrade or silence doctor failures",
|
|
38
38
|
].join("\n");
|
|
39
39
|
|
package/consumer/css-root.mjs
CHANGED
|
@@ -149,7 +149,7 @@ export function findTailwindRoot(
|
|
|
149
149
|
"Could not identify one Tailwind root CSS file (found " + found.length + ": " + found.join(", ") + "). " +
|
|
150
150
|
"Ask the user which of these is the app's Tailwind root, then run " + tailwindRootEnvironmentVariable + "=<that file> " +
|
|
151
151
|
runnerCommand(packageManager, "sync:eds") + " once. sync records the choice in package.json as \"" + consumerConfigField +
|
|
152
|
-
"\": { \"" + tailwindRootConfigKey + "\": \"<that file>\" } so doctor and
|
|
152
|
+
"\": { \"" + tailwindRootConfigKey + "\": \"<that file>\" } so doctor and sync reuse it.",
|
|
153
153
|
2,
|
|
154
154
|
);
|
|
155
155
|
}
|
package/consumer/init.mjs
CHANGED
|
@@ -77,7 +77,7 @@ export function renderCiSnippet(target, packageManager) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// npm 12+ blocks dependency install scripts unless package.json allows them. A name-only entry keeps
|
|
80
|
-
// the EDS postinstall
|
|
80
|
+
// the EDS postinstall available for script maintenance and first-sync bootstrap.
|
|
81
81
|
function writeAllowScripts(consumerRoot, { log, dryRun }) {
|
|
82
82
|
const packagePath = path.join(consumerRoot, "package.json");
|
|
83
83
|
const source = fs.readFileSync(packagePath, "utf8");
|
|
@@ -98,7 +98,7 @@ function writeAllowScripts(consumerRoot, { log, dryRun }) {
|
|
|
98
98
|
}
|
|
99
99
|
consumerPackage[allowScriptsField] = { ...(existing ?? {}), [packageName]: true };
|
|
100
100
|
writeConsumerPackageJson(packagePath, source, consumerPackage);
|
|
101
|
-
log("[EDS] wrote " + allowScriptsField + "[\"" + packageName + "\"] = true to package.json so npm " + minimumAllowScriptsNpmMajor + "+
|
|
101
|
+
log("[EDS] wrote " + allowScriptsField + "[\"" + packageName + "\"] = true to package.json so npm " + minimumAllowScriptsNpmMajor + "+ can run the EDS postinstall on later installs.");
|
|
102
102
|
return true;
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -113,24 +113,23 @@ function printInstallScriptGuidance(consumerRoot, packageManager, { log, dryRun,
|
|
|
113
113
|
}
|
|
114
114
|
} else if (major === null) {
|
|
115
115
|
log("[EDS] The npm version is unknown because init did not run through npm. If this project uses npm " + minimumAllowScriptsNpmMajor +
|
|
116
|
-
"+, run " + approveCommand + ", or rerun " + cliCommand(packageManager, "init") + " so init can
|
|
116
|
+
"+, run " + approveCommand + ", or rerun " + cliCommand(packageManager, "init") + " so init can enable the EDS postinstall.");
|
|
117
117
|
}
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
|
-
//
|
|
121
|
-
// except npm 12+, where init records the approval itself.
|
|
120
|
+
// Install hooks are optional in package managers that require dependency build approval.
|
|
122
121
|
if (name === "pnpm") {
|
|
123
|
-
log("[EDS] pnpm:
|
|
124
|
-
|
|
122
|
+
log("[EDS] pnpm: postinstall can sync EDS files but does not persist package.json script edits. The coding agent registers them with " +
|
|
123
|
+
cliCommand(packageManager, "sync") + " at the start of its next UI task.");
|
|
125
124
|
return;
|
|
126
125
|
}
|
|
127
126
|
if (name === "bun") {
|
|
128
|
-
log("[EDS] Optional (bun): to let the EDS postinstall
|
|
127
|
+
log("[EDS] Optional (bun): to let the EDS postinstall bootstrap files and maintain scripts, add \"trustedDependencies\": [\"" +
|
|
129
128
|
packageName + "\"] to package.json. It replaces bun's default trusted list, so this is the project owner's decision.");
|
|
130
129
|
return;
|
|
131
130
|
}
|
|
132
131
|
if (name === "yarn" && berry) {
|
|
133
|
-
log("[EDS] Optional (Yarn 2+): to let the EDS postinstall
|
|
132
|
+
log("[EDS] Optional (Yarn 2+): to let the EDS postinstall bootstrap files and maintain scripts, keep enableScripts: true in .yarnrc.yml " +
|
|
134
133
|
"or add \"dependenciesMeta\": { \"" + packageName + "\": { \"built\": true } } to package.json.");
|
|
135
134
|
}
|
|
136
135
|
}
|
|
@@ -159,7 +158,7 @@ export function runInit({
|
|
|
159
158
|
1,
|
|
160
159
|
);
|
|
161
160
|
}
|
|
162
|
-
// A workspace root or a parent folder can resolve a hoisted EDS; the scripts
|
|
161
|
+
// A workspace root or a parent folder can resolve a hoisted EDS; the scripts and AGENTS.md belong to the
|
|
163
162
|
// app package that declares it.
|
|
164
163
|
const consumerPackage = readPackageJson(consumerRoot);
|
|
165
164
|
const declared = ["dependencies", "devDependencies", "optionalDependencies"].some((field) => consumerPackage?.[field]?.[packageName] !== undefined);
|
|
@@ -182,5 +181,5 @@ export function runInit({
|
|
|
182
181
|
log("[EDS] Run " + registered.syncRunCommand + " to finish setup.");
|
|
183
182
|
return 0;
|
|
184
183
|
}
|
|
185
|
-
return runSync({ consumerRoot, env, dryRun, log });
|
|
184
|
+
return runSync({ consumerRoot, env, dryRun, ensureScripts: false, log });
|
|
186
185
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { renderRunnerCommands } from "./paths.mjs";
|
|
3
|
+
import { renderRunnerCommands, runnerCommand } from "./paths.mjs";
|
|
4
4
|
|
|
5
5
|
export const beginMarker = "<!-- EDS:BEGIN -->";
|
|
6
6
|
export const endMarker = "<!-- EDS:END -->";
|
|
@@ -21,13 +21,19 @@ export function readTemplateBlock(packageRoot) {
|
|
|
21
21
|
|
|
22
22
|
// The template is written for npm; the rendered block uses the consumer's package-manager runner
|
|
23
23
|
// (pnpm, yarn, bun run) so the commands an agent reads work in that repository.
|
|
24
|
-
export function renderBlock(template, version, packageManager = null) {
|
|
24
|
+
export function renderBlock(template, version, packageManager = null, commands = null) {
|
|
25
25
|
const versionLine = "<!-- EDS:VERSION " + version + " -->";
|
|
26
26
|
const withoutVersion = template.replace(/^<!-- EDS:VERSION \S+ -->\r?\n/m, "");
|
|
27
27
|
if (!withoutVersion.startsWith(beginMarker)) {
|
|
28
28
|
throw new Error("CONSUMER_AGENT.md managed block must start with " + beginMarker + ".");
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
let body = renderRunnerCommands(withoutVersion.slice(beginMarker.length), packageManager);
|
|
31
|
+
if (commands?.sync) {
|
|
32
|
+
body = body.replaceAll(runnerCommand(packageManager, "sync:eds"), commands.sync);
|
|
33
|
+
}
|
|
34
|
+
if (commands?.doctor) {
|
|
35
|
+
body = body.replaceAll(runnerCommand(packageManager, "eds:doctor"), commands.doctor);
|
|
36
|
+
}
|
|
31
37
|
return beginMarker + "\n" + versionLine + body;
|
|
32
38
|
}
|
|
33
39
|
|