@alisio/alisio-code 0.1.0-alpha.12 → 0.1.0-alpha.13

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,23 +1,102 @@
1
- # alisio
1
+ # @alisio/alisio-code
2
2
 
3
- **Alisio is an extensible, provider-agnostic coding-agent harness for your terminal.** It pairs a
4
- fast TUI with any OpenAI-compatible model, runs local tools behind explicit permissions, compacts
5
- long conversations into structured checkpoints, remembers decisions across sessions with an
6
- Engram-style memory plugin, and exposes a typed plugin SDK.
3
+ **Alisio is an extensible, provider-agnostic coding-agent harness for your terminal.** It pairs a fast
4
+ TUI with any OpenAI-compatible model, runs local tools behind explicit permissions, compacts long
5
+ conversations into structured checkpoints, remembers decisions across sessions with an Engram-style
6
+ memory plugin, and exposes a typed plugin SDK.
7
+
8
+ ## What it is
9
+
10
+ `alisio` is the CLI of the Alisio project. It connects to any OpenAI-compatible endpoint (Chat
11
+ Completions or Responses), drives its own agent tool loop, and runs interactively as a TUI or
12
+ headless for scripts and CI. Provider SDKs stay out of the harness: the CLI ships built-in DeepSeek,
13
+ OpenAI-compatible, OpenCode Console (Zen) and OpenCode Go providers, plus memory and subagents
14
+ plugins.
15
+
16
+ ## Installation
17
+
18
+ ```sh
19
+ npm i -g @alisio/alisio-code # or: pnpm add -g @alisio/alisio-code · bun add -g @alisio/alisio-code
20
+ alisio # the binary is installed as `alisio`
21
+ ```
22
+
23
+ Standalone binaries (Bun embedded, no Node required) are attached to GitHub releases.
24
+
25
+ ## Quick start
26
+
27
+ The fastest path is the TUI's `/connect` form: pick a provider, enter its settings and key, choose a
28
+ model, and Alisio persists the selection globally (`/model` re-opens the same selector). A plain
29
+ config start looks like:
30
+
31
+ ```sh
32
+ alisio setup # writes a secret-free .alisio/config.json in .alisio/
33
+ export DEEPSEEK_API_KEY=... # keys come from environment variables or /connect, never config files
34
+ alisio --config .alisio/config.json
35
+ ```
36
+
37
+ Run one prompt headless, emitting versioned JSONL events:
7
38
 
8
39
  ```sh
9
- npm install -g @alisio/alisio-code # or: pnpm add -g @alisio/alisio-code · bun add -g @alisio/alisio-code
10
- alisio # the CLI binary is installed as `alisio`
11
- export DEEPSEEK_API_KEY=... # keys are read from environment variables only
12
- alisio --config ./alisio.json
40
+ alisio run "Summarize this repository" --json
41
+ alisio run "/init" --allow-write # generate AGENTS.md from the built-in /init template
13
42
  ```
14
43
 
15
- - Terminal UI: streaming Markdown, tool blocks with diffs, context/token bar, slash commands, copy-on-select.
16
- - Headless: `alisio run "prompt" --json` emits versioned JSONL events.
17
- - Permissions: reads by default; `--allow-write`, `--allow-process` or interactive approval; `--read-only`.
18
- - Built-in memory plugin (disable with `--disable-plugin memory`); npm plugins via `--plugin <package>`.
19
- - Runs on Node.js >= 22.16 or Bun; standalone binaries are attached to GitHub releases.
44
+ ## Commands
45
+
46
+ | Command | Description |
47
+ | --- | --- |
48
+ | `alisio` | Interactive TUI (readline with `--no-tui`) |
49
+ | `alisio run <prompt>` | Headless run; `/name args` runs a prompt template |
50
+ | `alisio resume <session> [prompt]` | Resume a session |
51
+ | `alisio setup` | Write a secret-free example `.alisio/config.json` |
52
+ | `alisio doctor` | Environment and provider diagnostics |
53
+ | `alisio trust list` / `trust revoke <path>` | Inspect or revoke per-directory project trust |
54
+ | `alisio sessions list` / `sessions recover <id> --acknowledge` | List sessions; recover after a crash |
55
+ | `alisio skills list` / `skills validate` | Discover and validate Agent Skills |
56
+ | `alisio plugins list` / `plugins doctor` | List/load plugins and show their tools and commands |
57
+ | `alisio mcp list` / `mcp doctor <server>` | List configured MCP servers; connect to one (`--allow-mcp`) |
58
+ | `alisio context explain <path>` | Show which `AGENTS.md` files apply to a path |
59
+ | `alisio install npm:<package>` | Install an npm plugin into the global plugins directory |
60
+
61
+ ## Permissions and key flags
62
+
63
+ Reads run by default; anything else needs a flag or interactive approval:
64
+
65
+ | Flag | Effect |
66
+ | --- | --- |
67
+ | `--allow-write` | Allow file writes |
68
+ | `--allow-process` | Allow arbitrary subprocesses (not sandboxed) |
69
+ | `--allow-external` | Allow network tools: `webfetch`, `websearch`, provider-native search |
70
+ | `--allow-mcp` | Allow configured MCP servers and remote tool calls |
71
+ | `--allow-agents` | Allow messaging neighboring agents through Herdr |
72
+ | `--read-only` | Disable writes, subprocesses, network tools, executable plugins and MCP |
73
+ | `--plugin <path…>` / `--trust-project` | Load explicitly trusted plugins / trust project config |
74
+ | `--disable-plugin <ids…>` | Disable built-in plugins (e.g. `memory`) |
75
+ | `--json` | Emit versioned JSONL events (headless) |
76
+
77
+ Other global flags: `--cwd`, `--config`, `--model`, `--base-url`, `--api-mode`, `--db`,
78
+ `--no-tui`, `--no-banner`, `--no-herdr`, `--agents <json>`, `--quiet`, `-V`, `-h`.
79
+
80
+ ## In the TUI
81
+
82
+ `/connect` adds a provider; `/model` picks a saved provider/model; `/compact`, `/stats`, `/clear`,
83
+ `/sessions`, `/resume` manage conversations; `/plugins`, `/skills`, `/mcp`, `/settings` manage
84
+ extensions and preferences; `/memory` and `/agents` drive the built-in plugins; `/init` writes
85
+ `AGENTS.md`.
86
+
87
+ ## Requirements
88
+
89
+ Node.js **>= 22.16** (`node:sqlite` with FTS5) or Bun **>= 1.4.2**. Git and ripgrep on `PATH` for the
90
+ Git and search tools; `alisio doctor` reports what it detects.
91
+
92
+ ## Docs
93
+
94
+ Documentation (EN/ES): <https://gustavogutierrez.github.io/alisio/> — [quick start](https://gustavogutierrez.github.io/alisio/quick-start),
95
+ [configuration](https://gustavogutierrez.github.io/alisio/configuration), [plugins](https://gustavogutierrez.github.io/alisio/plugins),
96
+ [subagents](https://gustavogutierrez.github.io/alisio/subagents), [memory](https://gustavogutierrez.github.io/alisio/memory),
97
+ [TUI](https://gustavogutierrez.github.io/alisio/tui).
20
98
 
21
- Documentation: [English](https://gustavogutierrez.github.io/alisio/) · [Español](https://gustavogutierrez.github.io/alisio/es/)
99
+ ## License
22
100
 
23
- Maintainer: Gustavo Gutiérrez · License: MIT
101
+ MIT. Maintained by Gustavo Gutiérrez Mercado. Source: <https://github.com/GustavoGutierrez/alisio> ·
102
+ npm: <https://www.npmjs.com/settings/alisio/packages>.
package/dist/tui/app.js CHANGED
@@ -326,7 +326,13 @@ export async function runTui(options) {
326
326
  tui.requestRender();
327
327
  return;
328
328
  }
329
- if (["run_completed", "run_failed", "run_cancelled", "compaction_failed"].includes(event.type))
329
+ if ([
330
+ "run_completed",
331
+ "run_failed",
332
+ "run_cancelled",
333
+ "run_turns_exceeded",
334
+ "compaction_failed",
335
+ ].includes(event.type))
330
336
  terminalEvent = true;
331
337
  view = reduceEvent(view, event);
332
338
  sync();
@@ -30,7 +30,7 @@ export class Header {
30
30
  render(width) {
31
31
  const i = this.info(), v = this.view();
32
32
  const line1 = line([
33
- { text: "◆ alisio", priority: 8, paint: (t) => style.bold(style.brightCyan(t)) },
33
+ { text: "◆ Alisio Code", priority: 8, paint: (t) => style.bold(style.brightCyan(t)) },
34
34
  { text: `v${i.version}`, priority: 1, paint: style.gray },
35
35
  {
36
36
  text: v.model || "not connected",
@@ -11,7 +11,7 @@ export const WEBSEARCH_PROVIDERS = [
11
11
  export const defaultConfig = {
12
12
  compaction: { auto: true, threshold: 0.85, keepTurns: 2, maxOutputTokens: 16_000 },
13
13
  context: { claudeMdFallback: false, maxBytes: 32 * 1024 },
14
- limits: { maxTurns: 20, maxOutputTokens: 16_384, maxContextChars: 800_000, timeoutMs: 300_000 },
14
+ limits: { maxTurns: 100, maxOutputTokens: 16_384, maxContextChars: 800_000, timeoutMs: 300_000 },
15
15
  tui: { paddingX: 1, skillSlashCommands: true },
16
16
  mcp: { allow: false },
17
17
  websearch: { provider: undefined },
@@ -112,7 +112,7 @@ export const SETTINGS_DEFINITIONS = [
112
112
  valueType: "number",
113
113
  values: [5, 10, 15, 20, 30, 50, 100],
114
114
  read: (config) => config.limits.maxTurns,
115
- description: "Maximum agent-loop turns per run before the run ends. Applied from the next run; longer tasks may need a higher budget.",
115
+ description: "Maximum agent-loop turns per run. Reaching the limit ends the run softly: everything so far is kept and the session stays usable, so you can just say continue. Raise it for long read-heavy audits. Applied from the next run.",
116
116
  },
117
117
  {
118
118
  id: "limits.maxOutputTokens",
package/dist/tui/state.js CHANGED
@@ -529,7 +529,8 @@ export function reduceEvent(state, event) {
529
529
  }
530
530
  case "run_completed":
531
531
  case "run_failed":
532
- case "run_cancelled": {
532
+ case "run_cancelled":
533
+ case "run_turns_exceeded": {
533
534
  const ended = {
534
535
  ...state,
535
536
  streaming: false,
@@ -541,6 +542,11 @@ export function reduceEvent(state, event) {
541
542
  };
542
543
  if (event.type === "run_failed")
543
544
  return addItem(ended, { kind: "error", text: String(d.error ?? "Run failed") });
545
+ if (event.type === "run_turns_exceeded")
546
+ return addItem(ended, {
547
+ kind: "notice",
548
+ text: "Turn limit reached — the answer may be incomplete. Continue with another prompt or raise limits.maxTurns (/settings → Max turns).",
549
+ });
544
550
  if (event.type === "run_cancelled") {
545
551
  const reason = String(d.error ?? "cancelled");
546
552
  return addItem(ended, {
package/dist/version.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  /**
2
- * Reads the package version at runtime so --version, doctor, plugin metadata and MCP client
3
- * metadata stay in sync with the published package without a build-time constant to update.
4
- * The manifest is resolved relative to the module (`src/version.ts` → `../package.json` in the
5
- * source tree; `dist/version.js` → `../package.json` of the installed package). Standalone
6
- * binaries inject the version at build time via ALISIO_PACKAGE_VERSION (scripts/binary-build.ts).
2
+ * Reads the package version at runtime so --version, the TUI header, doctor, plugin metadata and
3
+ * MCP client metadata stay in sync with the published package without a build-time constant to
4
+ * update. The manifest is resolved by walking UP from the module directory until a package.json
5
+ * with a string `version` is found (bounded, any depth: module, then up to 8 parents), so deeply
6
+ * nested call sites like `src/tui/app.ts` and compiled `dist/*` resolve the same manifest as
7
+ * `src/main.ts`. Standalone binaries inject the version at build time via
8
+ * ALISIO_PACKAGE_VERSION (scripts/binary-build.ts).
7
9
  */
8
10
  export declare function loadVersion(fromHere: string): string;
package/dist/version.js CHANGED
@@ -8,19 +8,55 @@ import { fileURLToPath } from "node:url";
8
8
  */
9
9
  const FALLBACK = "dev";
10
10
  /**
11
- * Reads the package version at runtime so --version, doctor, plugin metadata and MCP client
12
- * metadata stay in sync with the published package without a build-time constant to update.
13
- * The manifest is resolved relative to the module (`src/version.ts` → `../package.json` in the
14
- * source tree; `dist/version.js` → `../package.json` of the installed package). Standalone
15
- * binaries inject the version at build time via ALISIO_PACKAGE_VERSION (scripts/binary-build.ts).
11
+ * How many parent directories the loader walks up before giving up. Bounded so a missing
12
+ * manifest can never make the lookup climb an unbounded path.
13
+ */
14
+ const MAX_PARENT_HOPS = 8;
15
+ /** Manifests whose `name` identifies the CLI package; preferred when several are hit. */
16
+ const CLI_MANIFEST_NAMES = new Set(["@alisio/alisio-code", "alisio"]);
17
+ /**
18
+ * Walks up from `dir` looking for a package manifest. Returns the version of the nearest
19
+ * manifest that declares a string `version`, preferring a manifest whose `name` identifies the
20
+ * CLI package (`@alisio/alisio-code`/`alisio`) when several are hit — e.g. running from source
21
+ * inside the monorepo, where the repo-root manifest is also a candidate. `undefined` when no
22
+ * manifest with a version is reached within the bound.
23
+ */
24
+ function findManifestVersion(dir) {
25
+ let nearest;
26
+ let current = dir;
27
+ for (let hop = 0; hop <= MAX_PARENT_HOPS; hop++) {
28
+ try {
29
+ const parsed = JSON.parse(readFileSync(join(current, "package.json"), "utf8"));
30
+ if (typeof parsed.version === "string" && parsed.version) {
31
+ if (typeof parsed.name === "string" && CLI_MANIFEST_NAMES.has(parsed.name))
32
+ return parsed.version;
33
+ nearest ??= parsed.version;
34
+ }
35
+ }
36
+ catch {
37
+ // No manifest here; keep walking up.
38
+ }
39
+ const parent = dirname(current);
40
+ if (parent === current)
41
+ break; // Filesystem root.
42
+ current = parent;
43
+ }
44
+ return nearest;
45
+ }
46
+ /**
47
+ * Reads the package version at runtime so --version, the TUI header, doctor, plugin metadata and
48
+ * MCP client metadata stay in sync with the published package without a build-time constant to
49
+ * update. The manifest is resolved by walking UP from the module directory until a package.json
50
+ * with a string `version` is found (bounded, any depth: module, then up to 8 parents), so deeply
51
+ * nested call sites like `src/tui/app.ts` and compiled `dist/*` resolve the same manifest as
52
+ * `src/main.ts`. Standalone binaries inject the version at build time via
53
+ * ALISIO_PACKAGE_VERSION (scripts/binary-build.ts).
16
54
  */
17
55
  export function loadVersion(fromHere) {
18
56
  if (process.env.ALISIO_PACKAGE_VERSION)
19
57
  return process.env.ALISIO_PACKAGE_VERSION;
20
58
  try {
21
- const manifest = join(dirname(fileURLToPath(fromHere)), "..", "package.json");
22
- const parsed = JSON.parse(readFileSync(manifest, "utf8"));
23
- return typeof parsed.version === "string" && parsed.version ? parsed.version : FALLBACK;
59
+ return findManifestVersion(dirname(fileURLToPath(fromHere))) ?? FALLBACK;
24
60
  }
25
61
  catch {
26
62
  return FALLBACK;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alisio/alisio-code",
3
- "version": "0.1.0-alpha.12",
3
+ "version": "0.1.0-alpha.13",
4
4
  "description": "Alisio: an extensible, provider-agnostic coding-agent harness for your terminal. TUI, OpenAI-compatible providers, permissioned local tools, context compaction, persistent memory and a typed plugin SDK.",
5
5
  "author": "Gustavo Gutiérrez",
6
6
  "license": "MIT",
@@ -45,14 +45,14 @@
45
45
  "alisio": "./dist/main.js"
46
46
  },
47
47
  "dependencies": {
48
- "@alisio/core": "0.1.0-alpha.10",
49
- "@alisio/plugin-deepseek": "0.1.0-alpha.8",
50
- "@alisio/plugin-memory": "0.1.0-alpha.6",
51
- "@alisio/plugin-openai-compatible": "0.1.0-alpha.8",
52
- "@alisio/plugin-opencode": "0.1.0-alpha.7",
53
- "@alisio/plugin-opencode-go": "0.1.0-alpha.7",
54
- "@alisio/plugin-subagents": "0.1.0-alpha.7",
55
- "@alisio/sdk": "0.1.0-alpha.6",
48
+ "@alisio/core": "0.1.0-alpha.11",
49
+ "@alisio/plugin-deepseek": "0.1.0-alpha.9",
50
+ "@alisio/plugin-memory": "0.1.0-alpha.7",
51
+ "@alisio/plugin-openai-compatible": "0.1.0-alpha.9",
52
+ "@alisio/plugin-opencode": "0.1.0-alpha.8",
53
+ "@alisio/plugin-opencode-go": "0.1.0-alpha.8",
54
+ "@alisio/plugin-subagents": "0.1.0-alpha.8",
55
+ "@alisio/sdk": "0.1.0-alpha.7",
56
56
  "@earendil-works/pi-tui": "0.87.1",
57
57
  "commander": "15.0.0"
58
58
  },