kentutai-app 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 (165) hide show
  1. package/.dockerignore +32 -0
  2. package/Dockerfile +52 -0
  3. package/LICENSE +21 -0
  4. package/README.md +1318 -0
  5. package/README.zh-CN.md +1311 -0
  6. package/captain-definition +4 -0
  7. package/check-connections.js +20 -0
  8. package/check-db.js +41 -0
  9. package/check-key.js +20 -0
  10. package/check-key2.js +21 -0
  11. package/check-mimo-conn.js +29 -0
  12. package/check-mimo.js +22 -0
  13. package/check-nodes.js +26 -0
  14. package/check-nodes2.js +29 -0
  15. package/check-providers.js +48 -0
  16. package/dev.log +15 -0
  17. package/next-env.d.ts +6 -0
  18. package/opencode.json +22 -0
  19. package/package.json +65 -0
  20. package/public/favicon.png +0 -0
  21. package/public/file.svg +1 -0
  22. package/public/globe.svg +1 -0
  23. package/public/i18n/literals/ar.json +194 -0
  24. package/public/i18n/literals/bn.json +194 -0
  25. package/public/i18n/literals/cs.json +194 -0
  26. package/public/i18n/literals/da.json +194 -0
  27. package/public/i18n/literals/de.json +194 -0
  28. package/public/i18n/literals/el.json +194 -0
  29. package/public/i18n/literals/es.json +194 -0
  30. package/public/i18n/literals/fi.json +194 -0
  31. package/public/i18n/literals/fr.json +194 -0
  32. package/public/i18n/literals/he.json +194 -0
  33. package/public/i18n/literals/hi.json +194 -0
  34. package/public/i18n/literals/hu.json +194 -0
  35. package/public/i18n/literals/id.json +194 -0
  36. package/public/i18n/literals/it.json +194 -0
  37. package/public/i18n/literals/ja.json +194 -0
  38. package/public/i18n/literals/ko.json +194 -0
  39. package/public/i18n/literals/nl.json +194 -0
  40. package/public/i18n/literals/no.json +194 -0
  41. package/public/i18n/literals/pl.json +194 -0
  42. package/public/i18n/literals/pt-BR.json +194 -0
  43. package/public/i18n/literals/pt-PT.json +194 -0
  44. package/public/i18n/literals/ro.json +194 -0
  45. package/public/i18n/literals/ru.json +194 -0
  46. package/public/i18n/literals/sv.json +194 -0
  47. package/public/i18n/literals/th.json +194 -0
  48. package/public/i18n/literals/tl.json +194 -0
  49. package/public/i18n/literals/tr.json +194 -0
  50. package/public/i18n/literals/uk.json +194 -0
  51. package/public/i18n/literals/ur.json +194 -0
  52. package/public/i18n/literals/vi.json +194 -0
  53. package/public/i18n/literals/zh-CN.json +768 -0
  54. package/public/i18n/literals/zh-TW.json +194 -0
  55. package/public/icon.ico +0 -0
  56. package/public/icons/icon-192.svg +4 -0
  57. package/public/icons/icon-512.svg +4 -0
  58. package/public/kentutai-icon.png +0 -0
  59. package/public/kentutai-logo.png +0 -0
  60. package/public/next.svg +1 -0
  61. package/public/providers/alicode-intl.png +0 -0
  62. package/public/providers/alicode.png +0 -0
  63. package/public/providers/amp.png +0 -0
  64. package/public/providers/anthropic-m.png +0 -0
  65. package/public/providers/anthropic.png +0 -0
  66. package/public/providers/antigravity.png +0 -0
  67. package/public/providers/assemblyai.png +0 -0
  68. package/public/providers/aws-polly.png +0 -0
  69. package/public/providers/azure.png +0 -0
  70. package/public/providers/black-forest-labs.png +0 -0
  71. package/public/providers/blackbox.png +0 -0
  72. package/public/providers/brave-search.png +0 -0
  73. package/public/providers/byteplus.png +0 -0
  74. package/public/providers/cartesia.png +0 -0
  75. package/public/providers/cerebras.png +0 -0
  76. package/public/providers/chutes.png +0 -0
  77. package/public/providers/claude.png +0 -0
  78. package/public/providers/cline.png +0 -0
  79. package/public/providers/cloudflare-ai.png +0 -0
  80. package/public/providers/codex.png +0 -0
  81. package/public/providers/cohere.png +0 -0
  82. package/public/providers/comfyui.png +0 -0
  83. package/public/providers/commandcode.png +0 -0
  84. package/public/providers/continue.png +0 -0
  85. package/public/providers/copilot.png +0 -0
  86. package/public/providers/coqui.png +0 -0
  87. package/public/providers/cursor.png +0 -0
  88. package/public/providers/deepgram.png +0 -0
  89. package/public/providers/deepseek-tui.png +0 -0
  90. package/public/providers/deepseek.png +0 -0
  91. package/public/providers/droid.png +0 -0
  92. package/public/providers/edge-tts.png +0 -0
  93. package/public/providers/elevenlabs.png +0 -0
  94. package/public/providers/exa.png +0 -0
  95. package/public/providers/fal-ai.png +0 -0
  96. package/public/providers/firecrawl.png +0 -0
  97. package/public/providers/fireworks.png +0 -0
  98. package/public/providers/gemini-cli.png +0 -0
  99. package/public/providers/gemini.png +0 -0
  100. package/public/providers/github.png +0 -0
  101. package/public/providers/glm-cn.png +0 -0
  102. package/public/providers/glm.png +0 -0
  103. package/public/providers/google-pse.png +0 -0
  104. package/public/providers/google-tts.png +0 -0
  105. package/public/providers/grok-web.png +0 -0
  106. package/public/providers/groq.png +0 -0
  107. package/public/providers/hermes.png +0 -0
  108. package/public/providers/huggingface.png +0 -0
  109. package/public/providers/hyperbolic.png +0 -0
  110. package/public/providers/iflow.png +0 -0
  111. package/public/providers/inworld.png +0 -0
  112. package/public/providers/jcode.png +0 -0
  113. package/public/providers/jina-ai.png +0 -0
  114. package/public/providers/jina-reader.png +0 -0
  115. package/public/providers/kilocode.png +0 -0
  116. package/public/providers/kimi-coding.png +0 -0
  117. package/public/providers/kimi.png +0 -0
  118. package/public/providers/kiro.png +0 -0
  119. package/public/providers/linkup.png +0 -0
  120. package/public/providers/local-device.png +0 -0
  121. package/public/providers/minimax-cn.png +0 -0
  122. package/public/providers/minimax.png +0 -0
  123. package/public/providers/mistral.png +0 -0
  124. package/public/providers/nanobanana.png +0 -0
  125. package/public/providers/nebius.png +0 -0
  126. package/public/providers/nvidia.png +0 -0
  127. package/public/providers/oai-cc.png +0 -0
  128. package/public/providers/oai-r.png +0 -0
  129. package/public/providers/ollama-local.png +0 -0
  130. package/public/providers/ollama.png +0 -0
  131. package/public/providers/openai.png +0 -0
  132. package/public/providers/openclaw.png +0 -0
  133. package/public/providers/opencode-go.png +0 -0
  134. package/public/providers/opencode.png +0 -0
  135. package/public/providers/openrouter.png +0 -0
  136. package/public/providers/perplexity-web.png +0 -0
  137. package/public/providers/perplexity.png +0 -0
  138. package/public/providers/playht.png +0 -0
  139. package/public/providers/qwen.png +0 -0
  140. package/public/providers/recraft.png +0 -0
  141. package/public/providers/roo.png +0 -0
  142. package/public/providers/runwayml.png +0 -0
  143. package/public/providers/sdwebui.png +0 -0
  144. package/public/providers/searchapi.png +0 -0
  145. package/public/providers/searxng.png +0 -0
  146. package/public/providers/serper.png +0 -0
  147. package/public/providers/siliconflow.png +0 -0
  148. package/public/providers/stability-ai.png +0 -0
  149. package/public/providers/tavily.png +0 -0
  150. package/public/providers/together.png +0 -0
  151. package/public/providers/topaz.png +0 -0
  152. package/public/providers/tortoise.png +0 -0
  153. package/public/providers/vertex-partner.png +0 -0
  154. package/public/providers/vertex.png +0 -0
  155. package/public/providers/volcengine-ark.png +0 -0
  156. package/public/providers/voyage-ai.png +0 -0
  157. package/public/providers/xai.png +0 -0
  158. package/public/providers/xiaomi-mimo.png +0 -0
  159. package/public/providers/xiaomi-tokenplan.png +0 -0
  160. package/public/providers/youcom.png +0 -0
  161. package/public/sw.js +22 -0
  162. package/public/vercel.svg +1 -0
  163. package/public/window.svg +1 -0
  164. package/start.sh +4 -0
  165. package/vitest.config.js +21 -0
@@ -0,0 +1,4 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "dockerfilePath": "./Dockerfile"
4
+ }
@@ -0,0 +1,20 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // Get all provider connections with full data
9
+ const connections = db.exec("SELECT id, data FROM providerConnections");
10
+ if (connections[0]?.values) {
11
+ connections[0].values.forEach(row => {
12
+ const data = JSON.parse(row[1]);
13
+ console.log(`\n--- Connection: ${row[0]} ---`);
14
+ console.log(JSON.stringify(data, null, 2));
15
+ });
16
+ }
17
+
18
+ db.close();
19
+ process.exit(0);
20
+ });
package/check-db.js ADDED
@@ -0,0 +1,41 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // List all tables
9
+ const tables = db.exec("SELECT name FROM sqlite_master WHERE type='table'");
10
+ console.log('Tables:', tables[0]?.values.map(v => v[0]).join(', '));
11
+
12
+ // Get providers
13
+ try {
14
+ const providers = db.exec("SELECT id, data FROM providers");
15
+ console.log('\nProviders:', providers[0]?.columns);
16
+ if (providers[0]?.values) {
17
+ providers[0].values.forEach(row => {
18
+ const data = JSON.parse(row[1]);
19
+ console.log(`- ${row[0]}: ${data.name || 'unknown'}, enabled: ${data.enabled}`);
20
+ });
21
+ }
22
+ } catch (e) {
23
+ console.log('Providers error:', e.message);
24
+ }
25
+
26
+ // Get API keys
27
+ try {
28
+ const keys = db.exec("SELECT id, key, name FROM apiKeys");
29
+ console.log('\nAPI Keys:', keys[0]?.columns);
30
+ if (keys[0]?.values) {
31
+ keys[0].values.forEach(row => {
32
+ console.log(`- ${row[2]}: ${row[1]?.substring(0, 10)}...`);
33
+ });
34
+ }
35
+ } catch (e) {
36
+ console.log('API Keys error:', e.message);
37
+ }
38
+
39
+ db.close();
40
+ process.exit(0);
41
+ });
package/check-key.js ADDED
@@ -0,0 +1,20 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // Get full key data for the first key
9
+ const result = db.exec("SELECT id, key, name, data FROM apiKeys LIMIT 1");
10
+ if (result[0]?.values) {
11
+ console.log('First API Key:');
12
+ console.log('ID:', result[0].values[0][0]);
13
+ console.log('Key:', result[0].values[0][1]);
14
+ console.log('Name:', result[0].values[0][2]);
15
+ console.log('Data:', result[0].values[0][3]);
16
+ }
17
+
18
+ db.close();
19
+ process.exit(0);
20
+ });
package/check-key2.js ADDED
@@ -0,0 +1,21 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // Get schema
9
+ const schema = db.exec("SELECT sql FROM sqlite_master WHERE name='apiKeys'");
10
+ console.log('apiKeys schema:', schema[0]?.values[0][0]);
11
+
12
+ // Get first key
13
+ const result = db.exec("SELECT * FROM apiKeys LIMIT 1");
14
+ if (result[0]) {
15
+ console.log('\nColumns:', result[0].columns);
16
+ console.log('First row:', result[0].values[0]);
17
+ }
18
+
19
+ db.close();
20
+ process.exit(0);
21
+ });
@@ -0,0 +1,29 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // Get all connections with provider column
9
+ const result = db.exec("SELECT id, provider, isActive, data FROM providerConnections");
10
+ if (result[0]?.values) {
11
+ console.log('All Provider Connections (with provider column):\n');
12
+ result[0].values.forEach(row => {
13
+ const data = JSON.parse(row[3] || '{}');
14
+ const isMimo = data.baseUrl?.includes('mimo') || data.providerSpecificData?.baseUrl?.includes('mimo');
15
+ if (isMimo || row[1]?.includes('mimo')) {
16
+ console.log(`--- ${row[0]} ---`);
17
+ console.log(`Provider: ${row[1]}`);
18
+ console.log(`isActive: ${row[2]}`);
19
+ console.log(`API Key: ${data.apiKey || data.providerSpecificData?.apiKey || 'NOT FOUND'}`);
20
+ console.log(`Prefix: ${data.prefix || data.providerSpecificData?.prefix}`);
21
+ console.log(`Base URL: ${data.baseUrl || data.providerSpecificData?.baseUrl}`);
22
+ console.log('');
23
+ }
24
+ });
25
+ }
26
+
27
+ db.close();
28
+ process.exit(0);
29
+ });
package/check-mimo.js ADDED
@@ -0,0 +1,22 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // Get MiMo provider full data
9
+ const nodes = db.exec("SELECT id, data FROM providerNodes");
10
+ if (nodes[0]?.values) {
11
+ nodes[0].values.forEach(row => {
12
+ const data = JSON.parse(row[1]);
13
+ if (data.baseUrl?.includes('mimo')) {
14
+ console.log('MiMo Provider Full Data:');
15
+ console.log(JSON.stringify(data, null, 2));
16
+ }
17
+ });
18
+ }
19
+
20
+ db.close();
21
+ process.exit(0);
22
+ });
package/check-nodes.js ADDED
@@ -0,0 +1,26 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // Get all provider nodes
9
+ const result = db.exec("SELECT id, provider, name, data FROM providerNodes");
10
+ if (result[0]?.values) {
11
+ console.log('All Provider Nodes:\n');
12
+ result[0].values.forEach(row => {
13
+ const data = JSON.parse(row[3] || '{}');
14
+ console.log(`ID: ${row[0]}`);
15
+ console.log(`Provider: ${row[1]}`);
16
+ console.log(`Name: ${row[2]}`);
17
+ console.log(`Prefix: ${data.prefix}`);
18
+ console.log(`Base URL: ${data.baseUrl}`);
19
+ console.log(`Has API Key: ${!!data.apiKey}`);
20
+ console.log('---');
21
+ });
22
+ }
23
+
24
+ db.close();
25
+ process.exit(0);
26
+ });
@@ -0,0 +1,29 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // Get schema
9
+ const schema = db.exec("SELECT sql FROM sqlite_master WHERE name='providerNodes'");
10
+ console.log('providerNodes schema:');
11
+ console.log(schema[0]?.values[0][0]);
12
+
13
+ // Get all nodes without provider column
14
+ const result = db.exec("SELECT id, data FROM providerNodes");
15
+ if (result[0]?.values) {
16
+ console.log('\nAll Provider Nodes:\n');
17
+ result[0].values.forEach(row => {
18
+ const data = JSON.parse(row[1] || '{}');
19
+ console.log(`ID: ${row[0]}`);
20
+ console.log(`Prefix: ${data.prefix}`);
21
+ console.log(`Base URL: ${data.baseUrl}`);
22
+ console.log(`Name: ${data.name}`);
23
+ console.log('---');
24
+ });
25
+ }
26
+
27
+ db.close();
28
+ process.exit(0);
29
+ });
@@ -0,0 +1,48 @@
1
+ const initSqlJs = require('sql.js');
2
+ const fs = require('fs');
3
+
4
+ initSqlJs().then(SQL => {
5
+ const buffer = fs.readFileSync('E:/var/lib/9router/db/data.sqlite');
6
+ const db = new SQL.Database(buffer);
7
+
8
+ // Get provider connections
9
+ try {
10
+ const providers = db.exec("SELECT id, data FROM providerConnections");
11
+ console.log('Provider Connections:');
12
+ if (providers[0]?.values) {
13
+ providers[0].values.forEach(row => {
14
+ const data = JSON.parse(row[1]);
15
+ console.log(`\n- ID: ${row[0]}`);
16
+ console.log(` Name: ${data.name}`);
17
+ console.log(` Type: ${data.type}`);
18
+ console.log(` Enabled: ${data.enabled}`);
19
+ if (data.nodes) {
20
+ console.log(` Nodes: ${data.nodes.length}`);
21
+ }
22
+ });
23
+ }
24
+ } catch (e) {
25
+ console.log('Provider Connections error:', e.message);
26
+ }
27
+
28
+ // Get provider nodes
29
+ try {
30
+ const nodes = db.exec("SELECT id, data FROM providerNodes");
31
+ console.log('\n\nProvider Nodes:');
32
+ if (nodes[0]?.values) {
33
+ nodes[0].values.forEach(row => {
34
+ const data = JSON.parse(row[1]);
35
+ console.log(`\n- ID: ${row[0]}`);
36
+ console.log(` Name: ${data.name}`);
37
+ console.log(` Base URL: ${data.baseUrl}`);
38
+ console.log(` Has API Key: ${data.apiKey ? 'yes' : 'no'}`);
39
+ console.log(` Enabled: ${data.enabled}`);
40
+ });
41
+ }
42
+ } catch (e) {
43
+ console.log('Provider Nodes error:', e.message);
44
+ }
45
+
46
+ db.close();
47
+ process.exit(0);
48
+ });
package/dev.log ADDED
@@ -0,0 +1,15 @@
1
+
2
+ > kentutai-app@1.0.0 dev
3
+ > next dev --webpack --port 20123
4
+
5
+ ⨯ Failed to start server
6
+ Error: listen EADDRINUSE: address already in use :::20123
7
+ at <unknown> (Error: listen EADDRINUSE: address already in use :::20123)
8
+ at new Promise (<anonymous>) {
9
+ code: 'EADDRINUSE',
10
+ errno: -4091,
11
+ syscall: 'listen',
12
+ address: '::',
13
+ port: 20123
14
+ }
15
+ [?25h
package/next-env.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+ import "./.next/dev/types/routes.d.ts";
4
+
5
+ // NOTE: This file should not be edited
6
+ // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
package/opencode.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://opencode.ai/config.json",
3
+ "name": "Kentut-Router",
4
+ "version": "1.0.0",
5
+ "description": "KentutAI web dashboard - FREE AI Router & Token Saver",
6
+ "skills": [
7
+ "skills/9router/SKILL.md",
8
+ "skills/9router-chat/SKILL.md",
9
+ "skills/9router-embeddings/SKILL.md",
10
+ "skills/9router-image/SKILL.md",
11
+ "skills/9router-stt/SKILL.md",
12
+ "skills/9router-tts/SKILL.md",
13
+ "skills/9router-web-fetch/SKILL.md",
14
+ "skills/9router-web-search/SKILL.md"
15
+ ],
16
+ "omo": {
17
+ "plans_dir": ".omo/plans",
18
+ "boulder_file": ".omo/boulder.json",
19
+ "evidence_dir": ".omo/evidence",
20
+ "drafts_dir": ".omo/drafts"
21
+ }
22
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "kentutai-app",
3
+ "version": "1.0.0",
4
+ "description": "KentutAI web dashboard",
5
+ "private": false,
6
+ "scripts": {
7
+ "dev": "next dev --webpack --port 20123",
8
+ "build": "next build",
9
+ "build:cli": "powershell -ExecutionPolicy Bypass -File scripts/build-cli.ps1",
10
+ "start": "next start --port 20123",
11
+ "dev:bun": "bun --bun next dev --webpack --port 20123",
12
+ "build:bun": "bun --bun next build --turbopack",
13
+ "start:bun": "bun ./.next/standalone/server.js",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest"
16
+ },
17
+ "dependencies": {
18
+ "@dnd-kit/core": "^6.3.1",
19
+ "@dnd-kit/modifiers": "^9.0.0",
20
+ "@dnd-kit/sortable": "^10.0.0",
21
+ "@dnd-kit/utilities": "^3.2.2",
22
+ "@monaco-editor/react": "^4.7.0",
23
+ "@xyflow/react": "^12.10.1",
24
+ "bcryptjs": "^3.0.3",
25
+ "confbox": "^0.2.4",
26
+ "date-fns": "^4.3.0",
27
+ "express": "^5.2.1",
28
+ "fs": "^0.0.1-security",
29
+ "http-proxy-middleware": "^3.0.5",
30
+ "jose": "^6.1.3",
31
+ "jspdf": "^4.2.1",
32
+ "jspdf-autotable": "^5.0.8",
33
+ "marked": "^18.0.1",
34
+ "material-symbols": "^0.44.6",
35
+ "monaco-editor": "^0.55.1",
36
+ "next": "^16.1.6",
37
+ "node-forge": "^1.3.3",
38
+ "node-machine-id": "^1.1.12",
39
+ "open": "^11.0.0",
40
+ "ora": "^9.1.0",
41
+ "react": "19.2.4",
42
+ "react-dom": "19.2.4",
43
+ "react-is": "^16.13.1",
44
+ "recharts": "^3.7.0",
45
+ "selfsigned": "^5.5.0",
46
+ "socks-proxy-agent": "^8.0.5",
47
+ "sql.js": "^1.14.1",
48
+ "undici": "^7.19.2",
49
+ "uuid": "^13.0.0",
50
+ "zustand": "^5.0.10"
51
+ },
52
+ "optionalDependencies": {
53
+ "better-sqlite3": "^12.6.2"
54
+ },
55
+ "comment_better_sqlite3": "kept in optionalDependencies so npm install doesn't fail on systems without build tools — sql.js is used as fallback at runtime",
56
+ "devDependencies": {
57
+ "@tailwindcss/postcss": "^4.1.18",
58
+ "@types/react": "19.2.15",
59
+ "eslint": "^9",
60
+ "eslint-config-next": "16.1.6",
61
+ "postcss": "^8.5.6",
62
+ "tailwindcss": "^4",
63
+ "vitest": "^4.1.7"
64
+ }
65
+ }
Binary file
@@ -0,0 +1 @@
1
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -0,0 +1,194 @@
1
+ {
2
+ "Cancel": "إلغاء",
3
+ "Delete": "حذف",
4
+ "Edit": "تحرير",
5
+ "Save": "حفظ",
6
+ "Close": "إغلاق",
7
+ "Add": "إضافة",
8
+ "Remove": "إزالة",
9
+ "Settings": "الإعدادات",
10
+ "Profile": "الملف الشخصي",
11
+ "Dashboard": "لوحة التحكم",
12
+ "Logout": "تسجيل الخروج",
13
+ "Login": "تسجيل الدخول",
14
+ "Providers": "الموفرون",
15
+ "Usage": "الإحصائيات",
16
+ "API Key": "مفتاح API",
17
+ "Connected": "متصل",
18
+ "Disconnected": "غير متصل",
19
+ "Active": "نشط",
20
+ "Inactive": "غير نشط",
21
+ "Success": "نجح",
22
+ "Failed": "فشل",
23
+ "Error": "خطأ",
24
+ "Warning": "تحذير",
25
+ "Info": "معلومات",
26
+ "Loading": "جاري التحميل",
27
+ "Search": "بحث",
28
+ "Filter": "تصفية",
29
+ "Sort": "ترتيب",
30
+ "Export": "تصدير",
31
+ "Import": "استيراد",
32
+ "Refresh": "تحديث",
33
+ "Back": "رجوع",
34
+ "Next": "التالي",
35
+ "Previous": "السابق",
36
+ "Submit": "إرسال",
37
+ "Confirm": "تأكيد",
38
+ "Yes": "نعم",
39
+ "No": "لا",
40
+ "OK": "حسنا",
41
+ "Apply": "تطبيق",
42
+ "Reset": "إعادة تعيين",
43
+ "Clear": "مسح",
44
+ "Select": "تحديد",
45
+ "Upload": "تحميل",
46
+ "Download": "تنزيل",
47
+ "Copy": "نسخ",
48
+ "Paste": "لصق",
49
+ "Cut": "قص",
50
+ "Undo": "تراجع",
51
+ "Redo": "إعادة",
52
+ "Name": "الاسم",
53
+ "Description": "الوصف",
54
+ "Status": "الحالة",
55
+ "Type": "النوع",
56
+ "Date": "التاريخ",
57
+ "Time": "الوقت",
58
+ "Created": "تم إنشاء",
59
+ "Updated": "تم التحديث",
60
+ "Actions": "الإجراءات",
61
+ "Details": "التفاصيل",
62
+ "View": "عرض",
63
+ "New": "جديد",
64
+ "Total": "الإجمالي",
65
+ "Count": "العدد",
66
+ "Price": "السعر",
67
+ "Cost": "التكلفة",
68
+ "Free": "مجاني",
69
+ "Paid": "مدفوع",
70
+ "Enable": "تفعيل",
71
+ "Disable": "تعطيل",
72
+ "Enabled": "مفعل",
73
+ "Disabled": "معطل",
74
+ "Online": "متصل",
75
+ "Offline": "غير متصل",
76
+ "Available": "متاح",
77
+ "Unavailable": "غير متاح",
78
+ "Required": "مطلوب",
79
+ "Optional": "اختياري",
80
+ "Default": "افتراضي",
81
+ "Custom": "مخصص",
82
+ "Advanced": "متقدم",
83
+ "Basic": "أساسي",
84
+ "Help": "مساعدة",
85
+ "Support": "دعم",
86
+ "Documentation": "التوثيق",
87
+ "Version": "الإصدار",
88
+ "Language": "اللغة",
89
+ "Theme": "المظهر",
90
+ "Light": "فاتح",
91
+ "Dark": "داكن",
92
+ "Auto": "تلقائي",
93
+ "Endpoint": "نقطة نهاية",
94
+ "Combos": "تراكيب",
95
+ "Quota Tracker": "متتبع الحصة",
96
+ "MITM": "MITM",
97
+ "CLI Tools": "أدوات CLI",
98
+ "Console Log": "سجل وحدة التحكم",
99
+ "System": "النظام",
100
+ "Debug": "تصحيح",
101
+ "Shutdown": "إيقاف",
102
+ "Close Proxy": "إغلاق الوكيل",
103
+ "Are you sure you want to close the proxy server?": "هل أنت متأكد من أنك تريد إغلاق خادم الوكيل؟",
104
+ "Server Disconnected": "خادم غير متصل",
105
+ "The proxy server has been stopped.": "تم إيقاف خادم الوكيل.",
106
+ "Reload Page": "إعادة تحميل الصفحة",
107
+ "Service is running in terminal. You can close this web page. Shutdown will stop the service.": "الخدمة تعمل في المحطة الطرفية. يمكنك إغلاق صفحة الويب هذه. سيؤدي الإيقاف إلى إيقاف الخدمة.",
108
+ "Manage your AI provider connections": "إدارة اتصالات موفر الذكاء الاصطناعي الخاصة بك",
109
+ "Model combos with fallback": "تراكيب النموذج مع الخيار البديل",
110
+ "Monitor your API usage, token consumption, and request logs": "راقب استخدام API وتناول الرموز وسجلات الطلب",
111
+ "Intercept CLI tool traffic and route through 9Router": "اعترض حركة مرور أداة CLI وحجم من خلال 9Router",
112
+ "Configure CLI tools": "تكوين أدوات CLI",
113
+ "API endpoint configuration": "تكوين نقطة نهاية API",
114
+ "Manage your preferences": "إدارة تفضيلاتك",
115
+ "Debug translation flow between formats": "تصحيح تدفق الترجمة بين الصيغ",
116
+ "Live server console output": "مخرجات وحدة التحكم على الخادم المباشر",
117
+ "Create model combos with fallback support": "إنشاء تراكيب نموذج مع دعم الخيار البديل",
118
+ "Local Mode": "الوضع المحلي",
119
+ "Running on your machine": "يعمل على جهازك",
120
+ "Database Location": "موقع قاعدة البيانات",
121
+ "Download Backup": "تنزيل النسخة الاحتياطية",
122
+ "Import Backup": "استيراد النسخة الاحتياطية",
123
+ "Database backup downloaded": "تم تنزيل النسخة الاحتياطية لقاعدة البيانات",
124
+ "Database imported successfully": "تم استيراد قاعدة البيانات بنجاح",
125
+ "Security": "الأمان",
126
+ "Require login": "يتطلب تسجيل الدخول",
127
+ "When ON, dashboard requires password. When OFF, access without login.": "عند التشغيل، يتطلب لوحة التحكم كلمة مرور. عند الإيقاف، الوصول بدون تسجيل دخول.",
128
+ "Current Password": "كلمة المرور الحالية",
129
+ "Enter current password": "أدخل كلمة المرور الحالية",
130
+ "New Password": "كلمة مرور جديدة",
131
+ "Enter new password": "أدخل كلمة مرور جديدة",
132
+ "Confirm New Password": "تأكيد كلمة المرور الجديدة",
133
+ "Confirm new password": "تأكيد كلمة المرور الجديدة",
134
+ "Update Password": "تحديث كلمة المرور",
135
+ "Set Password": "تعيين كلمة المرور",
136
+ "Password updated successfully": "تم تحديث كلمة المرور بنجاح",
137
+ "Passwords do not match": "كلمات المرور لا تتطابق",
138
+ "Routing Strategy": "استراتيجية التوجيه",
139
+ "Round Robin": "جولة روبن",
140
+ "Cycle through accounts to distribute load": "الدوران عبر الحسابات لتوزيع الحمل",
141
+ "Sticky Limit": "حد لزج",
142
+ "Calls per account before switching": "المكالمات لكل حساب قبل التبديل",
143
+ "Network": "الشبكة",
144
+ "Outbound Proxy": "وكيل الخروج",
145
+ "Enable proxy for OAuth + provider outbound requests.": "تفعيل الوكيل لطلبات OAuth + الخروج من الموفر.",
146
+ "Proxy URL": "عنوان URL الوكيل",
147
+ "Leave empty to inherit existing env proxy (if any).": "اترك فارغًا لوراثة وكيل env الموجود (إن وجد).",
148
+ "No Proxy": "لا يوجد وكيل",
149
+ "Comma-separated hostnames/domains to bypass the proxy.": "أسماء المضيفين/النطاقات المفصولة بفواصل لتجاوز الوكيل.",
150
+ "Test proxy URL": "اختبر عنوان URL الوكيل",
151
+ "Proxy settings applied": "تم تطبيق إعدادات الوكيل",
152
+ "Proxy enabled": "الوكيل مفعل",
153
+ "Proxy disabled": "الوكيل معطل",
154
+ "Proxy test OK": "اختبار الوكيل حسنا",
155
+ "Proxy test failed": "فشل اختبار الوكيل",
156
+ "Please enter a Proxy URL to test": "يرجى إدخال عنوان URL الوكيل للاختبار",
157
+ "Observability": "القابلية للمراقبة",
158
+ "Enable Observability": "تفعيل القابلية للمراقبة",
159
+ "Turn request detail recording on/off globally": "تشغيل/إيقاف تسجيل تفاصيل الطلب بشكل عام",
160
+ "Max Records": "أقصى عدد من السجلات",
161
+ "Maximum request detail records to keep (older records are auto-deleted)": "الحد الأقصى من سجلات تفاصيل الطلب للاحتفاظ بها (يتم حذف السجلات الأقدم تلقائيًا)",
162
+ "Batch Size": "حجم الدفعة",
163
+ "Number of items to accumulate before writing to database (higher = better performance)": "عدد العناصر المراد تجميعها قبل الكتابة إلى قاعدة البيانات (أعلى = أداء أفضل)",
164
+ "Flush Interval (ms)": "فترة المسح (ms)",
165
+ "Maximum time to wait before flushing buffer (prevents data loss during low traffic)": "الحد الأقصى للانتظار قبل مسح المخزن المؤقت (يمنع فقدان البيانات أثناء الحركة المنخفضة)",
166
+ "Max JSON Size (KB)": "أقصى حجم JSON (KB)",
167
+ "Maximum size for each JSON field (request/response) before truncation": "الحد الأقصى لحجم كل حقل JSON (الطلب/الرد) قبل القطع",
168
+ "All data stored on your machine": "جميع البيانات المخزنة على جهازك",
169
+ "MITM Server": "خادم MITM",
170
+ "Running": "يجري",
171
+ "Stopped": "متوقف",
172
+ "Cert": "شهادة",
173
+ "Server": "الخادم",
174
+ "Purpose:": "الغرض:",
175
+ "Use Antigravity IDE & GitHub Copilot → with ANY provider/model from 9Router": "استخدم Antigravity IDE و GitHub Copilot → مع أي موفر/نموذج من 9Router",
176
+ "How it works:": "كيف يعمل:",
177
+ "Antigravity/Copilot IDE request → DNS redirect to localhost:443 → MITM proxy intercepts → 9Router → response to Antigravity/Copilot": "طلب Antigravity/Copilot IDE → إعادة توجيه DNS إلى localhost:443 → يعترض وكيل MITM → 9Router → الرد إلى Antigravity/Copilot",
178
+ "No API keys — create one in Keys page": "لا توجد مفاتيح API — قم بإنشاء واحدة في صفحة المفاتيح",
179
+ "sk_9router (default)": "sk_9router (افتراضي)",
180
+ "Server started": "تم بدء الخادم",
181
+ "Failed to start server": "فشل في بدء الخادم",
182
+ "Server stopped — all DNS cleared": "تم إيقاف الخادم — تم مسح جميع DNS",
183
+ "Failed to stop server": "فشل في إيقاف الخادم",
184
+ "Sudo password is required": "كلمة مرور sudo مطلوبة",
185
+ "Stop Server": "إيقاف الخادم",
186
+ "Start Server": "بدء الخادم",
187
+ "Enable DNS per tool below to activate interception": "قم بتفعيل DNS لكل أداة أدناه لتفعيل الاعتراض",
188
+ "Sudo Password Required": "كلمة مرور Sudo مطلوبة",
189
+ "Enter your sudo password to start/stop MITM server": "أدخل كلمة مرور sudo للبدء/الإيقاف من خادم MITM",
190
+ "Sudo Password": "كلمة مرور Sudo",
191
+ "Click to add, click again to remove. Changes are saved automatically.": "انقر للإضافة، انقر مرة أخرى للإزالة. يتم حفظ التغييرات تلقائيًا.",
192
+ "⚠️ Risk Notice: This provider uses a subscription/OAuth session not officially licensed for proxy/router use. Account may be restricted or banned. Use at your own risk.": "⚠️ تنبيه مخاطر: يستخدم هذا الموفر اشتراكًا/جلسة OAuth غير مرخصة رسميًا للاستخدام عبر البروكسي/الراوتر. قد يتم تقييد الحساب أو حظره. الاستخدام على مسؤوليتك الخاصة.",
193
+ "⚠️ MITM intercepts HTTPS traffic of IDE tools (Antigravity, GitHub Copilot, Kiro) via local CA to redirect requests to your providers. May violate ToS → account ban. Use at your own risk.": "⚠️ يعترض MITM حركة مرور HTTPS لأدوات IDE (Antigravity، GitHub Copilot، Kiro) عبر CA محلية لإعادة توجيه الطلبات إلى مزوديك. قد ينتهك شروط الخدمة → خطر حظر الحساب. الاستخدام على مسؤوليتك الخاصة."
194
+ }