@tt-a1i/openpi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +643 -0
- package/SETUP.md +74 -0
- package/THIRD_PARTY_NOTICES.md +16 -0
- package/assets/openpi-package.png +0 -0
- package/assets/readme-hero-mobile.svg +72 -0
- package/assets/readme-hero.svg +118 -0
- package/assets/readme-runtime-mobile.svg +91 -0
- package/assets/readme-runtime.svg +111 -0
- package/extensions/ask-user/handoff.ts +205 -0
- package/extensions/ask-user/index.ts +1110 -0
- package/extensions/ask-user/limits.ts +89 -0
- package/extensions/ask-user/prompt.ts +76 -0
- package/extensions/background-terminals/index.ts +653 -0
- package/extensions/background-terminals/src/domain.ts +99 -0
- package/extensions/background-terminals/src/manager.ts +989 -0
- package/extensions/background-terminals/src/output.ts +84 -0
- package/extensions/background-terminals/src/prompt.ts +195 -0
- package/extensions/background-terminals/src/result-delivery.ts +43 -0
- package/extensions/background-terminals/src/runtime.ts +36 -0
- package/extensions/background-terminals/src/ui/output-view.ts +55 -0
- package/extensions/background-terminals/src/ui/ps.ts +642 -0
- package/extensions/background-terminals/src/ui/tool-result.ts +146 -0
- package/extensions/background-terminals/src/watch.ts +192 -0
- package/extensions/context-pivot/index.ts +222 -0
- package/extensions/copy-all/index.ts +65 -0
- package/extensions/cron/index.ts +173 -0
- package/extensions/cron/schedule.ts +127 -0
- package/extensions/file-mutation-display/index.ts +105 -0
- package/extensions/file-mutation-display/render.ts +107 -0
- package/extensions/file-search/index.ts +515 -0
- package/extensions/file-search/src/args.ts +129 -0
- package/extensions/file-search/src/binaries.ts +419 -0
- package/extensions/file-search/src/output.ts +142 -0
- package/extensions/file-search/src/process.ts +309 -0
- package/extensions/file-search/src/prompt.ts +53 -0
- package/extensions/git-info/index.ts +272 -0
- package/extensions/git-info/src/changed-files-view.ts +414 -0
- package/extensions/git-info/src/process.ts +107 -0
- package/extensions/git-info/src/refresh-coordinator.ts +13 -0
- package/extensions/git-info/src/runtime.ts +28 -0
- package/extensions/goal/controller.ts +794 -0
- package/extensions/goal/index.ts +521 -0
- package/extensions/goal/prompts.ts +122 -0
- package/extensions/goal/state.ts +763 -0
- package/extensions/goal/ui.ts +158 -0
- package/extensions/model-info/index.ts +234 -0
- package/extensions/plan-mode/bash-policy.ts +313 -0
- package/extensions/plan-mode/index.ts +539 -0
- package/extensions/post-edit/index.ts +129 -0
- package/extensions/sessions/LICENSE.upstream +21 -0
- package/extensions/sessions/git-stats.ts +226 -0
- package/extensions/sessions/index.ts +1092 -0
- package/extensions/sessions/sessions.ts +385 -0
- package/extensions/setup/index.ts +408 -0
- package/extensions/shared/activity-status.ts +65 -0
- package/extensions/shared/below-editor-navigation.ts +343 -0
- package/extensions/shared/child-session.ts +352 -0
- package/extensions/shared/context-utilization.ts +47 -0
- package/extensions/shared/dashboard-state.ts +102 -0
- package/extensions/shared/plan-mode-state.ts +65 -0
- package/extensions/shared/setup-config.ts +971 -0
- package/extensions/shared/subagent-roles.ts +22 -0
- package/extensions/shared/terminal-text.ts +38 -0
- package/extensions/shared/tool-call-timeout.ts +104 -0
- package/extensions/shared/worktree.ts +526 -0
- package/extensions/subagents/index.ts +1225 -0
- package/extensions/subagents/navigation.ts +121 -0
- package/extensions/subagents/src/agent-types.ts +543 -0
- package/extensions/subagents/src/backend.ts +63 -0
- package/extensions/subagents/src/backends/pi.ts +493 -0
- package/extensions/subagents/src/backends/stub.ts +296 -0
- package/extensions/subagents/src/by-the-way.ts +21 -0
- package/extensions/subagents/src/domain.ts +271 -0
- package/extensions/subagents/src/format.ts +48 -0
- package/extensions/subagents/src/manager.ts +769 -0
- package/extensions/subagents/src/prompt.ts +190 -0
- package/extensions/subagents/src/result-delivery.ts +20 -0
- package/extensions/subagents/src/runtime.ts +51 -0
- package/extensions/subagents/src/ui/takeover.ts +615 -0
- package/extensions/subagents/src/ui/transcript.ts +293 -0
- package/extensions/subagents/src/ui/wait-result.ts +89 -0
- package/extensions/suggestions/index.ts +172 -0
- package/extensions/suggestions/src/config.ts +12 -0
- package/extensions/suggestions/src/predictor.ts +147 -0
- package/extensions/suggestions/src/prompt.ts +20 -0
- package/extensions/suggestions/src/transcript.ts +233 -0
- package/extensions/suggestions/src/ui.ts +224 -0
- package/extensions/tasks/index.ts +512 -0
- package/extensions/tasks/tasks.ts +649 -0
- package/extensions/tasks/ui.ts +421 -0
- package/extensions/turn-time/index.ts +61 -0
- package/extensions/ui-customization/footer.ts +512 -0
- package/extensions/ui-customization/index.ts +217 -0
- package/extensions/workflows/acceptance.ts +298 -0
- package/extensions/workflows/artifacts.ts +225 -0
- package/extensions/workflows/controller.ts +210 -0
- package/extensions/workflows/dashboard.ts +1226 -0
- package/extensions/workflows/index.ts +1884 -0
- package/extensions/workflows/journal.ts +188 -0
- package/extensions/workflows/meta.ts +250 -0
- package/extensions/workflows/model.ts +423 -0
- package/extensions/workflows/navigation.ts +93 -0
- package/extensions/workflows/prompt.ts +212 -0
- package/extensions/workflows/replay-safety.ts +577 -0
- package/extensions/workflows/runner.ts +786 -0
- package/extensions/workflows/sandbox-child.cjs +402 -0
- package/extensions/workflows/sandbox.ts +397 -0
- package/extensions/workflows/serialization.ts +162 -0
- package/extensions/workflows/worktree-handoff.ts +216 -0
- package/package.json +87 -0
- package/scripts/prepare-effect-tsgo.mjs +16 -0
- package/skills/background-terminals/SKILL.md +30 -0
- package/skills/subagents/SKILL.md +15 -0
- package/themes/github-dark-default.json +89 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import type { Worktree, WorktreeCleanup } from "../shared/worktree.ts";
|
|
5
|
+
import { writeFileAtomic } from "./serialization.ts";
|
|
6
|
+
|
|
7
|
+
export const WORKTREE_HANDOFF_VERSION = 1;
|
|
8
|
+
const PATCH_MAX_BYTES = 512 * 1024;
|
|
9
|
+
const MANIFEST_MAX_BYTES = 1024 * 1024;
|
|
10
|
+
const GIT_MAX_BUFFER = PATCH_MAX_BYTES + 64 * 1024;
|
|
11
|
+
const HANDOFF_GIT_TIMEOUT_MS = 5_000;
|
|
12
|
+
|
|
13
|
+
export interface WorktreeHandoffManifest {
|
|
14
|
+
readonly version: typeof WORKTREE_HANDOFF_VERSION;
|
|
15
|
+
readonly runId: string;
|
|
16
|
+
readonly agentIndex: number;
|
|
17
|
+
readonly agentLabel: string;
|
|
18
|
+
readonly repository: string;
|
|
19
|
+
readonly worktree: string;
|
|
20
|
+
readonly baseSha: string;
|
|
21
|
+
readonly headSha: string;
|
|
22
|
+
readonly branch?: string;
|
|
23
|
+
readonly detached: boolean;
|
|
24
|
+
readonly patch: {
|
|
25
|
+
readonly format: "git-diff-binary";
|
|
26
|
+
readonly content: string;
|
|
27
|
+
};
|
|
28
|
+
readonly numstat: string;
|
|
29
|
+
readonly nameStatus: string;
|
|
30
|
+
/** Names only. Their contents are not claimed to be captured by the patch. */
|
|
31
|
+
readonly untracked: readonly string[];
|
|
32
|
+
/** Names only. Their contents are not claimed to be captured by the patch. */
|
|
33
|
+
readonly ignored: readonly string[];
|
|
34
|
+
readonly cleanup?: WorktreeCleanup;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type WorktreeHandoffPreparation =
|
|
38
|
+
| {
|
|
39
|
+
readonly ok: true;
|
|
40
|
+
readonly artifact: string;
|
|
41
|
+
readonly absolutePath: string;
|
|
42
|
+
readonly manifest: WorktreeHandoffManifest;
|
|
43
|
+
}
|
|
44
|
+
| { readonly ok: false; readonly reason: string };
|
|
45
|
+
|
|
46
|
+
function boundedGit(cwd: string, args: readonly string[], deadline: number) {
|
|
47
|
+
const remaining = deadline - Date.now();
|
|
48
|
+
if (remaining <= 0) throw new Error("Git handoff deadline exceeded");
|
|
49
|
+
const output = execFileSync("git", ["-c", "core.fsmonitor=false", ...args], {
|
|
50
|
+
cwd,
|
|
51
|
+
encoding: "utf8",
|
|
52
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
53
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
54
|
+
timeout: Math.min(remaining, HANDOFF_GIT_TIMEOUT_MS),
|
|
55
|
+
});
|
|
56
|
+
if (output.includes("\uFFFD")) {
|
|
57
|
+
throw new Error("Git handoff output is not valid UTF-8");
|
|
58
|
+
}
|
|
59
|
+
return output;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function nulPaths(value: string) {
|
|
63
|
+
if (value.includes("\uFFFD")) {
|
|
64
|
+
throw new Error("Git path inventory is not valid UTF-8");
|
|
65
|
+
}
|
|
66
|
+
return value.split("\0").filter(Boolean).sort();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function boundedError(error: unknown) {
|
|
70
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
71
|
+
return text.slice(0, 4096);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function serializeCompleteManifest(manifest: WorktreeHandoffManifest) {
|
|
75
|
+
const serialized = JSON.stringify(manifest, null, 2);
|
|
76
|
+
const bytes = Buffer.byteLength(serialized, "utf8");
|
|
77
|
+
if (bytes > MANIFEST_MAX_BYTES) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`worktree handoff manifest exceeded ${MANIFEST_MAX_BYTES} bytes`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
return serialized;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Persist the complete tracked Git handoff before cleanup is allowed. A failure
|
|
87
|
+
* returns `ok:false`; callers must preserve the checkout instead of guessing.
|
|
88
|
+
*/
|
|
89
|
+
export function prepareWorktreeHandoff(options: {
|
|
90
|
+
runDir: string;
|
|
91
|
+
runId: string;
|
|
92
|
+
agentIndex: number;
|
|
93
|
+
agentLabel: string;
|
|
94
|
+
repoCwd: string;
|
|
95
|
+
worktree: Worktree;
|
|
96
|
+
}): WorktreeHandoffPreparation {
|
|
97
|
+
const deadline = Date.now() + HANDOFF_GIT_TIMEOUT_MS;
|
|
98
|
+
const git = (cwd: string, args: readonly string[]) =>
|
|
99
|
+
boundedGit(cwd, args, deadline);
|
|
100
|
+
try {
|
|
101
|
+
if (!options.worktree.baseSha) {
|
|
102
|
+
return { ok: false, reason: "worktree creation baseline is unknown" };
|
|
103
|
+
}
|
|
104
|
+
const repository = fs.realpathSync.native(
|
|
105
|
+
git(options.repoCwd, ["rev-parse", "--show-toplevel"]).trim(),
|
|
106
|
+
);
|
|
107
|
+
const worktree = fs.realpathSync.native(options.worktree.path);
|
|
108
|
+
const common = fs.realpathSync.native(
|
|
109
|
+
path.resolve(
|
|
110
|
+
options.repoCwd,
|
|
111
|
+
git(options.repoCwd, ["rev-parse", "--git-common-dir"]).trim(),
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
if (worktree !== common && !worktree.startsWith(`${common}${path.sep}`)) {
|
|
115
|
+
return {
|
|
116
|
+
ok: false,
|
|
117
|
+
reason: "worktree path escaped the repository Git directory",
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const headSha = git(worktree, ["rev-parse", "--verify", "HEAD"]).trim();
|
|
122
|
+
let branch = "";
|
|
123
|
+
try {
|
|
124
|
+
branch = git(worktree, [
|
|
125
|
+
"symbolic-ref",
|
|
126
|
+
"--quiet",
|
|
127
|
+
"--short",
|
|
128
|
+
"HEAD",
|
|
129
|
+
]).trim();
|
|
130
|
+
} catch {
|
|
131
|
+
// A detached HEAD is valid, but cleanup will preserve productive ones.
|
|
132
|
+
}
|
|
133
|
+
const detached = !branch;
|
|
134
|
+
let patch: string;
|
|
135
|
+
try {
|
|
136
|
+
patch = git(worktree, [
|
|
137
|
+
"diff",
|
|
138
|
+
"--no-ext-diff",
|
|
139
|
+
"--no-textconv",
|
|
140
|
+
"--binary",
|
|
141
|
+
options.worktree.baseSha,
|
|
142
|
+
"--",
|
|
143
|
+
]);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
return {
|
|
146
|
+
ok: false,
|
|
147
|
+
reason: `could not capture bounded binary patch: ${boundedError(error)}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (Buffer.byteLength(patch, "utf8") > PATCH_MAX_BYTES) {
|
|
151
|
+
return {
|
|
152
|
+
ok: false,
|
|
153
|
+
reason: `binary patch exceeded ${PATCH_MAX_BYTES} bytes`,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const manifest: WorktreeHandoffManifest = {
|
|
158
|
+
version: WORKTREE_HANDOFF_VERSION,
|
|
159
|
+
runId: options.runId,
|
|
160
|
+
agentIndex: options.agentIndex,
|
|
161
|
+
agentLabel: options.agentLabel,
|
|
162
|
+
repository,
|
|
163
|
+
worktree,
|
|
164
|
+
baseSha: options.worktree.baseSha,
|
|
165
|
+
headSha,
|
|
166
|
+
...(branch ? { branch } : {}),
|
|
167
|
+
detached,
|
|
168
|
+
patch: { format: "git-diff-binary", content: patch },
|
|
169
|
+
numstat: git(worktree, [
|
|
170
|
+
"diff",
|
|
171
|
+
"--no-ext-diff",
|
|
172
|
+
"--no-textconv",
|
|
173
|
+
"--numstat",
|
|
174
|
+
options.worktree.baseSha,
|
|
175
|
+
"--",
|
|
176
|
+
]),
|
|
177
|
+
nameStatus: git(worktree, [
|
|
178
|
+
"diff",
|
|
179
|
+
"--no-ext-diff",
|
|
180
|
+
"--no-textconv",
|
|
181
|
+
"--name-status",
|
|
182
|
+
options.worktree.baseSha,
|
|
183
|
+
"--",
|
|
184
|
+
]),
|
|
185
|
+
untracked: nulPaths(
|
|
186
|
+
git(worktree, ["ls-files", "--others", "--exclude-standard", "-z"]),
|
|
187
|
+
),
|
|
188
|
+
ignored: nulPaths(
|
|
189
|
+
git(worktree, [
|
|
190
|
+
"ls-files",
|
|
191
|
+
"--others",
|
|
192
|
+
"--ignored",
|
|
193
|
+
"--exclude-standard",
|
|
194
|
+
"-z",
|
|
195
|
+
]),
|
|
196
|
+
),
|
|
197
|
+
};
|
|
198
|
+
// An inventory is not a content backup. Cleanup will preserve these trees,
|
|
199
|
+
// and the manifest says exactly what was not captured.
|
|
200
|
+
const artifact = path.join("worktrees", `agent-${options.agentIndex}.json`);
|
|
201
|
+
const absolutePath = path.join(options.runDir, artifact);
|
|
202
|
+
writeFileAtomic(absolutePath, serializeCompleteManifest(manifest));
|
|
203
|
+
return { ok: true, artifact, absolutePath, manifest };
|
|
204
|
+
} catch (error) {
|
|
205
|
+
return { ok: false, reason: boundedError(error) };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function finalizeWorktreeHandoff(
|
|
210
|
+
prepared: Extract<WorktreeHandoffPreparation, { ok: true }>,
|
|
211
|
+
cleanup: WorktreeCleanup,
|
|
212
|
+
) {
|
|
213
|
+
const manifest = { ...prepared.manifest, cleanup };
|
|
214
|
+
writeFileAtomic(prepared.absolutePath, serializeCompleteManifest(manifest));
|
|
215
|
+
return manifest;
|
|
216
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tt-a1i/openpi",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OpenPI — a Pi-native multi-agent workbench with background execution, isolated subagents, replay-safe workflows, goals, tasks, and observable TUI",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"author": "tt-a1i",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"pi-package",
|
|
9
|
+
"pi",
|
|
10
|
+
"coding-agent",
|
|
11
|
+
"multi-agent",
|
|
12
|
+
"subagents",
|
|
13
|
+
"workflows"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/tt-a1i/my-pi-setup.git"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/tt-a1i/my-pi-setup#readme",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/tt-a1i/my-pi-setup/issues"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"extensions",
|
|
25
|
+
"!extensions/**/*.test.ts",
|
|
26
|
+
"!extensions/**/*.spec.ts",
|
|
27
|
+
"!extensions/**/tsconfig.json",
|
|
28
|
+
"!extensions/*/docs",
|
|
29
|
+
"skills",
|
|
30
|
+
"themes",
|
|
31
|
+
"assets",
|
|
32
|
+
"scripts/prepare-effect-tsgo.mjs",
|
|
33
|
+
"README.md",
|
|
34
|
+
"SETUP.md",
|
|
35
|
+
"THIRD_PARTY_NOTICES.md"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"pi": {
|
|
41
|
+
"extensions": [
|
|
42
|
+
"./extensions"
|
|
43
|
+
],
|
|
44
|
+
"skills": [
|
|
45
|
+
"./skills"
|
|
46
|
+
],
|
|
47
|
+
"themes": [
|
|
48
|
+
"./themes"
|
|
49
|
+
],
|
|
50
|
+
"image": "https://raw.githubusercontent.com/tt-a1i/my-pi-setup/main/assets/openpi-package.png"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@effect/platform-node": "^4.0.0-beta.99",
|
|
54
|
+
"acorn": "^8.17.0",
|
|
55
|
+
"effect": "^4.0.0-beta.99"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@earendil-works/pi-ai": "^0.84.1",
|
|
59
|
+
"@earendil-works/pi-coding-agent": "^0.84.1",
|
|
60
|
+
"@earendil-works/pi-tui": "^0.84.1",
|
|
61
|
+
"@effect/tsgo": "^0.24.2",
|
|
62
|
+
"@effect/vitest": "^4.0.0-beta.99",
|
|
63
|
+
"@types/node": "^26.1.1",
|
|
64
|
+
"prettier": "^3.9.5",
|
|
65
|
+
"typebox": "^1.3.6",
|
|
66
|
+
"typescript": "^7.0.2",
|
|
67
|
+
"vitest": "4.1.10"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"@earendil-works/pi-ai": "*",
|
|
71
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
72
|
+
"@earendil-works/pi-tui": "*",
|
|
73
|
+
"typebox": "*"
|
|
74
|
+
},
|
|
75
|
+
"type": "module",
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=22.19.0"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"prepublishOnly": "npm run format:check && npm run check && npm test",
|
|
81
|
+
"check": "tsc --noEmit",
|
|
82
|
+
"prepare": "node scripts/prepare-effect-tsgo.mjs",
|
|
83
|
+
"format": "prettier --write \"extensions/**/*.{ts,cjs}\" \"scripts/**/*.{js,mjs,cjs,ts}\" \".github/**/*.{yml,yaml}\" \"*.json\"",
|
|
84
|
+
"format:check": "prettier --check \"extensions/**/*.{ts,cjs}\" \"scripts/**/*.{js,mjs,cjs,ts}\" \".github/**/*.{yml,yaml}\" \"*.json\"",
|
|
85
|
+
"test": "node --test --experimental-strip-types extensions/*/*.test.ts && vitest run extensions/file-search/index.spec.ts"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
|
|
4
|
+
let cli;
|
|
5
|
+
try {
|
|
6
|
+
cli = fileURLToPath(import.meta.resolve("@effect/tsgo/dist/effect-tsgo.js"));
|
|
7
|
+
} catch (error) {
|
|
8
|
+
if (error?.code === "ERR_MODULE_NOT_FOUND") process.exit(0);
|
|
9
|
+
throw error;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const result = spawnSync(process.execPath, [cli, "patch"], {
|
|
13
|
+
stdio: "inherit",
|
|
14
|
+
});
|
|
15
|
+
if (result.error) throw result.error;
|
|
16
|
+
process.exit(result.status ?? 1);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: background-terminals
|
|
3
|
+
description: Run and manage long-lived shell commands in background terminals. Use for dev servers, watchers, streaming builds, and other commands that should keep running while the agent continues working.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Background Terminals
|
|
7
|
+
|
|
8
|
+
Use `bg_start` for long-running commands; use regular `bash` for quick commands.
|
|
9
|
+
|
|
10
|
+
## Start
|
|
11
|
+
|
|
12
|
+
Call `bg_start` with:
|
|
13
|
+
|
|
14
|
+
- `command`: shell command to run
|
|
15
|
+
- `title`: short recognizable label
|
|
16
|
+
- `working_dir`: project directory when different from the current directory
|
|
17
|
+
- `timeout_seconds`: optional deadline for finite work such as builds, tests, or migrations; omit for servers and watchers
|
|
18
|
+
|
|
19
|
+
Background commands receive no stdin. Never use them for interactive prompts.
|
|
20
|
+
|
|
21
|
+
After starting, continue useful work instead of polling. The terminal sends one completion message when it exits or times out.
|
|
22
|
+
|
|
23
|
+
## Inspect and stop
|
|
24
|
+
|
|
25
|
+
- Use `bg_status` only when current output or status is needed.
|
|
26
|
+
- Use `bg_list` to inventory all tracked terminals.
|
|
27
|
+
- Use `bg_kill` when a process is no longer needed or is stuck; termination continues even if the tool wait is aborted.
|
|
28
|
+
- Tell the user they can open `/ps` to inspect live output and kill terminals interactively.
|
|
29
|
+
|
|
30
|
+
Prefer meaningful titles and avoid starting duplicate servers or watchers. Full output is captured to spill files; tool and completion output shows a concise tail. Terminals are session-scoped and are stopped during shutdown or reload.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: subagents
|
|
3
|
+
description: Invoke this skill when the user asks to use subagents or when a substantial, self-contained task can run independently in the background.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Subagents
|
|
7
|
+
|
|
8
|
+
The tool definitions are canonical for parameters, limits, model syntax, isolation, and lifecycle commands. This skill governs delegation decisions only.
|
|
9
|
+
|
|
10
|
+
- Delegate substantial independent work, not a lookup or edit the parent can do directly.
|
|
11
|
+
- Give the child a standalone prompt with paths, constraints, relevant context, and the expected report; it cannot see the parent conversation or ask the user.
|
|
12
|
+
- Inherit the parent model and thinking level by default. Override them only for an explicit user request or concrete task requirement.
|
|
13
|
+
- Prefer a matching agent type when one exists; its tool restriction is enforced. An explicit spawn model or reasoning effort wins, otherwise use the type default then inherit the parent. Types live in `~/.pi/agent/agents/*.md` and, for trusted projects, `.pi/agents/*.md`; see `extensions/subagents/docs/agent-types.md`.
|
|
14
|
+
- Isolate concurrent writers in worktrees according to the `subagent_spawn` schema so they cannot overwrite one checkout or git index. While Plan Mode is active, use only read-only exploration types (or no type); worktree isolation and types narrowed by Plan Mode are rejected.
|
|
15
|
+
- After spawning, continue useful parent work. Let automatic result delivery drive the next turn; block only when the immediate next step truly depends on that result.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/earendil-works/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
|
+
"name": "github-dark-default",
|
|
4
|
+
"vars": {
|
|
5
|
+
"bg": "#0d1117",
|
|
6
|
+
"panel": "#010409",
|
|
7
|
+
"surface": "#161b22",
|
|
8
|
+
"border": "#30363d",
|
|
9
|
+
"borderMuted": "#21262d",
|
|
10
|
+
"accent": "#2f81f7",
|
|
11
|
+
"focus": "#1f6feb",
|
|
12
|
+
"text": "#e6edf3",
|
|
13
|
+
"muted": "#7d8590",
|
|
14
|
+
"dim": "#6e7681",
|
|
15
|
+
"green": "#3fb950",
|
|
16
|
+
"red": "#f85149",
|
|
17
|
+
"yellow": "#d29922",
|
|
18
|
+
"purple": "#d2a8ff",
|
|
19
|
+
"orange": "#ffa657",
|
|
20
|
+
"cyan": "#79c0ff",
|
|
21
|
+
"string": "#a5d6ff",
|
|
22
|
+
"softGreen": "#7ee787",
|
|
23
|
+
"softRed": "#ff7b72"
|
|
24
|
+
},
|
|
25
|
+
"colors": {
|
|
26
|
+
"accent": "accent",
|
|
27
|
+
"border": "border",
|
|
28
|
+
"borderAccent": "focus",
|
|
29
|
+
"borderMuted": "borderMuted",
|
|
30
|
+
"success": "green",
|
|
31
|
+
"error": "red",
|
|
32
|
+
"warning": "yellow",
|
|
33
|
+
"muted": "muted",
|
|
34
|
+
"dim": "dim",
|
|
35
|
+
"text": "text",
|
|
36
|
+
"thinkingText": "muted",
|
|
37
|
+
|
|
38
|
+
"selectedBg": "#13233a",
|
|
39
|
+
"userMessageBg": "surface",
|
|
40
|
+
"userMessageText": "text",
|
|
41
|
+
"customMessageBg": "surface",
|
|
42
|
+
"customMessageText": "text",
|
|
43
|
+
"customMessageLabel": "accent",
|
|
44
|
+
"toolPendingBg": "surface",
|
|
45
|
+
"toolSuccessBg": "surface",
|
|
46
|
+
"toolErrorBg": "#2b1618",
|
|
47
|
+
"toolTitle": "accent",
|
|
48
|
+
"toolOutput": "muted",
|
|
49
|
+
|
|
50
|
+
"mdHeading": "cyan",
|
|
51
|
+
"mdLink": "accent",
|
|
52
|
+
"mdLinkUrl": "muted",
|
|
53
|
+
"mdCode": "cyan",
|
|
54
|
+
"mdCodeBlock": "text",
|
|
55
|
+
"mdCodeBlockBorder": "border",
|
|
56
|
+
"mdQuote": "muted",
|
|
57
|
+
"mdQuoteBorder": "border",
|
|
58
|
+
"mdHr": "borderMuted",
|
|
59
|
+
"mdListBullet": "orange",
|
|
60
|
+
|
|
61
|
+
"toolDiffAdded": "green",
|
|
62
|
+
"toolDiffRemoved": "red",
|
|
63
|
+
"toolDiffContext": "muted",
|
|
64
|
+
|
|
65
|
+
"syntaxComment": "#8b949e",
|
|
66
|
+
"syntaxKeyword": "softRed",
|
|
67
|
+
"syntaxFunction": "purple",
|
|
68
|
+
"syntaxVariable": "orange",
|
|
69
|
+
"syntaxString": "string",
|
|
70
|
+
"syntaxNumber": "cyan",
|
|
71
|
+
"syntaxType": "softGreen",
|
|
72
|
+
"syntaxOperator": "text",
|
|
73
|
+
"syntaxPunctuation": "dim",
|
|
74
|
+
|
|
75
|
+
"thinkingOff": "dim",
|
|
76
|
+
"thinkingMinimal": "muted",
|
|
77
|
+
"thinkingLow": "accent",
|
|
78
|
+
"thinkingMedium": "cyan",
|
|
79
|
+
"thinkingHigh": "purple",
|
|
80
|
+
"thinkingXhigh": "softRed",
|
|
81
|
+
|
|
82
|
+
"bashMode": "green"
|
|
83
|
+
},
|
|
84
|
+
"export": {
|
|
85
|
+
"pageBg": "bg",
|
|
86
|
+
"cardBg": "panel",
|
|
87
|
+
"infoBg": "surface"
|
|
88
|
+
}
|
|
89
|
+
}
|