devlyn-cli 0.0.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.
@@ -0,0 +1,680 @@
1
+ # Product Spec
2
+
3
+ > **Purpose**: Source of truth for WHAT to build and WHY.
4
+ > **Usage**: Input for AI agents generating Feature Specs → Plans → Tasks → Code.
5
+ > **Principle**: Define the WHAT and WHY. Downstream agents derive the HOW.
6
+
7
+ ---
8
+
9
+ # 1. META
10
+
11
+ ```yaml
12
+ meta:
13
+ name: "{Product Name}"
14
+ version: "{X.Y}"
15
+ updated: "{YYYY-MM-DD}"
16
+ status: "{draft | review | approved | implementing}"
17
+ owner: "{decision maker}"
18
+
19
+ platform:
20
+ type: "{web | mobile | desktop | cli | backend}"
21
+ framework: "{framework + version}"
22
+ ```
23
+
24
+ ---
25
+
26
+ # 2. IDENTITY
27
+
28
+ ```yaml
29
+ identity:
30
+ summary: "{X is a Y that does Z for W}"
31
+
32
+ insight: "{Core belief that makes this viable — what do we believe that others don't?}"
33
+
34
+ principles:
35
+ # Guide ALL downstream decisions. Feature Specs apply these.
36
+ - principle: "{name}"
37
+ meaning: "{what this means in practice}"
38
+ tradeoff: "{what we sacrifice}"
39
+
40
+ # Common principles to consider:
41
+ # - Optimistic UI (show result before server confirms)
42
+ # - Keyboard-first (every action without mouse)
43
+ # - Progressive disclosure (simple first, reveal complexity)
44
+ # - Undo over confirm (reverse actions vs block with dialogs)
45
+ # - Offline-capable (works without network)
46
+ # - Responsive feedback (user knows state within 100ms)
47
+
48
+ anti_goals:
49
+ - "{what we will NOT build, even if users ask}"
50
+ ```
51
+
52
+ ---
53
+
54
+ # 3. USERS
55
+
56
+ ```yaml
57
+ users:
58
+ primary:
59
+ who: "{description}"
60
+ goals: ["{what they want to accomplish}"]
61
+ pains: ["{current problems}"]
62
+ context: "{when/where they use this}"
63
+ capabilities:
64
+ technical: "{novice | intermediate | expert}"
65
+ domain: "{none | familiar | expert}"
66
+
67
+ not_for:
68
+ - "{who we don't serve, and why}"
69
+ ```
70
+
71
+ ---
72
+
73
+ # 4. INVARIANTS
74
+
75
+ > Rules that must NEVER break. Violations are bugs.
76
+
77
+ ```yaml
78
+ invariants:
79
+ - rule: "{invariant}"
80
+ why: "{rationale}"
81
+
82
+ # Common invariants:
83
+ # - "Users cannot access other users' data"
84
+ # - "All mutations require authentication"
85
+ # - "User data is never permanently deleted without explicit request"
86
+ # - "Secrets never appear in logs or API responses"
87
+ ```
88
+
89
+ # 5. BEHAVIORS
90
+
91
+ > All actions in the system. Feature Specs derive implementation.
92
+
93
+ ```yaml
94
+ behaviors:
95
+ "{behavior_name}":
96
+ purpose: "{what this accomplishes}"
97
+ actor: "{user | system | schedule}"
98
+ trigger: "{what initiates}"
99
+
100
+ input:
101
+ - name: "{name}"
102
+ type: "{type}"
103
+ required: "{true | false}"
104
+ validation: "{rules}"
105
+
106
+ outcome: "{what changes when successful}"
107
+
108
+ rules: # business logic
109
+ - "{rule}"
110
+
111
+ errors:
112
+ - when: "{condition}"
113
+ error: "{code}"
114
+ message: "{user-facing}"
115
+ recovery: "{what user can do}"
116
+
117
+ emits: ["{triggered behaviors or events}"] # optional
118
+ ```
119
+
120
+ <details>
121
+ <summary>Behavior Examples</summary>
122
+
123
+ ```yaml
124
+ paste_content:
125
+ purpose: "Save content from clipboard to inbox"
126
+ actor: user
127
+ trigger: "Paste in drop zone or keyboard shortcut"
128
+
129
+ input:
130
+ - name: content
131
+ type: string | file
132
+ required: true
133
+ validation: "Max 10MB"
134
+ - name: space_id
135
+ type: uuid
136
+ required: false
137
+ validation: "User's space"
138
+
139
+ outcome: "Source created with status=pending"
140
+
141
+ rules:
142
+ - "Detect content type (URL, text, image, file)"
143
+ - "If URL: check for duplicate"
144
+ - "If duplicate: surface existing instead"
145
+
146
+ errors:
147
+ - when: "Clipboard empty"
148
+ error: "EMPTY_CLIPBOARD"
149
+ message: "Nothing to paste"
150
+ recovery: "Copy content first"
151
+ - when: "Exceeds limit"
152
+ error: "TOO_LARGE"
153
+ message: "Content exceeds 10MB"
154
+ recovery: "Try smaller content"
155
+ - when: "Duplicate URL"
156
+ error: "DUPLICATE"
157
+ message: "Already saved"
158
+ recovery: "View existing"
159
+
160
+ emits: [process_source]
161
+
162
+ process_source:
163
+ purpose: "Extract content and generate embedding"
164
+ actor: system
165
+ trigger: "Source created with status=pending"
166
+
167
+ input:
168
+ - name: source_id
169
+ type: uuid
170
+ required: true
171
+
172
+ outcome: "Source has content, embedding, status=complete"
173
+
174
+ rules:
175
+ - "URL: fetch and extract main content"
176
+ - "YouTube: extract transcript"
177
+ - "Image: OCR"
178
+ - "Timeout: 60s"
179
+
180
+ errors:
181
+ - when: "URL unreachable"
182
+ error: "UNREACHABLE"
183
+ message: "Couldn't reach URL"
184
+ recovery: "Check link and retry"
185
+ - when: "Extraction failed"
186
+ error: "EXTRACTION_FAILED"
187
+ message: "Couldn't extract content"
188
+ recovery: "Try different content"
189
+
190
+ search:
191
+ purpose: "Find sources by semantic similarity"
192
+ actor: user
193
+ trigger: "User enters query"
194
+
195
+ input:
196
+ - name: query
197
+ type: string
198
+ required: true
199
+ validation: "1-500 chars"
200
+ - name: space_id
201
+ type: uuid
202
+ required: false
203
+
204
+ outcome: "Ranked list of matching sources (max 20)"
205
+
206
+ rules:
207
+ - "Generate query embedding"
208
+ - "Vector similarity against user's sources"
209
+ - "Only status=complete sources"
210
+
211
+ errors:
212
+ - when: "Query too short"
213
+ error: "QUERY_SHORT"
214
+ message: "Enter a few more words"
215
+ recovery: "Add detail"
216
+ ```
217
+
218
+ </details>
219
+
220
+ ---
221
+
222
+ # 6. PERMISSIONS
223
+
224
+ > Who can do what. Business rules, not implementation.
225
+
226
+ ```yaml
227
+ permissions:
228
+ "{Entity}":
229
+ create: "{who}"
230
+ read: "{who}"
231
+ update: "{who}"
232
+ delete: "{who}"
233
+
234
+ # "who" examples:
235
+ # - "authenticated" (any logged-in user)
236
+ # - "owner" (created/owns the resource)
237
+ # - "owner + invited" (shared access)
238
+ # - "admin" (admin role only)
239
+ # - "public" (no auth required)
240
+ ```
241
+
242
+ Example:
243
+
244
+ ```yaml
245
+ permissions:
246
+ Source:
247
+ create: authenticated
248
+ read: owner
249
+ update: owner
250
+ delete: owner
251
+
252
+ Space:
253
+ create: authenticated
254
+ read: owner
255
+ update: owner
256
+ delete: owner
257
+ ```
258
+
259
+ ---
260
+
261
+ # 7. LIMITS
262
+
263
+ > Business constraints and quotas.
264
+
265
+ ```yaml
266
+ limits:
267
+ tiers:
268
+ "{tier_name}":
269
+ "{resource}": "{limit}"
270
+ price: "{price}" # if paid
271
+
272
+ on_limit: "{block | upgrade_prompt | soft_warning}"
273
+
274
+ # Per-action limits (if different from tier)
275
+ actions:
276
+ "{behavior}": "{limit per time}"
277
+ ```
278
+
279
+ Example:
280
+
281
+ ```yaml
282
+ limits:
283
+ tiers:
284
+ free:
285
+ sources: 100
286
+ storage: "100MB"
287
+ ai_queries: "50/month"
288
+
289
+ pro:
290
+ sources: unlimited
291
+ storage: "10GB"
292
+ ai_queries: unlimited
293
+ price: "$10/month"
294
+
295
+ on_limit: upgrade_prompt
296
+
297
+ actions:
298
+ process_source: "10/minute" # rate limit
299
+ ```
300
+
301
+ ---
302
+
303
+ # 8. INTEGRATIONS
304
+
305
+ > External services we depend on.
306
+
307
+ ```yaml
308
+ integrations:
309
+ "{service}":
310
+ purpose: "{why we use this}"
311
+ used_by: ["{behavior}"]
312
+ fallback: "{what happens if unavailable}" # optional
313
+ ```
314
+
315
+ Example:
316
+
317
+ ```yaml
318
+ integrations:
319
+ openai:
320
+ purpose: "Embeddings (text-embedding-3-small) and chat (gpt-4)"
321
+ used_by: [process_source, chat_with_sources]
322
+ fallback: "Queue for retry, show 'AI temporarily unavailable'"
323
+
324
+ youtube_transcript:
325
+ purpose: "Extract video transcripts"
326
+ used_by: [process_source]
327
+ fallback: "Index title/description only"
328
+
329
+ readability:
330
+ purpose: "Extract article content from URLs"
331
+ used_by: [process_source]
332
+ ```
333
+
334
+ ---
335
+
336
+ # 9. VIEWS
337
+
338
+ > UI surfaces and their states.
339
+
340
+ ```yaml
341
+ views:
342
+ "{view_name}":
343
+ purpose: "{what user does here}"
344
+ route: "{path}"
345
+
346
+ states:
347
+ "{state}":
348
+ when: "{condition}"
349
+ shows: ["{elements}"]
350
+
351
+ data: ["{Entity}"]
352
+ actions: ["{behavior}"]
353
+ ```
354
+
355
+ Example:
356
+
357
+ ```yaml
358
+ views:
359
+ home:
360
+ purpose: "Capture content and browse sources"
361
+ route: "/"
362
+
363
+ states:
364
+ empty:
365
+ when: "No sources"
366
+ shows: [drop_zone, onboarding_hint]
367
+ has_content:
368
+ when: "Has sources"
369
+ shows: [drop_zone, source_list, chat_input]
370
+ viewing_source:
371
+ when: "Source selected"
372
+ shows: [source_list, source_detail_panel]
373
+
374
+ data: [Source, Space]
375
+ actions: [paste_content, search, view_source, delete_source]
376
+
377
+ source_detail:
378
+ purpose: "View and interact with single source"
379
+ route: "/source/:id"
380
+
381
+ states:
382
+ loading:
383
+ when: "Data loading"
384
+ shows: [skeleton]
385
+ processing:
386
+ when: "status=pending|processing"
387
+ shows: [header, processing_indicator]
388
+ ready:
389
+ when: "status=complete"
390
+ shows: [header, content, chat]
391
+ failed:
392
+ when: "status=failed"
393
+ shows: [header, error_state, retry_button]
394
+
395
+ data: [Source, ChatMessage]
396
+ actions: [chat_with_source, edit_source, delete_source]
397
+ ```
398
+
399
+ ---
400
+
401
+ # 10. DESIGN
402
+
403
+ > Visual and verbal direction. Feature Specs derive specifics.
404
+
405
+ ```yaml
406
+ design:
407
+ foundation:
408
+ system: "{base system}" # e.g., "tailwind + shadcn/ui"
409
+
410
+ aesthetic:
411
+ personality: ["{adjective}", "{adjective}", "{adjective}"]
412
+ inspiration:
413
+ - source: "{reference}"
414
+ take: "{what to learn}"
415
+ avoid:
416
+ - "{anti-pattern}"
417
+ signature:
418
+ - "{distinctive element}"
419
+
420
+ patterns:
421
+ # UX conventions — Feature Specs apply these
422
+ list_order: "{newest_first | oldest_first | manual}"
423
+ new_items: "{prepend | append}"
424
+ empty_states: "{illustration | minimal | action-focused}"
425
+ loading: "{skeleton | spinner}"
426
+ optimistic: "{true | false}"
427
+ detail_view: "{panel | page | modal}"
428
+ destructive_actions: "{undo | confirm}"
429
+ density: "{compact | comfortable | spacious}"
430
+
431
+ voice:
432
+ tone: ["{adjective}", "{adjective}"]
433
+ formality: "{formal | conversational | casual}"
434
+ patterns:
435
+ success: "{how to say it}"
436
+ error: "{how to say it}"
437
+ empty: "{how to say it}"
438
+ vocabulary:
439
+ prefer: ["{word}"]
440
+ avoid: ["{word}"]
441
+ ```
442
+
443
+ <details>
444
+ <summary>Full Design Example</summary>
445
+
446
+ ```yaml
447
+ design:
448
+ foundation:
449
+ system: "tailwind + shadcn/ui"
450
+
451
+ aesthetic:
452
+ personality: ["calm", "focused", "intelligent"]
453
+ inspiration:
454
+ - source: "Linear"
455
+ take: "command palette, keyboard-first"
456
+ - source: "Notion"
457
+ take: "content-focused, subtle interactions"
458
+ - source: "Arc"
459
+ take: "spatial organization"
460
+ avoid:
461
+ - "generic SaaS gradients"
462
+ - "stock illustrations"
463
+ - "modal overload"
464
+ - "hamburger menus on desktop"
465
+ signature:
466
+ - "command palette as primary nav"
467
+ - "persistent AI chat sidebar"
468
+ - "monospace for metadata"
469
+
470
+ patterns:
471
+ list_order: newest_first
472
+ new_items: prepend
473
+ empty_states: action-focused
474
+ loading: skeleton
475
+ optimistic: true
476
+ detail_view: panel
477
+ destructive_actions: undo
478
+ density: comfortable
479
+
480
+ voice:
481
+ tone: ["helpful", "concise"]
482
+ formality: conversational
483
+ patterns:
484
+ success: "Brief, no exclamation"
485
+ error: "Cause + fix. No apology."
486
+ empty: "What's missing + one action"
487
+ vocabulary:
488
+ prefer: [save, source, space]
489
+ avoid: [submit, item, folder, oops, please]
490
+ ```
491
+
492
+ </details>
493
+
494
+ ---
495
+
496
+ # 11. POLICIES
497
+
498
+ > Cross-cutting requirements.
499
+
500
+ ```yaml
501
+ policies:
502
+ auth:
503
+ method: "{session | jwt | oauth}"
504
+ providers: ["{provider}"]
505
+
506
+ privacy:
507
+ data_export: "{yes | no}"
508
+ data_deletion: "{soft | hard | on_request}"
509
+
510
+ i18n:
511
+ default: "{locale}"
512
+ supported: ["{locale}"]
513
+
514
+ accessibility:
515
+ standard: "{WCAG 2.1 AA | none}"
516
+ ```
517
+
518
+ ---
519
+
520
+ # 12. PHASES
521
+
522
+ > What's in each release.
523
+
524
+ ```yaml
525
+ phases:
526
+ "{n}":
527
+ name: "{name}"
528
+ goal: "{what users can do after}"
529
+
530
+ includes:
531
+ entities: ["{name}"]
532
+ behaviors: ["{name}"]
533
+ views: ["{name}"]
534
+
535
+ excludes:
536
+ - what: "{deferred}"
537
+ why: "{reason}"
538
+
539
+ success: "{measurable outcome}"
540
+ ```
541
+
542
+ Example:
543
+
544
+ ```yaml
545
+ phases:
546
+ 1:
547
+ name: "Core Capture"
548
+ goal: "Save URLs/text, view, search"
549
+
550
+ includes:
551
+ entities: [User, Source]
552
+ behaviors: [paste_content, process_source, search, delete_source]
553
+ views: [home, source_detail]
554
+
555
+ excludes:
556
+ - what: "AI chat"
557
+ why: "Capture loop first"
558
+ - what: "Spaces"
559
+ why: "Inbox-only simplifies UX"
560
+
561
+ success: "Save URL → find via search in <30s"
562
+ ```
563
+
564
+ ---
565
+
566
+ # 13. DECISIONS
567
+
568
+ > What was decided and WHY.
569
+
570
+ ```yaml
571
+ decisions:
572
+ - id: "D-{n}"
573
+ date: "{YYYY-MM-DD}"
574
+ context: "{what question arose}"
575
+ decision: "{what was decided}"
576
+ why: "{reasoning}"
577
+ implications: ["{consequence}"]
578
+ revisit: "{when to reconsider}"
579
+ ```
580
+
581
+ Example:
582
+
583
+ ```yaml
584
+ decisions:
585
+ - id: "D-001"
586
+ date: "2024-01-15"
587
+ context: "Users want shared spaces for teams"
588
+ decision: "Single-user only for v1"
589
+ why: |
590
+ Collaboration adds complexity (permissions, sync, conflicts).
591
+ Core value is personal knowledge management.
592
+ Teams can layer on once core is solid.
593
+ implications:
594
+ - "No sharing UI"
595
+ - "Simpler permissions"
596
+ revisit: "Post-launch based on feedback"
597
+ ```
598
+
599
+ ---
600
+
601
+ # 14. OPEN
602
+
603
+ > Undecided items.
604
+
605
+ ```yaml
606
+ open:
607
+ - id: "Q-{n}"
608
+ question: "{decision needed}"
609
+ options:
610
+ - "{option}: {tradeoff}"
611
+ blocks: ["{what can't proceed}"]
612
+ owner: "{who decides}"
613
+ deadline: "{when}"
614
+ ```
615
+
616
+ ---
617
+
618
+ # 15. GLOSSARY
619
+
620
+ > Precise definitions.
621
+
622
+ ```yaml
623
+ glossary:
624
+ "{Term}": "{definition in this product's context}"
625
+ ```
626
+
627
+ Example:
628
+
629
+ ```yaml
630
+ glossary:
631
+ Source: "Content saved by user (URL, note, file, etc.)"
632
+ Space: "User-created container for organizing sources"
633
+ Inbox: "Default location for new sources before organized"
634
+ ```
635
+
636
+ ---
637
+
638
+ # Validation Checklist
639
+
640
+ Before generating Feature Specs:
641
+
642
+ - [ ] Principles cover key UX decisions (optimistic? keyboard? undo vs confirm?)
643
+ - [ ] Every entity has complete fields and examples
644
+ - [ ] Every behavior has outcome and errors defined
645
+ - [ ] Permissions cover all entities
646
+ - [ ] Limits define tier boundaries
647
+ - [ ] Integrations list all external dependencies
648
+ - [ ] Design patterns answer: loading? new items? destructive actions?
649
+ - [ ] Decisions explain WHY, not just WHAT
650
+ - [ ] No [TBD] — move to Open Questions
651
+
652
+ ---
653
+
654
+ # Size Guide
655
+
656
+ | Complexity | Lines |
657
+ | ---------- | --------- |
658
+ | MVP | 300-500 |
659
+ | Small | 500-700 |
660
+ | Medium | 700-1000 |
661
+ | Large | 1000-1300 |
662
+
663
+ Over 1300 lines → split into Core + Domain specs.
664
+
665
+ ---
666
+
667
+ # Derivation Reference
668
+
669
+ | Product Spec | → Feature Spec Derives |
670
+ | ------------------------ | ----------------------------- |
671
+ | Entity fields | Schema, types, validators |
672
+ | Entity examples | Test fixtures |
673
+ | Behavior outcome + rules | Logic, sequences |
674
+ | Behavior errors | Error handling, UI feedback |
675
+ | Permissions | Auth middleware |
676
+ | Limits | Quota checks, upgrade prompts |
677
+ | Integrations | API clients, fallbacks |
678
+ | View states | Components, routing |
679
+ | Design patterns | Layout, interactions, loading |
680
+ | Voice | Copy, messages |
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "devlyn-cli",
3
+ "version": "0.0.1",
4
+ "description": "Claude Code configuration toolkit for teams",
5
+ "bin": {
6
+ "devlyn": "bin/devlyn.js"
7
+ },
8
+ "files": [
9
+ "bin",
10
+ "config"
11
+ ],
12
+ "keywords": [
13
+ "claude",
14
+ "claude-code",
15
+ "ai",
16
+ "config",
17
+ "devlyn"
18
+ ],
19
+ "author": "",
20
+ "license": "MIT",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/fysoul17/devlyn-cli.git"
24
+ }
25
+ }