@whykusanagi/corrupted-theme 0.1.8 → 0.1.9

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.
@@ -1,26 +1,65 @@
1
1
  /**
2
2
  * Corrupted Text Animation
3
- * Cycles through Japanese (hiragana/katakana/kanji), romaji, and English text
4
- *
5
- * Usage:
6
- * <span class="corrupted-multilang"
7
- * data-english="Hello"
8
- * data-romaji="konnichiwa"
9
- * data-hiragana="こんにちは"
10
- * data-katakana="コンニチハ"
3
+ *
4
+ * Cycles through Japanese (hiragana/katakana/kanji), romaji, and English text variants
5
+ * with character-level corruption effects. The text progressively corrupts from one
6
+ * variant to another, creating a glitchy Matrix-style transformation effect.
7
+ *
8
+ * @class CorruptedText
9
+ * @version 1.0.0
10
+ * @author whykusanagi
11
+ * @license MIT
12
+ *
13
+ * @example Basic Usage (Auto-initialization via data attributes)
14
+ * ```html
15
+ * <span class="corrupted-multilang"
16
+ * data-english="Hello World"
17
+ * data-romaji="konnichiwa"
18
+ * data-hiragana="こんにちは"
19
+ * data-katakana="コンニチハ"
11
20
  * data-kanji="今日は">
12
21
  * </span>
22
+ * ```
23
+ *
24
+ * @example Manual Initialization
25
+ * ```javascript
26
+ * const element = document.querySelector('.my-text');
27
+ * const corrupted = new CorruptedText(element, {
28
+ * duration: 3000,
29
+ * cycleDelay: 100,
30
+ * loop: true
31
+ * });
32
+ *
33
+ * // Control playback
34
+ * corrupted.start();
35
+ * corrupted.stop();
36
+ * corrupted.restart();
37
+ * corrupted.settle('Final Text');
38
+ * ```
39
+ *
40
+ * @see https://github.com/whykusanagi/corrupted-theme
41
+ * @see CORRUPTED_THEME_SPEC.md - Character-by-Character Decoding pattern
13
42
  */
14
-
15
43
  class CorruptedText {
44
+ /**
45
+ * Creates a new CorruptedText animation instance
46
+ *
47
+ * @param {HTMLElement} element - The DOM element to animate
48
+ * @param {Object} [options={}] - Configuration options
49
+ * @param {number} [options.duration=3000] - Total animation duration in milliseconds
50
+ * @param {number} [options.cycleDelay=100] - Delay between character corruption steps (ms)
51
+ * @param {number} [options.startDelay=0] - Initial delay before animation starts (ms)
52
+ * @param {boolean} [options.loop=true] - Whether to loop through variants continuously
53
+ * @param {string|null} [options.finalText=null] - Text to settle on after cycle (if loop=false)
54
+ */
16
55
  constructor(element, options = {}) {
17
56
  this.element = element;
18
57
  this.options = {
19
- duration: options.duration || 3000, // Total animation duration
20
- cycleDelay: options.cycleDelay || 100, // Delay between character changes
21
- startDelay: options.startDelay || 0, // Initial delay before starting
22
- loop: options.loop !== false, // Whether to loop
23
- finalText: options.finalText || null, // Final text to settle on (null = loop)
58
+ duration: options.duration || 3000,
59
+ cycleDelay: options.cycleDelay || 100,
60
+ startDelay: options.startDelay || 0,
61
+ loop: options.loop !== false,
62
+ finalText: options.finalText || null,
24
63
  ...options
25
64
  };
26
65
 
@@ -33,13 +72,13 @@ class CorruptedText {
33
72
  kanji: this.element.dataset.kanji || null
34
73
  };
35
74
 
36
- // Filter out null variants
75
+ // Filter out null variants and create array of available variants
37
76
  this.availableVariants = Object.entries(this.variants)
38
77
  .filter(([_, value]) => value !== null)
39
78
  .map(([key, value]) => ({ type: key, text: value }));
40
79
 
41
80
  if (this.availableVariants.length === 0) {
42
- console.warn('CorruptedText: No text variants found');
81
+ console.warn('CorruptedText: No text variants found for element', element);
43
82
  return;
44
83
  }
45
84
 
@@ -53,8 +92,12 @@ class CorruptedText {
53
92
  this.init();
54
93
  }
55
94
 
95
+ /**
96
+ * Initialize the corruption animation
97
+ * @private
98
+ */
56
99
  init() {
57
- // Add corrupted class if not present
100
+ // Add corrupted class for styling
58
101
  if (!this.element.classList.contains('corrupted-multilang')) {
59
102
  this.element.classList.add('corrupted-multilang');
60
103
  }
@@ -62,7 +105,7 @@ class CorruptedText {
62
105
  // Store original text
63
106
  this.originalText = this.element.textContent.trim();
64
107
 
65
- // Start animation after delay
108
+ // Start animation after configured delay
66
109
  if (this.options.startDelay > 0) {
67
110
  this._startDelayId = setTimeout(() => this.start(), this.options.startDelay);
68
111
  } else {
@@ -70,12 +113,20 @@ class CorruptedText {
70
113
  }
71
114
  }
72
115
 
116
+ /**
117
+ * Start the corruption animation
118
+ * @public
119
+ */
73
120
  start() {
74
121
  if (this.isAnimating) return;
75
122
  this.isAnimating = true;
76
123
  this.animate();
77
124
  }
78
125
 
126
+ /**
127
+ * Stop the corruption animation
128
+ * @public
129
+ */
79
130
  stop() {
80
131
  this.isAnimating = false;
81
132
  if (this.animationFrame) cancelAnimationFrame(this.animationFrame);
@@ -88,6 +139,10 @@ class CorruptedText {
88
139
  this._corruptTimeoutId = null;
89
140
  }
90
141
 
142
+ /**
143
+ * Fully tear down this instance: stop animation and release element reference.
144
+ * @public
145
+ */
91
146
  destroy() {
92
147
  this.stop();
93
148
  if (this.element && this.element.corruptedTextInstance === this) {
@@ -96,17 +151,21 @@ class CorruptedText {
96
151
  this.element = null;
97
152
  }
98
153
 
154
+ /**
155
+ * Main animation loop - cycles through text variants
156
+ * @private
157
+ */
99
158
  animate() {
100
159
  if (!this.isAnimating) return;
101
160
 
102
161
  const variant = this.availableVariants[this.currentVariantIndex];
103
162
  this.corruptToText(variant.text, () => {
104
- // Move to next variant
163
+ // Move to next variant in cycle
105
164
  this.currentVariantIndex = (this.currentVariantIndex + 1) % this.availableVariants.length;
106
165
 
107
- // Check if we should stop
166
+ // Check if animation should stop
108
167
  if (!this.options.loop && this.currentVariantIndex === 0) {
109
- // If we have a final text, use it, otherwise use original
168
+ // One full cycle complete - settle on final text
110
169
  const finalText = this.options.finalText || this.variants.english;
111
170
  this.corruptToText(finalText, () => {
112
171
  this.isAnimating = false;
@@ -114,7 +173,7 @@ class CorruptedText {
114
173
  return;
115
174
  }
116
175
 
117
- // Continue animation
176
+ // Continue animation to next variant
118
177
  this._animateTimeoutId = setTimeout(() => {
119
178
  if (this.isAnimating) {
120
179
  this.animate();
@@ -123,30 +182,41 @@ class CorruptedText {
123
182
  });
124
183
  }
125
184
 
185
+ /**
186
+ * Corrupt the current text to a target text with progressive reveal
187
+ *
188
+ * @param {string} targetText - The text to reveal through corruption
189
+ * @param {Function} callback - Called when corruption is complete
190
+ * @private
191
+ */
126
192
  corruptToText(targetText, callback) {
127
193
  const currentText = this.element.textContent.trim();
128
194
  const maxLength = Math.max(currentText.length, targetText.length);
129
- const steps = 20; // Number of corruption steps
195
+ const steps = 20; // Number of corruption animation steps
130
196
  let step = 0;
131
197
 
132
- // Character sets for corruption effect
133
- const corruptChars = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン0123456789!@#$%^&*()_+-=[]{}|;:,.<>?~`';
134
- const romajiChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
135
- const allCorruptChars = corruptChars + romajiChars + 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん';
198
+ // Character sets for corruption effect (from CORRUPTED_THEME_SPEC.md)
199
+ const katakana = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン';
200
+ const hiragana = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん';
201
+ const romaji = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
202
+ const symbols = '0123456789!@#$%^&*()_+-=[]{}|;:,.<>?~`';
203
+
204
+ // Combined corruption character set
205
+ const allCorruptChars = katakana + hiragana + romaji + symbols;
136
206
 
137
207
  const corrupt = () => {
138
208
  if (step >= steps) {
139
- // Set final text
209
+ // Animation complete - set final text
140
210
  this.element.textContent = targetText;
141
211
  if (callback) callback();
142
212
  return;
143
213
  }
144
214
 
145
- // Generate corrupted text
215
+ // Generate corrupted text with progressive reveal
146
216
  let corrupted = '';
147
217
  for (let i = 0; i < maxLength; i++) {
148
218
  if (i < targetText.length && step > steps * 0.7) {
149
- // Start revealing target text
219
+ // Last 30% of animation - start revealing target text
150
220
  const revealProgress = (step - steps * 0.7) / (steps * 0.3);
151
221
  if (Math.random() < revealProgress) {
152
222
  corrupted += targetText[i];
@@ -154,7 +224,7 @@ class CorruptedText {
154
224
  corrupted += allCorruptChars[Math.floor(Math.random() * allCorruptChars.length)];
155
225
  }
156
226
  } else {
157
- // Random corruption
227
+ // First 70% - full random corruption
158
228
  corrupted += allCorruptChars[Math.floor(Math.random() * allCorruptChars.length)];
159
229
  }
160
230
  }
@@ -162,6 +232,7 @@ class CorruptedText {
162
232
  this.element.textContent = corrupted;
163
233
  step++;
164
234
 
235
+ // Schedule next corruption step
165
236
  this.animationFrame = requestAnimationFrame(() => {
166
237
  this._corruptTimeoutId = setTimeout(corrupt, this.options.cycleDelay);
167
238
  });
@@ -170,14 +241,22 @@ class CorruptedText {
170
241
  corrupt();
171
242
  }
172
243
 
173
- // Public method to restart animation
244
+ /**
245
+ * Restart the animation from the beginning
246
+ * @public
247
+ */
174
248
  restart() {
175
249
  this.stop();
176
250
  this.currentVariantIndex = 0;
177
251
  this.start();
178
252
  }
179
253
 
180
- // Public method to set final text and stop
254
+ /**
255
+ * Stop animation and settle on a specific text
256
+ *
257
+ * @param {string} [finalText] - Text to settle on (defaults to english variant)
258
+ * @public
259
+ */
181
260
  settle(finalText) {
182
261
  this.stop();
183
262
  this.corruptToText(finalText || this.variants.english, () => {
@@ -186,7 +265,14 @@ class CorruptedText {
186
265
  }
187
266
  }
188
267
 
189
- // Auto-initialize elements with corrupted-multilang class
268
+ /**
269
+ * Auto-initialize all elements with the 'corrupted-multilang' class
270
+ *
271
+ * This function is automatically called on DOM ready and can be called
272
+ * manually to initialize dynamically added elements.
273
+ *
274
+ * @public
275
+ */
190
276
  function initCorruptedText() {
191
277
  document.querySelectorAll('.corrupted-multilang').forEach(element => {
192
278
  if (!element.corruptedTextInstance) {
@@ -195,15 +281,20 @@ function initCorruptedText() {
195
281
  });
196
282
  }
197
283
 
198
- // Initialize on DOM ready
284
+ // Auto-initialize on DOM ready
199
285
  if (document.readyState === 'loading') {
200
286
  document.addEventListener('DOMContentLoaded', initCorruptedText);
201
287
  } else {
202
288
  initCorruptedText();
203
289
  }
204
290
 
205
- // Export for manual use
291
+ // Export for both ES6 modules and CommonJS
206
292
  if (typeof module !== 'undefined' && module.exports) {
207
293
  module.exports = { CorruptedText, initCorruptedText };
208
294
  }
209
295
 
296
+ // Export for ES6 modules
297
+ if (typeof exports !== 'undefined') {
298
+ exports.CorruptedText = CorruptedText;
299
+ exports.initCorruptedText = initCorruptedText;
300
+ }
package/docs/ROADMAP.md DELETED
@@ -1,266 +0,0 @@
1
- # CelesteCLI Roadmap
2
-
3
- This document tracks planned features, enhancements, and potential migrations for CelesteCLI.
4
-
5
- ## Current Status (December 2025)
6
-
7
- ### ✅ Completed
8
- - Enterprise-grade RPG menu system with contextual help
9
- - 18 AI-powered skills via function calling
10
- - Multi-provider support (OpenAI, Grok, Venice, Anthropic, OpenRouter, DigitalOcean)
11
- - Vertex AI support via OpenAI-compatible endpoint
12
- - Session persistence and auto-save
13
- - NSFW mode with Venice.ai image generation
14
- - Context-aware /safe command
15
- - Tool result filtering (hide raw JSON from UI)
16
-
17
- ---
18
-
19
- ## Short-Term (Q1 2025)
20
-
21
- ### High Priority
22
-
23
- #### 1. Vertex AI (Google Cloud) Setup Guide
24
- - **Status**: Requires complex Google Cloud configuration
25
- - **Goal**: Document complete Vertex AI setup for enterprise users
26
- - **Provider Clarification**:
27
- - **Gemini AI (AI Studio)**: Simple API keys ✅ READY
28
- - **Vertex AI (Google Cloud)**: OAuth2 tokens, requires setup ⚠️ ENTERPRISE ONLY
29
-
30
- **Vertex AI Requirements:**
31
- 1. **Google Cloud Project**: Active GCP project with billing enabled
32
- 2. **Vertex AI API**: Enable Vertex AI API in GCP console
33
- 3. **Service Account**: Create service account with `Vertex AI User` role
34
- 4. **Authentication**: Use OAuth2 tokens (NOT simple API keys)
35
- 5. **Token Management**: Tokens expire after 1 hour, need refresh mechanism
36
-
37
- **Endpoint URL Format:**
38
- ```
39
- https://aiplatform.googleapis.com/v1/projects/{PROJECT_ID}/locations/{LOCATION}/endpoints/openapi
40
- ```
41
-
42
- **Configuration Example:**
43
- ```json
44
- {
45
- "api_key": "ya29.c.c0ASRK0Ga...", // OAuth2 access token
46
- "base_url": "https://aiplatform.googleapis.com/v1/projects/my-project/locations/us-central1/endpoints/openapi",
47
- "model": "gemini-2.0-flash",
48
- "timeout": 60
49
- }
50
- ```
51
-
52
- **Token Generation (Go example):**
53
- ```go
54
- import "golang.org/x/oauth2/google"
55
-
56
- creds, _ := google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/cloud-platform")
57
- token, _ := creds.TokenSource.Token()
58
- config.APIKey = token.AccessToken
59
- ```
60
-
61
- **Why Most Users Should Use Gemini Instead:**
62
- - Gemini AI: Simple API key from https://aistudio.google.com/apikey
63
- - Vertex AI: Requires GCP project, billing, OAuth2 setup
64
- - Both use same Gemini models, same function calling capabilities
65
- - Vertex AI is for enterprise users with existing GCP infrastructure
66
-
67
- - **Decision**: Gemini AI is the recommended provider for most users
68
-
69
- #### 2. Improve Error Messaging
70
- - **Goal**: Better error messages for common issues
71
- - **Tasks**:
72
- - [ ] API key validation on startup
73
- - [ ] Clear messages for unsupported model features
74
- - [ ] Network timeout handling with retry suggestions
75
- - [ ] Configuration validation with fix suggestions
76
-
77
- #### 3. Performance Optimization
78
- - **Goal**: Reduce latency and improve responsiveness
79
- - **Tasks**:
80
- - [ ] Stream parsing optimization
81
- - [ ] Reduce re-renders in TUI
82
- - [ ] Cache provider model lists
83
- - [ ] Lazy-load skill definitions
84
-
85
- ### Medium Priority
86
-
87
- #### 4. Enhanced Skill Management
88
- - **Goal**: Better skill discovery and usage
89
- - **Tasks**:
90
- - [ ] /skills menu shows skill descriptions on hover/selection
91
- - [ ] Skill usage examples in help text
92
- - [ ] Skill execution history (recent skills used)
93
- - [ ] Skill favorites/pinning
94
-
95
- #### 5. Configuration Management
96
- - **Goal**: Easier config switching and management
97
- - **Tasks**:
98
- - [ ] /config list shows model details and capabilities
99
- - [ ] /config test <profile> - test API connectivity
100
- - [ ] Config templates for common providers
101
- - [ ] Import/export config profiles
102
-
103
- ---
104
-
105
- ## Medium-Term (Q2-Q3 2025)
106
-
107
- ### Research & Evaluation
108
-
109
- #### 6. Native Vertex AI SDK Migration (Option B)
110
- - **Status**: Documented as potential enhancement
111
- - **Trigger**: If Google deprecates OpenAI-compatible endpoint OR performance benefits are significant
112
- - **Complexity**: MEDIUM (8-12 hours estimated)
113
- - **Impact**: Better long-term stability, native Gemini features
114
-
115
- **Migration Plan**:
116
-
117
- ##### Phase 1: Research & Prototyping (2-3 hours)
118
- - [ ] Set up native genai SDK in test branch
119
- - [ ] Prototype skill definition conversion (JSON → genai.FunctionDeclaration)
120
- - [ ] Test response parsing (functionCall vs tool_calls)
121
- - [ ] Benchmark performance vs OpenAI-compatible endpoint
122
-
123
- ##### Phase 2: Abstraction Layer (3-4 hours)
124
- - [ ] Create provider abstraction interface
125
- - [ ] Implement OpenAI provider adapter
126
- - [ ] Implement native Gemini provider adapter
127
- - [ ] Unified response format converter
128
-
129
- ##### Phase 3: Testing & Validation (2-3 hours)
130
- - [ ] Test all 18 skills with native SDK
131
- - [ ] Validate function calling accuracy
132
- - [ ] Test multi-turn conversations
133
- - [ ] Compare performance metrics
134
-
135
- ##### Phase 4: Migration (1-2 hours)
136
- - [ ] Switch default Vertex AI provider to native SDK
137
- - [ ] Update documentation
138
- - [ ] Deprecation notice for OpenAI-compatible endpoint
139
-
140
- **Code Structure Example**:
141
- ```go
142
- // Future architecture with provider abstraction
143
-
144
- type Provider interface {
145
- SendMessage(ctx context.Context, messages []Message, tools []Tool) (*Response, error)
146
- SupportsFunctionCalling() bool
147
- ConvertSkillDefinition(skill SkillDefinition) interface{}
148
- }
149
-
150
- type OpenAIProvider struct {
151
- client *openai.Client
152
- }
153
-
154
- type GeminiProvider struct {
155
- client *genai.Client
156
- }
157
-
158
- // Skills remain unchanged - adapters handle conversion
159
- ```
160
-
161
- **Decision Criteria**:
162
- - Google announces deprecation of OpenAI endpoint → Migrate immediately
163
- - Native SDK shows >20% performance improvement → Evaluate migration
164
- - Native SDK enables exclusive features → Evaluate value vs effort
165
- - Community reports OpenAI endpoint issues → Migrate proactively
166
-
167
- **Resources**:
168
- - [Google GenAI SDK Docs](https://pkg.go.dev/google.golang.org/genai)
169
- - [Function Calling Guide](https://ai.google.dev/gemini-api/docs/function-calling)
170
- - [Migration Guide](https://ai.google.dev/gemini-api/docs/migrate)
171
-
172
- ---
173
-
174
- ### Feature Enhancements
175
-
176
- #### 7. Advanced Skill Features
177
- - **Goal**: More powerful AI capabilities
178
- - **Tasks**:
179
- - [ ] Parallel skill execution (when LLM calls multiple)
180
- - [ ] Skill chaining (output of one feeds another)
181
- - [ ] Custom user-defined skills (plugin system)
182
- - [ ] Skill templates and generators
183
-
184
- #### 8. Conversation Management
185
- - **Goal**: Better session handling
186
- - **Tasks**:
187
- - [ ] Named sessions (save/load by name)
188
- - [ ] Session search (find past conversations)
189
- - [ ] Session export (markdown, JSON)
190
- - [ ] Session branching (fork conversation)
191
-
192
- #### 9. Multi-Modal Support
193
- - **Goal**: Beyond text interactions
194
- - **Tasks**:
195
- - [ ] Image input support (upload images for analysis)
196
- - [ ] File attachment support
197
- - [ ] Voice input/output (ElevenLabs integration)
198
- - [ ] PDF parsing and analysis
199
-
200
- ---
201
-
202
- ## Long-Term (Q4 2025+)
203
-
204
- ### Major Features
205
-
206
- #### 10. Team/Collaboration Features
207
- - **Goal**: Multi-user support
208
- - **Tasks**:
209
- - [ ] Shared sessions
210
- - [ ] Team workspaces
211
- - [ ] Permission management
212
- - [ ] Audit logs
213
-
214
- #### 11. Cloud Sync
215
- - **Goal**: Cross-device session sync
216
- - **Tasks**:
217
- - [ ] Optional cloud backup
218
- - [ ] Encrypted session storage
219
- - [ ] Device sync
220
- - [ ] Web UI companion
221
-
222
- #### 12. Advanced Analytics
223
- - **Goal**: Usage insights
224
- - **Tasks**:
225
- - [ ] Token usage tracking
226
- - [ ] Cost estimation per provider
227
- - [ ] Skill usage analytics
228
- - [ ] Performance metrics dashboard
229
-
230
- ---
231
-
232
- ## Deprecated/Archived
233
-
234
- ### Considered but Deferred
235
- - **Local LLM support**: Complexity vs benefit ratio too high for v1
236
- - **Browser extension**: Scope too large, focus on CLI first
237
- - **Mobile app**: Desktop/terminal focus more valuable
238
-
239
- ---
240
-
241
- ## Contributing to Roadmap
242
-
243
- This roadmap is living document. To propose additions:
244
-
245
- 1. Check existing items to avoid duplicates
246
- 2. Open GitHub issue with `[Roadmap]` prefix
247
- 3. Describe:
248
- - Use case and problem being solved
249
- - Estimated complexity (LOW/MEDIUM/HIGH)
250
- - Impact on existing features
251
- - User benefit
252
-
253
- Priority is determined by:
254
- - User requests and feedback
255
- - Technical dependencies
256
- - Maintenance burden
257
- - Strategic value
258
-
259
- ---
260
-
261
- ## Version History
262
-
263
- - **v0.1** (Dec 2025): Initial roadmap creation
264
- - Enterprise menu system complete
265
- - Vertex AI OpenAI-compatible endpoint implemented
266
- - Native SDK migration documented as Option B