@agentproto/cli 0.9.0 → 0.10.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 +1 -1
- package/dist/cli.mjs +318 -74
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +308 -67
- package/dist/index.mjs.map +1 -1
- package/dist/registry/builtins.mjs +1 -1
- package/dist/registry/manifest.mjs +1 -1
- package/dist/registry/plugins.mjs +1 -1
- package/dist/registry/runtime.mjs +1 -1
- package/dist/util/credentials.mjs +1 -1
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ agentproto pair <offer|accept|ls|revoke|exec> pairing over
|
|
|
40
40
|
agentproto rendezvous serve [--port <n>] [--host <ip>] run a rendezvous broker
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
`agentproto --help` prints the full usage; `--version` prints the package version.
|
|
43
|
+
> `agentproto --help` prints the full usage; `--version` prints the package version.
|
|
44
44
|
|
|
45
45
|
## Quick start
|
|
46
46
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { promises, existsSync, readFileSync, chmodSync, mkdirSync, writeFileSync, readdirSync, accessSync, constants, renameSync, createReadStream, createWriteStream, statSync, openSync, closeSync } from 'fs';
|
|
3
|
+
import { promises, existsSync, readFileSync, chmodSync, mkdirSync, writeFileSync, readdirSync, accessSync, constants, renameSync, createReadStream, createWriteStream, statSync, realpathSync, openSync, closeSync } from 'fs';
|
|
4
4
|
import { homedir, userInfo, hostname, platform, tmpdir } from 'os';
|
|
5
5
|
import { join, resolve, isAbsolute, dirname, normalize, basename, delimiter, relative } from 'path';
|
|
6
6
|
import * as childProc from 'child_process';
|
|
@@ -46,7 +46,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
46
46
|
import { runRendezvousCli } from '@agentproto/rendezvous/cli';
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
* @agentproto/cli v0.
|
|
49
|
+
* @agentproto/cli v0.10.0
|
|
50
50
|
* The `agentproto` binary — install / run / serve AIP-45 agent CLIs.
|
|
51
51
|
*/
|
|
52
52
|
// Provide a real `require` in the ESM bundle. Some bundled deps (e.g.
|
|
@@ -16753,9 +16753,18 @@ function isWorkflowHandle(v2) {
|
|
|
16753
16753
|
}
|
|
16754
16754
|
async function importEntryHandle(workflowMdPath, entry) {
|
|
16755
16755
|
const abs = isAbsolute(entry) ? entry : join(dirname(workflowMdPath), entry);
|
|
16756
|
+
let href = pathToFileURL(abs).href;
|
|
16757
|
+
if (!process.env.VITEST) {
|
|
16758
|
+
try {
|
|
16759
|
+
const url = pathToFileURL(abs);
|
|
16760
|
+
url.searchParams.set("v", String((await stat(abs)).mtimeMs));
|
|
16761
|
+
href = url.href;
|
|
16762
|
+
} catch {
|
|
16763
|
+
}
|
|
16764
|
+
}
|
|
16756
16765
|
let mod;
|
|
16757
16766
|
try {
|
|
16758
|
-
mod = await import(
|
|
16767
|
+
mod = await import(href);
|
|
16759
16768
|
} catch (err) {
|
|
16760
16769
|
throw new WorkflowLoadError(
|
|
16761
16770
|
`cannot import entry '${entry}': ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -19068,9 +19077,19 @@ function setActiveWorkspace(config, slug) {
|
|
|
19068
19077
|
function findWorkspace(config, slug) {
|
|
19069
19078
|
return config.workspaces.find((w) => w.slug === sanitizeSlug(slug));
|
|
19070
19079
|
}
|
|
19080
|
+
function canonical(p2) {
|
|
19081
|
+
try {
|
|
19082
|
+
return realpathSync(resolve(p2));
|
|
19083
|
+
} catch {
|
|
19084
|
+
return resolve(p2);
|
|
19085
|
+
}
|
|
19086
|
+
}
|
|
19071
19087
|
function findWorkspaceByPath(config, dir) {
|
|
19072
|
-
const resolved =
|
|
19073
|
-
const candidates2 = config.workspaces.filter((w) =>
|
|
19088
|
+
const resolved = canonical(dir);
|
|
19089
|
+
const candidates2 = config.workspaces.filter((w) => {
|
|
19090
|
+
const wPath = canonical(w.path);
|
|
19091
|
+
return resolved.startsWith(wPath + "/") || resolved === wPath;
|
|
19092
|
+
}).sort((a, b2) => b2.path.length - a.path.length);
|
|
19074
19093
|
return candidates2[0];
|
|
19075
19094
|
}
|
|
19076
19095
|
function getActiveWorkspace(config) {
|
|
@@ -19156,6 +19175,76 @@ async function loadConfig2(path) {
|
|
|
19156
19175
|
return {};
|
|
19157
19176
|
}
|
|
19158
19177
|
}
|
|
19178
|
+
var markerSchema = z.object({ worktreeId: z.string() });
|
|
19179
|
+
function statOrUndefined(path) {
|
|
19180
|
+
try {
|
|
19181
|
+
return statSync(path);
|
|
19182
|
+
} catch {
|
|
19183
|
+
return void 0;
|
|
19184
|
+
}
|
|
19185
|
+
}
|
|
19186
|
+
function readWorktreeGitDir(dir) {
|
|
19187
|
+
const link = (() => {
|
|
19188
|
+
try {
|
|
19189
|
+
return readFileSync(join(dir, ".git"), "utf8");
|
|
19190
|
+
} catch {
|
|
19191
|
+
return void 0;
|
|
19192
|
+
}
|
|
19193
|
+
})();
|
|
19194
|
+
if (link === void 0) return void 0;
|
|
19195
|
+
const target = /^gitdir:\s*(.+)$/m.exec(link)?.[1]?.trim();
|
|
19196
|
+
if (!target) return void 0;
|
|
19197
|
+
const gitDir = isAbsolute(target) ? target : resolve(dir, target);
|
|
19198
|
+
return statOrUndefined(join(gitDir, "gitdir"))?.isFile() === true ? gitDir : void 0;
|
|
19199
|
+
}
|
|
19200
|
+
function readMainRepoPath(gitDir) {
|
|
19201
|
+
let raw;
|
|
19202
|
+
try {
|
|
19203
|
+
raw = readFileSync(join(gitDir, "commondir"), "utf8").trim();
|
|
19204
|
+
} catch {
|
|
19205
|
+
return void 0;
|
|
19206
|
+
}
|
|
19207
|
+
if (!raw) return void 0;
|
|
19208
|
+
const commonGitDir = isAbsolute(raw) ? raw : resolve(gitDir, raw);
|
|
19209
|
+
return dirname(commonGitDir);
|
|
19210
|
+
}
|
|
19211
|
+
function readWorktreeId(gitDir) {
|
|
19212
|
+
let raw;
|
|
19213
|
+
try {
|
|
19214
|
+
raw = readFileSync(join(gitDir, "agentproto-worktree.json"), "utf8");
|
|
19215
|
+
} catch {
|
|
19216
|
+
return void 0;
|
|
19217
|
+
}
|
|
19218
|
+
let parsed;
|
|
19219
|
+
try {
|
|
19220
|
+
parsed = JSON.parse(raw);
|
|
19221
|
+
} catch {
|
|
19222
|
+
return void 0;
|
|
19223
|
+
}
|
|
19224
|
+
const result = markerSchema.safeParse(parsed);
|
|
19225
|
+
return result.success ? result.data.worktreeId : void 0;
|
|
19226
|
+
}
|
|
19227
|
+
function resolveWorktreeIdentity(cwd) {
|
|
19228
|
+
let dir = resolve(cwd);
|
|
19229
|
+
for (; ; ) {
|
|
19230
|
+
const dotGit = statOrUndefined(join(dir, ".git"));
|
|
19231
|
+
if (dotGit) {
|
|
19232
|
+
if (!dotGit.isFile()) return void 0;
|
|
19233
|
+
const gitDir = readWorktreeGitDir(dir);
|
|
19234
|
+
if (gitDir === void 0) return void 0;
|
|
19235
|
+
const worktreeId = readWorktreeId(gitDir);
|
|
19236
|
+
const mainRepoPath = readMainRepoPath(gitDir);
|
|
19237
|
+
return {
|
|
19238
|
+
worktreePath: dir,
|
|
19239
|
+
...worktreeId === void 0 ? {} : { worktreeId },
|
|
19240
|
+
...mainRepoPath === void 0 ? {} : { mainRepoPath }
|
|
19241
|
+
};
|
|
19242
|
+
}
|
|
19243
|
+
const parent = dirname(dir);
|
|
19244
|
+
if (parent === dir) return void 0;
|
|
19245
|
+
dir = parent;
|
|
19246
|
+
}
|
|
19247
|
+
}
|
|
19159
19248
|
var providers_store_exports = {};
|
|
19160
19249
|
__reExport(providers_store_exports, dist_exports);
|
|
19161
19250
|
function resolveSpawnDefaults(defaults, adapterSlug, input2) {
|
|
@@ -19706,15 +19795,38 @@ async function spawnAgentSession(deps2, input2) {
|
|
|
19706
19795
|
try {
|
|
19707
19796
|
const config = await loadWorkspacesConfig();
|
|
19708
19797
|
if (!cwd) {
|
|
19709
|
-
|
|
19710
|
-
|
|
19711
|
-
|
|
19712
|
-
|
|
19798
|
+
if (input2.workspaceSlug) {
|
|
19799
|
+
const ws = findWorkspace(config, input2.workspaceSlug);
|
|
19800
|
+
if (ws) {
|
|
19801
|
+
cwd = ws.path;
|
|
19802
|
+
resolvedSlug = ws.slug;
|
|
19803
|
+
}
|
|
19804
|
+
} else if (callerScope) {
|
|
19805
|
+
const parentCwd = callerScope.ownerSessionId ? registry.get(callerScope.ownerSessionId)?.cwd : void 0;
|
|
19806
|
+
if (parentCwd) {
|
|
19807
|
+
cwd = parentCwd;
|
|
19808
|
+
const ws = findWorkspaceByPath(config, parentCwd);
|
|
19809
|
+
if (ws) {
|
|
19810
|
+
resolvedSlug = ws.slug;
|
|
19811
|
+
}
|
|
19812
|
+
}
|
|
19813
|
+
} else {
|
|
19814
|
+
const ws = getActiveWorkspace(config);
|
|
19815
|
+
if (ws) {
|
|
19816
|
+
cwd = ws.path;
|
|
19817
|
+
resolvedSlug = ws.slug;
|
|
19818
|
+
}
|
|
19713
19819
|
}
|
|
19714
19820
|
} else if (!resolvedSlug) {
|
|
19715
19821
|
const ws = findWorkspaceByPath(config, cwd);
|
|
19716
19822
|
if (ws) {
|
|
19717
19823
|
resolvedSlug = ws.slug;
|
|
19824
|
+
} else {
|
|
19825
|
+
const identity = resolveWorktreeIdentity(cwd);
|
|
19826
|
+
if (identity?.mainRepoPath) {
|
|
19827
|
+
const baseWs = findWorkspaceByPath(config, identity.mainRepoPath);
|
|
19828
|
+
if (baseWs) resolvedSlug = baseWs.slug;
|
|
19829
|
+
}
|
|
19718
19830
|
}
|
|
19719
19831
|
}
|
|
19720
19832
|
} catch {
|
|
@@ -19920,7 +20032,8 @@ async function spawnAgentSession(deps2, input2) {
|
|
|
19920
20032
|
const effectivePrompt = input2.prompt ? `${composeRoleContext(role, input2.promptAppend, roleRegistry)}
|
|
19921
20033
|
|
|
19922
20034
|
${input2.prompt}` : input2.prompt;
|
|
19923
|
-
const
|
|
20035
|
+
const explicitTitle = input2.title?.trim() ? input2.title.trim() : void 0;
|
|
20036
|
+
const initialTitle = explicitTitle ?? (input2.prompt ? deriveSessionTitle(input2.prompt) : void 0);
|
|
19924
20037
|
let settleClaim;
|
|
19925
20038
|
if (input2.idempotencyKey) {
|
|
19926
20039
|
const claims = claimsFor(registry);
|
|
@@ -22731,6 +22844,90 @@ function registerSessionTools(rawServer, opts) {
|
|
|
22731
22844
|
}
|
|
22732
22845
|
}
|
|
22733
22846
|
);
|
|
22847
|
+
server.tool(
|
|
22848
|
+
"session_rename",
|
|
22849
|
+
"Set or clear a session's user-facing name \u2014 the label the sessions tree, transcript header, and tab show. `label` out-ranks `title` in that display chain, so a user rename should write `label` (the default a UI picks) to be sure it shows; `title` is the auto-derived first-sentence fallback. For EACH of `title`/`label`: a non-empty string sets it (trimmed + length-capped), an empty string clears it (reverting to the derived title / a friendly `adapter \xB7 id` fallback), and omitting it leaves that field untouched. Persists across daemon restarts. Does NOT rename the adapter-native session or touch the running agent.",
|
|
22850
|
+
{
|
|
22851
|
+
idOrName: z.string().min(1).describe("Session id or name to rename \u2014 from `session_list`."),
|
|
22852
|
+
label: z.string().optional().describe(
|
|
22853
|
+
"New label (the winning display field). Empty string clears it. Omit to leave the label untouched."
|
|
22854
|
+
),
|
|
22855
|
+
title: z.string().optional().describe(
|
|
22856
|
+
"New title (the auto-derived fallback slot). Empty string clears it, reverting to the first-sentence derivation. Omit to leave it untouched."
|
|
22857
|
+
)
|
|
22858
|
+
},
|
|
22859
|
+
async (input2) => {
|
|
22860
|
+
const prev = registry.findByIdOrName(input2.idOrName);
|
|
22861
|
+
if (!prev) {
|
|
22862
|
+
return {
|
|
22863
|
+
content: [
|
|
22864
|
+
{
|
|
22865
|
+
type: "text",
|
|
22866
|
+
text: JSON.stringify({ error: `no session "${input2.idOrName}" found` })
|
|
22867
|
+
}
|
|
22868
|
+
],
|
|
22869
|
+
isError: true
|
|
22870
|
+
};
|
|
22871
|
+
}
|
|
22872
|
+
if (callerScope) {
|
|
22873
|
+
const subtree = collectSubtree(
|
|
22874
|
+
callerScope.ownerSessionId,
|
|
22875
|
+
registry.list({ includeArchived: true })
|
|
22876
|
+
);
|
|
22877
|
+
if (!subtree.has(prev.id)) {
|
|
22878
|
+
return {
|
|
22879
|
+
content: [
|
|
22880
|
+
{
|
|
22881
|
+
type: "text",
|
|
22882
|
+
text: JSON.stringify({
|
|
22883
|
+
error: "orchestrator_session_out_of_scope",
|
|
22884
|
+
message: `session_rename: session "${prev.id}" is not in your subtree \u2014 a scoped orchestrator can only rename sessions it (transitively) spawned.`,
|
|
22885
|
+
ok: false,
|
|
22886
|
+
sessionId: prev.id
|
|
22887
|
+
})
|
|
22888
|
+
}
|
|
22889
|
+
],
|
|
22890
|
+
isError: true
|
|
22891
|
+
};
|
|
22892
|
+
}
|
|
22893
|
+
}
|
|
22894
|
+
if (input2.title === void 0 && input2.label === void 0) {
|
|
22895
|
+
return {
|
|
22896
|
+
content: [
|
|
22897
|
+
{
|
|
22898
|
+
type: "text",
|
|
22899
|
+
text: JSON.stringify({
|
|
22900
|
+
error: "nothing_to_rename",
|
|
22901
|
+
message: "session_rename: supply at least one of `title` or `label`.",
|
|
22902
|
+
ok: false,
|
|
22903
|
+
sessionId: prev.id
|
|
22904
|
+
})
|
|
22905
|
+
}
|
|
22906
|
+
],
|
|
22907
|
+
isError: true
|
|
22908
|
+
};
|
|
22909
|
+
}
|
|
22910
|
+
try {
|
|
22911
|
+
const desc = registry.renameSession(prev.id, {
|
|
22912
|
+
...input2.title !== void 0 ? { title: input2.title } : {},
|
|
22913
|
+
...input2.label !== void 0 ? { label: input2.label } : {}
|
|
22914
|
+
});
|
|
22915
|
+
return {
|
|
22916
|
+
content: [{ type: "text", text: JSON.stringify(desc, null, 2) }]
|
|
22917
|
+
};
|
|
22918
|
+
} catch (err) {
|
|
22919
|
+
return {
|
|
22920
|
+
content: [
|
|
22921
|
+
{
|
|
22922
|
+
type: "text",
|
|
22923
|
+
text: `session_rename: ${err instanceof Error ? err.message : String(err)}`
|
|
22924
|
+
}
|
|
22925
|
+
],
|
|
22926
|
+
isError: true
|
|
22927
|
+
};
|
|
22928
|
+
}
|
|
22929
|
+
}
|
|
22930
|
+
);
|
|
22734
22931
|
server.tool(
|
|
22735
22932
|
"terminal_start",
|
|
22736
22933
|
"Spawn a process under a real PTY (node-pty) on the host. Bytes (including ANSI escapes, alt-screen sequences) flow through the daemon's byte ring buffer; subscribers attach via the WS at /sessions/:id/pty. Use for interactive TUIs (claude, vim, htop) or to orchestrate shells from another agent. Returns the session descriptor.",
|
|
@@ -25997,60 +26194,6 @@ function createTerminalTranscriptWriter(opts) {
|
|
|
25997
26194
|
}
|
|
25998
26195
|
};
|
|
25999
26196
|
}
|
|
26000
|
-
var markerSchema = z.object({ worktreeId: z.string() });
|
|
26001
|
-
function statOrUndefined(path) {
|
|
26002
|
-
try {
|
|
26003
|
-
return statSync(path);
|
|
26004
|
-
} catch {
|
|
26005
|
-
return void 0;
|
|
26006
|
-
}
|
|
26007
|
-
}
|
|
26008
|
-
function readWorktreeGitDir(dir) {
|
|
26009
|
-
const link = (() => {
|
|
26010
|
-
try {
|
|
26011
|
-
return readFileSync(join(dir, ".git"), "utf8");
|
|
26012
|
-
} catch {
|
|
26013
|
-
return void 0;
|
|
26014
|
-
}
|
|
26015
|
-
})();
|
|
26016
|
-
if (link === void 0) return void 0;
|
|
26017
|
-
const target = /^gitdir:\s*(.+)$/m.exec(link)?.[1]?.trim();
|
|
26018
|
-
if (!target) return void 0;
|
|
26019
|
-
const gitDir = isAbsolute(target) ? target : resolve(dir, target);
|
|
26020
|
-
return statOrUndefined(join(gitDir, "gitdir"))?.isFile() === true ? gitDir : void 0;
|
|
26021
|
-
}
|
|
26022
|
-
function readWorktreeId(gitDir) {
|
|
26023
|
-
let raw;
|
|
26024
|
-
try {
|
|
26025
|
-
raw = readFileSync(join(gitDir, "agentproto-worktree.json"), "utf8");
|
|
26026
|
-
} catch {
|
|
26027
|
-
return void 0;
|
|
26028
|
-
}
|
|
26029
|
-
let parsed;
|
|
26030
|
-
try {
|
|
26031
|
-
parsed = JSON.parse(raw);
|
|
26032
|
-
} catch {
|
|
26033
|
-
return void 0;
|
|
26034
|
-
}
|
|
26035
|
-
const result = markerSchema.safeParse(parsed);
|
|
26036
|
-
return result.success ? result.data.worktreeId : void 0;
|
|
26037
|
-
}
|
|
26038
|
-
function resolveWorktreeIdentity(cwd) {
|
|
26039
|
-
let dir = resolve(cwd);
|
|
26040
|
-
for (; ; ) {
|
|
26041
|
-
const dotGit = statOrUndefined(join(dir, ".git"));
|
|
26042
|
-
if (dotGit) {
|
|
26043
|
-
if (!dotGit.isFile()) return void 0;
|
|
26044
|
-
const gitDir = readWorktreeGitDir(dir);
|
|
26045
|
-
if (gitDir === void 0) return void 0;
|
|
26046
|
-
const worktreeId = readWorktreeId(gitDir);
|
|
26047
|
-
return worktreeId === void 0 ? { worktreePath: dir } : { worktreePath: dir, worktreeId };
|
|
26048
|
-
}
|
|
26049
|
-
const parent = dirname(dir);
|
|
26050
|
-
if (parent === dir) return void 0;
|
|
26051
|
-
dir = parent;
|
|
26052
|
-
}
|
|
26053
|
-
}
|
|
26054
26197
|
function normalizeAgentPromptOptions(raw) {
|
|
26055
26198
|
if (!Array.isArray(raw)) return void 0;
|
|
26056
26199
|
const labels = raw.map((o) => {
|
|
@@ -27586,6 +27729,33 @@ function createSessionsRegistry(opts) {
|
|
|
27586
27729
|
stampProcessAlive(rt.desc);
|
|
27587
27730
|
return rt.desc;
|
|
27588
27731
|
},
|
|
27732
|
+
renameSession(id, patch) {
|
|
27733
|
+
const rt = sessions.get(id);
|
|
27734
|
+
if (!rt) throw new Error(`renameSession: no session "${id}"`);
|
|
27735
|
+
const apply = (field) => {
|
|
27736
|
+
const raw = patch[field];
|
|
27737
|
+
if (raw === void 0) return;
|
|
27738
|
+
const trimmed = raw === null ? "" : raw.trim();
|
|
27739
|
+
if (trimmed === "") {
|
|
27740
|
+
rt.desc[field] = void 0;
|
|
27741
|
+
return;
|
|
27742
|
+
}
|
|
27743
|
+
const points = Array.from(trimmed);
|
|
27744
|
+
rt.desc[field] = points.length > MAX_LENGTH ? points.slice(0, MAX_LENGTH).join("") : trimmed;
|
|
27745
|
+
};
|
|
27746
|
+
apply("title");
|
|
27747
|
+
apply("label");
|
|
27748
|
+
schedulePersist();
|
|
27749
|
+
sessionEvents?.emit({
|
|
27750
|
+
type: "session:renamed",
|
|
27751
|
+
sessionId: id,
|
|
27752
|
+
...rt.desc.title !== void 0 ? { title: rt.desc.title } : {},
|
|
27753
|
+
...rt.desc.label !== void 0 ? { label: rt.desc.label } : {},
|
|
27754
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
27755
|
+
});
|
|
27756
|
+
stampProcessAlive(rt.desc);
|
|
27757
|
+
return rt.desc;
|
|
27758
|
+
},
|
|
27589
27759
|
listPendingPermissions(filter) {
|
|
27590
27760
|
const all = Array.from(pendingPermissions.values());
|
|
27591
27761
|
const scoped = filter?.sessionId ? all.filter((p2) => p2.sessionId === filter.sessionId) : all;
|
|
@@ -30718,6 +30888,9 @@ async function handleSessions(req, res, path, registry, resolveAgentAdapter, pty
|
|
|
30718
30888
|
})() : {},
|
|
30719
30889
|
...typeof b2.prompt === "string" ? { prompt: b2.prompt } : {},
|
|
30720
30890
|
...typeof b2.label === "string" ? { label: b2.label } : {},
|
|
30891
|
+
// Explicit title override (SPEC-3 FIX C, `--title`) — wins over the
|
|
30892
|
+
// first-sentence derivation from the prompt (see session-spawn.ts).
|
|
30893
|
+
...typeof b2.title === "string" ? { title: b2.title } : {},
|
|
30721
30894
|
...typeof b2.idempotencyKey === "string" && b2.idempotencyKey.length > 0 ? { idempotencyKey: b2.idempotencyKey } : {},
|
|
30722
30895
|
...typeof b2.role === "string" && b2.role.length > 0 ? { role: b2.role } : {},
|
|
30723
30896
|
...typeof b2.promptAppend === "string" ? { promptAppend: b2.promptAppend } : {},
|
|
@@ -30974,6 +31147,49 @@ async function handleSessions(req, res, path, registry, resolveAgentAdapter, pty
|
|
|
30974
31147
|
}
|
|
30975
31148
|
return true;
|
|
30976
31149
|
}
|
|
31150
|
+
const terminalInputMatch = path.match(/^\/sessions\/([^/]+)\/terminal\/input$/);
|
|
31151
|
+
if (terminalInputMatch && req.method === "POST") {
|
|
31152
|
+
const id2 = terminalInputMatch[1];
|
|
31153
|
+
if (!id2) return false;
|
|
31154
|
+
if (!ptyEnabled) {
|
|
31155
|
+
json(501, {
|
|
31156
|
+
error: "pty_not_configured",
|
|
31157
|
+
message: "POST /sessions/:id/terminal/input needs the host to inject `spawnPty` into createGateway (node-pty optional dep \u2014 install in @agentproto/cli)."
|
|
31158
|
+
});
|
|
31159
|
+
return true;
|
|
31160
|
+
}
|
|
31161
|
+
const desc = registry.get(id2);
|
|
31162
|
+
if (!desc) {
|
|
31163
|
+
json(404, { error: "no_session", message: `no session "${id2}"` });
|
|
31164
|
+
return true;
|
|
31165
|
+
}
|
|
31166
|
+
const body = await readJsonBody(req);
|
|
31167
|
+
const text6 = body?.text;
|
|
31168
|
+
if (typeof text6 !== "string") {
|
|
31169
|
+
json(400, { error: "missing_text", message: "Body `text` must be a string." });
|
|
31170
|
+
return true;
|
|
31171
|
+
}
|
|
31172
|
+
if (desc.kind !== "terminal" || desc.pty !== true) {
|
|
31173
|
+
json(400, {
|
|
31174
|
+
error: "not_a_pty",
|
|
31175
|
+
message: `session "${id2}" is not a live PTY (kind=${desc.kind})`
|
|
31176
|
+
});
|
|
31177
|
+
return true;
|
|
31178
|
+
}
|
|
31179
|
+
const enter = body?.enter !== false;
|
|
31180
|
+
let ok = true;
|
|
31181
|
+
if (text6.length > 0) ok = registry.writeTerminalInput(id2, text6) && ok;
|
|
31182
|
+
if (enter) ok = registry.writeTerminalInput(id2, "\r") && ok;
|
|
31183
|
+
if (!ok) {
|
|
31184
|
+
json(400, {
|
|
31185
|
+
error: "not_a_pty",
|
|
31186
|
+
message: `session "${id2}" has no live PTY to write to`
|
|
31187
|
+
});
|
|
31188
|
+
return true;
|
|
31189
|
+
}
|
|
31190
|
+
json(200, { ok: true });
|
|
31191
|
+
return true;
|
|
31192
|
+
}
|
|
30977
31193
|
const modelMatch = path.match(/^\/sessions\/([^/]+)\/model$/);
|
|
30978
31194
|
if (modelMatch && req.method === "POST") {
|
|
30979
31195
|
const id2 = modelMatch[1];
|
|
@@ -31097,6 +31313,31 @@ async function handleSessions(req, res, path, registry, resolveAgentAdapter, pty
|
|
|
31097
31313
|
}
|
|
31098
31314
|
return true;
|
|
31099
31315
|
}
|
|
31316
|
+
const renameMatch = path.match(/^\/sessions\/([^/]+)$/);
|
|
31317
|
+
if (renameMatch && req.method === "PATCH") {
|
|
31318
|
+
const rawIdOrName2 = renameMatch[1];
|
|
31319
|
+
if (!rawIdOrName2) return false;
|
|
31320
|
+
const resolved = registry.findByIdOrName(rawIdOrName2);
|
|
31321
|
+
if (!resolved) {
|
|
31322
|
+
json(404, { error: "session_not_found", id: rawIdOrName2 });
|
|
31323
|
+
return true;
|
|
31324
|
+
}
|
|
31325
|
+
const body = await readJsonBody(req);
|
|
31326
|
+
const b2 = body && typeof body === "object" ? body : {};
|
|
31327
|
+
const field = (v2) => typeof v2 === "string" ? v2 : v2 === null ? null : void 0;
|
|
31328
|
+
const patch = {
|
|
31329
|
+
..."title" in b2 ? { title: field(b2.title) } : {},
|
|
31330
|
+
..."label" in b2 ? { label: field(b2.label) } : {}
|
|
31331
|
+
};
|
|
31332
|
+
try {
|
|
31333
|
+
const desc = registry.renameSession(resolved.id, patch);
|
|
31334
|
+
json(200, desc);
|
|
31335
|
+
} catch (err) {
|
|
31336
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
31337
|
+
json(msg.includes("no session") ? 404 : 500, { error: "rename_failed", message: msg });
|
|
31338
|
+
}
|
|
31339
|
+
return true;
|
|
31340
|
+
}
|
|
31100
31341
|
if (path === "/sessions" && req.method === "POST") {
|
|
31101
31342
|
const body = await readJsonBody(req);
|
|
31102
31343
|
if (!body || typeof body !== "object") {
|
|
@@ -40837,9 +41078,9 @@ async function discoverDaemon() {
|
|
|
40837
41078
|
}
|
|
40838
41079
|
async function readRuntimeJsonWithStatus(workspacePath) {
|
|
40839
41080
|
const path = resolve(workspacePath, ".agentproto", "runtime.json");
|
|
40840
|
-
let
|
|
41081
|
+
let stat10;
|
|
40841
41082
|
try {
|
|
40842
|
-
|
|
41083
|
+
stat10 = await promises.stat(path);
|
|
40843
41084
|
} catch {
|
|
40844
41085
|
return { endpoint: null };
|
|
40845
41086
|
}
|
|
@@ -40862,7 +41103,7 @@ async function readRuntimeJsonWithStatus(workspacePath) {
|
|
|
40862
41103
|
stale: {
|
|
40863
41104
|
path,
|
|
40864
41105
|
pid: parsed.pid ?? null,
|
|
40865
|
-
mtime:
|
|
41106
|
+
mtime: stat10.mtime ?? null
|
|
40866
41107
|
}
|
|
40867
41108
|
};
|
|
40868
41109
|
}
|
|
@@ -43825,8 +44066,8 @@ async function runServe(args) {
|
|
|
43825
44066
|
values.workspace ?? cfgDaemon.workspace ?? process.cwd()
|
|
43826
44067
|
);
|
|
43827
44068
|
try {
|
|
43828
|
-
const
|
|
43829
|
-
if (!
|
|
44069
|
+
const stat10 = await promises.stat(workspace);
|
|
44070
|
+
if (!stat10.isDirectory()) {
|
|
43830
44071
|
process.stderr.write(
|
|
43831
44072
|
`agentproto serve: --workspace "${workspace}" is not a directory.
|
|
43832
44073
|
`
|
|
@@ -44233,7 +44474,7 @@ ${color.dim}\u2500\u2500 shutting down (${signal}) \u2500\u2500${color.reset}
|
|
|
44233
44474
|
async function runOneTunnel(opts, gateway, announcedTools, spawnPty, signal, reconnectState) {
|
|
44234
44475
|
if (!opts.connect) throw new Error("runOneTunnel: --connect not set");
|
|
44235
44476
|
const headers = {
|
|
44236
|
-
"user-agent": `agentproto/${"0.
|
|
44477
|
+
"user-agent": `agentproto/${"0.10.0"}`
|
|
44237
44478
|
};
|
|
44238
44479
|
if (opts.token) headers.authorization = `Bearer ${opts.token}`;
|
|
44239
44480
|
const ws = new WebSocket3(opts.connect, { headers });
|
|
@@ -46105,7 +46346,8 @@ Usage:
|
|
|
46105
46346
|
[--base-url <url>] [--auth-token <token>]
|
|
46106
46347
|
[--options-json <json|@file>]
|
|
46107
46348
|
[--prompt <text>]
|
|
46108
|
-
[--label <text>] [--
|
|
46349
|
+
[--label <text>] [--title <text>]
|
|
46350
|
+
[--attach] [--json]
|
|
46109
46351
|
[--orchestrator | --orchestrator-json <json>]
|
|
46110
46352
|
[--mcp-servers-json <json|@file>]
|
|
46111
46353
|
[--hold-permissions] [--no-color]
|
|
@@ -46243,6 +46485,7 @@ async function runStart(args) {
|
|
|
46243
46485
|
"options-json": { type: "string" },
|
|
46244
46486
|
prompt: { type: "string", short: "p" },
|
|
46245
46487
|
label: { type: "string" },
|
|
46488
|
+
title: { type: "string" },
|
|
46246
46489
|
attach: { type: "boolean" },
|
|
46247
46490
|
json: { type: "boolean" },
|
|
46248
46491
|
"no-color": { type: "boolean" },
|
|
@@ -46372,6 +46615,7 @@ async function runStart(args) {
|
|
|
46372
46615
|
if (options !== void 0 && Object.keys(options).length > 0) body.options = options;
|
|
46373
46616
|
if (values.prompt) body.prompt = values.prompt;
|
|
46374
46617
|
if (values.label) body.label = values.label;
|
|
46618
|
+
if (values.title) body.title = values.title;
|
|
46375
46619
|
if (orchestrator !== void 0) body.orchestrator = orchestrator;
|
|
46376
46620
|
if (mcpServers !== void 0) body.mcpServers = mcpServers;
|
|
46377
46621
|
if (values["hold-permissions"]) body.permissionHold = true;
|
|
@@ -50017,8 +50261,8 @@ async function fileExists3(path) {
|
|
|
50017
50261
|
}
|
|
50018
50262
|
async function dirExists(path) {
|
|
50019
50263
|
try {
|
|
50020
|
-
const
|
|
50021
|
-
return
|
|
50264
|
+
const stat10 = await promises.stat(path);
|
|
50265
|
+
return stat10.isDirectory();
|
|
50022
50266
|
} catch {
|
|
50023
50267
|
return false;
|
|
50024
50268
|
}
|
|
@@ -52869,7 +53113,7 @@ async function main(argv) {
|
|
|
52869
53113
|
const verbIdx = argv.findIndex((a) => VERBS.has(a));
|
|
52870
53114
|
if (verbIdx === -1) {
|
|
52871
53115
|
if (argv.includes("--version") || argv.includes("-v")) {
|
|
52872
|
-
process.stdout.write(`agentproto ${"0.
|
|
53116
|
+
process.stdout.write(`agentproto ${"0.10.0"}
|
|
52873
53117
|
`);
|
|
52874
53118
|
return 0;
|
|
52875
53119
|
}
|