llm-cli-gateway 2.13.0 → 2.13.2

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.
@@ -60,4 +60,13 @@ export declare function registerExistingWorkspace(input: {
60
60
  logger?: Logger;
61
61
  }): WorkspaceRepo;
62
62
  export declare function createTempWorkspaceConfig(contents: string): string;
63
+ export interface RemoteSafeWorkspaceSummary {
64
+ ready: boolean;
65
+ default: string | null;
66
+ aliases: string[];
67
+ repo_count: number;
68
+ allowed_root_count: number;
69
+ }
70
+ export declare function remoteSafeWorkspaceSummary(registry: WorkspaceRegistry): RemoteSafeWorkspaceSummary;
71
+ export declare function describeWorkspaceRemote(repo: WorkspaceRepo): Record<string, unknown>;
63
72
  export declare function describeWorkspace(repo: WorkspaceRepo): Record<string, unknown>;
@@ -350,13 +350,19 @@ export function registerExistingWorkspace(input) {
350
350
  if (registry.repos.some(repo => repo.alias === alias)) {
351
351
  throw new WorkspaceRegistryError(`Workspace alias "${alias}" already exists`);
352
352
  }
353
+ const genericDenied = new WorkspaceRegistryError("No allowed root permits registering a Git repository at the requested path.");
354
+ if (!path.isAbsolute(input.repoPath))
355
+ throw genericDenied;
356
+ const candidateReal = path.resolve(expandHome(input.repoPath));
357
+ const permittingRoot = registry.allowedRoots.find(candidate => candidate.allowRegisterExistingGitRepos && isUnder(candidate.path, candidateReal));
358
+ if (!permittingRoot)
359
+ throw genericDenied;
353
360
  const real = realExistingPath(input.repoPath);
354
361
  if (!isGitRepo(real))
355
362
  throw new WorkspaceRegistryError("Existing workspace must be a Git repo");
356
- const root = registry.allowedRoots.find(candidate => isUnder(candidate.path, real));
357
- if (!root?.allowRegisterExistingGitRepos) {
358
- throw new WorkspaceRegistryError("No allowed root permits registering this Git repo");
359
- }
363
+ const root = registry.allowedRoots.find(candidate => candidate.allowRegisterExistingGitRepos && isUnder(candidate.path, real));
364
+ if (!root)
365
+ throw genericDenied;
360
366
  const workspaces = (raw.workspaces ?? {});
361
367
  const repos = (Array.isArray(workspaces.repos) ? workspaces.repos : []);
362
368
  repos.push({
@@ -389,6 +395,20 @@ export function createTempWorkspaceConfig(contents) {
389
395
  writeFileSync(configPath, contents, { mode: 0o600 });
390
396
  return configPath;
391
397
  }
398
+ export function remoteSafeWorkspaceSummary(registry) {
399
+ return {
400
+ ready: registry.defaultAlias !== null || registry.repos.length > 0,
401
+ default: registry.defaultAlias,
402
+ aliases: registry.repos.map(repo => repo.alias),
403
+ repo_count: registry.repos.length,
404
+ allowed_root_count: registry.allowedRoots.length,
405
+ };
406
+ }
407
+ export function describeWorkspaceRemote(repo) {
408
+ const full = describeWorkspace(repo);
409
+ delete full.path;
410
+ return full;
411
+ }
392
412
  export function describeWorkspace(repo) {
393
413
  let branch = null;
394
414
  let dirty = false;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "llm-cli-gateway",
3
- "version": "2.13.0",
3
+ "version": "2.13.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "llm-cli-gateway",
9
- "version": "2.13.0",
9
+ "version": "2.13.2",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@modelcontextprotocol/sdk": "^1.29.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-cli-gateway",
3
- "version": "2.13.0",
3
+ "version": "2.13.2",
4
4
  "mcpName": "io.github.verivus-oss/llm-cli-gateway",
5
5
  "description": "MCP server providing unified access to Claude Code, Codex, Gemini, Grok, Mistral Vibe, and Devin CLIs with session management, retry logic, async job orchestration, durable job results, and cross-LLM validation.",
6
6
  "license": "MIT",
@@ -14,6 +14,7 @@
14
14
  "workspaces",
15
15
  "providers",
16
16
  "endpoint_exposure",
17
+ "remote_http_oauth",
17
18
  "client_config",
18
19
  "cache_awareness",
19
20
  "provider_capabilities",
@@ -229,6 +230,80 @@
229
230
  },
230
231
  "additionalProperties": false
231
232
  },
233
+ "remote_http_oauth": {
234
+ "type": "object",
235
+ "description": "Stable readiness projection for the preferred remote connector path (public HTTPS URL + /mcp + OAuth + registered/default workspace). Secret-free.",
236
+ "required": [
237
+ "ready",
238
+ "stage",
239
+ "public_url",
240
+ "mcp_url",
241
+ "auth_mode",
242
+ "oauth",
243
+ "workspace",
244
+ "next_actions"
245
+ ],
246
+ "properties": {
247
+ "ready": { "type": "boolean" },
248
+ "stage": {
249
+ "enum": [
250
+ "not_started",
251
+ "missing_public_url",
252
+ "endpoint_unreachable",
253
+ "oauth_disabled",
254
+ "unsafe_oauth_config",
255
+ "missing_oauth_client",
256
+ "missing_workspace",
257
+ "ready"
258
+ ]
259
+ },
260
+ "public_url": { "type": ["string", "null"] },
261
+ "mcp_url": { "type": ["string", "null"] },
262
+ "auth_mode": { "enum": ["oauth", "bearer_token", "none"] },
263
+ "oauth": {
264
+ "type": "object",
265
+ "required": [
266
+ "enabled",
267
+ "issuer",
268
+ "authorization_url",
269
+ "token_url",
270
+ "registration_policy",
271
+ "clients_configured",
272
+ "consent_required"
273
+ ],
274
+ "properties": {
275
+ "enabled": { "type": "boolean" },
276
+ "issuer": { "type": ["string", "null"] },
277
+ "authorization_url": { "type": ["string", "null"] },
278
+ "token_url": { "type": ["string", "null"] },
279
+ "registration_policy": {
280
+ "enum": ["static_clients", "shared_secret", "open_dev"]
281
+ },
282
+ "clients_configured": { "type": "integer", "minimum": 0 },
283
+ "consent_required": { "type": "boolean" }
284
+ },
285
+ "additionalProperties": false
286
+ },
287
+ "workspace": {
288
+ "type": "object",
289
+ "required": ["ready", "default", "aliases"],
290
+ "properties": {
291
+ "ready": { "type": "boolean" },
292
+ "default": { "type": ["string", "null"] },
293
+ "aliases": {
294
+ "type": "array",
295
+ "items": { "type": "string" }
296
+ }
297
+ },
298
+ "additionalProperties": false
299
+ },
300
+ "next_actions": {
301
+ "type": "array",
302
+ "items": { "type": "string" }
303
+ }
304
+ },
305
+ "additionalProperties": false
306
+ },
232
307
  "client_config": {
233
308
  "type": "object",
234
309
  "required": [