@whykusanagi/corrupted-theme 0.1.7 → 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.
@@ -0,0 +1,329 @@
1
+ // src/lib/corrupted-vortex.js
2
+ // CorruptedVortex — WebGL1 raymarched spiral-vortex component
3
+ // Part of @whykusanagi/corrupted-theme
4
+
5
+ const VERT_SRC = `
6
+ attribute vec2 aPosition;
7
+ void main() {
8
+ gl_Position = vec4(aPosition, 0.0, 1.0);
9
+ }
10
+ `;
11
+
12
+ const FRAG_SRC = `
13
+ precision highp float;
14
+
15
+ uniform vec2 uResolution;
16
+ uniform float uTime;
17
+ uniform float uIntensity;
18
+ uniform float uRotationRate;
19
+ uniform float uHue;
20
+
21
+ vec3 hsv(float h, float s, float v) {
22
+ vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);
23
+ vec3 p = abs(fract(vec3(h) + K.xyz) * 6.0 - K.www);
24
+ return v * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), s);
25
+ }
26
+
27
+ mat2 rotate2D(float a) {
28
+ float c = cos(a), s = sin(a);
29
+ return mat2(c, -s, s, c);
30
+ }
31
+
32
+ // Continuous 3-D accretion disk viewed at ~60° inclination, major axis 45° CW.
33
+ // Perpendicular-distance-to-radial-ray trick gives analytic nearest orbit:
34
+ // phi = atan((sx+sy)/B, sx-sy) [orbital angle, r-invariant]
35
+ // K = 0.7071*(cos φ+B·sin φ, -cos φ+B·sin φ) [radial direction on ellipse]
36
+ // r0 = dot(uv, K) / dot(K,K) [nearest orbital radius]
37
+ // dr = length(uv - r0·K) [perpendicular disk offset]
38
+ vec3 diskSample(vec2 uv) {
39
+ float B = 0.15; // near edge-on (~9° from edge) → Saturn-like flat stripe
40
+ float phi = atan((uv.x + uv.y) / B, uv.x - uv.y);
41
+ vec2 K = vec2(0.7071 * (cos(phi) + B * sin(phi)),
42
+ 0.7071 * (-cos(phi) + B * sin(phi)));
43
+ float r0 = dot(uv, K) / dot(K, K);
44
+ float dr = length(uv - r0 * K);
45
+
46
+ // Radial extent: inner edge near photon sphere, outer at 0.65
47
+ float radial = smoothstep(0.185, 0.235, r0) * smoothstep(0.65, 0.50, r0);
48
+
49
+ // Disk height (thin, crisp; spaghettifies near horizon)
50
+ float fall = smoothstep(0.30, 0.19, length(uv));
51
+ float sigma = (0.012 + r0 * 0.022) * max(0.07, 1.0 - fall * 0.93);
52
+ float height = exp(-pow(dr / sigma, 2.0));
53
+
54
+ // Gas-flow striations along orbital direction
55
+ float fiber = 0.62 + 0.38 * abs(sin(phi * 18.0 + r0 * 22.0 - uTime * 0.25));
56
+
57
+ // Doppler: approaching half (sin φ > 0) → brighter
58
+ float dop = 0.30 + 1.40 * max(0.0, sin(phi));
59
+
60
+ // Color: inner cream-white → gold → dark orange outer
61
+ float t = clamp((r0 - 0.18) / (0.62 - 0.18), 0.0, 1.0);
62
+ vec3 col;
63
+ if (t < 0.25) {
64
+ col = mix(vec3(1.00, 0.97, 0.85), vec3(1.00, 0.72, 0.18), t / 0.25);
65
+ } else {
66
+ col = mix(vec3(1.00, 0.72, 0.18), vec3(0.38, 0.12, 0.01), (t - 0.25) / 0.75);
67
+ }
68
+
69
+ // Tidal brightening near inner edge (kept subtle to avoid drowning the corona)
70
+ float innerBoost = 1.0 + 0.5 * exp(-pow((r0 - 0.21) / 0.10, 2.0));
71
+
72
+ return col * (height * radial * fiber * dop * innerBoost);
73
+ }
74
+
75
+ void main() {
76
+ vec4 o = vec4(0.0);
77
+ float e = 0.0, R = 0.0;
78
+ vec3 q = vec3(0.0), p = vec3(0.0);
79
+ vec3 d = vec3((gl_FragCoord.xy - 0.5 * uResolution) / uResolution.y, 0.7);
80
+ q.z -= 1.0;
81
+
82
+ for (float i = 0.0; i < 33.0; i += 1.0) {
83
+ // Corrupted-theme quasar palette:
84
+ // 0–25% early iters (dim) → magenta outer glow [0.83–0.88]
85
+ // 25–70% mid iters → purple body [0.65–0.74]
86
+ // 70–85% bright inner iters → magenta burst [0.82–0.88]
87
+ // 85–100% late iters (high e)→ gold/yellow sparks [0.14–0.19]
88
+ float t = fract(i / 33.0);
89
+ float base;
90
+ if (t < 0.25) {
91
+ base = mix(0.83, 0.88, t / 0.25);
92
+ } else if (t < 0.70) {
93
+ base = mix(0.65, 0.74, (t - 0.25) / 0.45);
94
+ } else if (t < 0.85) {
95
+ base = mix(0.82, 0.88, (t - 0.70) / 0.15);
96
+ } else {
97
+ base = mix(0.14, 0.19, (t - 0.85) / 0.15);
98
+ }
99
+ float h = (uHue >= 0.0) ? uHue : base + p.y * 0.04;
100
+ o.rgb += hsv(h, clamp(e * 0.4, 0.0, 1.0), e / 30.0 * uIntensity);
101
+
102
+ p = q += d * max(e, 0.01) * R * 0.14;
103
+ p.xy *= rotate2D(0.8 * uRotationRate);
104
+
105
+ R = length(p);
106
+ float newPy = -p.z / R - 0.8;
107
+ e = newPy;
108
+ p = vec3(log2(R) + uTime, newPy, atan(p.x * 0.08, p.y) - uTime * 0.2);
109
+
110
+ float s = 1.0;
111
+ for (int si = 0; si < 10; si++) {
112
+ e += abs(dot(sin(p.yzx * s), cos(p.yyz * s))) / s;
113
+ s += s;
114
+ }
115
+ }
116
+
117
+ // Reinhard + contrast curve: compress sum then push dim areas toward black.
118
+ // pow(1.8) is softer than 2.2 — keeps the magenta/purple corona visible
119
+ // while still collapsing near-zero cloud artifacts to black.
120
+ o.rgb = o.rgb / (1.0 + o.rgb);
121
+ o.rgb = pow(o.rgb, vec3(1.8));
122
+
123
+ // Near/far depth split: project onto the 45° CW major axis direction (1,-1)/√2.
124
+ // majorProj > 0 → lower-right arm → near (passes in front of BH)
125
+ // majorProj < 0 → upper-left arm → far (passes behind BH)
126
+ float dist = length(d.xy);
127
+ float majorProj = dot(d.xy, vec2(0.7071, -0.7071));
128
+ float nearMask = smoothstep(-0.04, 0.04, majorProj);
129
+ vec3 diskVal = diskSample(d.xy) * 2.0 * uIntensity;
130
+
131
+ // Far arm: add before shadow; extra depth-fade darkens it near the BH centre
132
+ float farDepth = smoothstep(0.12, 0.26, dist);
133
+ o.rgb += diskVal * (1.0 - nearMask) * farDepth;
134
+
135
+ // Black-hole event horizon: shadows the vortex cloud (and the far arm)
136
+ float shadow = smoothstep(0.12, 0.18, dist);
137
+ float ring = exp(-pow((dist - 0.18) * 30.0, 2.0)) * 0.9;
138
+ o.rgb = o.rgb * shadow + vec3(ring, ring * 0.80, ring * 0.45);
139
+
140
+ // Near arm: add after shadow → visibly crosses in front of the event horizon
141
+ o.rgb += diskVal * nearMask;
142
+
143
+ // Lensed arc: thin bright stripe above the shadow boundary
144
+ float lensThe = atan(d.y, d.x);
145
+ float bend = exp(-(dist - 0.19) * 9.0);
146
+ float thetaS = lensThe + 3.14159 * bend;
147
+ vec2 uvLens = vec2(cos(thetaS), sin(thetaS)) * dist;
148
+ float lensFade = exp(-pow((dist - 0.22) * 16.0, 2.0))
149
+ * smoothstep(0.03, 0.08, d.y);
150
+ o.rgb += diskSample(uvLens) * lensFade * 0.5 * uIntensity;
151
+
152
+ // Magenta corona: tight photon-ring — width 50 gives ~0.033 FWHM, <4% bleed into shadow
153
+ float coronaAmt = exp(-pow((dist - 0.21) * 50.0, 2.0)) * 0.7;
154
+ o.rgb += vec3(coronaAmt, 0.0, coronaAmt) * uIntensity;
155
+
156
+ o.a = 1.0;
157
+ gl_FragColor = clamp(o, 0.0, 1.0);
158
+ }
159
+ `;
160
+
161
+ class CorruptedVortex {
162
+ constructor(canvas, options = {}) {
163
+ this.canvas = canvas;
164
+ this.options = {
165
+ speed: options.speed ?? 1.0,
166
+ intensity: options.intensity ?? 1.0,
167
+ rotationRate: options.rotationRate ?? 1.0,
168
+ hue: options.hue ?? null,
169
+ };
170
+
171
+ this.gl = null;
172
+ this.program = null;
173
+ this.uniforms = {};
174
+ this.buffer = null;
175
+ this._rafId = null;
176
+ this._isRunning = false;
177
+ this._elapsed = 0;
178
+ this._lastTs = null;
179
+ this._resizeObserver = null;
180
+ this._intersectionObserver = null;
181
+
182
+ this.init();
183
+ }
184
+
185
+ _compileShader(type, src) {
186
+ const gl = this.gl;
187
+ const shader = gl.createShader(type);
188
+ gl.shaderSource(shader, src);
189
+ gl.compileShader(shader);
190
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
191
+ console.warn('CorruptedVortex: shader compile failed\n', gl.getShaderInfoLog(shader));
192
+ gl.deleteShader(shader);
193
+ return null;
194
+ }
195
+ return shader;
196
+ }
197
+
198
+ init() {
199
+ const gl = this.canvas.getContext('webgl', { alpha: false });
200
+ if (!gl) {
201
+ console.warn('CorruptedVortex: WebGL not supported in this browser.');
202
+ return;
203
+ }
204
+ this.gl = gl;
205
+
206
+ const vs = this._compileShader(gl.VERTEX_SHADER, VERT_SRC);
207
+ const fs = this._compileShader(gl.FRAGMENT_SHADER, FRAG_SRC);
208
+ if (!vs || !fs) { this.destroy(); return; }
209
+
210
+ this.program = gl.createProgram();
211
+ gl.attachShader(this.program, vs);
212
+ gl.attachShader(this.program, fs);
213
+ gl.linkProgram(this.program);
214
+ gl.deleteShader(vs);
215
+ gl.deleteShader(fs);
216
+
217
+ if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
218
+ console.warn('CorruptedVortex: program link failed\n', gl.getProgramInfoLog(this.program));
219
+ this.destroy();
220
+ return;
221
+ }
222
+
223
+ gl.useProgram(this.program);
224
+
225
+ this.uniforms = {
226
+ resolution: gl.getUniformLocation(this.program, 'uResolution'),
227
+ time: gl.getUniformLocation(this.program, 'uTime'),
228
+ intensity: gl.getUniformLocation(this.program, 'uIntensity'),
229
+ rotationRate: gl.getUniformLocation(this.program, 'uRotationRate'),
230
+ hue: gl.getUniformLocation(this.program, 'uHue'),
231
+ };
232
+
233
+ // Fullscreen triangle — one triangle covers the full NDC square
234
+ this.buffer = gl.createBuffer();
235
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
236
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);
237
+
238
+ const posLoc = gl.getAttribLocation(this.program, 'aPosition');
239
+ gl.enableVertexAttribArray(posLoc);
240
+ gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);
241
+
242
+ this._resizeObserver = new ResizeObserver(() => this._resize());
243
+ this._resizeObserver.observe(this.canvas);
244
+
245
+ this._intersectionObserver = new IntersectionObserver(entries => {
246
+ if (entries[0].isIntersecting) {
247
+ this.start();
248
+ } else {
249
+ this.stop();
250
+ }
251
+ }, { threshold: 0.1 });
252
+ this._intersectionObserver.observe(this.canvas);
253
+
254
+ this._resize();
255
+ this.start();
256
+ }
257
+
258
+ _resize() {
259
+ const gl = this.gl;
260
+ if (!gl || !this.canvas) return;
261
+ const dpr = 0.5; // half-res: GPU renders fewer pixels, CSS scales up
262
+ const rect = this.canvas.getBoundingClientRect();
263
+ if (rect.width === 0 || rect.height === 0) return;
264
+ this.canvas.width = Math.round(rect.width * dpr);
265
+ this.canvas.height = Math.round(rect.height * dpr);
266
+ gl.viewport(0, 0, this.canvas.width, this.canvas.height);
267
+ }
268
+
269
+ _render(ts) {
270
+ if (!this._isRunning) return;
271
+
272
+ // Throttle to ~30fps to keep GPU load manageable
273
+ if (this._lastTs !== null && ts - this._lastTs < 33) {
274
+ this._rafId = requestAnimationFrame(ts => this._render(ts));
275
+ return;
276
+ }
277
+
278
+ if (this._lastTs !== null) {
279
+ this._elapsed += (ts - this._lastTs) / 1000.0;
280
+ }
281
+ this._lastTs = ts;
282
+
283
+ const gl = this.gl;
284
+ gl.useProgram(this.program);
285
+ gl.uniform2f(this.uniforms.resolution, this.canvas.width, this.canvas.height);
286
+ gl.uniform1f(this.uniforms.time, this._elapsed * this.options.speed);
287
+ gl.uniform1f(this.uniforms.intensity, this.options.intensity);
288
+ gl.uniform1f(this.uniforms.rotationRate, this.options.rotationRate);
289
+ gl.uniform1f(this.uniforms.hue, this.options.hue !== null ? this.options.hue : -1.0);
290
+
291
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
292
+
293
+ this._rafId = requestAnimationFrame(ts => this._render(ts));
294
+ }
295
+
296
+ start() {
297
+ if (this._isRunning || !this.gl) return;
298
+ this._isRunning = true;
299
+ this._lastTs = null;
300
+ this._rafId = requestAnimationFrame(ts => this._render(ts));
301
+ }
302
+
303
+ stop() {
304
+ this._isRunning = false;
305
+ this._lastTs = null;
306
+ if (this._rafId) {
307
+ cancelAnimationFrame(this._rafId);
308
+ this._rafId = null;
309
+ }
310
+ }
311
+
312
+ destroy() {
313
+ this.stop();
314
+ const gl = this.gl;
315
+ if (gl) {
316
+ if (this.program) gl.deleteProgram(this.program);
317
+ if (this.buffer) gl.deleteBuffer(this.buffer);
318
+ }
319
+ if (this._resizeObserver) { this._resizeObserver.disconnect(); this._resizeObserver = null; }
320
+ if (this._intersectionObserver) { this._intersectionObserver.disconnect(); this._intersectionObserver = null; }
321
+ this.gl = null;
322
+ this.canvas = null;
323
+ }
324
+ }
325
+
326
+ // Export for manual use / build pipelines
327
+ if (typeof module !== 'undefined' && module.exports) {
328
+ module.exports = { CorruptedVortex };
329
+ }
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