@skein-code/cli 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mosaic Code 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 ADDED
@@ -0,0 +1,462 @@
1
+ # Skein
2
+
3
+ **An open, context-first coding agent for the terminal.**
4
+
5
+ Skein understands the change surface before it edits, exposes every tool call,
6
+ and keeps sessions and pre-write checkpoints on your machine. It supports
7
+ OpenAI, Anthropic, Gemini, and OpenAI-compatible endpoints, with
8
+ [ContextEngine-plugin](https://github.com/lixiang12345/ContextEngine-plugin) as
9
+ an optional high-quality retrieval layer and a built-in local index as the
10
+ zero-service fallback.
11
+
12
+ ```text
13
+ ◆ SKEIN · ~/work/api ● BUILD
14
+ anthropic/claude-sonnet-4-5 · context auto · memory on · agents 3
15
+
16
+ › Find the webhook retry bug and add a regression test.
17
+ ◇ context contextengine · 12 spans · ~8.4k
18
+ · prompt/debug intent:debug · working-memory · code:contextengine
19
+ ✓ read_file src/billing/webhook.ts 31ms
20
+ ✓ apply_patch src/billing/webhook.ts 18ms
21
+
22
+ ◆ Skein
23
+ The retry timestamp was advanced before the failed attempt was persisted.
24
+ I moved the update after persistence and added the timeout regression test.
25
+
26
+ ────────────────────────────────────────────────────────────────────
27
+ › ask anything…
28
+ Type a request · @file · /command
29
+
30
+ ● ready · ctx 18% · 14.2k tokens · 2 changed graphite · /help
31
+ ```
32
+
33
+ ## Why Skein
34
+
35
+ - **Open automation:** text, quiet, JSON, and JSONL event modes are core
36
+ features, suitable for local scripts and CI.
37
+ - **Model ownership:** use four provider families without changing the agent or
38
+ session format.
39
+ - **Retrieval you control:** select ContextEngine for hybrid
40
+ FTS/symbol/vector/graph retrieval, or run the local BM25/path/symbol index.
41
+ - **Visible trust:** per-category permissions, deny rules, hooks, workspace path
42
+ enforcement, changed-file telemetry, and persisted tool results.
43
+ - **Reversible work:** Skein snapshots affected files before mutation without
44
+ touching your Git history.
45
+ - **Resumable by default:** conversations, tasks, usage, and changed files live
46
+ in project-local session files.
47
+ - **Layered agent runtime:** progressive Skills, MCP tools, typed workflows,
48
+ isolated read-only experts, working memory, compacted session state, and
49
+ reviewed durable memory share one permission and audit model.
50
+
51
+ The product rationale and competitor research are in
52
+ [docs/PRODUCT.md](docs/PRODUCT.md); the implementation model is in
53
+ [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
54
+
55
+ ## Requirements
56
+
57
+ - Node.js 22.16 or newer
58
+ - A model API key, or an OpenAI-compatible local endpoint
59
+ - Optional: Git and ripgrep
60
+ - Optional: ContextEngine-plugin plus PostgreSQL/pgvector
61
+
62
+ ## Install
63
+
64
+ From this repository:
65
+
66
+ ```bash
67
+ npm install
68
+ npm run build
69
+ npm link
70
+ ```
71
+
72
+ To install the packaged artifact included with this checkout:
73
+
74
+ ```bash
75
+ npm install -g ./skein-code-cli-0.2.0.tgz
76
+ ```
77
+
78
+ After the public package is published, install it from the registry with:
79
+
80
+ ```bash
81
+ npm install -g @skein-code/cli
82
+ ```
83
+
84
+ `skein` is the primary command. Existing installations can continue using
85
+ `mosaic` or `mosaic-code`; the `.mosaic/` project state and `MOSAIC_*`
86
+ environment variables remain compatible with this release.
87
+
88
+ ## Quick start
89
+
90
+ Set credentials for one provider:
91
+
92
+ ```bash
93
+ export OPENAI_API_KEY=...
94
+ # or ANTHROPIC_API_KEY / GEMINI_API_KEY / SKEIN_API_KEY
95
+ ```
96
+
97
+ For an OpenAI-compatible local or self-hosted endpoint, provide the endpoint
98
+ explicitly so Skein never guesses where workspace code should be sent:
99
+
100
+ ```bash
101
+ export SKEIN_API_KEY=... # omit when the local endpoint needs no authentication
102
+ skein init --provider compatible --base-url http://localhost:11434/v1 --yes
103
+ ```
104
+
105
+ Create project configuration, index, and start the TUI:
106
+
107
+ ```bash
108
+ cd /path/to/project
109
+ skein init --provider openai --model gpt-5 --yes
110
+ skein index
111
+ skein
112
+ ```
113
+
114
+ Use `@path` to guarantee a file is attached to the current request:
115
+
116
+ ```text
117
+ Explain the race in @src/queue/worker.ts and fix it with the smallest change.
118
+ ```
119
+
120
+ ### Interactive workspace
121
+
122
+ The transcript stays on the terminal's native background. A thin rule marks the
123
+ composer; consequential permission requests become an inline warning band with
124
+ the exact tool target and working directory. Enter sends a request, or steers the current run when it is busy;
125
+ `Alt+Enter` queues a follow-up, while `Ctrl+J` or `Shift+Enter` inserts a
126
+ newline. `Ctrl+R` searches prompt history, `Ctrl+O` expands or collapses the
127
+ latest tool result, and Escape interrupts the current run. The composer supports
128
+ multiline cursor movement, word movement/deletion, `Ctrl+U`/`Ctrl+K`, and
129
+ bounded undo/redo. Type `/` for a keyboard-navigable command palette, or run
130
+ `/hotkeys` inside Skein.
131
+
132
+ Useful interactive commands include `/workflow`, `/context`, `/mode`, `/memory`,
133
+ `/remember`, `/skills`, `/agents`, `/mcp`, `/tools`, `/permissions`, and
134
+ `/theme`. `/transcript` reveals bounded full tool results, `/changes` lists
135
+ session writes, `/diff` opens the current Git diff through the normal permission
136
+ policy, and `/checkpoints` shows recoverable pre-mutation snapshots. `/mode ask`,
137
+ `/mode plan`, and `/mode build` switch the workflow posture without restarting.
138
+ Plan mode is read-only and produces an approval-ready implementation plan;
139
+ Build mode is the only mode that can mutate under the configured policy.
140
+ `/context`
141
+ toggles one live inspector for the active transcript, mutable working memory,
142
+ compacted session summary, and durable retrieval layer separately. Model-
143
+ suggested durable memories can be reviewed with `/memory candidates` and then
144
+ approved or rejected.
145
+
146
+ The default `/theme auto` follows
147
+ `SKEIN_APPEARANCE=light|dark` or a terminal `COLORFGBG` hint and otherwise uses
148
+ the dark-safe graphite palette. Cinder and Mono mirror the interactive prototype;
149
+ Midnight and Paper remain available compatibility choices. Place data-only JSON palettes in `~/.mosaic/themes/` (or
150
+ `SKEIN_THEME_DIR`) and run `/theme reload`; each palette uses semantic keys such
151
+ as `accent`, `text`, `muted`, `success`, and `error`. Set
152
+ `SKEIN_GLYPHS=ascii` when a terminal or multiplexer renders Unicode symbols
153
+ inconsistently. `NO_COLOR=1` or `ui.color: false` removes palette colors while
154
+ keeping status symbols and semantic labels intact. `/density compact` and
155
+ `/density comfortable` control vertical rhythm.
156
+
157
+ Run `skein doctor --visual` to inspect terminal width, color mode, glyph
158
+ fallback, keyboard protocol support, and a CJK/emoji/box-drawing calibration
159
+ sample. Skein cannot force a terminal font; Iosevka Term is a compact default,
160
+ JetBrains Mono NL maximizes compatibility, and Sarasa Mono SC is recommended
161
+ for Chinese-heavy work.
162
+
163
+ ## Automation
164
+
165
+ ```bash
166
+ # One-shot progress plus final answer
167
+ skein --print "Fix the failing typecheck"
168
+
169
+ # Final answer only
170
+ skein --print --quiet "Summarize the staged changes"
171
+
172
+ # A deterministic object for CI
173
+ skein --print --output-format json "Review this branch"
174
+
175
+ # One JSON event per line
176
+ skein --print --output-format stream-json "Run tests and fix failures"
177
+
178
+ # Pipeline input and sequential follow-up
179
+ cat build.log | skein --print --quiet "Find the root cause"
180
+ skein --print --queue "Run focused tests" --queue "Summarize risks" "Fix the bug"
181
+
182
+ # Read-only investigation
183
+ skein --ask --print "Trace request authentication"
184
+
185
+ # Read-only implementation planning
186
+ skein --plan --print "Design the storage migration"
187
+ ```
188
+
189
+ Non-interactive permission requests are denied unless the operation is already
190
+ allowed by policy. Use `--auto-edit` to allow file edits while retaining prompts
191
+ for shell/Git/network, or `--yes` for intentionally unattended runs. Hard deny
192
+ rules still win over both flags.
193
+
194
+ ## Commands
195
+
196
+ ```text
197
+ skein [prompt] interactive workspace
198
+ skein --print [prompt] headless agent run
199
+ skein init project setup
200
+ skein doctor prerequisite and fallback checks
201
+ skein doctor --visual terminal rendering and input calibration
202
+ skein config show resolved, redacted configuration
203
+ skein index build/update the selected index
204
+ skein search <query> ranked grounded spans
205
+ skein context <task> packed model context
206
+ skein status model and index status
207
+ skein session list|show|delete local session management
208
+ skein session export <id> Markdown audit export
209
+ skein checkpoint list <session> inspect snapshots
210
+ skein checkpoint restore <s> <c> restore a snapshot
211
+ skein tools tool schemas and categories
212
+ skein rules loaded user/workspace rule files
213
+ ```
214
+
215
+ Run `skein <command> --help` for complete flags.
216
+
217
+ ### Project configuration trust
218
+
219
+ A cloned repository must not be able to execute commands merely by committing
220
+ `.mosaic/config.*`. Skein therefore ignores project-defined hooks, custom
221
+ ContextEngine executables, verification commands, checkpoint overrides, and
222
+ permission policy by default. It also ignores remote model provider/endpoint
223
+ overrides and their project-stored API keys; loopback compatible endpoints and
224
+ local credentials remain available for local models. Review the file first,
225
+ then opt in explicitly:
226
+
227
+ ```bash
228
+ skein --trust-project-config --print "Run the project checks and fix failures"
229
+ skein --trust-project-config index
230
+ ```
231
+
232
+ User-level configuration and an explicitly supplied `--config` file remain the
233
+ recommended locations for trusted automation policy.
234
+
235
+ `skein init` records an owner-only fingerprint of the model settings it just
236
+ created under `~/.mosaic` (or `SKEIN_HOME`). This lets Anthropic, Gemini, and
237
+ remote compatible setup work normally without trusting project hooks or
238
+ permissions. If those model settings are later edited, that narrow routing
239
+ trust is invalidated automatically.
240
+
241
+ ## Configuration
242
+
243
+ Skein merges configuration in this order:
244
+
245
+ 1. defaults and environment variables;
246
+ 2. `~/.mosaic/config.yaml`;
247
+ 3. `<workspace>/.mosaic/config.yaml`;
248
+ 4. `<workspace>/.mosaic/config.json`;
249
+ 5. command-line overrides.
250
+
251
+ Example:
252
+
253
+ ```yaml
254
+ model:
255
+ provider: anthropic
256
+ model: claude-sonnet-4-5
257
+ temperature: 0.2
258
+ maxTokens: 8192
259
+
260
+ context:
261
+ engine: auto
262
+ maxTokens: 12000
263
+ topK: 12
264
+ contextEngineCommand: contextengine
265
+
266
+ permissions:
267
+ read: allow
268
+ write: ask
269
+ shell: ask
270
+ git: ask
271
+ network: ask
272
+ allowCommands:
273
+ - git status
274
+ - git diff
275
+ - npm test
276
+ denyCommands:
277
+ - rm -rf /
278
+ - git reset --hard
279
+ - sudo
280
+
281
+ agent:
282
+ maxTurns: 24
283
+ maxSessionTokens: 250000
284
+ autoVerify: true
285
+ verifyCommands:
286
+ - npm run typecheck
287
+ - npm test
288
+ checkpointBeforeWrite: true
289
+
290
+ hooks:
291
+ beforeTool: []
292
+ afterTool: []
293
+ afterTurn: []
294
+ ```
295
+
296
+ See [examples/config.yaml](examples/config.yaml) for a ready-to-adapt file.
297
+ Secrets should normally stay in environment variables instead of committed
298
+ configuration.
299
+
300
+ `provider: compatible` must be paired with `model.baseUrl` (or the
301
+ `--base-url` flag). Additional roots declared in project config are constrained
302
+ to the project directory; use `--add-workspace` for an intentionally external
303
+ root.
304
+
305
+ ## ContextEngine integration
306
+
307
+ Skein's `auto` mode negotiates a ContextEngine-compatible CLI by version,
308
+ required command flags, exit behavior, and response schemas. `skein index` can
309
+ bootstrap a compatible but unindexed workspace; `search` and `context` use the
310
+ external engine only after an index is ready. Missing, incompatible, unhealthy,
311
+ stale, malformed, or over-budget results fall back to the local index and emit
312
+ structured degradation metadata. `contextengine` makes those conditions hard
313
+ errors, while `local` never starts an external process.
314
+
315
+ ```bash
316
+ git clone https://github.com/lixiang12345/ContextEngine-plugin.git
317
+ cd ContextEngine-plugin
318
+ npm install && npm run build && npm link
319
+ npm run db:up
320
+ export CONTEXTENGINE_DATABASE_URL=postgresql://contextengine:contextengine@127.0.0.1:54329/contextengine
321
+ # Optional semantic channel, using an embedding-specific credential:
322
+ # export CONTEXTENGINE_EMBEDDING_API_KEY=...
323
+ # export CONTEXTENGINE_EMBEDDING_BASE_URL=https://embedding.example/v1
324
+ # export CONTEXTENGINE_EMBEDDING_MODEL=your-embedding-model
325
+
326
+ cd /path/to/project
327
+ skein index
328
+ skein status
329
+ ```
330
+
331
+ External commands run from a private temporary directory. Skein forwards only
332
+ `CONTEXTENGINE_*` variables and required proxy, certificate, locale, and
333
+ temporary-directory settings; it does not load a repository `.env` or forward
334
+ chat-model credentials. A shared gateway key should therefore be referenced by
335
+ an embedding-specific `CONTEXTENGINE_*` variable rather than reused implicitly.
336
+
337
+ ContextEngine status cannot prove that every indexed line still matches the
338
+ filesystem. Skein realpath-checks each result, verifies its hash and current line
339
+ content, and reruns the entire query locally if any hit is stale or invalid.
340
+ Empty external results in `auto` mode are cross-checked against the current
341
+ local index so newly added files are not silently missed. ContextEngine's
342
+ synthetic commit-lineage hits are reconstructed from the current repository
343
+ with a constrained read-only Git invocation before use. The external
344
+ `packedText` is never passed directly to a model; Skein repacks only verified
345
+ current-file or commit-summary spans under its own token cap.
346
+
347
+ ContextEngine remains an optional adapter, not a hidden hard dependency. The
348
+ local fallback keeps Skein useful offline, and fallback reason/remediation is
349
+ visible in TUI context telemetry, headless output, direct JSON commands, and
350
+ `skein doctor`.
351
+
352
+ ## Safety model
353
+
354
+ - `read`, `write`, `shell`, `git`, and `network` have independent policies.
355
+ - File tools reject lexical and symlink escapes from configured workspace roots.
356
+ - Writes and patches are atomic; multi-file patches roll back partial commits.
357
+ - A checkpoint manifest and file blobs are saved before mutation.
358
+ - Command allow rules cannot bypass approval with shell control or substitution.
359
+ - Command allow rules approve only the shell/Git execution category; derived
360
+ write and network policies still apply to package scripts and mutations.
361
+ - Ask mode only exposes inspection and planning tools to the model.
362
+ - Hooks receive JSON on stdin and run with bounded time/output.
363
+ - Project configuration cannot enable executable hooks or relax safety policy
364
+ unless `--trust-project-config` is explicitly supplied.
365
+ - Untrusted project configuration cannot switch providers or redirect
366
+ credentials/source code to a remote custom endpoint; these require trust.
367
+ - Git aliases, Git config overrides, repository hooks, and workspace overrides
368
+ are disabled by the built-in Git tool; use an explicitly approved shell
369
+ command when a repository workflow genuinely needs them.
370
+ - Git operations that may invoke transport, signing, merge, or checkout helpers
371
+ require the `shell` category in addition to Git/write/network as applicable.
372
+ Git and ContextEngine executables are resolved outside workspace-controlled
373
+ `PATH` entries.
374
+ - Git checkpoints include dirty and explicitly named paths before a mutation.
375
+ Branch switches can change clean tracked files that cannot be predicted
376
+ without snapshotting the entire repository, so review the checkpoint list.
377
+
378
+ Shell approval is still powerful: an approved shell program can perform actions
379
+ that a file tool cannot. Custom environments require a fresh approval, common
380
+ mutation targets are checkpointed and audited, and network detection is
381
+ conservative but necessarily heuristic. Review the shown command, and use an
382
+ OS/container sandbox around Skein for untrusted repositories or fully
383
+ unattended agents.
384
+
385
+ ## Project data
386
+
387
+ Existing installations keep using `<workspace>/.mosaic/` until migration is
388
+ explicitly requested. New canonical storage uses `<workspace>/.skein/` with
389
+ the same layout:
390
+
391
+ ```text
392
+ .skein/
393
+ config.json
394
+ index.json
395
+ sessions/
396
+ checkpoints/
397
+ ```
398
+
399
+ Preview and apply project migration, or verify and roll it back:
400
+
401
+ ```bash
402
+ skein migrate
403
+ skein migrate --yes
404
+ skein migrate --recover
405
+ skein migrate --recover --yes
406
+ skein migrate --rollback
407
+ skein migrate --rollback --yes
408
+ ```
409
+
410
+ Use `--home` for user-level configuration, memory, themes, Skills, rules, and
411
+ agent profiles. Migration copies through a temporary directory and retains the
412
+ legacy source. Rollback is available only when the source, canonical copy, and
413
+ hash-bearing migration manifest still match; changed data is never deleted.
414
+ If a process exits between copy, rename, verification, and cleanup,
415
+ `--recover` previews the remaining `.migrating-*` or `.rollback-*` directory.
416
+ `--recover --yes` resumes a complete migration, restores a complete rollback
417
+ snapshot, or removes only a partial copy proven redundant with legacy state.
418
+ Conflicting or ambiguous candidates remain untouched. Normal Skein processes
419
+ hold shared namespace leases for the storage they use; migration, rollback, and
420
+ recovery require an exclusive lease. A live session, indexer, team run, or
421
+ default memory store therefore blocks namespace mutation, while an operating
422
+ system process exit (including a crash) releases its lease immediately. Custom
423
+ legacy and canonical paths must be separate and non-nested after symbolic links
424
+ are resolved.
425
+
426
+ The default durable memory database is user-owned at `~/.mosaic/memory.sqlite`
427
+ until user storage is migrated to `~/.skein/` (or overridden by `SKEIN_HOME`).
428
+ Set `memory.databasePath` when a team or deployment
429
+ needs a different local SQLite location. Working memory and compacted summaries
430
+ remain inside each session, while durable facts are retrieved only when their
431
+ lexical evidence and confidence clear the configured threshold.
432
+
433
+ Memory is intentionally layered: the active prompt holds the current turn,
434
+ `working_memory` holds bounded goals/constraints/decisions for the session,
435
+ compaction produces a fallible handoff summary, and SQLite FTS5 stores durable
436
+ semantic/episodic/procedural facts. A model can call `memory_propose`, but its
437
+ candidate is inactive, expires automatically, and carries provenance until a
438
+ person approves it with `/memory candidates` and `/memory approve <id>`. The
439
+ interactive `/remember` command and `skein memory add` are explicit user writes.
440
+ This prevents retrieved text from becoming an unreviewed instruction or
441
+ permission grant.
442
+
443
+ Add both `.mosaic/` and `.skein/` to `.gitignore` unless the team intentionally
444
+ shares a sanitized configuration file elsewhere.
445
+
446
+ Session JSON also keeps a bounded audit trail of permission decisions, tool
447
+ outcomes, changed files, and checkpoint ids. `skein session export` includes
448
+ that trail in the Markdown export.
449
+
450
+ ## Development
451
+
452
+ ```bash
453
+ npm run dev -- "explain this project"
454
+ npm run typecheck
455
+ npm test
456
+ npm run build
457
+ npm run check
458
+ npm run test:pty
459
+ npm run release:verify
460
+ ```
461
+
462
+ Skein is licensed under MIT.