@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.
- package/CHANGELOG.md +10 -0
- package/README.md +7 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/defaults/models.json +41 -55
- package/dist/defaults/settings.json +7 -8
- package/dist/extensions/pi-subagents/CHANGELOG.md +26 -3
- package/dist/extensions/pi-subagents/README.md +2 -0
- package/dist/extensions/pi-subagents/docs/configuration.md +46 -2
- package/dist/extensions/pi-subagents/docs/observability.md +1 -1
- package/dist/extensions/pi-subagents/docs/tool-reference.md +1 -1
- package/dist/extensions/pi-subagents/package-lock.json +2 -2
- package/dist/extensions/pi-subagents/package.json +1 -1
- package/dist/extensions/pi-subagents/src/agents/agents.ts +9 -3
- package/dist/extensions/pi-subagents/src/extension/config.ts +6 -0
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +40 -0
- package/dist/extensions/pi-subagents/src/extension/index.ts +21 -0
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +5 -0
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +3 -9
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +2 -2
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -1
- package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +4 -7
- package/dist/extensions/pi-subagents/src/missions/store.ts +4 -4
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +6 -2
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +374 -0
- package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +9 -5
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +117 -29
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +7 -1
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +11 -5
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +33 -15
- package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +104 -0
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +17 -3
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +5 -1
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +84 -36
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +37 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +135 -22
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +12 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +171 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +614 -187
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +13 -4
- package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +286 -0
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +23 -0
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +44 -1
- package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +280 -0
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +4 -2
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +19 -3
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +17 -5
- package/dist/extensions/pi-subagents/src/shared/types.ts +92 -0
- package/dist/extensions/pi-subagents/src/shared/utils.ts +3 -1
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +7 -5
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +225 -12
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +22 -5
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +96 -6
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +28 -5
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +8 -5
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +83 -2
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +211 -15
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +41 -3
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +314 -10
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +31 -1
- package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +317 -0
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +21 -2
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +16 -1
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +6 -1
- package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +75 -4
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +29 -1
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +31 -5
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +139 -1
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +2 -1
- package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +171 -0
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +30 -4
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +69 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +83 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +55 -2
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +12 -1
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +7 -7
- package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +121 -0
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +9 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +4 -3
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +28 -0
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +10 -1
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +39 -0
- package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +65 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +61 -0
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.js +48 -1
- package/docs/quickstart.md +27 -43
- package/docs/settings.md +4 -0
- package/docs/usage.md +1 -0
- 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.");
|
package/docs/quickstart.md
CHANGED
|
@@ -1,42 +1,26 @@
|
|
|
1
1
|
# Quickstart
|
|
2
2
|
|
|
3
|
-
This page gets you from install to a useful first
|
|
3
|
+
This page gets you from install to a useful first Selesai session.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Selesai is distributed as an npm package:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install -g
|
|
10
|
+
npm install -g @selesai/code
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
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
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
42
|
+
Set an API key before launching Selesai:
|
|
59
43
|
|
|
60
44
|
```bash
|
|
61
45
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
62
|
-
|
|
46
|
+
selesai
|
|
63
47
|
```
|
|
64
48
|
|
|
65
|
-
You can also run `/login` and select an API-key provider to store the key in `~/.
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
- `~/.
|
|
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
|
|
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
|
-
|
|
113
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
|
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
|
-
|
|
151
|
-
cat README.md |
|
|
152
|
-
|
|
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.
|
|
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
|
},
|