pinomad 0.4.0 → 0.6.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 +4 -2
- package/dist/{chunk-837gh8nr.js → chunk-0xh6cy9v.js} +69 -17
- package/dist/{chunk-n73t5xzw.js → chunk-367n9je8.js} +2 -2
- package/dist/{chunk-xhwkx9bd.js → chunk-3dnnaz4j.js} +14 -15
- package/dist/{chunk-z5pmcscx.js → chunk-4btj08we.js} +676 -377
- package/dist/{chunk-7gmkgyaz.js → chunk-7qb9tq54.js} +324 -4
- package/dist/{chunk-d4y99pfy.js → chunk-7s1f4z4g.js} +4 -3
- package/dist/chunk-b1h374jr.js +159 -0
- package/dist/{chunk-fgx2sh7d.js → chunk-c8nxym2z.js} +1 -1
- package/dist/{chunk-akgxwg8f.js → chunk-d5ypmmr7.js} +29 -12
- package/dist/{chunk-374zqx5h.js → chunk-d93kvxvc.js} +18 -2
- package/dist/chunk-ggb1taqy.js +16 -0
- package/dist/chunk-jn7y815x.js +79 -0
- package/dist/{chunk-b3f0ced1.js → chunk-k2s1hfq5.js} +39 -16
- package/dist/chunk-kzbzacz9.js +12 -0
- package/dist/{chunk-myjp910s.js → chunk-n4tjhcb7.js} +25 -21
- package/dist/{chunk-cjfmfyjb.js → chunk-ngf1zatm.js} +7 -6
- package/dist/{chunk-vw5yb5pd.js → chunk-wqvp1fwh.js} +304 -38
- package/dist/{chunk-5785kwej.js → chunk-ywmm63ks.js} +9 -7
- package/dist/chunk-znhn8af7.js +33 -0
- package/dist/pinomad.js +40 -16
- package/package.json +1 -1
- package/web/apple-touch-icon.png +0 -0
- package/web/assets/index-C_aU_ZiV.js +383 -0
- package/web/assets/index-DaPcXZPM.css +1 -0
- package/web/favicon.svg +1 -0
- package/web/index.html +4 -2
- package/dist/chunk-17p6bfvy.js +0 -63
- package/dist/chunk-302y6by9.js +0 -50
- package/dist/chunk-knaw1a9g.js +0 -182
- package/dist/chunk-prhvksh3.js +0 -14
- package/dist/chunk-xrvmnymc.js +0 -33
- package/web/assets/index-8mNNPXPT.js +0 -383
- package/web/assets/index-BFJJgGGo.css +0 -1
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
hostSupportsCall,
|
|
12
12
|
hostSupportsFeature,
|
|
13
13
|
organize
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-n4tjhcb7.js";
|
|
15
15
|
|
|
16
16
|
// packages/protocol/src/remote-durable.ts
|
|
17
17
|
import { applyImmutable } from "@earendil-works/chord/delta";
|
|
@@ -440,6 +440,9 @@ class RemoteClient {
|
|
|
440
440
|
if (images.length > 0 && !hostSupportsFeature(this.#hostMinor, "images")) {
|
|
441
441
|
throw new Error("The host is too old for images (needs protocol 5.5); run `pinomad upgrade` on the host");
|
|
442
442
|
}
|
|
443
|
+
if (options?.agent !== undefined && !hostSupportsFeature(this.#hostMinor, "agentConversations")) {
|
|
444
|
+
throw new Error("The host is too old for named agents (needs protocol 5.10); run `pinomad upgrade` on the host");
|
|
445
|
+
}
|
|
443
446
|
const { conversationId: conversationId2 } = await this.#call("createConversation", {
|
|
444
447
|
home,
|
|
445
448
|
text,
|
|
@@ -447,6 +450,7 @@ class RemoteClient {
|
|
|
447
450
|
...options?.checkout === undefined ? {} : { checkout: options.checkout },
|
|
448
451
|
...options?.model === undefined ? {} : { model: options.model },
|
|
449
452
|
...options?.thinkingLevel === undefined ? {} : { thinkingLevel: options.thinkingLevel },
|
|
453
|
+
...options?.agent === undefined ? {} : { agent: options.agent },
|
|
450
454
|
...images.length === 0 ? {} : { images }
|
|
451
455
|
});
|
|
452
456
|
await this.#switch(conversationId2);
|
|
@@ -510,6 +514,12 @@ class RemoteClient {
|
|
|
510
514
|
}),
|
|
511
515
|
answer: (kind, requestId, answers, target) => this.#command(() => this.#call("answer", { conversationId: target ?? conversationId(), kind, requestId, answers })),
|
|
512
516
|
changes: () => this.#request(() => this.#call("changes", { conversationId: conversationId() })),
|
|
517
|
+
listFiles: (scope, query) => {
|
|
518
|
+
if (!hostSupportsCall(this.#hostMinor, "listFiles")) {
|
|
519
|
+
return Promise.reject(new Error("The host is too old for this (needs protocol 5.10); run `pinomad upgrade` on the host"));
|
|
520
|
+
}
|
|
521
|
+
return this.#call("listFiles", { scope, query });
|
|
522
|
+
},
|
|
513
523
|
createPairing: () => this.#request(() => this.#call("createPairing", {})),
|
|
514
524
|
revokeDevice: (publicKey) => this.#command(() => this.#call("revokeDevice", { publicKey })),
|
|
515
525
|
logout: (providerId) => this.#command(() => {
|
|
@@ -525,6 +535,9 @@ class RemoteClient {
|
|
|
525
535
|
if (patch.acceptAccountDevices !== undefined && !hostSupportsFeature(this.#hostMinor, "acceptAccountDevices")) {
|
|
526
536
|
throw new Error("The host is too old for this (needs protocol 5.8); run `pinomad upgrade` on the host");
|
|
527
537
|
}
|
|
538
|
+
if (patch.hostName !== undefined && !hostSupportsFeature(this.#hostMinor, "hostName")) {
|
|
539
|
+
throw new Error("The host is too old for this (needs protocol 5.12); run `pinomad upgrade` on the host");
|
|
540
|
+
}
|
|
528
541
|
return this.#call("updateSettings", { patch });
|
|
529
542
|
}),
|
|
530
543
|
createAgent: (role) => this.#request(async () => {
|
|
@@ -549,6 +562,9 @@ class RemoteClient {
|
|
|
549
562
|
if (!hostSupportsCall(this.#hostMinor, "setPushToken")) {
|
|
550
563
|
throw new Error("The host is too old for this (needs protocol 5.7); run `pinomad upgrade` on the host");
|
|
551
564
|
}
|
|
565
|
+
if (token !== null && typeof token !== "string" && !hostSupportsFeature(this.#hostMinor, "apnsPush")) {
|
|
566
|
+
throw new Error("The host is too old for this (needs protocol 5.9); run `pinomad upgrade` on the host");
|
|
567
|
+
}
|
|
552
568
|
await this.#call("setPushToken", { token });
|
|
553
569
|
})
|
|
554
570
|
};
|
|
@@ -591,4 +607,4 @@ class RemoteClient {
|
|
|
591
607
|
}
|
|
592
608
|
}
|
|
593
609
|
|
|
594
|
-
export { connectRemoteDurable };
|
|
610
|
+
export { connectRemoteDurable, ProtocolMismatchError };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
main,
|
|
4
|
+
restartService
|
|
5
|
+
} from "./chunk-d5ypmmr7.js";
|
|
6
|
+
import"./chunk-kzbzacz9.js";
|
|
7
|
+
import"./chunk-c8nxym2z.js";
|
|
8
|
+
import"./chunk-d93kvxvc.js";
|
|
9
|
+
import"./chunk-n4tjhcb7.js";
|
|
10
|
+
import"./chunk-znhn8af7.js";
|
|
11
|
+
import"./chunk-ngf1zatm.js";
|
|
12
|
+
import"./chunk-df32avw6.js";
|
|
13
|
+
export {
|
|
14
|
+
restartService,
|
|
15
|
+
main
|
|
16
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
restartService,
|
|
4
|
+
serviceManager
|
|
5
|
+
} from "./chunk-d5ypmmr7.js";
|
|
6
|
+
import"./chunk-kzbzacz9.js";
|
|
7
|
+
import {
|
|
8
|
+
globalPrefixOf,
|
|
9
|
+
packageDir,
|
|
10
|
+
packagedVersion
|
|
11
|
+
} from "./chunk-c8nxym2z.js";
|
|
12
|
+
import"./chunk-d93kvxvc.js";
|
|
13
|
+
import"./chunk-n4tjhcb7.js";
|
|
14
|
+
import"./chunk-znhn8af7.js";
|
|
15
|
+
import {
|
|
16
|
+
hostAddressOptions
|
|
17
|
+
} from "./chunk-ngf1zatm.js";
|
|
18
|
+
import"./chunk-df32avw6.js";
|
|
19
|
+
|
|
20
|
+
// apps/host/src/cli/upgrade.ts
|
|
21
|
+
import { execFile, spawn } from "node:child_process";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
import { parseArgs, promisify } from "node:util";
|
|
24
|
+
var exec = promisify(execFile);
|
|
25
|
+
var repoRoot = fileURLToPath(new URL("../../../../", import.meta.url));
|
|
26
|
+
var step = (command, args) => new Promise((resolve) => {
|
|
27
|
+
spawn(command, [...args], { cwd: repoRoot, stdio: "inherit" }).once("exit", (code) => resolve(code ?? 1));
|
|
28
|
+
});
|
|
29
|
+
var serviceInstalled = () => Promise.resolve().then(() => serviceManager().state()).then((state) => state.installed, () => false);
|
|
30
|
+
async function main(argv, deps = {}) {
|
|
31
|
+
const { values } = parseArgs({
|
|
32
|
+
args: [...argv],
|
|
33
|
+
options: { force: { type: "boolean", default: false }, ...hostAddressOptions }
|
|
34
|
+
});
|
|
35
|
+
const run = deps.run ?? ((command, args) => exec(command, args, { cwd: repoRoot }));
|
|
36
|
+
const runStep = deps.step ?? step;
|
|
37
|
+
const restart = deps.restart ?? restartService;
|
|
38
|
+
if (packagedVersion === undefined) {
|
|
39
|
+
const { stdout } = await run("git", ["status", "--porcelain"]);
|
|
40
|
+
if (stdout.trim() !== "") {
|
|
41
|
+
console.error("upgrade: the checkout has uncommitted changes; commit or stash them first");
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
for (const [command, args] of [
|
|
46
|
+
["git", ["pull", "--ff-only"]],
|
|
47
|
+
["bun", ["install"]],
|
|
48
|
+
["bun", ["run", "build"]]
|
|
49
|
+
]) {
|
|
50
|
+
const code = await runStep(command, args);
|
|
51
|
+
if (code !== 0) {
|
|
52
|
+
process.exitCode = code;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
const prefix = globalPrefixOf(packageDir);
|
|
58
|
+
if (prefix === undefined) {
|
|
59
|
+
console.error(`upgrade: pinomad isn't a global npm install (${packageDir}); upgrade it the way it was installed`);
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const code = await runStep("npm", ["install", "-g", "--prefix", prefix, "pinomad@latest"]);
|
|
64
|
+
if (code !== 0) {
|
|
65
|
+
process.exitCode = code;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!await (deps.serviceInstalled ?? serviceInstalled)()) {
|
|
70
|
+
console.log("service not installed; upgrade done, nothing restarted");
|
|
71
|
+
process.exitCode = 0;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
(deps.exit ?? process.exit)(await restart({ force: values.force, argv: argv.filter((arg) => arg !== "--force") }));
|
|
75
|
+
}
|
|
76
|
+
if (false) {}
|
|
77
|
+
export {
|
|
78
|
+
main
|
|
79
|
+
};
|
|
@@ -3,46 +3,55 @@ import {
|
|
|
3
3
|
assertSecureServerOrigin,
|
|
4
4
|
probeServerAccounts,
|
|
5
5
|
runServerOperation
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ywmm63ks.js";
|
|
7
7
|
import {
|
|
8
|
+
constantValue,
|
|
9
|
+
openHostSettings
|
|
10
|
+
} from "./chunk-b1h374jr.js";
|
|
11
|
+
import {
|
|
12
|
+
loadHostKey,
|
|
13
|
+
loadRelayKey,
|
|
8
14
|
writeServerConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import
|
|
15
|
+
} from "./chunk-0xh6cy9v.js";
|
|
16
|
+
import {
|
|
17
|
+
relayHostId
|
|
18
|
+
} from "./chunk-7qb9tq54.js";
|
|
11
19
|
import {
|
|
12
20
|
argValue,
|
|
13
21
|
installSpec,
|
|
14
22
|
restartService,
|
|
15
23
|
serviceManager,
|
|
16
24
|
withoutRelayArgs
|
|
17
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-d5ypmmr7.js";
|
|
26
|
+
import"./chunk-kzbzacz9.js";
|
|
18
27
|
import {
|
|
19
28
|
commandHint,
|
|
20
29
|
hostEntry
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import"./chunk-
|
|
23
|
-
import"./chunk-
|
|
30
|
+
} from "./chunk-c8nxym2z.js";
|
|
31
|
+
import"./chunk-d93kvxvc.js";
|
|
32
|
+
import"./chunk-n4tjhcb7.js";
|
|
24
33
|
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
} from "./chunk-
|
|
28
|
-
import {
|
|
29
|
-
relayHostId
|
|
30
|
-
} from "./chunk-7gmkgyaz.js";
|
|
34
|
+
cleanHostName,
|
|
35
|
+
normalizeHostName
|
|
36
|
+
} from "./chunk-znhn8af7.js";
|
|
31
37
|
import {
|
|
32
38
|
DEFAULT_DATA_DIR
|
|
33
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-ngf1zatm.js";
|
|
34
40
|
import"./chunk-df32avw6.js";
|
|
35
41
|
|
|
36
42
|
// apps/host/src/cli/join.ts
|
|
37
43
|
import { mkdir } from "node:fs/promises";
|
|
38
44
|
import { homedir, hostname } from "node:os";
|
|
39
|
-
import { resolve } from "node:path";
|
|
45
|
+
import { join, resolve } from "node:path";
|
|
40
46
|
import { parseArgs } from "node:util";
|
|
41
47
|
var message = (error) => error instanceof Error ? error.message : String(error);
|
|
42
48
|
async function joinServer(args, deps) {
|
|
43
49
|
const origin = args.origin.replace(/\/+$/, "");
|
|
44
50
|
const dataDir = resolve(args.dataDir);
|
|
45
51
|
assertSecureServerOrigin(origin);
|
|
52
|
+
if (args.name !== undefined && cleanHostName(args.name) === "") {
|
|
53
|
+
throw new Error(`Invalid host name: ${JSON.stringify(args.name)}`);
|
|
54
|
+
}
|
|
46
55
|
await mkdir(dataDir, { recursive: true });
|
|
47
56
|
const signingKey = await loadRelayKey(dataDir);
|
|
48
57
|
const hostKey = await loadHostKey(dataDir);
|
|
@@ -59,13 +68,25 @@ async function joinServer(args, deps) {
|
|
|
59
68
|
if (probe === "disabled") {
|
|
60
69
|
throw new Error(`${origin} does not run server accounts — the server is too old or was started without a data dir`);
|
|
61
70
|
}
|
|
71
|
+
const settings = await openHostSettings({
|
|
72
|
+
path: join(dataDir, "settings.json"),
|
|
73
|
+
fallback: {
|
|
74
|
+
defaultModel: () => null,
|
|
75
|
+
defaultThinkingLevel: () => null,
|
|
76
|
+
steeringMode: () => "one-at-a-time",
|
|
77
|
+
followUpMode: () => "one-at-a-time"
|
|
78
|
+
},
|
|
79
|
+
models: constantValue([])
|
|
80
|
+
});
|
|
81
|
+
const current = settings.value;
|
|
82
|
+
const storedName = current.custom.includes("hostName") ? current.hostName : undefined;
|
|
62
83
|
const reply = await runServerOperation({
|
|
63
84
|
origin,
|
|
64
85
|
signingKey,
|
|
65
86
|
noisePublicKey: hostKey.publicKey,
|
|
66
87
|
op: "join",
|
|
67
88
|
joinToken: args.token,
|
|
68
|
-
name: args.name ?? deps?.hostname ?? hostname()
|
|
89
|
+
name: normalizeHostName(args.name ?? storedName ?? deps?.hostname ?? hostname())
|
|
69
90
|
});
|
|
70
91
|
if (reply.t === "refused") {
|
|
71
92
|
throw new Error(reply.reason === "expired_token" ? "the join token expired — generate a fresh one" : reply.reason === "invalid_token" ? "the join token is invalid or already spent — generate a fresh one" : `the server refused the join: ${reply.reason}`);
|
|
@@ -76,6 +97,8 @@ async function joinServer(args, deps) {
|
|
|
76
97
|
let service;
|
|
77
98
|
try {
|
|
78
99
|
await writeServerConfig(dataDir, { origin });
|
|
100
|
+
if (args.name !== undefined)
|
|
101
|
+
await settings.update({ hostName: args.name });
|
|
79
102
|
const freshSpec = installSpec(["--data-dir", dataDir], {
|
|
80
103
|
execPath: process.execPath,
|
|
81
104
|
env: process.env,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// apps/host/src/cli/args.ts
|
|
2
|
+
function isParseArgsError(error) {
|
|
3
|
+
const code = error.code;
|
|
4
|
+
return typeof code === "string" && code.startsWith("ERR_PARSE_ARGS_");
|
|
5
|
+
}
|
|
6
|
+
function reportParseArgsError(command, error) {
|
|
7
|
+
console.error(`${command}: ${error instanceof Error ? error.message : String(error)}`);
|
|
8
|
+
console.error(`run "${command} --help" for usage`);
|
|
9
|
+
process.exitCode = 2;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { isParseArgsError, reportParseArgsError };
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
followUpMode: true,
|
|
7
|
-
acceptAccountDevices: true
|
|
8
|
-
};
|
|
9
|
-
var HOST_SETTING_KEYS = Object.keys(HOST_SETTING_KEY_SET);
|
|
10
|
-
var THINKING_LEVEL_KEYS = { off: true, minimal: true, low: true, medium: true, high: true, xhigh: true, max: true };
|
|
11
|
-
var THINKING_LEVELS = Object.keys(THINKING_LEVEL_KEYS);
|
|
12
|
-
var isThinkingLevel = (value) => typeof value === "string" && Object.prototype.hasOwnProperty.call(THINKING_LEVEL_KEYS, value);
|
|
13
|
-
var isQueueMode = (value) => value === "all" || value === "one-at-a-time";
|
|
1
|
+
import {
|
|
2
|
+
HOST_SETTING_KEYS,
|
|
3
|
+
isQueueMode,
|
|
4
|
+
isThinkingLevel
|
|
5
|
+
} from "./chunk-znhn8af7.js";
|
|
14
6
|
|
|
15
7
|
// packages/protocol/src/frames.ts
|
|
16
8
|
var HOST_STREAMS = { conversations: 0, index: 0, devices: 0, mcp: 0, models: 1, auth: 1, settings: 2, agents: 6 };
|
|
@@ -22,7 +14,7 @@ var conversationStream = (id) => `conversation:${id}`;
|
|
|
22
14
|
var docStream = (kind, id) => `doc:${kind}:${id}`;
|
|
23
15
|
var UNAUTHORIZED_CLOSE_CODE = 4401;
|
|
24
16
|
var INVALID_FRAME_CLOSE_CODE = 4400;
|
|
25
|
-
var PROTOCOL = { major: 5, minor:
|
|
17
|
+
var PROTOCOL = { major: 5, minor: 12 };
|
|
26
18
|
var CALL_SINCE = {
|
|
27
19
|
logout: 1,
|
|
28
20
|
updateSettings: 2,
|
|
@@ -31,12 +23,20 @@ var CALL_SINCE = {
|
|
|
31
23
|
createAgent: 6,
|
|
32
24
|
updateAgent: 6,
|
|
33
25
|
deleteAgent: 6,
|
|
34
|
-
setPushToken: 7
|
|
26
|
+
setPushToken: 7,
|
|
27
|
+
listFiles: 10
|
|
35
28
|
};
|
|
36
29
|
function hostSupportsCall(hostMinor, method) {
|
|
37
30
|
return hostMinor >= (CALL_SINCE[method] ?? 0);
|
|
38
31
|
}
|
|
39
|
-
var FEATURE_SINCE = {
|
|
32
|
+
var FEATURE_SINCE = {
|
|
33
|
+
images: 5,
|
|
34
|
+
acceptAccountDevices: 8,
|
|
35
|
+
apnsPush: 9,
|
|
36
|
+
agentConversations: 10,
|
|
37
|
+
liveBranch: 11,
|
|
38
|
+
hostName: 12
|
|
39
|
+
};
|
|
40
40
|
function hostSupportsFeature(hostMinor, feature) {
|
|
41
41
|
return hostMinor >= FEATURE_SINCE[feature];
|
|
42
42
|
}
|
|
@@ -92,14 +92,16 @@ var CALL_METHODS = [
|
|
|
92
92
|
"createAgent",
|
|
93
93
|
"updateAgent",
|
|
94
94
|
"deleteAgent",
|
|
95
|
-
"setPushToken"
|
|
95
|
+
"setPushToken",
|
|
96
|
+
"listFiles"
|
|
96
97
|
];
|
|
97
98
|
var SETTING_VALIDATORS = {
|
|
98
99
|
defaultModel: (value) => value === null || record(value) && nonempty(value.provider) && nonempty(value.modelId),
|
|
99
100
|
defaultThinkingLevel: (value) => value === null || isThinkingLevel(value),
|
|
100
101
|
steeringMode: (value) => value === null || isQueueMode(value),
|
|
101
102
|
followUpMode: (value) => value === null || isQueueMode(value),
|
|
102
|
-
acceptAccountDevices: (value) => value === null || typeof value === "boolean"
|
|
103
|
+
acceptAccountDevices: (value) => value === null || typeof value === "boolean",
|
|
104
|
+
hostName: (value) => value === null || typeof value === "string"
|
|
103
105
|
};
|
|
104
106
|
function validCallArgs(method, args) {
|
|
105
107
|
const conversationId = () => typeof args.conversationId === "number" && Number.isSafeInteger(args.conversationId) && args.conversationId >= 1;
|
|
@@ -128,7 +130,9 @@ function validCallArgs(method, args) {
|
|
|
128
130
|
case "listFolders":
|
|
129
131
|
return args.path === undefined || nonempty(args.path);
|
|
130
132
|
case "createConversation":
|
|
131
|
-
return record(args.home) && (args.home.kind === "chat" || args.home.kind === "project" && nonempty(args.home.path)) && typeof args.text === "string" && (nonempty(args.text) || Array.isArray(args.images) && args.images.length > 0) && nonempty(args.requestId) && images() && (args.checkout === undefined || args.checkout === "worktree" || args.checkout === "project") && (args.model === undefined || record(args.model) && nonempty(args.model.provider) && nonempty(args.model.modelId)) && (args.thinkingLevel === undefined || nonempty(args.thinkingLevel));
|
|
133
|
+
return record(args.home) && (args.home.kind === "chat" || args.home.kind === "project" && nonempty(args.home.path)) && typeof args.text === "string" && (nonempty(args.text) || Array.isArray(args.images) && args.images.length > 0) && nonempty(args.requestId) && images() && (args.checkout === undefined || args.checkout === "worktree" || args.checkout === "project") && (args.model === undefined || record(args.model) && nonempty(args.model.provider) && nonempty(args.model.modelId)) && (args.thinkingLevel === undefined || nonempty(args.thinkingLevel)) && (args.agent === undefined || nonempty(args.agent));
|
|
134
|
+
case "listFiles":
|
|
135
|
+
return typeof args.query === "string" && record(args.scope) && (args.scope.kind === "conversation" && typeof args.scope.conversationId === "number" && Number.isSafeInteger(args.scope.conversationId) && args.scope.conversationId >= 1 || args.scope.kind === "project" && nonempty(args.scope.path) && (args.scope.checkout === "worktree" || args.scope.checkout === "project"));
|
|
132
136
|
case "archive":
|
|
133
137
|
return conversationId() && typeof args.archived === "boolean";
|
|
134
138
|
case "renameConversation":
|
|
@@ -145,7 +149,7 @@ function validCallArgs(method, args) {
|
|
|
145
149
|
case "deleteAgent":
|
|
146
150
|
return typeof args.name === "string";
|
|
147
151
|
case "setPushToken":
|
|
148
|
-
return args.token === null || typeof args.token === "string";
|
|
152
|
+
return args.token === null || typeof args.token === "string" || record(args.token) && typeof args.token.apns === "string" && (args.token.environment === "production" || args.token.environment === "development");
|
|
149
153
|
case "updateSettings":
|
|
150
154
|
return record(args.patch) && Object.keys(args.patch).every((key) => HOST_SETTING_KEYS.includes(key)) && Object.entries(args.patch).every(([key, value]) => SETTING_VALIDATORS[key]?.(value) === true);
|
|
151
155
|
}
|
|
@@ -250,4 +254,4 @@ function homeOf(index, summaries, id) {
|
|
|
250
254
|
return;
|
|
251
255
|
}
|
|
252
256
|
|
|
253
|
-
export {
|
|
257
|
+
export { HOST_STREAM_NAMES, hostStreams, conversationStream, docStream, UNAUTHORIZED_CLOSE_CODE, INVALID_FRAME_CLOSE_CODE, PROTOCOL, hostSupportsCall, hostSupportsFeature, parseClientFrame, organize, checkoutOf, homeOf };
|
|
@@ -4,18 +4,19 @@ import { homedir } from "node:os";
|
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { parseArgs } from "node:util";
|
|
6
6
|
var DEFAULT_DATA_DIR = process.env.PINOMAD_DATA_DIR ?? join(homedir(), ".pinomad");
|
|
7
|
+
var hostAddressOptions = {
|
|
8
|
+
"data-dir": { type: "string" },
|
|
9
|
+
url: { type: "string", default: "ws://127.0.0.1:7420" },
|
|
10
|
+
token: { type: "string" }
|
|
11
|
+
};
|
|
7
12
|
async function hostAddress(argv) {
|
|
8
13
|
const { values } = parseArgs({
|
|
9
14
|
args: [...argv],
|
|
10
|
-
options:
|
|
11
|
-
"data-dir": { type: "string" },
|
|
12
|
-
url: { type: "string", default: "ws://127.0.0.1:7420" },
|
|
13
|
-
token: { type: "string" }
|
|
14
|
-
}
|
|
15
|
+
options: hostAddressOptions
|
|
15
16
|
});
|
|
16
17
|
const dataDir = resolve(values["data-dir"] ?? DEFAULT_DATA_DIR);
|
|
17
18
|
const token = values.token ?? (await readFile(join(dataDir, "token"), "utf8")).trim();
|
|
18
19
|
return { url: values.url, token, dataDir };
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
export { DEFAULT_DATA_DIR, hostAddress };
|
|
22
|
+
export { DEFAULT_DATA_DIR, hostAddressOptions, hostAddress };
|