@kmugalkhod/lightcode 0.7.1 → 0.8.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 CHANGED
@@ -1,119 +1,119 @@
1
- # Lightcode
2
-
3
- A personal AI coding agent with a terminal UI. Lightcode pairs an OpenTUI
4
- chat interface with a local Hono API server, persistent SQLite sessions, a
5
- permission-gated tool suite (files, shell, git, web, MCP), and tiered context
6
- optimization that keeps long sessions inside the model's context window
7
- without ever losing history.
8
-
9
- ## Install
10
-
11
- ```bash
12
- npm install -g @kmugalkhod/lightcode
13
- lightcode
14
- ```
15
-
16
- Works on macOS (Apple Silicon and Intel), Linux, and Windows. Bun ships with
17
- the package, so there's nothing else to install — the first `lightcode` run
18
- uses the bundled runtime automatically (and reuses a system Bun if you already
19
- have one). The published package is scoped as `@kmugalkhod/lightcode`; the
20
- command it installs is `lightcode`.
21
-
22
- ## Quick start (from source)
23
-
24
- ```bash
25
- bun install
26
- bun run cli:dev # starts the TUI; it boots the server automatically
27
- ```
28
-
29
- Lightcode is aware of the directory you launch it in: each turn it reads the
30
- project's shape (top-level files, git branch/status) and any `AGENTS.md` /
31
- `CLAUDE.md` / `README.md`, so "review my code" or "explain this" inspects your
32
- actual files instead of asking you to paste them.
33
-
34
- On first run Lightcode walks you through provider setup (Anthropic,
35
- OpenRouter, OpenCode Zen, or any OpenAI-compatible endpoint) and stores the
36
- API key in `~/.lightcode/credentials.json`. Environment variables such as
37
- `ANTHROPIC_API_KEY` always take precedence.
38
-
39
- ## Commands
40
-
41
- ```bash
42
- bun run cli:dev # TUI (auto-starts the server)
43
- bun run server:dev # API server alone, watch mode
44
- bun run typecheck # TypeScript + tool schema preflight
45
- bun test # test suite
46
- bun run build # build the publishable package into dist/
47
- bun run release # verify + build + npm pack (--publish to release)
48
- ```
49
-
50
- ## Configuration
51
-
52
- Settings merge from `~/.lightcode/settings.json`, then
53
- `.lightcode/settings.json` in the project, then `LIGHTCODE_*` environment
54
- variables. Notable keys:
55
-
56
- | Key | Purpose |
57
- | --- | --- |
58
- | `provider`, `model`, `baseUrl` | Provider selection and model id |
59
- | `defaultMode` | `build` or `plan` |
60
- | `permissionMode`, `permissions` | Tool permission policy |
61
- | `context.compactAtFraction` | Context compaction threshold (default 0.8) |
62
- | `context.pruneAtFraction` | Tool-output pruning threshold (default 0.6) |
63
- | `context.contextWindowOverride` | Override the model context window |
64
- | `maxRetries` | Provider-call retries for transient errors (default 5) |
65
- | `autoContinue.stallTimeoutSeconds` | Abort+retry a byte-silent stream (default 300; raise for very slow reasoning models) |
66
- | `autoContinue.maxErrorRetries` | Auto-resends before surfacing a stream error (default 8) |
67
-
68
- The local companion server listens on `127.0.0.1:4983` (uncommon on purpose —
69
- port 3000 belongs to the apps you build). Override with `PORT` for the server
70
- and `LIGHTCODE_API_URL` for the CLI. Runtime model switching: `/model` in the
71
- TUI lists every OpenRouter model and persists the choice to
72
- `~/.lightcode/settings.json`. Diagnostics: `GET /diagnostics/connectivity`
73
- probes the provider endpoint, and daily JSONL logs live under the Lightcode
74
- data directory (`logs/`).
75
-
76
- ## Context optimization
77
-
78
- Long sessions stay healthy through three tiers: real-usage-calibrated token
79
- estimation, free pruning of stale tool outputs and duplicate file reads, and
80
- LLM-written summaries once the compaction threshold is crossed (with an
81
- extractive fallback when the model is unreachable). The full conversation is
82
- always preserved in SQLite — compaction only changes what the model sees.
83
- Use `/compact` in a chat to compact manually.
84
-
85
- ## Skills
86
-
87
- Skills are reusable instruction files the agent can load on demand — a recipe
88
- for a recurring task (writing a PR description, cutting a release, following a
89
- review checklist). Each skill is a `SKILL.md` file with frontmatter:
90
-
91
- ```markdown
92
- ---
93
- name: pr-description
94
- description: Write a clear PR title and description from the diff.
95
- ---
96
-
97
- # Instructions the agent follows when this skill is loaded…
98
- ```
99
-
100
- Lightcode discovers skills from three locations, first match wins (project
101
- overrides user):
102
-
103
- 1. `.lightcode/skills/<name>/SKILL.md` — project-local
104
- 2. `.agents/skills/<name>/SKILL.md` — project-local (fallback)
105
- 3. `~/.lightcode/skills/<name>/SKILL.md` — available in every project
106
-
107
- Each turn the agent is told which skills are available (name + description), so
108
- just ask it to "use the pr-description skill" (or mention the skill by name) and
109
- it loads the instructions via the `skill` tool and follows them. Run `/skills`
110
- in the TUI to list what's installed. Only simple `key: value` frontmatter lines
111
- are parsed (`name`, `description`); the rest of the file is the instruction body.
112
-
113
- ## Workspaces
114
-
115
- - `apps/cli` — OpenTUI React terminal interface
116
- - `apps/server` — Hono API server (sessions, streaming, diagnostics)
117
- - `packages/ai` — agent core: tools, permissions, context engine, config
118
- - `packages/db` — Prisma + local SQLite storage
119
- - `packages/shared` — logging, errors, version
1
+ # Lightcode
2
+
3
+ A personal AI coding agent with a terminal UI. Lightcode pairs an OpenTUI
4
+ chat interface with a local Hono API server, persistent SQLite sessions, a
5
+ permission-gated tool suite (files, shell, git, web, MCP), and tiered context
6
+ optimization that keeps long sessions inside the model's context window
7
+ without ever losing history.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g @kmugalkhod/lightcode
13
+ lightcode
14
+ ```
15
+
16
+ Works on macOS (Apple Silicon and Intel), Linux, and Windows. Bun ships with
17
+ the package, so there's nothing else to install — the first `lightcode` run
18
+ uses the bundled runtime automatically (and reuses a system Bun if you already
19
+ have one). The published package is scoped as `@kmugalkhod/lightcode`; the
20
+ command it installs is `lightcode`.
21
+
22
+ ## Quick start (from source)
23
+
24
+ ```bash
25
+ bun install
26
+ bun run cli:dev # starts the TUI; it boots the server automatically
27
+ ```
28
+
29
+ Lightcode is aware of the directory you launch it in: each turn it reads the
30
+ project's shape (top-level files, git branch/status) and any `AGENTS.md` /
31
+ `CLAUDE.md` / `README.md`, so "review my code" or "explain this" inspects your
32
+ actual files instead of asking you to paste them.
33
+
34
+ On first run Lightcode walks you through provider setup (Anthropic,
35
+ OpenRouter, OpenCode Zen, or any OpenAI-compatible endpoint) and stores the
36
+ API key in `~/.lightcode/credentials.json`. Environment variables such as
37
+ `ANTHROPIC_API_KEY` always take precedence.
38
+
39
+ ## Commands
40
+
41
+ ```bash
42
+ bun run cli:dev # TUI (auto-starts the server)
43
+ bun run server:dev # API server alone, watch mode
44
+ bun run typecheck # TypeScript + tool schema preflight
45
+ bun test # test suite
46
+ bun run build # build the publishable package into dist/
47
+ bun run release # verify + build + npm pack (--publish to release)
48
+ ```
49
+
50
+ ## Configuration
51
+
52
+ Settings merge from `~/.lightcode/settings.json`, then
53
+ `.lightcode/settings.json` in the project, then `LIGHTCODE_*` environment
54
+ variables. Notable keys:
55
+
56
+ | Key | Purpose |
57
+ | --- | --- |
58
+ | `provider`, `model`, `baseUrl` | Provider selection and model id |
59
+ | `defaultMode` | `build` or `plan` |
60
+ | `permissionMode`, `permissions` | Tool permission policy |
61
+ | `context.compactAtFraction` | Context compaction threshold (default 0.8) |
62
+ | `context.pruneAtFraction` | Tool-output pruning threshold (default 0.6) |
63
+ | `context.contextWindowOverride` | Override the model context window |
64
+ | `maxRetries` | Provider-call retries for transient errors (default 5) |
65
+ | `autoContinue.stallTimeoutSeconds` | Abort+retry a byte-silent stream (default 300; raise for very slow reasoning models) |
66
+ | `autoContinue.maxErrorRetries` | Auto-resends before surfacing a stream error (default 8) |
67
+
68
+ The local companion server listens on `127.0.0.1:4983` (uncommon on purpose —
69
+ port 3000 belongs to the apps you build). Override with `PORT` for the server
70
+ and `LIGHTCODE_API_URL` for the CLI. Runtime model switching: `/model` in the
71
+ TUI lists every OpenRouter model and persists the choice to
72
+ `~/.lightcode/settings.json`. Diagnostics: `GET /diagnostics/connectivity`
73
+ probes the provider endpoint, and daily JSONL logs live under the Lightcode
74
+ data directory (`logs/`).
75
+
76
+ ## Context optimization
77
+
78
+ Long sessions stay healthy through three tiers: real-usage-calibrated token
79
+ estimation, free pruning of stale tool outputs and duplicate file reads, and
80
+ LLM-written summaries once the compaction threshold is crossed (with an
81
+ extractive fallback when the model is unreachable). The full conversation is
82
+ always preserved in SQLite — compaction only changes what the model sees.
83
+ Use `/compact` in a chat to compact manually.
84
+
85
+ ## Skills
86
+
87
+ Skills are reusable instruction files the agent can load on demand — a recipe
88
+ for a recurring task (writing a PR description, cutting a release, following a
89
+ review checklist). Each skill is a `SKILL.md` file with frontmatter:
90
+
91
+ ```markdown
92
+ ---
93
+ name: pr-description
94
+ description: Write a clear PR title and description from the diff.
95
+ ---
96
+
97
+ # Instructions the agent follows when this skill is loaded…
98
+ ```
99
+
100
+ Lightcode discovers skills from three locations, first match wins (project
101
+ overrides user):
102
+
103
+ 1. `.lightcode/skills/<name>/SKILL.md` — project-local
104
+ 2. `.agents/skills/<name>/SKILL.md` — project-local (fallback)
105
+ 3. `~/.lightcode/skills/<name>/SKILL.md` — available in every project
106
+
107
+ Each turn the agent is told which skills are available (name + description), so
108
+ just ask it to "use the pr-description skill" (or mention the skill by name) and
109
+ it loads the instructions via the `skill` tool and follows them. Run `/skills`
110
+ in the TUI to list what's installed. Only simple `key: value` frontmatter lines
111
+ are parsed (`name`, `description`); the rest of the file is the instruction body.
112
+
113
+ ## Workspaces
114
+
115
+ - `apps/cli` — OpenTUI React terminal interface
116
+ - `apps/server` — Hono API server (sessions, streaming, diagnostics)
117
+ - `packages/ai` — agent core: tools, permissions, context engine, config
118
+ - `packages/db` — Prisma + local SQLite storage
119
+ - `packages/shared` — logging, errors, version
@@ -0,0 +1,341 @@
1
+ ; Lower priority to prefer @variable.parameter when identifier appears in parameter_declaration.
2
+ ((identifier) @variable
3
+ (#set! priority 95))
4
+
5
+ (preproc_def
6
+ (preproc_arg) @variable)
7
+
8
+ [
9
+ "default"
10
+ "goto"
11
+ "asm"
12
+ "__asm__"
13
+ ] @keyword
14
+
15
+ [
16
+ "enum"
17
+ "struct"
18
+ "union"
19
+ "typedef"
20
+ ] @keyword.type
21
+
22
+ [
23
+ "sizeof"
24
+ "offsetof"
25
+ ] @keyword.operator
26
+
27
+ (alignof_expression
28
+ .
29
+ _ @keyword.operator)
30
+
31
+ "return" @keyword.return
32
+
33
+ [
34
+ "while"
35
+ "for"
36
+ "do"
37
+ "continue"
38
+ "break"
39
+ ] @keyword.repeat
40
+
41
+ [
42
+ "if"
43
+ "else"
44
+ "case"
45
+ "switch"
46
+ ] @keyword.conditional
47
+
48
+ [
49
+ "#if"
50
+ "#ifdef"
51
+ "#ifndef"
52
+ "#else"
53
+ "#elif"
54
+ "#endif"
55
+ "#elifdef"
56
+ "#elifndef"
57
+ (preproc_directive)
58
+ ] @keyword.directive
59
+
60
+ "#define" @keyword.directive.define
61
+
62
+ "#include" @keyword.import
63
+
64
+ [
65
+ ";"
66
+ ":"
67
+ ","
68
+ "."
69
+ "::"
70
+ ] @punctuation.delimiter
71
+
72
+ "..." @punctuation.special
73
+
74
+ [
75
+ "("
76
+ ")"
77
+ "["
78
+ "]"
79
+ "{"
80
+ "}"
81
+ ] @punctuation.bracket
82
+
83
+ [
84
+ "="
85
+ "-"
86
+ "*"
87
+ "/"
88
+ "+"
89
+ "%"
90
+ "~"
91
+ "|"
92
+ "&"
93
+ "^"
94
+ "<<"
95
+ ">>"
96
+ "->"
97
+ "<"
98
+ "<="
99
+ ">="
100
+ ">"
101
+ "=="
102
+ "!="
103
+ "!"
104
+ "&&"
105
+ "||"
106
+ "-="
107
+ "+="
108
+ "*="
109
+ "/="
110
+ "%="
111
+ "|="
112
+ "&="
113
+ "^="
114
+ ">>="
115
+ "<<="
116
+ "--"
117
+ "++"
118
+ ] @operator
119
+
120
+ ; Make sure the comma operator is given a highlight group after the comma
121
+ ; punctuator so the operator is highlighted properly.
122
+ (comma_expression
123
+ "," @operator)
124
+
125
+ [
126
+ (true)
127
+ (false)
128
+ ] @boolean
129
+
130
+ (conditional_expression
131
+ [
132
+ "?"
133
+ ":"
134
+ ] @keyword.conditional.ternary)
135
+
136
+ (string_literal) @string
137
+
138
+ (system_lib_string) @string
139
+
140
+ (escape_sequence) @string.escape
141
+
142
+ (null) @constant.builtin
143
+
144
+ (number_literal) @number
145
+
146
+ (char_literal) @character
147
+
148
+ (preproc_defined) @function.macro
149
+
150
+ ((field_expression
151
+ (field_identifier) @property) @_parent
152
+ (#not-has-parent? @_parent template_method function_declarator call_expression))
153
+
154
+ (field_designator) @property
155
+
156
+ ((field_identifier) @property
157
+ (#has-ancestor? @property field_declaration)
158
+ (#not-has-ancestor? @property function_declarator))
159
+
160
+ (statement_identifier) @label
161
+
162
+ (declaration
163
+ type: (type_identifier) @_type
164
+ declarator: (identifier) @label
165
+ (#eq? @_type "__label__"))
166
+
167
+ [
168
+ (type_identifier)
169
+ (type_descriptor)
170
+ ] @type
171
+
172
+ (storage_class_specifier) @keyword.modifier
173
+
174
+ [
175
+ (type_qualifier)
176
+ (gnu_asm_qualifier)
177
+ "__extension__"
178
+ ] @keyword.modifier
179
+
180
+ (linkage_specification
181
+ "extern" @keyword.modifier)
182
+
183
+ (type_definition
184
+ declarator: (type_identifier) @type.definition)
185
+
186
+ (primitive_type) @type.builtin
187
+
188
+ (sized_type_specifier
189
+ _ @type.builtin
190
+ type: _?)
191
+
192
+ ((identifier) @constant
193
+ (#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
194
+
195
+ (preproc_def
196
+ (preproc_arg) @constant
197
+ (#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
198
+
199
+ (enumerator
200
+ name: (identifier) @constant)
201
+
202
+ (case_statement
203
+ value: (identifier) @constant)
204
+
205
+ ((identifier) @constant.builtin
206
+ ; format-ignore
207
+ (#any-of? @constant.builtin
208
+ "stderr" "stdin" "stdout"
209
+ "__FILE__" "__LINE__" "__DATE__" "__TIME__"
210
+ "__STDC__" "__STDC_VERSION__" "__STDC_HOSTED__"
211
+ "__cplusplus" "__OBJC__" "__ASSEMBLER__"
212
+ "__BASE_FILE__" "__FILE_NAME__" "__INCLUDE_LEVEL__"
213
+ "__TIMESTAMP__" "__clang__" "__clang_major__"
214
+ "__clang_minor__" "__clang_patchlevel__"
215
+ "__clang_version__" "__clang_literal_encoding__"
216
+ "__clang_wide_literal_encoding__"
217
+ "__FUNCTION__" "__func__" "__PRETTY_FUNCTION__"
218
+ "__VA_ARGS__" "__VA_OPT__"))
219
+
220
+ (preproc_def
221
+ (preproc_arg) @constant.builtin
222
+ ; format-ignore
223
+ (#any-of? @constant.builtin
224
+ "stderr" "stdin" "stdout"
225
+ "__FILE__" "__LINE__" "__DATE__" "__TIME__"
226
+ "__STDC__" "__STDC_VERSION__" "__STDC_HOSTED__"
227
+ "__cplusplus" "__OBJC__" "__ASSEMBLER__"
228
+ "__BASE_FILE__" "__FILE_NAME__" "__INCLUDE_LEVEL__"
229
+ "__TIMESTAMP__" "__clang__" "__clang_major__"
230
+ "__clang_minor__" "__clang_patchlevel__"
231
+ "__clang_version__" "__clang_literal_encoding__"
232
+ "__clang_wide_literal_encoding__"
233
+ "__FUNCTION__" "__func__" "__PRETTY_FUNCTION__"
234
+ "__VA_ARGS__" "__VA_OPT__"))
235
+
236
+ (attribute_specifier
237
+ (argument_list
238
+ (identifier) @variable.builtin))
239
+
240
+ (attribute_specifier
241
+ (argument_list
242
+ (call_expression
243
+ function: (identifier) @variable.builtin)))
244
+
245
+ ((call_expression
246
+ function: (identifier) @function.builtin)
247
+ (#lua-match? @function.builtin "^__builtin_"))
248
+
249
+ ((call_expression
250
+ function: (identifier) @function.builtin)
251
+ (#has-ancestor? @function.builtin attribute_specifier))
252
+
253
+ ; Preproc def / undef
254
+ (preproc_def
255
+ name: (_) @constant.macro)
256
+
257
+ (preproc_call
258
+ directive: (preproc_directive) @_u
259
+ argument: (_) @constant.macro
260
+ (#eq? @_u "#undef"))
261
+
262
+ (preproc_ifdef
263
+ name: (identifier) @constant.macro)
264
+
265
+ (preproc_elifdef
266
+ name: (identifier) @constant.macro)
267
+
268
+ (preproc_defined
269
+ (identifier) @constant.macro)
270
+
271
+ (call_expression
272
+ function: (identifier) @function.call)
273
+
274
+ (call_expression
275
+ function: (field_expression
276
+ field: (field_identifier) @function.call))
277
+
278
+ (function_declarator
279
+ declarator: (identifier) @function)
280
+
281
+ (function_declarator
282
+ declarator: (parenthesized_declarator
283
+ (pointer_declarator
284
+ declarator: (field_identifier) @function)))
285
+
286
+ (preproc_function_def
287
+ name: (identifier) @function.macro)
288
+
289
+ (comment) @comment @spell
290
+
291
+ ((comment) @comment.documentation
292
+ (#lua-match? @comment.documentation "^/[*][*][^*].*[*]/$"))
293
+
294
+ ; Parameters
295
+ (parameter_declaration
296
+ declarator: (identifier) @variable.parameter)
297
+
298
+ (parameter_declaration
299
+ declarator: (array_declarator) @variable.parameter)
300
+
301
+ (parameter_declaration
302
+ declarator: (pointer_declarator) @variable.parameter)
303
+
304
+ ; K&R functions
305
+ ; To enable support for K&R functions,
306
+ ; add the following lines to your own query config and uncomment them.
307
+ ; They are commented out as they'll conflict with C++
308
+ ; Note that you'll need to have `; extends` at the top of your query file.
309
+ ;
310
+ ; (parameter_list (identifier) @variable.parameter)
311
+ ;
312
+ ; (function_definition
313
+ ; declarator: _
314
+ ; (declaration
315
+ ; declarator: (identifier) @variable.parameter))
316
+ ;
317
+ ; (function_definition
318
+ ; declarator: _
319
+ ; (declaration
320
+ ; declarator: (array_declarator) @variable.parameter))
321
+ ;
322
+ ; (function_definition
323
+ ; declarator: _
324
+ ; (declaration
325
+ ; declarator: (pointer_declarator) @variable.parameter))
326
+ (preproc_params
327
+ (identifier) @variable.parameter)
328
+
329
+ [
330
+ "__attribute__"
331
+ "__declspec"
332
+ "__based"
333
+ "__cdecl"
334
+ "__clrcall"
335
+ "__stdcall"
336
+ "__fastcall"
337
+ "__thiscall"
338
+ "__vectorcall"
339
+ (ms_pointer_modifier)
340
+ (attribute_declaration)
341
+ ] @attribute
@@ -0,0 +1,74 @@
1
+ ; Functions
2
+
3
+ (call_expression
4
+ function: (qualified_identifier
5
+ name: (identifier) @function))
6
+
7
+ (template_function
8
+ name: (identifier) @function)
9
+
10
+ (template_method
11
+ name: (field_identifier) @function)
12
+
13
+ (template_function
14
+ name: (identifier) @function)
15
+
16
+ (function_declarator
17
+ declarator: (qualified_identifier
18
+ name: (identifier) @function))
19
+
20
+ (function_declarator
21
+ declarator: (qualified_identifier
22
+ name: (identifier) @function))
23
+
24
+ (function_declarator
25
+ declarator: (field_identifier) @function)
26
+
27
+ ; Types
28
+
29
+ ((namespace_identifier) @type
30
+ (#match? @type "^[A-Z]"))
31
+
32
+ (auto) @type
33
+
34
+ ; Constants
35
+
36
+ (this) @variable.builtin
37
+ (null "nullptr" @constant)
38
+
39
+ ; Keywords
40
+
41
+ [
42
+ "catch"
43
+ "class"
44
+ "co_await"
45
+ "co_return"
46
+ "co_yield"
47
+ "constexpr"
48
+ "constinit"
49
+ "consteval"
50
+ "delete"
51
+ "explicit"
52
+ "final"
53
+ "friend"
54
+ "mutable"
55
+ "namespace"
56
+ "noexcept"
57
+ "new"
58
+ "override"
59
+ "private"
60
+ "protected"
61
+ "public"
62
+ "template"
63
+ "throw"
64
+ "try"
65
+ "typename"
66
+ "using"
67
+ "virtual"
68
+ "concept"
69
+ "requires"
70
+ ] @keyword
71
+
72
+ ; Strings
73
+
74
+ (raw_string_literal) @string