@ywldan/karsa 0.0.0-stage → 0.1.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 +21 -0
- package/README.md +207 -2
- package/bin/karsa.js +34 -0
- package/karsa +0 -0
- package/package.json +31 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Karsa contributors
|
|
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,208 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# ▚▞ Karsa
|
|
4
|
+
|
|
5
|
+
**"Ember in the terminal"** — agentic coding CLI berbasis Rust yang ringan,
|
|
6
|
+
dengan TUI fullscreen, daemon multi-sesi, dan keamanan berlapis.
|
|
7
|
+
|
|
8
|
+
`v0.1.0` · Rust 2024 · workspace 17 crate · semua teks UI Bahasa Indonesia
|
|
9
|
+
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Tangkapan layar
|
|
15
|
+
|
|
16
|
+
Frame berikut adalah tangkapan **nyata** dari TUI (pty + emulasi ANSI `pyte`,
|
|
17
|
+
binary `target/release/karsa`):
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
karsa default · mock ctx 0% · · - t/s · 0s ·
|
|
21
|
+
ℹ ▚▞ karsa v0.1.0 — ketik prompt; `/` palette; Ctrl+C 2× keluar TODO FILES PLAN MCP TAB
|
|
22
|
+
────────────────────────────
|
|
23
|
+
ℹ mcp: 1 server aktif — 1 terhubung, 0 gagal (rincian `/mcp`)
|
|
24
|
+
╭ /cmd · ⏎ kirim · ⇧⏎ antri · ↑ riwayat ───────────────────────────────────────────────────────────╮
|
|
25
|
+
│▸ │
|
|
26
|
+
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
(Warna asli: palet *dark orange × black* dari `karsa-theme`; tangkapan teks
|
|
30
|
+
kehilangan warna. Rekaman animasi/asciinema menyusul — lihat [Kurang](#yang-masih-kurang).)
|
|
31
|
+
|
|
32
|
+
## Ini apa?
|
|
33
|
+
|
|
34
|
+
**Karsa** adalah pengkodean bersama agen (agentic coding harness) seperti jcode /
|
|
35
|
+
Claude Code, tetapi di terminal Rust: satu binary, TUI fullscreen `ratatui +
|
|
36
|
+
crossterm`, lapisan provider pluggable, sistem tool dengan izin bertingkat, sesi
|
|
37
|
+
JSONL, daemon multi-klien via unix socket, dan protokol NDJSON bermigrasi
|
|
38
|
+
(`karsa-sdk`) — semua dirancang untuk lingkungan offline/self-hosted dengan
|
|
39
|
+
endpoint OpenAI-compatible apa pun.
|
|
40
|
+
|
|
41
|
+
Silahkan lihat dokumen lengkap spesifikasi di [`KARSA-BUILD.md`](KARSA-BUILD.md)
|
|
42
|
+
(= sumber kebenaran proyek & roadmap Fase 0–6).
|
|
43
|
+
|
|
44
|
+
## Fungsi utama
|
|
45
|
+
|
|
46
|
+
| Area | Fungsi |
|
|
47
|
+
|---|---|
|
|
48
|
+
| **TUI** | fullscreen (3 layout `zen/split/wide`, panel `TODO/FILES/PLAN/MCP`, mode status `rich/slim/off`), palette `/` dengan autocomplete, markdown render, Git/`vim` opsional (⚠ *stub*: `/keybinds`, `/vim`) |
|
|
49
|
+
| **Headless** | `karsa run "<prompt>"` (`-p`): `--output-format text\|json\|stream-json`, `--resume`, `--model/provider`, `--effort`, `--allowed-tools`, `--permission-mode` |
|
|
50
|
+
| **Provider** | lapisan pluggable `Provider`: kind `openai-compatible` (SSE toleran, retry 429/5xx, non-stream fallback), auth `env/file/command/none`, kind `mock` buat uji; wizard `/provider add` + CLI `provider add/test/use/list` |
|
|
51
|
+
| **Tool & izin** | 12 tool bawaan (`read_file`, `write_file`, `edit_file`, `multi_edit`, `patch`, `ls`, `glob`, `grep`, `run_cmd`, `todo_write`, `plan_submit`, `skill`), 4 mode izin (`ask/workspace-write/read-only/yolo`), risiko terklasifikasi (`safe/needs-approval/destructive`), path-guard workspace |
|
|
52
|
+
| **Hooks** | 5 mata acak (`session_start`, `user_prompt_submit`, `pre_tool_use`, `post_tool_use`, `stop`) via shell commands + `KARSA_TOOL`; exit 2 = blokir |
|
|
53
|
+
| **Sesi** | `~/.karsa/sessions/<id>.jsonl` + index `sessions.json`, `/resume`, `/fork`, `/export`, checkpoint & `/undo`, kompaksi otomatis per ambang konteks |
|
|
54
|
+
| **MCP** | klien MCP transport `stdio` + `http`, proxy menjadi tool `mcp__<server>__<tool>`, panel dan CLI `mcp add/list` |
|
|
55
|
+
| **Skill** | skill di `~/.karsa/skills/<n>/SKILL.md` — deskripsi masuk system prompt, isi dimuat lazy via tool `skill`; skill bawaan tersemat (feature `embed`) |
|
|
56
|
+
| **Daemon** | `karsa daemon start/stop/status` — server unix socket multi-klien, tiap klien = 1 agen ber-nama, turn paralel, pesan antar agen (DM/broadcast), jejak konflik file + lock ber-umur turn; TUI `/daemon status|attach <id>|detach` mengikuti file sesi dekat waktu nyata |
|
|
57
|
+
| **karsa-sdk** | protokol NDJSON versi 1 (`hello/ping/turn/stop/message/broadcast/sessions/swarm/bye`) + client async + `karsa sdk schema` |
|
|
58
|
+
| **Slash commands** | **68 perintah tepat terdaftar** (≥ 58 syarat §15.3) dengan metadata (alias, argumen, summary, help, scope); yang belum tersedia tampil `not-implemented` — tidak pernah senyap |
|
|
59
|
+
|
|
60
|
+
## Mulai cepat
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# bangun
|
|
64
|
+
cargo build --release -p karsa-cli
|
|
65
|
+
alias karsa='/home/ubuntu/Karsa/target/release/karsa' # sesuaikan jalur
|
|
66
|
+
|
|
67
|
+
# TUI
|
|
68
|
+
karsa
|
|
69
|
+
|
|
70
|
+
# headless
|
|
71
|
+
karsa run "jelaskan repo ini dengan singkat" -p # = karsa -p "..."
|
|
72
|
+
|
|
73
|
+
# endpoint mock lokal untuk uji tanpa API key
|
|
74
|
+
karsa provider add --name mock --kind openai-compatible \
|
|
75
|
+
--base-url http://127.0.0.1:8992/v1 --auth none --model mock-1
|
|
76
|
+
|
|
77
|
+
# daemon multi-sesi + klien socket
|
|
78
|
+
karsa daemon start
|
|
79
|
+
karsa sdk schema # protokol NDJSON lengkap
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Config di `KARSA_HOME` (default `$HOME`): `$KARSA_HOME/.karsa/config.toml`.
|
|
83
|
+
Preseden: **flag CLI > env `KARSA_*` > `.karsa/config.toml` proyek >
|
|
84
|
+
`~/.karsa/config.toml` global > default bawaan** (komentar file dipertahankan).
|
|
85
|
+
|
|
86
|
+
Rincian: [`PROVIDERS.md`](docs/PROVIDERS.md) ·
|
|
87
|
+
[`SLASH_COMMANDS.md`](docs/SLASH_COMMANDS.md) · [`THEME.md`](docs/THEME.md) ·
|
|
88
|
+
[`LAYOUT.md`](docs/LAYOUT.md) · [`SECURITY.md`](docs/SECURITY.md) ·
|
|
89
|
+
dokumen self-dev: [`KARSA.md`](KARSA.md).
|
|
90
|
+
|
|
91
|
+
## CLI
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
karsa # TUI (default)
|
|
95
|
+
karsa run|run -p "..." # headless satu shot
|
|
96
|
+
karsa config get|set|list|edit|path
|
|
97
|
+
karsa provider list|add|... # kelola endpoint
|
|
98
|
+
karsa sessions list|show|resume|rm
|
|
99
|
+
karsa doctor [--deep] # ⚠ --deep diparse tapi belum menambah cek
|
|
100
|
+
karsa mcp list|add|...
|
|
101
|
+
karsa skills | context | plan <prompt>
|
|
102
|
+
karsa sdk schema # skema protokol NDJSON
|
|
103
|
+
karsa daemon start|stop|status
|
|
104
|
+
karsa completions <shell>
|
|
105
|
+
karsa about / --help
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
## Arsitektur (17 crate)
|
|
110
|
+
|
|
111
|
+
| Crate | Tanggung jawab |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `karsa-theme` | satu-satunya sumber warna: 24 token semantik, deteksi profil terminal, tema `\*.toml` |
|
|
114
|
+
| `karsa-config` | schema config + loader berlapis + editor TOML aman-komentar |
|
|
115
|
+
| `karsa-slash` | parser/registry/palette/dispatch slash (§15) |
|
|
116
|
+
| `karsa-security` | mode izin, path guard, risiko, klasisifikasi, authorizer |
|
|
117
|
+
| `karsa-tools` | trait `Tool`, `ToolCtx`, registry + laporan tool bawaan, hook runner, skill lazy |
|
|
118
|
+
| `karsa-core` | loop agent, mesin turn, komposer konteks, hitung token (§8) |
|
|
119
|
+
| `karsa-provider-core` | tipe inti provider: pesan/tool/event streaming/`WireApi`/`CancelToken` |
|
|
120
|
+
| `karsa-provider-compat` | generik `openai-compatible` + parser SSE toleran + retry + `MockProvider` |
|
|
121
|
+
| `karsa-provider-anthropic` / `-ollama` / `-openai` | kerangka provider native (belum dirute broker; stub saat ini) |
|
|
122
|
+
| `karsa-mcp` | klien MCP `stdio` + `http`, proxy ke `mcp__<server>__<tool>` |
|
|
123
|
+
| `karsa-store` | sesi JSONL + `sessions.json` + ekspor markdown |
|
|
124
|
+
| `karsa-git` | helper git via subprocess (ringan, §4.2) |
|
|
125
|
+
| `karsa-tui` | aplikasi `ratatui`: state, renderer, markdown-lite, input |
|
|
126
|
+
| `karsa-sdk` | protokol NDJSON + `KarsaClient` async (§17) |
|
|
127
|
+
| `karsa-cli` | binary: `engine` (rakit agent bersama run/daemon), `run`, `tui_cmd`, `daemon`, `doctor`, dispatch |
|
|
128
|
+
|
|
129
|
+
### Deteksi daemon (§17)
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
[klien karsa / klien extern] --unix-- \(daemon.sock) karsa daemon-server
|
|
133
|
+
├─ 1 klien = 1 agen (rename via hello)
|
|
134
|
+
├─ turn paralel per koneksi (id balasan = id permintaan)
|
|
135
|
+
├─ agent_message / broadcast → swarm_note (id 0)
|
|
136
|
+
└─ jejak akses file → swarm_conflict + lock .karsa/locks/
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Angka terukur (binary `release`; diukur nyata, bukan karangan)
|
|
140
|
+
|
|
141
|
+
| Metrik | Syarat (§21) | Hasil |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| First frame TUI | < 30 ms | **13,7 ms** (debug 10–34 ms) |
|
|
144
|
+
| RSS idle | < 40 MB | **6,3 MB** (debug 17,4 MB) |
|
|
145
|
+
| Ukuran binary | < 20 MB | **4,2 MB** (`opt-level="z"` + LTO + strip) |
|
|
146
|
+
| `cargo tree` runtime | < 350 crates | **185** crates unik |
|
|
147
|
+
| Test workspace | hijau | **143 pass / 0 fail** |
|
|
148
|
+
| fmt + clippy | bersih | 0 temuan |
|
|
149
|
+
|
|
150
|
+
## Uji & gerbang
|
|
151
|
+
|
|
152
|
+
Unit = Rust (`cargo test`); integrasi = provider `mock` (server SSE/file lokal
|
|
153
|
+
`/tmp/opencode/mock-openai.py`, mode `normal/tool/mcp/compact/dm`); gerbang pty =
|
|
154
|
+
simulasi terminal via `pyte`, menguji TUI ujung-ke-ujung (wizard, extensi, MCP, daemon,
|
|
155
|
+
swarm, `/swarm`). Semua hijau selangkah per milestone — hasil terakhir:
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
gate-dmn 23/23 · gate-swarm 17/17 · pty-swm 1/1
|
|
159
|
+
pty-wiz 9/9 · pty-ext 10/10 · pty-mcp 8/8
|
|
160
|
+
cargo test --workspace: 143 pass / 0 fail
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Yang masih kurang
|
|
164
|
+
|
|
165
|
+
Kejujuran (hasil audit DoD hari ini, detail di `KARSA-BUILD.md` §21):
|
|
166
|
+
|
|
167
|
+
- **Gate #9 docs** — ✅ dicatat (dokumen set ini).
|
|
168
|
+
- **Gate #2 provider** — ◐ lulus sebagian: 2 endpoint terbukti di gerbang (mock +
|
|
169
|
+
self-hosted), tapi **hanya 1 kind nyata**: `openai-compatible`. Kind
|
|
170
|
+
`anthropic` / `ollama` di broker masih `NotImplementedProvider` (stub yang
|
|
171
|
+
beri pesan jelas); crate `karsa-provider-{anthropic,ollama,openai}` ada
|
|
172
|
+
tapi belum dirutekan. `providers test` tersedia.
|
|
173
|
+
- **Gate #8 benchmark di README** — ✅ setelah dokumen ini; tapi **CI benchmark**
|
|
174
|
+
(blokir regresi 10%) sentinel belum diadopsi.
|
|
175
|
+
- **`/doctor --deep`** — ⚠ flag CLI diparser tapi belum menambah cek (diabaikan).
|
|
176
|
+
- **Pendudukan / replay TUI** — tangkapan teks nyata di dokumen ini;
|
|
177
|
+
**screenshot/asciinema grafis** belum.
|
|
178
|
+
- **Snapshot TUI (`TestBackend` golden)** + **fuzz SSE/prompt-injection** (§20) — belum ada.
|
|
179
|
+
- **Event daemon**: `TurnStart/TurnEnd/State/Compact` belum dikirim lewat protokol
|
|
180
|
+
(dokumentasi parity di commit `feat(daemon)`); manajer MCP hangat per-daemon
|
|
181
|
+
belum. ✅ **`/daemon status|attach|detach` di TUI** sudah nyata — attach mengikuti
|
|
182
|
+
file sesi JSONL (hanya-baca, per-socket event tidak dipancarkan antar-klien);
|
|
183
|
+
memakai turn sesi orang lain menunggu request `subscribe` protokol.
|
|
184
|
+
- **Mode izenhaks**: `write_file` di daemon mematuhi mode config; default `ask`
|
|
185
|
+
menolak headless (pesan: `mode ask — headless tak bisa tanya`).
|
|
186
|
+
- **`/bench`, self-dev mode, audit alokasi/cap RSS** — belum dibuat.
|
|
187
|
+
- ✅ **self-update `karsa update`** sudah nyata (cek `--check` + pasang
|
|
188
|
+
atomik; kontrak sumber di `update.rs`; gerbang `gate-update` 9/9).
|
|
189
|
+
- **`karsa update`** stub (cetak pesan).
|
|
190
|
+
- **Slash stub**: masih ada beberapa perintah di registry dgn `Handler::Stub`
|
|
191
|
+
(lihat dokumen `SLASH_COMMANDS.md` untuk daftar tak-silent).
|
|
192
|
+
|
|
193
|
+
## Struktur proyek
|
|
194
|
+
|
|
195
|
+
```text
|
|
196
|
+
Cargo.toml # workspace; profile release z/lto/strip
|
|
197
|
+
KARSA-BUILD.md # spesifikasi build + roadmap Fase 0–6 + DoD
|
|
198
|
+
KARSA.md # arsitektur self-dev (untuk introspeksi Karsa sendiri)
|
|
199
|
+
README.md # dokumen ini
|
|
200
|
+
docs/ # PROVIDERS · SLASH_COMMANDS · THEME · LAYOUT · SECURITY
|
|
201
|
+
crates/ # 17 crate — lihat tabel Arsitektur
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Lisensi & kredit
|
|
205
|
+
|
|
206
|
+
MIT (file [`LICENSE`](LICENSE)). Desain terinspirasi
|
|
207
|
+
**jcode** (1jehuang, https://github.com/1jehuang/jcode) — kredit di `/about`.
|
|
208
|
+
UI default **Bahasa Indonesia** (`[ui] language = "id"`, fallback `en`).
|
package/bin/karsa.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { execSync } = require('child_process');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
|
|
7
|
+
const platform = os.platform();
|
|
8
|
+
const arch = os.arch();
|
|
9
|
+
|
|
10
|
+
let binaryName = 'karsa';
|
|
11
|
+
if (platform === 'win32') {
|
|
12
|
+
binaryName += '.exe';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Determine the directory where this script resides
|
|
16
|
+
const __dirname = path.dirname(process.mainModule.filename);
|
|
17
|
+
const binaryPath = path.join(__dirname, '..', binaryName);
|
|
18
|
+
|
|
19
|
+
// If the binary exists next to the script (in the package root), run it
|
|
20
|
+
if (fs.existsSync(binaryPath)) {
|
|
21
|
+
try {
|
|
22
|
+
execSync(`"${binaryPath}" ${process.argv.slice(2).join(' ')}`, { stdio: 'inherit' });
|
|
23
|
+
} catch (e) {
|
|
24
|
+
process.exit(e.code);
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
// Fallback: try to run from PATH (in case user installed globally via other means)
|
|
28
|
+
try {
|
|
29
|
+
execSync(`${binaryName} ${process.argv.slice(2).join(' ')}`, { stdio: 'inherit' });
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.error(`Karsa binary not found. Please install it via cargo install karsa-cli or download a release from GitHub.`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
package/karsa
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ywldan/karsa",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Karsa - Rust agentic coding CLI",
|
|
5
|
+
"bin": {
|
|
6
|
+
"karsa": "./bin/karsa.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"README.md",
|
|
11
|
+
"karsa"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/ywildan/karsa-cli-landing.git"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"cli",
|
|
22
|
+
"coding",
|
|
23
|
+
"agent",
|
|
24
|
+
"rust",
|
|
25
|
+
"terminal"
|
|
26
|
+
],
|
|
27
|
+
"author": "Karsa contributors",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/ywildan/karsa-cli-landing/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/ywildan/karsa-cli-landing#readme"
|
|
33
|
+
}
|