@pipod/cli 0.1.7 → 0.1.9
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/dist/cli.js +72 -49
- package/dist/cli.js.map +1 -1
- package/man/pipod-config.5 +1 -1
- package/man/pipod.1 +6 -2
- package/man/pipod.1.md +5 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -583,7 +583,7 @@ import * as path5 from "path";
|
|
|
583
583
|
import * as fs from "fs";
|
|
584
584
|
import * as path from "path";
|
|
585
585
|
var HOST_PI_AGENT_SUBPATH = path.join(".pi", "agent");
|
|
586
|
-
var HOST_COUPLED_SETTINGS_KEYS = ["hooks", "mcpServers"];
|
|
586
|
+
var HOST_COUPLED_SETTINGS_KEYS = ["hooks", "mcpServers", "deviceId", "trackingId"];
|
|
587
587
|
var DEFAULT_HOST_CONFIG = {
|
|
588
588
|
settings: true,
|
|
589
589
|
packages: true
|
|
@@ -6520,7 +6520,6 @@ import * as path17 from "path";
|
|
|
6520
6520
|
import { promisify as promisify2 } from "util";
|
|
6521
6521
|
|
|
6522
6522
|
// src/client/runtime/local-extensions.ts
|
|
6523
|
-
import { randomUUID } from "crypto";
|
|
6524
6523
|
import * as fs17 from "fs";
|
|
6525
6524
|
import * as path16 from "path";
|
|
6526
6525
|
|
|
@@ -7208,7 +7207,7 @@ function branchOf(entries, fromId) {
|
|
|
7208
7207
|
}
|
|
7209
7208
|
async function createLocalExtensionHost(opts) {
|
|
7210
7209
|
if (opts.paths.length === 0) return null;
|
|
7211
|
-
const { cache, bridge
|
|
7210
|
+
const { cache, bridge } = opts;
|
|
7212
7211
|
const notifyWhenBound = (message, type) => {
|
|
7213
7212
|
bridge.onUiBound(() => bridge.notify(message, type));
|
|
7214
7213
|
};
|
|
@@ -7271,48 +7270,6 @@ async function createLocalExtensionHost(opts) {
|
|
|
7271
7270
|
resetLeaf: throwMutator("resetLeaf")
|
|
7272
7271
|
};
|
|
7273
7272
|
const runner = new ExtensionRunnerClass(kept, runtime, opts.hostCwd, sessionManagerFacade, opts.modelRegistry);
|
|
7274
|
-
let appendEntryWarned = false;
|
|
7275
|
-
const appendEntryUnavailable = (reason) => {
|
|
7276
|
-
if (appendEntryWarned) return;
|
|
7277
|
-
appendEntryWarned = true;
|
|
7278
|
-
notifyWhenBound(`pod extension appendEntry: ${reason} \u2014 the entry was not recorded`, "warning");
|
|
7279
|
-
};
|
|
7280
|
-
const supportsAppendEntry = () => cache.commands.some((command) => {
|
|
7281
|
-
const candidate = command;
|
|
7282
|
-
return candidate.name === APPEND_ENTRY_COMMAND && candidate.source === "extension";
|
|
7283
|
-
});
|
|
7284
|
-
const sendAppendEntry = (customType, data) => {
|
|
7285
|
-
if (typeof customType !== "string" || customType.length === 0 || customType.length > APPEND_ENTRY_MAX_CUSTOM_TYPE_LENGTH) {
|
|
7286
|
-
appendEntryUnavailable(`invalid custom type ${JSON.stringify(customType).slice(0, 64)}`);
|
|
7287
|
-
return;
|
|
7288
|
-
}
|
|
7289
|
-
if (!supportsAppendEntry()) {
|
|
7290
|
-
appendEntryUnavailable("this pod runs an older pi pod extension (restart Pi in the pod to update it)");
|
|
7291
|
-
return;
|
|
7292
|
-
}
|
|
7293
|
-
const request = {
|
|
7294
|
-
v: APPEND_ENTRY_PROTOCOL_VERSION,
|
|
7295
|
-
id: randomUUID(),
|
|
7296
|
-
op: "append-entry",
|
|
7297
|
-
customType,
|
|
7298
|
-
...data !== void 0 ? { data } : {}
|
|
7299
|
-
};
|
|
7300
|
-
let encoded;
|
|
7301
|
-
try {
|
|
7302
|
-
encoded = Buffer.from(JSON.stringify(request), "utf8").toString("base64url");
|
|
7303
|
-
} catch (error2) {
|
|
7304
|
-
appendEntryUnavailable(`entry data is not serializable (${error2 instanceof Error ? error2.message : String(error2)})`);
|
|
7305
|
-
return;
|
|
7306
|
-
}
|
|
7307
|
-
if (Buffer.byteLength(encoded, "utf8") > TREE_BRIDGE_MAX_ENCODED_REQUEST_BYTES) {
|
|
7308
|
-
appendEntryUnavailable("entry data exceeds the bridge size limit");
|
|
7309
|
-
return;
|
|
7310
|
-
}
|
|
7311
|
-
void rpc.prompt(`/${APPEND_ENTRY_COMMAND} ${encoded}`).then(() => cache.refreshTree().then(() => void 0)).catch((error2) => {
|
|
7312
|
-
appendEntryUnavailable(error2 instanceof Error ? error2.message : String(error2));
|
|
7313
|
-
debug(`append-entry bridge failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
7314
|
-
});
|
|
7315
|
-
};
|
|
7316
7273
|
const actions = {
|
|
7317
7274
|
sendMessage: unavailable("pi.sendMessage", "conversation context is built in the pod"),
|
|
7318
7275
|
sendUserMessage: (content, sendOptions) => {
|
|
@@ -7324,7 +7281,7 @@ async function createLocalExtensionHost(opts) {
|
|
|
7324
7281
|
)
|
|
7325
7282
|
);
|
|
7326
7283
|
},
|
|
7327
|
-
appendEntry:
|
|
7284
|
+
appendEntry: opts.appendEntry,
|
|
7328
7285
|
setSessionName: (name) => void opts.setSessionName(name),
|
|
7329
7286
|
getSessionName: () => cache.state.sessionName,
|
|
7330
7287
|
setLabel: (entryId, label2) => opts.setLabel(entryId, label2),
|
|
@@ -8514,6 +8471,54 @@ import {
|
|
|
8514
8471
|
resolveModelScopeWithDiagnostics
|
|
8515
8472
|
} from "@earendil-works/pi-coding-agent";
|
|
8516
8473
|
|
|
8474
|
+
// src/client/runtime/append-entry-bridge.ts
|
|
8475
|
+
import { randomUUID } from "crypto";
|
|
8476
|
+
function createAppendEntryBridge(opts) {
|
|
8477
|
+
const { rpc, cache, bridge } = opts;
|
|
8478
|
+
let warned = false;
|
|
8479
|
+
const unavailable3 = (reason) => {
|
|
8480
|
+
if (warned) return;
|
|
8481
|
+
warned = true;
|
|
8482
|
+
bridge.onUiBound(() => bridge.notify(`session entry not recorded: ${reason}`, "warning"));
|
|
8483
|
+
};
|
|
8484
|
+
const supported = () => cache.commands.some((command) => {
|
|
8485
|
+
const candidate = command;
|
|
8486
|
+
return candidate.name === APPEND_ENTRY_COMMAND && candidate.source === "extension";
|
|
8487
|
+
});
|
|
8488
|
+
return (customType, data) => {
|
|
8489
|
+
if (typeof customType !== "string" || customType.length === 0 || customType.length > APPEND_ENTRY_MAX_CUSTOM_TYPE_LENGTH) {
|
|
8490
|
+
unavailable3(`invalid custom type ${JSON.stringify(customType).slice(0, 64)}`);
|
|
8491
|
+
return;
|
|
8492
|
+
}
|
|
8493
|
+
if (!supported()) {
|
|
8494
|
+
unavailable3("this pod runs an older pi pod extension (restart Pi in the pod to update it)");
|
|
8495
|
+
return;
|
|
8496
|
+
}
|
|
8497
|
+
const request = {
|
|
8498
|
+
v: APPEND_ENTRY_PROTOCOL_VERSION,
|
|
8499
|
+
id: randomUUID(),
|
|
8500
|
+
op: "append-entry",
|
|
8501
|
+
customType,
|
|
8502
|
+
...data !== void 0 ? { data } : {}
|
|
8503
|
+
};
|
|
8504
|
+
let encoded;
|
|
8505
|
+
try {
|
|
8506
|
+
encoded = Buffer.from(JSON.stringify(request), "utf8").toString("base64url");
|
|
8507
|
+
} catch (error2) {
|
|
8508
|
+
unavailable3(`entry data is not serializable (${error2 instanceof Error ? error2.message : String(error2)})`);
|
|
8509
|
+
return;
|
|
8510
|
+
}
|
|
8511
|
+
if (Buffer.byteLength(encoded, "utf8") > TREE_BRIDGE_MAX_ENCODED_REQUEST_BYTES) {
|
|
8512
|
+
unavailable3("entry data exceeds the bridge size limit");
|
|
8513
|
+
return;
|
|
8514
|
+
}
|
|
8515
|
+
void rpc.prompt(`/${APPEND_ENTRY_COMMAND} ${encoded}`).then(() => cache.refreshTree().then(() => void 0)).catch((error2) => {
|
|
8516
|
+
unavailable3(error2 instanceof Error ? error2.message : String(error2));
|
|
8517
|
+
debug(`append-entry bridge failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
8518
|
+
});
|
|
8519
|
+
};
|
|
8520
|
+
}
|
|
8521
|
+
|
|
8517
8522
|
// src/client/runtime/bridge.ts
|
|
8518
8523
|
var HostBridge = class {
|
|
8519
8524
|
/** Set exactly once, by the first ending path to fire; later writers lose. */
|
|
@@ -10588,6 +10593,7 @@ function createRemoteRuntime(opts) {
|
|
|
10588
10593
|
const { rpc, cwd } = opts;
|
|
10589
10594
|
const bridge = new HostBridge();
|
|
10590
10595
|
const cache = new RemoteStateCache(rpc);
|
|
10596
|
+
const appendEntry = createAppendEntryBridge({ rpc, cache, bridge });
|
|
10591
10597
|
const refreshThinkingLevels = async () => {
|
|
10592
10598
|
cache.availableThinkingLevels = null;
|
|
10593
10599
|
if (!opts.getAvailableThinkingLevels) return;
|
|
@@ -11017,6 +11023,8 @@ function createRemoteRuntime(opts) {
|
|
|
11017
11023
|
// (including Mermaid) still compose — InteractiveMode appends these to its own chain.
|
|
11018
11024
|
// Pod extension transforms remain honestly unavailable; client extensions supply theirs here.
|
|
11019
11025
|
getMarkdownTransformers: () => localHost?.runner.getMarkdownTransformers() ?? [],
|
|
11026
|
+
// Tool renderers from client extensions wrap the built-in one, as in-process.
|
|
11027
|
+
resolveToolRenderers: (toolName, base) => localHost ? localHost.runner.resolveToolRenderers(toolName, base) : base(),
|
|
11020
11028
|
getCommandDiagnostics: () => localHost?.runner.getCommandDiagnostics() ?? [],
|
|
11021
11029
|
getShortcutDiagnostics: () => localHost?.runner.getShortcutDiagnostics() ?? [],
|
|
11022
11030
|
getModelRegistry: () => localHost ? extensionModelRegistry : void 0,
|
|
@@ -11062,6 +11070,8 @@ function createRemoteRuntime(opts) {
|
|
|
11062
11070
|
const sessionManager = {
|
|
11063
11071
|
getCwd: () => cwd,
|
|
11064
11072
|
getEntries: () => cache.entries,
|
|
11073
|
+
getBranch: () => cache.entries,
|
|
11074
|
+
getEntryCount: () => cache.entries.length,
|
|
11065
11075
|
getLeafId: () => cache.leafId ?? void 0,
|
|
11066
11076
|
getSessionDir: () => cwd,
|
|
11067
11077
|
getSessionFile: () => cache.state.sessionFile,
|
|
@@ -11071,6 +11081,8 @@ function createRemoteRuntime(opts) {
|
|
|
11071
11081
|
usesDefaultSessionDir: () => true,
|
|
11072
11082
|
isPersisted: () => cache.state.sessionFile !== void 0,
|
|
11073
11083
|
appendLabelChange: (entryId, label2) => trackLabelMutation(entryId, label2),
|
|
11084
|
+
/** pi's `/bug` records the report here; the entry belongs in the pod's session file. */
|
|
11085
|
+
appendCustomEntry: (customType, data) => appendEntry(customType, data),
|
|
11074
11086
|
buildContextEntries: () => cache.entries
|
|
11075
11087
|
};
|
|
11076
11088
|
const session = {
|
|
@@ -11152,6 +11164,14 @@ function createRemoteRuntime(opts) {
|
|
|
11152
11164
|
get hasPendingBashMessages() {
|
|
11153
11165
|
return false;
|
|
11154
11166
|
},
|
|
11167
|
+
// RPC reports neither the cache warmer nor where a virtual model routed a request, so the
|
|
11168
|
+
// footer and /settings show what pi shows when they are unavailable.
|
|
11169
|
+
get cacheWarmingStatus() {
|
|
11170
|
+
return void 0;
|
|
11171
|
+
},
|
|
11172
|
+
get routedModel() {
|
|
11173
|
+
return void 0;
|
|
11174
|
+
},
|
|
11155
11175
|
// local-by-nature services
|
|
11156
11176
|
settingsManager: remoteSettingsManager,
|
|
11157
11177
|
sessionManager,
|
|
@@ -11203,6 +11223,8 @@ function createRemoteRuntime(opts) {
|
|
|
11203
11223
|
abortBranchSummary: () => {
|
|
11204
11224
|
},
|
|
11205
11225
|
setAutoCompactionEnabled: (enabled) => mutate(() => rpc.setAutoCompaction(enabled)),
|
|
11226
|
+
/** Persisted like the /transport toggle; the warmer itself runs in the pod. */
|
|
11227
|
+
setCacheWarmingMode: (mode) => remoteSettingsManager.setCacheWarmingMode(mode),
|
|
11206
11228
|
setAutoRetryEnabled: (enabled) => mutate(() => rpc.setAutoRetry(enabled)),
|
|
11207
11229
|
abortRetry: () => rpc.abortRetry(),
|
|
11208
11230
|
/** `!command` bash: streamed chunks arrive as bash_execution_update events with our id (§8). */
|
|
@@ -11423,7 +11445,7 @@ function createRemoteRuntime(opts) {
|
|
|
11423
11445
|
hostCwd: cwd,
|
|
11424
11446
|
cache,
|
|
11425
11447
|
bridge,
|
|
11426
|
-
|
|
11448
|
+
appendEntry,
|
|
11427
11449
|
getScopedModels: () => scopedModels,
|
|
11428
11450
|
prompt,
|
|
11429
11451
|
setModel: (model) => setRemoteModel(() => rpc.setModel(model.provider, model.id)),
|
|
@@ -17933,12 +17955,13 @@ async function removeCredential(args, flags) {
|
|
|
17933
17955
|
});
|
|
17934
17956
|
}
|
|
17935
17957
|
const approved = await confirm(
|
|
17936
|
-
`Remove the saved ${providerId} sign-in? Pods using it
|
|
17958
|
+
`Remove the saved ${providerId} sign-in? Pods stop using it.`,
|
|
17937
17959
|
{ nonInteractiveDefault: false, assumeYes: yes }
|
|
17938
17960
|
);
|
|
17939
17961
|
if (!approved) throw new CancelledError("Credential removal cancelled");
|
|
17940
17962
|
await clientFor(flags).deleteModelCredential(providerId);
|
|
17941
|
-
info(`removed the saved ${providerId} sign-in`);
|
|
17963
|
+
info(`removed the saved ${providerId} sign-in; pods stop using it`);
|
|
17964
|
+
info(`${providerId} still accepts it until you revoke it there; do that if a pod may have exposed it`);
|
|
17942
17965
|
return 0;
|
|
17943
17966
|
}
|
|
17944
17967
|
function formatStatus(status) {
|