elenalyse 0.0.0-stage → 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hakaisha1
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,169 @@
1
- # Temporary Holding Version
1
+ <div align="center">
2
+ <img src="assets/elenalyse.png" alt="Elenalyse Logo" width="600" style="background-color: transparent;" />
2
3
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
4
+ # Elenalyse
5
+
6
+ ### Multi-Modal CLI Developer Assistant & Persona Quartet
7
+ **Persona-driven code analysis, autonomous multi-step auditing, visual diff previews, and Japanese TTS audio cues.**
8
+
9
+ [![npm version](https://img.shields.io/npm/v/elenalyse.svg?style=flat-square)](https://www.npmjs.com/package/elenalyse)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE)
11
+ [![TypeScript: 5.0+](https://img.shields.io/badge/TypeScript-5.0+-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/)
12
+ [![Node.js: >=18](https://img.shields.io/badge/Node.js->=18-339933.svg?style=flat-square)](https://nodejs.org/)
13
+
14
+ </div>
15
+
16
+ ---
17
+
18
+ ## Overview
19
+
20
+ **Elenalyse** is an interactive, agentic developer assistant designed for the terminal. Built on top of the Vercel AI SDK, Elenalyse combines deep codebase auditing, multi-step autonomous tool execution, and visual diff previews with the distinct analytical strengths of the **Persona Quartet**.
21
+
22
+ Whether you need a relentless security audit from **RIN**, cold architecture refactoring from **REI**, enthusiastic feature ideation from **SORA**, or patient mentorship and synthesis from **ELI**, Elenalyse adapts to your workflow.
23
+
24
+ ---
25
+
26
+ ## Core Features in v1.0
27
+
28
+ * **The Persona Quartet & Isolated Memory Handoff**: Four archetypes (ELI, REI, SORA, RIN) with isolated conversation memories. Switching personas automatically preserves technical context without personality bleed.
29
+ * **Simultaneous Party Mode (`/party`)**: Orchestrates all four personas simultaneously under ELI's leadership. RIN, REI, and SORA inspect your codebase in parallel, and ELI synthesizes their findings into a prioritized, actionable roadmap.
30
+ * **Autonomous Multi-Step Analysis**: Analyzes, audits, and navigates large codebases across up to 25 autonomous steps with real-time status spinners and text-based tool call fallback.
31
+ * **Visual Unified Diff Preview**: Calculates line-level diffs and renders clean boxed previews (`+ green`, `- red`, `@@ hunk`) before any file write or edit is confirmed.
32
+ * **Developer Safety & Rollback (`/undo`)**: Automatic pre-modification snapshots allow instant reversal of any file write or edit via `/undo`.
33
+ * **Actionable Remediation (`/fix`)**: Formulates and executes targeted code fixes (`/fix blockers`, `/fix majors`, `/fix all`) based on prior audit findings.
34
+ * **Interactive Slash Autocomplete Dropdown**: Terminal dropdown popup with arrow-key navigation (`↑/↓`), multi-level sub-command drilldowns, Tab/Enter selection, and non-intrusive auto-dismissal.
35
+ * **Persistent In-Chat Settings (`/setting`)**: Configure memory context limits (`amnesia`, `default`, `focus`), maximum autonomous inspection steps, and voice toggle directly within the REPL.
36
+ * **Session Persistence (`/session`)**: Save, load, and list isolated conversation sessions stored in `~/.elenalyse/sessions/`.
37
+ * **Terminal Markdown & Syntax Highlighting**: Custom pure-TypeScript ANSI renderer for headers, bold/italic, inline code, and boxed code containers with syntax highlighting (TypeScript, Python, SQL, Diff, JSON, Shell).
38
+ * **Multi-Provider Resilience & Failover**: Built-in support for Google Gemini, OpenAI, OpenRouter, and Ollama with automatic rate-limit and server failover.
39
+ * **Expressive Japanese TTS Audio Cues**: Optional voice feedback powered by the local [VOICEVOX](https://voicevox.hiroshiba.jp/) engine.
40
+
41
+ ---
42
+
43
+ ## The Persona Quartet
44
+
45
+ | Persona | Archetype | Tone & Personality | Analytical Focus |
46
+ | :--- | :--- | :--- | :--- |
47
+ | **ELI** | **Warm Mentor** | Friendly, patient, empathetic, supportive | Onboarding, architecture explanation, ELI5 breakdowns, Party leader |
48
+ | **REI** | **Kuudere** | Cold, concise, highly efficient, objective | Code refactoring, performance optimization, structural complexity |
49
+ | **SORA** | **Deredere** | Cheerful, energetic, creative, inspiring | Brainstorming, user experience, developer delight, new features |
50
+ | **RIN** | **Tsundere** | Strict, merciless, sharp-tongued, thorough | Security auditing, bug detection, input validation, critical blockers |
51
+
52
+ ---
53
+
54
+ ## Installation
55
+
56
+ Install Elenalyse globally using npm:
57
+
58
+ ```bash
59
+ npm install -g elenalyse
60
+ ```
61
+
62
+ Or run directly using `npx`:
63
+
64
+ ```bash
65
+ npx elenalyse start
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Quick Start
71
+
72
+ ### 1. Interactive REPL Mode (Recommended)
73
+
74
+ Launch the interactive chat loop with rich dashboard banners and slash autocomplete:
75
+
76
+ ```bash
77
+ elenalyse start
78
+ ```
79
+
80
+ #### Launch Flags:
81
+ * `elenalyse start --voice` : Enable local VOICEVOX Japanese speech synthesis.
82
+ * `elenalyse start --amnesia` : Restrict conversation memory to 10 messages (for low-token models).
83
+ * `elenalyse start --focus` : Expand conversation memory to 100 messages (for extended context).
84
+ * `elenalyse start --debug` : Display token usage and memory dump logs.
85
+
86
+ Inside the chat, save your provider API keys permanently:
87
+ ```text
88
+ 👤 You ❯ /api google <YOUR_API_KEY>
89
+ 👤 You ❯ /api openrouter <YOUR_API_KEY>
90
+ 👤 You ❯ /api openai <YOUR_API_KEY>
91
+ ```
92
+
93
+ ### 2. Single Message Usage
94
+
95
+ Execute quick, one-off tasks from your shell or CI/CD pipelines:
96
+
97
+ ```bash
98
+ # Analyze a bug or ask a quick question
99
+ elenalyse chat "Inspect src/index.ts and check for unhandled exceptions"
100
+
101
+ # Switch global active persona
102
+ elenalyse persona set rei
103
+ ```
104
+
105
+ ---
106
+
107
+ ## In-Chat Slash Commands Reference
108
+
109
+ | Command | Syntax | Description |
110
+ | :--- | :--- | :--- |
111
+ | **`/help`** | `/help` | Show command menu, shortcuts, and usage guide |
112
+ | **`/persona`** | `/persona <eli\|rei\|sora\|rin>` | Switch active persona with automatic technical context handoff |
113
+ | **`/party`** | `/party [audit\|review\|brainstorm\|<task>]` | Orchestrate all 4 personas simultaneously under ELI's coordination |
114
+ | **`/fix`** | `/fix [blockers\|majors\|all\|<issue>]` | Automatically generate and execute code fixes for audit findings |
115
+ | **`/setting`** | `/setting [show\|memory\|steps\|voice] [value]` | Configure runtime settings (memory limits, autonomous steps, voice) |
116
+ | **`/undo`** | `/undo` | Revert the last file modification made by Elenalyse |
117
+ | **`/session`** | `/session <save\|load\|list> [name]` | Save, load, or list persistent conversation sessions |
118
+ | **`/provider`** | `/provider <name\|fallback>` | Switch AI provider (`google`, `openai`, `openrouter`, `local`) |
119
+ | **`/model`** | `/model <model-slug>` | Change the active model (e.g. `gemini-2.5-flash`, `gpt-4o`) |
120
+ | **`/api`** | `/api <provider> <key>` | Save API key permanently to `~/.elenalyserc.json` |
121
+ | **`/paste`** | `/paste` | Enter multi-line paste mode (type `END` to submit) |
122
+ | **`/retry`** | `/retry` | Retry the previous prompt with pristine turn memory |
123
+ | **`/clear`** | `/clear` | Clear terminal screen and re-display the dashboard banner |
124
+ | **`/exit`** | `/exit` | Exit the interactive session safely |
125
+
126
+ ---
127
+
128
+ ## Voice Engine & Attribution
129
+
130
+ Elenalyse supports local Japanese speech synthesis using the **[VOICEVOX](https://voicevox.hiroshiba.jp/)** engine.
131
+
132
+ ### Setting Up VOICEVOX:
133
+ 1. Download and install the [VOICEVOX Official Editor](https://voicevox.hiroshiba.jp/).
134
+ 2. Launch the application; Elenalyse connects to the local engine on port `50021`.
135
+ 3. Start the chat with `elenalyse start --voice` (or toggle with `/setting voice on`).
136
+
137
+ ### Mandatory Voice Attribution:
138
+ When recording, streaming, or publishing audio produced by Elenalyse, you must credit the VOICEVOX characters used in accordance with their terms of service:
139
+ * **VOICEVOX: 四国めたん** (Shikoku Metan - ELI)
140
+ * **VOICEVOX: 春日部つむぎ** (Kasukabe Tsumugi - REI)
141
+ * **VOICEVOX: No.7** (SORA)
142
+ * **VOICEVOX: ずんだもん** (Zundamon - RIN)
143
+
144
+ Please review the [VOICEVOX Terms of Use](https://voicevox.hiroshiba.jp/term/) before sharing audio publicly.
145
+
146
+ ---
147
+
148
+ ## Upcoming in v1.1+ (Roadmap)
149
+
150
+ Version 1.0 focuses on delivering a hardened, rock-solid, developer-first terminal core. The following graphical extensions are actively developed and slated for upcoming releases:
151
+
152
+ * **3D Live Desktop Mascot (`elenalyse live`)**: A transparent, borderless desktop overlay powered by Tauri + Three.js displaying an expressive 3D VRM persona hovering alongside your IDE with real-time lip-sync audio cues.
153
+ * **Repository 3D Graph Visualization (`elenalyse viz`)**: An interactive 3D force-directed module graph visualizing file imports, dependencies, and architectural coupling directly in your browser.
154
+
155
+ ---
156
+
157
+ ## Tech Stack
158
+
159
+ * **CLI Core**: Node.js, TypeScript, Commander, Chalk, Ora.
160
+ * **Agentic Engine**: Vercel AI SDK (`ai`), Zod.
161
+ * **Terminal UI**: Custom ANSI parser, TTY Raw Mode prompt engine, box-drawing renderers.
162
+ * **TTS Engine**: VOICEVOX Engine (Local REST API), Sound-Play.
163
+ * **Testing**: Vitest (175+ tests).
164
+
165
+ ---
166
+
167
+ ## License
168
+
169
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "../dist/index.js";
package/dist/bridge.js ADDED
@@ -0,0 +1,116 @@
1
+ import http from "http";
2
+ export const BRIDGE_PORT = 39420;
3
+ let server = null;
4
+ const clients = new Set();
5
+ let heartbeatTimer = null;
6
+ export function hasConnectedClients() {
7
+ return clients.size > 0;
8
+ }
9
+ export function broadcastSpeakEvent(payload) {
10
+ if (clients.size === 0)
11
+ return;
12
+ const message = `event: speak\ndata: ${JSON.stringify(payload)}\n\n`;
13
+ for (const client of clients) {
14
+ try {
15
+ client.write(message);
16
+ }
17
+ catch {
18
+ clients.delete(client);
19
+ }
20
+ }
21
+ }
22
+ export function broadcastPersonaEvent(persona) {
23
+ if (clients.size === 0)
24
+ return;
25
+ const message = `event: persona\ndata: ${JSON.stringify({ persona })}\n\n`;
26
+ for (const client of clients) {
27
+ try {
28
+ client.write(message);
29
+ }
30
+ catch {
31
+ clients.delete(client);
32
+ }
33
+ }
34
+ }
35
+ export function startBridgeServer(port = BRIDGE_PORT) {
36
+ if (server)
37
+ return Promise.resolve(true);
38
+ return new Promise((resolve) => {
39
+ server = http.createServer((req, res) => {
40
+ // Set permissive CORS headers for Desktop Webview
41
+ res.setHeader("Access-Control-Allow-Origin", "*");
42
+ res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
43
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
44
+ if (req.method === "OPTIONS") {
45
+ res.writeHead(204);
46
+ res.end();
47
+ return;
48
+ }
49
+ if (req.url === "/health") {
50
+ res.writeHead(200, { "Content-Type": "application/json" });
51
+ res.end(JSON.stringify({ status: "ok", connectedClients: clients.size }));
52
+ return;
53
+ }
54
+ if (req.url === "/events") {
55
+ res.writeHead(200, {
56
+ "Content-Type": "text/event-stream",
57
+ "Cache-Control": "no-cache, no-transform",
58
+ Connection: "keep-alive",
59
+ });
60
+ // Kirim initial connection handshake
61
+ res.write(`event: connected\ndata: ${JSON.stringify({ connectedClients: clients.size + 1 })}\n\n`);
62
+ clients.add(res);
63
+ req.on("close", () => {
64
+ clients.delete(res);
65
+ });
66
+ return;
67
+ }
68
+ res.writeHead(404, { "Content-Type": "text/plain" });
69
+ res.end("Not Found");
70
+ });
71
+ server.on("error", (err) => {
72
+ if (err.code === "EADDRINUSE") {
73
+ // Port sudah dipakai oleh sesi CLI lain, abaikan agar tidak crash
74
+ server = null;
75
+ resolve(false);
76
+ }
77
+ else {
78
+ console.error("[Bridge Error]", err.message);
79
+ resolve(false);
80
+ }
81
+ });
82
+ server.listen(port, "127.0.0.1", () => {
83
+ // Heartbeat ping setiap 15 detik agar koneksi SSE tidak timeout
84
+ heartbeatTimer = setInterval(() => {
85
+ if (clients.size > 0) {
86
+ for (const client of clients) {
87
+ try {
88
+ client.write(`: ping\n\n`);
89
+ }
90
+ catch {
91
+ clients.delete(client);
92
+ }
93
+ }
94
+ }
95
+ }, 15000);
96
+ resolve(true);
97
+ });
98
+ });
99
+ }
100
+ export function stopBridgeServer() {
101
+ if (heartbeatTimer) {
102
+ clearInterval(heartbeatTimer);
103
+ heartbeatTimer = null;
104
+ }
105
+ for (const client of clients) {
106
+ try {
107
+ client.end();
108
+ }
109
+ catch { }
110
+ }
111
+ clients.clear();
112
+ if (server) {
113
+ server.close();
114
+ server = null;
115
+ }
116
+ }