@route_33/opencode 0.4.7-rc.7 → 0.4.7-rc.9

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.
@@ -1,6 +1,70 @@
1
1
  // src/v2-entry/create-route33-v2-plugin/create-route33-v2-plugin.ts
2
2
  import { Integration as Integration2, Plugin } from "@opencode/plugin";
3
3
 
4
+ // src/auth/open-system-browser/open-system-browser.ts
5
+ import { spawn } from "node:child_process";
6
+ var openSystemBrowser = async (url, options = {}) => new Promise((resolve2, reject) => {
7
+ let command = "xdg-open";
8
+ let args = [url.href];
9
+ if (process.platform === "darwin") {
10
+ command = "open";
11
+ } else if (process.platform === "win32") {
12
+ command = "cmd";
13
+ args = ["/c", "start", "", url.href];
14
+ }
15
+ if (options.spawnUrl !== void 0) {
16
+ options.spawnUrl(command, args, { detached: true, stdio: "ignore" });
17
+ resolve2();
18
+ return;
19
+ }
20
+ const child = spawn(command, args, {
21
+ detached: true,
22
+ stdio: "ignore"
23
+ });
24
+ child.once("error", reject);
25
+ child.once("spawn", () => {
26
+ child.unref();
27
+ resolve2();
28
+ });
29
+ });
30
+
31
+ // src/auth/authorization-url-stash/authorization-url-stash.ts
32
+ var FALLBACK_URL = "https://route33.ai";
33
+ var SIGN_IN_INSTRUCTIONS = "Open the Route 33 sign-in link \u2014 your browser will finish at a confirmation page.";
34
+ var FINISHING_INSTRUCTIONS = "Finishing Route 33 setup\u2026";
35
+ var URL_WAIT_BUDGET_MS = 3e4;
36
+ var createAuthorizationUrlStash = (options = {}) => {
37
+ const open = options.open ?? ((url) => openSystemBrowser(url));
38
+ const waitBudgetMs = options.waitBudgetMs ?? URL_WAIT_BUDGET_MS;
39
+ let resolveUrl;
40
+ const nextUrl = new Promise((resolve2) => {
41
+ resolveUrl = resolve2;
42
+ });
43
+ const browserRunner = (url) => {
44
+ resolveUrl?.(url);
45
+ return open(url);
46
+ };
47
+ const urlForConnect = async (callback) => {
48
+ let decide;
49
+ const decided = new Promise((resolve2) => {
50
+ decide = resolve2;
51
+ });
52
+ const timer = setTimeout(() => {
53
+ decide({ instructions: SIGN_IN_INSTRUCTIONS, url: FALLBACK_URL });
54
+ }, waitBudgetMs);
55
+ void nextUrl.then((url) => {
56
+ clearTimeout(timer);
57
+ decide({ instructions: SIGN_IN_INSTRUCTIONS, url: url.toString() });
58
+ });
59
+ void Promise.resolve(callback).catch(() => void 0).then(() => {
60
+ clearTimeout(timer);
61
+ decide({ instructions: FINISHING_INSTRUCTIONS, url: FALLBACK_URL });
62
+ });
63
+ return decided;
64
+ };
65
+ return { browserRunner, urlForConnect };
66
+ };
67
+
4
68
  // src/cli/read-env-base-url/read-env-base-url.ts
5
69
  var readEnvBaseUrl = (env = process.env) => {
6
70
  const value = env["ROUTE33_BASE_URL"]?.trim();
@@ -2733,7 +2797,6 @@ var createAuthSession = (options) => {
2733
2797
  };
2734
2798
 
2735
2799
  // src/auth/open-browser-and-capture/open-browser-and-capture.ts
2736
- import { spawn } from "node:child_process";
2737
2800
  import { timingSafeEqual } from "node:crypto";
2738
2801
 
2739
2802
  // src/auth/loopback-callback/loopback-callback.ts
@@ -2852,25 +2915,7 @@ var createAuthLoopbackCallback = async () => {
2852
2915
  var openBrowserAndCapture = async (options) => {
2853
2916
  const callback = await createAuthLoopbackCallback();
2854
2917
  const authorizationUrl = options.authorizationUrl(callback.redirectUri);
2855
- const browserRunner = options.browserRunner ?? ((url) => new Promise((resolve2, reject) => {
2856
- let command = "xdg-open";
2857
- let args = [url.href];
2858
- if (process.platform === "darwin") {
2859
- command = "open";
2860
- } else if (process.platform === "win32") {
2861
- command = "cmd";
2862
- args = ["/c", "start", "", url.href];
2863
- }
2864
- const child = spawn(command, args, {
2865
- detached: true,
2866
- stdio: "ignore"
2867
- });
2868
- child.once("error", reject);
2869
- child.once("spawn", () => {
2870
- child.unref();
2871
- resolve2();
2872
- });
2873
- }));
2918
+ const browserRunner = options.browserRunner ?? ((url) => openSystemBrowser(url));
2874
2919
  let timer;
2875
2920
  const timeout = new Promise((_resolve, reject) => {
2876
2921
  timer = setTimeout(() => {
@@ -3164,7 +3209,7 @@ var Route33Runtime = class {
3164
3209
  if (typeof client !== "function") {
3165
3210
  return client;
3166
3211
  }
3167
- this.#managementClient ??= client(() => this.#session.credential());
3212
+ this.#managementClient ??= client();
3168
3213
  return this.#managementClient;
3169
3214
  }
3170
3215
  #subject(credential) {
@@ -3754,20 +3799,20 @@ var HttpManagementKeys = class {
3754
3799
 
3755
3800
  // src/lazy-management-keys/lazy-management-keys.ts
3756
3801
  var lazyManagementKeys = (options) => {
3757
- const client = async () => new HttpManagementKeys({
3802
+ const client = (accessToken) => new HttpManagementKeys({
3758
3803
  baseUrl: options.apiBaseUrl,
3759
- credential: await options.obtainCredential(),
3804
+ credential: accessToken,
3760
3805
  ...options.fetchImpl === void 0 ? {} : { fetchImpl: options.fetchImpl }
3761
3806
  });
3762
3807
  return {
3763
- create: async (accessToken, input) => (await client()).create(accessToken, input),
3764
- delete: async (accessToken, id) => (await client()).delete(accessToken, id),
3765
- get: async (accessToken, id) => (await client()).get(accessToken, id),
3766
- list: async (accessToken) => (await client()).list(accessToken),
3767
- listOrganizations: async (accessToken) => (await client()).listOrganizations(accessToken),
3768
- listProjects: async (accessToken, organisationId) => (await client()).listProjects(accessToken, organisationId),
3769
- regenerate: async (accessToken, id, expiresAt) => (await client()).regenerate(accessToken, id, expiresAt),
3770
- update: async (accessToken, id, input) => (await client()).update(accessToken, id, input)
3808
+ create: async (accessToken, input) => client(accessToken).create(accessToken, input),
3809
+ delete: async (accessToken, id) => client(accessToken).delete(accessToken, id),
3810
+ get: async (accessToken, id) => client(accessToken).get(accessToken, id),
3811
+ list: async (accessToken) => client(accessToken).list(accessToken),
3812
+ listOrganizations: async (accessToken) => client(accessToken).listOrganizations(accessToken),
3813
+ listProjects: async (accessToken, organisationId) => client(accessToken).listProjects(accessToken, organisationId),
3814
+ regenerate: async (accessToken, id, expiresAt) => client(accessToken).regenerate(accessToken, id, expiresAt),
3815
+ update: async (accessToken, id, input) => client(accessToken).update(accessToken, id, input)
3771
3816
  };
3772
3817
  };
3773
3818
 
@@ -3783,49 +3828,11 @@ var buildProductionRuntimeOptions = (input) => ({
3783
3828
  timeoutMs: LOGIN_BUDGET_MS
3784
3829
  },
3785
3830
  management: {
3786
- client: (obtainCredential) => lazyManagementKeys({
3787
- apiBaseUrl: input.apiBaseUrl,
3788
- obtainCredential
3789
- })
3831
+ client: () => lazyManagementKeys({ apiBaseUrl: input.apiBaseUrl })
3790
3832
  },
3791
3833
  ...input.tokenStore === void 0 ? {} : { tokenStore: input.tokenStore }
3792
3834
  });
3793
3835
 
3794
- // src/v2-entry/authorization-url-stash/authorization-url-stash.ts
3795
- var FALLBACK_URL = "https://route33.ai";
3796
- var SIGN_IN_INSTRUCTIONS = "Open the Route 33 sign-in link \u2014 your browser will finish at a confirmation page.";
3797
- var FINISHING_INSTRUCTIONS = "Finishing Route 33 setup\u2026";
3798
- var URL_WAIT_BUDGET_MS = 3e4;
3799
- var createAuthorizationUrlStash = () => {
3800
- let resolveUrl;
3801
- const nextUrl = new Promise((resolve2) => {
3802
- resolveUrl = resolve2;
3803
- });
3804
- const browserRunner = (url) => {
3805
- resolveUrl?.(url);
3806
- return Promise.resolve();
3807
- };
3808
- const urlForConnect = async (callback) => {
3809
- let decide;
3810
- const decided = new Promise((resolve2) => {
3811
- decide = resolve2;
3812
- });
3813
- const timer = setTimeout(() => {
3814
- decide({ instructions: SIGN_IN_INSTRUCTIONS, url: FALLBACK_URL });
3815
- }, URL_WAIT_BUDGET_MS);
3816
- void nextUrl.then((url) => {
3817
- clearTimeout(timer);
3818
- decide({ instructions: SIGN_IN_INSTRUCTIONS, url: url.toString() });
3819
- });
3820
- void Promise.resolve(callback).catch(() => void 0).then(() => {
3821
- clearTimeout(timer);
3822
- decide({ instructions: FINISHING_INSTRUCTIONS, url: FALLBACK_URL });
3823
- });
3824
- return decided;
3825
- };
3826
- return { browserRunner, urlForConnect };
3827
- };
3828
-
3829
3836
  // src/v2-entry/connect-copy/connect-copy.ts
3830
3837
  var CONNECT_COPY = {
3831
3838
  failFastClientId: "This Route 33 build has no OAuth client id. Reinstall it from the opencode-dist ref, or set ROUTE33_CLIENT_ID and restart OpenCode.",
@@ -4006,12 +4013,10 @@ var hostTokenStore = (options) => ({
4006
4013
  // src/v2-entry/parse-r33-subcommand/parse-r33-subcommand.ts
4007
4014
  var SUBCOMMANDS = ["inspect", "rotate", "reset"];
4008
4015
  var parseR33Subcommand = (promptText) => {
4009
- const [invocation, argument] = promptText.trim().split(/\s+/u);
4010
- const name = invocation?.replace(/^\/+/u, "").split(":")[0] ?? "";
4011
- if (name !== "r33") {
4012
- return "help";
4013
- }
4014
- if (argument === void 0) {
4016
+ const [first = "", ...rest] = promptText.trim().split(/\s+/u).filter(Boolean);
4017
+ const name = first.replace(/^\/+/u, "").split(":")[0] ?? "";
4018
+ const argument = name === "r33" ? rest[0] : first;
4019
+ if (argument === void 0 || argument === "") {
4015
4020
  return "inspect";
4016
4021
  }
4017
4022
  return SUBCOMMANDS.includes(argument) ? argument : "help";
@@ -4041,6 +4046,20 @@ var executeR33Command = async (input) => {
4041
4046
  }
4042
4047
  };
4043
4048
 
4049
+ // src/v2-entry/v2-unattributed-model-gate/v2-unattributed-model-gate.ts
4050
+ var GATE_COPY = "Route 33 needs a budget for this folder first \u2014 finish the setup dialog in the TUI, or run /connect, choose Route 33, and follow the steps.";
4051
+ var createV2UnattributedModelGate = (deps) => async (input) => {
4052
+ if (input.model.providerID !== "route_33") return;
4053
+ const session = await deps.session.get({ sessionID: input.sessionID });
4054
+ const directory = session?.location.directory ?? deps.fallbackDirectory;
4055
+ const state = {
4056
+ directory,
4057
+ outsideWorktree: "return-undefined"
4058
+ };
4059
+ if (readAttribution(state) !== void 0) return;
4060
+ throw new Error(GATE_COPY);
4061
+ };
4062
+
4044
4063
  // src/v2-entry/workspace-key-request-hook/workspace-key-request-hook.ts
4045
4064
  var createWorkspaceKeyHook = (deps) => async (input) => {
4046
4065
  const target = new URL(input.request.url);
@@ -4191,6 +4210,14 @@ var createRoute33V2Plugin = (options = {}) => {
4191
4210
  session: context.session
4192
4211
  })
4193
4212
  );
4213
+ const modelGate = await context.session.hook(
4214
+ "model.request",
4215
+ createV2UnattributedModelGate({
4216
+ fallbackDirectory: context.location.directory,
4217
+ session: context.session
4218
+ }),
4219
+ { providerID: "route_33" }
4220
+ );
4194
4221
  const bootstrapFromRefresh = async () => {
4195
4222
  if (runtime === void 0) {
4196
4223
  return;
@@ -4223,7 +4250,8 @@ var createRoute33V2Plugin = (options = {}) => {
4223
4250
  commandTransform.dispose(),
4224
4251
  integrationTransform.dispose(),
4225
4252
  providerTransform.dispose(),
4226
- sessionHook.dispose()
4253
+ sessionHook.dispose(),
4254
+ modelGate.dispose()
4227
4255
  ]);
4228
4256
  };
4229
4257
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@route_33/opencode",
3
- "version": "0.4.7-rc.7",
3
+ "version": "0.4.7-rc.9",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,8 +42,8 @@
42
42
  "eslint": "10.13.0",
43
43
  "typescript": "6.0.3",
44
44
  "vitest": "5.0.5",
45
- "@cronos-ai-lab/eslint-config": "0.1.2",
46
- "@cronos-ai-lab/typescript-config": "0.1.2"
45
+ "@cronos-ai-lab/typescript-config": "0.1.2",
46
+ "@cronos-ai-lab/eslint-config": "0.1.2"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "esbuild src/index.ts src/v2-entry/index.ts src/tui-entry/index.ts src/cli/production-smoke/production-smoke.ts --bundle --format=esm --platform=node --packages=external --outbase=src --outdir=dist --alias:@opencode-ai/plugin-v2=@opencode/plugin --define:__ROUTE33_DEFAULT_CLIENT_ID__=\\\"${ROUTE33_DEFAULT_CLIENT_ID:-}\\\"",