ag-cortex 0.1.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.
Files changed (162) hide show
  1. package/.agent/commands/test-browser.md +339 -0
  2. package/.agent/rules/00-constitution.md +46 -0
  3. package/.agent/rules/project-rules.md +49 -0
  4. package/.agent/skills/agent-browser/SKILL.md +223 -0
  5. package/.agent/skills/agent-native-architecture/SKILL.md +435 -0
  6. package/.agent/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
  7. package/.agent/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
  8. package/.agent/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
  9. package/.agent/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
  10. package/.agent/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
  11. package/.agent/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
  12. package/.agent/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
  13. package/.agent/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
  14. package/.agent/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
  15. package/.agent/skills/agent-native-architecture/references/product-implications.md +443 -0
  16. package/.agent/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
  17. package/.agent/skills/agent-native-architecture/references/self-modification.md +269 -0
  18. package/.agent/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
  19. package/.agent/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
  20. package/.agent/skills/agent-native-reviewer/SKILL.md +246 -0
  21. package/.agent/skills/andrew-kane-gem-writer/SKILL.md +184 -0
  22. package/.agent/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
  23. package/.agent/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
  24. package/.agent/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
  25. package/.agent/skills/andrew-kane-gem-writer/references/resources.md +119 -0
  26. package/.agent/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
  27. package/.agent/skills/ankane-readme-writer/SKILL.md +50 -0
  28. package/.agent/skills/architecture-strategist/SKILL.md +52 -0
  29. package/.agent/skills/best-practices-researcher/SKILL.md +100 -0
  30. package/.agent/skills/bug-reproduction-validator/SKILL.md +67 -0
  31. package/.agent/skills/code-simplicity-reviewer/SKILL.md +85 -0
  32. package/.agent/skills/coding-tutor/.claude-plugin/plugin.json +9 -0
  33. package/.agent/skills/coding-tutor/README.md +37 -0
  34. package/.agent/skills/coding-tutor/commands/quiz-me.md +1 -0
  35. package/.agent/skills/coding-tutor/commands/sync-tutorials.md +25 -0
  36. package/.agent/skills/coding-tutor/commands/teach-me.md +1 -0
  37. package/.agent/skills/coding-tutor/skills/coding-tutor/SKILL.md +214 -0
  38. package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py +202 -0
  39. package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py +203 -0
  40. package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py +190 -0
  41. package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py +132 -0
  42. package/.agent/skills/compound-docs/SKILL.md +510 -0
  43. package/.agent/skills/compound-docs/assets/critical-pattern-template.md +34 -0
  44. package/.agent/skills/compound-docs/assets/resolution-template.md +93 -0
  45. package/.agent/skills/compound-docs/references/yaml-schema.md +65 -0
  46. package/.agent/skills/compound-docs/schema.yaml +176 -0
  47. package/.agent/skills/create-agent-skills/SKILL.md +299 -0
  48. package/.agent/skills/create-agent-skills/references/api-security.md +226 -0
  49. package/.agent/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
  50. package/.agent/skills/create-agent-skills/references/best-practices.md +404 -0
  51. package/.agent/skills/create-agent-skills/references/common-patterns.md +595 -0
  52. package/.agent/skills/create-agent-skills/references/core-principles.md +437 -0
  53. package/.agent/skills/create-agent-skills/references/executable-code.md +175 -0
  54. package/.agent/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
  55. package/.agent/skills/create-agent-skills/references/official-spec.md +185 -0
  56. package/.agent/skills/create-agent-skills/references/recommended-structure.md +168 -0
  57. package/.agent/skills/create-agent-skills/references/skill-structure.md +372 -0
  58. package/.agent/skills/create-agent-skills/references/using-scripts.md +113 -0
  59. package/.agent/skills/create-agent-skills/references/using-templates.md +112 -0
  60. package/.agent/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
  61. package/.agent/skills/create-agent-skills/templates/router-skill.md +73 -0
  62. package/.agent/skills/create-agent-skills/templates/simple-skill.md +33 -0
  63. package/.agent/skills/create-agent-skills/workflows/add-reference.md +96 -0
  64. package/.agent/skills/create-agent-skills/workflows/add-script.md +93 -0
  65. package/.agent/skills/create-agent-skills/workflows/add-template.md +74 -0
  66. package/.agent/skills/create-agent-skills/workflows/add-workflow.md +120 -0
  67. package/.agent/skills/create-agent-skills/workflows/audit-skill.md +138 -0
  68. package/.agent/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
  69. package/.agent/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
  70. package/.agent/skills/create-agent-skills/workflows/get-guidance.md +121 -0
  71. package/.agent/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
  72. package/.agent/skills/create-agent-skills/workflows/verify-skill.md +204 -0
  73. package/.agent/skills/data-integrity-guardian/SKILL.md +70 -0
  74. package/.agent/skills/data-migration-expert/SKILL.md +97 -0
  75. package/.agent/skills/deployment-verification-agent/SKILL.md +159 -0
  76. package/.agent/skills/design-implementation-reviewer/SKILL.md +85 -0
  77. package/.agent/skills/design-iterator/SKILL.md +197 -0
  78. package/.agent/skills/dhh-rails-reviewer/SKILL.md +45 -0
  79. package/.agent/skills/dhh-rails-style/SKILL.md +184 -0
  80. package/.agent/skills/dhh-rails-style/references/architecture.md +653 -0
  81. package/.agent/skills/dhh-rails-style/references/controllers.md +303 -0
  82. package/.agent/skills/dhh-rails-style/references/frontend.md +510 -0
  83. package/.agent/skills/dhh-rails-style/references/gems.md +266 -0
  84. package/.agent/skills/dhh-rails-style/references/models.md +359 -0
  85. package/.agent/skills/dhh-rails-style/references/testing.md +338 -0
  86. package/.agent/skills/dspy-ruby/SKILL.md +594 -0
  87. package/.agent/skills/dspy-ruby/assets/config-template.rb +359 -0
  88. package/.agent/skills/dspy-ruby/assets/module-template.rb +326 -0
  89. package/.agent/skills/dspy-ruby/assets/signature-template.rb +143 -0
  90. package/.agent/skills/dspy-ruby/references/core-concepts.md +265 -0
  91. package/.agent/skills/dspy-ruby/references/optimization.md +623 -0
  92. package/.agent/skills/dspy-ruby/references/providers.md +305 -0
  93. package/.agent/skills/every-style-editor/SKILL.md +134 -0
  94. package/.agent/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
  95. package/.agent/skills/figma-design-sync/SKILL.md +166 -0
  96. package/.agent/skills/file-todos/SKILL.md +251 -0
  97. package/.agent/skills/file-todos/assets/todo-template.md +155 -0
  98. package/.agent/skills/framework-docs-researcher/SKILL.md +83 -0
  99. package/.agent/skills/frontend-design/SKILL.md +42 -0
  100. package/.agent/skills/gemini-imagegen/SKILL.md +237 -0
  101. package/.agent/skills/gemini-imagegen/requirements.txt +2 -0
  102. package/.agent/skills/gemini-imagegen/scripts/compose_images.py +168 -0
  103. package/.agent/skills/gemini-imagegen/scripts/edit_image.py +157 -0
  104. package/.agent/skills/gemini-imagegen/scripts/gemini_images.py +265 -0
  105. package/.agent/skills/gemini-imagegen/scripts/generate_image.py +147 -0
  106. package/.agent/skills/gemini-imagegen/scripts/multi_turn_chat.py +215 -0
  107. package/.agent/skills/git-history-analyzer/SKILL.md +42 -0
  108. package/.agent/skills/git-worktree/SKILL.md +302 -0
  109. package/.agent/skills/git-worktree/scripts/worktree-manager.sh +345 -0
  110. package/.agent/skills/julik-frontend-races-reviewer/SKILL.md +222 -0
  111. package/.agent/skills/kieran-python-reviewer/SKILL.md +104 -0
  112. package/.agent/skills/kieran-rails-reviewer/SKILL.md +86 -0
  113. package/.agent/skills/kieran-typescript-reviewer/SKILL.md +95 -0
  114. package/.agent/skills/lint/SKILL.md +16 -0
  115. package/.agent/skills/pattern-recognition-specialist/SKILL.md +57 -0
  116. package/.agent/skills/performance-oracle/SKILL.md +110 -0
  117. package/.agent/skills/pr-comment-resolver/SKILL.md +69 -0
  118. package/.agent/skills/rclone/SKILL.md +150 -0
  119. package/.agent/skills/rclone/scripts/check_setup.sh +60 -0
  120. package/.agent/skills/repo-research-analyst/SKILL.md +113 -0
  121. package/.agent/skills/security-sentinel/SKILL.md +93 -0
  122. package/.agent/skills/skill-creator/SKILL.md +209 -0
  123. package/.agent/skills/skill-creator/scripts/init_skill.py +304 -0
  124. package/.agent/skills/skill-creator/scripts/package_skill.py +112 -0
  125. package/.agent/skills/skill-creator/scripts/quick_validate.py +72 -0
  126. package/.agent/skills/spec-flow-analyzer/SKILL.md +113 -0
  127. package/.agent/skills/test-agent/SKILL.md +4 -0
  128. package/.agent/workflows/agent-native-audit.md +277 -0
  129. package/.agent/workflows/ask-user-question.md +21 -0
  130. package/.agent/workflows/changelog.md +137 -0
  131. package/.agent/workflows/compound.md +202 -0
  132. package/.agent/workflows/create-agent-skill.md +8 -0
  133. package/.agent/workflows/deepen-plan-research.md +334 -0
  134. package/.agent/workflows/deepen-plan-synthesis.md +182 -0
  135. package/.agent/workflows/deepen-plan.md +79 -0
  136. package/.agent/workflows/feature-video.md +342 -0
  137. package/.agent/workflows/generate-command.md +162 -0
  138. package/.agent/workflows/heal-skill.md +142 -0
  139. package/.agent/workflows/lfg.md +20 -0
  140. package/.agent/workflows/plan-analysis.md +67 -0
  141. package/.agent/workflows/plan-next-steps.md +63 -0
  142. package/.agent/workflows/plan-review.md +33 -0
  143. package/.agent/workflows/plan-synthesis.md +106 -0
  144. package/.agent/workflows/plan.md +49 -0
  145. package/.agent/workflows/report-bug.md +150 -0
  146. package/.agent/workflows/reproduce-bug.md +99 -0
  147. package/.agent/workflows/resolve-parallel.md +34 -0
  148. package/.agent/workflows/resolve-pr-parallel.md +49 -0
  149. package/.agent/workflows/resolve-todo-parallel.md +35 -0
  150. package/.agent/workflows/review-analysis.md +145 -0
  151. package/.agent/workflows/review-synthesis.md +262 -0
  152. package/.agent/workflows/review.md +64 -0
  153. package/.agent/workflows/ship.md +90 -0
  154. package/.agent/workflows/test-command.md +3 -0
  155. package/.agent/workflows/triage.md +310 -0
  156. package/.agent/workflows/work.md +157 -0
  157. package/.agent/workflows/xcode-test.md +332 -0
  158. package/LICENSE +22 -0
  159. package/README.md +49 -0
  160. package/bin/ag-cortex.js +54 -0
  161. package/lib/core.js +165 -0
  162. package/package.json +31 -0
@@ -0,0 +1,680 @@
1
+ <overview>
2
+ Agents and users should work in the same data space, not separate sandboxes. When the agent writes a file, the user can see it. When the user edits something, the agent can read the changes. This creates transparency, enables collaboration, and eliminates the need for sync layers.
3
+
4
+ **Core principle:** The agent operates in the same filesystem as the user, not a walled garden.
5
+ </overview>
6
+
7
+ <why_shared_workspace>
8
+ ## Why Shared Workspace?
9
+
10
+ ### The Sandbox Anti-Pattern
11
+
12
+ Many agent implementations isolate the agent:
13
+
14
+ ```
15
+ ┌─────────────────┐ ┌─────────────────┐
16
+ │ User Space │ │ Agent Space │
17
+ ├─────────────────┤ ├─────────────────┤
18
+ │ Documents/ │ │ agent_output/ │
19
+ │ user_files/ │ ←→ │ temp_files/ │
20
+ │ settings.json │sync │ cache/ │
21
+ └─────────────────┘ └─────────────────┘
22
+ ```
23
+
24
+ Problems:
25
+ - Need a sync layer to move data between spaces
26
+ - User can't easily inspect agent work
27
+ - Agent can't build on user contributions
28
+ - Duplication of state
29
+ - Complexity in keeping spaces consistent
30
+
31
+ ### The Shared Workspace Pattern
32
+
33
+ ```
34
+ ┌─────────────────────────────────────────┐
35
+ │ Shared Workspace │
36
+ ├─────────────────────────────────────────┤
37
+ │ Documents/ │
38
+ │ ├── Research/ │
39
+ │ │ └── {bookId}/ ← Agent writes │
40
+ │ │ ├── full_text.txt │
41
+ │ │ ├── introduction.md ← User can edit │
42
+ │ │ └── sources/ │
43
+ │ ├── Chats/ ← Both read/write │
44
+ │ └── profile.md ← Agent generates, user refines │
45
+ └─────────────────────────────────────────┘
46
+ ↑ ↑
47
+ User Agent
48
+ (UI) (Tools)
49
+ ```
50
+
51
+ Benefits:
52
+ - Users can inspect, edit, and extend agent work
53
+ - Agents can build on user contributions
54
+ - No synchronization layer needed
55
+ - Complete transparency
56
+ - Single source of truth
57
+ </why_shared_workspace>
58
+
59
+ <directory_structure>
60
+ ## Designing Your Shared Workspace
61
+
62
+ ### Structure by Domain
63
+
64
+ Organize by what the data represents, not who created it:
65
+
66
+ ```
67
+ Documents/
68
+ ├── Research/
69
+ │ └── {bookId}/
70
+ │ ├── full_text.txt # Agent downloads
71
+ │ ├── introduction.md # Agent generates, user can edit
72
+ │ ├── notes.md # User adds, agent can read
73
+ │ └── sources/
74
+ │ └── {source}.md # Agent gathers
75
+ ├── Chats/
76
+ │ └── {conversationId}.json # Both read/write
77
+ ├── Exports/
78
+ │ └── {date}/ # Agent generates for user
79
+ └── profile.md # Agent generates from photos
80
+ ```
81
+
82
+ ### Don't Structure by Actor
83
+
84
+ ```
85
+ # BAD - Separates by who created it
86
+ Documents/
87
+ ├── user_created/
88
+ │ └── notes.md
89
+ ├── agent_created/
90
+ │ └── research.md
91
+ └── system/
92
+ └── config.json
93
+ ```
94
+
95
+ This creates artificial boundaries and makes collaboration harder.
96
+
97
+ ### Use Conventions for Metadata
98
+
99
+ If you need to track who created/modified something:
100
+
101
+ ```markdown
102
+ <!-- introduction.md -->
103
+ ---
104
+ created_by: agent
105
+ created_at: 2024-01-15
106
+ last_modified_by: user
107
+ last_modified_at: 2024-01-16
108
+ ---
109
+
110
+ # Introduction to Moby Dick
111
+
112
+ This personalized introduction was generated by your reading assistant
113
+ and refined by you on January 16th.
114
+ ```
115
+ </directory_structure>
116
+
117
+ <file_tools>
118
+ ## File Tools for Shared Workspace
119
+
120
+ Give the agent the same file primitives the app uses:
121
+
122
+ ```swift
123
+ // iOS/Swift implementation
124
+ struct FileTools {
125
+ static func readFile() -> AgentTool {
126
+ tool(
127
+ name: "read_file",
128
+ description: "Read a file from the user's documents",
129
+ parameters: ["path": .string("File path relative to Documents/")],
130
+ execute: { params in
131
+ let path = params["path"] as! String
132
+ let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
133
+ let fileURL = documentsURL.appendingPathComponent(path)
134
+ let content = try String(contentsOf: fileURL)
135
+ return ToolResult(text: content)
136
+ }
137
+ )
138
+ }
139
+
140
+ static func writeFile() -> AgentTool {
141
+ tool(
142
+ name: "write_file",
143
+ description: "Write a file to the user's documents",
144
+ parameters: [
145
+ "path": .string("File path relative to Documents/"),
146
+ "content": .string("File content")
147
+ ],
148
+ execute: { params in
149
+ let path = params["path"] as! String
150
+ let content = params["content"] as! String
151
+ let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
152
+ let fileURL = documentsURL.appendingPathComponent(path)
153
+
154
+ // Create parent directories if needed
155
+ try FileManager.default.createDirectory(
156
+ at: fileURL.deletingLastPathComponent(),
157
+ withIntermediateDirectories: true
158
+ )
159
+
160
+ try content.write(to: fileURL, atomically: true, encoding: .utf8)
161
+ return ToolResult(text: "Wrote \(path)")
162
+ }
163
+ )
164
+ }
165
+
166
+ static func listFiles() -> AgentTool {
167
+ tool(
168
+ name: "list_files",
169
+ description: "List files in a directory",
170
+ parameters: ["path": .string("Directory path relative to Documents/")],
171
+ execute: { params in
172
+ let path = params["path"] as! String
173
+ let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
174
+ let dirURL = documentsURL.appendingPathComponent(path)
175
+ let contents = try FileManager.default.contentsOfDirectory(atPath: dirURL.path)
176
+ return ToolResult(text: contents.joined(separator: "\n"))
177
+ }
178
+ )
179
+ }
180
+
181
+ static func searchText() -> AgentTool {
182
+ tool(
183
+ name: "search_text",
184
+ description: "Search for text across files",
185
+ parameters: [
186
+ "query": .string("Text to search for"),
187
+ "path": .string("Directory to search in").optional()
188
+ ],
189
+ execute: { params in
190
+ // Implement text search across documents
191
+ // Return matching files and snippets
192
+ }
193
+ )
194
+ }
195
+ }
196
+ ```
197
+
198
+ ### TypeScript/Node.js Implementation
199
+
200
+ ```typescript
201
+ const fileTools = [
202
+ tool(
203
+ "read_file",
204
+ "Read a file from the workspace",
205
+ { path: z.string().describe("File path") },
206
+ async ({ path }) => {
207
+ const content = await fs.readFile(path, 'utf-8');
208
+ return { text: content };
209
+ }
210
+ ),
211
+
212
+ tool(
213
+ "write_file",
214
+ "Write a file to the workspace",
215
+ {
216
+ path: z.string().describe("File path"),
217
+ content: z.string().describe("File content")
218
+ },
219
+ async ({ path, content }) => {
220
+ await fs.mkdir(dirname(path), { recursive: true });
221
+ await fs.writeFile(path, content, 'utf-8');
222
+ return { text: `Wrote ${path}` };
223
+ }
224
+ ),
225
+
226
+ tool(
227
+ "list_files",
228
+ "List files in a directory",
229
+ { path: z.string().describe("Directory path") },
230
+ async ({ path }) => {
231
+ const files = await fs.readdir(path);
232
+ return { text: files.join('\n') };
233
+ }
234
+ ),
235
+
236
+ tool(
237
+ "append_file",
238
+ "Append content to a file",
239
+ {
240
+ path: z.string().describe("File path"),
241
+ content: z.string().describe("Content to append")
242
+ },
243
+ async ({ path, content }) => {
244
+ await fs.appendFile(path, content, 'utf-8');
245
+ return { text: `Appended to ${path}` };
246
+ }
247
+ ),
248
+ ];
249
+ ```
250
+ </file_tools>
251
+
252
+ <ui_integration>
253
+ ## UI Integration with Shared Workspace
254
+
255
+ The UI should observe the same files the agent writes to:
256
+
257
+ ### Pattern 1: File-Based Reactivity (iOS)
258
+
259
+ ```swift
260
+ class ResearchViewModel: ObservableObject {
261
+ @Published var researchFiles: [ResearchFile] = []
262
+
263
+ private var watcher: DirectoryWatcher?
264
+
265
+ func startWatching(bookId: String) {
266
+ let researchPath = documentsURL
267
+ .appendingPathComponent("Research")
268
+ .appendingPathComponent(bookId)
269
+
270
+ watcher = DirectoryWatcher(url: researchPath) { [weak self] in
271
+ // Reload when agent writes new files
272
+ self?.loadResearchFiles(from: researchPath)
273
+ }
274
+
275
+ loadResearchFiles(from: researchPath)
276
+ }
277
+ }
278
+
279
+ // SwiftUI automatically updates when files change
280
+ struct ResearchView: View {
281
+ @StateObject var viewModel = ResearchViewModel()
282
+
283
+ var body: some View {
284
+ List(viewModel.researchFiles) { file in
285
+ ResearchFileRow(file: file)
286
+ }
287
+ }
288
+ }
289
+ ```
290
+
291
+ ### Pattern 2: Shared Data Store
292
+
293
+ When file-watching isn't practical, use a shared data store:
294
+
295
+ ```swift
296
+ // Shared service that both UI and agent tools use
297
+ class BookLibraryService: ObservableObject {
298
+ static let shared = BookLibraryService()
299
+
300
+ @Published var books: [Book] = []
301
+ @Published var analysisRecords: [AnalysisRecord] = []
302
+
303
+ func addAnalysisRecord(_ record: AnalysisRecord) {
304
+ analysisRecords.append(record)
305
+ // Persists to shared storage
306
+ saveToStorage()
307
+ }
308
+ }
309
+
310
+ // Agent tool writes through the same service
311
+ tool("publish_to_feed", async ({ bookId, content, headline }) => {
312
+ let record = AnalysisRecord(bookId: bookId, content: content, headline: headline)
313
+ BookLibraryService.shared.addAnalysisRecord(record)
314
+ return { text: "Published to feed" }
315
+ })
316
+
317
+ // UI observes the same service
318
+ struct FeedView: View {
319
+ @StateObject var library = BookLibraryService.shared
320
+
321
+ var body: some View {
322
+ List(library.analysisRecords) { record in
323
+ FeedItemRow(record: record)
324
+ }
325
+ }
326
+ }
327
+ ```
328
+
329
+ ### Pattern 3: Hybrid (Files + Index)
330
+
331
+ Use files for content, database for indexing:
332
+
333
+ ```
334
+ Documents/
335
+ ├── Research/
336
+ │ └── book_123/
337
+ │ └── introduction.md # Actual content (file)
338
+
339
+ Database:
340
+ ├── research_index
341
+ │ └── { bookId: "book_123", path: "Research/book_123/introduction.md", ... }
342
+ ```
343
+
344
+ ```swift
345
+ // Agent writes file
346
+ await writeFile("Research/\(bookId)/introduction.md", content)
347
+
348
+ // And updates index
349
+ await database.insert("research_index", {
350
+ bookId: bookId,
351
+ path: "Research/\(bookId)/introduction.md",
352
+ title: extractTitle(content),
353
+ createdAt: Date()
354
+ })
355
+
356
+ // UI queries index, then reads files
357
+ let items = database.query("research_index", where: bookId == "book_123")
358
+ for item in items {
359
+ let content = readFile(item.path)
360
+ // Display...
361
+ }
362
+ ```
363
+ </ui_integration>
364
+
365
+ <collaboration_patterns>
366
+ ## Agent-User Collaboration Patterns
367
+
368
+ ### Pattern: Agent Drafts, User Refines
369
+
370
+ ```
371
+ 1. Agent generates introduction.md
372
+ 2. User opens in Files app or in-app editor
373
+ 3. User makes refinements
374
+ 4. Agent can see changes via read_file
375
+ 5. Future agent work builds on user refinements
376
+ ```
377
+
378
+ The agent's system prompt should acknowledge this:
379
+
380
+ ```markdown
381
+ ## Working with User Content
382
+
383
+ When you create content (introductions, research notes, etc.), the user may
384
+ edit it afterward. Always read existing files before modifying them—the user
385
+ may have made improvements you should preserve.
386
+
387
+ If a file exists and has been modified by the user (check the metadata or
388
+ compare to your last known version), ask before overwriting.
389
+ ```
390
+
391
+ ### Pattern: User Seeds, Agent Expands
392
+
393
+ ```
394
+ 1. User creates notes.md with initial thoughts
395
+ 2. User asks: "Research more about this"
396
+ 3. Agent reads notes.md to understand context
397
+ 4. Agent adds to notes.md or creates related files
398
+ 5. User continues building on agent additions
399
+ ```
400
+
401
+ ### Pattern: Append-Only Collaboration
402
+
403
+ For chat logs or activity streams:
404
+
405
+ ```markdown
406
+ <!-- activity.md - Both append, neither overwrites -->
407
+
408
+ ## 2024-01-15
409
+
410
+ **User:** Started reading "Moby Dick"
411
+
412
+ **Agent:** Downloaded full text and created research folder
413
+
414
+ **User:** Added highlight about whale symbolism
415
+
416
+ **Agent:** Found 3 academic sources on whale symbolism in Melville's work
417
+ ```
418
+ </collaboration_patterns>
419
+
420
+ <security_considerations>
421
+ ## Security in Shared Workspace
422
+
423
+ ### Scope the Workspace
424
+
425
+ Don't give agents access to the entire filesystem:
426
+
427
+ ```swift
428
+ // GOOD: Scoped to app's documents
429
+ let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
430
+
431
+ tool("read_file", { path }) {
432
+ // Path is relative to documents, can't escape
433
+ let fileURL = documentsURL.appendingPathComponent(path)
434
+ guard fileURL.path.hasPrefix(documentsURL.path) else {
435
+ throw ToolError("Invalid path")
436
+ }
437
+ return try String(contentsOf: fileURL)
438
+ }
439
+
440
+ // BAD: Absolute paths allow escape
441
+ tool("read_file", { path }) {
442
+ return try String(contentsOf: URL(fileURLWithPath: path)) // Can read /etc/passwd!
443
+ }
444
+ ```
445
+
446
+ ### Protect Sensitive Files
447
+
448
+ ```swift
449
+ let protectedPaths = [".env", "credentials.json", "secrets/"]
450
+
451
+ tool("read_file", { path }) {
452
+ if protectedPaths.any({ path.contains($0) }) {
453
+ throw ToolError("Cannot access protected file")
454
+ }
455
+ // ...
456
+ }
457
+ ```
458
+
459
+ ### Audit Agent Actions
460
+
461
+ Log what the agent reads/writes:
462
+
463
+ ```swift
464
+ func logFileAccess(action: String, path: String, agentId: String) {
465
+ logger.info("[\(agentId)] \(action): \(path)")
466
+ }
467
+
468
+ tool("write_file", { path, content }) {
469
+ logFileAccess(action: "WRITE", path: path, agentId: context.agentId)
470
+ // ...
471
+ }
472
+ ```
473
+ </security_considerations>
474
+
475
+ <examples>
476
+ ## Real-World Example: Every Reader
477
+
478
+ The Every Reader app uses shared workspace for research:
479
+
480
+ ```
481
+ Documents/
482
+ ├── Research/
483
+ │ └── book_moby_dick/
484
+ │ ├── full_text.txt # Agent downloads from Gutenberg
485
+ │ ├── introduction.md # Agent generates, personalized
486
+ │ ├── sources/
487
+ │ │ ├── whale_symbolism.md # Agent researches
488
+ │ │ └── melville_bio.md # Agent researches
489
+ │ └── user_notes.md # User can add their own notes
490
+ ├── Chats/
491
+ │ └── 2024-01-15.json # Chat history
492
+ └── profile.md # Agent generated from photos
493
+ ```
494
+
495
+ **How it works:**
496
+
497
+ 1. User adds "Moby Dick" to library
498
+ 2. User starts research agent
499
+ 3. Agent downloads full text to `Research/book_moby_dick/full_text.txt`
500
+ 4. Agent researches and writes to `sources/`
501
+ 5. Agent generates `introduction.md` based on user's reading profile
502
+ 6. User can view all files in the app or Files.app
503
+ 7. User can edit `introduction.md` to refine it
504
+ 8. Chat agent can read all of this context when answering questions
505
+ </examples>
506
+
507
+ <icloud_sync>
508
+ ## iCloud File Storage for Multi-Device Sync (iOS)
509
+
510
+ For agent-native iOS apps, use iCloud Drive's Documents folder for your shared workspace. This gives you **free, automatic multi-device sync** without building a sync layer or running a server.
511
+
512
+ ### Why iCloud Documents?
513
+
514
+ | Approach | Cost | Complexity | Offline | Multi-Device |
515
+ |----------|------|------------|---------|--------------|
516
+ | Custom backend + sync | $$$ | High | Manual | Yes |
517
+ | CloudKit database | Free tier limits | Medium | Manual | Yes |
518
+ | **iCloud Documents** | Free (user's storage) | Low | Automatic | Automatic |
519
+
520
+ iCloud Documents:
521
+ - Uses user's existing iCloud storage (free 5GB, most users have more)
522
+ - Automatic sync across all user's devices
523
+ - Works offline, syncs when online
524
+ - Files visible in Files.app for transparency
525
+ - No server costs, no sync code to maintain
526
+
527
+ ### Implementation Pattern
528
+
529
+ ```swift
530
+ // Get the iCloud Documents container
531
+ func iCloudDocumentsURL() -> URL? {
532
+ FileManager.default.url(forUbiquityContainerIdentifier: nil)?
533
+ .appendingPathComponent("Documents")
534
+ }
535
+
536
+ // Your shared workspace lives in iCloud
537
+ class SharedWorkspace {
538
+ let rootURL: URL
539
+
540
+ init() {
541
+ // Use iCloud if available, fall back to local
542
+ if let iCloudURL = iCloudDocumentsURL() {
543
+ self.rootURL = iCloudURL
544
+ } else {
545
+ // Fallback to local Documents (user not signed into iCloud)
546
+ self.rootURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
547
+ }
548
+ }
549
+
550
+ // All file operations go through this root
551
+ func researchPath(for bookId: String) -> URL {
552
+ rootURL.appendingPathComponent("Research/\(bookId)")
553
+ }
554
+
555
+ func journalPath() -> URL {
556
+ rootURL.appendingPathComponent("Journal")
557
+ }
558
+ }
559
+ ```
560
+
561
+ ### Directory Structure in iCloud
562
+
563
+ ```
564
+ iCloud Drive/
565
+ └── YourApp/ # Your app's container
566
+ └── Documents/ # Visible in Files.app
567
+ ├── Journal/
568
+ │ ├── user/
569
+ │ │ └── 2025-01-15.md # Syncs across devices
570
+ │ └── agent/
571
+ │ └── 2025-01-15.md # Agent observations sync too
572
+ ├── Experiments/
573
+ │ └── magnesium-sleep/
574
+ │ ├── config.json
575
+ │ └── log.json
576
+ └── Research/
577
+ └── {topic}/
578
+ └── sources.md
579
+ ```
580
+
581
+ ### Handling Sync Conflicts
582
+
583
+ iCloud handles conflicts automatically, but you should design for it:
584
+
585
+ ```swift
586
+ // Check for conflicts when reading
587
+ func readJournalEntry(at url: URL) throws -> JournalEntry {
588
+ // iCloud may create .icloud placeholder files for not-yet-downloaded content
589
+ if url.pathExtension == "icloud" {
590
+ // Trigger download
591
+ try FileManager.default.startDownloadingUbiquitousItem(at: url)
592
+ throw FileNotYetAvailableError()
593
+ }
594
+
595
+ let data = try Data(contentsOf: url)
596
+ return try JSONDecoder().decode(JournalEntry.self, from: data)
597
+ }
598
+
599
+ // For writes, use coordinated file access
600
+ func writeJournalEntry(_ entry: JournalEntry, to url: URL) throws {
601
+ let coordinator = NSFileCoordinator()
602
+ var error: NSError?
603
+
604
+ coordinator.coordinate(writingItemAt: url, options: .forReplacing, error: &error) { newURL in
605
+ let data = try? JSONEncoder().encode(entry)
606
+ try? data?.write(to: newURL)
607
+ }
608
+
609
+ if let error = error {
610
+ throw error
611
+ }
612
+ }
613
+ ```
614
+
615
+ ### What This Enables
616
+
617
+ 1. **User starts experiment on iPhone** → Agent creates `Experiments/sleep-tracking/config.json`
618
+ 2. **User opens app on iPad** → Same experiment visible, no sync code needed
619
+ 3. **Agent logs observation on iPhone** → Syncs to iPad automatically
620
+ 4. **User edits journal on iPad** → iPhone sees the edit
621
+
622
+ ### Entitlements Required
623
+
624
+ Add to your app's entitlements:
625
+
626
+ ```xml
627
+ <key>com.apple.developer.icloud-container-identifiers</key>
628
+ <array>
629
+ <string>iCloud.com.yourcompany.yourapp</string>
630
+ </array>
631
+ <key>com.apple.developer.icloud-services</key>
632
+ <array>
633
+ <string>CloudDocuments</string>
634
+ </array>
635
+ <key>com.apple.developer.ubiquity-container-identifiers</key>
636
+ <array>
637
+ <string>iCloud.com.yourcompany.yourapp</string>
638
+ </array>
639
+ ```
640
+
641
+ ### When NOT to Use iCloud Documents
642
+
643
+ - **Sensitive data** - Use Keychain or encrypted local storage instead
644
+ - **High-frequency writes** - iCloud sync has latency; use local + periodic sync
645
+ - **Large media files** - Consider CloudKit Assets or on-demand resources
646
+ - **Shared between users** - iCloud Documents is single-user; use CloudKit for sharing
647
+ </icloud_sync>
648
+
649
+ <checklist>
650
+ ## Shared Workspace Checklist
651
+
652
+ Architecture:
653
+ - [ ] Single shared directory for agent and user data
654
+ - [ ] Organized by domain, not by actor
655
+ - [ ] File tools scoped to workspace (no escape)
656
+ - [ ] Protected paths for sensitive files
657
+
658
+ Tools:
659
+ - [ ] `read_file` - Read any file in workspace
660
+ - [ ] `write_file` - Write any file in workspace
661
+ - [ ] `list_files` - Browse directory structure
662
+ - [ ] `search_text` - Find content across files (optional)
663
+
664
+ UI Integration:
665
+ - [ ] UI observes same files agent writes
666
+ - [ ] Changes reflect immediately (file watching or shared store)
667
+ - [ ] User can edit agent-created files
668
+ - [ ] Agent reads user modifications before overwriting
669
+
670
+ Collaboration:
671
+ - [ ] System prompt acknowledges user may edit files
672
+ - [ ] Agent checks for user modifications before overwriting
673
+ - [ ] Metadata tracks who created/modified (optional)
674
+
675
+ Multi-Device (iOS):
676
+ - [ ] Use iCloud Documents for shared workspace (free sync)
677
+ - [ ] Fallback to local Documents if iCloud unavailable
678
+ - [ ] Handle `.icloud` placeholder files (trigger download)
679
+ - [ ] Use NSFileCoordinator for conflict-safe writes
680
+ </checklist>