@stigmer/cli 3.10.0 → 3.11.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/commands/connect.d.ts.map +1 -1
- package/commands/connect.js +9 -1
- package/commands/connect.js.map +1 -1
- package/package.json +5 -5
- package/resources/connect/connect.d.ts +9 -0
- package/resources/connect/connect.d.ts.map +1 -1
- package/resources/connect/connect.js +30 -2
- package/resources/connect/connect.js.map +1 -1
- package/resources/run/attachments.d.ts.map +1 -1
- package/resources/run/attachments.js +33 -5
- package/resources/run/attachments.js.map +1 -1
- package/resources/validate.d.ts +1 -0
- package/resources/validate.d.ts.map +1 -1
- package/resources/validate.js +5 -1
- package/resources/validate.js.map +1 -1
- package/src/commands/connect.ts +13 -1
- package/src/registry/registry.test.ts +7 -0
- package/src/resources/connect/connect.integration.test.ts +45 -1
- package/src/resources/connect/connect.ts +48 -2
- package/src/resources/run/attachments.test.ts +22 -0
- package/src/resources/run/attachments.ts +44 -5
- package/src/resources/validate.ts +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoBtD"}
|
package/commands/connect.js
CHANGED
|
@@ -15,13 +15,20 @@ export function registerConnect(program) {
|
|
|
15
15
|
connect
|
|
16
16
|
.command("mcp-server <slug-or-id>")
|
|
17
17
|
.description("connect to an MCP server and discover its tools")
|
|
18
|
-
.option("--timeout <seconds>", "
|
|
18
|
+
.option("--timeout <seconds>", "bound the wait for connection and discovery (always bounds --dry-run; " +
|
|
19
|
+
"bounds the server-side connect only when set explicitly)", String(DEFAULT_TIMEOUT_SECONDS))
|
|
19
20
|
.option("--dry-run", "discover and display results without pushing to the backend")
|
|
20
21
|
.option("--env <KEY=VALUE>", "environment variable for the MCP server (repeatable)", (value, previous) => [...previous, value], [])
|
|
21
22
|
.action((reference, options, command) => runConnect(reference, options, command));
|
|
22
23
|
}
|
|
23
24
|
async function runConnect(reference, options, command) {
|
|
24
25
|
const timeoutMs = parseTimeout(options.timeout);
|
|
26
|
+
// The 30s default exists for --dry-run's local discovery. A real connect
|
|
27
|
+
// legitimately takes minutes (server-side sandbox boot + discovery + tool
|
|
28
|
+
// classification), so bounding it by the DEFAULT would fail healthy
|
|
29
|
+
// connects — the wait is bounded only when the user set --timeout
|
|
30
|
+
// explicitly (issue #239: the flag used to be silently ignored here).
|
|
31
|
+
const timeoutIsExplicit = command.getOptionValueSource("timeout") === "cli";
|
|
25
32
|
const [{ connectBackend }, { connectMcpServer }, { renderConnectResult }] = await Promise.all([
|
|
26
33
|
import("../backend.js"),
|
|
27
34
|
import("../resources/connect/connect.js"),
|
|
@@ -45,6 +52,7 @@ async function runConnect(reference, options, command) {
|
|
|
45
52
|
reference,
|
|
46
53
|
org,
|
|
47
54
|
timeoutMs,
|
|
55
|
+
pushTimeoutMs: timeoutIsExplicit ? timeoutMs : undefined,
|
|
48
56
|
dryRun: options.dryRun === true,
|
|
49
57
|
envOverrides: options.env,
|
|
50
58
|
backendType: client.config.backend.type,
|
package/commands/connect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,4EAA4E;AAC5E,4DAA4D;AAC5D,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,iBAAiB;AAGjB,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQxC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,wDAAwD,CAAC,CAAC;IAEjH,OAAO;SACJ,OAAO,CAAC,yBAAyB,CAAC;SAClC,WAAW,CAAC,iDAAiD,CAAC;SAC9D,MAAM,
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.0",
|
|
4
4
|
"description": "Stigmer command-line interface — manage agents, workflows, MCP servers, skills, and executions from the terminal",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"@connectrpc/connect": "^2.0.0",
|
|
36
36
|
"@connectrpc/connect-node": "^2.1.1",
|
|
37
37
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
38
|
-
"@stigmer/ink": "3.
|
|
39
|
-
"@stigmer/mcp-server": "3.
|
|
40
|
-
"@stigmer/protos": "3.
|
|
41
|
-
"@stigmer/sdk": "3.
|
|
38
|
+
"@stigmer/ink": "3.11.0",
|
|
39
|
+
"@stigmer/mcp-server": "3.11.0",
|
|
40
|
+
"@stigmer/protos": "3.11.0",
|
|
41
|
+
"@stigmer/sdk": "3.11.0",
|
|
42
42
|
"commander": "^12.1.0",
|
|
43
43
|
"fflate": "^0.8.3",
|
|
44
44
|
"ink": "^7.0.0",
|
|
@@ -6,6 +6,15 @@ export interface ConnectOptions {
|
|
|
6
6
|
readonly reference: string;
|
|
7
7
|
readonly org: string;
|
|
8
8
|
readonly timeoutMs: number;
|
|
9
|
+
/**
|
|
10
|
+
* Bound the wait on the server-side connect RPC. Unset by default: a real
|
|
11
|
+
* connect legitimately takes minutes (sandbox boot + discovery + tool
|
|
12
|
+
* classification), so only an EXPLICIT --timeout bounds it — the flag's
|
|
13
|
+
* 30s default is sized for --dry-run's local discovery and would fail
|
|
14
|
+
* healthy connects. The bound is soft (the CLI stops waiting; the backend
|
|
15
|
+
* finishes the connect on its own).
|
|
16
|
+
*/
|
|
17
|
+
readonly pushTimeoutMs?: number;
|
|
9
18
|
readonly dryRun: boolean;
|
|
10
19
|
readonly envOverrides: readonly string[];
|
|
11
20
|
/** Backend type, for resolving the OAuth web-console URL. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/resources/connect/connect.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wDAAwD,CAAC;AAExF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2DAA2D,CAAC;AAExG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAQ1D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC1D,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;CACzC;AAED,gFAAgF;AAChF,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/resources/connect/connect.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wDAAwD,CAAC;AAExF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2DAA2D,CAAC;AAExG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAQ1D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC1D,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;CACzC;AAED,gFAAgF;AAChF,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAkCpG"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// Audit identity (reviewer) and token acquisition stay server-side by design.
|
|
11
11
|
import { create } from "@bufbuild/protobuf";
|
|
12
12
|
import { ConnectInputSchema, GetOAuthGrantStatusInputSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
|
|
13
|
-
import { UsageError } from "../../errors/index.js";
|
|
13
|
+
import { CliExitError, ExitCode, UsageError } from "../../errors/index.js";
|
|
14
14
|
import { defaultRegistry } from "../../registry/index.js";
|
|
15
15
|
import { PlaceholderResolutionError } from "../mcp/placeholder-resolver.js";
|
|
16
16
|
import { buildRuntimeEnv } from "../mcp/runtime-env.js";
|
|
@@ -41,13 +41,41 @@ export async function connectMcpServer(client, opts) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
await ensureOAuthSatisfied(client, server, opts);
|
|
44
|
-
const
|
|
44
|
+
const push = client.mcpServer.connect(create(ConnectInputSchema, {
|
|
45
45
|
mcpServerId: server.metadata?.id ?? "",
|
|
46
46
|
org: opts.org,
|
|
47
47
|
runtimeEnv: buildRuntimeEnv(server, opts.envOverrides),
|
|
48
48
|
}));
|
|
49
|
+
const updated = opts.pushTimeoutMs === undefined
|
|
50
|
+
? await push
|
|
51
|
+
: await boundedPush(push, opts.pushTimeoutMs, server);
|
|
49
52
|
return { server, capabilities: updated.status?.discoveredCapabilities, updated };
|
|
50
53
|
}
|
|
54
|
+
// Soft timeout on the server-side connect (the client/client.ts idiom): races
|
|
55
|
+
// the RPC against a timer without cancelling it — the backend's connect
|
|
56
|
+
// workflow keeps running and persists its result on its own, so the message
|
|
57
|
+
// says exactly that instead of implying the connect failed.
|
|
58
|
+
async function boundedPush(push, timeoutMs, server) {
|
|
59
|
+
const slug = server.metadata?.slug ?? server.metadata?.id ?? "the server";
|
|
60
|
+
let timer;
|
|
61
|
+
const timeout = new Promise((_, reject) => {
|
|
62
|
+
timer = setTimeout(() => reject(new CliExitError(`Stopped waiting for the connect of MCP server '${slug}' after ${timeoutMs / 1000}s (--timeout)`, ExitCode.Connection, [
|
|
63
|
+
"The server-side connect is still running and will persist its result if it succeeds.",
|
|
64
|
+
`Check the outcome with: stigmer get mcp-server ${slug}`,
|
|
65
|
+
"Re-run without --timeout to wait for completion.",
|
|
66
|
+
])), timeoutMs);
|
|
67
|
+
});
|
|
68
|
+
// The losing push may settle after the CLI has started exiting; swallow its
|
|
69
|
+
// late rejection so it cannot surface as an unhandled-rejection crash.
|
|
70
|
+
void push.catch(() => { });
|
|
71
|
+
try {
|
|
72
|
+
return await Promise.race([push, timeout]);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
if (timer !== undefined)
|
|
76
|
+
clearTimeout(timer);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
51
79
|
// Resolve a reference (id, org/slug, or bare slug) to an McpServer. Mirrors Go's
|
|
52
80
|
// GetFromBackend.
|
|
53
81
|
async function resolveMcpServer(client, reference, org) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/resources/connect/connect.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,4EAA4E;AAC5E,gFAAgF;AAChF,iEAAiE;AACjE,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,6EAA6E;AAC7E,8EAA8E;AAE9E,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,8BAA8B,EAAE,MAAM,uDAAuD,CAAC;AAK3H,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/resources/connect/connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../../src/resources/run/attachments.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,8DAA8D,CAAC;AACjH,OAAO,EACL,KAAK,uBAAuB,EAE5B,KAAK,wBAAwB,EAC9B,MAAM,4DAA4D,CAAC;AAMpE,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAElD,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACnF;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC;IACnC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,cAAc,EAAE,SAAS,MAAM,EAAE,EACjC,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../../src/resources/run/attachments.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,8DAA8D,CAAC;AACjH,OAAO,EACL,KAAK,uBAAuB,EAE5B,KAAK,wBAAwB,EAC9B,MAAM,4DAA4D,CAAC;AAMpE,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAElD,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACnF;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC;IACnC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,cAAc,EAAE,SAAS,MAAM,EAAE,EACjC,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAiB3B"}
|
|
@@ -25,6 +25,7 @@ export async function processAttachments(uploader, paths, workspaceRoots, progre
|
|
|
25
25
|
const workspaceFileRefs = [];
|
|
26
26
|
if (paths.length === 0)
|
|
27
27
|
return { attachments, workspaceFileRefs };
|
|
28
|
+
const takenDirNames = new Set();
|
|
28
29
|
for (const path of paths) {
|
|
29
30
|
const rel = matchWorkspaceRoot(path, workspaceRoots);
|
|
30
31
|
if (rel !== null) {
|
|
@@ -32,7 +33,7 @@ export async function processAttachments(uploader, paths, workspaceRoots, progre
|
|
|
32
33
|
workspaceFileRefs.push(rel);
|
|
33
34
|
continue;
|
|
34
35
|
}
|
|
35
|
-
attachments.push(await processFile(uploader, path, progress));
|
|
36
|
+
attachments.push(await processFile(uploader, path, takenDirNames, progress));
|
|
36
37
|
}
|
|
37
38
|
return { attachments, workspaceFileRefs };
|
|
38
39
|
}
|
|
@@ -58,7 +59,7 @@ function matchWorkspaceRoot(path, roots) {
|
|
|
58
59
|
}
|
|
59
60
|
// Stat the path, then upload a file or zip+upload a directory. Mirrors Go's
|
|
60
61
|
// processFile.
|
|
61
|
-
async function processFile(uploader, path, progress) {
|
|
62
|
+
async function processFile(uploader, path, takenDirNames, progress) {
|
|
62
63
|
let stat;
|
|
63
64
|
try {
|
|
64
65
|
stat = statSync(path);
|
|
@@ -70,7 +71,7 @@ async function processFile(uploader, path, progress) {
|
|
|
70
71
|
throw new UsageError(`failed to stat attachment "${path}": ${e.message}`);
|
|
71
72
|
}
|
|
72
73
|
if (stat.isDirectory())
|
|
73
|
-
return processDirectory(uploader, path, progress);
|
|
74
|
+
return processDirectory(uploader, path, takenDirNames, progress);
|
|
74
75
|
const absPath = resolve(path);
|
|
75
76
|
const filename = basenameOf(path);
|
|
76
77
|
const contentType = detectContentType(filename);
|
|
@@ -81,9 +82,22 @@ async function processFile(uploader, path, progress) {
|
|
|
81
82
|
}
|
|
82
83
|
// Zip a directory (extract=true so the runner unpacks it at mount_path) and
|
|
83
84
|
// upload it as one archive. Mirrors Go's processDirectory.
|
|
84
|
-
async function processDirectory(uploader, path, progress) {
|
|
85
|
+
async function processDirectory(uploader, path, takenDirNames, progress) {
|
|
85
86
|
const absPath = resolve(path);
|
|
86
|
-
|
|
87
|
+
// Two same-named directories (`--attach a/data --attach b/data`) would
|
|
88
|
+
// derive the SAME explicit mount path, which the runner rejects as a user
|
|
89
|
+
// contradiction (attachment-injector.ts resolveMountPaths). The CLI derives
|
|
90
|
+
// these names mechanically from basenames, so it owns the rename — the same
|
|
91
|
+
// principle as the React composer's client-side uniquify (sdk/react
|
|
92
|
+
// attachment-utils.ts). Duplicate FILE attachments need no CLI handling:
|
|
93
|
+
// they carry no mountPath, so the runner renames them itself.
|
|
94
|
+
const requestedName = basenameOf(absPath);
|
|
95
|
+
const dirname = uniquifyDirName(requestedName, takenDirNames);
|
|
96
|
+
takenDirNames.add(dirname);
|
|
97
|
+
if (dirname !== requestedName) {
|
|
98
|
+
progress?.(`Attaching second '${requestedName}/' as '${dirname}/' (a directory ` +
|
|
99
|
+
`named '${requestedName}' is already attached)`);
|
|
100
|
+
}
|
|
87
101
|
const { bytes, fileCount, originalSize } = zipDirectory(absPath, progress);
|
|
88
102
|
const zipSize = bytes.byteLength;
|
|
89
103
|
progress?.(`Zipping directory: ${dirname}/ (${fileCount} files, ` +
|
|
@@ -196,6 +210,20 @@ function formatFileSize(bytes) {
|
|
|
196
210
|
return `${(bytes / KB).toFixed(1)} KB`;
|
|
197
211
|
return `${bytes} B`;
|
|
198
212
|
}
|
|
213
|
+
// Returns `name` unchanged when free, otherwise the first free `name-2`,
|
|
214
|
+
// `name-3`, … variant. Deliberately extension-blind — directory names have no
|
|
215
|
+
// extension semantics ("reports.2024" becomes "reports.2024-2", not
|
|
216
|
+
// "reports-2.2024"), unlike the filename uniquify in the runner and React SDK
|
|
217
|
+
// (shared/attachment-naming.ts / attachment-utils.ts) this mirrors.
|
|
218
|
+
function uniquifyDirName(name, taken) {
|
|
219
|
+
if (!taken.has(name))
|
|
220
|
+
return name;
|
|
221
|
+
for (let n = 2;; n++) {
|
|
222
|
+
const candidate = `${name}-${n}`;
|
|
223
|
+
if (!taken.has(candidate))
|
|
224
|
+
return candidate;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
199
227
|
// path.basename, but resilient to trailing slashes (matches Go filepath.Base
|
|
200
228
|
// semantics closely enough for display/name derivation).
|
|
201
229
|
function basenameOf(p) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/resources/run/attachments.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,kFAAkF;AAClF,kFAAkF;AAClF,+EAA+E;AAC/E,gFAAgF;AAChF,gFAAgF;AAChF,mCAAmC;AAEnC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAmB,gBAAgB,EAAE,MAAM,8DAA8D,CAAC;AACjH,OAAO,EAEL,6BAA6B,GAE9B,MAAM,4DAA4D,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,uEAAuE;AACvE,MAAM,mBAAmB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AAoBtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,QAA4B,EAC5B,KAAwB,EACxB,cAAiC,EACjC,QAAuB;IAEvB,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,iBAAiB,GAAa,EAAE,CAAC;IACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;IAElE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QACrD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,QAAQ,EAAE,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;YACjD,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/resources/run/attachments.ts"],"names":[],"mappings":"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"}
|
package/resources/validate.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type DescMessage, type JsonValue } from "@bufbuild/protobuf";
|
|
2
2
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
3
|
+
export declare const VALIDATE_SCHEMAS: ReadonlyMap<ApiResourceKind, DescMessage>;
|
|
3
4
|
export declare function schemaForValidate(kind: ApiResourceKind): DescMessage | undefined;
|
|
4
5
|
/** Structurally validate a parsed YAML document against its proto schema. */
|
|
5
6
|
export declare function validateDocument(schema: DescMessage, document: JsonValue): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/resources/validate.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,WAAW,EAAY,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKhF,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/resources/validate.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,WAAW,EAAY,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKhF,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AAOtH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,eAAe,EAAE,WAAW,CAMrE,CAAC;AAEH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW,GAAG,SAAS,CAEhF;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,GAAG,IAAI,CAI/E"}
|
package/resources/validate.js
CHANGED
|
@@ -11,7 +11,11 @@ import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1
|
|
|
11
11
|
import { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/api_pb";
|
|
12
12
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
13
13
|
import { ProjectSchema } from "@stigmer/protos/ai/stigmer/tenancy/project/v1/api_pb";
|
|
14
|
-
|
|
14
|
+
// Exported for the verb/dispatch conformance suite (registry/registry.test.ts),
|
|
15
|
+
// which holds this map and the matrix's Verb.Validate promises to strict
|
|
16
|
+
// bidirectional equality — the stigmer/stigmer#353 drift class. Command code
|
|
17
|
+
// resolves schemas through `schemaForValidate`, never this map directly.
|
|
18
|
+
export const VALIDATE_SCHEMAS = new Map([
|
|
15
19
|
[ApiResourceKind.agent, AgentSchema],
|
|
16
20
|
[ApiResourceKind.workflow, WorkflowSchema],
|
|
17
21
|
[ApiResourceKind.mcp_server, McpServerSchema],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/resources/validate.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,6EAA6E;AAC7E,qDAAqD;AAErD,OAAO,EAAoB,QAAQ,EAAkB,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,wDAAwD,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,wDAAwD,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,MAAM,uDAAuD,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AACtH,OAAO,EAAE,aAAa,EAAE,MAAM,sDAAsD,CAAC;AAErF,MAAM,gBAAgB,GAA8C,IAAI,GAAG,CAA+B;
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/resources/validate.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,6EAA6E;AAC7E,qDAAqD;AAErD,OAAO,EAAoB,QAAQ,EAAkB,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,wDAAwD,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,wDAAwD,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,MAAM,uDAAuD,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AACtH,OAAO,EAAE,aAAa,EAAE,MAAM,sDAAsD,CAAC;AAErF,gFAAgF;AAChF,yEAAyE;AACzE,6EAA6E;AAC7E,yEAAyE;AACzE,MAAM,CAAC,MAAM,gBAAgB,GAA8C,IAAI,GAAG,CAA+B;IAC/G,CAAC,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC;IACpC,CAAC,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IAC1C,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,CAAC;IAC7C,CAAC,eAAe,CAAC,OAAO,EAAE,aAAa,CAAC;IACxC,CAAC,eAAe,CAAC,SAAS,EAAE,eAAe,CAAC;CAC7C,CAAC,CAAC;AAEH,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,MAAmB,EAAE,QAAmB;IACvE,6EAA6E;IAC7E,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5D,CAAC"}
|
package/src/commands/connect.ts
CHANGED
|
@@ -26,7 +26,12 @@ export function registerConnect(program: Command): void {
|
|
|
26
26
|
connect
|
|
27
27
|
.command("mcp-server <slug-or-id>")
|
|
28
28
|
.description("connect to an MCP server and discover its tools")
|
|
29
|
-
.option(
|
|
29
|
+
.option(
|
|
30
|
+
"--timeout <seconds>",
|
|
31
|
+
"bound the wait for connection and discovery (always bounds --dry-run; " +
|
|
32
|
+
"bounds the server-side connect only when set explicitly)",
|
|
33
|
+
String(DEFAULT_TIMEOUT_SECONDS),
|
|
34
|
+
)
|
|
30
35
|
.option("--dry-run", "discover and display results without pushing to the backend")
|
|
31
36
|
.option(
|
|
32
37
|
"--env <KEY=VALUE>",
|
|
@@ -39,6 +44,12 @@ export function registerConnect(program: Command): void {
|
|
|
39
44
|
|
|
40
45
|
async function runConnect(reference: string, options: ConnectFlags, command: Command): Promise<void> {
|
|
41
46
|
const timeoutMs = parseTimeout(options.timeout);
|
|
47
|
+
// The 30s default exists for --dry-run's local discovery. A real connect
|
|
48
|
+
// legitimately takes minutes (server-side sandbox boot + discovery + tool
|
|
49
|
+
// classification), so bounding it by the DEFAULT would fail healthy
|
|
50
|
+
// connects — the wait is bounded only when the user set --timeout
|
|
51
|
+
// explicitly (issue #239: the flag used to be silently ignored here).
|
|
52
|
+
const timeoutIsExplicit = command.getOptionValueSource("timeout") === "cli";
|
|
42
53
|
const [{ connectBackend }, { connectMcpServer }, { renderConnectResult }] = await Promise.all([
|
|
43
54
|
import("../backend.js"),
|
|
44
55
|
import("../resources/connect/connect.js"),
|
|
@@ -67,6 +78,7 @@ async function runConnect(reference: string, options: ConnectFlags, command: Com
|
|
|
67
78
|
reference,
|
|
68
79
|
org,
|
|
69
80
|
timeoutMs,
|
|
81
|
+
pushTimeoutMs: timeoutIsExplicit ? timeoutMs : undefined,
|
|
70
82
|
dryRun: options.dryRun === true,
|
|
71
83
|
envOverrides: options.env,
|
|
72
84
|
backendType: client.config.backend.type,
|
|
@@ -4,6 +4,7 @@ import { APPLY_HANDLERS } from "../resources/apply/handlers.js";
|
|
|
4
4
|
import { DELETE_HANDLERS } from "../resources/delete.js";
|
|
5
5
|
import { GET_BINDINGS } from "../resources/get-bindings.js";
|
|
6
6
|
import { LIST_HANDLERS, SEARCH_KINDS } from "../resources/list.js";
|
|
7
|
+
import { VALIDATE_SCHEMAS } from "../resources/validate.js";
|
|
7
8
|
import { defaultRegistry } from "./registry.js";
|
|
8
9
|
import { Verb } from "./verbs.js";
|
|
9
10
|
|
|
@@ -167,6 +168,12 @@ describe("registry — verb/dispatch conformance", () => {
|
|
|
167
168
|
wired: new Set([...LIST_HANDLERS.keys(), ...SEARCH_KINDS]),
|
|
168
169
|
specialCases: new Map(),
|
|
169
170
|
},
|
|
171
|
+
{
|
|
172
|
+
label: "validate",
|
|
173
|
+
verb: Verb.Validate,
|
|
174
|
+
wired: new Set(VALIDATE_SCHEMAS.keys()),
|
|
175
|
+
specialCases: new Map(),
|
|
176
|
+
},
|
|
170
177
|
{
|
|
171
178
|
label: "delete",
|
|
172
179
|
verb: Verb.Delete,
|
|
@@ -34,12 +34,17 @@ const openSessions = new Set<ServerHttp2Session>();
|
|
|
34
34
|
|
|
35
35
|
let connectCalls: ConnectInput[] = [];
|
|
36
36
|
let grantConnected = false;
|
|
37
|
+
// Delay before the mock Connect RPC answers; lets the --timeout tests
|
|
38
|
+
// simulate a long-running server-side connect. The timer is unref'd so a
|
|
39
|
+
// still-pending delayed response can never hold the test process open.
|
|
40
|
+
let connectDelayMs = 0;
|
|
37
41
|
// The server returned by getByReference; mutated per test for auth scenarios.
|
|
38
42
|
let servedSpec: ReturnType<typeof create<typeof McpServerSchema>>;
|
|
39
43
|
|
|
40
44
|
beforeEach(() => {
|
|
41
45
|
connectCalls = [];
|
|
42
46
|
grantConnected = false;
|
|
47
|
+
connectDelayMs = 0;
|
|
43
48
|
servedSpec = create(McpServerSchema, {
|
|
44
49
|
metadata: { id: "mcp_1", name: "github", slug: "github", org: "acme" },
|
|
45
50
|
spec: {
|
|
@@ -72,8 +77,11 @@ beforeAll(async () => {
|
|
|
72
77
|
// Mirror the backend's protovalidate rule (org min_len=1): reject an empty
|
|
73
78
|
// org so a regression that drops org fails loudly here instead of silently
|
|
74
79
|
// passing (the mock adapter does not run protovalidate on its own).
|
|
75
|
-
connect: (req) => {
|
|
80
|
+
connect: async (req) => {
|
|
76
81
|
if (req.org === "") throw new ConnectError("org – value length must be at least 1 characters", Code.InvalidArgument);
|
|
82
|
+
if (connectDelayMs > 0) {
|
|
83
|
+
await new Promise((resolve) => setTimeout(resolve, connectDelayMs).unref());
|
|
84
|
+
}
|
|
77
85
|
connectCalls.push(req);
|
|
78
86
|
return updatedServer;
|
|
79
87
|
},
|
|
@@ -120,6 +128,42 @@ describe("connect push path", () => {
|
|
|
120
128
|
});
|
|
121
129
|
});
|
|
122
130
|
|
|
131
|
+
describe("--timeout bounds the server-side connect (issue #239)", () => {
|
|
132
|
+
it("stops waiting with actionable guidance when pushTimeoutMs elapses", async () => {
|
|
133
|
+
connectDelayMs = 5_000;
|
|
134
|
+
await expect(
|
|
135
|
+
connectMcpServer(client, {
|
|
136
|
+
reference: "github",
|
|
137
|
+
org: "acme",
|
|
138
|
+
timeoutMs: 30_000,
|
|
139
|
+
pushTimeoutMs: 150,
|
|
140
|
+
dryRun: false,
|
|
141
|
+
envOverrides: ["GITHUB_TOKEN=ghp-x"],
|
|
142
|
+
backendType: "cloud",
|
|
143
|
+
interactive: false,
|
|
144
|
+
}),
|
|
145
|
+
).rejects.toThrow(/Stopped waiting for the connect of MCP server 'github' after 0\.15s/);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("does not bound the wait when pushTimeoutMs is unset (default --timeout)", async () => {
|
|
149
|
+
// The flag's 30s default is sized for --dry-run local discovery; a real
|
|
150
|
+
// connect legitimately outlives it, so only an explicit --timeout bounds
|
|
151
|
+
// the push. 200ms of server delay stands in for "longer than the bound
|
|
152
|
+
// would have been".
|
|
153
|
+
connectDelayMs = 200;
|
|
154
|
+
const result = await connectMcpServer(client, {
|
|
155
|
+
reference: "github",
|
|
156
|
+
org: "acme",
|
|
157
|
+
timeoutMs: 100,
|
|
158
|
+
dryRun: false,
|
|
159
|
+
envOverrides: ["GITHUB_TOKEN=ghp-x"],
|
|
160
|
+
backendType: "cloud",
|
|
161
|
+
interactive: false,
|
|
162
|
+
});
|
|
163
|
+
expect(result.updated?.metadata?.id).toBe("mcp_1");
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
123
167
|
describe("OAuth guidance gate", () => {
|
|
124
168
|
beforeEach(() => {
|
|
125
169
|
servedSpec.spec!.auth = create(McpServerAuthSchema, { targetEnvVar: "GITHUB_TOKEN" });
|
|
@@ -16,7 +16,7 @@ import type { DiscoveredCapabilities } from "@stigmer/protos/ai/stigmer/agentic/
|
|
|
16
16
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
17
17
|
import type { Stigmer } from "@stigmer/sdk";
|
|
18
18
|
import type { BackendType } from "../../config/config.js";
|
|
19
|
-
import { UsageError } from "../../errors/index.js";
|
|
19
|
+
import { CliExitError, ExitCode, UsageError } from "../../errors/index.js";
|
|
20
20
|
import { defaultRegistry } from "../../registry/index.js";
|
|
21
21
|
import { PlaceholderResolutionError } from "../mcp/placeholder-resolver.js";
|
|
22
22
|
import { buildRuntimeEnv } from "../mcp/runtime-env.js";
|
|
@@ -27,6 +27,15 @@ export interface ConnectOptions {
|
|
|
27
27
|
readonly reference: string;
|
|
28
28
|
readonly org: string;
|
|
29
29
|
readonly timeoutMs: number;
|
|
30
|
+
/**
|
|
31
|
+
* Bound the wait on the server-side connect RPC. Unset by default: a real
|
|
32
|
+
* connect legitimately takes minutes (sandbox boot + discovery + tool
|
|
33
|
+
* classification), so only an EXPLICIT --timeout bounds it — the flag's
|
|
34
|
+
* 30s default is sized for --dry-run's local discovery and would fail
|
|
35
|
+
* healthy connects. The bound is soft (the CLI stops waiting; the backend
|
|
36
|
+
* finishes the connect on its own).
|
|
37
|
+
*/
|
|
38
|
+
readonly pushTimeoutMs?: number;
|
|
30
39
|
readonly dryRun: boolean;
|
|
31
40
|
readonly envOverrides: readonly string[];
|
|
32
41
|
/** Backend type, for resolving the OAuth web-console URL. */
|
|
@@ -66,16 +75,53 @@ export async function connectMcpServer(client: Stigmer, opts: ConnectOptions): P
|
|
|
66
75
|
|
|
67
76
|
await ensureOAuthSatisfied(client, server, opts);
|
|
68
77
|
|
|
69
|
-
const
|
|
78
|
+
const push = client.mcpServer.connect(
|
|
70
79
|
create(ConnectInputSchema, {
|
|
71
80
|
mcpServerId: server.metadata?.id ?? "",
|
|
72
81
|
org: opts.org,
|
|
73
82
|
runtimeEnv: buildRuntimeEnv(server, opts.envOverrides),
|
|
74
83
|
}),
|
|
75
84
|
);
|
|
85
|
+
const updated = opts.pushTimeoutMs === undefined
|
|
86
|
+
? await push
|
|
87
|
+
: await boundedPush(push, opts.pushTimeoutMs, server);
|
|
76
88
|
return { server, capabilities: updated.status?.discoveredCapabilities, updated };
|
|
77
89
|
}
|
|
78
90
|
|
|
91
|
+
// Soft timeout on the server-side connect (the client/client.ts idiom): races
|
|
92
|
+
// the RPC against a timer without cancelling it — the backend's connect
|
|
93
|
+
// workflow keeps running and persists its result on its own, so the message
|
|
94
|
+
// says exactly that instead of implying the connect failed.
|
|
95
|
+
async function boundedPush<T>(push: Promise<T>, timeoutMs: number, server: McpServer): Promise<T> {
|
|
96
|
+
const slug = server.metadata?.slug ?? server.metadata?.id ?? "the server";
|
|
97
|
+
let timer: NodeJS.Timeout | undefined;
|
|
98
|
+
const timeout = new Promise<never>((_, reject) => {
|
|
99
|
+
timer = setTimeout(
|
|
100
|
+
() =>
|
|
101
|
+
reject(
|
|
102
|
+
new CliExitError(
|
|
103
|
+
`Stopped waiting for the connect of MCP server '${slug}' after ${timeoutMs / 1000}s (--timeout)`,
|
|
104
|
+
ExitCode.Connection,
|
|
105
|
+
[
|
|
106
|
+
"The server-side connect is still running and will persist its result if it succeeds.",
|
|
107
|
+
`Check the outcome with: stigmer get mcp-server ${slug}`,
|
|
108
|
+
"Re-run without --timeout to wait for completion.",
|
|
109
|
+
],
|
|
110
|
+
),
|
|
111
|
+
),
|
|
112
|
+
timeoutMs,
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
// The losing push may settle after the CLI has started exiting; swallow its
|
|
116
|
+
// late rejection so it cannot surface as an unhandled-rejection crash.
|
|
117
|
+
void push.catch(() => {});
|
|
118
|
+
try {
|
|
119
|
+
return await Promise.race([push, timeout]);
|
|
120
|
+
} finally {
|
|
121
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
79
125
|
// Resolve a reference (id, org/slug, or bare slug) to an McpServer. Mirrors Go's
|
|
80
126
|
// GetFromBackend.
|
|
81
127
|
async function resolveMcpServer(client: Stigmer, reference: string, org: string): Promise<McpServer> {
|
|
@@ -110,4 +110,26 @@ describe("directory zipping", () => {
|
|
|
110
110
|
writeFileSync(join(empty, ".hidden"), "x"); // only hidden -> nothing attachable
|
|
111
111
|
await expect(processAttachments(uploader, [empty], [])).rejects.toThrow(/no attachable files/);
|
|
112
112
|
});
|
|
113
|
+
|
|
114
|
+
it("uniquifies duplicate directory basenames so mount paths never contradict (issue #364)", async () => {
|
|
115
|
+
// Two dirs named `data` from different parents would otherwise derive the
|
|
116
|
+
// SAME explicit mount path, which the runner rejects as a contradiction.
|
|
117
|
+
const dirA = join(dir, "a", "data");
|
|
118
|
+
const dirB = join(dir, "b", "data");
|
|
119
|
+
mkdirSync(dirA, { recursive: true });
|
|
120
|
+
mkdirSync(dirB, { recursive: true });
|
|
121
|
+
writeFileSync(join(dirA, "one.txt"), "1");
|
|
122
|
+
writeFileSync(join(dirB, "two.txt"), "2");
|
|
123
|
+
|
|
124
|
+
const progress: string[] = [];
|
|
125
|
+
const result = await processAttachments(uploader, [dirA, dirB], [], (l) => progress.push(l));
|
|
126
|
+
|
|
127
|
+
expect(result.attachments).toHaveLength(2);
|
|
128
|
+
expect(result.attachments[0].filename).toBe("data.zip");
|
|
129
|
+
expect(result.attachments[0].mountPath).toBe("inputs/data/");
|
|
130
|
+
expect(result.attachments[1].filename).toBe("data-2.zip");
|
|
131
|
+
expect(result.attachments[1].mountPath).toBe("inputs/data-2/");
|
|
132
|
+
// The rename is disclosed to the user on the progress sink.
|
|
133
|
+
expect(progress.some((l) => l.includes("'data/'") && l.includes("'data-2/'"))).toBe(true);
|
|
134
|
+
});
|
|
113
135
|
});
|
|
@@ -55,6 +55,7 @@ export async function processAttachments(
|
|
|
55
55
|
const workspaceFileRefs: string[] = [];
|
|
56
56
|
if (paths.length === 0) return { attachments, workspaceFileRefs };
|
|
57
57
|
|
|
58
|
+
const takenDirNames = new Set<string>();
|
|
58
59
|
for (const path of paths) {
|
|
59
60
|
const rel = matchWorkspaceRoot(path, workspaceRoots);
|
|
60
61
|
if (rel !== null) {
|
|
@@ -62,7 +63,7 @@ export async function processAttachments(
|
|
|
62
63
|
workspaceFileRefs.push(rel);
|
|
63
64
|
continue;
|
|
64
65
|
}
|
|
65
|
-
attachments.push(await processFile(uploader, path, progress));
|
|
66
|
+
attachments.push(await processFile(uploader, path, takenDirNames, progress));
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
return { attachments, workspaceFileRefs };
|
|
@@ -90,7 +91,12 @@ function matchWorkspaceRoot(path: string, roots: readonly string[]): string | nu
|
|
|
90
91
|
|
|
91
92
|
// Stat the path, then upload a file or zip+upload a directory. Mirrors Go's
|
|
92
93
|
// processFile.
|
|
93
|
-
async function processFile(
|
|
94
|
+
async function processFile(
|
|
95
|
+
uploader: AttachmentUploader,
|
|
96
|
+
path: string,
|
|
97
|
+
takenDirNames: Set<string>,
|
|
98
|
+
progress?: ProgressSink,
|
|
99
|
+
): Promise<Attachment> {
|
|
94
100
|
let stat: ReturnType<typeof statSync>;
|
|
95
101
|
try {
|
|
96
102
|
stat = statSync(path);
|
|
@@ -100,7 +106,7 @@ async function processFile(uploader: AttachmentUploader, path: string, progress?
|
|
|
100
106
|
throw new UsageError(`failed to stat attachment "${path}": ${e.message}`);
|
|
101
107
|
}
|
|
102
108
|
|
|
103
|
-
if (stat.isDirectory()) return processDirectory(uploader, path, progress);
|
|
109
|
+
if (stat.isDirectory()) return processDirectory(uploader, path, takenDirNames, progress);
|
|
104
110
|
|
|
105
111
|
const absPath = resolve(path);
|
|
106
112
|
const filename = basenameOf(path);
|
|
@@ -113,9 +119,29 @@ async function processFile(uploader: AttachmentUploader, path: string, progress?
|
|
|
113
119
|
|
|
114
120
|
// Zip a directory (extract=true so the runner unpacks it at mount_path) and
|
|
115
121
|
// upload it as one archive. Mirrors Go's processDirectory.
|
|
116
|
-
async function processDirectory(
|
|
122
|
+
async function processDirectory(
|
|
123
|
+
uploader: AttachmentUploader,
|
|
124
|
+
path: string,
|
|
125
|
+
takenDirNames: Set<string>,
|
|
126
|
+
progress?: ProgressSink,
|
|
127
|
+
): Promise<Attachment> {
|
|
117
128
|
const absPath = resolve(path);
|
|
118
|
-
|
|
129
|
+
// Two same-named directories (`--attach a/data --attach b/data`) would
|
|
130
|
+
// derive the SAME explicit mount path, which the runner rejects as a user
|
|
131
|
+
// contradiction (attachment-injector.ts resolveMountPaths). The CLI derives
|
|
132
|
+
// these names mechanically from basenames, so it owns the rename — the same
|
|
133
|
+
// principle as the React composer's client-side uniquify (sdk/react
|
|
134
|
+
// attachment-utils.ts). Duplicate FILE attachments need no CLI handling:
|
|
135
|
+
// they carry no mountPath, so the runner renames them itself.
|
|
136
|
+
const requestedName = basenameOf(absPath);
|
|
137
|
+
const dirname = uniquifyDirName(requestedName, takenDirNames);
|
|
138
|
+
takenDirNames.add(dirname);
|
|
139
|
+
if (dirname !== requestedName) {
|
|
140
|
+
progress?.(
|
|
141
|
+
`Attaching second '${requestedName}/' as '${dirname}/' (a directory ` +
|
|
142
|
+
`named '${requestedName}' is already attached)`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
119
145
|
|
|
120
146
|
const { bytes, fileCount, originalSize } = zipDirectory(absPath, progress);
|
|
121
147
|
const zipSize = bytes.byteLength;
|
|
@@ -248,6 +274,19 @@ function formatFileSize(bytes: number): string {
|
|
|
248
274
|
return `${bytes} B`;
|
|
249
275
|
}
|
|
250
276
|
|
|
277
|
+
// Returns `name` unchanged when free, otherwise the first free `name-2`,
|
|
278
|
+
// `name-3`, … variant. Deliberately extension-blind — directory names have no
|
|
279
|
+
// extension semantics ("reports.2024" becomes "reports.2024-2", not
|
|
280
|
+
// "reports-2.2024"), unlike the filename uniquify in the runner and React SDK
|
|
281
|
+
// (shared/attachment-naming.ts / attachment-utils.ts) this mirrors.
|
|
282
|
+
function uniquifyDirName(name: string, taken: ReadonlySet<string>): string {
|
|
283
|
+
if (!taken.has(name)) return name;
|
|
284
|
+
for (let n = 2; ; n++) {
|
|
285
|
+
const candidate = `${name}-${n}`;
|
|
286
|
+
if (!taken.has(candidate)) return candidate;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
251
290
|
// path.basename, but resilient to trailing slashes (matches Go filepath.Base
|
|
252
291
|
// semantics closely enough for display/name derivation).
|
|
253
292
|
function basenameOf(p: string): string {
|
|
@@ -13,7 +13,11 @@ import { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/a
|
|
|
13
13
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
14
14
|
import { ProjectSchema } from "@stigmer/protos/ai/stigmer/tenancy/project/v1/api_pb";
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Exported for the verb/dispatch conformance suite (registry/registry.test.ts),
|
|
17
|
+
// which holds this map and the matrix's Verb.Validate promises to strict
|
|
18
|
+
// bidirectional equality — the stigmer/stigmer#353 drift class. Command code
|
|
19
|
+
// resolves schemas through `schemaForValidate`, never this map directly.
|
|
20
|
+
export const VALIDATE_SCHEMAS: ReadonlyMap<ApiResourceKind, DescMessage> = new Map<ApiResourceKind, DescMessage>([
|
|
17
21
|
[ApiResourceKind.agent, AgentSchema],
|
|
18
22
|
[ApiResourceKind.workflow, WorkflowSchema],
|
|
19
23
|
[ApiResourceKind.mcp_server, McpServerSchema],
|