@vln.codes__/icode 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 (3) hide show
  1. package/README.md +213 -0
  2. package/bin/icode.js +57 -0
  3. package/package.json +35 -0
package/README.md ADDED
@@ -0,0 +1,213 @@
1
+ # iCode (packages/icode)
2
+
3
+ **iCode** is a professional terminal-based coding agent built on **OpenCode AI**,
4
+ designed from the beginning for **Kinyarwanda** speakers.
5
+
6
+ - **Kinyarwanda-first** developer experience (UI, prompts, explanations).
7
+ - **EjoChat** as a dedicated Kinyarwanda language-intelligence service.
8
+ - **OpenCode** remains the coding engine (files, terminal, Git, tools, commands).
9
+ - Streams output, slash commands, semantic colors with ASCII/monochrome fallback.
10
+
11
+ > iCode is not "English software translated into Kinyarwanda". It is a developer
12
+ > tool designed natively for Kinyarwanda speakers, while keeping all technical
13
+ > code, syntax, identifiers, paths, and commands unchanged.
14
+
15
+ ---
16
+
17
+ ## Install
18
+
19
+ `iCode` ships as a **fast native binary** on npm, distributed per-platform
20
+ (via optional dependencies, the same model as `esbuild`). Install it globally:
21
+
22
+ ```sh
23
+ npm install -g @vln.codes__/icode
24
+ ```
25
+
26
+ Then run `icode` from anywhere:
27
+
28
+ ```sh
29
+ icode # start the interactive TUI
30
+ icode "help me refactor login" # one-shot prompt
31
+ icode --help
32
+ ```
33
+
34
+ > The bare `icode` name and the `@icode` scope are reserved on npm, so the
35
+ > published package is `@vln.codes__/icode`. It installs the native `icode`
36
+ > command.
37
+
38
+ **Supported platforms** (native binary, no Node/Bun runtime needed):
39
+
40
+ | OS | Architecture |
41
+ |----|--------------|
42
+ | Linux | x64, arm64 |
43
+ | macOS (Darwin) | x64, arm64 |
44
+ | Windows | x64, arm64 |
45
+
46
+ On first run you'll be asked to connect an AI provider (`icode providers`)
47
+ and, optionally, set an EjoChat API key for Kinyarwanda language intelligence.
48
+
49
+ ---
50
+
51
+ ## Architecture
52
+
53
+ ```
54
+ src/
55
+ cli/ renderer, prompt, spinner, theme, terminal, slashes, danger, shell
56
+ language/ kinyarwanda (dictionaries), detector, token-protector,
57
+ ejochat (Anthropic-compatible client), kinyarwanda-service
58
+ agent/ opencode (OpenCode SDK driver), context (project info)
59
+ config/ load ~/.config/icode/config.* + env
60
+ security/ secret detection & redaction
61
+ utils/ lightweight config parsers (jsonc/toml/yaml)
62
+ ```
63
+
64
+ **Pipeline** (see spec section 5):
65
+
66
+ ```
67
+ USER INPUT
68
+ -> language detection
69
+ -> Kinyarwanda understanding (EjoChat)
70
+ -> intent extraction
71
+ -> OpenCode agent (code/tools)
72
+ -> tool execution
73
+ -> technical result
74
+ -> EjoChat Kinyarwanda explanation
75
+ -> CLI renderer
76
+ ```
77
+
78
+ **The rule that matters:** EjoChat is the *language-intelligence* layer only. It
79
+ never runs coding tools. OpenCode owns the coding engine. Every string sent to
80
+ EjoChat passes through token protection and secret redaction, so technical
81
+ tokens are never corrupted and secrets are never exposed.
82
+
83
+ ---
84
+
85
+ ## Setup
86
+
87
+ Requires [Bun](https://bun.sh) and the workspace-installed dependencies:
88
+
89
+ ```sh
90
+ bun install
91
+ ```
92
+
93
+ Provide the EjoChat key (never hard-coded, never committed):
94
+
95
+ ```sh
96
+ export EJOCHAT_API_KEY=ejochat_your_key_here
97
+ ```
98
+
99
+ Optional config in `~/.config/icode/config.{json,jsonc,toml,yaml}` — see
100
+ `examples/`. All values are overridable via environment variables:
101
+
102
+ | Variable | Purpose |
103
+ | --------------------- | ------------------------------------------ |
104
+ | `EJOCHAT_API_KEY` | Required for Kinyarwanda intelligence |
105
+ | `EJOCHAT_BASE_URL` | Default `https://api.ejolabs.com/api/v1` |
106
+ | `EJOCHAT_MODEL` | EjoChat model |
107
+ | `EJOCHAT_DISABLED` | `1` to disable EjoChat entirely |
108
+ | `ICODE_LANGUAGE` | `rw` (default) \| `auto` \| `en` |
109
+ | `ICODE_DEBUG` | `1` to surface technical errors |
110
+ | `ICODE_ASCII` | `1` to force ASCII-only glyphs |
111
+ | `ICODE_NO_COLOR` | `1` to disable color |
112
+
113
+ ### EjoChat API contract
114
+
115
+ This package integrates with the official **EjoChat** API (by Ejo Labs):
116
+
117
+ - Endpoint: `POST https://api.ejolabs.com/api/v1/subiza` (configurable via
118
+ `EJOCHAT_BASE_URL`; the `/subiza` path is appended automatically).
119
+ - Auth: `X-API-Key` header (an `ejochat_...` or `kgpt_...` key). The key is
120
+ only ever sent in request headers — never in the body, logs, or prompts.
121
+ - Body: OpenAI-style `{ "model", "messages": [{ role, content }] }`; an
122
+ optional system prompt is injected as the first `system` message.
123
+ - The library parses several common response shapes
124
+ (`choices[].message.content`, `content[].text`, and plain `text`/`answer`).
125
+
126
+
127
+ ---
128
+
129
+ ## Usage
130
+
131
+ ```sh
132
+ bun run bin/icode.ts
133
+ ```
134
+
135
+ Interactive prompt:
136
+
137
+ ```
138
+ ⚡ iCode > sobanura iyi dosiye
139
+ ```
140
+
141
+ Single-shot mode:
142
+
143
+ ```sh
144
+ bun run bin/icode.ts "Kosora ikibazo kiri muri iyi code."
145
+ ```
146
+
147
+ ### Slash commands (English names, Kinyarwanda descriptions)
148
+
149
+ | Command | Meaning (Kinyarwanda) |
150
+ | ------------------- | -------------------------------------- |
151
+ | `/help` | Erekana amabwiriza yose ya iCode. |
152
+ | `/status` | Erekana uko umushinga umeze. |
153
+ | `/model` | Reba model ikoreshwa. |
154
+ | `/language rw\|auto\|en` | Hitamo ururimi. |
155
+ | `/config` | Reba ahantu iCode ibitswe config. |
156
+ | `/clear` | Siba ibyo bigaragara kuri terminal. |
157
+ | `/exit` | Sohoka muri iCode. |
158
+ | `/version` | Erekana version ya iCode. |
159
+
160
+ ---
161
+
162
+ ## Language modes
163
+
164
+ - **`rw`** (default): UI and explanations in Kinyarwanda; code/syntax/commands
165
+ unchanged.
166
+ - **`auto`**: detects whether the input is Kinyarwanda.
167
+ - **`en`**: English UI/explanations.
168
+
169
+ ## Security
170
+
171
+ - API key is read from the environment only, never printed, never logged, never
172
+ committed, and never sent to EjoChat as content.
173
+ - `security/secret.ts` detects and redacts JWT-like tokens, key fields, and
174
+ high-entropy strings before external calls and before display.
175
+ - If `EJOCHAT_API_KEY` is missing, iCode prints a warning and continues as a
176
+ normal coding agent — it never crashes (spec section 4).
177
+
178
+ ## Technical token protection
179
+
180
+ `language/token-protector.ts` protects file paths, URLs, code blocks, inline
181
+ code, commands, env vars, and identifiers before Kinyarwanda processing, then
182
+ restores them — so language processing can never corrupt code or paths.
183
+
184
+ ## Testing
185
+
186
+ ```sh
187
+ bun test
188
+ bun typecheck # tsgo
189
+ ```
190
+
191
+ ## Package notes
192
+
193
+ - Published package `@vln.codes__/icode` (native `icode` command). The `npm`
194
+ tarball ships a small cross-platform `bin/icode.js` launcher plus per-platform
195
+ native binaries as optional dependencies (`@vln.codes__/icode-linux-x64`,
196
+ `@vln.codes__/icode-linux-arm64`, `@vln.codes__/icode-darwin-x64`,
197
+ `@vln.codes__/icode-darwin-arm64`, `@vln.codes__/icode-windows-x64`,
198
+ `@vln.codes__/icode-windows-arm64`).
199
+ - Build the binaries from `packages/opencode` (`bun run script/build.ts`), then
200
+ assemble the npm packages with `bun run script/package.ts --version=<ver>`
201
+ from this directory.
202
+ - The repo also keeps a self-contained TypeScript reference implementation under
203
+ `src/` (Kinyarwanda CLI built on OpenCode), used for development and tests.
204
+ The shipped product is the native binary, not this source.
205
+
206
+ ## Credits
207
+
208
+ - **iCode** is created by **Irabizi Paisible Valentin**.
209
+ - The coding engine and underlying coding workflows are built on the
210
+ **OpenCode** engine (MIT, © 2025 opencode). iCode is not affiliated with the
211
+ OpenCode team. See the repository LICENSE (root and `packages/opencode`).
212
+ - **EjoChat** (by Ejo Labs) is used only as a Kinyarwanda language-intelligence
213
+ layer and never runs coding tools.
package/bin/icode.js ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from "node:child_process"
3
+ import { createRequire } from "node:module"
4
+ import { fileURLToPath } from "node:url"
5
+ import path from "node:path"
6
+
7
+ const require = createRequire(import.meta.url)
8
+ const binDir = path.dirname(fileURLToPath(import.meta.url))
9
+
10
+ const KNOWN = {
11
+ "linux-x64": "@vln.codes__/icode-linux-x64",
12
+ "linux-arm64": "@vln.codes__/icode-linux-arm64",
13
+ "darwin-x64": "@vln.codes__/icode-darwin-x64",
14
+ "darwin-arm64": "@vln.codes__/icode-darwin-arm64",
15
+ "win32-x64": "@vln.codes__/icode-windows-x64",
16
+ "win32-arm64": "@vln.codes__/icode-windows-arm64",
17
+ }
18
+
19
+ const key = `${process.platform}-${process.arch}`
20
+ const pkg = KNOWN[key]
21
+
22
+ if (!pkg) {
23
+ console.error(
24
+ `iCode does not support ${process.platform}-${process.arch} yet.\n` +
25
+ `Supported platforms: ${Object.keys(KNOWN).join(", ")}`,
26
+ )
27
+ process.exit(1)
28
+ }
29
+
30
+ let bin
31
+ try {
32
+ const binName = process.platform === "win32" ? "icode.exe" : "icode"
33
+ bin = require.resolve(`${pkg}/bin/${binName}`, { paths: [binDir, process.cwd()] })
34
+ } catch {
35
+ console.error(
36
+ `iCode native binary for ${key} (${pkg}) is not installed.\n` +
37
+ `This usually means the optional dependency was skipped. Run:\n` +
38
+ ` npm install -g @icode/cli --force\n` +
39
+ `or reinstall @icode/cli so the matching platform package is fetched.`,
40
+ )
41
+ process.exit(1)
42
+ }
43
+
44
+ const child = spawn(bin, process.argv.slice(2), { stdio: "inherit", windowsHide: true })
45
+
46
+ child.on("error", (error) => {
47
+ console.error(`iCode failed to launch: ${error.message}`)
48
+ process.exit(1)
49
+ })
50
+
51
+ child.on("exit", (code, signal) => {
52
+ if (signal) {
53
+ process.kill(process.pid, signal)
54
+ return
55
+ }
56
+ process.exit(code ?? 0)
57
+ })
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/package.json",
3
+ "name": "@vln.codes__/icode",
4
+ "version": "1.0.0",
5
+ "description": "iCode — a fast, native AI coding agent with a Kinyarwanda-first experience. Install globally to run `icode`.",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "bin": {
9
+ "icode": "bin/icode.js"
10
+ },
11
+ "files": [
12
+ "bin/icode.js"
13
+ ],
14
+ "scripts": {
15
+ "dev": "bun run ./bin/icode.ts",
16
+ "typecheck": "tsgo --noEmit",
17
+ "test": "bun test --timeout 30000",
18
+ "package": "bun run script/package.ts --version=$npm_package_version"
19
+ },
20
+ "optionalDependencies": {
21
+ "@vln.codes__/icode-linux-x64": "1.0.0",
22
+ "@vln.codes__/icode-linux-arm64": "1.0.0",
23
+ "@vln.codes__/icode-darwin-x64": "1.0.0",
24
+ "@vln.codes__/icode-darwin-arm64": "1.0.0",
25
+ "@vln.codes__/icode-windows-x64": "1.0.0",
26
+ "@vln.codes__/icode-windows-arm64": "1.0.0"
27
+ },
28
+ "devDependencies": {
29
+ "@opencode-ai/script": "workspace:*",
30
+ "@tsconfig/bun": "catalog:",
31
+ "@types/bun": "catalog:",
32
+ "@types/node": "catalog:",
33
+ "@typescript/native-preview": "catalog:"
34
+ }
35
+ }