popilot 0.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.
Files changed (136) hide show
  1. package/README.md +372 -0
  2. package/adapters/claude-code/.claude/commands/_domain.md.hbs +32 -0
  3. package/adapters/claude-code/.claude/commands/analytics.md.hbs +55 -0
  4. package/adapters/claude-code/.claude/commands/daily.md.hbs +301 -0
  5. package/adapters/claude-code/.claude/commands/dev.md.hbs +62 -0
  6. package/adapters/claude-code/.claude/commands/handoff.md +258 -0
  7. package/adapters/claude-code/.claude/commands/market.md +120 -0
  8. package/adapters/claude-code/.claude/commands/metrics.md +123 -0
  9. package/adapters/claude-code/.claude/commands/oscar-loop.md +436 -0
  10. package/adapters/claude-code/.claude/commands/party.md +85 -0
  11. package/adapters/claude-code/.claude/commands/plan.md +43 -0
  12. package/adapters/claude-code/.claude/commands/research.md +203 -0
  13. package/adapters/claude-code/.claude/commands/retro.md +68 -0
  14. package/adapters/claude-code/.claude/commands/save.md +440 -0
  15. package/adapters/claude-code/.claude/commands/sessions.md +139 -0
  16. package/adapters/claude-code/.claude/commands/sprint.md +106 -0
  17. package/adapters/claude-code/.claude/commands/start.md +368 -0
  18. package/adapters/claude-code/.claude/commands/strategy.md +41 -0
  19. package/adapters/claude-code/.claude/commands/task.md +220 -0
  20. package/adapters/claude-code/.claude/commands/tracking.md +116 -0
  21. package/adapters/claude-code/.claude/commands/validate.md +58 -0
  22. package/adapters/claude-code/CLAUDE.md.hbs +208 -0
  23. package/adapters/claude-code/manifest.yaml +36 -0
  24. package/bin/cli.mjs +218 -0
  25. package/lib/adapter.mjs +68 -0
  26. package/lib/doctor.mjs +161 -0
  27. package/lib/hydrate.mjs +421 -0
  28. package/lib/prompt.mjs +78 -0
  29. package/lib/scaffold.mjs +155 -0
  30. package/lib/setup-wizard.mjs +331 -0
  31. package/lib/template-engine.mjs +164 -0
  32. package/lib/yaml-lite.mjs +476 -0
  33. package/package.json +30 -0
  34. package/scaffold/.context/.secrets.yaml.example +20 -0
  35. package/scaffold/.context/WORKFLOW.md.hbs +332 -0
  36. package/scaffold/.context/agents/TEMPLATE.md +115 -0
  37. package/scaffold/.context/agents/analyst.md.hbs +362 -0
  38. package/scaffold/.context/agents/developer.md.hbs +390 -0
  39. package/scaffold/.context/agents/handoff-specialist.md.hbs +292 -0
  40. package/scaffold/.context/agents/market-researcher.md.hbs +288 -0
  41. package/scaffold/.context/agents/ollie.md +323 -0
  42. package/scaffold/.context/agents/operations.md.hbs +293 -0
  43. package/scaffold/.context/agents/orchestrator.md.hbs +434 -0
  44. package/scaffold/.context/agents/planner.md.hbs +405 -0
  45. package/scaffold/.context/agents/qa.md.hbs +409 -0
  46. package/scaffold/.context/agents/researcher.md.hbs +330 -0
  47. package/scaffold/.context/agents/sage.md +349 -0
  48. package/scaffold/.context/agents/strategist.md.hbs +339 -0
  49. package/scaffold/.context/agents/tracking-governor.md.hbs +291 -0
  50. package/scaffold/.context/agents/validator.md.hbs +365 -0
  51. package/scaffold/.context/integrations/_registry.yaml +38 -0
  52. package/scaffold/.context/integrations/providers/channel_io.yaml +38 -0
  53. package/scaffold/.context/integrations/providers/corti.yaml +203 -0
  54. package/scaffold/.context/integrations/providers/ga4.yaml +116 -0
  55. package/scaffold/.context/integrations/providers/intercom.yaml +47 -0
  56. package/scaffold/.context/integrations/providers/linear.yaml +46 -0
  57. package/scaffold/.context/integrations/providers/mixpanel.yaml +73 -0
  58. package/scaffold/.context/integrations/providers/notebooklm.yaml +74 -0
  59. package/scaffold/.context/integrations/providers/notion.yaml +129 -0
  60. package/scaffold/.context/integrations/providers/prod_db.yaml +183 -0
  61. package/scaffold/.context/oscar/workflows/multi-agent.md +82 -0
  62. package/scaffold/.context/oscar/workflows/ollie-sage.md +128 -0
  63. package/scaffold/.context/oscar/workflows/session-git.md +71 -0
  64. package/scaffold/.context/oscar/workflows/setup.md +663 -0
  65. package/scaffold/.context/oscar/workflows/tracking.md +118 -0
  66. package/scaffold/.context/project.yaml.example +102 -0
  67. package/scaffold/.context/templates/dev-guide.md +217 -0
  68. package/scaffold/.context/templates/epic-spec.md +225 -0
  69. package/scaffold/.context/templates/guardrail.md +94 -0
  70. package/scaffold/.context/templates/handoff-checklist.md +197 -0
  71. package/scaffold/.context/templates/prd.md +80 -0
  72. package/scaffold/.context/templates/retrospective.md +78 -0
  73. package/scaffold/.context/templates/screen-spec.md +714 -0
  74. package/scaffold/.context/templates/sprint-plan.md +72 -0
  75. package/scaffold/.context/templates/sprint-status.yaml +109 -0
  76. package/scaffold/.context/templates/story-v2.md +228 -0
  77. package/scaffold/.context/templates/validation-report.md +99 -0
  78. package/scaffold/.gitignore.append +7 -0
  79. package/scaffold/spec-site/env.d.ts +7 -0
  80. package/scaffold/spec-site/index.html +14 -0
  81. package/scaffold/spec-site/package.json +20 -0
  82. package/scaffold/spec-site/src/App.vue +27 -0
  83. package/scaffold/spec-site/src/assets/icons/menu/ic_ads.svg +10 -0
  84. package/scaffold/spec-site/src/assets/icons/menu/ic_ads_on.svg +10 -0
  85. package/scaffold/spec-site/src/assets/icons/menu/ic_board.svg +14 -0
  86. package/scaffold/spec-site/src/assets/icons/menu/ic_board_on.svg +14 -0
  87. package/scaffold/spec-site/src/assets/icons/menu/ic_dashboard.svg +21 -0
  88. package/scaffold/spec-site/src/assets/icons/menu/ic_dashboard_on.svg +21 -0
  89. package/scaffold/spec-site/src/assets/icons/menu/ic_pricing.svg +20 -0
  90. package/scaffold/spec-site/src/assets/icons/menu/ic_pricing_on.svg +20 -0
  91. package/scaffold/spec-site/src/assets/icons/menu/ic_store.svg +11 -0
  92. package/scaffold/spec-site/src/assets/icons/menu/ic_store_on.svg +11 -0
  93. package/scaffold/spec-site/src/components/Accordion.vue +108 -0
  94. package/scaffold/spec-site/src/components/AppHeader.vue +304 -0
  95. package/scaffold/spec-site/src/components/Badge.vue +25 -0
  96. package/scaffold/spec-site/src/components/CoachingCard.vue +112 -0
  97. package/scaffold/spec-site/src/components/MemoSidebar.vue +239 -0
  98. package/scaffold/spec-site/src/components/MockupShell.vue +100 -0
  99. package/scaffold/spec-site/src/components/RuleTable.vue +99 -0
  100. package/scaffold/spec-site/src/components/ScenarioSwitcher.vue +103 -0
  101. package/scaffold/spec-site/src/components/SpecNav.vue +26 -0
  102. package/scaffold/spec-site/src/components/SpecSection.vue +59 -0
  103. package/scaffold/spec-site/src/components/SummaryGrid.vue +39 -0
  104. package/scaffold/spec-site/src/components/VersionBadge.vue +38 -0
  105. package/scaffold/spec-site/src/composables/useActiveSection.ts +53 -0
  106. package/scaffold/spec-site/src/composables/useMemo.ts +138 -0
  107. package/scaffold/spec-site/src/composables/useRetro.ts +313 -0
  108. package/scaffold/spec-site/src/composables/useScenario.ts +43 -0
  109. package/scaffold/spec-site/src/composables/useScenarioStore.ts +102 -0
  110. package/scaffold/spec-site/src/composables/useTurso.ts +160 -0
  111. package/scaffold/spec-site/src/composables/useUser.ts +25 -0
  112. package/scaffold/spec-site/src/data/navigation.ts +59 -0
  113. package/scaffold/spec-site/src/data/types.ts +90 -0
  114. package/scaffold/spec-site/src/data/wireframeRegistry.ts +25 -0
  115. package/scaffold/spec-site/src/layouts/SplitPaneLayout.vue +79 -0
  116. package/scaffold/spec-site/src/main.ts +10 -0
  117. package/scaffold/spec-site/src/pages/IndexPage.vue +66 -0
  118. package/scaffold/spec-site/src/pages/PolicyDetail.vue +215 -0
  119. package/scaffold/spec-site/src/pages/PolicyIndex.vue +74 -0
  120. package/scaffold/spec-site/src/pages/retro/RetroActions.vue +191 -0
  121. package/scaffold/spec-site/src/pages/retro/RetroBoard.vue +192 -0
  122. package/scaffold/spec-site/src/pages/retro/RetroCard.vue +131 -0
  123. package/scaffold/spec-site/src/pages/retro/RetroHeader.vue +287 -0
  124. package/scaffold/spec-site/src/pages/retro/RetroPage.vue +178 -0
  125. package/scaffold/spec-site/src/pages/shared/NoContentPlaceholder.vue +34 -0
  126. package/scaffold/spec-site/src/pages/shared/PlaceholderContent.vue +22 -0
  127. package/scaffold/spec-site/src/pages/shared/PlaceholderSpecPanel.vue +16 -0
  128. package/scaffold/spec-site/src/pages/shared/PolicyFallback.vue +145 -0
  129. package/scaffold/spec-site/src/pages/wireframe/WireframeShell.vue +151 -0
  130. package/scaffold/spec-site/src/router.ts +85 -0
  131. package/scaffold/spec-site/src/styles/base.css +21 -0
  132. package/scaffold/spec-site/src/styles/split-pane.css +143 -0
  133. package/scaffold/spec-site/src/styles/variables.css +47 -0
  134. package/scaffold/spec-site/src/utils/markdown.ts +197 -0
  135. package/scaffold/spec-site/tsconfig.json +20 -0
  136. package/scaffold/spec-site/vite.config.ts +18 -0
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Minimal markdown -> HTML converter (zero dependencies).
3
+ * Handles the subset used in epic spec documents.
4
+ */
5
+ export function renderMarkdown(md: string): string {
6
+ const lines = md.split('\n')
7
+ const html: string[] = []
8
+ let inCodeBlock = false
9
+ let codeLines: string[] = []
10
+ let inTable = false
11
+ let inList = false
12
+ let listType: 'ul' | 'ol' = 'ul'
13
+
14
+ function closeList() {
15
+ if (inList) {
16
+ html.push(listType === 'ul' ? '</ul>' : '</ol>')
17
+ inList = false
18
+ }
19
+ }
20
+
21
+ function esc(s: string): string {
22
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
23
+ }
24
+
25
+ function escAttr(s: string): string {
26
+ return s
27
+ .replace(/&/g, '&amp;')
28
+ .replace(/"/g, '&quot;')
29
+ .replace(/</g, '&lt;')
30
+ .replace(/>/g, '&gt;')
31
+ }
32
+
33
+ function normalizeHref(raw: string): string | null {
34
+ const href = raw.trim().replace(/&amp;/g, '&')
35
+ if (!href) return null
36
+
37
+ const lowered = href.toLowerCase()
38
+ if (
39
+ lowered.startsWith('javascript:') ||
40
+ lowered.startsWith('data:') ||
41
+ lowered.startsWith('vbscript:')
42
+ ) {
43
+ return null
44
+ }
45
+
46
+ if (
47
+ href.startsWith('#') ||
48
+ href.startsWith('/') ||
49
+ href.startsWith('./') ||
50
+ href.startsWith('../')
51
+ ) {
52
+ return href
53
+ }
54
+
55
+ try {
56
+ const parsed = new URL(href)
57
+ if (
58
+ parsed.protocol === 'http:' ||
59
+ parsed.protocol === 'https:' ||
60
+ parsed.protocol === 'mailto:' ||
61
+ parsed.protocol === 'tel:'
62
+ ) {
63
+ return href
64
+ }
65
+ } catch {
66
+ return null
67
+ }
68
+
69
+ return null
70
+ }
71
+
72
+ function inline(s: string): string {
73
+ s = esc(s)
74
+ // bold
75
+ s = s.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
76
+ // italic
77
+ s = s.replace(/\*(.+?)\*/g, '<em>$1</em>')
78
+ // inline code
79
+ s = s.replace(/`([^`]+)`/g, '<code>$1</code>')
80
+ // links
81
+ s = s.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, text: string, url: string) => {
82
+ const safeHref = normalizeHref(url)
83
+ if (!safeHref) return text
84
+ return `<a href="${escAttr(safeHref)}" rel="noopener noreferrer">${text}</a>`
85
+ })
86
+ return s
87
+ }
88
+
89
+ for (let i = 0; i < lines.length; i++) {
90
+ const line = lines[i]
91
+
92
+ // Code blocks
93
+ if (line.startsWith('```')) {
94
+ if (inCodeBlock) {
95
+ html.push(`<pre><code>${codeLines.map(esc).join('\n')}</code></pre>`)
96
+ codeLines = []
97
+ inCodeBlock = false
98
+ } else {
99
+ closeList()
100
+ inCodeBlock = true
101
+ }
102
+ continue
103
+ }
104
+ if (inCodeBlock) {
105
+ codeLines.push(line)
106
+ continue
107
+ }
108
+
109
+ // Empty line
110
+ if (line.trim() === '') {
111
+ closeList()
112
+ if (inTable) { inTable = false }
113
+ continue
114
+ }
115
+
116
+ // Headings
117
+ const headingMatch = line.match(/^(#{1,4})\s+(.+)/)
118
+ if (headingMatch) {
119
+ closeList()
120
+ const level = headingMatch[1].length
121
+ html.push(`<h${level}>${inline(headingMatch[2])}</h${level}>`)
122
+ continue
123
+ }
124
+
125
+ // Horizontal rule
126
+ if (/^---+$/.test(line.trim())) {
127
+ closeList()
128
+ html.push('<hr>')
129
+ continue
130
+ }
131
+
132
+ // Table
133
+ if (line.trim().startsWith('|')) {
134
+ // Skip separator row
135
+ if (/^\|[\s:-]+\|/.test(line.trim()) && line.includes('-')) continue
136
+
137
+ const cells = line.split('|').filter((_, i, a) => i > 0 && i < a.length - 1).map(c => c.trim())
138
+ if (!inTable) {
139
+ closeList()
140
+ html.push('<table>')
141
+ html.push('<thead><tr>' + cells.map(c => `<th>${inline(c)}</th>`).join('') + '</tr></thead>')
142
+ html.push('<tbody>')
143
+ inTable = true
144
+ } else {
145
+ html.push('<tr>' + cells.map(c => `<td>${inline(c)}</td>`).join('') + '</tr>')
146
+ }
147
+ continue
148
+ }
149
+ if (inTable) {
150
+ html.push('</tbody></table>')
151
+ inTable = false
152
+ }
153
+
154
+ // Blockquote
155
+ if (line.startsWith('> ')) {
156
+ closeList()
157
+ html.push(`<blockquote>${inline(line.slice(2))}</blockquote>`)
158
+ continue
159
+ }
160
+
161
+ // Unordered list
162
+ const ulMatch = line.match(/^(\s*)[-*]\s+(.+)/)
163
+ if (ulMatch) {
164
+ if (!inList || listType !== 'ul') {
165
+ closeList()
166
+ html.push('<ul>')
167
+ inList = true
168
+ listType = 'ul'
169
+ }
170
+ html.push(`<li>${inline(ulMatch[2])}</li>`)
171
+ continue
172
+ }
173
+
174
+ // Ordered list
175
+ const olMatch = line.match(/^(\s*)\d+\.\s+(.+)/)
176
+ if (olMatch) {
177
+ if (!inList || listType !== 'ol') {
178
+ closeList()
179
+ html.push('<ol>')
180
+ inList = true
181
+ listType = 'ol'
182
+ }
183
+ html.push(`<li>${inline(olMatch[2])}</li>`)
184
+ continue
185
+ }
186
+
187
+ // Paragraph
188
+ closeList()
189
+ html.push(`<p>${inline(line)}</p>`)
190
+ }
191
+
192
+ closeList()
193
+ if (inTable) html.push('</tbody></table>')
194
+ if (inCodeBlock) html.push(`<pre><code>${codeLines.map(esc).join('\n')}</code></pre>`)
195
+
196
+ return html.join('\n')
197
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "moduleResolution": "bundler",
7
+ "strict": true,
8
+ "jsx": "preserve",
9
+ "resolveJsonModule": true,
10
+ "isolatedModules": true,
11
+ "esModuleInterop": true,
12
+ "skipLibCheck": true,
13
+ "forceConsistentCasingInFileNames": true,
14
+ "baseUrl": ".",
15
+ "paths": {
16
+ "@/*": ["src/*"]
17
+ }
18
+ },
19
+ "include": ["src/**/*.ts", "src/**/*.vue", "env.d.ts"]
20
+ }
@@ -0,0 +1,18 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+ import { resolve } from 'path'
4
+
5
+ export default defineConfig({
6
+ plugins: [vue()],
7
+ resolve: {
8
+ alias: {
9
+ '@': resolve(__dirname, 'src'),
10
+ },
11
+ },
12
+ server: {
13
+ port: 5174,
14
+ fs: {
15
+ allow: ['..'],
16
+ },
17
+ },
18
+ })