switchroom 0.13.12 → 0.13.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/switchroom.js +60 -5
- package/package.json +1 -1
- package/telegram-plugin/dist/gateway/gateway.js +290 -88
- package/telegram-plugin/final-answer-detect.ts +83 -0
- package/telegram-plugin/gateway/gateway.ts +213 -11
- package/telegram-plugin/hooks/silent-end-interrupt-stop.mjs +17 -5
- package/telegram-plugin/pending-work-progress.ts +377 -0
- package/telegram-plugin/runtime-metrics.ts +20 -0
- package/telegram-plugin/silent-end.ts +37 -11
- package/telegram-plugin/tests/final-answer-detect.test.ts +89 -0
- package/telegram-plugin/tests/pending-work-progress.test.ts +354 -0
- package/telegram-plugin/tests/silent-end.test.ts +118 -0
- package/telegram-plugin/uat/scenarios/cross-turn-pending-progress-dm.test.ts +237 -0
package/dist/cli/switchroom.js
CHANGED
|
@@ -26509,17 +26509,34 @@ var init_wait = __esm(() => {
|
|
|
26509
26509
|
// src/cli/drive.ts
|
|
26510
26510
|
var exports_drive = {};
|
|
26511
26511
|
__export(exports_drive, {
|
|
26512
|
+
workspaceScopesForTier: () => workspaceScopesForTier,
|
|
26513
|
+
selectGoogleWorkspaceScopes: () => selectGoogleWorkspaceScopes,
|
|
26512
26514
|
selectDriveAccountScopes: () => selectDriveAccountScopes,
|
|
26513
26515
|
runDriveOAuthFlow: () => runDriveOAuthFlow,
|
|
26514
26516
|
registerDriveCommand: () => registerDriveCommand,
|
|
26515
26517
|
__test: () => __test,
|
|
26518
|
+
GOOGLE_SLIDES_SCOPE: () => GOOGLE_SLIDES_SCOPE,
|
|
26519
|
+
GOOGLE_SHEETS_SCOPE: () => GOOGLE_SHEETS_SCOPE,
|
|
26520
|
+
GOOGLE_DOCS_SCOPE: () => GOOGLE_DOCS_SCOPE,
|
|
26516
26521
|
DRIVE_WRITE_SCOPES: () => DRIVE_WRITE_SCOPES,
|
|
26517
26522
|
DRIVE_READONLY_SCOPES: () => DRIVE_READONLY_SCOPES
|
|
26518
26523
|
});
|
|
26519
26524
|
import { createInterface as createInterface2 } from "node:readline";
|
|
26525
|
+
function workspaceScopesForTier(tier) {
|
|
26526
|
+
const docScopes = [GOOGLE_DOCS_SCOPE, GOOGLE_SHEETS_SCOPE];
|
|
26527
|
+
if (tier === "extended" || tier === "complete") {
|
|
26528
|
+
return [...docScopes, GOOGLE_SLIDES_SCOPE];
|
|
26529
|
+
}
|
|
26530
|
+
return docScopes;
|
|
26531
|
+
}
|
|
26520
26532
|
function selectDriveAccountScopes(write) {
|
|
26521
26533
|
return write ? DRIVE_WRITE_SCOPES : DRIVE_READONLY_SCOPES;
|
|
26522
26534
|
}
|
|
26535
|
+
function selectGoogleWorkspaceScopes(opts) {
|
|
26536
|
+
const base = selectDriveAccountScopes(opts.write);
|
|
26537
|
+
const workspace = workspaceScopesForTier(opts.tier ?? "core");
|
|
26538
|
+
return [...new Set([...base, ...workspace])];
|
|
26539
|
+
}
|
|
26523
26540
|
function getVaultPath(configPath) {
|
|
26524
26541
|
try {
|
|
26525
26542
|
const config = loadConfig(configPath);
|
|
@@ -26932,7 +26949,7 @@ function registerDriveCommand(program3, deps = {}) {
|
|
|
26932
26949
|
await runDisconnect({ agentName: agent }, deps);
|
|
26933
26950
|
});
|
|
26934
26951
|
}
|
|
26935
|
-
var EXIT_OK = 0, EXIT_DENIED = 1, EXIT_TIMEOUT = 2, EXIT_RATE_LIMITED = 3, EXIT_ERROR = 4, EXIT_ABORTED = 130, DRIVE_READONLY_SCOPES, DRIVE_WRITE_SCOPES, DEFAULT_SCOPES, __test;
|
|
26952
|
+
var EXIT_OK = 0, EXIT_DENIED = 1, EXIT_TIMEOUT = 2, EXIT_RATE_LIMITED = 3, EXIT_ERROR = 4, EXIT_ABORTED = 130, DRIVE_READONLY_SCOPES, DRIVE_WRITE_SCOPES, DEFAULT_SCOPES, GOOGLE_DOCS_SCOPE = "https://www.googleapis.com/auth/documents", GOOGLE_SHEETS_SCOPE = "https://www.googleapis.com/auth/spreadsheets", GOOGLE_SLIDES_SCOPE = "https://www.googleapis.com/auth/presentations", __test;
|
|
26936
26953
|
var init_drive = __esm(() => {
|
|
26937
26954
|
init_source();
|
|
26938
26955
|
init_loader();
|
|
@@ -47314,8 +47331,8 @@ var {
|
|
|
47314
47331
|
} = import__.default;
|
|
47315
47332
|
|
|
47316
47333
|
// src/build-info.ts
|
|
47317
|
-
var VERSION = "0.13.
|
|
47318
|
-
var COMMIT_SHA = "
|
|
47334
|
+
var VERSION = "0.13.14";
|
|
47335
|
+
var COMMIT_SHA = "0cf961a6";
|
|
47319
47336
|
|
|
47320
47337
|
// src/cli/agent.ts
|
|
47321
47338
|
init_source();
|
|
@@ -54578,7 +54595,7 @@ function registerAccountAdd(accountParent) {
|
|
|
54578
54595
|
accountParent.command("add <account>").description("Mint a Google OAuth refresh token for <account> and register it with the auth-broker. For Drive scopes the effective flow is desktop-loopback (device-code returns invalid_scope for Drive; OOB is retired) \u2014 use a Desktop OAuth client; on a headless host complete the browser step over an SSH port-forward. Add --write for create/edit (drive.file); default is read-only.").option("--replace", "Overwrite existing credentials for <account> (default refuses if account already registered)", false).option("--write", "Request Drive WRITE scope (drive.file: create + edit app-created files) in addition to read. Default is read-only \u2014 a read grant never silently becomes a write grant. Re-consent an existing account with `--replace --write`.", false).action(withConfigError(async (account, opts) => {
|
|
54579
54596
|
const normalizedAccount = validateAndNormalizeAccountEmail(account);
|
|
54580
54597
|
const [
|
|
54581
|
-
{ runDriveOAuthFlow: runDriveOAuthFlow2,
|
|
54598
|
+
{ runDriveOAuthFlow: runDriveOAuthFlow2, selectGoogleWorkspaceScopes: selectGoogleWorkspaceScopes2 },
|
|
54582
54599
|
{ selectInitialTier: selectInitialTier2 },
|
|
54583
54600
|
{ brokerCall: brokerCall2 },
|
|
54584
54601
|
{ loadConfig: loadConfig2, resolvePath: resolvePath2 },
|
|
@@ -54647,7 +54664,11 @@ function registerAccountAdd(accountParent) {
|
|
|
54647
54664
|
clientIdRaw = await resolveRef(clientIdRaw, "google_client_id");
|
|
54648
54665
|
clientSecretRaw = await resolveRef(clientSecretRaw, "google_client_secret");
|
|
54649
54666
|
}
|
|
54650
|
-
const
|
|
54667
|
+
const tier = gw.tier ?? "core";
|
|
54668
|
+
const accountScopes = selectGoogleWorkspaceScopes2({
|
|
54669
|
+
write: opts.write ?? false,
|
|
54670
|
+
tier
|
|
54671
|
+
});
|
|
54651
54672
|
const oauthCfg = {
|
|
54652
54673
|
client_id: clientIdRaw,
|
|
54653
54674
|
client_secret: clientSecretRaw,
|
|
@@ -54656,6 +54677,9 @@ function registerAccountAdd(accountParent) {
|
|
|
54656
54677
|
if (opts.write) {
|
|
54657
54678
|
console.log(source_default.yellow(" Requesting Drive WRITE scope (drive.file \u2014 create/edit app-created files)."));
|
|
54658
54679
|
}
|
|
54680
|
+
console.log(source_default.gray(` Workspace tier: ${tier} \u2014 requesting Docs + Sheets` + (tier === "extended" || tier === "complete" ? " + Slides" : "") + " API scopes so the tier's tools can authenticate."));
|
|
54681
|
+
console.log(source_default.gray(` Changing the tier later requires re-running this command
|
|
54682
|
+
` + " (`--replace`) \u2014 OAuth scopes are fixed at consent time."));
|
|
54659
54683
|
const oauthEnv = {
|
|
54660
54684
|
DISPLAY: process.env.DISPLAY,
|
|
54661
54685
|
WAYLAND_DISPLAY: process.env.WAYLAND_DISPLAY,
|
|
@@ -73048,6 +73072,29 @@ function buildSeedCredentials(input) {
|
|
|
73048
73072
|
}
|
|
73049
73073
|
var AIOFILE_PIN = "aiofile==3.10.2";
|
|
73050
73074
|
var AIOFILE_PKG = AIOFILE_PIN.split("==")[0];
|
|
73075
|
+
function requiredWorkspaceScopesForTier(tier) {
|
|
73076
|
+
const docs = [
|
|
73077
|
+
"https://www.googleapis.com/auth/documents",
|
|
73078
|
+
"https://www.googleapis.com/auth/spreadsheets"
|
|
73079
|
+
];
|
|
73080
|
+
if (tier === "extended" || tier === "complete") {
|
|
73081
|
+
return [...docs, "https://www.googleapis.com/auth/presentations"];
|
|
73082
|
+
}
|
|
73083
|
+
return docs;
|
|
73084
|
+
}
|
|
73085
|
+
function findMissingWorkspaceScopes(seedScope, tier) {
|
|
73086
|
+
const have = new Set(seedScope.split(/\s+/).map((s) => s.trim()).filter((s) => s.length > 0));
|
|
73087
|
+
return requiredWorkspaceScopesForTier(tier).filter((s) => !have.has(s));
|
|
73088
|
+
}
|
|
73089
|
+
var DRIVE_FILE_SCOPE = "https://www.googleapis.com/auth/drive.file";
|
|
73090
|
+
function buildMissingScopeWarning(missing, tier, accountEmail, hasWriteScope) {
|
|
73091
|
+
const short = missing.map((s) => s.replace(/^https:\/\/www\.googleapis\.com\/auth\//, "")).join(", ");
|
|
73092
|
+
return `drive-mcp-launcher: WARNING \u2014 the Google account '${accountEmail}' was ` + `consented WITHOUT the scope(s) needed for tier '${tier ?? "core"}': ` + `${short}.
|
|
73093
|
+
` + ` The matching MCP tools (Docs / Sheets / Slides create+edit) will FAIL ` + `to authenticate. OAuth scopes are fixed at consent time \u2014 re-run on the ` + `host to re-mint the token with the correct scopes:
|
|
73094
|
+
` + ` switchroom auth google account add ${accountEmail} --replace` + `${hasWriteScope ? " --write" : ""}
|
|
73095
|
+
` + ` (scopes are derived from \`google_workspace.tier\` \u2014 set the tier ` + `before re-running${hasWriteScope ? "; --write preserves the existing " + "Drive write capability" : ""}). Drive read/file tools are unaffected.
|
|
73096
|
+
`;
|
|
73097
|
+
}
|
|
73051
73098
|
function buildUvxArgs(tier) {
|
|
73052
73099
|
const args = [
|
|
73053
73100
|
"--from",
|
|
@@ -73072,6 +73119,9 @@ function buildChildEnv(baseEnv, credentialsDir, accountEmail) {
|
|
|
73072
73119
|
delete env2.WORKSPACE_MCP_STATELESS_MODE;
|
|
73073
73120
|
delete env2.GOOGLE_APPLICATION_CREDENTIALS;
|
|
73074
73121
|
delete env2.WORKSPACE_MCP_SERVICE_ACCOUNT_FILE;
|
|
73122
|
+
if (!env2.WORKSPACE_MCP_PORT) {
|
|
73123
|
+
env2.WORKSPACE_MCP_PORT = env2.SWITCHROOM_GDRIVE_MCP_PORT ?? "8631";
|
|
73124
|
+
}
|
|
73075
73125
|
return env2;
|
|
73076
73126
|
}
|
|
73077
73127
|
function classifyRootSchema(schema) {
|
|
@@ -73288,6 +73338,11 @@ async function runDriveMcpLauncher(opts) {
|
|
|
73288
73338
|
process.exit(1);
|
|
73289
73339
|
}
|
|
73290
73340
|
const tier = opts.tier ?? configSecrets.tier;
|
|
73341
|
+
const missingScopes = findMissingWorkspaceScopes(brokerCreds.scope, tier);
|
|
73342
|
+
if (missingScopes.length > 0) {
|
|
73343
|
+
const hasWriteScope = brokerCreds.scope.split(/\s+/).map((s) => s.trim()).includes(DRIVE_FILE_SCOPE);
|
|
73344
|
+
process.stderr.write(buildMissingScopeWarning(missingScopes, tier, brokerCreds.accountEmail, hasWriteScope));
|
|
73345
|
+
}
|
|
73291
73346
|
const args = buildUvxArgs(tier);
|
|
73292
73347
|
const env2 = buildChildEnv(process.env, credentialsDir, brokerCreds.accountEmail);
|
|
73293
73348
|
const { spawn: spawn5 } = await import("node:child_process");
|
package/package.json
CHANGED