@drunkcoding/agents-and-skills 0.0.45 → 0.0.46

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 (107) hide show
  1. package/.claude-plugin/marketplace.json +2 -47
  2. package/README.md +3 -6
  3. package/package.json +4 -1
  4. package/plugins/multica-tool/.claude-plugin/plugin.json +1 -1
  5. package/plugins/multica-tool/scripts/lib.mjs +53 -4
  6. package/plugins/multica-tool/scripts/multica-export.mjs +135 -32
  7. package/plugins/multica-tool/scripts/multica-import.mjs +192 -17
  8. package/plugins/multica-tool/skills/export/SKILL.md +84 -14
  9. package/plugins/multica-tool/skills/import/SKILL.md +22 -7
  10. package/plugins/multica-tool/skills/sync/SKILL.md +1 -1
  11. package/plugins/plugin-validator/.claude-plugin/plugin.json +1 -1
  12. package/plugins/html-effectiveness/.claude-plugin/plugin.json +0 -17
  13. package/plugins/html-effectiveness/README.md +0 -28
  14. package/plugins/html-effectiveness/agents/report-builder.md +0 -66
  15. package/plugins/html-effectiveness/assets/base.css +0 -51
  16. package/plugins/html-effectiveness/assets/base.js +0 -11
  17. package/plugins/html-effectiveness/assets/charts.js +0 -1
  18. package/plugins/html-effectiveness/assets/components.css +0 -10
  19. package/plugins/html-effectiveness/commands/html-report.md +0 -13
  20. package/plugins/html-effectiveness/docs/template-gallery.md +0 -28
  21. package/plugins/html-effectiveness/package.json +0 -6
  22. package/plugins/html-effectiveness/scripts/_tmp.js +0 -37
  23. package/plugins/html-effectiveness/scripts/catalog.js +0 -47
  24. package/plugins/html-effectiveness/scripts/extract.js +0 -104
  25. package/plugins/html-effectiveness/scripts/mustache.js +0 -90
  26. package/plugins/html-effectiveness/scripts/render.js +0 -176
  27. package/plugins/html-effectiveness/skills/html-effectiveness/SKILL.md +0 -94
  28. package/plugins/html-effectiveness/templates/01-exploration-code-approaches.html.tmpl +0 -400
  29. package/plugins/html-effectiveness/templates/02-exploration-visual-designs.html.tmpl +0 -456
  30. package/plugins/html-effectiveness/templates/03-code-review-pr.html.tmpl +0 -581
  31. package/plugins/html-effectiveness/templates/04-code-understanding.html.tmpl +0 -443
  32. package/plugins/html-effectiveness/templates/05-design-system.html.tmpl +0 -578
  33. package/plugins/html-effectiveness/templates/06-component-variants.html.tmpl +0 -557
  34. package/plugins/html-effectiveness/templates/07-prototype-animation.html.tmpl +0 -417
  35. package/plugins/html-effectiveness/templates/08-prototype-interaction.html.tmpl +0 -363
  36. package/plugins/html-effectiveness/templates/09-slide-deck.html.tmpl +0 -535
  37. package/plugins/html-effectiveness/templates/10-svg-illustrations.html.tmpl +0 -444
  38. package/plugins/html-effectiveness/templates/11-status-report.html.tmpl +0 -152
  39. package/plugins/html-effectiveness/templates/12-incident-report.html.tmpl +0 -547
  40. package/plugins/html-effectiveness/templates/13-flowchart-diagram.html.tmpl +0 -361
  41. package/plugins/html-effectiveness/templates/14-research-feature-explainer.html.tmpl +0 -348
  42. package/plugins/html-effectiveness/templates/15-research-concept-explainer.html.tmpl +0 -334
  43. package/plugins/html-effectiveness/templates/16-implementation-plan.html.tmpl +0 -657
  44. package/plugins/html-effectiveness/templates/17-pr-writeup.html.tmpl +0 -553
  45. package/plugins/html-effectiveness/templates/18-editor-triage-board.html.tmpl +0 -541
  46. package/plugins/html-effectiveness/templates/19-editor-feature-flags.html.tmpl +0 -627
  47. package/plugins/html-effectiveness/templates/20-editor-prompt-tuner.html.tmpl +0 -687
  48. package/plugins/html-effectiveness/templates/manifest.json +0 -441
  49. package/plugins/team-share/.claude-plugin/plugin.json +0 -18
  50. package/plugins/team-share/README.md +0 -46
  51. package/plugins/team-share/agents/team-share.md +0 -53
  52. package/plugins/team-share/commands/team-share.md +0 -4
  53. package/plugins/team-share/skills/claude-config/SKILL.md +0 -143
  54. package/plugins/team-share/skills/codegraph-setup/SKILL.md +0 -81
  55. package/plugins/team-share/skills/understand-setup/SKILL.md +0 -115
  56. package/plugins/tech-graph/.claude-plugin/plugin.json +0 -17
  57. package/plugins/tech-graph/README.md +0 -66
  58. package/plugins/tech-graph/agents/tech-graph.md +0 -97
  59. package/plugins/tech-graph/commands/tech-graph.md +0 -13
  60. package/plugins/tech-graph/scripts/check-deps.sh +0 -55
  61. package/plugins/tech-graph/skills/tech-graph/LICENSE +0 -21
  62. package/plugins/tech-graph/skills/tech-graph/README.md +0 -555
  63. package/plugins/tech-graph/skills/tech-graph/README.zh.md +0 -514
  64. package/plugins/tech-graph/skills/tech-graph/SKILL.md +0 -263
  65. package/plugins/tech-graph/skills/tech-graph/agents/openai.yaml +0 -4
  66. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style1-flat.png +0 -0
  67. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style2-dark.png +0 -0
  68. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style3-blueprint.png +0 -0
  69. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style4-notion.png +0 -0
  70. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style5-glass.png +0 -0
  71. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style6-claude.png +0 -0
  72. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style7-openai.png +0 -0
  73. package/plugins/tech-graph/skills/tech-graph/fixtures/agent-memory-types-style4.json +0 -181
  74. package/plugins/tech-graph/skills/tech-graph/fixtures/api-flow-style7.json +0 -40
  75. package/plugins/tech-graph/skills/tech-graph/fixtures/mem0-style1.json +0 -297
  76. package/plugins/tech-graph/skills/tech-graph/fixtures/microservices-style3.json +0 -64
  77. package/plugins/tech-graph/skills/tech-graph/fixtures/multi-agent-style5.json +0 -45
  78. package/plugins/tech-graph/skills/tech-graph/fixtures/system-architecture-style6.json +0 -48
  79. package/plugins/tech-graph/skills/tech-graph/fixtures/tool-call-style2.json +0 -182
  80. package/plugins/tech-graph/skills/tech-graph/package.json +0 -42
  81. package/plugins/tech-graph/skills/tech-graph/references/diagram-types.md +0 -171
  82. package/plugins/tech-graph/skills/tech-graph/references/icons.md +0 -406
  83. package/plugins/tech-graph/skills/tech-graph/references/style-1-flat-icon.md +0 -108
  84. package/plugins/tech-graph/skills/tech-graph/references/style-2-dark-terminal.md +0 -107
  85. package/plugins/tech-graph/skills/tech-graph/references/style-3-blueprint.md +0 -113
  86. package/plugins/tech-graph/skills/tech-graph/references/style-4-notion-clean.md +0 -95
  87. package/plugins/tech-graph/skills/tech-graph/references/style-5-glassmorphism.md +0 -125
  88. package/plugins/tech-graph/skills/tech-graph/references/style-6-claude-official.md +0 -209
  89. package/plugins/tech-graph/skills/tech-graph/references/style-7-openai.md +0 -215
  90. package/plugins/tech-graph/skills/tech-graph/references/style-diagram-matrix.md +0 -135
  91. package/plugins/tech-graph/skills/tech-graph/references/svg-layout-best-practices.md +0 -100
  92. package/plugins/tech-graph/skills/tech-graph/references/svg-to-png.md +0 -115
  93. package/plugins/tech-graph/skills/tech-graph/scripts/README.md +0 -269
  94. package/plugins/tech-graph/skills/tech-graph/scripts/generate-diagram.sh +0 -181
  95. package/plugins/tech-graph/skills/tech-graph/scripts/generate-from-template.py +0 -1587
  96. package/plugins/tech-graph/skills/tech-graph/scripts/test-all-styles.sh +0 -143
  97. package/plugins/tech-graph/skills/tech-graph/scripts/validate-svg.sh +0 -306
  98. package/plugins/tech-graph/skills/tech-graph/templates/agent-architecture.svg +0 -28
  99. package/plugins/tech-graph/skills/tech-graph/templates/architecture.svg +0 -23
  100. package/plugins/tech-graph/skills/tech-graph/templates/comparison-matrix.svg +0 -14
  101. package/plugins/tech-graph/skills/tech-graph/templates/data-flow.svg +0 -28
  102. package/plugins/tech-graph/skills/tech-graph/templates/er-diagram.svg +0 -21
  103. package/plugins/tech-graph/skills/tech-graph/templates/flowchart.svg +0 -21
  104. package/plugins/tech-graph/skills/tech-graph/templates/sequence.svg +0 -20
  105. package/plugins/tech-graph/skills/tech-graph/templates/state-machine.svg +0 -20
  106. package/plugins/tech-graph/skills/tech-graph/templates/timeline.svg +0 -19
  107. package/plugins/tech-graph/skills/tech-graph/templates/use-case.svg +0 -21
@@ -1,541 +0,0 @@
1
- <!--
2
- template: 18-editor-triage-board
3
- upstream: 18-editor-triage-board.html
4
- slots:
5
- title: string # replaces first <h1> innerHTML
6
- -->
7
- <div class="wrap">
8
-
9
- <header>
10
- <div class="eyebrow">Acme / editor / triage</div>
11
- <h1>{{title}}</h1>
12
- <p class="sub">
13
- Twenty-four open Linear tickets, pre-sorted into a best guess. Drag them
14
- across Now / Next / Later / Cut until the cut feels right, then copy the
15
- result back into the planning doc as markdown.
16
- </p>
17
- <div class="hintline">drag tickets between columns &nbsp;·&nbsp; click a tag to filter</div>
18
- </header>
19
-
20
- <div class="toolbar">
21
- <div class="summary" id="summary"></div>
22
- <div class="spacer"></div>
23
- <button class="filter-active" id="filterBadge"></button>
24
- <button class="ghost" id="resetBtn">Reset</button>
25
- <button class="primary" id="copyBtn">Copy as markdown</button>
26
- </div>
27
-
28
- <div class="board" id="board"></div>
29
-
30
- </div>
31
-
32
- <style>
33
- * { box-sizing: border-box; }
34
- .wrap {
35
- max-width: 1180px;
36
- margin: 0 auto;
37
- padding: 48px 32px 64px;
38
- }
39
- /* ---------- header ---------- */
40
- header { margin-bottom: 22px; }
41
- .eyebrow {
42
- font-family: var(--mono);
43
- font-size: 11px;
44
- letter-spacing: 0.08em;
45
- text-transform: uppercase;
46
- color: var(--gray-500);
47
- }
48
- h1 {
49
- font-family: var(--serif);
50
- font-weight: 500;
51
- font-size: 30px;
52
- letter-spacing: -0.01em;
53
- margin: 6px 0 4px;
54
- }
55
- .sub {
56
- color: var(--gray-500);
57
- max-width: 620px;
58
- margin: 0;
59
- }
60
- .hintline {
61
- font-family: var(--mono);
62
- font-size: 11px;
63
- color: var(--gray-500);
64
- margin-top: 10px;
65
- }
66
- .hintline::before {
67
- content: "›";
68
- color: var(--clay);
69
- margin-right: 6px;
70
- }
71
- /* ---------- toolbar ---------- */
72
- .toolbar {
73
- position: sticky;
74
- top: 0;
75
- z-index: 5;
76
- background: var(--ivory);
77
- display: flex;
78
- align-items: center;
79
- gap: 14px;
80
- padding: 14px 0 12px;
81
- margin-bottom: 14px;
82
- border-bottom: 1.5px solid var(--gray-200);
83
- }
84
- .summary {
85
- font-family: var(--mono);
86
- font-size: 12px;
87
- color: var(--gray-800);
88
- letter-spacing: 0.01em;
89
- }
90
- .summary b { color: var(--slate); font-weight: 600; }
91
- .summary .dot { color: var(--gray-200); margin: 0 4px; }
92
- .spacer { flex: 1; }
93
- .filter-active {
94
- font-family: var(--mono);
95
- font-size: 11px;
96
- color: var(--clay-d);
97
- background: #F5E6DE;
98
- border: 1.5px solid #E8C9BA;
99
- border-radius: 999px;
100
- padding: 4px 10px;
101
- cursor: pointer;
102
- display: none;
103
- }
104
- .filter-active.on { display: inline-block; }
105
- .filter-active:hover { border-color: var(--clay); }
106
- button.primary {
107
- background: var(--slate);
108
- color: var(--ivory);
109
- border: 1.5px solid var(--slate);
110
- border-radius: 999px;
111
- font-family: var(--mono);
112
- font-size: 12px;
113
- padding: 9px 16px;
114
- cursor: pointer;
115
- letter-spacing: 0.01em;
116
- }
117
- button.primary:hover { background: var(--gray-800); }
118
- button.primary.copied { background: var(--olive); border-color: var(--olive); }
119
- button.ghost {
120
- background: transparent;
121
- color: var(--gray-800);
122
- border: 1.5px solid var(--gray-200);
123
- border-radius: 999px;
124
- font-family: var(--mono);
125
- font-size: 12px;
126
- padding: 9px 16px;
127
- cursor: pointer;
128
- }
129
- button.ghost:hover { border-color: var(--gray-500); }
130
- /* ---------- board ---------- */
131
- .board {
132
- display: grid;
133
- grid-template-columns: repeat(4, 1fr);
134
- gap: 16px;
135
- align-items: start;
136
- }
137
- .col {
138
- background: var(--white);
139
- border: 1.5px solid var(--gray-200);
140
- border-radius: 12px;
141
- overflow: hidden;
142
- display: flex;
143
- flex-direction: column;
144
- min-height: 200px;
145
- }
146
- .col[data-col="now"] { border-top: 3px solid var(--clay); }
147
- .col[data-col="next"] { border-top: 3px solid var(--olive); }
148
- .col[data-col="later"] { border-top: 3px solid var(--gray-500); }
149
- .col[data-col="cut"] { border-top: 3px solid var(--gray-200); }
150
- .col.dragover {
151
- outline: 2px dashed var(--clay);
152
- outline-offset: -6px;
153
- background: #FBF6F2;
154
- }
155
- .col-head {
156
- position: sticky;
157
- top: 0;
158
- z-index: 1;
159
- background: var(--white);
160
- display: flex;
161
- align-items: baseline;
162
- gap: 8px;
163
- padding: 14px 14px 10px;
164
- border-bottom: 1.5px solid var(--gray-50);
165
- }
166
- .col-head h2 {
167
- font-family: var(--serif);
168
- font-weight: 500;
169
- font-size: 17px;
170
- margin: 0;
171
- letter-spacing: -0.01em;
172
- }
173
- .col-head .count {
174
- margin-left: auto;
175
- font-family: var(--mono);
176
- font-size: 11px;
177
- color: var(--gray-500);
178
- background: var(--gray-50);
179
- border: 1.5px solid var(--gray-200);
180
- border-radius: 999px;
181
- padding: 1px 8px;
182
- min-width: 26px;
183
- text-align: center;
184
- }
185
- .col-body {
186
- padding: 10px 10px 6px;
187
- display: flex;
188
- flex-direction: column;
189
- gap: 8px;
190
- flex: 1;
191
- min-height: 60px;
192
- }
193
- .col-foot {
194
- border-top: 1.5px solid var(--gray-50);
195
- padding: 8px 14px 12px;
196
- font-family: var(--mono);
197
- font-size: 11px;
198
- color: var(--gray-500);
199
- display: flex;
200
- justify-content: space-between;
201
- }
202
- .col-foot b { color: var(--gray-800); font-weight: 600; }
203
- /* ---------- ticket card ---------- */
204
- .ticket {
205
- background: var(--white);
206
- border: 1.5px solid var(--gray-200);
207
- border-radius: 8px;
208
- padding: 10px 11px 9px;
209
- cursor: grab;
210
- user-select: none;
211
- transition: border-color 120ms ease, box-shadow 120ms ease, opacity 120ms ease;
212
- }
213
- .ticket:hover { border-color: var(--gray-500); box-shadow: 0 1px 3px rgba(20,20,19,0.06); }
214
- .ticket:active { cursor: grabbing; }
215
- .ticket.dragging { opacity: .4; }
216
- .ticket.dim { opacity: .25; }
217
- .ticket-top {
218
- display: flex;
219
- align-items: center;
220
- gap: 8px;
221
- margin-bottom: 5px;
222
- }
223
- .tid {
224
- font-family: var(--mono);
225
- font-size: 11px;
226
- color: var(--gray-500);
227
- letter-spacing: 0.01em;
228
- }
229
- .tag {
230
- font-family: var(--mono);
231
- font-size: 10px;
232
- text-transform: uppercase;
233
- letter-spacing: 0.05em;
234
- border-radius: 999px;
235
- padding: 1px 7px 2px;
236
- border: 1px solid transparent;
237
- cursor: pointer;
238
- }
239
- .tag:hover { filter: brightness(0.96); }
240
- .tag-bug { background: #F5E2D8; color: var(--clay-d); border-color: #E8C9BA; }
241
- .tag-feat { background: #E8EDE0; color: #5C6F44; border-color: #CFDAC0; }
242
- .tag-chore { background: var(--gray-50); color: var(--gray-800); border-color: var(--gray-200); }
243
- .tag-debt { background: var(--gray-50); color: var(--gray-800); border-color: var(--gray-200); }
244
- .est {
245
- margin-left: auto;
246
- font-family: var(--mono);
247
- font-size: 10px;
248
- color: var(--gray-500);
249
- border: 1.5px solid var(--gray-200);
250
- border-radius: 4px;
251
- width: 18px;
252
- height: 18px;
253
- display: flex;
254
- align-items: center;
255
- justify-content: center;
256
- }
257
- .ttitle {
258
- font-size: 13px;
259
- line-height: 1.35;
260
- color: var(--slate);
261
- margin-bottom: 7px;
262
- }
263
- .ticket-bot {
264
- display: flex;
265
- align-items: center;
266
- gap: 6px;
267
- }
268
- .owner {
269
- font-family: var(--mono);
270
- font-size: 10px;
271
- width: 20px;
272
- height: 20px;
273
- border-radius: 50%;
274
- background: var(--oat);
275
- color: var(--gray-800);
276
- display: flex;
277
- align-items: center;
278
- justify-content: center;
279
- letter-spacing: 0.02em;
280
- }
281
- .owner.o2 { background: #DCE4D2; }
282
- .owner.o3 { background: #ECD9CE; }
283
- .owner.o4 { background: var(--gray-50); }
284
- @media (max-width: 920px) {
285
- .board { grid-template-columns: repeat(2, 1fr); }
286
- }
287
- </style>
288
-
289
- <script>
290
- // ---------- data ----------
291
- var COLUMNS = [
292
- { key: 'now', label: 'Now', rationale: 'Blocking the v2.4 release or actively losing user data.' },
293
- { key: 'next', label: 'Next', rationale: 'High-leverage and well-scoped — start the moment Now clears.' },
294
- { key: 'later', label: 'Later', rationale: 'Real, but can ride to a future cycle without anyone noticing.' },
295
- { key: 'cut', label: 'Cut', rationale: 'Not this quarter — close, dedupe, or push back to the requester.' }
296
- ];
297
-
298
- var EST_PTS = { S: 1, M: 2, L: 3 };
299
-
300
- // tag, est, owner, col
301
- var INITIAL = [
302
- { id: 'BIR-241', title: 'Fix sync conflict toast firing twice on reconnect', tag: 'bug', est: 'M', owner: 'AK', col: 'now' },
303
- { id: 'BIR-238', title: 'Comments lost when editing offline then reloading', tag: 'bug', est: 'L', owner: 'JM', col: 'now' },
304
- { id: 'BIR-252', title: 'Billing webhook 500s on annual → monthly downgrade', tag: 'bug', est: 'M', owner: 'RS', col: 'now' },
305
- { id: 'BIR-219', title: 'Migrate workspace permissions to new ACL table', tag: 'debt', est: 'L', owner: 'AK', col: 'now' },
306
- { id: 'BIR-260', title: 'SSO login loop on Safari 17 with strict cookies', tag: 'bug', est: 'S', owner: 'TN', col: 'now' },
307
-
308
- { id: 'BIR-244', title: 'Inline @-mention picker in doc comments', tag: 'feat', est: 'M', owner: 'JM', col: 'next' },
309
- { id: 'BIR-231', title: 'Bulk-archive completed projects from the sidebar', tag: 'feat', est: 'S', owner: 'EL', col: 'next' },
310
- { id: 'BIR-247', title: 'Activity feed: collapse repeated edit events', tag: 'feat', est: 'M', owner: 'TN', col: 'next' },
311
- { id: 'BIR-228', title: 'Notification preferences per project', tag: 'feat', est: 'L', owner: 'EL', col: 'next' },
312
- { id: 'BIR-255', title: 'Keyboard shortcut cheat-sheet overlay (⌘/)', tag: 'feat', est: 'S', owner: 'RS', col: 'next' },
313
- { id: 'BIR-236', title: 'Empty-state illustrations for new workspaces', tag: 'chore', est: 'S', owner: 'EL', col: 'next' },
314
- { id: 'BIR-249', title: 'Audit log export to CSV for admins', tag: 'feat', est: 'M', owner: 'AK', col: 'next' },
315
-
316
- { id: 'BIR-213', title: 'Dark mode pass on settings + billing pages', tag: 'chore', est: 'M', owner: 'EL', col: 'later' },
317
- { id: 'BIR-258', title: 'Slack integration: post on milestone close', tag: 'feat', est: 'M', owner: 'RS', col: 'later' },
318
- { id: 'BIR-221', title: 'Replace moment.js with date-fns across web', tag: 'debt', est: 'L', owner: 'TN', col: 'later' },
319
- { id: 'BIR-263', title: 'Drag-to-reorder columns on the board view', tag: 'feat', est: 'M', owner: 'JM', col: 'later' },
320
- { id: 'BIR-209', title: 'Upgrade Postgres minor + reindex search vectors', tag: 'chore', est: 'M', owner: 'AK', col: 'later' },
321
- { id: 'BIR-251', title: 'Per-doc read receipts in the share dialog', tag: 'feat', est: 'L', owner: 'JM', col: 'later' },
322
- { id: 'BIR-240', title: 'Onboarding checklist resurfaces after dismissal', tag: 'bug', est: 'S', owner: 'TN', col: 'later' },
323
- { id: 'BIR-265', title: 'Add request-id to client error reports', tag: 'debt', est: 'S', owner: 'RS', col: 'later' },
324
-
325
- { id: 'BIR-198', title: 'Custom emoji reactions on comments', tag: 'feat', est: 'M', owner: 'EL', col: 'cut' },
326
- { id: 'BIR-204', title: 'Native Windows desktop wrapper', tag: 'feat', est: 'L', owner: 'TN', col: 'cut' },
327
- { id: 'BIR-217', title: 'AI summary of long comment threads', tag: 'feat', est: 'L', owner: 'JM', col: 'cut' },
328
- { id: 'BIR-233', title: 'Public roadmap page with voting', tag: 'feat', est: 'L', owner: 'RS', col: 'cut' }
329
- ];
330
-
331
- var OWNER_CLASS = { AK: 'o1', JM: 'o2', RS: 'o3', TN: 'o4', EL: 'o1' };
332
-
333
- var tickets = []; // live state
334
- var activeFilter = null; // tag string or null
335
- var dragId = null;
336
-
337
- // ---------- build DOM ----------
338
- var board = document.getElementById('board');
339
- var colBodies = {};
340
- var colCounts = {};
341
- var colFoots = {};
342
-
343
- COLUMNS.forEach(function (c) {
344
- var col = document.createElement('section');
345
- col.className = 'col';
346
- col.dataset.col = c.key;
347
-
348
- var head = document.createElement('div');
349
- head.className = 'col-head';
350
- var h2 = document.createElement('h2');
351
- h2.textContent = c.label;
352
- var count = document.createElement('span');
353
- count.className = 'count';
354
- head.appendChild(h2);
355
- head.appendChild(count);
356
-
357
- var body = document.createElement('div');
358
- body.className = 'col-body';
359
-
360
- var foot = document.createElement('div');
361
- foot.className = 'col-foot';
362
-
363
- col.appendChild(head);
364
- col.appendChild(body);
365
- col.appendChild(foot);
366
- board.appendChild(col);
367
-
368
- colBodies[c.key] = body;
369
- colCounts[c.key] = count;
370
- colFoots[c.key] = foot;
371
-
372
- // drop targets
373
- col.addEventListener('dragover', function (e) {
374
- e.preventDefault();
375
- e.dataTransfer.dropEffect = 'move';
376
- col.classList.add('dragover');
377
- });
378
- col.addEventListener('dragleave', function (e) {
379
- if (!col.contains(e.relatedTarget)) col.classList.remove('dragover');
380
- });
381
- col.addEventListener('drop', function (e) {
382
- e.preventDefault();
383
- col.classList.remove('dragover');
384
- if (!dragId) return;
385
- var t = tickets.find(function (x) { return x.id === dragId; });
386
- if (t && t.col !== c.key) { t.col = c.key; render(); }
387
- });
388
- });
389
-
390
- function makeCard(t) {
391
- var card = document.createElement('article');
392
- card.className = 'ticket';
393
- card.draggable = true;
394
- card.dataset.id = t.id;
395
- if (activeFilter && t.tag !== activeFilter) card.classList.add('dim');
396
-
397
- var top = document.createElement('div');
398
- top.className = 'ticket-top';
399
- var tid = document.createElement('span');
400
- tid.className = 'tid';
401
- tid.textContent = t.id;
402
- var tag = document.createElement('button');
403
- tag.type = 'button';
404
- tag.className = 'tag tag-' + t.tag;
405
- tag.textContent = t.tag;
406
- tag.addEventListener('click', function (e) {
407
- e.stopPropagation();
408
- activeFilter = (activeFilter === t.tag) ? null : t.tag;
409
- render();
410
- });
411
- var est = document.createElement('span');
412
- est.className = 'est';
413
- est.textContent = t.est;
414
- top.appendChild(tid);
415
- top.appendChild(tag);
416
- top.appendChild(est);
417
-
418
- var title = document.createElement('div');
419
- title.className = 'ttitle';
420
- title.textContent = t.title;
421
-
422
- var bot = document.createElement('div');
423
- bot.className = 'ticket-bot';
424
- var owner = document.createElement('span');
425
- owner.className = 'owner ' + (OWNER_CLASS[t.owner] || 'o1');
426
- owner.textContent = t.owner;
427
- bot.appendChild(owner);
428
-
429
- card.appendChild(top);
430
- card.appendChild(title);
431
- card.appendChild(bot);
432
-
433
- card.addEventListener('dragstart', function (e) {
434
- dragId = t.id;
435
- card.classList.add('dragging');
436
- e.dataTransfer.effectAllowed = 'move';
437
- e.dataTransfer.setData('text/plain', t.id);
438
- });
439
- card.addEventListener('dragend', function () {
440
- dragId = null;
441
- card.classList.remove('dragging');
442
- document.querySelectorAll('.col.dragover').forEach(function (el) {
443
- el.classList.remove('dragover');
444
- });
445
- });
446
-
447
- return card;
448
- }
449
-
450
- function render() {
451
- COLUMNS.forEach(function (c) { colBodies[c.key].innerHTML = ''; });
452
- var counts = {};
453
- var pts = {};
454
- COLUMNS.forEach(function (c) { counts[c.key] = 0; pts[c.key] = 0; });
455
-
456
- tickets.forEach(function (t) {
457
- colBodies[t.col].appendChild(makeCard(t));
458
- counts[t.col] += 1;
459
- pts[t.col] += EST_PTS[t.est] || 0;
460
- });
461
-
462
- COLUMNS.forEach(function (c) {
463
- colCounts[c.key].textContent = counts[c.key];
464
- colFoots[c.key].innerHTML = 'estimate <b>' + pts[c.key] + ' pt' + (pts[c.key] === 1 ? '' : 's') + '</b>';
465
- });
466
-
467
- var summary = document.getElementById('summary');
468
- summary.innerHTML = COLUMNS.map(function (c) {
469
- return '<b>' + counts[c.key] + '</b>&nbsp;' + c.key;
470
- }).join('<span class="dot">·</span>');
471
-
472
- var badge = document.getElementById('filterBadge');
473
- if (activeFilter) {
474
- badge.textContent = 'filter: ' + activeFilter + ' ×';
475
- badge.classList.add('on');
476
- } else {
477
- badge.classList.remove('on');
478
- }
479
- }
480
-
481
- document.getElementById('filterBadge').addEventListener('click', function () {
482
- activeFilter = null;
483
- render();
484
- });
485
-
486
- // ---------- export ----------
487
- function buildMarkdown() {
488
- var lines = [];
489
- lines.push('# Acme — Cycle 14 triage');
490
- lines.push('');
491
- COLUMNS.forEach(function (c) {
492
- var rows = tickets.filter(function (t) { return t.col === c.key; });
493
- var pts = rows.reduce(function (s, t) { return s + (EST_PTS[t.est] || 0); }, 0);
494
- lines.push('## ' + c.label + ' (' + rows.length + ' · ' + pts + ' pts)');
495
- lines.push('');
496
- lines.push('_' + c.rationale + '_');
497
- lines.push('');
498
- rows.forEach(function (t) {
499
- lines.push('- **' + t.id + '** ' + t.title + ' — ' + t.tag + ', ' + t.est + ', ' + t.owner);
500
- });
501
- lines.push('');
502
- });
503
- return lines.join('\n');
504
- }
505
-
506
- var copyBtn = document.getElementById('copyBtn');
507
- var copyTimer = null;
508
- copyBtn.addEventListener('click', function () {
509
- var md = buildMarkdown();
510
- function flash() {
511
- copyBtn.textContent = 'Copied ✓';
512
- copyBtn.classList.add('copied');
513
- clearTimeout(copyTimer);
514
- copyTimer = setTimeout(function () {
515
- copyBtn.textContent = 'Copy as markdown';
516
- copyBtn.classList.remove('copied');
517
- }, 1200);
518
- }
519
- if (navigator.clipboard && navigator.clipboard.writeText) {
520
- navigator.clipboard.writeText(md).then(flash, flash);
521
- } else {
522
- var ta = document.createElement('textarea');
523
- ta.value = md;
524
- document.body.appendChild(ta);
525
- ta.select();
526
- try { document.execCommand('copy'); } catch (e) {}
527
- document.body.removeChild(ta);
528
- flash();
529
- }
530
- });
531
-
532
- document.getElementById('resetBtn').addEventListener('click', function () {
533
- tickets = INITIAL.map(function (t) { return Object.assign({}, t); });
534
- activeFilter = null;
535
- render();
536
- });
537
-
538
- // ---------- init ----------
539
- tickets = INITIAL.map(function (t) { return Object.assign({}, t); });
540
- render();
541
- </script>