claudeck 1.4.0 → 1.4.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.
Files changed (37) hide show
  1. package/README.md +6 -6
  2. package/package.json +1 -1
  3. package/plugins/claude-editor/manifest.json +10 -0
  4. package/plugins/linear/manifest.json +10 -0
  5. package/plugins/repos/manifest.json +10 -0
  6. package/public/css/ui/right-panel.css +207 -0
  7. package/public/css/ui/settings.css +75 -0
  8. package/public/index.html +7 -0
  9. package/public/js/components/settings-modal.js +65 -0
  10. package/public/js/core/events.js +11 -0
  11. package/public/js/core/plugin-loader.js +96 -11
  12. package/public/js/core/store.js +11 -0
  13. package/public/js/main.js +1 -0
  14. package/public/js/panels/assistant-bot.js +16 -0
  15. package/public/js/panels/dev-docs.js +2 -2
  16. package/public/js/panels/memory.js +1 -0
  17. package/public/js/ui/context-gauge.js +10 -1
  18. package/public/js/ui/header-dropdowns.js +30 -0
  19. package/public/js/ui/input-meta.js +13 -6
  20. package/public/js/ui/max-turns.js +6 -3
  21. package/public/js/ui/model-selector.js +1 -0
  22. package/public/js/ui/permissions.js +1 -0
  23. package/public/js/ui/tab-sdk.js +395 -176
  24. package/public/style.css +1 -0
  25. package/server/memory-optimizer.js +17 -13
  26. package/server/routes/marketplace.js +316 -0
  27. package/server/ws-handler.js +22 -15
  28. package/server.js +18 -0
  29. package/plugins/event-stream/client.css +0 -207
  30. package/plugins/event-stream/client.js +0 -271
  31. package/plugins/sudoku/client.css +0 -196
  32. package/plugins/sudoku/client.js +0 -329
  33. package/plugins/tasks/client.css +0 -414
  34. package/plugins/tasks/client.js +0 -394
  35. package/plugins/tasks/server.js +0 -116
  36. package/plugins/tic-tac-toe/client.css +0 -167
  37. package/plugins/tic-tac-toe/client.js +0 -241
@@ -1,241 +0,0 @@
1
- // Tic Tac Toe — Tab SDK plugin
2
- // A classic tic-tac-toe game vs AI or a friend
3
- import { registerTab } from '/js/ui/tab-sdk.js';
4
-
5
- registerTab({
6
- id: 'tic-tac-toe',
7
- title: 'Tic Tac Toe',
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"><line x1="8" y1="2" x2="8" y2="22"/><line x1="16" y1="2" x2="16" y2="22"/><line x1="2" y1="8" x2="22" y2="8"/><line x1="2" y1="16" x2="22" y2="16"/></svg>',
9
- lazy: true,
10
-
11
- init(ctx) {
12
- const root = document.createElement('div');
13
- root.className = 'tic-tac-toe-tab';
14
- root.style.cssText = 'display:flex;flex-direction:column;flex:1;overflow:hidden;';
15
-
16
- // ── State ──
17
- let board = Array(9).fill(null); // 'X', 'O', or null
18
- let currentPlayer = 'X'; // X always goes first
19
- const mode = 'ai';
20
- let difficulty = 'hard'; // 'easy', 'medium', 'hard'
21
- let gameOver = false;
22
- let winLine = null;
23
- let scores = { X: 0, O: 0, draw: 0 };
24
-
25
- const WIN_COMBOS = [
26
- [0,1,2],[3,4,5],[6,7,8], // rows
27
- [0,3,6],[1,4,7],[2,5,8], // cols
28
- [0,4,8],[2,4,6], // diags
29
- ];
30
-
31
- function checkWin(b) {
32
- for (const combo of WIN_COMBOS) {
33
- const [a, c, d] = combo;
34
- if (b[a] && b[a] === b[c] && b[a] === b[d]) return combo;
35
- }
36
- return null;
37
- }
38
-
39
- function isDraw(b) {
40
- return b.every(cell => cell !== null) && !checkWin(b);
41
- }
42
-
43
- // ── AI (minimax) ──
44
- function minimax(b, isMax, depth) {
45
- const win = checkWin(b);
46
- if (win) return b[win[0]] === 'O' ? 10 - depth : depth - 10;
47
- if (b.every(c => c !== null)) return 0;
48
-
49
- if (isMax) {
50
- let best = -Infinity;
51
- for (let i = 0; i < 9; i++) {
52
- if (!b[i]) { b[i] = 'O'; best = Math.max(best, minimax(b, false, depth + 1)); b[i] = null; }
53
- }
54
- return best;
55
- } else {
56
- let best = Infinity;
57
- for (let i = 0; i < 9; i++) {
58
- if (!b[i]) { b[i] = 'X'; best = Math.min(best, minimax(b, true, depth + 1)); b[i] = null; }
59
- }
60
- return best;
61
- }
62
- }
63
-
64
- function getAiMove() {
65
- const empty = board.map((v, i) => v === null ? i : -1).filter(i => i >= 0);
66
- if (empty.length === 0) return -1;
67
-
68
- if (difficulty === 'easy') {
69
- // Random move
70
- return empty[Math.floor(Math.random() * empty.length)];
71
- }
72
-
73
- if (difficulty === 'medium') {
74
- // 50% chance of optimal, 50% random
75
- if (Math.random() < 0.5) return empty[Math.floor(Math.random() * empty.length)];
76
- }
77
-
78
- // Hard: full minimax
79
- let bestScore = -Infinity;
80
- let bestMove = empty[0];
81
- for (const i of empty) {
82
- board[i] = 'O';
83
- const score = minimax(board, false, 0);
84
- board[i] = null;
85
- if (score > bestScore) { bestScore = score; bestMove = i; }
86
- }
87
- return bestMove;
88
- }
89
-
90
- // ── Game logic ──
91
- function makeMove(index) {
92
- if (board[index] || gameOver) return;
93
- board[index] = currentPlayer;
94
- const win = checkWin(board);
95
- if (win) {
96
- winLine = win;
97
- gameOver = true;
98
- scores[currentPlayer]++;
99
- render();
100
- return;
101
- }
102
- if (isDraw(board)) {
103
- gameOver = true;
104
- scores.draw++;
105
- render();
106
- return;
107
- }
108
- currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
109
- render();
110
-
111
- // AI turn
112
- if (mode === 'ai' && currentPlayer === 'O' && !gameOver) {
113
- setTimeout(() => {
114
- const move = getAiMove();
115
- if (move >= 0) makeMove(move);
116
- }, 200);
117
- }
118
- }
119
-
120
- function resetBoard() {
121
- board = Array(9).fill(null);
122
- currentPlayer = 'X';
123
- gameOver = false;
124
- winLine = null;
125
- render();
126
- }
127
-
128
- function resetScores() {
129
- scores = { X: 0, O: 0, draw: 0 };
130
- resetBoard();
131
- }
132
-
133
- // ── Render ──
134
- function getStatusText() {
135
- if (gameOver) {
136
- const win = checkWin(board);
137
- if (win) {
138
- const winner = board[win[0]];
139
- return winner === 'X' ? 'You win!' : 'AI wins!';
140
- }
141
- return "It's a draw!";
142
- }
143
- return currentPlayer === 'X' ? 'Your turn (X)' : 'AI thinking...';
144
- }
145
-
146
- function render() {
147
- const gridEl = root.querySelector('.ttt-grid');
148
- const statusEl = root.querySelector('.ttt-status');
149
- const scoreEl = root.querySelector('.ttt-scores');
150
-
151
- if (!gridEl) return;
152
-
153
- // Grid
154
- gridEl.innerHTML = '';
155
- for (let i = 0; i < 9; i++) {
156
- const cell = document.createElement('div');
157
- cell.className = 'ttt-cell';
158
- cell.dataset.index = i;
159
- if (board[i]) {
160
- cell.textContent = board[i];
161
- cell.classList.add(board[i] === 'X' ? 'is-x' : 'is-o');
162
- }
163
- if (winLine && winLine.includes(i)) cell.classList.add('winner');
164
- if (!board[i] && !gameOver) cell.classList.add('empty');
165
- gridEl.appendChild(cell);
166
- }
167
-
168
- // Status
169
- if (statusEl) {
170
- statusEl.textContent = getStatusText();
171
- statusEl.className = 'ttt-status';
172
- if (gameOver) {
173
- const win = checkWin(board);
174
- if (win) {
175
- const w = board[win[0]];
176
- statusEl.classList.add(w === 'X' ? 'status-win' : 'status-lose');
177
- } else {
178
- statusEl.classList.add('status-draw');
179
- }
180
- }
181
- }
182
-
183
- // Scores
184
- if (scoreEl) {
185
- scoreEl.innerHTML = `
186
- <span class="ttt-score-item"><span class="ttt-score-x">You</span> ${scores.X}</span>
187
- <span class="ttt-score-sep">·</span>
188
- <span class="ttt-score-item"><span class="ttt-score-draw">Draw</span> ${scores.draw}</span>
189
- <span class="ttt-score-sep">·</span>
190
- <span class="ttt-score-item"><span class="ttt-score-o">AI</span> ${scores.O}</span>
191
- `;
192
- }
193
- }
194
-
195
- // ── Build DOM ──
196
- root.innerHTML = `
197
- <div class="ttt-header">
198
- <div class="ttt-diff-btns">
199
- <button class="ttt-diff-btn" data-diff="easy">Easy</button>
200
- <button class="ttt-diff-btn" data-diff="medium">Med</button>
201
- <button class="ttt-diff-btn active" data-diff="hard">Hard</button>
202
- </div>
203
- </div>
204
- <div class="ttt-status">Your turn (X)</div>
205
- <div class="ttt-board-wrap">
206
- <div class="ttt-grid"></div>
207
- </div>
208
- <div class="ttt-scores"></div>
209
- <div class="ttt-actions">
210
- <button class="ttt-action-btn" data-action="restart">New Round</button>
211
- <button class="ttt-action-btn" data-action="reset">Reset Scores</button>
212
- </div>
213
- `;
214
-
215
- // ── Events ──
216
- root.querySelector('.ttt-grid').addEventListener('click', (e) => {
217
- const cell = e.target.closest('.ttt-cell');
218
- if (!cell) return;
219
- if (currentPlayer === 'O') return; // AI's turn
220
- makeMove(+cell.dataset.index);
221
- });
222
-
223
- root.querySelector('.ttt-diff-btns').addEventListener('click', (e) => {
224
- const btn = e.target.closest('.ttt-diff-btn');
225
- if (!btn) return;
226
- difficulty = btn.dataset.diff;
227
- root.querySelectorAll('.ttt-diff-btn').forEach(b => b.classList.toggle('active', b === btn));
228
- resetBoard();
229
- });
230
-
231
- root.querySelector('.ttt-actions').addEventListener('click', (e) => {
232
- const btn = e.target.closest('.ttt-action-btn');
233
- if (!btn) return;
234
- if (btn.dataset.action === 'restart') resetBoard();
235
- else if (btn.dataset.action === 'reset') resetScores();
236
- });
237
-
238
- render();
239
- return root;
240
- },
241
- });