@nockdev/awf 6.2.5 → 6.2.7
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/.agent/config.yaml +2 -2
- package/.agent/core/AGENT_BEHAVIOR.md +1 -1
- package/.agent/core/AUDIT_POLICY.md +1 -1
- package/.agent/core/CACHE.md +1 -1
- package/.agent/core/DATA_SAFETY.md +1 -1
- package/.agent/core/MEMORY_PATHS.yaml +2 -2
- package/.agent/core/PERMISSIONS.md +1 -1
- package/.agent/core/README.md +1 -1
- package/.agent/core/VERSION.yaml +4 -4
- package/.agent/core/archive/ACTIVE_MEMORY.yaml +2 -2
- package/.agent/core/archive/CHECKPOINT.yaml +2 -2
- package/.agent/core/archive/CLEANUP_ENGINE.yaml +2 -2
- package/.agent/core/archive/CONTEXT_INJECTOR.yaml +2 -2
- package/.agent/core/archive/CONTEXT_LOADER.yaml +1 -1
- package/.agent/core/archive/CONTEXT_OPTIMIZATION.yaml +1 -1
- package/.agent/core/archive/CONTEXT_PRIORITY.yaml +2 -2
- package/.agent/core/archive/FLOW_ENGINE.yaml +1 -1
- package/.agent/core/archive/GRAPH_MEMORY.yaml +1 -1
- package/.agent/core/archive/HYBRID_ROUTER.yaml +1 -1
- package/.agent/core/archive/INTENT_DETECTION.yaml +1 -1
- package/.agent/core/archive/MEMORY_CONSOLIDATION.yaml +3 -3
- package/.agent/core/archive/MEMORY_ENGINE.yaml +2 -2
- package/.agent/core/archive/MEMORY_UTILS.yaml +1 -1
- package/.agent/core/archive/REFLECTION_ENGINE.yaml +1 -1
- package/.agent/core/archive/ROUTER.yaml +4 -4
- package/.agent/core/archive/SCORING_FORMULA.yaml +2 -2
- package/.agent/core/archive/SEMANTIC_ENGINE.yaml +1 -1
- package/.agent/core/archive/SKILLS_FLOW.yaml +1 -1
- package/.agent/core/archive/STATE_MACHINE.yaml +1 -1
- package/.agent/core/archive/SUMMARIZATION_ENGINE.yaml +2 -2
- package/.agent/core/archive/TOKEN_BUDGETS.yaml +2 -2
- package/.agent/core/archive/TOKEN_LOADING.yaml +2 -2
- package/.agent/core/archive/TOKEN_SUMMARY.yaml +2 -2
- package/.agent/core/reference/CODING_STYLES.yaml +1 -1
- package/.agent/core/reference/LIBRARY_REGISTRY.yaml +1 -1
- package/.agent/core/reference/MCP_TOOLS.yaml +2 -2
- package/.agent/core/reference/PATTERNS.yaml +1 -1
- package/.agent/core/reference/SKILL_SCHEMA.yaml +1 -1
- package/.agent/i18n/en.yaml +6 -6
- package/.agent/i18n/vi.yaml +6 -6
- package/.agent/ide/README.md +1 -1
- package/.agent/ide/amazonq.json +1 -1
- package/.agent/ide/amp.json +1 -1
- package/.agent/ide/antigravity.json +1 -1
- package/.agent/ide/augment.json +1 -1
- package/.agent/ide/claude.json +1 -1
- package/.agent/ide/cline.json +1 -1
- package/.agent/ide/cody.json +1 -1
- package/.agent/ide/continue.json +1 -1
- package/.agent/ide/cursor.json +1 -1
- package/.agent/ide/gemini.json +1 -1
- package/.agent/ide/jetbrains.json +1 -1
- package/.agent/ide/kiro.json +1 -1
- package/.agent/ide/opencode.json +1 -1
- package/.agent/ide/roo.json +1 -1
- package/.agent/ide/tabnine.json +1 -1
- package/.agent/ide/trae.json +1 -1
- package/.agent/ide/vscode.json +1 -1
- package/.agent/ide/windsurf.json +1 -1
- package/.agent/ide/zed.json +1 -1
- package/.agent/manifest.yaml +1 -1
- package/.agent/personas/README.md +1 -1
- package/.agent/personas/architect.md +1 -1
- package/.agent/personas/auditor.md +1 -1
- package/.agent/personas/debugger.md +1 -1
- package/.agent/personas/developer.md +1 -1
- package/.agent/personas/devops.md +1 -1
- package/.agent/personas/documenter.md +1 -1
- package/.agent/personas/orchestrator.md +1 -1
- package/.agent/personas/persona.schema.yaml +1 -1
- package/.agent/personas/planner.md +1 -1
- package/.agent/personas/researcher.md +1 -1
- package/.agent/personas/security.md +1 -1
- package/.agent/personas/tester.md +1 -1
- package/.agent/rules/README.md +1 -1
- package/.agent/rules/archive/constitutional/tier-0-core.yaml +5 -5
- package/.agent/rules/archive/constitutional/tier-1-safety.yaml +5 -5
- package/.agent/rules/archive/constitutional/tier-2-execution.yaml +6 -6
- package/.agent/rules/archive/context-management.yaml +1 -1
- package/.agent/rules/archive/duplication-prevention.md +1 -1
- package/.agent/rules/archive/evidence.yaml +1 -1
- package/.agent/rules/archive/project-detection.md +1 -1
- package/.agent/rules/archive/reflection.yaml +1 -1
- package/.agent/rules/archive/versioning.yaml +5 -5
- package/.agent/rules/data/build-systems.yaml +57 -2
- package/.agent/rules/modules/agent-delegation.yaml +2 -2
- package/.agent/rules/modules/edit-verification.yaml +1 -1
- package/.agent/rules/modules/git-workflow.yaml +1 -1
- package/.agent/rules/modules/language.yaml +1 -1
- package/.agent/rules/modules/online-research.yaml +1 -1
- package/.agent/rules/modules/performance-optimization.yaml +2 -2
- package/.agent/rules/modules/quality.yaml +1 -1
- package/.agent/rules/modules/stop-conditions.yaml +1 -1
- package/.agent/rules/modules/terminal-safety.yaml +1 -1
- package/.agent/rules/modules/yagni.yaml +1 -1
- package/.agent/rules/validation-framework.md +1 -1
- package/.agent/skills/README.md +1 -1
- package/.agent/skills/_categories.yaml +2 -2
- package/.agent/skills/ai-ml/rag-patterns/META.yaml +2 -0
- package/.agent/skills/core/api-design/META.yaml +1 -1
- package/.agent/skills/core/authentication/META.yaml +1 -1
- package/.agent/skills/core/error-handling/META.yaml +1 -1
- package/.agent/skills/core/logging/META.yaml +1 -1
- package/.agent/skills/core/observability/META.yaml +1 -1
- package/.agent/skills/core/security/META.yaml +1 -1
- package/.agent/skills/core/security/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/accessibility/META.yaml +1 -1
- package/.agent/skills/cross-cutting/audit-pro/META.yaml +9 -1
- package/.agent/skills/cross-cutting/audit-pro/SKILL.md +61 -5
- package/.agent/skills/cross-cutting/bun/META.yaml +17 -8
- package/.agent/skills/cross-cutting/bun/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/coding-rules/META.yaml +1 -1
- package/.agent/skills/cross-cutting/database/META.yaml +42 -1
- package/.agent/skills/cross-cutting/database/SKILL.md +44 -628
- package/.agent/skills/cross-cutting/database/references/nosql-patterns.md +194 -0
- package/.agent/skills/cross-cutting/database/references/orms-patterns.md +278 -0
- package/.agent/skills/cross-cutting/database/references/postgresql.md +144 -0
- package/.agent/skills/cross-cutting/deno/META.yaml +19 -10
- package/.agent/skills/cross-cutting/deno/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/domyh-design/META.yaml +1 -1
- package/.agent/skills/cross-cutting/domyh-design/data/desktop-colors.yaml +1 -1
- package/.agent/skills/cross-cutting/electron/SKILL.md +15 -616
- package/.agent/skills/cross-cutting/electron/references/ipc-testing.md +114 -0
- package/.agent/skills/cross-cutting/electron/references/native-integrations.md +216 -0
- package/.agent/skills/cross-cutting/electron/references/performance-accessibility.md +118 -0
- package/.agent/skills/cross-cutting/electron/references/updates-persistence.md +165 -0
- package/.agent/skills/cross-cutting/seo/META.yaml +1 -1
- package/.agent/skills/cross-cutting/skill-creator/META.yaml +37 -0
- package/.agent/skills/cross-cutting/skill-creator/SKILL.md +163 -0
- package/.agent/skills/cross-cutting/skill-creator/references/patterns.md +58 -0
- package/.agent/skills/cross-cutting/skill-creator/references/schema-v2.md +44 -0
- package/.agent/skills/cross-cutting/sql/META.yaml +1 -1
- package/.agent/skills/cross-cutting/sql/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/tailwind/META.yaml +1 -1
- package/.agent/skills/cross-cutting/tailwind/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/tdd-workflow/META.yaml +1 -1
- package/.agent/skills/cross-cutting/testing/META.yaml +7 -1
- package/.agent/skills/cross-cutting/testing/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/testing/data/frameworks.yaml +1 -1
- package/.agent/skills/cross-cutting/web-perf/META.yaml +1 -1
- package/.agent/skills/cross-cutting/web-perf/SKILL.md +1 -1
- package/.agent/skills/devops/aws/META.yaml +1 -1
- package/.agent/skills/devops/aws/SKILL.md +101 -16
- package/.agent/skills/devops/azure/SKILL.md +96 -30
- package/.agent/skills/devops/ci-cd/META.yaml +1 -1
- package/.agent/skills/devops/ci-cd/SKILL.md +114 -8
- package/.agent/skills/devops/docker/META.yaml +1 -1
- package/.agent/skills/devops/docker/SKILL.md +96 -8
- package/.agent/skills/devops/gcp/SKILL.md +106 -30
- package/.agent/skills/devops/kubernetes/META.yaml +1 -1
- package/.agent/skills/devops/kubernetes/SKILL.md +125 -8
- package/.agent/skills/frameworks/angular/META.yaml +1 -1
- package/.agent/skills/frameworks/angular/SKILL.md +1 -1
- package/.agent/skills/frameworks/flutter/META.yaml +1 -1
- package/.agent/skills/frameworks/flutter/SKILL.md +1 -1
- package/.agent/skills/frameworks/nextjs/META.yaml +1 -1
- package/.agent/skills/frameworks/nextjs/SKILL.md +1 -1
- package/.agent/skills/frameworks/nuxt/META.yaml +1 -1
- package/.agent/skills/frameworks/nuxt/SKILL.md +1 -1
- package/.agent/skills/frameworks/react/META.yaml +1 -1
- package/.agent/skills/frameworks/react/SKILL.md +24 -1
- package/.agent/skills/frameworks/react-native/META.yaml +1 -1
- package/.agent/skills/frameworks/react-native/SKILL.md +1 -1
- package/.agent/skills/frameworks/svelte/META.yaml +1 -1
- package/.agent/skills/frameworks/svelte/SKILL.md +1 -1
- package/.agent/skills/frameworks/vue/META.yaml +1 -1
- package/.agent/skills/frameworks/vue/SKILL.md +1 -1
- package/.agent/skills/index.json +2 -2
- package/.agent/skills/languages/asm/META.yaml +1 -1
- package/.agent/skills/languages/asm/SKILL.md +27 -436
- package/.agent/skills/languages/asm/references/advanced-architectures.md +191 -0
- package/.agent/skills/languages/asm/references/build-structure.md +150 -0
- package/.agent/skills/languages/asm/references/simd-programming.md +92 -0
- package/.agent/skills/languages/c/META.yaml +1 -1
- package/.agent/skills/languages/c/SKILL.md +14 -356
- package/.agent/skills/languages/c/references/data-structures.md +63 -0
- package/.agent/skills/languages/c/references/memory-management.md +74 -0
- package/.agent/skills/languages/c/references/platform-headers.md +230 -0
- package/.agent/skills/languages/clojure/META.yaml +1 -1
- package/.agent/skills/languages/clojure/SKILL.md +1 -1
- package/.agent/skills/languages/cpp/META.yaml +1 -1
- package/.agent/skills/languages/cpp/SKILL.md +22 -753
- package/.agent/skills/languages/cpp/references/headers-optimization.md +229 -0
- package/.agent/skills/languages/cpp/references/memory-concurrency.md +85 -0
- package/.agent/skills/languages/cpp/references/modern-cpp-features.md +126 -0
- package/.agent/skills/languages/cpp/references/platform-headers.md +202 -0
- package/.agent/skills/languages/cpp/references/stl-containers.md +57 -0
- package/.agent/skills/languages/crystal/META.yaml +1 -1
- package/.agent/skills/languages/crystal/SKILL.md +1 -1
- package/.agent/skills/languages/csharp/META.yaml +1 -1
- package/.agent/skills/languages/csharp/SKILL.md +1 -1
- package/.agent/skills/languages/elixir/META.yaml +1 -1
- package/.agent/skills/languages/elixir/SKILL.md +1 -1
- package/.agent/skills/languages/fsharp/META.yaml +1 -1
- package/.agent/skills/languages/fsharp/SKILL.md +1 -1
- package/.agent/skills/languages/go/META.yaml +1 -1
- package/.agent/skills/languages/go/SKILL.md +1 -1
- package/.agent/skills/languages/haskell/META.yaml +1 -1
- package/.agent/skills/languages/haskell/SKILL.md +1 -1
- package/.agent/skills/languages/java/META.yaml +1 -1
- package/.agent/skills/languages/java/SKILL.md +1 -1
- package/.agent/skills/languages/javascript/META.yaml +1 -1
- package/.agent/skills/languages/javascript/SKILL.md +1 -1
- package/.agent/skills/languages/julia/META.yaml +1 -1
- package/.agent/skills/languages/julia/SKILL.md +1 -1
- package/.agent/skills/languages/kotlin/META.yaml +1 -1
- package/.agent/skills/languages/kotlin/SKILL.md +1 -1
- package/.agent/skills/languages/lua/META.yaml +1 -1
- package/.agent/skills/languages/lua/SKILL.md +3 -3
- package/.agent/skills/languages/nim/META.yaml +1 -1
- package/.agent/skills/languages/nim/SKILL.md +1 -1
- package/.agent/skills/languages/ocaml/META.yaml +1 -1
- package/.agent/skills/languages/ocaml/SKILL.md +1 -1
- package/.agent/skills/languages/perl/META.yaml +1 -1
- package/.agent/skills/languages/perl/SKILL.md +1 -1
- package/.agent/skills/languages/php/META.yaml +1 -1
- package/.agent/skills/languages/php/SKILL.md +1 -1
- package/.agent/skills/languages/python/META.yaml +1 -1
- package/.agent/skills/languages/python/SKILL.md +1 -1
- package/.agent/skills/languages/r/META.yaml +1 -1
- package/.agent/skills/languages/r/SKILL.md +1 -1
- package/.agent/skills/languages/ruby/META.yaml +1 -1
- package/.agent/skills/languages/ruby/SKILL.md +1 -1
- package/.agent/skills/languages/rust/META.yaml +1 -1
- package/.agent/skills/languages/rust/SKILL.md +1 -1
- package/.agent/skills/languages/scala/META.yaml +1 -1
- package/.agent/skills/languages/scala/SKILL.md +1 -1
- package/.agent/skills/languages/solidity/META.yaml +1 -1
- package/.agent/skills/languages/solidity/SKILL.md +1 -1
- package/.agent/skills/languages/swift/META.yaml +1 -1
- package/.agent/skills/languages/swift/SKILL.md +1 -1
- package/.agent/skills/languages/typescript/META.yaml +19 -1
- package/.agent/skills/languages/typescript/SKILL.md +23 -1
- package/.agent/skills/languages/zig/META.yaml +1 -1
- package/.agent/skills/languages/zig/SKILL.md +1 -1
- package/.agent/templates/README.md +2 -2
- package/.agent/templates/chains/feature/step1-requirements.md +76 -0
- package/.agent/templates/chains/feature/step2-design.md +75 -0
- package/.agent/templates/chains/feature/step3-planning.md +81 -0
- package/.agent/templates/chains/feature/step4-implementation.md +74 -0
- package/.agent/templates/chains/feature/step5-testing.md +81 -0
- package/.agent/templates/debug-report.md +1 -1
- package/.agent/templates/deploy-plan.md +1 -1
- package/.agent/templates/doc-template.md +1 -1
- package/.agent/templates/feature-lifecycle.md +53 -0
- package/.agent/templates/index.yaml +53 -2
- package/.agent/templates/migrate-plan.md +1 -1
- package/.agent/templates/phase-template.md +1 -1
- package/.agent/templates/tasks/audit.yaml +1 -1
- package/.agent/templates/tasks/bug_fix.yaml +1 -1
- package/.agent/templates/tasks/code_implementation.yaml +1 -1
- package/.agent/templates/tasks/feature_development.yaml +89 -0
- package/.agent/templates/tasks/refactor.yaml +1 -1
- package/.agent/templates/test-report.md +1 -1
- package/.agent/workflows/doctor.md +124 -0
- package/.agent/workflows/feature.md +130 -0
- package/.agent/workflows/help.md +7 -5
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
---
|
|
1
|
+
---
|
|
2
2
|
name: electron
|
|
3
3
|
detect:
|
|
4
4
|
[
|
|
@@ -12,7 +12,7 @@ category: desktop
|
|
|
12
12
|
tier: 1
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
# Electron Patterns
|
|
15
|
+
# Electron Patterns DOMYH Awesome Code
|
|
16
16
|
|
|
17
17
|
> **Version**: Electron 35-40 (2025-2026)
|
|
18
18
|
> **Chromium**: 134.0.6998+
|
|
@@ -21,7 +21,7 @@ tier: 1
|
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## 📦 When to Use This Skill
|
|
25
25
|
|
|
26
26
|
Use for: Cross-platform desktop apps, web tech on desktop.
|
|
27
27
|
**NOT for**: Mobile (→ react-native), CLI tools (→ nodejs), Lightweight apps (→ tauri).
|
|
@@ -43,7 +43,7 @@ Use for: Cross-platform desktop apps, web tech on desktop.
|
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
46
|
-
##
|
|
46
|
+
## 📦 Build Tools Comparison
|
|
47
47
|
|
|
48
48
|
| Tool | Purpose | Best For |
|
|
49
49
|
| -------------------- | ------------------- | ------------------------------------- |
|
|
@@ -190,620 +190,19 @@ export {};
|
|
|
190
190
|
|
|
191
191
|
---
|
|
192
192
|
|
|
193
|
-
##
|
|
194
|
-
|
|
195
|
-
### Main Process Handlers
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
// main.ts
|
|
199
|
-
import { ipcMain, dialog, BrowserWindow } from "electron";
|
|
200
|
-
import { z } from "zod";
|
|
201
|
-
|
|
202
|
-
// ✅ Schema validation
|
|
203
|
-
const SaveFileSchema = z.object({
|
|
204
|
-
path: z.string(),
|
|
205
|
-
content: z.string(),
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
ipcMain.handle("dialog:openFile", async (event) => {
|
|
209
|
-
const window = BrowserWindow.fromWebContents(event.sender);
|
|
210
|
-
if (!window) return null;
|
|
211
|
-
|
|
212
|
-
const result = await dialog.showOpenDialog(window, {
|
|
213
|
-
properties: ["openFile"],
|
|
214
|
-
filters: [{ name: "Text", extensions: ["txt", "md"] }],
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
if (result.canceled) return null;
|
|
218
|
-
return result.filePaths[0];
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
ipcMain.handle("file:save", async (event, data: unknown) => {
|
|
222
|
-
const parsed = SaveFileSchema.safeParse(data);
|
|
223
|
-
if (!parsed.success) {
|
|
224
|
-
throw new Error("Invalid data format");
|
|
225
|
-
}
|
|
226
|
-
// Save logic with validated data
|
|
227
|
-
return true;
|
|
228
|
-
});
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
## 🧪 Testing Patterns
|
|
234
|
-
|
|
235
|
-
### Unit Testing with Vitest
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
// src/main/__tests__/validators.test.ts
|
|
239
|
-
import { describe, it, expect } from "vitest";
|
|
240
|
-
import { validateFilePath, sanitizeInput } from "../validators";
|
|
241
|
-
|
|
242
|
-
describe("Input Validation", () => {
|
|
243
|
-
it("rejects path traversal", () => {
|
|
244
|
-
expect(validateFilePath("../etc/passwd")).toBe(false);
|
|
245
|
-
expect(validateFilePath("..\\windows\\system32")).toBe(false);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it("accepts valid paths", () => {
|
|
249
|
-
expect(validateFilePath("/home/user/documents/file.txt")).toBe(true);
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
it("sanitizes HTML input", () => {
|
|
253
|
-
expect(sanitizeInput("<script>alert(1)</script>")).toBe("");
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### E2E Testing with Playwright
|
|
259
|
-
|
|
260
|
-
```typescript
|
|
261
|
-
// e2e/app.spec.ts
|
|
262
|
-
import { test, expect, _electron as electron } from "@playwright/test";
|
|
263
|
-
|
|
264
|
-
test("app launches and shows main window", async () => {
|
|
265
|
-
const app = await electron.launch({ args: ["./dist/main.js"] });
|
|
266
|
-
const window = await app.firstWindow();
|
|
267
|
-
|
|
268
|
-
await expect(window).toHaveTitle(/MyApp/);
|
|
269
|
-
|
|
270
|
-
// Test IPC communication
|
|
271
|
-
const result = await window.evaluate(() => {
|
|
272
|
-
return window.electronAPI.getVersion();
|
|
273
|
-
});
|
|
274
|
-
expect(result).toMatch(/\d+\.\d+\.\d+/);
|
|
275
|
-
|
|
276
|
-
await app.close();
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
test("file dialog works", async () => {
|
|
280
|
-
const app = await electron.launch({ args: ["./dist/main.js"] });
|
|
281
|
-
const window = await app.firstWindow();
|
|
282
|
-
|
|
283
|
-
await window.click('button[data-testid="open-file"]');
|
|
284
|
-
// Dialog opens - mock or handle appropriately
|
|
285
|
-
|
|
286
|
-
await app.close();
|
|
287
|
-
});
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### Playwright Config
|
|
291
|
-
|
|
292
|
-
```typescript
|
|
293
|
-
// playwright.config.ts
|
|
294
|
-
import { defineConfig } from "@playwright/test";
|
|
295
|
-
|
|
296
|
-
export default defineConfig({
|
|
297
|
-
testDir: "./e2e",
|
|
298
|
-
timeout: 30000,
|
|
299
|
-
use: {
|
|
300
|
-
trace: "on-first-retry",
|
|
301
|
-
},
|
|
302
|
-
projects: [{ name: "electron" }],
|
|
303
|
-
});
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
---
|
|
307
|
-
|
|
308
|
-
## 🔄 Auto Updates
|
|
309
|
-
|
|
310
|
-
### electron-updater Setup
|
|
311
|
-
|
|
312
|
-
```typescript
|
|
313
|
-
// main.ts
|
|
314
|
-
import { autoUpdater } from "electron-updater";
|
|
315
|
-
import { app, dialog, BrowserWindow } from "electron";
|
|
316
|
-
import log from "electron-log";
|
|
317
|
-
|
|
318
|
-
// Configure logging
|
|
319
|
-
autoUpdater.logger = log;
|
|
320
|
-
autoUpdater.autoDownload = false;
|
|
321
|
-
|
|
322
|
-
export function initAutoUpdater(mainWindow: BrowserWindow) {
|
|
323
|
-
// Check for updates on launch
|
|
324
|
-
autoUpdater.checkForUpdatesAndNotify();
|
|
325
|
-
|
|
326
|
-
autoUpdater.on("checking-for-update", () => {
|
|
327
|
-
log.info("Checking for update...");
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
autoUpdater.on("update-available", (info) => {
|
|
331
|
-
dialog
|
|
332
|
-
.showMessageBox(mainWindow, {
|
|
333
|
-
type: "info",
|
|
334
|
-
title: "Update Available",
|
|
335
|
-
message: `Version ${info.version} is available. Download now?`,
|
|
336
|
-
buttons: ["Download", "Later"],
|
|
337
|
-
})
|
|
338
|
-
.then(({ response }) => {
|
|
339
|
-
if (response === 0) autoUpdater.downloadUpdate();
|
|
340
|
-
});
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
autoUpdater.on("download-progress", (progress) => {
|
|
344
|
-
mainWindow.webContents.send("update:progress", progress.percent);
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
autoUpdater.on("update-downloaded", (info) => {
|
|
348
|
-
dialog
|
|
349
|
-
.showMessageBox(mainWindow, {
|
|
350
|
-
type: "info",
|
|
351
|
-
title: "Update Ready",
|
|
352
|
-
message: `Version ${info.version} is ready. Restart to apply?`,
|
|
353
|
-
buttons: ["Restart", "Later"],
|
|
354
|
-
})
|
|
355
|
-
.then(({ response }) => {
|
|
356
|
-
if (response === 0) autoUpdater.quitAndInstall();
|
|
357
|
-
});
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
autoUpdater.on("error", (err) => {
|
|
361
|
-
log.error("Auto-update error:", err);
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
### Code Signing (macOS)
|
|
367
|
-
|
|
368
|
-
```bash
|
|
369
|
-
# macOS notarization
|
|
370
|
-
npx electron-builder --mac --publish always
|
|
371
|
-
|
|
372
|
-
# Required environment variables
|
|
373
|
-
export APPLE_ID="your@email.com"
|
|
374
|
-
export APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
|
|
375
|
-
export APPLE_TEAM_ID="XXXXXXXXXX"
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
---
|
|
379
|
-
|
|
380
|
-
## 💾 Data Persistence
|
|
381
|
-
|
|
382
|
-
### better-sqlite3 (Best for Desktop)
|
|
383
|
-
|
|
384
|
-
```typescript
|
|
385
|
-
// main/database.ts
|
|
386
|
-
import Database from "better-sqlite3";
|
|
387
|
-
import path from "path";
|
|
388
|
-
import { app } from "electron";
|
|
389
|
-
|
|
390
|
-
const dbPath = path.join(app.getPath("userData"), "app.db");
|
|
391
|
-
const db = new Database(dbPath);
|
|
392
|
-
|
|
393
|
-
// Enable WAL mode for better concurrent performance
|
|
394
|
-
db.pragma("journal_mode = WAL");
|
|
395
|
-
|
|
396
|
-
// Initialize schema
|
|
397
|
-
db.exec(`
|
|
398
|
-
CREATE TABLE IF NOT EXISTS settings (
|
|
399
|
-
key TEXT PRIMARY KEY,
|
|
400
|
-
value TEXT NOT NULL
|
|
401
|
-
)
|
|
402
|
-
`);
|
|
403
|
-
|
|
404
|
-
// Type-safe operations
|
|
405
|
-
export const settings = {
|
|
406
|
-
get: db.prepare("SELECT value FROM settings WHERE key = ?"),
|
|
407
|
-
set: db.prepare("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)"),
|
|
408
|
-
};
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### electron-store (Simple Key-Value)
|
|
412
|
-
|
|
413
|
-
```typescript
|
|
414
|
-
// main/store.ts
|
|
415
|
-
import Store from "electron-store";
|
|
416
|
-
|
|
417
|
-
interface AppSettings {
|
|
418
|
-
theme: "light" | "dark" | "system";
|
|
419
|
-
windowBounds?: { width: number; height: number; x: number; y: number };
|
|
420
|
-
recentFiles: string[];
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
const store = new Store<AppSettings>({
|
|
424
|
-
defaults: {
|
|
425
|
-
theme: "system",
|
|
426
|
-
recentFiles: [],
|
|
427
|
-
},
|
|
428
|
-
encryptionKey: process.env.STORE_ENCRYPTION_KEY, // Optional
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
export function getSetting<K extends keyof AppSettings>(
|
|
432
|
-
key: K,
|
|
433
|
-
): AppSettings[K] {
|
|
434
|
-
return store.get(key);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
export function setSetting<K extends keyof AppSettings>(
|
|
438
|
-
key: K,
|
|
439
|
-
value: AppSettings[K],
|
|
440
|
-
) {
|
|
441
|
-
store.set(key, value);
|
|
442
|
-
}
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
### safeStorage (Sensitive Data)
|
|
446
|
-
|
|
447
|
-
```typescript
|
|
448
|
-
// main/secrets.ts
|
|
449
|
-
import { safeStorage } from "electron";
|
|
450
|
-
import fs from "fs";
|
|
451
|
-
import path from "path";
|
|
452
|
-
import { app } from "electron";
|
|
453
|
-
|
|
454
|
-
const secretsPath = path.join(app.getPath("userData"), "secrets.enc");
|
|
455
|
-
|
|
456
|
-
export function storeSecret(key: string, value: string) {
|
|
457
|
-
if (!safeStorage.isEncryptionAvailable()) {
|
|
458
|
-
throw new Error("Encryption not available");
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
const encrypted = safeStorage.encryptString(`${key}:${value}`);
|
|
462
|
-
// Append to secrets file or use a database
|
|
463
|
-
fs.appendFileSync(secretsPath, encrypted);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
export function getSecret(key: string): string | null {
|
|
467
|
-
// Implementation to retrieve and decrypt
|
|
468
|
-
// ...
|
|
469
|
-
}
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
---
|
|
473
|
-
|
|
474
|
-
## 📟 Native Integrations
|
|
475
|
-
|
|
476
|
-
### System Tray
|
|
477
|
-
|
|
478
|
-
```typescript
|
|
479
|
-
// main/tray.ts
|
|
480
|
-
import { Tray, Menu, nativeImage, app, BrowserWindow } from "electron";
|
|
481
|
-
import path from "path";
|
|
482
|
-
|
|
483
|
-
let tray: Tray | null = null;
|
|
484
|
-
|
|
485
|
-
export function createTray(mainWindow: BrowserWindow) {
|
|
486
|
-
const icon = nativeImage.createFromPath(
|
|
487
|
-
path.join(__dirname, "assets/tray-icon.png"),
|
|
488
|
-
);
|
|
489
|
-
|
|
490
|
-
tray = new Tray(icon);
|
|
491
|
-
tray.setToolTip("MyApp");
|
|
492
|
-
|
|
493
|
-
const contextMenu = Menu.buildFromTemplate([
|
|
494
|
-
{ label: "Show", click: () => mainWindow.show() },
|
|
495
|
-
{ type: "separator" },
|
|
496
|
-
{ label: "Quit", click: () => app.quit() },
|
|
497
|
-
]);
|
|
498
|
-
|
|
499
|
-
tray.setContextMenu(contextMenu);
|
|
500
|
-
|
|
501
|
-
// Click to show window
|
|
502
|
-
tray.on("click", () => {
|
|
503
|
-
mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show();
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
### Global Shortcuts
|
|
509
|
-
|
|
510
|
-
```typescript
|
|
511
|
-
// main/shortcuts.ts
|
|
512
|
-
import { globalShortcut, app, BrowserWindow } from "electron";
|
|
513
|
-
|
|
514
|
-
export function registerGlobalShortcuts(mainWindow: BrowserWindow) {
|
|
515
|
-
// Register when app is ready
|
|
516
|
-
app.whenReady().then(() => {
|
|
517
|
-
globalShortcut.register("CommandOrControl+Shift+X", () => {
|
|
518
|
-
if (mainWindow.isVisible()) {
|
|
519
|
-
mainWindow.hide();
|
|
520
|
-
} else {
|
|
521
|
-
mainWindow.show();
|
|
522
|
-
mainWindow.focus();
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
// Unregister on quit
|
|
528
|
-
app.on("will-quit", () => {
|
|
529
|
-
globalShortcut.unregisterAll();
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
### Power Monitor
|
|
535
|
-
|
|
536
|
-
```typescript
|
|
537
|
-
// main/power.ts
|
|
538
|
-
import { powerMonitor } from "electron";
|
|
539
|
-
|
|
540
|
-
export function initPowerMonitor() {
|
|
541
|
-
powerMonitor.on("suspend", () => {
|
|
542
|
-
console.log("System suspended - saving state");
|
|
543
|
-
// Save draft, pause sync, etc.
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
powerMonitor.on("resume", () => {
|
|
547
|
-
console.log("System resumed - checking for updates");
|
|
548
|
-
// Resume sync, check for updates
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
powerMonitor.on("on-battery", () => {
|
|
552
|
-
console.log("On battery - reducing background tasks");
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
powerMonitor.on("on-ac", () => {
|
|
556
|
-
console.log("On AC power - resuming normal operations");
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
### Notifications
|
|
562
|
-
|
|
563
|
-
```typescript
|
|
564
|
-
// main/notifications.ts
|
|
565
|
-
import { Notification } from "electron";
|
|
566
|
-
|
|
567
|
-
export function showNotification(title: string, body: string) {
|
|
568
|
-
if (!Notification.isSupported()) return;
|
|
569
|
-
|
|
570
|
-
new Notification({
|
|
571
|
-
title,
|
|
572
|
-
body,
|
|
573
|
-
icon: path.join(__dirname, "assets/icon.png"),
|
|
574
|
-
}).show();
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
// With actions (macOS)
|
|
578
|
-
export function showActionNotification(title: string, body: string) {
|
|
579
|
-
const notification = new Notification({
|
|
580
|
-
title,
|
|
581
|
-
body,
|
|
582
|
-
actions: [
|
|
583
|
-
{ text: "View", type: "button" },
|
|
584
|
-
{ text: "Dismiss", type: "button" },
|
|
585
|
-
],
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
notification.on("action", (_, index) => {
|
|
589
|
-
if (index === 0) {
|
|
590
|
-
// Handle View action
|
|
591
|
-
}
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
notification.show();
|
|
595
|
-
}
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
---
|
|
599
|
-
|
|
600
|
-
## 🔗 Deep Linking
|
|
601
|
-
|
|
602
|
-
```typescript
|
|
603
|
-
// main.ts
|
|
604
|
-
import { app, BrowserWindow } from "electron";
|
|
605
|
-
|
|
606
|
-
const PROTOCOL = "my-app";
|
|
607
|
-
|
|
608
|
-
// Register protocol
|
|
609
|
-
if (process.defaultApp) {
|
|
610
|
-
app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, [__dirname]);
|
|
611
|
-
} else {
|
|
612
|
-
app.setAsDefaultProtocolClient(PROTOCOL);
|
|
613
|
-
}
|
|
193
|
+
## 📚 Deep-Dive References
|
|
614
194
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
if (!gotTheLock) {
|
|
619
|
-
app.quit();
|
|
620
|
-
} else {
|
|
621
|
-
app.on("second-instance", (event, argv) => {
|
|
622
|
-
// Windows/Linux: URL in argv
|
|
623
|
-
const url = argv.find((arg) => arg.startsWith(`${PROTOCOL}://`));
|
|
624
|
-
if (url) handleDeepLink(url);
|
|
625
|
-
|
|
626
|
-
// Focus window
|
|
627
|
-
if (mainWindow) {
|
|
628
|
-
if (mainWindow.isMinimized()) mainWindow.restore();
|
|
629
|
-
mainWindow.focus();
|
|
630
|
-
}
|
|
631
|
-
});
|
|
632
|
-
|
|
633
|
-
// macOS: URL via open-url event
|
|
634
|
-
app.on("open-url", (event, url) => {
|
|
635
|
-
event.preventDefault();
|
|
636
|
-
handleDeepLink(url);
|
|
637
|
-
});
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
function handleDeepLink(url: string) {
|
|
641
|
-
const parsed = new URL(url);
|
|
642
|
-
console.log("Deep link:", parsed.pathname, parsed.searchParams);
|
|
643
|
-
// Route to appropriate view
|
|
644
|
-
}
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
---
|
|
195
|
+
- **IPC Communication & Testing** — Inter-process communication, testing patterns
|
|
196
|
+
→ See [references/ipc-testing.md](references/ipc-testing.md)
|
|
648
197
|
|
|
649
|
-
|
|
198
|
+
- **Auto Updates & Data Persistence** — electron-updater, SQLite, keytar, electron-store
|
|
199
|
+
→ See [references/updates-persistence.md](references/updates-persistence.md)
|
|
650
200
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
// main.ts
|
|
655
|
-
import { crashReporter } from "electron";
|
|
656
|
-
|
|
657
|
-
crashReporter.start({
|
|
658
|
-
productName: "MyApp",
|
|
659
|
-
submitURL: "https://your-crash-server.com/submit",
|
|
660
|
-
uploadToServer: true,
|
|
661
|
-
extra: {
|
|
662
|
-
app_version: app.getVersion(),
|
|
663
|
-
build_type: process.env.NODE_ENV,
|
|
664
|
-
},
|
|
665
|
-
});
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
### Sentry Integration
|
|
669
|
-
|
|
670
|
-
```typescript
|
|
671
|
-
// main.ts
|
|
672
|
-
import * as Sentry from "@sentry/electron/main";
|
|
201
|
+
- **Native Integrations & Deep Linking** — Tray, notifications, clipboard, protocol handlers
|
|
202
|
+
→ See [references/native-integrations.md](references/native-integrations.md)
|
|
673
203
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
release: app.getVersion(),
|
|
677
|
-
});
|
|
678
|
-
|
|
679
|
-
// preload.ts
|
|
680
|
-
import * as Sentry from "@sentry/electron/renderer";
|
|
681
|
-
|
|
682
|
-
Sentry.init({
|
|
683
|
-
dsn: "https://your-dsn@sentry.io/project",
|
|
684
|
-
});
|
|
685
|
-
```
|
|
686
|
-
|
|
687
|
-
---
|
|
688
|
-
|
|
689
|
-
## ⚡ Performance Optimization
|
|
690
|
-
|
|
691
|
-
### Lazy Window Loading
|
|
692
|
-
|
|
693
|
-
```typescript
|
|
694
|
-
// main/windows.ts
|
|
695
|
-
let settingsWindow: BrowserWindow | null = null;
|
|
696
|
-
|
|
697
|
-
export function getSettingsWindow(): BrowserWindow {
|
|
698
|
-
if (!settingsWindow || settingsWindow.isDestroyed()) {
|
|
699
|
-
settingsWindow = new BrowserWindow({
|
|
700
|
-
show: false,
|
|
701
|
-
webPreferences: { preload: settingsPreload },
|
|
702
|
-
});
|
|
703
|
-
settingsWindow.loadFile("settings.html");
|
|
704
|
-
}
|
|
705
|
-
return settingsWindow;
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
// Show when ready
|
|
709
|
-
ipcMain.handle("open-settings", () => {
|
|
710
|
-
const win = getSettingsWindow();
|
|
711
|
-
win.once("ready-to-show", () => win.show());
|
|
712
|
-
});
|
|
713
|
-
```
|
|
714
|
-
|
|
715
|
-
### Worker Threads for Heavy Tasks
|
|
716
|
-
|
|
717
|
-
```typescript
|
|
718
|
-
// main/workers/heavy-task.ts
|
|
719
|
-
import { Worker, isMainThread, parentPort } from "worker_threads";
|
|
720
|
-
|
|
721
|
-
if (!isMainThread && parentPort) {
|
|
722
|
-
parentPort.on("message", (data) => {
|
|
723
|
-
const result = processHeavyTask(data);
|
|
724
|
-
parentPort!.postMessage(result);
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
// main.ts
|
|
729
|
-
const worker = new Worker("./workers/heavy-task.js");
|
|
730
|
-
worker.postMessage(largeDataset);
|
|
731
|
-
worker.on("message", (result) => {
|
|
732
|
-
mainWindow.webContents.send("task:complete", result);
|
|
733
|
-
});
|
|
734
|
-
```
|
|
735
|
-
|
|
736
|
-
---
|
|
737
|
-
|
|
738
|
-
## ♿ Accessibility
|
|
739
|
-
|
|
740
|
-
```typescript
|
|
741
|
-
// main.ts
|
|
742
|
-
import { app } from "electron";
|
|
743
|
-
|
|
744
|
-
// Check if accessibility is enabled
|
|
745
|
-
if (app.accessibilitySupportEnabled) {
|
|
746
|
-
console.log("Accessibility support enabled");
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
// Enable programmatically if needed
|
|
750
|
-
app.setAccessibilitySupportEnabled(true);
|
|
751
|
-
|
|
752
|
-
// Inform renderer about accessibility state
|
|
753
|
-
ipcMain.handle("get-accessibility-state", () => {
|
|
754
|
-
return app.accessibilitySupportEnabled;
|
|
755
|
-
});
|
|
756
|
-
```
|
|
757
|
-
|
|
758
|
-
### Renderer Best Practices
|
|
759
|
-
|
|
760
|
-
```typescript
|
|
761
|
-
// Use semantic HTML and ARIA
|
|
762
|
-
<button
|
|
763
|
-
aria-label="Open file"
|
|
764
|
-
aria-keyshortcuts="Ctrl+O"
|
|
765
|
-
onClick={handleOpen}
|
|
766
|
-
>
|
|
767
|
-
Open
|
|
768
|
-
</button>
|
|
769
|
-
|
|
770
|
-
// Focus management
|
|
771
|
-
useEffect(() => {
|
|
772
|
-
if (isModalOpen) {
|
|
773
|
-
modalRef.current?.focus();
|
|
774
|
-
}
|
|
775
|
-
}, [isModalOpen]);
|
|
776
|
-
```
|
|
777
|
-
|
|
778
|
-
---
|
|
779
|
-
|
|
780
|
-
## 📁 Project Structure
|
|
781
|
-
|
|
782
|
-
```
|
|
783
|
-
my-electron-app/
|
|
784
|
-
├── src/
|
|
785
|
-
│ ├── main/ # Main process
|
|
786
|
-
│ │ ├── index.ts # Entry point
|
|
787
|
-
│ │ ├── ipc.ts # IPC handlers
|
|
788
|
-
│ │ ├── tray.ts # System tray
|
|
789
|
-
│ │ ├── shortcuts.ts # Global shortcuts
|
|
790
|
-
│ │ ├── updates.ts # Auto-updater
|
|
791
|
-
│ │ └── database.ts # SQLite
|
|
792
|
-
│ ├── preload/ # Preload scripts
|
|
793
|
-
│ │ ├── index.ts # Main preload
|
|
794
|
-
│ │ └── index.d.ts # Type declarations
|
|
795
|
-
│ └── renderer/ # Renderer (React/Vue)
|
|
796
|
-
│ ├── App.tsx
|
|
797
|
-
│ └── main.tsx
|
|
798
|
-
├── e2e/ # E2E tests
|
|
799
|
-
│ └── app.spec.ts
|
|
800
|
-
├── electron.vite.config.ts
|
|
801
|
-
├── electron-builder.json5
|
|
802
|
-
├── playwright.config.ts
|
|
803
|
-
└── package.json
|
|
804
|
-
```
|
|
805
|
-
|
|
806
|
-
---
|
|
204
|
+
- **Performance & Accessibility** — V8 optimization, memory, WCAG compliance
|
|
205
|
+
→ See [references/performance-accessibility.md](references/performance-accessibility.md)
|
|
807
206
|
|
|
808
207
|
## ✅ Best Practices Checklist
|
|
809
208
|
|
|
@@ -840,7 +239,7 @@ my-electron-app/
|
|
|
840
239
|
|
|
841
240
|
---
|
|
842
241
|
|
|
843
|
-
##
|
|
242
|
+
## 📌 HSA Integration
|
|
844
243
|
|
|
845
244
|
Data powered by HSA BM25 search engine. Query YAML data via skill search:
|
|
846
245
|
|
|
@@ -855,4 +254,4 @@ Data powered by HSA BM25 search engine. Query YAML data via skill search:
|
|
|
855
254
|
|
|
856
255
|
---
|
|
857
256
|
|
|
858
|
-
_DOMYH Awesome Code
|
|
257
|
+
_DOMYH Awesome Code Electron 35-40 HSA v1.0.0 2026_
|