@route_33/opencode 0.4.7-rc.3 → 0.4.7-rc.5

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 CHANGED
@@ -1,20 +1,31 @@
1
1
  # @route_33/opencode
2
2
 
3
- The Route 33 plugin for OpenCode: sign in with your browser, pick who pays for
3
+ The Route 33 plugin for OpenCode: sign in with your browser, assign the budget for
4
4
  usage, and use the route_33 models — no API keys to paste, ever.
5
5
 
6
6
  ## Install
7
7
 
8
+ **OpenCode v2 (recommended)** uses the `add` subcommand and installs into
9
+ the global configuration (`~/.config/opencode/opencode.json` + `tui.json`):
10
+
8
11
  ```sh
9
12
  opencode plugin add @route_33/opencode
10
13
  ```
11
14
 
12
- Restart OpenCode afterwards — plugins load at startup.
15
+ **OpenCode v1** installs the package and registers the plugin at the nearest
16
+ definition — the project's `.opencode/opencode.json` (plus the TUI part in
17
+ `tui.json`) when run inside a project, the global config with `--global`:
18
+
19
+ ```sh
20
+ opencode plugin @route_33/opencode # project scope
21
+ opencode plugin @route_33/opencode --global # global scope
22
+ ```
13
23
 
14
- Prefer config? Add the package to `opencode.jsonc` instead:
24
+ Either way, restart OpenCode afterwards — plugins load at startup. Prefer
25
+ config? Declare the plugin directly in `opencode.json(c)`:
15
26
 
16
27
  ```jsonc
17
- { "plugins": ["@route_33/opencode"] }
28
+ { "plugin": ["@route_33/opencode"] }
18
29
  ```
19
30
 
20
31
  ## First run
@@ -22,20 +33,20 @@ Prefer config? Add the package to `opencode.jsonc` instead:
22
33
  1. Pick any route_33 model (or run `/connect` and choose **Route 33**).
23
34
  2. Open the sign-in link — your browser finishes at a Route 33 confirmation
24
35
  page.
25
- 3. Connect again and pick **who pays for usage in this folder**: one of your
36
+ 3. Connect again and assign **which budget covers usage in this folder**: one of your
26
37
  Route 33 projects, or your personal key.
27
38
  4. The route_33 models appear. Done.
28
39
 
29
- To change who pays later, connect again and pick another option. `/r33` shows
40
+ To change the budget later, connect again and pick another option. `/r33` shows
30
41
  the current state at any time.
31
42
 
32
43
  ## Commands
33
44
 
34
- | Command | Effect |
35
- | ------------- | --------------------------------------------------------- |
36
- | `/r33` | Show who pays, the active key, and its rotation state |
37
- | `/r33 rotate` | Rotate the key immediately |
38
- | `/r33 reset` | Clear who pays — connect again to pick a different option |
45
+ | Command | Effect |
46
+ | ------------- | -------------------------------------------------------------------- |
47
+ | `/r33` | Show the assigned budget, the active key, and its rotation state |
48
+ | `/r33 rotate` | Rotate the key immediately |
49
+ | `/r33 reset` | Clear the assigned budget — connect again to pick a different option |
39
50
 
40
51
  A browser is required for every sign-in; restarts afterwards sign in silently.
41
52
 
@@ -260,7 +260,7 @@ var buildCallbackPage = (state, errorCode) => {
260
260
  const safeCode = (errorCode ?? "").replace(/[^a-z0-9_-]/gi, "");
261
261
  const title = isError ? "Sign-in failed" : "Signed in";
262
262
  const headline = isError ? "Sign-in failed" : "Signed in to route33";
263
- const subline = isError ? "Return to OpenCode and retry." : "Return to OpenCode \u2014 one more step may wait there: if it asks who pays for usage, pick a project. Then this window can be closed.";
263
+ const subline = isError ? "Return to OpenCode and retry." : "Return to OpenCode \u2014 one more step may wait there: if it asks which budget covers usage, pick a project. Then this window can be closed.";
264
264
  const statusLabel = isError ? "Authentication error" : "Authenticated";
265
265
  const dotClass = isError ? "r33-status__dot r33-status__dot--error" : "r33-status__dot";
266
266
  const codeLine = isError && safeCode.length > 0 ? `<p class="r33-code">Error code: <span class="r33-code__value">${safeCode}</span></p>` : "";
package/dist/index.js CHANGED
@@ -2546,7 +2546,7 @@ var createAttributionPrompt = (projects) => {
2546
2546
 
2547
2547
  // src/ux/attribution-prompt-error/attribution-prompt-error.ts
2548
2548
  var MESSAGES = {
2549
- ATTRIBUTION_PRESENTER_UNAVAILABLE: "Route 33 needs OpenCode v2 to choose who pays for usage in this folder. Update to OpenCode v2, run /connect, choose Route 33, and follow the steps.",
2549
+ ATTRIBUTION_PRESENTER_UNAVAILABLE: "Route 33 needs OpenCode v2 to assign a budget for this folder. Update to OpenCode v2, run /connect, choose Route 33, and follow the steps.",
2550
2550
  ATTRIBUTION_SELECTION_INVALID: "That Route 33 option is no longer available. Connect again and pick another."
2551
2551
  };
2552
2552
  var AttributionPromptError = class extends GatewayCredentialError {
@@ -2762,7 +2762,7 @@ var buildCallbackPage = (state, errorCode) => {
2762
2762
  const safeCode = (errorCode ?? "").replace(/[^a-z0-9_-]/gi, "");
2763
2763
  const title = isError ? "Sign-in failed" : "Signed in";
2764
2764
  const headline = isError ? "Sign-in failed" : "Signed in to route33";
2765
- const subline = isError ? "Return to OpenCode and retry." : "Return to OpenCode \u2014 one more step may wait there: if it asks who pays for usage, pick a project. Then this window can be closed.";
2765
+ const subline = isError ? "Return to OpenCode and retry." : "Return to OpenCode \u2014 one more step may wait there: if it asks which budget covers usage, pick a project. Then this window can be closed.";
2766
2766
  const statusLabel = isError ? "Authentication error" : "Authenticated";
2767
2767
  const dotClass = isError ? "r33-status__dot r33-status__dot--error" : "r33-status__dot";
2768
2768
  const codeLine = isError && safeCode.length > 0 ? `<p class="r33-code">Error code: <span class="r33-code__value">${safeCode}</span></p>` : "";
@@ -1242,7 +1242,7 @@ html,body{margin:0}
1242
1242
  const safeCode = (errorCode ?? "").replace(/[^a-z0-9_-]/gi, "");
1243
1243
  const title = isError ? "Sign-in failed" : "Signed in";
1244
1244
  const headline = isError ? "Sign-in failed" : "Signed in to route33";
1245
- const subline = isError ? "Return to OpenCode and retry." : "Return to OpenCode \u2014 one more step may wait there: if it asks who pays for usage, pick a project. Then this window can be closed.";
1245
+ const subline = isError ? "Return to OpenCode and retry." : "Return to OpenCode \u2014 one more step may wait there: if it asks which budget covers usage, pick a project. Then this window can be closed.";
1246
1246
  const statusLabel = isError ? "Authentication error" : "Authenticated";
1247
1247
  const dotClass = isError ? "r33-status__dot r33-status__dot--error" : "r33-status__dot";
1248
1248
  const codeLine = isError && safeCode.length > 0 ? `<p class="r33-code">Error code: <span class="r33-code__value">${safeCode}</span></p>` : "";
@@ -5811,7 +5811,7 @@ var init_attribution_prompt_error = __esm({
5811
5811
  "use strict";
5812
5812
  init_config();
5813
5813
  MESSAGES = {
5814
- ATTRIBUTION_PRESENTER_UNAVAILABLE: "Route 33 needs OpenCode v2 to choose who pays for usage in this folder. Update to OpenCode v2, run /connect, choose Route 33, and follow the steps.",
5814
+ ATTRIBUTION_PRESENTER_UNAVAILABLE: "Route 33 needs OpenCode v2 to assign a budget for this folder. Update to OpenCode v2, run /connect, choose Route 33, and follow the steps.",
5815
5815
  ATTRIBUTION_SELECTION_INVALID: "That Route 33 option is no longer available. Connect again and pick another."
5816
5816
  };
5817
5817
  AttributionPromptError = class extends GatewayCredentialError {
@@ -6793,12 +6793,8 @@ var productionOptions = () => {
6793
6793
  };
6794
6794
  };
6795
6795
 
6796
- // src/tui-entry/run-connect/run-connect.ts
6797
- init_attribution();
6798
- init_config();
6799
-
6800
- // src/tui-entry/dialog-confirm/dialog-confirm.ts
6801
- var confirmFromDialog = (api, input) => new Promise((resolve2) => {
6796
+ // src/tui-entry/dialog-select/dialog-select.ts
6797
+ var selectFromDialog = async (api, input) => new Promise((resolve2) => {
6802
6798
  let settled = false;
6803
6799
  const settle = (value) => {
6804
6800
  if (settled) {
@@ -6810,14 +6806,12 @@ var confirmFromDialog = (api, input) => new Promise((resolve2) => {
6810
6806
  };
6811
6807
  const dialog = api.ui.dialog;
6812
6808
  dialog.replace(
6813
- () => api.ui.DialogConfirm({
6814
- message: input.message,
6815
- onCancel: () => {
6816
- settle(false);
6817
- },
6818
- onConfirm: () => {
6819
- settle(true);
6809
+ () => api.ui.DialogSelect({
6810
+ current: input.current,
6811
+ onSelect: (option) => {
6812
+ settle(option.value);
6820
6813
  },
6814
+ options: input.options,
6821
6815
  title: input.title
6822
6816
  }),
6823
6817
  () => {
@@ -6826,8 +6820,70 @@ var confirmFromDialog = (api, input) => new Promise((resolve2) => {
6826
6820
  );
6827
6821
  });
6828
6822
 
6829
- // src/tui-entry/dialog-select/dialog-select.ts
6830
- var selectFromDialog = async (api, input) => new Promise((resolve2) => {
6823
+ // src/tui-entry/r33-command-reply/r33-command-reply.ts
6824
+ init_create_route33_plugin2();
6825
+
6826
+ // src/v2-entry/parse-r33-subcommand/parse-r33-subcommand.ts
6827
+ var SUBCOMMANDS = ["inspect", "rotate", "reset"];
6828
+ var parseR33Subcommand = (promptText) => {
6829
+ const [invocation, argument] = promptText.trim().split(/\s+/u);
6830
+ const name = invocation?.replace(/^\/+/u, "").split(":")[0] ?? "";
6831
+ if (name !== "r33") {
6832
+ return "help";
6833
+ }
6834
+ if (argument === void 0) {
6835
+ return "inspect";
6836
+ }
6837
+ return SUBCOMMANDS.includes(argument) ? argument : "help";
6838
+ };
6839
+
6840
+ // src/v2-entry/r33-command/r33-command.ts
6841
+ var executeR33Command = async (input) => {
6842
+ const subcommand = parseR33Subcommand(input.promptText);
6843
+ if (input.handlers === void 0) {
6844
+ return "Route 33 is not connected in this folder. Run /connect, choose Route 33, and follow the steps.";
6845
+ }
6846
+ if (subcommand === "help") {
6847
+ return "Route 33 usage: /r33 [inspect|rotate|reset] \u2014 inspect shows attribution and key rotation, rotate rotates the key now, reset clears the assigned budget (assign again with /connect).";
6848
+ }
6849
+ switch (subcommand) {
6850
+ case "rotate": {
6851
+ const lease = await input.handlers["rotate-now"]();
6852
+ return `Route 33 key rotated. Key ${lease.keyId} is valid until ${lease.expiresAt}.`;
6853
+ }
6854
+ case "reset": {
6855
+ await input.handlers["reset-attribution"]();
6856
+ return "Route 33 attribution cleared. Run /connect, choose Route 33, and assign a budget again.";
6857
+ }
6858
+ default: {
6859
+ return JSON.stringify(input.handlers["inspect-session"](), null, 2);
6860
+ }
6861
+ }
6862
+ };
6863
+
6864
+ // src/tui-entry/r33-command-reply/r33-command-reply.ts
6865
+ var r33CommandReply = (deps) => async (subcommand) => {
6866
+ let runtime;
6867
+ const entry = createRoute33Plugin({
6868
+ ...deps.composeOptions(),
6869
+ bindRuntime: (instance) => {
6870
+ runtime = instance;
6871
+ }
6872
+ });
6873
+ await entry({ worktree: deps.api.state.path.directory });
6874
+ const handlers = runtime?.commandHandlers();
6875
+ return executeR33Command({
6876
+ handlers,
6877
+ promptText: `/r33 ${subcommand}`
6878
+ });
6879
+ };
6880
+
6881
+ // src/tui-entry/run-connect/run-connect.ts
6882
+ init_attribution();
6883
+ init_config();
6884
+
6885
+ // src/tui-entry/dialog-confirm/dialog-confirm.ts
6886
+ var confirmFromDialog = (api, input) => new Promise((resolve2) => {
6831
6887
  let settled = false;
6832
6888
  const settle = (value) => {
6833
6889
  if (settled) {
@@ -6839,12 +6895,14 @@ var selectFromDialog = async (api, input) => new Promise((resolve2) => {
6839
6895
  };
6840
6896
  const dialog = api.ui.dialog;
6841
6897
  dialog.replace(
6842
- () => api.ui.DialogSelect({
6843
- current: input.current,
6844
- onSelect: (option) => {
6845
- settle(option.value);
6898
+ () => api.ui.DialogConfirm({
6899
+ message: input.message,
6900
+ onCancel: () => {
6901
+ settle(false);
6902
+ },
6903
+ onConfirm: () => {
6904
+ settle(true);
6846
6905
  },
6847
- options: input.options,
6848
6906
  title: input.title
6849
6907
  }),
6850
6908
  () => {
@@ -6870,7 +6928,7 @@ var runConnect = async (api, composeOptions) => {
6870
6928
  }
6871
6929
  if (readAttribution(state) !== void 0) {
6872
6930
  const change = await confirmFromDialog(api, {
6873
- message: "Change who pays for usage in this folder?",
6931
+ message: "Change the budget assigned to this folder?",
6874
6932
  title: "Route 33"
6875
6933
  });
6876
6934
  if (change !== true) {
@@ -6925,6 +6983,45 @@ var runConnect = async (api, composeOptions) => {
6925
6983
  }
6926
6984
  };
6927
6985
 
6986
+ // src/tui-entry/r33-menu-actions/r33-menu-actions.ts
6987
+ var r33MenuActions = (deps) => async (selection) => {
6988
+ if (selection === "connect" || selection === "change") {
6989
+ await runConnect(deps.api, deps.composeOptions);
6990
+ return;
6991
+ }
6992
+ try {
6993
+ const reply = await r33CommandReply(deps)(selection);
6994
+ deps.api.ui.toast({
6995
+ message: reply,
6996
+ title: "Route 33",
6997
+ variant: "info"
6998
+ });
6999
+ } catch (error) {
7000
+ deps.api.ui.toast({
7001
+ message: error instanceof Error ? error.message : String(error),
7002
+ title: "Route 33",
7003
+ variant: "error"
7004
+ });
7005
+ }
7006
+ };
7007
+
7008
+ // src/tui-entry/r33-menu/r33-menu.ts
7009
+ var menuOptions = [
7010
+ { title: "Connect \u2014 sign in and assign a budget", value: "connect" },
7011
+ { title: "Inspect session \u2014 attribution and key metadata", value: "inspect" },
7012
+ { title: "Rotate key now", value: "rotate" },
7013
+ { title: "Change budget \u2014 reassign this folder", value: "change" },
7014
+ { title: "Reset attribution \u2014 clear the assigned budget", value: "reset" }
7015
+ ];
7016
+ var r33Menu = async (api, composeOptions) => {
7017
+ const selection = await selectFromDialog(api, {
7018
+ options: menuOptions,
7019
+ title: "Route 33 \u2014 choose an action"
7020
+ });
7021
+ if (selection === void 0) return;
7022
+ await r33MenuActions({ api, composeOptions })(selection);
7023
+ };
7024
+
6928
7025
  // src/tui-entry/v1-connect-wizard/v1-connect-wizard.ts
6929
7026
  var createV1ConnectWizard = (composeOptions = productionOptions) => (api) => {
6930
7027
  if (readEnvDirectApiKey() !== void 0 || readEnvAutoconnectDisabled()) {
@@ -6941,46 +7038,123 @@ var createV1ConnectWizard = (composeOptions = productionOptions) => (api) => {
6941
7038
  const legacyCommands = api.command;
6942
7039
  legacyCommands?.register(() => [
6943
7040
  {
6944
- onSelect: () => runConnect(api, composeOptions),
7041
+ onSelect: () => void r33Menu(api, composeOptions),
6945
7042
  slash: { name: "r33" },
6946
- title: "Route 33: sign in and pick who pays for this folder",
6947
- value: "route33.connect"
7043
+ title: "Route 33: status, budget, and key management",
7044
+ value: "route33.menu"
6948
7045
  }
6949
7046
  ]);
6950
7047
  return Promise.resolve();
6951
7048
  };
6952
7049
 
6953
- // src/tui-entry/v2-autoconnect/v2-autoconnect.ts
6954
- init_attribution();
6955
- init_cli();
6956
- var v2Autoconnect = async (context) => {
6957
- if (readEnvDirectApiKey() !== void 0 || readEnvAutoconnectDisabled() || context.location === void 0) {
6958
- return;
6959
- }
6960
- const oauth = context.client?.api?.integration?.oauth;
6961
- if (oauth === void 0 || oauth.connect === void 0) return;
6962
- const attribution = readAttribution({
6963
- directory: context.location.directory,
6964
- outsideWorktree: "return-undefined"
7050
+ // src/tui-entry/show-r33-menu/show-r33-menu.ts
7051
+ var menuOptions2 = [
7052
+ {
7053
+ title: "Connect \u2014 sign in and assign a budget",
7054
+ value: "connect"
7055
+ },
7056
+ {
7057
+ title: "Inspect session \u2014 attribution and key metadata",
7058
+ value: "inspect"
7059
+ },
7060
+ {
7061
+ title: "Rotate key now",
7062
+ value: "rotate"
7063
+ },
7064
+ {
7065
+ title: "Change budget \u2014 reassign this folder",
7066
+ value: "change"
7067
+ },
7068
+ {
7069
+ title: "Reset attribution \u2014 clear the assigned budget",
7070
+ value: "reset"
7071
+ }
7072
+ ];
7073
+ var showR33Menu = async (context) => {
7074
+ const selection = await context.ui.dialog.select({
7075
+ title: "Route 33 \u2014 choose an action",
7076
+ options: menuOptions2
6965
7077
  });
6966
- if (attribution !== void 0) {
7078
+ if (selection === void 0) return;
7079
+ if (selection === "connect") {
7080
+ context.ui.toast.show({
7081
+ message: "Route 33 connect \u2014 finish the browser sign-in, then run /connect in OpenCode and choose Route 33 to assign a budget.",
7082
+ variant: "info"
7083
+ });
6967
7084
  return;
6968
7085
  }
6969
7086
  context.ui.toast.show({
6970
- message: "Route 33 is not connected \u2014 signing in now. Follow the browser prompt, then run /connect to pick who pays.",
7087
+ message: `Route 33 ${selection} runs through /r33 ${selection} \u2014 type it in the prompt and send.`,
6971
7088
  variant: "info"
6972
7089
  });
6973
- await oauth.connect({
6974
- integrationID: "route33",
6975
- methodID: "browser"
6976
- }).catch(() => void 0);
6977
7090
  };
6978
7091
 
6979
- // src/tui-entry/index.ts
6980
- var route33V2Tui = {
6981
- id: "route33",
6982
- setup: (context) => v2Autoconnect(context)
7092
+ // src/tui-entry/v2-autoconnect/v2-autoconnect.ts
7093
+ init_attribution();
7094
+ init_cli();
7095
+
7096
+ // src/tui-entry/v2-connect-runner/v2-connect-runner.ts
7097
+ var createV2ConnectRunner = ({
7098
+ context,
7099
+ unattributed
7100
+ }) => {
7101
+ const oauth = context.client?.api?.integration?.oauth;
7102
+ return async (message) => {
7103
+ const connect = oauth?.connect;
7104
+ if (connect === void 0) return;
7105
+ if (!unattributed()) return;
7106
+ context.ui.toast.show({ message, variant: "info" });
7107
+ await connect({
7108
+ integrationID: "route33",
7109
+ methodID: "browser"
7110
+ }).catch(() => void 0);
7111
+ };
6983
7112
  };
7113
+
7114
+ // src/tui-entry/v2-autoconnect/v2-autoconnect.ts
7115
+ var v2Autoconnect = async (context) => {
7116
+ if (readEnvDirectApiKey() !== void 0) return;
7117
+ if (readEnvAutoconnectDisabled()) return;
7118
+ const location = context.location;
7119
+ if (location === void 0) return;
7120
+ const unattributed = () => readAttribution({
7121
+ directory: location.directory,
7122
+ outsideWorktree: "return-undefined"
7123
+ }) === void 0;
7124
+ const connectPass = createV2ConnectRunner({ context, unattributed });
7125
+ await connectPass(
7126
+ "Route 33 is not connected \u2014 signing in now, then pick the budget for this folder."
7127
+ );
7128
+ await connectPass("Signed in to Route 33 \u2014 opening the budget picker.");
7129
+ };
7130
+
7131
+ // src/tui-entry/v2-tui/v2-tui.ts
7132
+ var createV2Tui = () => ({
7133
+ id: "route33",
7134
+ setup: async (context) => {
7135
+ await v2Autoconnect(context);
7136
+ context.keymap?.layer(() => ({
7137
+ mode: "global",
7138
+ priority: 10,
7139
+ commands: [
7140
+ {
7141
+ id: "route33.menu",
7142
+ title: "Route 33: menu",
7143
+ group: "Route 33",
7144
+ slash: { name: "r33", arguments: true },
7145
+ enabled: () => true,
7146
+ run: async () => {
7147
+ await showR33Menu(context);
7148
+ }
7149
+ }
7150
+ ],
7151
+ bindings: ["route33.menu"]
7152
+ }));
7153
+ }
7154
+ });
7155
+
7156
+ // src/tui-entry/index.ts
7157
+ var route33V2Tui = createV2Tui();
6984
7158
  var tui = createV1ConnectWizard();
6985
7159
  var tui_entry_default = route33V2Tui;
6986
7160
  export {
@@ -2549,7 +2549,7 @@ var createAttributionPrompt = (projects) => {
2549
2549
 
2550
2550
  // src/ux/attribution-prompt-error/attribution-prompt-error.ts
2551
2551
  var MESSAGES = {
2552
- ATTRIBUTION_PRESENTER_UNAVAILABLE: "Route 33 needs OpenCode v2 to choose who pays for usage in this folder. Update to OpenCode v2, run /connect, choose Route 33, and follow the steps.",
2552
+ ATTRIBUTION_PRESENTER_UNAVAILABLE: "Route 33 needs OpenCode v2 to assign a budget for this folder. Update to OpenCode v2, run /connect, choose Route 33, and follow the steps.",
2553
2553
  ATTRIBUTION_SELECTION_INVALID: "That Route 33 option is no longer available. Connect again and pick another."
2554
2554
  };
2555
2555
  var AttributionPromptError = class extends GatewayCredentialError {
@@ -2765,7 +2765,7 @@ var buildCallbackPage = (state, errorCode) => {
2765
2765
  const safeCode = (errorCode ?? "").replace(/[^a-z0-9_-]/gi, "");
2766
2766
  const title = isError ? "Sign-in failed" : "Signed in";
2767
2767
  const headline = isError ? "Sign-in failed" : "Signed in to route33";
2768
- const subline = isError ? "Return to OpenCode and retry." : "Return to OpenCode \u2014 one more step may wait there: if it asks who pays for usage, pick a project. Then this window can be closed.";
2768
+ const subline = isError ? "Return to OpenCode and retry." : "Return to OpenCode \u2014 one more step may wait there: if it asks which budget covers usage, pick a project. Then this window can be closed.";
2769
2769
  const statusLabel = isError ? "Authentication error" : "Authenticated";
2770
2770
  const dotClass = isError ? "r33-status__dot r33-status__dot--error" : "r33-status__dot";
2771
2771
  const codeLine = isError && safeCode.length > 0 ? `<p class="r33-code">Error code: <span class="r33-code__value">${safeCode}</span></p>` : "";
@@ -3794,7 +3794,7 @@ var CONNECT_COPY = {
3794
3794
  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.",
3795
3795
  failFastWorktree: "Route 33 attributes usage to a project inside a Git worktree. Open a Git repository (or run git init), then connect again.",
3796
3796
  selectionInvalid: "That Route 33 option is no longer available. Connect again and pick another.",
3797
- signedInNextStep: "Signed in to Route 33 \u2713. One more step: connect again, choose Route 33, and pick who pays for usage in this folder."
3797
+ signedInNextStep: "Signed in to Route 33 \u2713. One more step: connect again, choose Route 33, and assign a budget for this folder."
3798
3798
  };
3799
3799
 
3800
3800
  // src/v2-entry/parse-connect-answer/parse-connect-answer.ts
@@ -3870,7 +3870,7 @@ var buildConnectForm = (plan) => ({
3870
3870
  value: option.selection
3871
3871
  })),
3872
3872
  required: true,
3873
- title: "Who pays for Route 33 usage in this folder?",
3873
+ title: "Which budget covers Route 33 usage in this folder?",
3874
3874
  type: "string"
3875
3875
  });
3876
3876
 
@@ -3987,7 +3987,7 @@ var executeR33Command = async (input) => {
3987
3987
  return "Route 33 is not connected in this folder. Run /connect, choose Route 33, and follow the steps.";
3988
3988
  }
3989
3989
  if (subcommand === "help") {
3990
- return "Route 33 usage: /r33 [inspect|rotate|reset] \u2014 inspect shows attribution and key rotation, rotate rotates the key now, reset clears who pays (pick again with /connect).";
3990
+ return "Route 33 usage: /r33 [inspect|rotate|reset] \u2014 inspect shows attribution and key rotation, rotate rotates the key now, reset clears the assigned budget (assign again with /connect).";
3991
3991
  }
3992
3992
  switch (subcommand) {
3993
3993
  case "rotate": {
@@ -3996,7 +3996,7 @@ var executeR33Command = async (input) => {
3996
3996
  }
3997
3997
  case "reset": {
3998
3998
  await input.handlers["reset-attribution"]();
3999
- return "Route 33 attribution cleared. Run /connect, choose Route 33, and pick who pays again.";
3999
+ return "Route 33 attribution cleared. Run /connect, choose Route 33, and assign a budget again.";
4000
4000
  }
4001
4001
  default: {
4002
4002
  return JSON.stringify(input.handlers["inspect-session"](), null, 2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@route_33/opencode",
3
- "version": "0.4.7-rc.3",
3
+ "version": "0.4.7-rc.5",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",