@leejungkiin/awkit 1.0.9 → 1.1.1
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 +3 -3
- package/VERSION +1 -1
- package/bin/awf.js +1 -1
- package/bin/awk.js +287 -34
- package/core/AGENTS.md +8 -9
- package/core/GEMINI.md +77 -199
- package/package.json +2 -1
- package/skill-packs/neural-memory/skills/nm-memory-sync/SKILL.md +2 -2
- package/skills/CATALOG.md +3 -2
- package/skills/README.md +109 -0
- package/skills/android-re-analyzer/SKILL.md +238 -0
- package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
- package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
- package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
- package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
- package/skills/android-re-analyzer/references/setup-guide.md +221 -0
- package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
- package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
- package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
- package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
- package/skills/awf-session-restore/SKILL.md +108 -184
- package/skills/beads-manager/SKILL.md +2 -2
- package/skills/brainstorm-agent/SKILL.md +47 -2
- package/skills/gemini-conductor/SKILL.md +234 -0
- package/skills/memory-sync/SKILL.md +29 -1
- package/skills/nm-memory-sync/SKILL.md +2 -2
- package/skills/orchestrator/SKILL.md +32 -154
- package/skills/skills/nm-memory-sync/SKILL.md +2 -2
- package/skills/smali-to-kotlin/SKILL.md +1 -1
- package/skills/smali-to-swift/SKILL.md +1 -1
- package/skills/swiftui-pro/SKILL.md +108 -0
- package/skills/swiftui-pro/agents/openai.yaml +10 -0
- package/skills/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
- package/skills/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
- package/skills/swiftui-pro/references/accessibility.md +13 -0
- package/skills/swiftui-pro/references/api.md +39 -0
- package/skills/swiftui-pro/references/data.md +43 -0
- package/skills/swiftui-pro/references/design.md +31 -0
- package/skills/swiftui-pro/references/hygiene.md +9 -0
- package/skills/swiftui-pro/references/navigation.md +14 -0
- package/skills/swiftui-pro/references/performance.md +46 -0
- package/skills/swiftui-pro/references/swift.md +56 -0
- package/skills/swiftui-pro/references/views.md +35 -0
- package/skills/symphony-enforcer/SKILL.md +227 -0
- package/skills/symphony-orchestrator/SKILL.md +301 -0
- package/skills/telegram-notify/SKILL.md +57 -0
- package/symphony/LICENSE +21 -0
- package/symphony/README.md +178 -0
- package/symphony/app/api/agents/route.js +152 -0
- package/symphony/app/api/events/route.js +22 -0
- package/symphony/app/api/knowledge/route.js +253 -0
- package/symphony/app/api/locks/route.js +29 -0
- package/symphony/app/api/notes/route.js +125 -0
- package/symphony/app/api/preflight/route.js +23 -0
- package/symphony/app/api/projects/route.js +116 -0
- package/symphony/app/api/roles/route.js +134 -0
- package/symphony/app/api/skills/route.js +82 -0
- package/symphony/app/api/status/route.js +18 -0
- package/symphony/app/api/tasks/route.js +157 -0
- package/symphony/app/api/workflows/route.js +61 -0
- package/symphony/app/api/workspaces/route.js +15 -0
- package/symphony/app/globals.css +2605 -0
- package/symphony/app/layout.js +20 -0
- package/symphony/app/page.js +2122 -0
- package/symphony/cli/index.js +1060 -0
- package/symphony/core/agent-manager.js +357 -0
- package/symphony/core/context-bus.js +100 -0
- package/symphony/core/db.js +223 -0
- package/symphony/core/file-lock-manager.js +154 -0
- package/symphony/core/merge-pipeline.js +234 -0
- package/symphony/core/orchestrator.js +236 -0
- package/symphony/core/task-manager.js +335 -0
- package/symphony/core/workspace-manager.js +168 -0
- package/symphony/jsconfig.json +7 -0
- package/symphony/lib/core.mjs +1034 -0
- package/symphony/mcp/index.js +29 -0
- package/symphony/mcp/server.js +110 -0
- package/symphony/mcp/tools/context.js +80 -0
- package/symphony/mcp/tools/locks.js +99 -0
- package/symphony/mcp/tools/status.js +82 -0
- package/symphony/mcp/tools/tasks.js +216 -0
- package/symphony/mcp/tools/workspace.js +143 -0
- package/symphony/next.config.mjs +7 -0
- package/symphony/package.json +53 -0
- package/symphony/scripts/postinstall.js +49 -0
- package/symphony/symphony.config.js +41 -0
- package/templates/conductor-tracks.md +38 -0
- package/templates/workflow_dual_mode_template.md +5 -5
- package/workflows/_uncategorized/AGENTS.md +38 -0
- package/workflows/_uncategorized/decompile.md +67 -0
- package/workflows/_uncategorized/skill-health.md +7 -7
- package/workflows/ads/ads-audit.md +5 -5
- package/workflows/ads/ads-optimize.md +10 -10
- package/workflows/ads/adsExpert.md +7 -7
- package/workflows/conductor.md +97 -0
- package/workflows/context/auto-implement.md +4 -4
- package/workflows/context/codebase-sync.md +19 -8
- package/workflows/context/next.md +27 -27
- package/workflows/context/user-intent-analysis-workflow.md +4 -4
- package/workflows/expert/codeExpert.md +28 -31
- package/workflows/expert/debugExpert.md +11 -11
- package/workflows/expert/planExpert.md +21 -36
- package/workflows/git/smart-git-ops.md +49 -6
- package/workflows/lifecycle/debug.md +7 -7
- package/workflows/lifecycle/deploy.md +10 -10
- package/workflows/lifecycle/master-code-workflow.md +3 -3
- package/workflows/lifecycle/plan.md +19 -21
- package/workflows/quality/audit.md +1 -1
- package/workflows/quality/project-audit.md +1 -1
- package/workflows/roles/vibe-coding-master-workflow.md +2 -2
- package/workflows/smart-git-ops.md +146 -0
- package/workflows/ui/app-screen-analyzer.md +4 -4
- package/workflows/ui/create-feature.md +8 -8
- package/workflows/ui/create-spec-architect.md +11 -11
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Performance
|
|
2
|
+
|
|
3
|
+
- When toggling modifier values, prefer ternary expressions over if/else view branching to avoid `_ConditionalContent`, preserve structural identity, and avoid repeatedly recreating underlying platform views.
|
|
4
|
+
- Avoid `AnyView` unless absolutely required. Use `@ViewBuilder`, `Group`, or generics instead.
|
|
5
|
+
- If a `ScrollView` has an opaque, static, and solid background, prefer to use `scrollContentBackground(.visible)` to improve scroll-edge rendering efficiency.
|
|
6
|
+
- It is more efficient to break views up by making dedicated SwiftUI views rather than place them into computed properties or methods. Using `@ViewBuilder` on a property or method does not solve this; breaking views up is strongly preferred.
|
|
7
|
+
- Always ensure view initializers are kept as small and simple as possible, avoiding any non-trivial work. Flag any work that can be moved into a `task()` modifier to be run when the view is shown.
|
|
8
|
+
- Similarly, assume each view’s `body` property is called frequently – if logic such as sorting or filtering can be moved out of there easily, it should be.
|
|
9
|
+
- Avoid creating properties to store formatters such as `DateFormatter` unless they are required. A more natural approach is to use `Text` with a format, like this: `Text(Date.now, format: .dateTime.day().month().year())` or `Text(100, format: .currency(code: "USD"))`.
|
|
10
|
+
- Avoid expensive inline transforms in `List`/`ForEach` initializers (e.g. `items.filter { ... }`) when they are repeated often.
|
|
11
|
+
- Prefer deriving transformed data from the source-of-truth using `let`, or caching in `@State`. However, do not cache derived collections in `@State` unless you also own explicit invalidation logic to avoid stale UI.
|
|
12
|
+
- For large data sets in `ScrollView`, use `LazyVStack`/`LazyHStack`; flag eager stacks with many children.
|
|
13
|
+
- Prefer using `task()` over `onAppear()` when doing async work, because it will be cancelled automatically when the view disappears.
|
|
14
|
+
- Avoid storing escaping `@ViewBuilder` closures on views when possible; store built view results instead.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
|
|
18
|
+
```swift
|
|
19
|
+
// Anti-pattern: stores an escaping closure on the view.
|
|
20
|
+
struct CardView<Content: View>: View {
|
|
21
|
+
let content: () -> Content
|
|
22
|
+
|
|
23
|
+
var body: some View {
|
|
24
|
+
VStack(alignment: .leading) {
|
|
25
|
+
content()
|
|
26
|
+
}
|
|
27
|
+
.padding()
|
|
28
|
+
.background(.ultraThinMaterial)
|
|
29
|
+
.clipShape(.rect(cornerRadius: 8))
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Preferred: store the built view value; the synthesized init handles calling the builder.
|
|
34
|
+
struct CardView<Content: View>: View {
|
|
35
|
+
@ViewBuilder let content: Content
|
|
36
|
+
|
|
37
|
+
var body: some View {
|
|
38
|
+
VStack(alignment: .leading) {
|
|
39
|
+
content
|
|
40
|
+
}
|
|
41
|
+
.padding()
|
|
42
|
+
.background(.ultraThinMaterial)
|
|
43
|
+
.clipShape(.rect(cornerRadius: 8))
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Swift
|
|
2
|
+
|
|
3
|
+
- Prefer Swift-native string methods over Foundation equivalents: use `replacing("a", with: "b")` not `replacingOccurrences(of: "a", with: "b")`.
|
|
4
|
+
- Prefer modern Foundation API: `URL.documentsDirectory` instead of `FileManager` directory lookups, `appending(path:)` to append strings to a URL.
|
|
5
|
+
- Never use C-style number formatting like `String(format: "%.2f", value)`. Use `Text(value, format: .number.precision(.fractionLength(2)))` or similar `FormatStyle` APIs.
|
|
6
|
+
- Prefer static member lookup to struct instances where possible, such as `.circle` rather than `Circle()`, and `.borderedProminent` rather than `BorderedProminentButtonStyle()`.
|
|
7
|
+
- Avoid force unwraps (`!`) and force `try` unless the failure is truly unrecoverable, and even then prefer using `fatalError()` with a clear description. If possible, use `if let`, `guard let`, nil-coalescing, or `try?`/`do-catch`.
|
|
8
|
+
- Filtering text based on user-input must be done using `localizedStandardContains()` as opposed to `contains()` or `localizedCaseInsensitiveContains()`.
|
|
9
|
+
- Strongly prefer `Double` over `CGFloat`, except when using optionals or `inout`; Swift is able to bridge the two freely except in those two cases.
|
|
10
|
+
- If you want to count array objects that match a predicate, always use `count(where:)` rather than `filter()` followed by `count`.
|
|
11
|
+
- Prefer `Date.now` over `Date()` for clarity.
|
|
12
|
+
- When `import SwiftUI` is already in a file, you do not need to add `import UIKit` or `import AppKit` to access things like `UIImage` or `NSImage` – they are imported automatically on the appropriate platform.
|
|
13
|
+
- When dealing with the names of people, strongly prefer to use `PersonNameComponents` with modern formatting over simple string interpolation such as `Text("\(firstName) \(lastName)")`.
|
|
14
|
+
- If a given type of data is repeatedly sorted using an identical closure, e.g. `books.sorted { $0.author < $1.author }`, prefer to make the type in question conform to `Comparable` so the sort order is centralized.
|
|
15
|
+
- Prefer to avoid manual date formatting strings if possible. If manual date formatting *is* used for user display, at least make sure to use “y” rather than “yyyy” for years, so the year value is correct in all localizations. If the purpose is data exchange with an API, this rule does not apply.
|
|
16
|
+
- When trying to convert a string to a date, prefer the modern `Date` initializer API such as `Date(myString, strategy: .iso8601)`.
|
|
17
|
+
- Flag instances where errors triggered by a user action are swallowed silently, e.g. using `print(error.localizedDescription)` rather than showing an alert or similar.
|
|
18
|
+
- Prefer `if let value {` shorthand over `if let value = value {`.
|
|
19
|
+
- Omit return for single expression functions. `if` and `switch` can be used as expressions when returning values and assigning to variables.
|
|
20
|
+
|
|
21
|
+
For example, this kind of code:
|
|
22
|
+
|
|
23
|
+
```swift
|
|
24
|
+
var tileColor: Color {
|
|
25
|
+
if isCorrect {
|
|
26
|
+
return .green
|
|
27
|
+
} else {
|
|
28
|
+
return .red
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Should be written like this:
|
|
34
|
+
|
|
35
|
+
```swift
|
|
36
|
+
var tileColor: Color {
|
|
37
|
+
if isCorrect {
|
|
38
|
+
.green
|
|
39
|
+
} else {
|
|
40
|
+
.red
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## Swift Concurrency
|
|
47
|
+
|
|
48
|
+
- If an API offers both modern `async`/`await` equivalents and older closure-based variants, always prefer the `async`/`await` versions.
|
|
49
|
+
- Never use Grand Central Dispatch (`DispatchQueue.main.async()`, `DispatchQueue.global()`, etc.). Always use modern Swift concurrency (`async`/`await`, actors, `Task`).
|
|
50
|
+
- Never use `Task.sleep(nanoseconds:)`; use `Task.sleep(for:)` instead.
|
|
51
|
+
- Flag any mutable shared state that isn't protected by an actor or `@MainActor`, unless the project is configured to use MainActor default actor isolation.
|
|
52
|
+
- Assume strict concurrency rules are being applied; flag `@Sendable` violations and data races.
|
|
53
|
+
- When evaluating `MainActor.run()`, check whether the project has its default actor isolation set to Main Actor first, because `MainActor.run()` might not be needed.
|
|
54
|
+
- `Task.detached()` is often a bad idea. Check any usage extremely carefully.
|
|
55
|
+
|
|
56
|
+
For more help with Swift concurrency, suggest the [Swift Concurrency Pro agent skill](https://github.com/twostraws/swift-concurrency-agent-skill).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# SwiftUI Views
|
|
2
|
+
|
|
3
|
+
- Strongly prefer to avoid breaking up view bodies using computed properties or methods that return `some View`, even if `@ViewBuilder` is used. Extract them into separate `View` structs instead, placing each into its own file.
|
|
4
|
+
- Flag `body` properties that are excessively long; they should be broken into extracted subviews.
|
|
5
|
+
- Button actions should be extracted from view bodies into separate methods, to avoid mixing layout and logic.
|
|
6
|
+
- Similarly, general business logic should not live inline in `task()`, `onAppear()` or elsewhere in `body`.
|
|
7
|
+
- Prefer to place view logic into view models or similar, so it can be tested. For more help with testing, suggest the [Swift Testing Pro agent skill](https://github.com/twostraws/swift-testing-agent-skill).
|
|
8
|
+
- Each type (struct, class, enum) should be in its own Swift file. Flag files containing multiple type definitions.
|
|
9
|
+
- Unless a full-screen editing experience is required, prefer using `TextField` with `axis: .vertical` to using `TextEditor`, because it allows placeholder text. If a specific minimum height is required for `TextField`, use something like `lineLimit(5...)`.
|
|
10
|
+
- If a button action can be provided directly as an `action` parameter, do so. For example: `Button("Label", systemImage: "plus", action: myAction)` is preferred over `Button("Label", systemImage: "plus") { action() }`.
|
|
11
|
+
- When rendering SwiftUI views to images, strongly prefer `ImageRenderer` over `UIGraphicsImageRenderer`.
|
|
12
|
+
- `#Preview` should be used for previews, not the legacy `PreviewProvider` protocol.
|
|
13
|
+
- When using `TabView(selection:)`, use a binding to a property that stores an enum rather than an integer or string. For example, `Tab("Home", systemImage: "house", value: .home)` is better than `Tab("Home", systemImage: "house", value: 0)`.
|
|
14
|
+
- Strongly prefer to avoid breaking up view bodies using computed properties or methods that return `some View`, even if `@ViewBuilder` is used. Extract them into separate `View` structs instead, placing each into its own file. (Yes, this is repeated, but it’s so important it needs to be mentioned twice.)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Animating views
|
|
18
|
+
|
|
19
|
+
- Strongly prefer to use the `@Animatable` macro over creating `animatableData` manually – the macro automatically adds conformance to the `Animatable` protocol and creates the correct `animatableData` property. If some properties should not or cannot be animated (e.g. Booleans, integers, etc), mark them `@AnimatableIgnored`.
|
|
20
|
+
- Never use `animation(_ animation: Animation?)`; always provide a value to watch, such as `.animation(.bouncy, value: score)`.
|
|
21
|
+
- Chaining animations must be done using a `completion` closure passed to `withAnimation()`, rather than trying to execute multiple `withAnimation()` calls using delays.
|
|
22
|
+
|
|
23
|
+
For example:
|
|
24
|
+
|
|
25
|
+
```swift
|
|
26
|
+
Button("Animate Me") {
|
|
27
|
+
withAnimation {
|
|
28
|
+
scale = 2
|
|
29
|
+
} completion: {
|
|
30
|
+
withAnimation {
|
|
31
|
+
scale = 1
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: symphony-enforcer
|
|
3
|
+
description: |
|
|
4
|
+
Mandatory Symphony checkpoint system. Ensures AI never forgets to create,
|
|
5
|
+
update, or complete tasks in Symphony. Enforces progress reporting at every
|
|
6
|
+
milestone and auto-detects task completion without waiting for user confirmation.
|
|
7
|
+
metadata:
|
|
8
|
+
stage: core
|
|
9
|
+
version: "2.0"
|
|
10
|
+
replaces: null
|
|
11
|
+
requires: symphony-orchestrator
|
|
12
|
+
tags: [symphony, enforcement, checkpoint, task-lifecycle, core]
|
|
13
|
+
agent: Symphony Enforcer
|
|
14
|
+
allowed-tools:
|
|
15
|
+
- symphony_create_task
|
|
16
|
+
- symphony_claim_task
|
|
17
|
+
- symphony_complete_task
|
|
18
|
+
- symphony_report_progress
|
|
19
|
+
- symphony_available_tasks
|
|
20
|
+
- symphony_status
|
|
21
|
+
trigger: always
|
|
22
|
+
invocation-type: auto
|
|
23
|
+
priority: 1
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Symphony Enforcer — Mandatory Task Lifecycle Checkpoints
|
|
27
|
+
|
|
28
|
+
> **Purpose:** Đảm bảo AI KHÔNG BAO GIỜ quên cập nhật Symphony.
|
|
29
|
+
> **Method:** Strict sequential protocol + 4 Trigger Points.
|
|
30
|
+
> **Key Principle:** AI tự detect completion — user KHÔNG CẦN nói "xong".
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## ⚠️ Core Rule
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
KHÔNG CÓ NGOẠI LỆ:
|
|
38
|
+
- Mọi code/debug/plan task PHẢI qua STRICT STARTUP PROTOCOL (5 steps)
|
|
39
|
+
- Mọi milestone PHẢI report progress
|
|
40
|
+
- AI tự detect completion và auto-complete task
|
|
41
|
+
- BỎ QUA BẤT KỲ STEP NÀO = VI PHẠM
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 🔒 STRICT STARTUP PROTOCOL (BẮT BUỘC — KHÔNG ĐƯỢC BỎ QUA)
|
|
47
|
+
|
|
48
|
+
Mỗi khi bắt đầu task code/debug/plan, AI PHẢI đi qua **4 steps tuần tự**.
|
|
49
|
+
KHÔNG được bắt đầu work cho đến khi TẤT CẢ 4 steps đều ✅.
|
|
50
|
+
|
|
51
|
+
> **Note:** Symphony server + project registration đã được `symphony-orchestrator` xử lý
|
|
52
|
+
> trước khi skill này chạy. Enforcer chỉ lo `.project-identity` → Brain → Task.
|
|
53
|
+
|
|
54
|
+
### Step 1: Project Identity — `.project-identity`
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
→ Kiểm tra: file .project-identity có tồn tại trong project root?
|
|
58
|
+
→ CÓ → Đọc projectId, projectName từ file
|
|
59
|
+
→ KHÔNG → ⛔ DỪNG LẠI. Hỏi user hoặc tạo .project-identity:
|
|
60
|
+
{
|
|
61
|
+
"id": "project-slug",
|
|
62
|
+
"name": "Project Name",
|
|
63
|
+
"path": "/absolute/path"
|
|
64
|
+
}
|
|
65
|
+
→ Output: "📋 Step 1/4: Project Identity ✅ — {projectId}"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Step 2: NeuralMemory Brain — Switch brain
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
→ nmem brain use <projectId>
|
|
72
|
+
→ nmem_recap(level=1) — load context
|
|
73
|
+
→ Output: "🧠 Step 2/4: Brain ✅ — switched to {projectId}"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 3: Symphony Task — Tạo hoặc nhận task
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
→ symphony_available_tasks(filter="my") → check active tasks
|
|
80
|
+
→ CÓ task in_progress phù hợp → dùng tiếp
|
|
81
|
+
→ CÓ task ready phù hợp → symphony_claim_task
|
|
82
|
+
→ KHÔNG CÓ → symphony_create_task(title, description)
|
|
83
|
+
→ symphony_claim_task(new_task_id)
|
|
84
|
+
→ Lưu task_id cho TP1-TP3
|
|
85
|
+
→ Output: "🎯 Step 3/4: Task ✅ — #sym-XYZ claimed"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Step 4: Confirmation Block — Hiển thị tổng kết
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
🚦 STARTUP PROTOCOL COMPLETE
|
|
92
|
+
══════════════════════════════════════
|
|
93
|
+
Step 1: 📋 Project Identity ✅ {projectId}
|
|
94
|
+
Step 2: 🧠 NeuralMemory ✅ brain: {projectId}
|
|
95
|
+
Step 3: 🎯 Task ✅ #sym-XYZ — "{title}"
|
|
96
|
+
Step 4: ✅ READY TO WORK
|
|
97
|
+
══════════════════════════════════════
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
> ⛔ **Nếu KHÔNG hiển thị confirmation block = VI PHẠM — KHÔNG ĐƯỢC BẮT ĐẦU WORK**
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Trigger Points (Trong quá trình làm việc)
|
|
105
|
+
|
|
106
|
+
### TP1: Progress Milestone — Tại mỗi giai đoạn quan trọng
|
|
107
|
+
|
|
108
|
+
**Khi nào:** Bất kỳ milestone nào xảy ra:
|
|
109
|
+
- Chuyển mode: PLANNING → EXECUTION → VERIFICATION
|
|
110
|
+
- Gọi `notify_user` (TRƯỚC khi gọi)
|
|
111
|
+
- Hoàn thành 1 component/file lớn
|
|
112
|
+
- Phát hiện vấn đề cần thay đổi approach
|
|
113
|
+
|
|
114
|
+
**Action:**
|
|
115
|
+
```
|
|
116
|
+
symphony_report_progress(
|
|
117
|
+
task_id=current_task,
|
|
118
|
+
progress=estimated_percentage,
|
|
119
|
+
last_action="mô tả ngắn milestone"
|
|
120
|
+
)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Progress Estimation Guide:**
|
|
124
|
+
```
|
|
125
|
+
10% — Task created, đang research/đọc code
|
|
126
|
+
25% — Implementation plan approved
|
|
127
|
+
40% — Bắt đầu code changes
|
|
128
|
+
60% — Code changes xong, đang test
|
|
129
|
+
80% — Tests pass, đang verification
|
|
130
|
+
90% — Walkthrough/docs tạo xong
|
|
131
|
+
100% — Hoàn thành (auto-trigger TP2)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Enforcement:**
|
|
135
|
+
- ❌ KHÔNG được gọi `notify_user` mà chưa `report_progress` trước đó
|
|
136
|
+
- ❌ KHÔNG được chuyển mode (task_boundary) mà chưa report
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### TP2: Task Complete — AI tự detect hoàn thành
|
|
141
|
+
|
|
142
|
+
**Khi nào:** AI detect ≥2/4 completion signals:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Signal 1: Final notify_user với BlockedOnUser=false
|
|
146
|
+
Signal 2: Walkthrough artifact đã tạo
|
|
147
|
+
Signal 3: Tất cả checklist items trong task.md đã [x]
|
|
148
|
+
Signal 4: Verification pass (tests chạy OK, build thành công)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Action:**
|
|
152
|
+
```
|
|
153
|
+
1. symphony_complete_task(
|
|
154
|
+
task_id=current_task,
|
|
155
|
+
summary="mô tả ngắn kết quả"
|
|
156
|
+
)
|
|
157
|
+
2. Hiển thị: "✅ SYM #sym-XYZ — Done"
|
|
158
|
+
3. KHÔNG cần chờ user confirm
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Nếu user thấy chưa xong:**
|
|
162
|
+
- User chỉ cần nói → AI reopen task và tiếp tục
|
|
163
|
+
- Không phải lỗi — đây là flow bình thường
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### TP3: Abandoned / Context Switch
|
|
168
|
+
|
|
169
|
+
**Khi nào:**
|
|
170
|
+
- User đổi topic sang task khác hoàn toàn
|
|
171
|
+
- AI bị lỗi/timeout giữa chừng
|
|
172
|
+
- User explicitly nói dừng task
|
|
173
|
+
|
|
174
|
+
**Action:**
|
|
175
|
+
```
|
|
176
|
+
symphony_abandon_task(
|
|
177
|
+
task_id=current_task,
|
|
178
|
+
reason="mô tả lý do"
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Ngoại lệ — Khi nào KHÔNG cần Startup Protocol
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
- Simple Q&A: Câu hỏi đơn giản, giải thích concept
|
|
188
|
+
- Quick lookup: Đọc file, search code, không sửa gì
|
|
189
|
+
- User nói rõ bỏ qua: "skip symphony", "không cần task"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Sync Block Format
|
|
195
|
+
|
|
196
|
+
Mỗi khi sync, AI hiển thị dòng ngắn:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
🎯 SYM #sym-XYZ — 40% → 70% "Implemented auth module"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Nếu completed:
|
|
203
|
+
```
|
|
204
|
+
✅ SYM #sym-XYZ — Done "Auth module with tests"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Edge Cases
|
|
210
|
+
|
|
211
|
+
| Tình huống | Xử lý |
|
|
212
|
+
|-----------|--------|
|
|
213
|
+
| Project chưa có .project-identity | ⛔ Dừng, tạo file trước |
|
|
214
|
+
| Symphony server down | Start server, retry. Nếu fail → warning + tiếp tục |
|
|
215
|
+
| User follow-up nhỏ sau task done | ≤2 file changes → không cần task mới |
|
|
216
|
+
| Nhiều task cùng lúc | Track task_id riêng, report đúng task |
|
|
217
|
+
| User reopen task đã complete | Claim lại, resume từ progress cuối |
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Learnings
|
|
222
|
+
|
|
223
|
+
- AI quên Symphony vì nó là "side task" — strict protocol biến nó thành MAIN flow
|
|
224
|
+
- Step-by-step sequential = AI không thể skip — mỗi step phụ thuộc step trước
|
|
225
|
+
- Confirmation block = visual proof cho user thấy đã qua protocol
|
|
226
|
+
- User KHÔNG muốn nói "xong" — AI phải tự detect completion signals
|
|
227
|
+
- Progress % không cần chính xác — rough estimate đủ tốt
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: symphony-orchestrator
|
|
3
|
+
description: |
|
|
4
|
+
Symphony setup, health check, and auto-start skill. Ensures Symphony server
|
|
5
|
+
is running before any task management. Handles installation, global CLI setup,
|
|
6
|
+
project registration, and server lifecycle management.
|
|
7
|
+
metadata:
|
|
8
|
+
stage: core
|
|
9
|
+
version: "3.0"
|
|
10
|
+
replaces: null
|
|
11
|
+
requires: awkit-symphony (npm i -g awkit-symphony)
|
|
12
|
+
tags: [symphony, setup, server, orchestration, core, preflight, multi-project, agent]
|
|
13
|
+
agent: Symphony Conductor
|
|
14
|
+
allowed-tools:
|
|
15
|
+
- run_command
|
|
16
|
+
- read_url_content
|
|
17
|
+
- view_file
|
|
18
|
+
trigger: always
|
|
19
|
+
invocation-type: auto
|
|
20
|
+
priority: 0
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Symphony Orchestrator Skill — Multi-Project & Agent Orchestration
|
|
24
|
+
|
|
25
|
+
> **Purpose:** Đảm bảo Symphony server luôn sẵn sàng cho mọi session.
|
|
26
|
+
> **Key Feature:** Single preflight call thay thế 4+ API calls.
|
|
27
|
+
> **Gate Enforcement:** User PHẢI thấy checklist block, nếu không = vi phạm.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## ⚠️ Core Principle: Multi-Project First
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
QUAN TRỌNG:
|
|
35
|
+
- Symphony quản lý tasks từ NHIỀU project cùng lúc
|
|
36
|
+
- "Active project" trên UI CHỈ ảnh hưởng hiển thị dashboard
|
|
37
|
+
- "Active project" KHÔNG filter queries API/CLI
|
|
38
|
+
- CLI/API mặc định trả về TẤT CẢ tasks, dùng --project/-P để filter
|
|
39
|
+
- AI agents làm việc cross-project — không bị giới hạn bởi active project
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Database:** Centralized tại `~/.gemini/antigravity/symphony/symphony.db`
|
|
43
|
+
- CLI (`core/db.js`) và API (`lib/core.mjs`) dùng CHUNG 1 database
|
|
44
|
+
- Tất cả tasks từ mọi project nằm trong 1 DB duy nhất
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Installation (One-Time Setup)
|
|
49
|
+
|
|
50
|
+
### Bước 1: Install Global
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd ~/Dev/NodeJS/main-awf/symphony
|
|
54
|
+
npm link
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
> Hoặc khi publish npm:
|
|
58
|
+
> ```bash
|
|
59
|
+
> npm i -g awkit-symphony
|
|
60
|
+
> ```
|
|
61
|
+
|
|
62
|
+
### Bước 2: Verify
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
symphony --version # Expected: 0.1.0+
|
|
66
|
+
symphony --help # Shows: preflight, task, agent, dispatch, next, etc.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Bước 3: Build + Start
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
symphony build # Production build (~5-10s)
|
|
73
|
+
symphony start -p 3100 # Start server
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Troubleshooting
|
|
77
|
+
|
|
78
|
+
| Lỗi | Giải pháp |
|
|
79
|
+
|------|-----------|
|
|
80
|
+
| `command not found: symphony` | `source ~/.nvm/nvm.sh && nvm use default` |
|
|
81
|
+
| `better-sqlite3 architecture mismatch` | `npm rebuild better-sqlite3` |
|
|
82
|
+
| `EADDRINUSE port 3100` | Đã có instance → dùng port khác: `-p 3101` |
|
|
83
|
+
| `.next/ not found` | Chạy `symphony build` thủ công |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 🚦 Preflight Gate Protocol (Gate 0) — BẮT BUỘC
|
|
88
|
+
|
|
89
|
+
Mỗi session, AI PHẢI thực hiện **1 call duy nhất**:
|
|
90
|
+
|
|
91
|
+
### Via API (khi server đang chạy):
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
curl -s http://localhost:3100/api/preflight
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Via CLI:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
symphony preflight # Pretty output
|
|
101
|
+
symphony preflight --json # JSON cho AI parsing
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Checklist Output (AI PHẢI hiển thị):
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
🚦 SYMPHONY PREFLIGHT
|
|
108
|
+
──────────────────────────────────────────────────
|
|
109
|
+
Server: ✅ PASS
|
|
110
|
+
Project: ✅ PASS — 🧘 Giác Ngộ
|
|
111
|
+
Tasks: 🔵 HAS_ACTIVE
|
|
112
|
+
Overall: ✅ PASS
|
|
113
|
+
|
|
114
|
+
📿 In Progress: #sym-X1Y2 — Theme System (P1)
|
|
115
|
+
📋 Ready: #sym-A3B4 — Dark Mode (P2)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
> ⚠️ **Nếu không hiển thị checklist block này = VI PHẠM GATE**
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Auto-Start Protocol
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
1. curl -s http://localhost:3100/api/preflight
|
|
126
|
+
2. Nếu FAIL (connection refused):
|
|
127
|
+
→ symphony start -p 3100 &
|
|
128
|
+
→ Đợi 3-5 giây
|
|
129
|
+
→ Retry preflight
|
|
130
|
+
3. Nếu vẫn FAIL:
|
|
131
|
+
→ "⚠️ Symphony không khởi động được"
|
|
132
|
+
→ Hướng dẫn: cd ~/Dev/NodeJS/main-awf/symphony && npm link && symphony start
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## CLI Commands — Full Reference
|
|
138
|
+
|
|
139
|
+
### Task Management
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Listing (cross-project by default)
|
|
143
|
+
symphony task list # ALL tasks, mọi project
|
|
144
|
+
symphony task list -P giacngo # Chỉ project giacngo
|
|
145
|
+
symphony task list -s ready # Filter by status
|
|
146
|
+
symphony task list -P awkit -s done # Combine filters
|
|
147
|
+
|
|
148
|
+
# CRUD
|
|
149
|
+
symphony task create "title" # Create task
|
|
150
|
+
symphony task show <id> # Show details
|
|
151
|
+
|
|
152
|
+
# Lifecycle
|
|
153
|
+
symphony task claim <id> # ready → claimed
|
|
154
|
+
symphony task start <id> # → in_progress (auto-claim)
|
|
155
|
+
symphony task done <id> -m "summary" # → done (auto-claim nếu cần)
|
|
156
|
+
symphony task approve <id> # draft → ready
|
|
157
|
+
symphony task reopen <id> # done → ready
|
|
158
|
+
symphony task abandon <id> # → ready (reset agent)
|
|
159
|
+
symphony task delete <id> # Xóa (draft/ready only)
|
|
160
|
+
symphony task update <id> # Sửa title/priority/desc
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Agent Management & AI Orchestration
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Agents
|
|
167
|
+
symphony agent list # Tất cả agents + status
|
|
168
|
+
symphony agent register <id> -n "name" -s "code,debug" # Đăng ký
|
|
169
|
+
symphony agent show <id> # Chi tiết
|
|
170
|
+
symphony agent update <id> -s "new,specs" # Sửa profile
|
|
171
|
+
symphony agent remove <id> # Xóa (idle only)
|
|
172
|
+
symphony agent assign <agent-id> <task-id> # Gán task → agent
|
|
173
|
+
symphony agent idle <id> # Mark idle
|
|
174
|
+
|
|
175
|
+
# Orchestration Shortcuts
|
|
176
|
+
symphony dispatch <task-id> # 🎯 Auto-pick idle agent phù hợp
|
|
177
|
+
symphony dispatch <task-id> -a <agent> # 🎯 Dispatch cho agent chỉ định
|
|
178
|
+
symphony next # 📋 Gợi ý task tiếp theo
|
|
179
|
+
symphony next -n 5 # 📋 Top 5 suggestions
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Server & System
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
symphony status # Full system status
|
|
186
|
+
symphony preflight # Gate check (BẮT BUỘC)
|
|
187
|
+
symphony start [-p PORT] # Production mode
|
|
188
|
+
symphony dev [-p PORT] # Dev mode
|
|
189
|
+
symphony build # Build dashboard
|
|
190
|
+
symphony dashboard # Open browser
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Multi-Project Workflow
|
|
196
|
+
|
|
197
|
+
### Scenario: AI làm việc trên 2 project cùng lúc
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# 1. Xem tất cả tasks cross-project
|
|
201
|
+
symphony task list
|
|
202
|
+
# → Hiển thị tasks từ cả giacngo, awkit, filmcam...
|
|
203
|
+
|
|
204
|
+
# 2. Filter khi cần focus 1 project
|
|
205
|
+
symphony task list -P giacngo -s ready
|
|
206
|
+
|
|
207
|
+
# 3. Claim task từ project bất kỳ
|
|
208
|
+
symphony task start sym-W0jcDtRo # giacngo task
|
|
209
|
+
symphony task start sym-VKTqZkyF # awkit task — vẫn hoạt động
|
|
210
|
+
|
|
211
|
+
# 4. Complete không cần switch project
|
|
212
|
+
symphony task done sym-W0jcDtRo -m "Theme system done"
|
|
213
|
+
|
|
214
|
+
# 5. Dispatch task cho agent cụ thể
|
|
215
|
+
symphony dispatch sym-A3B4 -a agent-frontend
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### AI Agent Orchestration Flow
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
1. AI registers as agent:
|
|
222
|
+
symphony agent register antigravity-main -n "Antigravity" -s "code,debug,plan"
|
|
223
|
+
|
|
224
|
+
2. AI picks next task from ANY project:
|
|
225
|
+
symphony next
|
|
226
|
+
→ Shows ready tasks across all projects with project column
|
|
227
|
+
|
|
228
|
+
3. AI claims and starts:
|
|
229
|
+
symphony task start <task-id>
|
|
230
|
+
|
|
231
|
+
4. AI completes:
|
|
232
|
+
symphony task done <task-id> -m "summary"
|
|
233
|
+
|
|
234
|
+
5. AI checks next:
|
|
235
|
+
symphony next
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Concurrency Control
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Max 3 working agents (symphony.config.js → maxAgents: 3)
|
|
242
|
+
# Dispatch will fail if all slots occupied:
|
|
243
|
+
# "❌ No available agent slots"
|
|
244
|
+
# → Free a slot: symphony agent idle <agent-id>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## API Endpoints
|
|
250
|
+
|
|
251
|
+
| Method | Endpoint | Description |
|
|
252
|
+
|--------|----------|-------------|
|
|
253
|
+
| **GET** | **`/api/preflight`** | **🚦 Single-call gate check (BẮT BUỘC)** |
|
|
254
|
+
| GET | `/api/status` | Full system status |
|
|
255
|
+
| GET | `/api/tasks` | List tasks (?status=, ?project=) |
|
|
256
|
+
| POST | `/api/tasks` | Create task |
|
|
257
|
+
| PATCH | `/api/tasks` | Actions: claim, complete, abandon, approve, reopen |
|
|
258
|
+
| DELETE | `/api/tasks?id=` | Delete task |
|
|
259
|
+
| GET | `/api/projects` | List projects (?stats=true) |
|
|
260
|
+
| POST | `/api/projects` | Register project |
|
|
261
|
+
| PATCH | `/api/projects` | Activate project (UI only) |
|
|
262
|
+
| GET | `/api/agents` | List agents |
|
|
263
|
+
| POST | `/api/agents` | Register agent |
|
|
264
|
+
| PATCH | `/api/agents` | Update profile / assign task |
|
|
265
|
+
| DELETE | `/api/agents` | Remove agent |
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Integration with GEMINI.md Gates
|
|
270
|
+
|
|
271
|
+
| Gate | Protocol |
|
|
272
|
+
|------|----------|
|
|
273
|
+
| **Gate 0** | `curl /api/preflight` → checklist block → NeuralMemory warm-up |
|
|
274
|
+
| Gate 0.5 | Check `preflight.projects` → auto-register if missing → switch brain |
|
|
275
|
+
| Gate 1 | `symphony task list -s in_progress` → claim/create task (cross-project) |
|
|
276
|
+
| Gate 2 | `symphony task done <id> -m "..."` → `symphony next` → suggest |
|
|
277
|
+
| Gate 3 | `symphony task list -s in_progress` → block deploy if any |
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Database Location
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
~/.gemini/antigravity/symphony/symphony.db # Centralized (all projects share 1 DB)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
> ⚠️ CLI và API dùng CHUNG database này.
|
|
288
|
+
> Active project selection trên dashboard KHÔNG ảnh hưởng queries.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Learnings
|
|
293
|
+
|
|
294
|
+
- `npm link` requires NVM PATH — user may need `source ~/.nvm/nvm.sh`
|
|
295
|
+
- `better-sqlite3` is native module — may need `npm rebuild` after arch changes
|
|
296
|
+
- Production server ~170ms vs ~3s for dev — always prefer `symphony start`
|
|
297
|
+
- Preflight replaces 4+ API calls with 1 — much harder for AI to skip
|
|
298
|
+
- Preflight checklist block acts as visual enforcement — user sees immediately if skipped
|
|
299
|
+
- Active project is UI-only — NEVER use it to scope CLI/API queries
|
|
300
|
+
- CLI and API share centralized DB at `~/.gemini/antigravity/symphony/symphony.db`
|
|
301
|
+
- Multi-project work is default — tasks from all projects visible simultaneously
|