@route_33/opencode 0.4.7-rc.4 → 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 +14 -3
- package/dist/tui-entry/index.js +154 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,16 +5,27 @@ 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
|
-
|
|
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
|
-
|
|
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
|
-
{ "
|
|
28
|
+
{ "plugin": ["@route_33/opencode"] }
|
|
18
29
|
```
|
|
19
30
|
|
|
20
31
|
## First run
|
package/dist/tui-entry/index.js
CHANGED
|
@@ -6793,12 +6793,8 @@ var productionOptions = () => {
|
|
|
6793
6793
|
};
|
|
6794
6794
|
};
|
|
6795
6795
|
|
|
6796
|
-
// src/tui-entry/
|
|
6797
|
-
|
|
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.
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
settle(
|
|
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/
|
|
6830
|
-
|
|
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.
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
settle(
|
|
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
|
() => {
|
|
@@ -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,17 +7038,17 @@ var createV1ConnectWizard = (composeOptions = productionOptions) => (api) => {
|
|
|
6941
7038
|
const legacyCommands = api.command;
|
|
6942
7039
|
legacyCommands?.register(() => [
|
|
6943
7040
|
{
|
|
6944
|
-
onSelect: () =>
|
|
7041
|
+
onSelect: () => void r33Menu(api, composeOptions),
|
|
6945
7042
|
slash: { name: "r33" },
|
|
6946
|
-
title: "Route 33:
|
|
6947
|
-
value: "route33.
|
|
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
7050
|
// src/tui-entry/show-r33-menu/show-r33-menu.ts
|
|
6954
|
-
var
|
|
7051
|
+
var menuOptions2 = [
|
|
6955
7052
|
{
|
|
6956
7053
|
title: "Connect \u2014 sign in and assign a budget",
|
|
6957
7054
|
value: "connect"
|
|
@@ -6976,7 +7073,7 @@ var menuOptions = [
|
|
|
6976
7073
|
var showR33Menu = async (context) => {
|
|
6977
7074
|
const selection = await context.ui.dialog.select({
|
|
6978
7075
|
title: "Route 33 \u2014 choose an action",
|
|
6979
|
-
options:
|
|
7076
|
+
options: menuOptions2
|
|
6980
7077
|
});
|
|
6981
7078
|
if (selection === void 0) return;
|
|
6982
7079
|
if (selection === "connect") {
|
|
@@ -6995,27 +7092,40 @@ var showR33Menu = async (context) => {
|
|
|
6995
7092
|
// src/tui-entry/v2-autoconnect/v2-autoconnect.ts
|
|
6996
7093
|
init_attribution();
|
|
6997
7094
|
init_cli();
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7095
|
+
|
|
7096
|
+
// src/tui-entry/v2-connect-runner/v2-connect-runner.ts
|
|
7097
|
+
var createV2ConnectRunner = ({
|
|
7098
|
+
context,
|
|
7099
|
+
unattributed
|
|
7100
|
+
}) => {
|
|
7002
7101
|
const oauth = context.client?.api?.integration?.oauth;
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
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
|
+
};
|
|
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,
|
|
7006
7122
|
outsideWorktree: "return-undefined"
|
|
7007
|
-
});
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
variant: "info"
|
|
7014
|
-
});
|
|
7015
|
-
await oauth.connect({
|
|
7016
|
-
integrationID: "route33",
|
|
7017
|
-
methodID: "browser"
|
|
7018
|
-
}).catch(() => void 0);
|
|
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.");
|
|
7019
7129
|
};
|
|
7020
7130
|
|
|
7021
7131
|
// src/tui-entry/v2-tui/v2-tui.ts
|