@selesai/code 0.8.4 → 0.8.5

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +7 -1
  3. package/dist/core/slash-commands.js +1 -0
  4. package/dist/defaults/models.json +41 -55
  5. package/dist/defaults/settings.json +7 -8
  6. package/dist/extensions/pi-subagents/CHANGELOG.md +26 -3
  7. package/dist/extensions/pi-subagents/README.md +2 -0
  8. package/dist/extensions/pi-subagents/docs/configuration.md +46 -2
  9. package/dist/extensions/pi-subagents/docs/observability.md +1 -1
  10. package/dist/extensions/pi-subagents/docs/tool-reference.md +1 -1
  11. package/dist/extensions/pi-subagents/package-lock.json +2 -2
  12. package/dist/extensions/pi-subagents/package.json +1 -1
  13. package/dist/extensions/pi-subagents/src/agents/agents.ts +9 -3
  14. package/dist/extensions/pi-subagents/src/extension/config.ts +6 -0
  15. package/dist/extensions/pi-subagents/src/extension/doctor.ts +40 -0
  16. package/dist/extensions/pi-subagents/src/extension/index.ts +21 -0
  17. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +5 -0
  18. package/dist/extensions/pi-subagents/src/extension/rpc.ts +3 -9
  19. package/dist/extensions/pi-subagents/src/extension/schemas.ts +2 -2
  20. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -1
  21. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +4 -7
  22. package/dist/extensions/pi-subagents/src/missions/store.ts +4 -4
  23. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +6 -2
  24. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +374 -0
  25. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +9 -5
  26. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +117 -29
  27. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +7 -1
  28. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +11 -5
  29. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +33 -15
  30. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +104 -0
  31. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +17 -3
  32. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +5 -1
  33. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -3
  34. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +84 -36
  35. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +37 -2
  36. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +135 -22
  37. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +12 -0
  38. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +171 -0
  39. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +614 -187
  40. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +13 -4
  41. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +286 -0
  42. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +23 -0
  43. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +2 -0
  44. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +44 -1
  45. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +280 -0
  46. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +4 -2
  47. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +19 -3
  48. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +17 -5
  49. package/dist/extensions/pi-subagents/src/shared/types.ts +92 -0
  50. package/dist/extensions/pi-subagents/src/shared/utils.ts +3 -1
  51. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +7 -5
  52. package/dist/extensions/pi-subagents/src/tui/fleet.ts +225 -12
  53. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +22 -5
  54. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +87 -0
  55. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +96 -6
  56. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +28 -5
  57. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +8 -5
  58. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +83 -2
  59. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +211 -15
  60. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +41 -3
  61. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +314 -10
  62. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +31 -1
  63. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +317 -0
  64. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +21 -2
  65. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +16 -1
  66. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +6 -1
  67. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +75 -4
  68. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +18 -0
  69. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +29 -1
  70. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +31 -5
  71. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +139 -1
  72. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +10 -0
  73. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +2 -1
  74. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +171 -0
  75. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +30 -4
  76. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +14 -0
  77. package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +69 -0
  78. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +83 -0
  79. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +2 -2
  80. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +55 -2
  81. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +12 -1
  82. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +7 -7
  83. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +121 -0
  84. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +9 -0
  85. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +4 -3
  86. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +28 -0
  87. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +10 -1
  88. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +39 -0
  89. package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +65 -0
  90. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +61 -0
  91. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  92. package/dist/modes/interactive/interactive-mode.js +48 -1
  93. package/docs/quickstart.md +27 -43
  94. package/docs/settings.md +4 -0
  95. package/docs/usage.md +1 -0
  96. package/package.json +2 -1
@@ -3,6 +3,7 @@ import { describe, it } from "node:test";
3
3
  import {
4
4
  DEFAULT_ASYNC_TIMEOUT_MS,
5
5
  DEFAULT_FOREGROUND_TIMEOUT_MS,
6
+ resolveConfigDefaultTimeoutMs,
6
7
  resolveSingleAgentLaunchTimeout,
7
8
  } from "../../src/runs/foreground/subagent-executor.ts";
8
9
 
@@ -70,4 +71,68 @@ describe("single-agent launch timeout wiring", () => {
70
71
  { timeoutMs: 5_000 },
71
72
  );
72
73
  });
74
+
75
+ const NINETY_MIN = 90 * 60 * 1000;
76
+
77
+ it("applies the global config default in place of the foreground backstop", () => {
78
+ assert.deepEqual(resolveSingleAgentLaunchTimeout({}, false, NINETY_MIN), {
79
+ timeoutMs: NINETY_MIN,
80
+ });
81
+ });
82
+
83
+ it("applies the global config default to composite foreground runs (parallel/chain)", () => {
84
+ assert.deepEqual(
85
+ resolveSingleAgentLaunchTimeout({ agent: "worker", task: "x", tasks: [{ agent: "worker", task: "y" }] }, false, NINETY_MIN),
86
+ { timeoutMs: NINETY_MIN },
87
+ );
88
+ assert.deepEqual(
89
+ resolveSingleAgentLaunchTimeout({ agent: "worker", task: "x", chain: [{ agent: "worker", task: "y" }] }, false, NINETY_MIN),
90
+ { timeoutMs: NINETY_MIN },
91
+ );
92
+ });
93
+
94
+ it("applies the global config default in place of the single-agent async backstop", () => {
95
+ assert.deepEqual(resolveSingleAgentLaunchTimeout({}, true, NINETY_MIN), {
96
+ timeoutMs: NINETY_MIN,
97
+ });
98
+ });
99
+
100
+ it("lets an explicit call timeout win over the global config default", () => {
101
+ assert.deepEqual(resolveSingleAgentLaunchTimeout({ timeoutMs: 5_000 }, false, NINETY_MIN), {
102
+ timeoutMs: 5_000,
103
+ });
104
+ });
105
+
106
+ it("keeps composite async runs unbounded even with a global config default", () => {
107
+ assert.deepEqual(
108
+ resolveSingleAgentLaunchTimeout({ agent: "worker", task: "x", tasks: [{ agent: "worker", task: "y" }] }, true, NINETY_MIN),
109
+ {},
110
+ );
111
+ });
112
+ });
113
+
114
+ describe("resolveConfigDefaultTimeoutMs", () => {
115
+ it("returns a positive integer unchanged", () => {
116
+ assert.equal(resolveConfigDefaultTimeoutMs(90 * 60 * 1000), 90 * 60 * 1000);
117
+ });
118
+
119
+ it("treats unset config as no default", () => {
120
+ assert.equal(resolveConfigDefaultTimeoutMs(undefined), undefined);
121
+ });
122
+
123
+ it("ignores non-positive, non-integer, and non-numeric values", () => {
124
+ assert.equal(resolveConfigDefaultTimeoutMs(0), undefined);
125
+ assert.equal(resolveConfigDefaultTimeoutMs(-1), undefined);
126
+ assert.equal(resolveConfigDefaultTimeoutMs(1.5), undefined);
127
+ assert.equal(resolveConfigDefaultTimeoutMs("600000" as unknown), undefined);
128
+ assert.equal(resolveConfigDefaultTimeoutMs(Number.NaN), undefined);
129
+ });
130
+
131
+ it("accepts the maximum schedulable timer delay but ignores anything larger", () => {
132
+ // 2_147_483_647 is the largest delay a Node.js timer can honor; above it
133
+ // setTimeout overflows to ~1ms and the run would expire almost immediately.
134
+ assert.equal(resolveConfigDefaultTimeoutMs(2_147_483_647), 2_147_483_647);
135
+ assert.equal(resolveConfigDefaultTimeoutMs(2_147_483_648), undefined);
136
+ assert.equal(resolveConfigDefaultTimeoutMs(Number.MAX_SAFE_INTEGER), undefined);
137
+ });
73
138
  });
@@ -125,6 +125,67 @@ describe("worktree", () => {
125
125
  }
126
126
  });
127
127
 
128
+ it("rejects worktree base directories inside Selesai extensions", () => {
129
+ const repoDir = createRepo("selesai-worktree-extension-dir-");
130
+ const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "selesai-worktree-home-"));
131
+ const previousAgentDir = process.env.SELESAI_CODING_AGENT_DIR;
132
+ const previousHome = process.env.HOME;
133
+ const previousUserProfile = process.env.USERPROFILE;
134
+ const extensionsDir = path.join(tempHome, ".selesai", "agent", "extensions");
135
+ try {
136
+ process.env.HOME = tempHome;
137
+ process.env.USERPROFILE = tempHome;
138
+ delete process.env.SELESAI_CODING_AGENT_DIR;
139
+ assert.throws(
140
+ () => createWorktrees(repoDir, "extension-dir", 1, { baseDir: extensionsDir }),
141
+ /worktree base directory cannot be inside Pi extensions directory/i,
142
+ );
143
+ assert.throws(
144
+ () => createWorktrees(repoDir, "extension-subdir", 1, { baseDir: path.join(extensionsDir, "checkout") }),
145
+ /worktree base directory cannot be inside Pi extensions directory/i,
146
+ );
147
+ } finally {
148
+ if (previousAgentDir === undefined) delete process.env.SELESAI_CODING_AGENT_DIR;
149
+ else process.env.SELESAI_CODING_AGENT_DIR = previousAgentDir;
150
+ if (previousHome === undefined) delete process.env.HOME;
151
+ else process.env.HOME = previousHome;
152
+ if (previousUserProfile === undefined) delete process.env.USERPROFILE;
153
+ else process.env.USERPROFILE = previousUserProfile;
154
+ cleanupRepo(repoDir);
155
+ fs.rmSync(tempHome, { recursive: true, force: true });
156
+ }
157
+ });
158
+
159
+ it("rejects symlinked worktree base directories inside Selesai extensions", () => {
160
+ const repoDir = createRepo("selesai-worktree-extension-symlink-");
161
+ const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "selesai-worktree-home-"));
162
+ const previousAgentDir = process.env.SELESAI_CODING_AGENT_DIR;
163
+ const previousHome = process.env.HOME;
164
+ const previousUserProfile = process.env.USERPROFILE;
165
+ const extensionsDir = path.join(tempHome, ".selesai", "agent", "extensions");
166
+ const aliasDir = path.join(tempHome, "extension-alias");
167
+ try {
168
+ process.env.HOME = tempHome;
169
+ process.env.USERPROFILE = tempHome;
170
+ delete process.env.SELESAI_CODING_AGENT_DIR;
171
+ fs.mkdirSync(extensionsDir, { recursive: true });
172
+ fs.symlinkSync(extensionsDir, aliasDir, process.platform === "win32" ? "junction" : "dir");
173
+ assert.throws(
174
+ () => createWorktrees(repoDir, "extension-symlink", 1, { baseDir: path.join(aliasDir, "checkout") }),
175
+ /worktree base directory cannot be inside Pi extensions directory/i,
176
+ );
177
+ } finally {
178
+ if (previousAgentDir === undefined) delete process.env.SELESAI_CODING_AGENT_DIR;
179
+ else process.env.SELESAI_CODING_AGENT_DIR = previousAgentDir;
180
+ if (previousHome === undefined) delete process.env.HOME;
181
+ else process.env.HOME = previousHome;
182
+ if (previousUserProfile === undefined) delete process.env.USERPROFILE;
183
+ else process.env.USERPROFILE = previousUserProfile;
184
+ cleanupRepo(repoDir);
185
+ fs.rmSync(tempHome, { recursive: true, force: true });
186
+ }
187
+ });
188
+
128
189
  it("uses SELESAI_SUBAGENTS_WORKTREE_DIR when no base directory is configured", () => {
129
190
  const repoDir = createRepo("pi-worktree-env-base-dir-");
130
191
  const previous = process.env.SELESAI_SUBAGENTS_WORKTREE_DIR;
@@ -398,6 +398,7 @@ export declare class InteractiveMode {
398
398
  private notifyAuthDialog;
399
399
  private loginProvider;
400
400
  private showLoginDialog;
401
+ private handleSettingsFactoryReset;
401
402
  private handleReloadCommand;
402
403
  private handleExportCommand;
403
404
  private getPathCommandArgument;
@@ -9,7 +9,7 @@ import * as TuiLayouts from "@earendil-works/pi-tui";
9
9
  import { CombinedAutocompleteProvider, Container, fuzzyFilter, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
10
10
  import chalk from "chalk";
11
11
  import { spawn, spawnSync } from "child_process";
12
- import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, getUpdateInstruction, PACKAGE_NAME, VERSION, } from "../../config.js";
12
+ import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getBundledDefaultsDir, getDebugLogPath, getDocsPath, getShareViewerUrl, getUpdateInstruction, PACKAGE_NAME, VERSION, } from "../../config.js";
13
13
  import { parseSkillBlocks } from "../../core/agent-session.js";
14
14
  import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
15
15
  import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
@@ -2319,6 +2319,11 @@ export class InteractiveMode {
2319
2319
  this.editor.setText("");
2320
2320
  return;
2321
2321
  }
2322
+ if (text === "/settings-factory-reset") {
2323
+ this.editor.setText("");
2324
+ await this.handleSettingsFactoryReset();
2325
+ return;
2326
+ }
2322
2327
  if (text === "/scoped-models") {
2323
2328
  this.editor.setText("");
2324
2329
  await this.showModelsSelector();
@@ -4649,6 +4654,48 @@ export class InteractiveMode {
4649
4654
  // =========================================================================
4650
4655
  // Command handlers
4651
4656
  // =========================================================================
4657
+ async handleSettingsFactoryReset() {
4658
+ if (this.session.isStreaming) {
4659
+ this.showWarning("Wait for the current response to finish before resetting settings.");
4660
+ return;
4661
+ }
4662
+ if (this.session.isCompacting) {
4663
+ this.showWarning("Wait for compaction to finish before resetting settings.");
4664
+ return;
4665
+ }
4666
+ const settingsPath = path.join(getAgentDir(), "settings.json");
4667
+ const confirmed = await this.showExtensionConfirm("Factory reset settings", `This replaces ${settingsPath} with the bundled factory defaults.\n\n`
4668
+ + "Your credentials (auth.json), sessions, extensions, skills, and themes are NOT touched.\n"
4669
+ + "A backup is saved next to the file before resetting.\n\n"
4670
+ + "Continue?");
4671
+ if (!confirmed) {
4672
+ this.showStatus("Settings factory reset cancelled.");
4673
+ return;
4674
+ }
4675
+ const bundledDefaultsDir = getBundledDefaultsDir();
4676
+ const bundledPath = path.join(bundledDefaultsDir, "settings.json");
4677
+ if (!fs.existsSync(bundledPath)) {
4678
+ this.showError(`Bundled defaults not found at ${bundledPath}`);
4679
+ return;
4680
+ }
4681
+ try {
4682
+ if (fs.existsSync(settingsPath)) {
4683
+ fs.copyFileSync(settingsPath, `${settingsPath}.bak`);
4684
+ }
4685
+ fs.copyFileSync(bundledPath, settingsPath);
4686
+ try {
4687
+ fs.chmodSync(settingsPath, 0o600);
4688
+ }
4689
+ catch {
4690
+ // chmod is best-effort (no-op on platforms that don't support it).
4691
+ }
4692
+ await this.session.reload();
4693
+ this.showStatus(`Settings reset to factory defaults (backup: ${settingsPath}.bak)`);
4694
+ }
4695
+ catch (error) {
4696
+ this.showError(`Settings factory reset failed: ${error instanceof Error ? error.message : String(error)}`);
4697
+ }
4698
+ }
4652
4699
  async handleReloadCommand() {
4653
4700
  if (this.session.isStreaming) {
4654
4701
  this.showWarning("Wait for the current response to finish before reloading.");
@@ -1,42 +1,26 @@
1
1
  # Quickstart
2
2
 
3
- This page gets you from install to a useful first pi session.
3
+ This page gets you from install to a useful first Selesai session.
4
4
 
5
5
  ## Install
6
6
 
7
- Pi is distributed as an npm package:
7
+ Selesai is distributed as an npm package:
8
8
 
9
9
  ```bash
10
- npm install -g --ignore-scripts @earendil-works/pi-coding-agent
10
+ npm install -g @selesai/code
11
11
  ```
12
12
 
13
- `--ignore-scripts` disables dependency lifecycle scripts during install. Pi does not require install scripts for normal npm installs.
14
-
15
- ### Uninstall
16
-
17
- Use the package manager that installed pi. The curl installer uses npm globally, so curl and npm installs are removed with npm:
13
+ Then start Selesai in the project directory you want it to work on:
18
14
 
19
15
  ```bash
20
- # curl installer or npm install -g
21
- npm uninstall -g @earendil-works/pi-coding-agent
22
-
23
- # pnpm
24
- pnpm remove -g @earendil-works/pi-coding-agent
25
-
26
- # Yarn
27
- yarn global remove @earendil-works/pi-coding-agent
28
-
29
- # Bun
30
- bun uninstall -g @earendil-works/pi-coding-agent
16
+ cd /path/to/project
17
+ selesai
31
18
  ```
32
19
 
33
- Uninstalling pi leaves settings, credentials, sessions, and installed pi packages in `~/.pi/agent/`.
34
-
35
- Then start pi in the project directory you want it to work on:
20
+ To install directly from the public repository (builds the latest `main` from source):
36
21
 
37
22
  ```bash
38
- cd /path/to/project
39
- pi
23
+ npm install -g github:SelesaiInTech/selesai-code
40
24
  ```
41
25
 
42
26
  ## Authenticate
@@ -45,7 +29,7 @@ Pi can use subscription providers through `/login`, or API-key providers through
45
29
 
46
30
  ### Option 1: subscription login
47
31
 
48
- Start pi and run:
32
+ Start Selesai and run:
49
33
 
50
34
  ```text
51
35
  /login
@@ -55,26 +39,26 @@ Then select a provider. Built-in subscription logins include Claude Pro/Max, Cha
55
39
 
56
40
  ### Option 2: API key
57
41
 
58
- Set an API key before launching pi:
42
+ Set an API key before launching Selesai:
59
43
 
60
44
  ```bash
61
45
  export ANTHROPIC_API_KEY=sk-ant-...
62
- pi
46
+ selesai
63
47
  ```
64
48
 
65
- You can also run `/login` and select an API-key provider to store the key in `~/.pi/agent/auth.json`.
49
+ You can also run `/login` and select an API-key provider to store the key in `~/.selesai/agent/auth.json`.
66
50
 
67
51
  See [Providers](providers.md) for all supported providers, environment variables, and cloud-provider setup.
68
52
 
69
53
  ## First session
70
54
 
71
- Once pi starts, type a request and press Enter:
55
+ Once Selesai starts, type a request and press Enter:
72
56
 
73
57
  ```text
74
58
  Summarize this repository and tell me how to run its checks.
75
59
  ```
76
60
 
77
- By default, pi gives the model four tools:
61
+ By default, Selesai gives the model four tools:
78
62
 
79
63
  - `read` - read files
80
64
  - `write` - create or overwrite files
@@ -83,7 +67,7 @@ By default, pi gives the model four tools:
83
67
 
84
68
  Additional built-in read-only tools (`grep`, `find`, `ls`) are available through tool options. Pi runs in your current working directory and can modify files there. Use git or another checkpointing workflow if you want easy rollback.
85
69
 
86
- ## Give pi project instructions
70
+ ## Give Selesai project instructions
87
71
 
88
72
  Pi loads context files at startup. Add an `AGENTS.md` file to tell it how to work in a project:
89
73
 
@@ -97,10 +81,10 @@ Pi loads context files at startup. Add an `AGENTS.md` file to tell it how to wor
97
81
 
98
82
  Pi loads:
99
83
 
100
- - `~/.pi/agent/AGENTS.md` for global instructions
84
+ - `~/.selesai/agent/AGENTS.md` for global instructions
101
85
  - `AGENTS.md` or `CLAUDE.md` from parent directories and the current directory
102
86
 
103
- Restart pi, or run `/reload`, after changing context files.
87
+ Restart Selesai, or run `/reload`, after changing context files.
104
88
 
105
89
  ## Common things to try
106
90
 
@@ -109,8 +93,8 @@ Restart pi, or run `/reload`, after changing context files.
109
93
  Type `@` in the editor to fuzzy-search files, or pass files on the command line:
110
94
 
111
95
  ```bash
112
- pi @README.md "Summarize this"
113
- pi @src/app.ts @src/app.test.ts "Review these together"
96
+ selesai @README.md "Summarize this"
97
+ selesai @src/app.ts @src/app.test.ts "Review these together"
114
98
  ```
115
99
 
116
100
  Images can be pasted with Ctrl+V (Alt+V on Windows) or dragged into supported terminals.
@@ -134,22 +118,22 @@ Use `/model` or Ctrl+L to choose a model. Use Shift+Tab to cycle thinking level.
134
118
  Sessions are saved automatically:
135
119
 
136
120
  ```bash
137
- pi -c # Continue most recent session
138
- pi -r # Browse previous sessions
139
- pi --name "my task" # Set session display name at startup
140
- pi --session <path|id> # Open a specific session
121
+ selesai -c # Continue most recent session
122
+ selesai -r # Browse previous sessions
123
+ selesai --name "my task" # Set session display name at startup
124
+ selesai --session <path|id> # Open a specific session
141
125
  ```
142
126
 
143
- Inside pi, use `/resume`, `/new`, `/tree`, `/fork`, and `/clone` to manage sessions.
127
+ Inside Selesai, use `/resume`, `/new`, `/tree`, `/fork`, and `/clone` to manage sessions.
144
128
 
145
129
  ### Non-interactive mode
146
130
 
147
131
  For one-shot prompts:
148
132
 
149
133
  ```bash
150
- pi -p "Summarize this codebase"
151
- cat README.md | pi -p "Summarize this text"
152
- pi -p @screenshot.png "What's in this image?"
134
+ selesai -p "Summarize this codebase"
135
+ cat README.md | selesai -p "Summarize this text"
136
+ selesai -p @screenshot.png "What's in this image?"
153
137
  ```
154
138
 
155
139
  Use `--mode json` for JSON event output or `--mode rpc` for process integration.
package/docs/settings.md CHANGED
@@ -322,3 +322,7 @@ Project settings (`.selesai/settings.json`) override global settings. Nested obj
322
322
  "compaction": { "enabled": true, "reserveTokens": 8192 }
323
323
  }
324
324
  ```
325
+
326
+ ## Factory Reset
327
+
328
+ Run `/settings-factory-reset` inside a session to restore the global settings file (`~/.selesai/agent/settings.json`) to the bundled factory defaults. The command warns before replacing the file, saves a backup as `settings.json.bak` next to it, and leaves credentials (`auth.json`), sessions, extensions, skills, and themes untouched. Settings take effect immediately after the reset (equivalent to `/reload`).
package/docs/usage.md CHANGED
@@ -43,6 +43,7 @@ Type `/` in the editor to open command completion. Extensions can register custo
43
43
  | `/model` | Switch models |
44
44
  | `/scoped-models` | Enable/disable models for Ctrl+P cycling |
45
45
  | `/settings` | Thinking level, theme, message delivery, transport |
46
+ | `/settings-factory-reset` | Reset settings to factory defaults (with confirmation) |
46
47
  | `/resume` | Pick from previous sessions |
47
48
  | `/new` | Start a new session |
48
49
  | `/name <name>` | Set session display name |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@selesai/code",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Maintained, extension-first Pi coding agent with built-in workflows, subagents, web research, questions, skills, and an enhanced terminal UI.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -50,6 +50,7 @@
50
50
  ],
51
51
  "scripts": {
52
52
  "clean": "shx rm -rf dist",
53
+ "prepare": "npm run build",
53
54
  "build": "npm run clean && tsgo -p tsconfig.build.json && shx chmod +x dist/cli.js dist/rpc-entry.js && npm run copy-assets",
54
55
  "copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/modes/interactive/assets && shx cp src/modes/interactive/assets/*.png dist/modes/interactive/assets/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/ && shx mkdir -p dist/defaults && shx cp src/defaults/* dist/defaults/ && shx mkdir -p dist/extensions && node scripts/copy-extensions.mjs && shx mkdir -p dist/themes && shx cp -r src/themes/. dist/themes/ && shx mkdir -p dist/skills && shx cp -r src/skills/. dist/skills/"
55
56
  },