@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
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
## 📦 IPC Communication
|
|
2
|
+
|
|
3
|
+
### Main Process Handlers
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// main.ts
|
|
7
|
+
import { ipcMain, dialog, BrowserWindow } from "electron";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
|
|
10
|
+
// ✅ Schema validation
|
|
11
|
+
const SaveFileSchema = z.object({
|
|
12
|
+
path: z.string(),
|
|
13
|
+
content: z.string(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
ipcMain.handle("dialog:openFile", async (event) => {
|
|
17
|
+
const window = BrowserWindow.fromWebContents(event.sender);
|
|
18
|
+
if (!window) return null;
|
|
19
|
+
|
|
20
|
+
const result = await dialog.showOpenDialog(window, {
|
|
21
|
+
properties: ["openFile"],
|
|
22
|
+
filters: [{ name: "Text", extensions: ["txt", "md"] }],
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (result.canceled) return null;
|
|
26
|
+
return result.filePaths[0];
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
ipcMain.handle("file:save", async (event, data: unknown) => {
|
|
30
|
+
const parsed = SaveFileSchema.safeParse(data);
|
|
31
|
+
if (!parsed.success) {
|
|
32
|
+
throw new Error("Invalid data format");
|
|
33
|
+
}
|
|
34
|
+
// Save logic with validated data
|
|
35
|
+
return true;
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 🧪 Testing Patterns
|
|
42
|
+
|
|
43
|
+
### Unit Testing with Vitest
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// src/main/__tests__/validators.test.ts
|
|
47
|
+
import { describe, it, expect } from "vitest";
|
|
48
|
+
import { validateFilePath, sanitizeInput } from "../validators";
|
|
49
|
+
|
|
50
|
+
describe("Input Validation", () => {
|
|
51
|
+
it("rejects path traversal", () => {
|
|
52
|
+
expect(validateFilePath("../etc/passwd")).toBe(false);
|
|
53
|
+
expect(validateFilePath("..\\windows\\system32")).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("accepts valid paths", () => {
|
|
57
|
+
expect(validateFilePath("/home/user/documents/file.txt")).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("sanitizes HTML input", () => {
|
|
61
|
+
expect(sanitizeInput("<script>alert(1)</script>")).toBe("");
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### E2E Testing with Playwright
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// e2e/app.spec.ts
|
|
70
|
+
import { test, expect, _electron as electron } from "@playwright/test";
|
|
71
|
+
|
|
72
|
+
test("app launches and shows main window", async () => {
|
|
73
|
+
const app = await electron.launch({ args: ["./dist/main.js"] });
|
|
74
|
+
const window = await app.firstWindow();
|
|
75
|
+
|
|
76
|
+
await expect(window).toHaveTitle(/MyApp/);
|
|
77
|
+
|
|
78
|
+
// Test IPC communication
|
|
79
|
+
const result = await window.evaluate(() => {
|
|
80
|
+
return window.electronAPI.getVersion();
|
|
81
|
+
});
|
|
82
|
+
expect(result).toMatch(/\d+\.\d+\.\d+/);
|
|
83
|
+
|
|
84
|
+
await app.close();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("file dialog works", async () => {
|
|
88
|
+
const app = await electron.launch({ args: ["./dist/main.js"] });
|
|
89
|
+
const window = await app.firstWindow();
|
|
90
|
+
|
|
91
|
+
await window.click('button[data-testid="open-file"]');
|
|
92
|
+
// Dialog opens - mock or handle appropriately
|
|
93
|
+
|
|
94
|
+
await app.close();
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Playwright Config
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// playwright.config.ts
|
|
102
|
+
import { defineConfig } from "@playwright/test";
|
|
103
|
+
|
|
104
|
+
export default defineConfig({
|
|
105
|
+
testDir: "./e2e",
|
|
106
|
+
timeout: 30000,
|
|
107
|
+
use: {
|
|
108
|
+
trace: "on-first-retry",
|
|
109
|
+
},
|
|
110
|
+
projects: [{ name: "electron" }],
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
## 📦 Native Integrations
|
|
2
|
+
|
|
3
|
+
### System Tray
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// main/tray.ts
|
|
7
|
+
import { Tray, Menu, nativeImage, app, BrowserWindow } from "electron";
|
|
8
|
+
import path from "path";
|
|
9
|
+
|
|
10
|
+
let tray: Tray | null = null;
|
|
11
|
+
|
|
12
|
+
export function createTray(mainWindow: BrowserWindow) {
|
|
13
|
+
const icon = nativeImage.createFromPath(
|
|
14
|
+
path.join(__dirname, "assets/tray-icon.png"),
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
tray = new Tray(icon);
|
|
18
|
+
tray.setToolTip("MyApp");
|
|
19
|
+
|
|
20
|
+
const contextMenu = Menu.buildFromTemplate([
|
|
21
|
+
{ label: "Show", click: () => mainWindow.show() },
|
|
22
|
+
{ type: "separator" },
|
|
23
|
+
{ label: "Quit", click: () => app.quit() },
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
tray.setContextMenu(contextMenu);
|
|
27
|
+
|
|
28
|
+
// Click to show window
|
|
29
|
+
tray.on("click", () => {
|
|
30
|
+
mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Global Shortcuts
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// main/shortcuts.ts
|
|
39
|
+
import { globalShortcut, app, BrowserWindow } from "electron";
|
|
40
|
+
|
|
41
|
+
export function registerGlobalShortcuts(mainWindow: BrowserWindow) {
|
|
42
|
+
// Register when app is ready
|
|
43
|
+
app.whenReady().then(() => {
|
|
44
|
+
globalShortcut.register("CommandOrControl+Shift+X", () => {
|
|
45
|
+
if (mainWindow.isVisible()) {
|
|
46
|
+
mainWindow.hide();
|
|
47
|
+
} else {
|
|
48
|
+
mainWindow.show();
|
|
49
|
+
mainWindow.focus();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Unregister on quit
|
|
55
|
+
app.on("will-quit", () => {
|
|
56
|
+
globalShortcut.unregisterAll();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Power Monitor
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// main/power.ts
|
|
65
|
+
import { powerMonitor } from "electron";
|
|
66
|
+
|
|
67
|
+
export function initPowerMonitor() {
|
|
68
|
+
powerMonitor.on("suspend", () => {
|
|
69
|
+
console.log("System suspended - saving state");
|
|
70
|
+
// Save draft, pause sync, etc.
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
powerMonitor.on("resume", () => {
|
|
74
|
+
console.log("System resumed - checking for updates");
|
|
75
|
+
// Resume sync, check for updates
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
powerMonitor.on("on-battery", () => {
|
|
79
|
+
console.log("On battery - reducing background tasks");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
powerMonitor.on("on-ac", () => {
|
|
83
|
+
console.log("On AC power - resuming normal operations");
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Notifications
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// main/notifications.ts
|
|
92
|
+
import { Notification } from "electron";
|
|
93
|
+
|
|
94
|
+
export function showNotification(title: string, body: string) {
|
|
95
|
+
if (!Notification.isSupported()) return;
|
|
96
|
+
|
|
97
|
+
new Notification({
|
|
98
|
+
title,
|
|
99
|
+
body,
|
|
100
|
+
icon: path.join(__dirname, "assets/icon.png"),
|
|
101
|
+
}).show();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// With actions (macOS)
|
|
105
|
+
export function showActionNotification(title: string, body: string) {
|
|
106
|
+
const notification = new Notification({
|
|
107
|
+
title,
|
|
108
|
+
body,
|
|
109
|
+
actions: [
|
|
110
|
+
{ text: "View", type: "button" },
|
|
111
|
+
{ text: "Dismiss", type: "button" },
|
|
112
|
+
],
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
notification.on("action", (_, index) => {
|
|
116
|
+
if (index === 0) {
|
|
117
|
+
// Handle View action
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
notification.show();
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 🔗 Deep Linking
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// main.ts
|
|
131
|
+
import { app, BrowserWindow } from "electron";
|
|
132
|
+
|
|
133
|
+
const PROTOCOL = "my-app";
|
|
134
|
+
|
|
135
|
+
// Register protocol
|
|
136
|
+
if (process.defaultApp) {
|
|
137
|
+
app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, [__dirname]);
|
|
138
|
+
} else {
|
|
139
|
+
app.setAsDefaultProtocolClient(PROTOCOL);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Single instance lock
|
|
143
|
+
const gotTheLock = app.requestSingleInstanceLock();
|
|
144
|
+
|
|
145
|
+
if (!gotTheLock) {
|
|
146
|
+
app.quit();
|
|
147
|
+
} else {
|
|
148
|
+
app.on("second-instance", (event, argv) => {
|
|
149
|
+
// Windows/Linux: URL in argv
|
|
150
|
+
const url = argv.find((arg) => arg.startsWith(`${PROTOCOL}://`));
|
|
151
|
+
if (url) handleDeepLink(url);
|
|
152
|
+
|
|
153
|
+
// Focus window
|
|
154
|
+
if (mainWindow) {
|
|
155
|
+
if (mainWindow.isMinimized()) mainWindow.restore();
|
|
156
|
+
mainWindow.focus();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// macOS: URL via open-url event
|
|
161
|
+
app.on("open-url", (event, url) => {
|
|
162
|
+
event.preventDefault();
|
|
163
|
+
handleDeepLink(url);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function handleDeepLink(url: string) {
|
|
168
|
+
const parsed = new URL(url);
|
|
169
|
+
console.log("Deep link:", parsed.pathname, parsed.searchParams);
|
|
170
|
+
// Route to appropriate view
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 💥 Crash Reporting
|
|
177
|
+
|
|
178
|
+
### Built-in crashReporter
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// main.ts
|
|
182
|
+
import { crashReporter } from "electron";
|
|
183
|
+
|
|
184
|
+
crashReporter.start({
|
|
185
|
+
productName: "MyApp",
|
|
186
|
+
submitURL: "https://your-crash-server.com/submit",
|
|
187
|
+
uploadToServer: true,
|
|
188
|
+
extra: {
|
|
189
|
+
app_version: app.getVersion(),
|
|
190
|
+
build_type: process.env.NODE_ENV,
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Sentry Integration
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// main.ts
|
|
199
|
+
import * as Sentry from "@sentry/electron/main";
|
|
200
|
+
|
|
201
|
+
Sentry.init({
|
|
202
|
+
dsn: "https://your-dsn@sentry.io/project",
|
|
203
|
+
release: app.getVersion(),
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// preload.ts
|
|
207
|
+
import * as Sentry from "@sentry/electron/renderer";
|
|
208
|
+
|
|
209
|
+
Sentry.init({
|
|
210
|
+
dsn: "https://your-dsn@sentry.io/project",
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## ⚡ Performance Optimization
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
## ⚡ Performance Optimization
|
|
2
|
+
|
|
3
|
+
### Lazy Window Loading
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// main/windows.ts
|
|
7
|
+
let settingsWindow: BrowserWindow | null = null;
|
|
8
|
+
|
|
9
|
+
export function getSettingsWindow(): BrowserWindow {
|
|
10
|
+
if (!settingsWindow || settingsWindow.isDestroyed()) {
|
|
11
|
+
settingsWindow = new BrowserWindow({
|
|
12
|
+
show: false,
|
|
13
|
+
webPreferences: { preload: settingsPreload },
|
|
14
|
+
});
|
|
15
|
+
settingsWindow.loadFile("settings.html");
|
|
16
|
+
}
|
|
17
|
+
return settingsWindow;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Show when ready
|
|
21
|
+
ipcMain.handle("open-settings", () => {
|
|
22
|
+
const win = getSettingsWindow();
|
|
23
|
+
win.once("ready-to-show", () => win.show());
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Worker Threads for Heavy Tasks
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// main/workers/heavy-task.ts
|
|
31
|
+
import { Worker, isMainThread, parentPort } from "worker_threads";
|
|
32
|
+
|
|
33
|
+
if (!isMainThread && parentPort) {
|
|
34
|
+
parentPort.on("message", (data) => {
|
|
35
|
+
const result = processHeavyTask(data);
|
|
36
|
+
parentPort!.postMessage(result);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// main.ts
|
|
41
|
+
const worker = new Worker("./workers/heavy-task.js");
|
|
42
|
+
worker.postMessage(largeDataset);
|
|
43
|
+
worker.on("message", (result) => {
|
|
44
|
+
mainWindow.webContents.send("task:complete", result);
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## ♿ Accessibility
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// main.ts
|
|
54
|
+
import { app } from "electron";
|
|
55
|
+
|
|
56
|
+
// Check if accessibility is enabled
|
|
57
|
+
if (app.accessibilitySupportEnabled) {
|
|
58
|
+
console.log("Accessibility support enabled");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Enable programmatically if needed
|
|
62
|
+
app.setAccessibilitySupportEnabled(true);
|
|
63
|
+
|
|
64
|
+
// Inform renderer about accessibility state
|
|
65
|
+
ipcMain.handle("get-accessibility-state", () => {
|
|
66
|
+
return app.accessibilitySupportEnabled;
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Renderer Best Practices
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// Use semantic HTML and ARIA
|
|
74
|
+
<button
|
|
75
|
+
aria-label="Open file"
|
|
76
|
+
aria-keyshortcuts="Ctrl+O"
|
|
77
|
+
onClick={handleOpen}
|
|
78
|
+
>
|
|
79
|
+
Open
|
|
80
|
+
</button>
|
|
81
|
+
|
|
82
|
+
// Focus management
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (isModalOpen) {
|
|
85
|
+
modalRef.current?.focus();
|
|
86
|
+
}
|
|
87
|
+
}, [isModalOpen]);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 📦 Project Structure
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
my-electron-app/
|
|
96
|
+
src/
|
|
97
|
+
main/ # Main process
|
|
98
|
+
index.ts # Entry point
|
|
99
|
+
ipc.ts # IPC handlers
|
|
100
|
+
tray.ts # System tray
|
|
101
|
+
shortcuts.ts # Global shortcuts
|
|
102
|
+
updates.ts # Auto-updater
|
|
103
|
+
database.ts # SQLite
|
|
104
|
+
preload/ # Preload scripts
|
|
105
|
+
index.ts # Main preload
|
|
106
|
+
index.d.ts # Type declarations
|
|
107
|
+
renderer/ # Renderer (React/Vue)
|
|
108
|
+
App.tsx
|
|
109
|
+
main.tsx
|
|
110
|
+
e2e/ # E2E tests
|
|
111
|
+
app.spec.ts
|
|
112
|
+
electron.vite.config.ts
|
|
113
|
+
electron-builder.json5
|
|
114
|
+
playwright.config.ts
|
|
115
|
+
package.json
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
## 📦 Auto Updates
|
|
2
|
+
|
|
3
|
+
### electron-updater Setup
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// main.ts
|
|
7
|
+
import { autoUpdater } from "electron-updater";
|
|
8
|
+
import { app, dialog, BrowserWindow } from "electron";
|
|
9
|
+
import log from "electron-log";
|
|
10
|
+
|
|
11
|
+
// Configure logging
|
|
12
|
+
autoUpdater.logger = log;
|
|
13
|
+
autoUpdater.autoDownload = false;
|
|
14
|
+
|
|
15
|
+
export function initAutoUpdater(mainWindow: BrowserWindow) {
|
|
16
|
+
// Check for updates on launch
|
|
17
|
+
autoUpdater.checkForUpdatesAndNotify();
|
|
18
|
+
|
|
19
|
+
autoUpdater.on("checking-for-update", () => {
|
|
20
|
+
log.info("Checking for update...");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
autoUpdater.on("update-available", (info) => {
|
|
24
|
+
dialog
|
|
25
|
+
.showMessageBox(mainWindow, {
|
|
26
|
+
type: "info",
|
|
27
|
+
title: "Update Available",
|
|
28
|
+
message: `Version ${info.version} is available. Download now?`,
|
|
29
|
+
buttons: ["Download", "Later"],
|
|
30
|
+
})
|
|
31
|
+
.then(({ response }) => {
|
|
32
|
+
if (response === 0) autoUpdater.downloadUpdate();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
autoUpdater.on("download-progress", (progress) => {
|
|
37
|
+
mainWindow.webContents.send("update:progress", progress.percent);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
autoUpdater.on("update-downloaded", (info) => {
|
|
41
|
+
dialog
|
|
42
|
+
.showMessageBox(mainWindow, {
|
|
43
|
+
type: "info",
|
|
44
|
+
title: "Update Ready",
|
|
45
|
+
message: `Version ${info.version} is ready. Restart to apply?`,
|
|
46
|
+
buttons: ["Restart", "Later"],
|
|
47
|
+
})
|
|
48
|
+
.then(({ response }) => {
|
|
49
|
+
if (response === 0) autoUpdater.quitAndInstall();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
autoUpdater.on("error", (err) => {
|
|
54
|
+
log.error("Auto-update error:", err);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Code Signing (macOS)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# macOS notarization
|
|
63
|
+
npx electron-builder --mac --publish always
|
|
64
|
+
|
|
65
|
+
# Required environment variables
|
|
66
|
+
export APPLE_ID="your@email.com"
|
|
67
|
+
export APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
|
|
68
|
+
export APPLE_TEAM_ID="XXXXXXXXXX"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 💾 Data Persistence
|
|
74
|
+
|
|
75
|
+
### better-sqlite3 (Best for Desktop)
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// main/database.ts
|
|
79
|
+
import Database from "better-sqlite3";
|
|
80
|
+
import path from "path";
|
|
81
|
+
import { app } from "electron";
|
|
82
|
+
|
|
83
|
+
const dbPath = path.join(app.getPath("userData"), "app.db");
|
|
84
|
+
const db = new Database(dbPath);
|
|
85
|
+
|
|
86
|
+
// Enable WAL mode for better concurrent performance
|
|
87
|
+
db.pragma("journal_mode = WAL");
|
|
88
|
+
|
|
89
|
+
// Initialize schema
|
|
90
|
+
db.exec(`
|
|
91
|
+
CREATE TABLE IF NOT EXISTS settings (
|
|
92
|
+
key TEXT PRIMARY KEY,
|
|
93
|
+
value TEXT NOT NULL
|
|
94
|
+
)
|
|
95
|
+
`);
|
|
96
|
+
|
|
97
|
+
// Type-safe operations
|
|
98
|
+
export const settings = {
|
|
99
|
+
get: db.prepare("SELECT value FROM settings WHERE key = ?"),
|
|
100
|
+
set: db.prepare("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)"),
|
|
101
|
+
};
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### electron-store (Simple Key-Value)
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// main/store.ts
|
|
108
|
+
import Store from "electron-store";
|
|
109
|
+
|
|
110
|
+
interface AppSettings {
|
|
111
|
+
theme: "light" | "dark" | "system";
|
|
112
|
+
windowBounds?: { width: number; height: number; x: number; y: number };
|
|
113
|
+
recentFiles: string[];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const store = new Store<AppSettings>({
|
|
117
|
+
defaults: {
|
|
118
|
+
theme: "system",
|
|
119
|
+
recentFiles: [],
|
|
120
|
+
},
|
|
121
|
+
encryptionKey: process.env.STORE_ENCRYPTION_KEY, // Optional
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
export function getSetting<K extends keyof AppSettings>(
|
|
125
|
+
key: K,
|
|
126
|
+
): AppSettings[K] {
|
|
127
|
+
return store.get(key);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function setSetting<K extends keyof AppSettings>(
|
|
131
|
+
key: K,
|
|
132
|
+
value: AppSettings[K],
|
|
133
|
+
) {
|
|
134
|
+
store.set(key, value);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### safeStorage (Sensitive Data)
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// main/secrets.ts
|
|
142
|
+
import { safeStorage } from "electron";
|
|
143
|
+
import fs from "fs";
|
|
144
|
+
import path from "path";
|
|
145
|
+
import { app } from "electron";
|
|
146
|
+
|
|
147
|
+
const secretsPath = path.join(app.getPath("userData"), "secrets.enc");
|
|
148
|
+
|
|
149
|
+
export function storeSecret(key: string, value: string) {
|
|
150
|
+
if (!safeStorage.isEncryptionAvailable()) {
|
|
151
|
+
throw new Error("Encryption not available");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const encrypted = safeStorage.encryptString(`${key}:${value}`);
|
|
155
|
+
// Append to secrets file or use a database
|
|
156
|
+
fs.appendFileSync(secretsPath, encrypted);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function getSecret(key: string): string | null {
|
|
160
|
+
// Implementation to retrieve and decrypt
|
|
161
|
+
// ...
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: skill-creator
|
|
2
|
+
version: "6.2.7"
|
|
3
|
+
display: Skill Creator
|
|
4
|
+
category: cross-cutting
|
|
5
|
+
tier: 2
|
|
6
|
+
priority: 4
|
|
7
|
+
|
|
8
|
+
desc: "Meta-skill for creating new domyh-awf skills with proper schema, structure, and progressive disclosure."
|
|
9
|
+
|
|
10
|
+
trigger_desc: |
|
|
11
|
+
Activate when user wants to create a new skill, scaffold a skill template,
|
|
12
|
+
or understand the skill system schema. Guides through META.yaml creation,
|
|
13
|
+
SKILL.md authoring, and data file organization.
|
|
14
|
+
|
|
15
|
+
triggers:
|
|
16
|
+
keywords:
|
|
17
|
+
- create skill
|
|
18
|
+
- new skill
|
|
19
|
+
- skill template
|
|
20
|
+
- scaffold skill
|
|
21
|
+
- META.yaml schema
|
|
22
|
+
- skill structure
|
|
23
|
+
intents:
|
|
24
|
+
- "create a new skill"
|
|
25
|
+
- "make a skill for"
|
|
26
|
+
- "skill template"
|
|
27
|
+
- "skill schema reference"
|
|
28
|
+
|
|
29
|
+
caps:
|
|
30
|
+
- Skill scaffolding
|
|
31
|
+
- META.yaml v2 schema
|
|
32
|
+
- Progressive disclosure patterns
|
|
33
|
+
- SKILL.md authoring guide
|
|
34
|
+
|
|
35
|
+
related_skills:
|
|
36
|
+
- coding-rules
|
|
37
|
+
- audit-pro
|