pi-plus 0.1.15 → 0.1.17
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 +2 -0
- package/README.md +45 -2
- package/api.d.ts +44 -0
- package/api.js +2368 -0
- package/package.json +13 -3
- package/pipi.js +17 -16
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
### Added
|
|
12
12
|
|
|
13
|
+
- `/cd <dir>` moves the session to a different working directory: the session file relocates to the target cwd's default session dir with only its header `cwd` rewritten (id, timestamp, and entries untouched — the same conversation, not a fork), the runtime then switches to it so tools, extensions, project settings, trust, and the system prompt re-bind to the new directory, and the old session file is removed once the switch completes. `/cd` with no argument shows the current cwd. A session that has not been persisted yet (no messages) starts directly in the target directory.
|
|
14
|
+
- The published `pi-plus` package gains a programmatic library entry alongside the `pipi` CLI: `import { createPlusAgentSession, createPlusUIContext, plusSdkExtensionFactories } from "pi-plus"` lets a host application (e.g. a desktop app) embed pi with the full pi-plus layer in-process — the compaction/context/reasoning overrides are baked into `api.js` by the same bundle-time redirect plugin as the CLI, and the seven non-TUI pi-plus extensions (subagent, tasks, memory, plan, ask-user, hooks, context-guard) are registered the same way the CLI wrapper registers them. `createPlusAgentSession()` composes the upstream `createAgentSession` with a `DefaultResourceLoader` carrying those factories, reloads it, and binds extensions once (emitting `session_start`); hosts pass dialog handlers via the `ui` option to get working `ask_user` questions (select/confirm/input bridged to native UI), or omit it for a headless session. The staged package.json now has an `exports` map (deep imports are closed off), ships a hand-authored `api.d.ts` re-exporting `@earendil-works/pi-coding-agent` types (added as an exact-pinned dependency for type resolution only; the runtime stays self-contained), and builds `api.js` as a second esbuild entry, roughly doubling the artifact size. Hosts without a pi CLI on PATH should pass `excludeTools: ["subagent"]`: the subagent tool launches a pi subprocess and could otherwise relaunch the host app itself.
|
|
13
15
|
- The tab-title spinner now also runs while context compaction is in progress (manual `/compact` when idle, or automatic/overflow compaction mid-run): `session_before_compact` marks compaction active and `session_compact`/`session_compact_failed` clear it, so a backgrounded tab shows at a glance that a long compaction is running. The spinner stops only when neither the agent run nor compaction is active, so mid-run compaction (which settles the run before retrying) no longer leaves the tab static.
|
|
14
16
|
- A `<tasks>` system-prompt section (registered by the `pi-plus-tasks` extension on every agent start) nudging the model to break non-trivial multi-step work into TaskCreate tasks and update statuses as it goes, and listing the session's current tasks (with status and blockers) when non-empty so resumed sessions can pick up where they left off.
|
|
15
17
|
- A `<subagents>` system-prompt section (registered by the `pi-plus-subagent` extension on every agent start) nudging the model to delegate self-contained work units via the `subagent` tool — including complete, self-contained prompts and concurrent calls in one turn — and listing the agent types available in this session (built-in `worker`/`explore` plus user- and project-defined agents) with their source, tools, and model.
|
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ Ports Claude Code semantics (reference: `../free-code/`, CC v2.1.87) onto pi's c
|
|
|
20
20
|
12. **Long-term memory** (`src/extensions/memory/`, openclaude memdir/extractMemories style) — per-project memories as markdown files with frontmatter (`name`, `description`, `type`: user/feedback/project/reference) under `<agent dir>/memory/<project-key>/`, indexed in `MEMORY.md` (200-line / 25 KB caps). The `memory_save`/`memory_recall` tools let the model persist and search durable facts; the index is injected as a `<memory>` system-prompt section each run; `/memory` browses/edits/adds/forgets. At `agent_settled` a background sub-agent restricted to the two memory tools reviews the conversation and saves noteworthy facts (skipped when the main agent already saved one, below `extractMinMessages` new messages, or within `extractCooldownMs`). Toggle via the `"memory"` key in settings.json (`enabled`, `autoExtract`, `extractMinMessages`, `extractCooldownMs`; project > agent dir > `~/.pi`).
|
|
21
21
|
13. **Tab title + busy spinner** (`src/extensions/tab-title/`) — the terminal window/tab title brands as `pi+ - [sessionName -] cwdBasename` (via the `config.ts` wrapper's `APP_TITLE`, which upstream's `updateTerminalTitle` also uses, so both paths agree). While the agent is working (`agent_start` until `agent_settled`/`turn_end`) or context compaction is running (`session_before_compact` until `session_compact`/`session_compact_failed`, covering manual `/compact` when idle and auto/overflow compaction mid-run), a braille spinner frame is prepended to the title and ticks every 120 ms, so a backgrounded tab shows at a glance that pi+ is busy. TUI mode only; the ticker is cleared on session shutdown.
|
|
22
22
|
14. **Plain tool blocks** (`src/extensions/plain-tools/`) — strips the background fills upstream paints on tool result blocks (`toolPendingBg` while running, `toolSuccessBg`/`toolErrorBg` on completion, including edit diff boxes), so tool status reads as text — words like `Command exited with code 3` and the subagent tool's `running` / `✓ done` / `✗ failed` — instead of colored blocks. Implemented as a one-time `Theme.prototype.bg` wrapper (idempotent, applied at extension registration), so it holds across theme switches and spares every other background token (selections, user message bubble).
|
|
23
|
+
15. **`/cd` working-directory switch** (`src/extensions/cd/`) — `/cd <dir>` moves the session to a different working directory. pi binds a session's cwd at runtime creation (tools, extensions, project settings, trust), so the command works by relocation rather than an in-place flip: the session file is rewritten into the target cwd's default session dir with only its header `cwd` changed (id, timestamp, and entries preserved — the same conversation, not a fork), the runtime's session replacement then switches to it so everything re-binds to the new directory, and the old session file is removed once the switch completes. `/cd` alone prints the current cwd; a not-yet-persisted session starts directly in the target dir.
|
|
23
24
|
|
|
24
25
|
The CLI identifies as **`pipi`** (pi-plus) in CLI text via the `config.ts` wrapper's `APP_NAME` shadow; the terminal tab title brands as **`pi+`** via the `APP_TITLE` shadow. Scope is the display name only — config dir (`.pi`), `PI_`-prefixed env vars, and session layout stay pi's.
|
|
25
26
|
|
|
@@ -88,14 +89,56 @@ npm publish --access public --ignore-scripts # in packages/plus/dist/npm
|
|
|
88
89
|
|
|
89
90
|
The bundle applies `loader/redirects.mjs` at bundle time (esbuild plugin) and keeps each
|
|
90
91
|
module a singleton by funneling every `packages/*/src/**` import with a compiled `dist/`
|
|
91
|
-
counterpart to that dist file. `--no-env` is preserved via a banner scrub
|
|
92
|
-
|
|
92
|
+
counterpart to that dist file. `--no-env` is preserved via a banner scrub (inert for
|
|
93
|
+
library imports: it only scrubs when `process.argv` contains a literal `--no-env`).
|
|
94
|
+
Provider credentials, config dir (`~/.pi`), and session layout are identical to
|
|
95
|
+
source-mode `pipi`.
|
|
96
|
+
|
|
97
|
+
### Programmatic API (library hosts)
|
|
98
|
+
|
|
99
|
+
The same package also exposes a programmatic entry for hosts that embed pi-plus
|
|
100
|
+
in-process (e.g. a desktop app) instead of running the `pipi` CLI:
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
import { createPlusAgentSession } from "pi-plus";
|
|
104
|
+
|
|
105
|
+
const { session } = await createPlusAgentSession({
|
|
106
|
+
cwd: projectDir,
|
|
107
|
+
ui: {
|
|
108
|
+
select: async (title, options) => showPicker(title, options),
|
|
109
|
+
confirm: async (title, message) => showConfirm(title, message),
|
|
110
|
+
input: async (title, placeholder) => showInput(title, placeholder),
|
|
111
|
+
},
|
|
112
|
+
// Hosts without a pi CLI on PATH should exclude the subagent tool: it
|
|
113
|
+
// launches a pi subprocess and could otherwise relaunch the host app.
|
|
114
|
+
excludeTools: ["subagent"],
|
|
115
|
+
});
|
|
116
|
+
await session.prompt("Review this repository");
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- The full pi-plus layer is included: the compaction/context/reasoning overrides are
|
|
120
|
+
baked into `api.js` by the same bundle-time redirect plugin as the CLI, and the seven
|
|
121
|
+
non-TUI pi-plus extensions (subagent, tasks, memory, plan, ask-user, hooks,
|
|
122
|
+
context-guard) are registered exactly as the CLI wrapper registers them.
|
|
123
|
+
- `createPlusAgentSession()` extends the upstream `createAgentSession` (re-exported, with
|
|
124
|
+
the whole upstream SDK surface) with those extension factories, and always binds
|
|
125
|
+
extensions once — do not call `session.bindExtensions()` yourself. Pass `ui` dialog
|
|
126
|
+
handlers to get working `ask_user` questions (bound with mode `"rpc"`, so the tool
|
|
127
|
+
falls back to sequential select/input/confirm dialogs bridged to your UI); omit `ui`
|
|
128
|
+
for a headless session.
|
|
129
|
+
- The staged `package.json` has an `exports` map, so deep imports (e.g.
|
|
130
|
+
`pi-plus/pipi.js`) are no longer reachable; `api.d.ts` re-exports the
|
|
131
|
+
`@earendil-works/pi-coding-agent` types (exact-pinned dependency, type resolution
|
|
132
|
+
only — the runtime is self-contained). Building `api.js` as a second esbuild entry
|
|
133
|
+
roughly doubles the artifact size.
|
|
93
134
|
|
|
94
135
|
Known limitations of the compiled artifact:
|
|
95
136
|
|
|
96
137
|
- `pipi server` / `pipi client` experimental subcommands (`PI_EXPERIMENTAL=1`) spawn sibling JS
|
|
97
138
|
files that are not emitted next to the bundle; use source-mode `./pipi` for those.
|
|
98
139
|
- `docs/` and `examples/` are not shipped, so `/docs`-style paths into them are absent.
|
|
140
|
+
- Hub profile resolution (`pipi --as <name>`, `pipi profile …`) is CLI-launch logic and is
|
|
141
|
+
not part of the programmatic entry; SDK hosts pass `cwd`/`agentDir` explicitly.
|
|
99
142
|
|
|
100
143
|
## Tests
|
|
101
144
|
|
package/api.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public type contract for the "pi-plus" npm package's programmatic entry
|
|
3
|
+
* (api.js). Hand-authored mirror of src/api.ts: the runtime is fully
|
|
4
|
+
* self-contained in api.js (built from this repo with the pi-plus override
|
|
5
|
+
* layer baked in), so this file only needs to re-export the upstream SDK
|
|
6
|
+
* types and declare the pi-plus additions. A vitest drift guard
|
|
7
|
+
* (test/api.test.ts) asserts every runtime export of src/api.ts appears here.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from "@earendil-works/pi-coding-agent";
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
CreateAgentSessionOptions,
|
|
14
|
+
CreateAgentSessionResult,
|
|
15
|
+
ExtensionCommandContextActions,
|
|
16
|
+
ExtensionError,
|
|
17
|
+
ExtensionUIContext,
|
|
18
|
+
InlineExtension,
|
|
19
|
+
} from "@earendil-works/pi-coding-agent";
|
|
20
|
+
|
|
21
|
+
export declare const plusSdkExtensionFactories: InlineExtension[];
|
|
22
|
+
|
|
23
|
+
export interface PlusUIDialogHandlers {
|
|
24
|
+
select(title: string, options: string[]): Promise<string | undefined>;
|
|
25
|
+
confirm(title: string, message: string): Promise<boolean>;
|
|
26
|
+
input(title: string, placeholder?: string): Promise<string | undefined>;
|
|
27
|
+
editor?(title: string, prefill?: string): Promise<string | undefined>;
|
|
28
|
+
notify?(message: string, type?: "info" | "warning" | "error"): void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export declare function createPlusUIContext(handlers: PlusUIDialogHandlers): ExtensionUIContext;
|
|
32
|
+
|
|
33
|
+
export interface CreatePlusAgentSessionOptions extends CreateAgentSessionOptions {
|
|
34
|
+
extensionFactories?: InlineExtension[];
|
|
35
|
+
ui?: PlusUIDialogHandlers;
|
|
36
|
+
commandContextActions?: ExtensionCommandContextActions;
|
|
37
|
+
abortHandler?: () => void;
|
|
38
|
+
shutdownHandler?: () => void;
|
|
39
|
+
onError?: (error: ExtensionError) => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export declare function createPlusAgentSession(
|
|
43
|
+
options?: CreatePlusAgentSessionOptions,
|
|
44
|
+
): Promise<CreateAgentSessionResult>;
|