@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.
- package/README.md +213 -0
- package/bin/icode.js +57 -0
- 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
|
+
}
|