claude-code-pilot 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/bin/install.js +20 -2
- package/manifest.json +5 -1
- package/package.json +18 -6
- package/src/agents/a11y-architect.md +141 -0
- package/src/agents/code-architect.md +71 -0
- package/src/agents/code-explorer.md +69 -0
- package/src/agents/code-simplifier.md +47 -0
- package/src/agents/comment-analyzer.md +45 -0
- package/src/agents/csharp-reviewer.md +101 -0
- package/src/agents/dart-build-resolver.md +201 -0
- package/src/agents/pr-test-analyzer.md +45 -0
- package/src/agents/silent-failure-hunter.md +50 -0
- package/src/agents/type-design-analyzer.md +41 -0
- package/src/available-rules/README.md +3 -1
- package/src/available-rules/dart/coding-style.md +159 -0
- package/src/available-rules/dart/hooks.md +66 -0
- package/src/available-rules/dart/patterns.md +261 -0
- package/src/available-rules/dart/security.md +135 -0
- package/src/available-rules/dart/testing.md +215 -0
- package/src/available-rules/web/coding-style.md +105 -0
- package/src/available-rules/web/design-quality.md +72 -0
- package/src/available-rules/web/hooks.md +129 -0
- package/src/available-rules/web/patterns.md +88 -0
- package/src/available-rules/web/performance.md +73 -0
- package/src/available-rules/web/security.md +66 -0
- package/src/available-rules/web/testing.md +64 -0
- package/src/commands/ccp/ai-integration-phase.md +36 -0
- package/src/commands/ccp/audit-fix.md +33 -0
- package/src/commands/ccp/code-review-fix.md +52 -0
- package/src/commands/ccp/eval-review.md +32 -0
- package/src/commands/ccp/extract_learnings.md +22 -0
- package/src/commands/ccp/import.md +37 -0
- package/src/commands/ccp/ingest-docs.md +42 -0
- package/src/commands/ccp/intel.md +179 -0
- package/src/commands/ccp/plan-review-convergence.md +58 -0
- package/src/commands/ccp/scan.md +26 -0
- package/src/commands/ccp/sketch-wrap-up.md +31 -0
- package/src/commands/ccp/sketch.md +54 -0
- package/src/commands/ccp/spec-phase.md +62 -0
- package/src/commands/ccp/spike-wrap-up.md +31 -0
- package/src/commands/ccp/spike.md +51 -0
- package/src/commands/ccp/ultraplan-phase.md +33 -0
- package/src/hooks/ccp-read-injection-scanner.js +152 -0
- package/src/hooks/kit-check-update.js +59 -7
- package/src/hooks/run-with-flags-shell.sh +1 -0
- package/src/hooks/run-with-flags.js +48 -1
- package/src/hooks/session-end.js +88 -1
- package/src/lib/hook-flags.js +14 -0
- package/src/pilot/references/agent-contracts.md +79 -0
- package/src/pilot/references/ai-evals.md +156 -0
- package/src/pilot/references/ai-frameworks.md +186 -0
- package/src/pilot/references/doc-conflict-engine.md +91 -0
- package/src/pilot/references/gate-prompts.md +100 -0
- package/src/pilot/references/gates.md +70 -0
- package/src/pilot/references/mandatory-initial-read.md +2 -0
- package/src/pilot/references/project-skills-discovery.md +19 -0
- package/src/pilot/references/revision-loop.md +97 -0
- package/src/pilot/references/sketch-interactivity.md +41 -0
- package/src/pilot/references/sketch-theme-system.md +94 -0
- package/src/pilot/references/sketch-tooling.md +45 -0
- package/src/pilot/references/sketch-variant-patterns.md +81 -0
- package/src/pilot/references/thinking-models-debug.md +44 -0
- package/src/pilot/references/thinking-models-execution.md +50 -0
- package/src/pilot/references/thinking-models-planning.md +62 -0
- package/src/pilot/references/thinking-models-research.md +50 -0
- package/src/pilot/references/thinking-models-verification.md +55 -0
- package/src/pilot/templates/AI-SPEC.md +246 -0
- package/src/pilot/templates/spec.md +307 -0
- package/src/pilot/workflows/ai-integration-phase.md +284 -0
- package/src/pilot/workflows/audit-fix.md +175 -0
- package/src/pilot/workflows/code-review-fix.md +497 -0
- package/src/pilot/workflows/eval-review.md +155 -0
- package/src/pilot/workflows/extract_learnings.md +242 -0
- package/src/pilot/workflows/import.md +246 -0
- package/src/pilot/workflows/ingest-docs.md +328 -0
- package/src/pilot/workflows/plan-review-convergence.md +329 -0
- package/src/pilot/workflows/scan.md +102 -0
- package/src/pilot/workflows/sketch-wrap-up.md +285 -0
- package/src/pilot/workflows/sketch.md +360 -0
- package/src/pilot/workflows/spec-phase.md +262 -0
- package/src/pilot/workflows/spike-wrap-up.md +306 -0
- package/src/pilot/workflows/spike.md +452 -0
- package/src/pilot/workflows/ultraplan-phase.md +189 -0
- package/src/skills/accessibility/SKILL.md +146 -0
- package/src/skills/agent-eval/SKILL.md +145 -0
- package/src/skills/agent-introspection-debugging/SKILL.md +153 -0
- package/src/skills/android-clean-architecture/SKILL.md +339 -0
- package/src/skills/api-connector-builder/SKILL.md +120 -0
- package/src/skills/code-tour/SKILL.md +236 -0
- package/src/skills/compose-multiplatform-patterns/SKILL.md +299 -0
- package/src/skills/csharp-testing/SKILL.md +321 -0
- package/src/skills/dart-flutter-patterns/SKILL.md +563 -0
- package/src/skills/dashboard-builder/SKILL.md +108 -0
- package/src/skills/dotnet-patterns/SKILL.md +321 -0
- package/src/skills/frontend-design/SKILL.md +145 -0
- package/src/skills/frontend-slides/SKILL.md +184 -0
- package/src/skills/frontend-slides/STYLE_PRESETS.md +330 -0
- package/src/skills/gateguard/SKILL.md +121 -0
- package/src/skills/github-ops/SKILL.md +144 -0
- package/src/skills/hookify-rules/SKILL.md +128 -0
- package/src/skills/knowledge-ops/SKILL.md +154 -0
- package/src/skills/liquid-glass-design/SKILL.md +279 -0
- package/src/skills/nestjs-patterns/SKILL.md +230 -0
- package/src/skills/security-bounty-hunter/SKILL.md +99 -0
- package/src/skills/swift-actor-persistence/SKILL.md +143 -0
- package/src/skills/swift-protocol-di-testing/SKILL.md +190 -0
- package/src/skills/swiftui-patterns/SKILL.md +259 -0
- package/src/skills/terminal-ops/SKILL.md +109 -0
- package/src/skills/ui-demo/SKILL.md +465 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hookify-rules
|
|
3
|
+
description: This skill should be used when the user asks to create a hookify rule, write a hook rule, configure hookify, add a hookify rule, or needs guidance on hookify rule syntax and patterns.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Writing Hookify Rules
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Hookify rules are markdown files with YAML frontmatter that define patterns to watch for and messages to show when those patterns match. Rules are stored in `.claude/hookify.{rule-name}.local.md` files.
|
|
11
|
+
|
|
12
|
+
## Rule File Format
|
|
13
|
+
|
|
14
|
+
### Basic Structure
|
|
15
|
+
|
|
16
|
+
```markdown
|
|
17
|
+
---
|
|
18
|
+
name: rule-identifier
|
|
19
|
+
enabled: true
|
|
20
|
+
event: bash|file|stop|prompt|all
|
|
21
|
+
pattern: regex-pattern-here
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
Message to show Claude when this rule triggers.
|
|
25
|
+
Can include markdown formatting, warnings, suggestions, etc.
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Frontmatter Fields
|
|
29
|
+
|
|
30
|
+
| Field | Required | Values | Description |
|
|
31
|
+
|-------|----------|--------|-------------|
|
|
32
|
+
| name | Yes | kebab-case string | Unique identifier (verb-first: warn-*, block-*, require-*) |
|
|
33
|
+
| enabled | Yes | true/false | Toggle without deleting |
|
|
34
|
+
| event | Yes | bash/file/stop/prompt/all | Which hook event triggers this |
|
|
35
|
+
| action | No | warn/block | warn (default) shows message; block prevents operation |
|
|
36
|
+
| pattern | Yes* | regex string | Pattern to match (*or use conditions for complex rules) |
|
|
37
|
+
|
|
38
|
+
### Advanced Format (Multiple Conditions)
|
|
39
|
+
|
|
40
|
+
```markdown
|
|
41
|
+
---
|
|
42
|
+
name: warn-env-api-keys
|
|
43
|
+
enabled: true
|
|
44
|
+
event: file
|
|
45
|
+
conditions:
|
|
46
|
+
- field: file_path
|
|
47
|
+
operator: regex_match
|
|
48
|
+
pattern: \.env$
|
|
49
|
+
- field: new_text
|
|
50
|
+
operator: contains
|
|
51
|
+
pattern: API_KEY
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
You're adding an API key to a .env file. Ensure this file is in .gitignore!
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Condition fields by event:**
|
|
58
|
+
- bash: `command`
|
|
59
|
+
- file: `file_path`, `new_text`, `old_text`, `content`
|
|
60
|
+
- prompt: `user_prompt`
|
|
61
|
+
|
|
62
|
+
**Operators:** `regex_match`, `contains`, `equals`, `not_contains`, `starts_with`, `ends_with`
|
|
63
|
+
|
|
64
|
+
All conditions must match for rule to trigger.
|
|
65
|
+
|
|
66
|
+
## Event Type Guide
|
|
67
|
+
|
|
68
|
+
### bash Events
|
|
69
|
+
Match Bash command patterns:
|
|
70
|
+
- Dangerous commands: `rm\s+-rf`, `dd\s+if=`, `mkfs`
|
|
71
|
+
- Privilege escalation: `sudo\s+`, `su\s+`
|
|
72
|
+
- Permission issues: `chmod\s+777`
|
|
73
|
+
|
|
74
|
+
### file Events
|
|
75
|
+
Match Edit/Write/MultiEdit operations:
|
|
76
|
+
- Debug code: `console\.log\(`, `debugger`
|
|
77
|
+
- Security risks: `eval\(`, `innerHTML\s*=`
|
|
78
|
+
- Sensitive files: `\.env$`, `credentials`, `\.pem$`
|
|
79
|
+
|
|
80
|
+
### stop Events
|
|
81
|
+
Completion checks and reminders. Pattern `.*` matches always.
|
|
82
|
+
|
|
83
|
+
### prompt Events
|
|
84
|
+
Match user prompt content for workflow enforcement.
|
|
85
|
+
|
|
86
|
+
## Pattern Writing Tips
|
|
87
|
+
|
|
88
|
+
### Regex Basics
|
|
89
|
+
- Escape special chars: `.` to `\.`, `(` to `\(`
|
|
90
|
+
- `\s` whitespace, `\d` digit, `\w` word char
|
|
91
|
+
- `+` one or more, `*` zero or more, `?` optional
|
|
92
|
+
- `|` OR operator
|
|
93
|
+
|
|
94
|
+
### Common Pitfalls
|
|
95
|
+
- **Too broad**: `log` matches "login", "dialog" — use `console\.log\(`
|
|
96
|
+
- **Too specific**: `rm -rf /tmp` — use `rm\s+-rf`
|
|
97
|
+
- **YAML escaping**: Use unquoted patterns; quoted strings need `\\s`
|
|
98
|
+
|
|
99
|
+
### Testing
|
|
100
|
+
```bash
|
|
101
|
+
python3 -c "import re; print(re.search(r'your_pattern', 'test text'))"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## File Organization
|
|
105
|
+
|
|
106
|
+
- **Location**: `.claude/` directory in project root
|
|
107
|
+
- **Naming**: `.claude/hookify.{descriptive-name}.local.md`
|
|
108
|
+
- **Gitignore**: Add `.claude/*.local.md` to `.gitignore`
|
|
109
|
+
|
|
110
|
+
## Commands
|
|
111
|
+
|
|
112
|
+
- `/hookify [description]` - Create new rules (auto-analyzes conversation if no args)
|
|
113
|
+
- `/hookify-list` - View all rules in table format
|
|
114
|
+
- `/hookify-configure` - Toggle rules on/off interactively
|
|
115
|
+
- `/hookify-help` - Full documentation
|
|
116
|
+
|
|
117
|
+
## Quick Reference
|
|
118
|
+
|
|
119
|
+
Minimum viable rule:
|
|
120
|
+
```markdown
|
|
121
|
+
---
|
|
122
|
+
name: my-rule
|
|
123
|
+
enabled: true
|
|
124
|
+
event: bash
|
|
125
|
+
pattern: dangerous_command
|
|
126
|
+
---
|
|
127
|
+
Warning message here
|
|
128
|
+
```
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: knowledge-ops
|
|
3
|
+
description: Knowledge base management, ingestion, sync, and retrieval across multiple storage layers (local files, MCP memory, vector stores, Git repos). Use when the user wants to save, organize, sync, deduplicate, or search across their knowledge systems.
|
|
4
|
+
origin: ECC
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Knowledge Operations
|
|
8
|
+
|
|
9
|
+
Manage a multi-layered knowledge system for ingesting, organizing, syncing, and retrieving knowledge across multiple stores.
|
|
10
|
+
|
|
11
|
+
Prefer the live workspace model:
|
|
12
|
+
- code work lives in the real cloned repos
|
|
13
|
+
- active execution context lives in GitHub, Linear, and repo-local working-context files
|
|
14
|
+
- broader human-facing notes can live in a non-repo context/archive folder
|
|
15
|
+
- durable cross-machine memory belongs in the knowledge base, not in a shadow repo workspace
|
|
16
|
+
|
|
17
|
+
## When to Activate
|
|
18
|
+
|
|
19
|
+
- User wants to save information to their knowledge base
|
|
20
|
+
- Ingesting documents, conversations, or data into structured storage
|
|
21
|
+
- Syncing knowledge across systems (local files, MCP memory, Supabase, Git repos)
|
|
22
|
+
- Deduplicating or organizing existing knowledge
|
|
23
|
+
- User says "save this to KB", "sync knowledge", "what do I know about X", "ingest this", "update the knowledge base"
|
|
24
|
+
- Any knowledge management task beyond simple memory recall
|
|
25
|
+
|
|
26
|
+
## Knowledge Architecture
|
|
27
|
+
|
|
28
|
+
### Layer 1: Active execution truth
|
|
29
|
+
- **Sources:** GitHub issues, PRs, discussions, release notes, Linear issues/projects/docs
|
|
30
|
+
- **Use for:** the current operational state of the work
|
|
31
|
+
- **Rule:** if something affects an active engineering plan, roadmap, rollout, or release, prefer putting it here first
|
|
32
|
+
|
|
33
|
+
### Layer 2: Claude Code Memory (Quick Access)
|
|
34
|
+
- **Path:** `./.claude/projects/*/memory/`
|
|
35
|
+
- **Format:** Markdown files with frontmatter
|
|
36
|
+
- **Types:** user preferences, feedback, project context, reference
|
|
37
|
+
- **Use for:** quick-access context that persists across conversations
|
|
38
|
+
- **Automatically loaded at session start**
|
|
39
|
+
|
|
40
|
+
### Layer 3: MCP Memory Server (Structured Knowledge Graph)
|
|
41
|
+
- **Access:** MCP memory tools (create_entities, create_relations, add_observations, search_nodes)
|
|
42
|
+
- **Use for:** Semantic search across all stored memories, relationship mapping
|
|
43
|
+
- **Cross-session persistence with queryable graph structure**
|
|
44
|
+
|
|
45
|
+
### Layer 4: Knowledge base repo / durable document store
|
|
46
|
+
- **Use for:** curated durable notes, session exports, synthesized research, operator memory, long-form docs
|
|
47
|
+
- **Rule:** this is the preferred durable store for cross-machine context when the content is not repo-owned code
|
|
48
|
+
|
|
49
|
+
### Layer 5: External Data Store (Supabase, PostgreSQL, etc.)
|
|
50
|
+
- **Use for:** Structured data, large document storage, full-text search
|
|
51
|
+
- **Good for:** Documents too large for memory files, data needing SQL queries
|
|
52
|
+
|
|
53
|
+
### Layer 6: Local context/archive folder
|
|
54
|
+
- **Use for:** human-facing notes, archived gameplans, local media organization, temporary non-code docs
|
|
55
|
+
- **Rule:** writable for information storage, but not a shadow code workspace
|
|
56
|
+
- **Do not use for:** active code changes or repo truth that should live upstream
|
|
57
|
+
|
|
58
|
+
## Ingestion Workflow
|
|
59
|
+
|
|
60
|
+
When new knowledge needs to be captured:
|
|
61
|
+
|
|
62
|
+
### 1. Classify
|
|
63
|
+
What type of knowledge is it?
|
|
64
|
+
- Business decision -> memory file (project type) + MCP memory
|
|
65
|
+
- Active roadmap / release / implementation state -> GitHub + Linear first
|
|
66
|
+
- Personal preference -> memory file (user/feedback type)
|
|
67
|
+
- Reference info -> memory file (reference type) + MCP memory
|
|
68
|
+
- Large document -> external data store + summary in memory
|
|
69
|
+
- Conversation/session -> knowledge base repo + short summary in memory
|
|
70
|
+
|
|
71
|
+
### 2. Deduplicate
|
|
72
|
+
Check if this knowledge already exists:
|
|
73
|
+
- Search memory files for existing entries
|
|
74
|
+
- Query MCP memory with relevant terms
|
|
75
|
+
- Check whether the information already exists in GitHub or Linear before creating another local note
|
|
76
|
+
- Do not create duplicates. Update existing entries instead.
|
|
77
|
+
|
|
78
|
+
### 3. Store
|
|
79
|
+
Write to appropriate layer(s):
|
|
80
|
+
- Always update Claude Code memory for quick access
|
|
81
|
+
- Use MCP memory for semantic searchability and relationship mapping
|
|
82
|
+
- Update GitHub / Linear first when the information changes live project truth
|
|
83
|
+
- Commit to the knowledge base repo for durable long-form additions
|
|
84
|
+
|
|
85
|
+
### 4. Index
|
|
86
|
+
Update any relevant indexes or summary files.
|
|
87
|
+
|
|
88
|
+
## Sync Operations
|
|
89
|
+
|
|
90
|
+
### Conversation Sync
|
|
91
|
+
Periodically sync conversation history into the knowledge base:
|
|
92
|
+
- Sources: Claude session files, Codex sessions, other agent sessions
|
|
93
|
+
- Destination: knowledge base repo
|
|
94
|
+
- Generate a session index for quick browsing
|
|
95
|
+
- Commit and push
|
|
96
|
+
|
|
97
|
+
### Workspace State Sync
|
|
98
|
+
Mirror important workspace configuration and scripts to the knowledge base:
|
|
99
|
+
- Generate directory maps
|
|
100
|
+
- Redact sensitive config before committing
|
|
101
|
+
- Track changes over time
|
|
102
|
+
- Do not treat the knowledge base or archive folder as the live code workspace
|
|
103
|
+
|
|
104
|
+
### GitHub / Linear Sync
|
|
105
|
+
When the information affects active execution:
|
|
106
|
+
- update the relevant GitHub issue, PR, discussion, release notes, or roadmap thread
|
|
107
|
+
- attach supporting docs to Linear when the work needs durable planning context
|
|
108
|
+
- only mirror a local note afterwards if it still adds value
|
|
109
|
+
|
|
110
|
+
### Cross-Source Knowledge Sync
|
|
111
|
+
Pull knowledge from multiple sources into one place:
|
|
112
|
+
- Claude/ChatGPT/Grok conversation exports
|
|
113
|
+
- Browser bookmarks
|
|
114
|
+
- GitHub activity events
|
|
115
|
+
- Write status summary, commit and push
|
|
116
|
+
|
|
117
|
+
## Memory Patterns
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
# Short-term: current session context
|
|
121
|
+
Use TodoWrite for in-session task tracking
|
|
122
|
+
|
|
123
|
+
# Medium-term: project memory files
|
|
124
|
+
Write to ./.claude/projects/*/memory/ for cross-session recall
|
|
125
|
+
|
|
126
|
+
# Long-term: GitHub / Linear / KB
|
|
127
|
+
Put active execution truth in GitHub + Linear
|
|
128
|
+
Put durable synthesized context in the knowledge base repo
|
|
129
|
+
|
|
130
|
+
# Semantic layer: MCP knowledge graph
|
|
131
|
+
Use mcp__memory__create_entities for permanent structured data
|
|
132
|
+
Use mcp__memory__create_relations for relationship mapping
|
|
133
|
+
Use mcp__memory__add_observations for new facts about known entities
|
|
134
|
+
Use mcp__memory__search_nodes to find existing knowledge
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Best Practices
|
|
138
|
+
|
|
139
|
+
- Keep memory files concise. Archive old data rather than letting files grow unbounded.
|
|
140
|
+
- Use frontmatter (YAML) for metadata on all knowledge files.
|
|
141
|
+
- Deduplicate before storing. Search first, then create or update.
|
|
142
|
+
- Prefer one canonical home per fact set. Avoid parallel copies of the same plan across local notes, repo files, and tracker docs.
|
|
143
|
+
- Redact sensitive information (API keys, passwords) before committing to Git.
|
|
144
|
+
- Use consistent naming conventions for knowledge files (lowercase-kebab-case).
|
|
145
|
+
- Tag entries with topics/categories for easier retrieval.
|
|
146
|
+
|
|
147
|
+
## Quality Gate
|
|
148
|
+
|
|
149
|
+
Before completing any knowledge operation:
|
|
150
|
+
- no duplicate entries created
|
|
151
|
+
- sensitive data redacted from any Git-tracked files
|
|
152
|
+
- indexes and summaries updated
|
|
153
|
+
- appropriate storage layer chosen for the data type
|
|
154
|
+
- cross-references added where relevant
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: liquid-glass-design
|
|
3
|
+
description: iOS 26 Liquid Glass design system — dynamic glass material with blur, reflection, and interactive morphing for SwiftUI, UIKit, and WidgetKit.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Liquid Glass Design System (iOS 26)
|
|
7
|
+
|
|
8
|
+
Patterns for implementing Apple's Liquid Glass — a dynamic material that blurs content behind it, reflects color and light from surrounding content, and reacts to touch and pointer interactions. Covers SwiftUI, UIKit, and WidgetKit integration.
|
|
9
|
+
|
|
10
|
+
## When to Activate
|
|
11
|
+
|
|
12
|
+
- Building or updating apps for iOS 26+ with the new design language
|
|
13
|
+
- Implementing glass-style buttons, cards, toolbars, or containers
|
|
14
|
+
- Creating morphing transitions between glass elements
|
|
15
|
+
- Applying Liquid Glass effects to widgets
|
|
16
|
+
- Migrating existing blur/material effects to the new Liquid Glass API
|
|
17
|
+
|
|
18
|
+
## Core Pattern — SwiftUI
|
|
19
|
+
|
|
20
|
+
### Basic Glass Effect
|
|
21
|
+
|
|
22
|
+
The simplest way to add Liquid Glass to any view:
|
|
23
|
+
|
|
24
|
+
```swift
|
|
25
|
+
Text("Hello, World!")
|
|
26
|
+
.font(.title)
|
|
27
|
+
.padding()
|
|
28
|
+
.glassEffect() // Default: regular variant, capsule shape
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Customizing Shape and Tint
|
|
32
|
+
|
|
33
|
+
```swift
|
|
34
|
+
Text("Hello, World!")
|
|
35
|
+
.font(.title)
|
|
36
|
+
.padding()
|
|
37
|
+
.glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Key customization options:
|
|
41
|
+
- `.regular` — standard glass effect
|
|
42
|
+
- `.tint(Color)` — add color tint for prominence
|
|
43
|
+
- `.interactive()` — react to touch and pointer interactions
|
|
44
|
+
- Shape: `.capsule` (default), `.rect(cornerRadius:)`, `.circle`
|
|
45
|
+
|
|
46
|
+
### Glass Button Styles
|
|
47
|
+
|
|
48
|
+
```swift
|
|
49
|
+
Button("Click Me") { /* action */ }
|
|
50
|
+
.buttonStyle(.glass)
|
|
51
|
+
|
|
52
|
+
Button("Important") { /* action */ }
|
|
53
|
+
.buttonStyle(.glassProminent)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### GlassEffectContainer for Multiple Elements
|
|
57
|
+
|
|
58
|
+
Always wrap multiple glass views in a container for performance and morphing:
|
|
59
|
+
|
|
60
|
+
```swift
|
|
61
|
+
GlassEffectContainer(spacing: 40.0) {
|
|
62
|
+
HStack(spacing: 40.0) {
|
|
63
|
+
Image(systemName: "scribble.variable")
|
|
64
|
+
.frame(width: 80.0, height: 80.0)
|
|
65
|
+
.font(.system(size: 36))
|
|
66
|
+
.glassEffect()
|
|
67
|
+
|
|
68
|
+
Image(systemName: "eraser.fill")
|
|
69
|
+
.frame(width: 80.0, height: 80.0)
|
|
70
|
+
.font(.system(size: 36))
|
|
71
|
+
.glassEffect()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The `spacing` parameter controls merge distance — closer elements blend their glass shapes together.
|
|
77
|
+
|
|
78
|
+
### Uniting Glass Effects
|
|
79
|
+
|
|
80
|
+
Combine multiple views into a single glass shape with `glassEffectUnion`:
|
|
81
|
+
|
|
82
|
+
```swift
|
|
83
|
+
@Namespace private var namespace
|
|
84
|
+
|
|
85
|
+
GlassEffectContainer(spacing: 20.0) {
|
|
86
|
+
HStack(spacing: 20.0) {
|
|
87
|
+
ForEach(symbolSet.indices, id: \.self) { item in
|
|
88
|
+
Image(systemName: symbolSet[item])
|
|
89
|
+
.frame(width: 80.0, height: 80.0)
|
|
90
|
+
.glassEffect()
|
|
91
|
+
.glassEffectUnion(id: item < 2 ? "group1" : "group2", namespace: namespace)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Morphing Transitions
|
|
98
|
+
|
|
99
|
+
Create smooth morphing when glass elements appear/disappear:
|
|
100
|
+
|
|
101
|
+
```swift
|
|
102
|
+
@State private var isExpanded = false
|
|
103
|
+
@Namespace private var namespace
|
|
104
|
+
|
|
105
|
+
GlassEffectContainer(spacing: 40.0) {
|
|
106
|
+
HStack(spacing: 40.0) {
|
|
107
|
+
Image(systemName: "scribble.variable")
|
|
108
|
+
.frame(width: 80.0, height: 80.0)
|
|
109
|
+
.glassEffect()
|
|
110
|
+
.glassEffectID("pencil", in: namespace)
|
|
111
|
+
|
|
112
|
+
if isExpanded {
|
|
113
|
+
Image(systemName: "eraser.fill")
|
|
114
|
+
.frame(width: 80.0, height: 80.0)
|
|
115
|
+
.glassEffect()
|
|
116
|
+
.glassEffectID("eraser", in: namespace)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Button("Toggle") {
|
|
122
|
+
withAnimation { isExpanded.toggle() }
|
|
123
|
+
}
|
|
124
|
+
.buttonStyle(.glass)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Extending Horizontal Scrolling Under Sidebar
|
|
128
|
+
|
|
129
|
+
To allow horizontal scroll content to extend under a sidebar or inspector, ensure the `ScrollView` content reaches the leading/trailing edges of the container. The system automatically handles the under-sidebar scrolling behavior when the layout extends to the edges — no additional modifier is needed.
|
|
130
|
+
|
|
131
|
+
## Core Pattern — UIKit
|
|
132
|
+
|
|
133
|
+
### Basic UIGlassEffect
|
|
134
|
+
|
|
135
|
+
```swift
|
|
136
|
+
let glassEffect = UIGlassEffect()
|
|
137
|
+
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
|
|
138
|
+
glassEffect.isInteractive = true
|
|
139
|
+
|
|
140
|
+
let visualEffectView = UIVisualEffectView(effect: glassEffect)
|
|
141
|
+
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
|
|
142
|
+
visualEffectView.layer.cornerRadius = 20
|
|
143
|
+
visualEffectView.clipsToBounds = true
|
|
144
|
+
|
|
145
|
+
view.addSubview(visualEffectView)
|
|
146
|
+
NSLayoutConstraint.activate([
|
|
147
|
+
visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
|
148
|
+
visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
|
|
149
|
+
visualEffectView.widthAnchor.constraint(equalToConstant: 200),
|
|
150
|
+
visualEffectView.heightAnchor.constraint(equalToConstant: 120)
|
|
151
|
+
])
|
|
152
|
+
|
|
153
|
+
// Add content to contentView
|
|
154
|
+
let label = UILabel()
|
|
155
|
+
label.text = "Liquid Glass"
|
|
156
|
+
label.translatesAutoresizingMaskIntoConstraints = false
|
|
157
|
+
visualEffectView.contentView.addSubview(label)
|
|
158
|
+
NSLayoutConstraint.activate([
|
|
159
|
+
label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor),
|
|
160
|
+
label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor)
|
|
161
|
+
])
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### UIGlassContainerEffect for Multiple Elements
|
|
165
|
+
|
|
166
|
+
```swift
|
|
167
|
+
let containerEffect = UIGlassContainerEffect()
|
|
168
|
+
containerEffect.spacing = 40.0
|
|
169
|
+
|
|
170
|
+
let containerView = UIVisualEffectView(effect: containerEffect)
|
|
171
|
+
|
|
172
|
+
let firstGlass = UIVisualEffectView(effect: UIGlassEffect())
|
|
173
|
+
let secondGlass = UIVisualEffectView(effect: UIGlassEffect())
|
|
174
|
+
|
|
175
|
+
containerView.contentView.addSubview(firstGlass)
|
|
176
|
+
containerView.contentView.addSubview(secondGlass)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Scroll Edge Effects
|
|
180
|
+
|
|
181
|
+
```swift
|
|
182
|
+
scrollView.topEdgeEffect.style = .automatic
|
|
183
|
+
scrollView.bottomEdgeEffect.style = .hard
|
|
184
|
+
scrollView.leftEdgeEffect.isHidden = true
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Toolbar Glass Integration
|
|
188
|
+
|
|
189
|
+
```swift
|
|
190
|
+
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
|
|
191
|
+
favoriteButton.hidesSharedBackground = true // Opt out of shared glass background
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Core Pattern — WidgetKit
|
|
195
|
+
|
|
196
|
+
### Rendering Mode Detection
|
|
197
|
+
|
|
198
|
+
```swift
|
|
199
|
+
struct MyWidgetView: View {
|
|
200
|
+
@Environment(\.widgetRenderingMode) var renderingMode
|
|
201
|
+
|
|
202
|
+
var body: some View {
|
|
203
|
+
if renderingMode == .accented {
|
|
204
|
+
// Tinted mode: white-tinted, themed glass background
|
|
205
|
+
} else {
|
|
206
|
+
// Full color mode: standard appearance
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Accent Groups for Visual Hierarchy
|
|
213
|
+
|
|
214
|
+
```swift
|
|
215
|
+
HStack {
|
|
216
|
+
VStack(alignment: .leading) {
|
|
217
|
+
Text("Title")
|
|
218
|
+
.widgetAccentable() // Accent group
|
|
219
|
+
Text("Subtitle")
|
|
220
|
+
// Primary group (default)
|
|
221
|
+
}
|
|
222
|
+
Image(systemName: "star.fill")
|
|
223
|
+
.widgetAccentable() // Accent group
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Image Rendering in Accented Mode
|
|
228
|
+
|
|
229
|
+
```swift
|
|
230
|
+
Image("myImage")
|
|
231
|
+
.widgetAccentedRenderingMode(.monochrome)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Container Background
|
|
235
|
+
|
|
236
|
+
```swift
|
|
237
|
+
VStack { /* content */ }
|
|
238
|
+
.containerBackground(for: .widget) {
|
|
239
|
+
Color.blue.opacity(0.2)
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Key Design Decisions
|
|
244
|
+
|
|
245
|
+
| Decision | Rationale |
|
|
246
|
+
|----------|-----------|
|
|
247
|
+
| GlassEffectContainer wrapping | Performance optimization, enables morphing between glass elements |
|
|
248
|
+
| `spacing` parameter | Controls merge distance — fine-tune how close elements must be to blend |
|
|
249
|
+
| `@Namespace` + `glassEffectID` | Enables smooth morphing transitions on view hierarchy changes |
|
|
250
|
+
| `interactive()` modifier | Explicit opt-in for touch/pointer reactions — not all glass should respond |
|
|
251
|
+
| UIGlassContainerEffect in UIKit | Same container pattern as SwiftUI for consistency |
|
|
252
|
+
| Accented rendering mode in widgets | System applies tinted glass when user selects tinted Home Screen |
|
|
253
|
+
|
|
254
|
+
## Best Practices
|
|
255
|
+
|
|
256
|
+
- **Always use GlassEffectContainer** when applying glass to multiple sibling views — it enables morphing and improves rendering performance
|
|
257
|
+
- **Apply `.glassEffect()` after** other appearance modifiers (frame, font, padding)
|
|
258
|
+
- **Use `.interactive()`** only on elements that respond to user interaction (buttons, toggleable items)
|
|
259
|
+
- **Choose spacing carefully** in containers to control when glass effects merge
|
|
260
|
+
- **Use `withAnimation`** when changing view hierarchies to enable smooth morphing transitions
|
|
261
|
+
- **Test across appearances** — light mode, dark mode, and accented/tinted modes
|
|
262
|
+
- **Ensure accessibility contrast** — text on glass must remain readable
|
|
263
|
+
|
|
264
|
+
## Anti-Patterns to Avoid
|
|
265
|
+
|
|
266
|
+
- Using multiple standalone `.glassEffect()` views without a GlassEffectContainer
|
|
267
|
+
- Nesting too many glass effects — degrades performance and visual clarity
|
|
268
|
+
- Applying glass to every view — reserve for interactive elements, toolbars, and cards
|
|
269
|
+
- Forgetting `clipsToBounds = true` in UIKit when using corner radii
|
|
270
|
+
- Ignoring accented rendering mode in widgets — breaks tinted Home Screen appearance
|
|
271
|
+
- Using opaque backgrounds behind glass — defeats the translucency effect
|
|
272
|
+
|
|
273
|
+
## When to Use
|
|
274
|
+
|
|
275
|
+
- Navigation bars, toolbars, and tab bars with the new iOS 26 design
|
|
276
|
+
- Floating action buttons and card-style containers
|
|
277
|
+
- Interactive controls that need visual depth and touch feedback
|
|
278
|
+
- Widgets that should integrate with the system's Liquid Glass appearance
|
|
279
|
+
- Morphing transitions between related UI states
|