@moon791017/neo-skills 1.0.27 → 1.0.28

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "neo-skills",
3
3
  "description": "A universal capability extension for Gemini CLI",
4
- "version": "0.53.0",
4
+ "version": "0.54.0",
5
5
  "mcpServers": {
6
6
  "neo-skills": {
7
7
  "command": "node",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moon791017/neo-skills",
3
- "version": "1.0.27",
3
+ "version": "1.0.28",
4
4
  "type": "module",
5
5
  "description": "Neo Skills: A Universal Expert Agent Extension",
6
6
  "homepage": "https://neo-blog-iota.vercel.app/",
@@ -110,3 +110,91 @@ export async function getUserById(id, signal) { ... }
110
110
  ```
111
111
  - **Logical Comments**: Comments should explain "Why" the processing is done this way, not repeat "What" the code does.
112
112
  - **TODO/FIXME**: Use `// TODO:` for planned improvements and `// FIXME:` for known issues.
113
+
114
+ ---
115
+
116
+ ## 7. Architecture Patterns for Vanilla JS (HTML/CSHTML)
117
+
118
+ This pattern should be applied when refactoring JavaScript files that are referenced by HTML or CSHTML files in non-SPA environments.
119
+
120
+ ### 7.1 Separation of Concerns
121
+ To maintain clean and testable code, split the logic into three distinct classes:
122
+
123
+ - **API Class**: Handles all network requests (e.g., `fetch`, AJAX) communicating with the backend.
124
+ - **UI Class**: Strictly responsible for DOM element selection, rendering, and UI updates. It should not contain business logic.
125
+ - **Controller Class**: Manages core business logic, registers event listeners, and orchestrates the flow by calling both the API and UI classes.
126
+
127
+ ### 7.2 Example Implementation
128
+
129
+ ```javascript
130
+ ((window, document) => {
131
+ // API Class - Handles data fetching
132
+ class UserAPI {
133
+ #baseUrl = '/api/users';
134
+
135
+ async getUser(id) {
136
+ const response = await fetch(`${this.#baseUrl}/${id}`);
137
+ if (!response.ok) throw new Error('Failed to fetch user');
138
+ return response.json();
139
+ }
140
+ }
141
+
142
+ // UI Class - Handles DOM manipulation
143
+ class UserUI {
144
+ #elements = {
145
+ nameDisplay: document.getElementById('userName'),
146
+ loadingSpinner: document.getElementById('spinner')
147
+ };
148
+
149
+ updateUserName(name) {
150
+ this.#elements.nameDisplay.textContent = name;
151
+ }
152
+
153
+ toggleLoading(show) {
154
+ this.#elements.loadingSpinner.style.display = show ? 'block' : 'none';
155
+ }
156
+ }
157
+
158
+ // Controller Class - Orchestrates business logic and events
159
+ class UserController {
160
+ #api;
161
+ #ui;
162
+
163
+ constructor(api, ui) {
164
+ this.#api = api;
165
+ this.#ui = ui;
166
+ }
167
+
168
+ init() {
169
+ this.#registerEvents();
170
+ }
171
+
172
+ #registerEvents() {
173
+ document.getElementById('fetchBtn')?.addEventListener('click', () => this.handleFetchUser());
174
+ }
175
+
176
+ async handleFetchUser() {
177
+ try {
178
+ const userId = document.getElementById('userIdInput').value;
179
+ this.#ui.toggleLoading(true);
180
+ const user = await this.#api.getUser(userId);
181
+ this.#ui.updateUserName(user.name);
182
+ } catch (error) {
183
+ console.error(error);
184
+ alert('Error fetching user data');
185
+ } finally {
186
+ this.#ui.toggleLoading(false);
187
+ }
188
+ }
189
+ }
190
+
191
+ // Initialization on Page Load
192
+ document.addEventListener('DOMContentLoaded', () => {
193
+ const api = new UserAPI();
194
+ const ui = new UserUI();
195
+ const controller = new UserController(api, ui);
196
+ controller.init();
197
+ });
198
+ })(window, document);
199
+ ```
200
+