@lark-apaas/coding-registry-buildless 0.1.0 → 0.1.2-alpha.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/README.md CHANGED
@@ -4,27 +4,32 @@
4
4
 
5
5
  **buildless 运行时**的 SDK registry(shadcn 式 copy-in 资产的单一事实源)。运行时契约 = *buildless(浏览器 Babel)+ 全局(window/UMD)+ CDN 钉版依赖*;当前由 design-html 栈使用,但本包按**运行时**而非 stack 命名,任何 buildless-globals 栈都可复用。
6
6
 
7
- 被 [miaoda-cli](https://code.byted.org/apaas/miaoda-cli) 的 `miaoda registry` 命令消费:抓本包 tarball → 递归扫含 USAGE 块的 SDK 文件 → 把源码**按目录结构原样拷进**用户项目(项目持有、可改、不覆盖)。
7
+ 被 [miaoda-cli](https://code.byted.org/apaas/miaoda-cli) 的 `miaoda registry` 命令消费:抓本包 tarball → 递归扫白名单目录下的代码文件 → 把源码**拍平为 basename 拷进**用户项目根(项目持有、可改、不覆盖)。
8
8
 
9
9
  **非运行时依赖**:buildless 栈不 `npm install` 本包;它只是个被 CLI 抓取的 catalog,与 template / steering 同分发模型。
10
10
 
11
- ## 结构(内容平铺在包根,拷贝时 1:1 落地)
11
+ ## 结构(包内按目录组织;落地拍平到项目根)
12
+
13
+ 包内 SDK 文件必须放在**白名单顶层目录**下(这是条目门槛之一):
12
14
 
13
15
  ```
14
- scripts/ # 纯 JS / Web Component(如 deck-stage.js) → 项目 scripts/
15
- components/ # React / JSX(如 tweaks-panel.jsx) → 项目 components/
16
- stylesheets/ # CSS(按需) → 项目 stylesheets/
16
+ scripts/ # 纯 JS / Web Component(如 deck-stage.js)
17
+ components/ # React / JSX(如 tweaks-panel.jsx)
18
+ stylesheets/ # CSS(按需)
17
19
  ```
18
20
 
19
- `add` 保留文件相对包根的路径:`scripts/deck-stage.js` → 项目 `scripts/deck-stage.js`。无 `targets` 映射、不拍平。
21
+ `add` **不保留子目录**:所有文件**拍平为 basename 落到项目根**(`scripts/deck-stage.js` → 项目根 `deck-stage.js`)。同名 basename 撞车时后者覆盖前者。
22
+
23
+ ## 条目识别:目录白名单 + USAGE(可选元数据)
20
24
 
21
- ## 无 registry.json:USAGE 块即事实源
25
+ 不维护独立 manifest。**条目门槛** = 白名单顶层目录(`scripts/` · `components/` · `stylesheets/`,任意深度)下的代码文件(`.js/.jsx/.mjs/.cjs/.ts/.tsx/.css`)。
22
26
 
23
- 不维护独立 manifest。每个 SDK 文件以 `/* BEGIN USAGE */ … /* END USAGE */` 注释块开头,声明 name / Exports(to window) / Usage / 约束,可选 `// Depends: <name>` 声明跨 SDK 依赖。
27
+ USAGE 块(`/* BEGIN USAGE */ … /* END USAGE */`)**可选但强烈推荐**:有则声明 name / Exports(to window) / Usage / 约束(供 Agent 读)+ `// Depends: <token>` 依赖;无则 usage 为空、无依赖,仍是条目。
24
28
 
25
- - 条目 `name` = 文件名去扩展名(`deck-stage.js` → `deck-stage`)。
26
- - `miaoda registry list` 直接输出各文件 USAGE 块原文供 Agent 消费。
27
- - `miaoda registry add <name>` 解析 `Depends` 闭包后按结构拷入。
29
+ - 条目 `name` = 文件名去扩展名(`deck-stage.js` → `deck-stage`),**不要求唯一**(`foo.jsx` + `foo.css` 可共存)。
30
+ - **寻址(多匹配)**:`add` / `Depends` 的 token 按「name / 完整文件名 / relPath」匹配,**命中的条目全部拉取**;`relPath`(相对包根路径)是唯一精确地址。
31
+ - `miaoda registry list` 输出各文件 USAGE 块原文供 Agent 消费(`--json` 的 `file` 字段即 relPath)。
32
+ - `miaoda registry add <token>` 解析 `Depends` 闭包后,**拍平为 basename 拷到项目根**(`added`/`skipped` 为落地 basename)。
28
33
 
29
34
  ## 解析(CLI 怎么找到本包)
30
35
 
@@ -0,0 +1,189 @@
1
+ /* BEGIN USAGE */
2
+ // Android.jsx — Simplified Android (Material 3) device frame
3
+ // Status bar + content + gesture nav + keyboard.
4
+ // Based on Figma M3 spec. No dependencies, no image assets.
5
+ // Exports (to window): AndroidDevice, AndroidStatusBar, AndroidListItem, AndroidNavBar, AndroidKeyboard
6
+ //
7
+ // Usage — wrap your screen content in <AndroidDevice> to get the bezel, status
8
+ // bar and gesture nav (props: width=412, height=892, dark, keyboard):
9
+ //
10
+ // <AndroidDevice>
11
+ // ...your screen content...
12
+ // </AndroidDevice>
13
+ // <AndroidDevice dark keyboard>…</AndroidDevice>
14
+ // <AndroidDevice width={360} height={800}>…</AndroidDevice> // smaller device size
15
+ /* END USAGE */
16
+
17
+ const MD_C = {
18
+ surface: '#f4fbf8',
19
+ surfaceVariant: '#dae5e1',
20
+ inverseOnSurface: '#ecf2ef',
21
+ secondaryContainer: '#cde8e1',
22
+ primaryFixedDim: '#83d5c6',
23
+ onSurface: '#171d1b',
24
+ onSurfaceVar: '#49454f',
25
+ onPrimaryContainer: '#00201c',
26
+ primary: '#006a60',
27
+ frameBorder: 'rgba(116,119,117,0.5)',
28
+ };
29
+
30
+ // ─────────────────────────────────────────────────────────────
31
+ // Status bar (time left, wifi/cell/battery right)
32
+ // ─────────────────────────────────────────────────────────────
33
+ function AndroidStatusBar({ dark = false }) {
34
+ const c = dark ? '#fff' : MD_C.onSurface;
35
+ return (
36
+ <div style={{
37
+ height: 40, display: 'flex', alignItems: 'center',
38
+ justifyContent: 'space-between', padding: '0 16px',
39
+ position: 'relative',
40
+ fontFamily: 'Roboto, system-ui, sans-serif',
41
+ }}>
42
+ {/* time left */}
43
+ <div style={{ width: 128, display: 'flex', alignItems: 'center', gap: 8 }}>
44
+ <span style={{ fontSize: 14, fontWeight: 400, letterSpacing: 0.25, lineHeight: '20px', color: c }}>9:30</span>
45
+ </div>
46
+ {/* camera punch-hole (center) */}
47
+ <div style={{
48
+ position: 'absolute', left: '50%', top: 8, transform: 'translateX(-50%)',
49
+ width: 24, height: 24, borderRadius: 100, background: '#2e2e2e',
50
+ }} />
51
+ {/* status icons right */}
52
+ <div style={{ display: 'flex', alignItems: 'center' }}>
53
+ <div style={{ display: 'flex', paddingRight: 2 }}>
54
+ <svg width="16" height="16" viewBox="0 0 16 16" style={{ marginRight: -2 }}>
55
+ <path d="M8 13.3L.67 5.97a10.37 10.37 0 0114.66 0L8 13.3z" fill={c}/>
56
+ </svg>
57
+ <svg width="16" height="16" viewBox="0 0 16 16" style={{ marginRight: -2 }}>
58
+ <path d="M14.67 14.67V1.33L1.33 14.67h13.34z" fill={c}/>
59
+ </svg>
60
+ </div>
61
+ <svg width="16" height="16" viewBox="0 0 16 16">
62
+ <rect x="3.75" y="2" width="8.5" height="13" rx="1.5" fill={c}/>
63
+ <rect x="5.5" y="0.9" width="5" height="2" rx="0.5" fill={c}/>
64
+ </svg>
65
+ </div>
66
+ </div>
67
+ );
68
+ }
69
+
70
+ // ─────────────────────────────────────────────────────────────
71
+ // List item (Material 3)
72
+ // ─────────────────────────────────────────────────────────────
73
+ function AndroidListItem({ headline, supporting, leading }) {
74
+ return (
75
+ <div style={{
76
+ display: 'flex', alignItems: 'center', gap: 16,
77
+ padding: '12px 16px', minHeight: 56, boxSizing: 'border-box',
78
+ fontFamily: 'Roboto, system-ui, sans-serif',
79
+ }}>
80
+ {leading && (
81
+ <div style={{
82
+ width: 40, height: 40, borderRadius: '50%',
83
+ background: MD_C.primary, color: '#fff',
84
+ display: 'flex', alignItems: 'center', justifyContent: 'center',
85
+ fontSize: 18, fontWeight: 500, flexShrink: 0,
86
+ }}>{leading}</div>
87
+ )}
88
+ <div style={{ flex: 1, minWidth: 0 }}>
89
+ <div style={{ fontSize: 16, color: MD_C.onSurface, lineHeight: '24px' }}>{headline}</div>
90
+ {supporting && (
91
+ <div style={{ fontSize: 14, color: MD_C.onSurfaceVar, lineHeight: '20px' }}>{supporting}</div>
92
+ )}
93
+ </div>
94
+ </div>
95
+ );
96
+ }
97
+
98
+ // ─────────────────────────────────────────────────────────────
99
+ // Gesture nav bar (pill)
100
+ // ─────────────────────────────────────────────────────────────
101
+ function AndroidNavBar({ dark = false }) {
102
+ return (
103
+ <div style={{
104
+ height: 24, display: 'flex', alignItems: 'center', justifyContent: 'center',
105
+ }}>
106
+ <div style={{
107
+ width: 108, height: 4, borderRadius: 2,
108
+ background: dark ? '#fff' : MD_C.onSurface, opacity: 0.4,
109
+ }} />
110
+ </div>
111
+ );
112
+ }
113
+
114
+ // ─────────────────────────────────────────────────────────────
115
+ // Device frame — wraps everything
116
+ // ─────────────────────────────────────────────────────────────
117
+ function AndroidDevice({
118
+ children, width = 412, height = 892, dark = false,
119
+ keyboard = false,
120
+ }) {
121
+ return (
122
+ <div style={{
123
+ width, height, borderRadius: 18, overflow: 'hidden',
124
+ background: dark ? '#1d1b20' : MD_C.surface,
125
+ border: `8px solid ${MD_C.frameBorder}`,
126
+ boxShadow: '0 30px 80px rgba(0,0,0,0.25)',
127
+ display: 'flex', flexDirection: 'column', boxSizing: 'border-box',
128
+ }}>
129
+ <AndroidStatusBar dark={dark} />
130
+ <div style={{ flex: 1, overflow: 'auto' }}>
131
+ {children}
132
+ </div>
133
+ {keyboard && <AndroidKeyboard />}
134
+ <AndroidNavBar dark={dark} />
135
+ </div>
136
+ );
137
+ }
138
+
139
+ // ─────────────────────────────────────────────────────────────
140
+ // Keyboard — Gboard (Material 3)
141
+ // ─────────────────────────────────────────────────────────────
142
+ function AndroidKeyboard() {
143
+ let _k = 0;
144
+ const key = (l, { flex = 1, bg = MD_C.surface, r = 6, minW, fs = 21 } = {}) => (
145
+ <div key={_k++} style={{
146
+ height: 46, borderRadius: r, flex, minWidth: minW,
147
+ background: bg, display: 'flex', alignItems: 'center', justifyContent: 'center',
148
+ fontFamily: 'Roboto, system-ui', fontSize: fs,
149
+ color: MD_C.onPrimaryContainer,
150
+ }}>{l}</div>
151
+ );
152
+ const row = (keys, style = {}) => (
153
+ <div style={{ display: 'flex', gap: 6, justifyContent: 'center', ...style }}>
154
+ {keys.map(l => key(l))}
155
+ </div>
156
+ );
157
+ return (
158
+ <div style={{
159
+ background: MD_C.inverseOnSurface, padding: '0 8px 8px',
160
+ display: 'flex', flexDirection: 'column', gap: 4,
161
+ }}>
162
+ {/* navbar spacer (icons omitted) */}
163
+ <div style={{ height: 44 }} />
164
+ {/* key rows */}
165
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
166
+ {row(['q','w','e','r','t','y','u','i','o','p'])}
167
+ {row(['a','s','d','f','g','h','j','k','l'], { padding: '0 20px' })}
168
+ <div style={{ display: 'flex', gap: 6 }}>
169
+ {key('', { bg: MD_C.surfaceVariant })}
170
+ <div style={{ display: 'flex', gap: 6, flex: 7, minWidth: 274 }}>
171
+ {['z','x','c','v','b','n','m'].map(l => key(l))}
172
+ </div>
173
+ {key('', { bg: MD_C.surfaceVariant })}
174
+ </div>
175
+ <div style={{ display: 'flex', gap: 6 }}>
176
+ {key('?123', { bg: MD_C.secondaryContainer, r: 100, minW: 58, fs: 14 })}
177
+ {key(',', { bg: MD_C.surfaceVariant })}
178
+ {key('', { flex: 3, minW: 154 })}
179
+ {key('.', { bg: MD_C.surfaceVariant })}
180
+ {key('', { bg: MD_C.primaryFixedDim, r: 100, minW: 58 })}
181
+ </div>
182
+ </div>
183
+ </div>
184
+ );
185
+ }
186
+
187
+ Object.assign(window, {
188
+ AndroidDevice, AndroidStatusBar, AndroidListItem, AndroidNavBar, AndroidKeyboard,
189
+ });