@pipod/cli 0.1.20 → 0.1.22
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 +71 -21
- package/dist/cli.js.map +1 -1
- package/dist/key-encoding-guard-6UOKKTJQ.js +41 -0
- package/dist/key-encoding-guard-6UOKKTJQ.js.map +1 -0
- package/docs/keyboard-input.md +42 -5
- package/docs/pod-list-pagination.md +36 -1
- package/man/pipod-config.5 +1 -1
- package/man/pipod.1 +4 -3
- package/man/pipod.1.md +3 -2
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1873,6 +1873,10 @@ var AccountClient = class {
|
|
|
1873
1873
|
listPods(query = {}) {
|
|
1874
1874
|
return this.request("/pods", { query });
|
|
1875
1875
|
}
|
|
1876
|
+
/** Null means an older server lacks lookup, not that the ref had no matches. */
|
|
1877
|
+
lookupPodRef(ref) {
|
|
1878
|
+
return this.request(`/pods/by-ref/${encodeURIComponent(ref)}`, { allow404: true });
|
|
1879
|
+
}
|
|
1876
1880
|
/** `waitMs` long-polls: a supporting server answers on the next pod change; older servers ignore it. */
|
|
1877
1881
|
getPod(id, opts = {}) {
|
|
1878
1882
|
const waitMs = opts.waitMs != null && opts.waitMs > 0 ? Math.floor(opts.waitMs) : void 0;
|
|
@@ -5068,19 +5072,24 @@ function displayRef(id, kind) {
|
|
|
5068
5072
|
const tail = id.replaceAll("-", "").slice(-DISPLAY_TAIL_LENGTH).toLowerCase();
|
|
5069
5073
|
return `${kind === "pod" ? "p" : "j"}-${tail}`;
|
|
5070
5074
|
}
|
|
5071
|
-
function
|
|
5072
|
-
const
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
const prefixed = /^[pj]-(.*)$/i.exec(normalizedRef);
|
|
5075
|
+
function parseRef(ref) {
|
|
5076
|
+
const normalized = ref.toLowerCase();
|
|
5077
|
+
if (FULL_UUID.test(normalized)) return { kind: "uuid", value: normalized };
|
|
5078
|
+
const prefixed = /^[pj]-(.*)$/i.exec(normalized);
|
|
5076
5079
|
if (prefixed) {
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
return normalizedId.replaceAll("-", "").endsWith(tail);
|
|
5080
|
+
assertUsableHexRef(ref, prefixed[1]);
|
|
5081
|
+
return { kind: "tail", value: prefixed[1] };
|
|
5080
5082
|
}
|
|
5081
|
-
if (!HEX.test(
|
|
5082
|
-
assertUsableHexRef(ref,
|
|
5083
|
-
return
|
|
5083
|
+
if (!HEX.test(normalized)) return null;
|
|
5084
|
+
assertUsableHexRef(ref, normalized);
|
|
5085
|
+
return { kind: "hex", value: normalized };
|
|
5086
|
+
}
|
|
5087
|
+
function matchesRef(id, ref) {
|
|
5088
|
+
const pattern = parseRef(ref);
|
|
5089
|
+
if (!pattern) return false;
|
|
5090
|
+
const normalizedId = id.toLowerCase();
|
|
5091
|
+
if (pattern.kind === "uuid") return normalizedId === pattern.value;
|
|
5092
|
+
return normalizedId.replaceAll("-", "").endsWith(pattern.value) || pattern.kind === "hex" && normalizedId.startsWith(pattern.value);
|
|
5084
5093
|
}
|
|
5085
5094
|
function assertUsableHexRef(ref, hex) {
|
|
5086
5095
|
if (!HEX.test(hex)) {
|
|
@@ -6577,6 +6586,7 @@ var RemoteStateCache = class {
|
|
|
6577
6586
|
sessionRefreshRequested = false;
|
|
6578
6587
|
expectedRefreshLeaf = NO_EXPECTED_LEAF;
|
|
6579
6588
|
cacheGeneration = 0;
|
|
6589
|
+
modelsRefresh = null;
|
|
6580
6590
|
replacementInProgress = false;
|
|
6581
6591
|
labelStates = /* @__PURE__ */ new Map();
|
|
6582
6592
|
seedBridge = null;
|
|
@@ -6812,11 +6822,22 @@ var RemoteStateCache = class {
|
|
|
6812
6822
|
}
|
|
6813
6823
|
throw lastError ?? new Error("pod session refresh could not be reconciled");
|
|
6814
6824
|
}
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6825
|
+
refreshModels() {
|
|
6826
|
+
const generation = this.cacheGeneration;
|
|
6827
|
+
if (this.modelsRefresh?.generation === generation) return this.modelsRefresh.promise;
|
|
6828
|
+
const promise = (async () => {
|
|
6829
|
+
try {
|
|
6830
|
+
const models = await this.rpc.getAvailableModels();
|
|
6831
|
+
if (generation === this.cacheGeneration) this.availableModels = models;
|
|
6832
|
+
} catch {
|
|
6833
|
+
}
|
|
6834
|
+
})();
|
|
6835
|
+
const entry = { generation, promise };
|
|
6836
|
+
this.modelsRefresh = entry;
|
|
6837
|
+
void promise.then(() => {
|
|
6838
|
+
if (this.modelsRefresh === entry) this.modelsRefresh = null;
|
|
6839
|
+
});
|
|
6840
|
+
return promise;
|
|
6820
6841
|
}
|
|
6821
6842
|
async refreshCommands() {
|
|
6822
6843
|
try {
|
|
@@ -11434,8 +11455,7 @@ function createRemoteRuntime(opts) {
|
|
|
11434
11455
|
treeBridge,
|
|
11435
11456
|
init: async () => {
|
|
11436
11457
|
await cache.init();
|
|
11437
|
-
await refreshThinkingLevels();
|
|
11438
|
-
await authBridge.refresh();
|
|
11458
|
+
await Promise.all([refreshThinkingLevels(), authBridge.refresh(), cache.refreshModels()]);
|
|
11439
11459
|
await seedScopedModels();
|
|
11440
11460
|
if (opts.attestedExtensionPaths?.length) {
|
|
11441
11461
|
try {
|
|
@@ -12403,6 +12423,7 @@ var GatewayRpcClient = class _GatewayRpcClient extends RpcClientBase {
|
|
|
12403
12423
|
/** False between adopting a skewed hello and readiness replacing it; ordinary RPC is gated. */
|
|
12404
12424
|
piVersionReady = false;
|
|
12405
12425
|
idPrefix = `cli-${randomBytes5(4).toString("hex")}-`;
|
|
12426
|
+
availableModelsRequest = null;
|
|
12406
12427
|
modelsRequest = null;
|
|
12407
12428
|
pendingSemantic = /* @__PURE__ */ new Map();
|
|
12408
12429
|
/** Auxiliary completions multiplex by caller id — unlike single-slot semantic queries. */
|
|
@@ -12556,6 +12577,20 @@ var GatewayRpcClient = class _GatewayRpcClient extends RpcClientBase {
|
|
|
12556
12577
|
}
|
|
12557
12578
|
return promise;
|
|
12558
12579
|
}
|
|
12580
|
+
/** Model and thinking consumers share one semantic catalog, not two large replies. */
|
|
12581
|
+
getAvailableModels() {
|
|
12582
|
+
if (this.availableModelsRequest) return this.availableModelsRequest;
|
|
12583
|
+
const task = this.getModels().then((snapshot) => snapshot.models).catch((error2) => {
|
|
12584
|
+
if (error2 instanceof Error && error2.message === "timed out waiting for the gateway model catalog" && !this.userClosed && this.piVersionReady) return super.getAvailableModels();
|
|
12585
|
+
throw error2;
|
|
12586
|
+
});
|
|
12587
|
+
this.availableModelsRequest = task;
|
|
12588
|
+
const clear = () => {
|
|
12589
|
+
if (this.availableModelsRequest === task) this.availableModelsRequest = null;
|
|
12590
|
+
};
|
|
12591
|
+
void task.then(clear, clear);
|
|
12592
|
+
return task;
|
|
12593
|
+
}
|
|
12559
12594
|
/** List pod-side sessions. A timeout or unsupported marker is an absent capability. */
|
|
12560
12595
|
getSessions() {
|
|
12561
12596
|
const absent = { sessions: [], workdir: "", complete: false, unsupported: true };
|
|
@@ -12913,6 +12948,7 @@ var GatewayRpcClient = class _GatewayRpcClient extends RpcClientBase {
|
|
|
12913
12948
|
}
|
|
12914
12949
|
}
|
|
12915
12950
|
resetHandshakeState(podId) {
|
|
12951
|
+
this.availableModelsRequest = null;
|
|
12916
12952
|
this.currentPodId = podId;
|
|
12917
12953
|
this.hello = null;
|
|
12918
12954
|
this.piExitCode = void 0;
|
|
@@ -14625,6 +14661,8 @@ ${choices.join("\n")}`,
|
|
|
14625
14661
|
};
|
|
14626
14662
|
let unwireDisconnectedQuit = () => {
|
|
14627
14663
|
};
|
|
14664
|
+
let unwireKeyEncoding = () => {
|
|
14665
|
+
};
|
|
14628
14666
|
let unwireKeyRepeat = () => {
|
|
14629
14667
|
};
|
|
14630
14668
|
let mode;
|
|
@@ -14632,6 +14670,7 @@ ${choices.join("\n")}`,
|
|
|
14632
14670
|
await runtime.init();
|
|
14633
14671
|
const { InteractiveMode } = await import("@earendil-works/pi-coding-agent");
|
|
14634
14672
|
const { wirePodChords } = await import("./chords-SOJBLC6R.js");
|
|
14673
|
+
const { wireKeyEncodingGuard } = await import("./key-encoding-guard-6UOKKTJQ.js");
|
|
14635
14674
|
const { wireKeyRepeatGuard } = await import("./key-repeat-guard-7OVKW5KD.js");
|
|
14636
14675
|
const { guardStdinFragments } = await import("./stdin-fragment-guard-SPIJC7GT.js");
|
|
14637
14676
|
guardStdinFragments();
|
|
@@ -14639,12 +14678,14 @@ ${choices.join("\n")}`,
|
|
|
14639
14678
|
runtime.bridge.setOnUiBound(() => {
|
|
14640
14679
|
unwireChords();
|
|
14641
14680
|
unwireDisconnectedQuit();
|
|
14681
|
+
unwireKeyEncoding();
|
|
14642
14682
|
unwireKeyRepeat();
|
|
14643
14683
|
unwireChords = wirePodChords(runtime.bridge, runtime.router, chords);
|
|
14644
14684
|
unwireDisconnectedQuit = wireDisconnectedQuit(
|
|
14645
14685
|
runtime.bridge,
|
|
14646
14686
|
() => connectionAllowsQuit(latestConnectionState)
|
|
14647
14687
|
);
|
|
14688
|
+
unwireKeyEncoding = wireKeyEncodingGuard(runtime.bridge.ui);
|
|
14648
14689
|
unwireKeyRepeat = wireKeyRepeatGuard(runtime.bridge.ui);
|
|
14649
14690
|
});
|
|
14650
14691
|
const tuiMode = opts.tuiMode ?? tuiModeFromArgv(context.config.pi.args);
|
|
@@ -14675,6 +14716,7 @@ ${choices.join("\n")}`,
|
|
|
14675
14716
|
runtime.bridge.setOnUiBound(null);
|
|
14676
14717
|
unwireChords();
|
|
14677
14718
|
unwireDisconnectedQuit();
|
|
14719
|
+
unwireKeyEncoding();
|
|
14678
14720
|
unwireKeyRepeat();
|
|
14679
14721
|
rpc.close();
|
|
14680
14722
|
derived?.dispose();
|
|
@@ -14702,6 +14744,7 @@ ${choices.join("\n")}`,
|
|
|
14702
14744
|
runtime.bridge.setOnUiBound(null);
|
|
14703
14745
|
unwireChords();
|
|
14704
14746
|
unwireDisconnectedQuit();
|
|
14747
|
+
unwireKeyEncoding();
|
|
14705
14748
|
unwireKeyRepeat();
|
|
14706
14749
|
process.off("SIGHUP", onHangUp);
|
|
14707
14750
|
process.off("SIGTERM", onHangUp);
|
|
@@ -14996,6 +15039,12 @@ function renderPodLines(pods) {
|
|
|
14996
15039
|
async function selectAccountPod(client, podRef, action, cwd) {
|
|
14997
15040
|
if (podRef) {
|
|
14998
15041
|
if (isFullUuid(podRef)) return client.getPod(podRef.toLowerCase());
|
|
15042
|
+
const found = await client.lookupPodRef(podRef);
|
|
15043
|
+
if (found !== null) {
|
|
15044
|
+
if (found.total > 1) throw ambiguousPodRef(podRef, found.matches, found.total);
|
|
15045
|
+
if (found.pod) return found.pod;
|
|
15046
|
+
throw new PiPodError(`no pod matches "${podRef}"`, { hint: "see `pipod list --all`" });
|
|
15047
|
+
}
|
|
14999
15048
|
const pods2 = (await listAllPods(client, {})).pods;
|
|
15000
15049
|
const named = pods2.filter((pod) => pod.name === podRef);
|
|
15001
15050
|
if (named.length === 1) return named[0];
|
|
@@ -15022,10 +15071,11 @@ ${podChoiceLines(pods)}`
|
|
|
15022
15071
|
}
|
|
15023
15072
|
return pods[0];
|
|
15024
15073
|
}
|
|
15025
|
-
function ambiguousPodRef(ref, pods) {
|
|
15026
|
-
return new PiPodError(`"${ref}" matches ${
|
|
15074
|
+
function ambiguousPodRef(ref, pods, total = pods.length) {
|
|
15075
|
+
return new PiPodError(`"${ref}" matches ${total} pods`, {
|
|
15027
15076
|
hint: `use a longer ref:
|
|
15028
|
-
${podChoiceLines(pods)}`
|
|
15077
|
+
${podChoiceLines(pods)}` + (total > pods.length ? `
|
|
15078
|
+
\u2026 showing the first ${pods.length} matches` : "")
|
|
15029
15079
|
});
|
|
15030
15080
|
}
|
|
15031
15081
|
function podChoiceLines(pods) {
|