claudeck 1.0.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 (157) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +233 -0
  3. package/cli.js +2 -0
  4. package/config/agent-chains.json +16 -0
  5. package/config/agent-dags.json +16 -0
  6. package/config/agents.json +46 -0
  7. package/config/bot-prompt.json +3 -0
  8. package/config/folders.json +66 -0
  9. package/config/prompts.json +92 -0
  10. package/config/repos.json +86 -0
  11. package/config/telegram-config.json +17 -0
  12. package/config/workflows.json +90 -0
  13. package/db.js +1198 -0
  14. package/package.json +55 -0
  15. package/plugins/claude-editor/client.css +171 -0
  16. package/plugins/claude-editor/client.js +183 -0
  17. package/plugins/event-stream/client.css +207 -0
  18. package/plugins/event-stream/client.js +271 -0
  19. package/plugins/linear/client.css +345 -0
  20. package/plugins/linear/client.js +380 -0
  21. package/plugins/linear/config.json +5 -0
  22. package/plugins/linear/server.js +312 -0
  23. package/plugins/repos/client.css +549 -0
  24. package/plugins/repos/client.js +663 -0
  25. package/plugins/repos/server.js +232 -0
  26. package/plugins/sudoku/client.css +196 -0
  27. package/plugins/sudoku/client.js +329 -0
  28. package/plugins/tasks/client.css +414 -0
  29. package/plugins/tasks/client.js +394 -0
  30. package/plugins/tasks/server.js +116 -0
  31. package/plugins/tic-tac-toe/client.css +167 -0
  32. package/plugins/tic-tac-toe/client.js +241 -0
  33. package/public/css/core/components.css +232 -0
  34. package/public/css/core/layout.css +330 -0
  35. package/public/css/core/print.css +18 -0
  36. package/public/css/core/reset.css +36 -0
  37. package/public/css/core/responsive.css +378 -0
  38. package/public/css/core/theme.css +116 -0
  39. package/public/css/core/variables.css +93 -0
  40. package/public/css/features/agent-monitor.css +297 -0
  41. package/public/css/features/agent-sidebar.css +525 -0
  42. package/public/css/features/agents.css +996 -0
  43. package/public/css/features/analytics.css +181 -0
  44. package/public/css/features/background-sessions.css +321 -0
  45. package/public/css/features/cost-dashboard.css +168 -0
  46. package/public/css/features/home.css +313 -0
  47. package/public/css/features/retro-terminal.css +88 -0
  48. package/public/css/features/telegram.css +127 -0
  49. package/public/css/features/tour.css +148 -0
  50. package/public/css/features/voice-input.css +60 -0
  51. package/public/css/features/welcome.css +241 -0
  52. package/public/css/panels/assistant-bot.css +442 -0
  53. package/public/css/panels/dev-docs.css +292 -0
  54. package/public/css/panels/file-explorer.css +322 -0
  55. package/public/css/panels/git-panel.css +221 -0
  56. package/public/css/panels/mcp-manager.css +199 -0
  57. package/public/css/panels/tips-feed.css +353 -0
  58. package/public/css/ui/commands.css +273 -0
  59. package/public/css/ui/context-gauge.css +76 -0
  60. package/public/css/ui/file-picker.css +69 -0
  61. package/public/css/ui/image-attachments.css +106 -0
  62. package/public/css/ui/messages.css +884 -0
  63. package/public/css/ui/modals.css +122 -0
  64. package/public/css/ui/parallel.css +217 -0
  65. package/public/css/ui/permissions.css +110 -0
  66. package/public/css/ui/right-panel.css +481 -0
  67. package/public/css/ui/sessions.css +689 -0
  68. package/public/css/ui/status-bar.css +425 -0
  69. package/public/css/ui/toolbox.css +206 -0
  70. package/public/data/tips.json +218 -0
  71. package/public/icons/favicon.png +0 -0
  72. package/public/icons/icon-192.png +0 -0
  73. package/public/icons/icon-512.png +0 -0
  74. package/public/icons/whaly.png +0 -0
  75. package/public/index.html +1140 -0
  76. package/public/js/core/api.js +591 -0
  77. package/public/js/core/constants.js +3 -0
  78. package/public/js/core/dom.js +270 -0
  79. package/public/js/core/events.js +10 -0
  80. package/public/js/core/plugin-loader.js +153 -0
  81. package/public/js/core/store.js +39 -0
  82. package/public/js/core/utils.js +25 -0
  83. package/public/js/core/ws.js +64 -0
  84. package/public/js/features/agent-monitor.js +222 -0
  85. package/public/js/features/agents.js +1209 -0
  86. package/public/js/features/analytics.js +397 -0
  87. package/public/js/features/attachments.js +251 -0
  88. package/public/js/features/background-sessions.js +475 -0
  89. package/public/js/features/chat.js +589 -0
  90. package/public/js/features/cost-dashboard.js +152 -0
  91. package/public/js/features/dag-editor.js +399 -0
  92. package/public/js/features/easter-egg.js +46 -0
  93. package/public/js/features/home.js +270 -0
  94. package/public/js/features/projects.js +372 -0
  95. package/public/js/features/prompts.js +228 -0
  96. package/public/js/features/sessions.js +332 -0
  97. package/public/js/features/telegram.js +131 -0
  98. package/public/js/features/tour.js +210 -0
  99. package/public/js/features/voice-input.js +185 -0
  100. package/public/js/features/welcome.js +43 -0
  101. package/public/js/features/workflows.js +277 -0
  102. package/public/js/main.js +51 -0
  103. package/public/js/panels/assistant-bot.js +445 -0
  104. package/public/js/panels/dev-docs.js +380 -0
  105. package/public/js/panels/file-explorer.js +486 -0
  106. package/public/js/panels/git-panel.js +285 -0
  107. package/public/js/panels/mcp-manager.js +311 -0
  108. package/public/js/panels/tips-feed.js +303 -0
  109. package/public/js/ui/commands.js +114 -0
  110. package/public/js/ui/context-gauge.js +100 -0
  111. package/public/js/ui/diff.js +124 -0
  112. package/public/js/ui/disabled-tools.js +36 -0
  113. package/public/js/ui/export.js +74 -0
  114. package/public/js/ui/formatting.js +206 -0
  115. package/public/js/ui/header-dropdowns.js +72 -0
  116. package/public/js/ui/input-meta.js +71 -0
  117. package/public/js/ui/max-turns.js +21 -0
  118. package/public/js/ui/messages.js +387 -0
  119. package/public/js/ui/model-selector.js +20 -0
  120. package/public/js/ui/notifications.js +232 -0
  121. package/public/js/ui/parallel.js +176 -0
  122. package/public/js/ui/permissions.js +168 -0
  123. package/public/js/ui/right-panel.js +173 -0
  124. package/public/js/ui/shortcuts.js +143 -0
  125. package/public/js/ui/sidebar-toggle.js +29 -0
  126. package/public/js/ui/status-bar.js +172 -0
  127. package/public/js/ui/tab-sdk.js +623 -0
  128. package/public/js/ui/theme.js +38 -0
  129. package/public/manifest.json +13 -0
  130. package/public/offline.html +190 -0
  131. package/public/style.css +42 -0
  132. package/public/sw.js +91 -0
  133. package/server/agent-loop.js +385 -0
  134. package/server/dag-executor.js +265 -0
  135. package/server/orchestrator.js +514 -0
  136. package/server/paths.js +61 -0
  137. package/server/plugin-mount.js +56 -0
  138. package/server/push-sender.js +31 -0
  139. package/server/routes/agents.js +294 -0
  140. package/server/routes/bot.js +45 -0
  141. package/server/routes/exec.js +35 -0
  142. package/server/routes/files.js +218 -0
  143. package/server/routes/mcp.js +82 -0
  144. package/server/routes/messages.js +36 -0
  145. package/server/routes/notifications.js +37 -0
  146. package/server/routes/projects.js +207 -0
  147. package/server/routes/prompts.js +53 -0
  148. package/server/routes/sessions.js +103 -0
  149. package/server/routes/stats.js +143 -0
  150. package/server/routes/telegram.js +71 -0
  151. package/server/routes/tips.js +135 -0
  152. package/server/routes/workflows.js +81 -0
  153. package/server/summarizer.js +55 -0
  154. package/server/telegram-poller.js +205 -0
  155. package/server/telegram-sender.js +304 -0
  156. package/server/ws-handler.js +926 -0
  157. package/server.js +179 -0
@@ -0,0 +1,329 @@
1
+ // Sudoku — Tab SDK plugin
2
+ // A mini sudoku game to play while waiting for tasks to finish
3
+ import { registerTab } from '/js/ui/tab-sdk.js';
4
+
5
+ registerTab({
6
+ id: 'sudoku',
7
+ title: 'Sudoku',
8
+ icon: '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/></svg>',
9
+ lazy: true,
10
+
11
+ init(ctx) {
12
+ const root = document.createElement('div');
13
+ root.className = 'sudoku-tab';
14
+ root.style.cssText = 'display:flex;flex-direction:column;flex:1;overflow:hidden;';
15
+
16
+ // ── State ──
17
+ let board = []; // current board (0 = empty)
18
+ let solution = []; // full solution
19
+ let fixed = []; // true if cell was part of the puzzle
20
+ let selectedCell = null;
21
+ let errors = new Set();
22
+ let timerInterval = null;
23
+ let seconds = 0;
24
+ let gameWon = false;
25
+
26
+ // ── Sudoku Generator ──
27
+ function shuffle(arr) {
28
+ for (let i = arr.length - 1; i > 0; i--) {
29
+ const j = Math.floor(Math.random() * (i + 1));
30
+ [arr[i], arr[j]] = [arr[j], arr[i]];
31
+ }
32
+ return arr;
33
+ }
34
+
35
+ function isValid(grid, row, col, num) {
36
+ for (let i = 0; i < 9; i++) {
37
+ if (grid[row][i] === num || grid[i][col] === num) return false;
38
+ }
39
+ const br = Math.floor(row / 3) * 3, bc = Math.floor(col / 3) * 3;
40
+ for (let r = br; r < br + 3; r++)
41
+ for (let c = bc; c < bc + 3; c++)
42
+ if (grid[r][c] === num) return false;
43
+ return true;
44
+ }
45
+
46
+ function solve(grid) {
47
+ for (let r = 0; r < 9; r++) {
48
+ for (let c = 0; c < 9; c++) {
49
+ if (grid[r][c] === 0) {
50
+ const nums = shuffle([1,2,3,4,5,6,7,8,9]);
51
+ for (const n of nums) {
52
+ if (isValid(grid, r, c, n)) {
53
+ grid[r][c] = n;
54
+ if (solve(grid)) return true;
55
+ grid[r][c] = 0;
56
+ }
57
+ }
58
+ return false;
59
+ }
60
+ }
61
+ }
62
+ return true;
63
+ }
64
+
65
+ function generatePuzzle(clues = 36) {
66
+ const grid = Array.from({length: 9}, () => Array(9).fill(0));
67
+ solve(grid);
68
+ solution = grid.map(r => [...r]);
69
+
70
+ board = grid.map(r => [...r]);
71
+ fixed = Array.from({length: 9}, () => Array(9).fill(true));
72
+
73
+ const cells = shuffle([...Array(81).keys()]);
74
+ const toRemove = 81 - clues;
75
+ for (let i = 0; i < toRemove; i++) {
76
+ const r = Math.floor(cells[i] / 9), c = cells[i] % 9;
77
+ board[r][c] = 0;
78
+ fixed[r][c] = false;
79
+ }
80
+ }
81
+
82
+ // ── Timer ──
83
+ function startTimer() {
84
+ stopTimer();
85
+ seconds = 0;
86
+ gameWon = false;
87
+ timerInterval = setInterval(() => {
88
+ if (!gameWon) {
89
+ seconds++;
90
+ const el = root.querySelector('.sudoku-timer');
91
+ if (el) el.textContent = formatTime(seconds);
92
+ }
93
+ }, 1000);
94
+ }
95
+
96
+ function stopTimer() {
97
+ if (timerInterval) { clearInterval(timerInterval); timerInterval = null; }
98
+ }
99
+
100
+ function formatTime(s) {
101
+ const m = Math.floor(s / 60);
102
+ return `${m}:${String(s % 60).padStart(2, '0')}`;
103
+ }
104
+
105
+ // ── Render ──
106
+ function render() {
107
+ const gridEl = root.querySelector('.sudoku-grid');
108
+ if (!gridEl) return;
109
+ gridEl.innerHTML = '';
110
+
111
+ for (let r = 0; r < 9; r++) {
112
+ for (let c = 0; c < 9; c++) {
113
+ const cell = document.createElement('div');
114
+ cell.className = 'sudoku-cell';
115
+ cell.dataset.row = r;
116
+ cell.dataset.col = c;
117
+
118
+ if (fixed[r][c]) cell.classList.add('fixed');
119
+ if (selectedCell && selectedCell[0] === r && selectedCell[1] === c) cell.classList.add('selected');
120
+ if (errors.has(`${r},${c}`)) cell.classList.add('error');
121
+
122
+ // Highlight same number
123
+ if (selectedCell && board[r][c] !== 0 && board[selectedCell[0]][selectedCell[1]] === board[r][c]) {
124
+ cell.classList.add('highlight');
125
+ }
126
+ // Highlight same row/col/box
127
+ if (selectedCell) {
128
+ const [sr, sc] = selectedCell;
129
+ const sameRow = r === sr;
130
+ const sameCol = c === sc;
131
+ const sameBox = Math.floor(r/3) === Math.floor(sr/3) && Math.floor(c/3) === Math.floor(sc/3);
132
+ if (sameRow || sameCol || sameBox) cell.classList.add('in-scope');
133
+ }
134
+
135
+ // Box borders
136
+ if (c % 3 === 0 && c !== 0) cell.classList.add('box-left');
137
+ if (r % 3 === 0 && r !== 0) cell.classList.add('box-top');
138
+
139
+ cell.textContent = board[r][c] || '';
140
+ gridEl.appendChild(cell);
141
+ }
142
+ }
143
+
144
+ // Update remaining count
145
+ const remaining = board.flat().filter(v => v === 0).length;
146
+ const remEl = root.querySelector('.sudoku-remaining');
147
+ if (remEl) remEl.textContent = `${remaining} empty`;
148
+ }
149
+
150
+ function checkErrors() {
151
+ errors.clear();
152
+ for (let r = 0; r < 9; r++) {
153
+ for (let c = 0; c < 9; c++) {
154
+ if (board[r][c] === 0) continue;
155
+ const val = board[r][c];
156
+ // Check row
157
+ for (let i = 0; i < 9; i++) {
158
+ if (i !== c && board[r][i] === val) { errors.add(`${r},${c}`); errors.add(`${r},${i}`); }
159
+ }
160
+ // Check col
161
+ for (let i = 0; i < 9; i++) {
162
+ if (i !== r && board[i][c] === val) { errors.add(`${r},${c}`); errors.add(`${i},${c}`); }
163
+ }
164
+ // Check box
165
+ const br = Math.floor(r/3)*3, bc = Math.floor(c/3)*3;
166
+ for (let rr = br; rr < br+3; rr++)
167
+ for (let cc = bc; cc < bc+3; cc++)
168
+ if ((rr !== r || cc !== c) && board[rr][cc] === val) { errors.add(`${r},${c}`); errors.add(`${rr},${cc}`); }
169
+ }
170
+ }
171
+ }
172
+
173
+ function checkWin() {
174
+ if (board.flat().some(v => v === 0)) return false;
175
+ if (errors.size > 0) return false;
176
+ return true;
177
+ }
178
+
179
+ function newGame(difficulty) {
180
+ const clues = difficulty === 'easy' ? 42 : difficulty === 'medium' ? 33 : 26;
181
+ generatePuzzle(clues);
182
+ selectedCell = null;
183
+ errors.clear();
184
+ gameWon = false;
185
+ startTimer();
186
+ render();
187
+ const msg = root.querySelector('.sudoku-message');
188
+ if (msg) msg.textContent = '';
189
+ // Update active difficulty button
190
+ root.querySelectorAll('.sudoku-diff-btn').forEach(b => {
191
+ b.classList.toggle('active', b.dataset.diff === difficulty);
192
+ });
193
+ }
194
+
195
+ // ── Build DOM ──
196
+ root.innerHTML = `
197
+ <div class="sudoku-header">
198
+ <div class="sudoku-controls">
199
+ <button class="sudoku-diff-btn active" data-diff="easy">Easy</button>
200
+ <button class="sudoku-diff-btn" data-diff="medium">Medium</button>
201
+ <button class="sudoku-diff-btn" data-diff="hard">Hard</button>
202
+ </div>
203
+ <div class="sudoku-info">
204
+ <span class="sudoku-timer">0:00</span>
205
+ <span class="sudoku-remaining">0 empty</span>
206
+ </div>
207
+ </div>
208
+ <div class="sudoku-board-wrap">
209
+ <div class="sudoku-grid"></div>
210
+ </div>
211
+ <div class="sudoku-numpad"></div>
212
+ <div class="sudoku-actions">
213
+ <button class="sudoku-action-btn" data-action="hint">Hint</button>
214
+ <button class="sudoku-action-btn" data-action="erase">Erase</button>
215
+ <button class="sudoku-action-btn" data-action="check">Check</button>
216
+ <button class="sudoku-action-btn" data-action="new">New Game</button>
217
+ </div>
218
+ <div class="sudoku-message"></div>
219
+ `;
220
+
221
+ // Number pad
222
+ const numpad = root.querySelector('.sudoku-numpad');
223
+ for (let n = 1; n <= 9; n++) {
224
+ const btn = document.createElement('button');
225
+ btn.className = 'sudoku-num-btn';
226
+ btn.textContent = n;
227
+ btn.addEventListener('click', () => placeNumber(n));
228
+ numpad.appendChild(btn);
229
+ }
230
+
231
+ function placeNumber(n) {
232
+ if (!selectedCell || gameWon) return;
233
+ const [r, c] = selectedCell;
234
+ if (fixed[r][c]) return;
235
+ board[r][c] = n;
236
+ checkErrors();
237
+ render();
238
+ if (checkWin()) {
239
+ gameWon = true;
240
+ stopTimer();
241
+ const msg = root.querySelector('.sudoku-message');
242
+ if (msg) msg.textContent = `Solved in ${formatTime(seconds)}!`;
243
+ }
244
+ }
245
+
246
+ // ── Grid click ──
247
+ root.querySelector('.sudoku-grid').addEventListener('click', (e) => {
248
+ const cell = e.target.closest('.sudoku-cell');
249
+ if (!cell || gameWon) return;
250
+ selectedCell = [+cell.dataset.row, +cell.dataset.col];
251
+ render();
252
+ });
253
+
254
+ // ── Action buttons ──
255
+ root.querySelector('.sudoku-actions').addEventListener('click', (e) => {
256
+ const btn = e.target.closest('.sudoku-action-btn');
257
+ if (!btn) return;
258
+ const action = btn.dataset.action;
259
+
260
+ if (action === 'new') {
261
+ const activeDiff = root.querySelector('.sudoku-diff-btn.active');
262
+ newGame(activeDiff ? activeDiff.dataset.diff : 'easy');
263
+ } else if (action === 'erase') {
264
+ if (!selectedCell) return;
265
+ const [r, c] = selectedCell;
266
+ if (!fixed[r][c]) { board[r][c] = 0; checkErrors(); render(); }
267
+ } else if (action === 'hint') {
268
+ if (!selectedCell || gameWon) return;
269
+ const [r, c] = selectedCell;
270
+ if (fixed[r][c] || board[r][c] === solution[r][c]) return;
271
+ board[r][c] = solution[r][c];
272
+ fixed[r][c] = true;
273
+ checkErrors();
274
+ render();
275
+ if (checkWin()) {
276
+ gameWon = true;
277
+ stopTimer();
278
+ const msg = root.querySelector('.sudoku-message');
279
+ if (msg) msg.textContent = `Solved in ${formatTime(seconds)}!`;
280
+ }
281
+ } else if (action === 'check') {
282
+ checkErrors();
283
+ render();
284
+ const msg = root.querySelector('.sudoku-message');
285
+ if (msg) msg.textContent = errors.size === 0 ? 'No errors found!' : `${errors.size} conflicting cells`;
286
+ setTimeout(() => { if (msg) msg.textContent = ''; }, 2000);
287
+ }
288
+ });
289
+
290
+ // ── Difficulty buttons ──
291
+ root.querySelector('.sudoku-controls').addEventListener('click', (e) => {
292
+ const btn = e.target.closest('.sudoku-diff-btn');
293
+ if (!btn) return;
294
+ newGame(btn.dataset.diff);
295
+ });
296
+
297
+ // ── Keyboard input ──
298
+ root.addEventListener('keydown', (e) => {
299
+ if (!selectedCell || gameWon) return;
300
+ const [r, c] = selectedCell;
301
+
302
+ if (e.key >= '1' && e.key <= '9') {
303
+ placeNumber(+e.key);
304
+ } else if (e.key === 'Backspace' || e.key === 'Delete' || e.key === '0') {
305
+ if (!fixed[r][c]) { board[r][c] = 0; checkErrors(); render(); }
306
+ } else if (e.key === 'ArrowUp' && r > 0) { selectedCell = [r-1, c]; render(); }
307
+ else if (e.key === 'ArrowDown' && r < 8) { selectedCell = [r+1, c]; render(); }
308
+ else if (e.key === 'ArrowLeft' && c > 0) { selectedCell = [r, c-1]; render(); }
309
+ else if (e.key === 'ArrowRight' && c < 8) { selectedCell = [r, c+1]; render(); }
310
+ });
311
+
312
+ // Make root focusable for keyboard events
313
+ root.tabIndex = 0;
314
+
315
+ // Start first game
316
+ newGame('easy');
317
+
318
+ return root;
319
+ },
320
+
321
+ onActivate() {
322
+ const root = document.querySelector('.sudoku-tab');
323
+ if (root) root.focus();
324
+ },
325
+
326
+ onDestroy() {
327
+ // Timer cleanup handled by closure
328
+ },
329
+ });