bdy 1.22.96-dev → 1.22.97-dev
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/distTs/package.json +1 -1
- package/distTs/src/command/agent/install.js +14 -2
- package/distTs/src/command/tunnel/http.js +1 -1
- package/distTs/src/command/tunnel/start.js +1 -1
- package/distTs/src/command/tunnel/tcp.js +1 -1
- package/distTs/src/command/tunnel/tls.js +1 -1
- package/distTs/src/format.js +13 -0
- package/distTs/src/output.js +6 -1
- package/distTs/src/texts.js +6 -6
- package/distTs/src/tunnel/api/buddy.js +13 -4
- package/distTs/src/tunnel/cfg.js +6 -0
- package/distTs/src/tunnel/config.js +5 -1
- package/distTs/src/tunnel/output/interactive/tunnel.js +25 -0
- package/distTs/src/tunnel/output/noninteractive/config/tunnel.js +2 -0
- package/distTs/src/tunnel/output/noninteractive/tunnel.js +13 -1
- package/distTs/src/tunnel/tunnel.js +3 -0
- package/distTs/src/utils.js +6 -0
- package/package.json +1 -1
package/distTs/package.json
CHANGED
|
@@ -79,6 +79,8 @@ const installService = async (options) => {
|
|
|
79
79
|
const target = !!options.target;
|
|
80
80
|
const tunneling = !!options.tunnels;
|
|
81
81
|
const proxy = !!options.proxy;
|
|
82
|
+
const note = options.note;
|
|
83
|
+
const agentNote = options.agentNote;
|
|
82
84
|
let agent;
|
|
83
85
|
if (id) {
|
|
84
86
|
try {
|
|
@@ -90,7 +92,10 @@ const installService = async (options) => {
|
|
|
90
92
|
}
|
|
91
93
|
if (!agent) {
|
|
92
94
|
const tags = prepareTags(options.tag);
|
|
93
|
-
agent = await ApiBuddy.register(true, target, tunneling, proxy, host, token, tags, (0, utils_1.getServiceUser)(options.user, options.pass),
|
|
95
|
+
agent = await ApiBuddy.register(true, target, tunneling, proxy, host, token, tags, (0, utils_1.getServiceUser)(options.user, options.pass), {
|
|
96
|
+
note,
|
|
97
|
+
agentNote,
|
|
98
|
+
}, (region) => {
|
|
94
99
|
cfg_1.default.setRegionIfNotSet(region);
|
|
95
100
|
});
|
|
96
101
|
id = agent.id;
|
|
@@ -156,9 +161,14 @@ const installApp = async (options) => {
|
|
|
156
161
|
const { token, host } = await input_1.default.tunnelToken(addToken);
|
|
157
162
|
if (!id) {
|
|
158
163
|
const tags = prepareTags(options.tag);
|
|
164
|
+
const note = options.note;
|
|
165
|
+
const agentNote = options.agentNote;
|
|
159
166
|
try {
|
|
160
167
|
output_1.default.normal(texts_1.TXT_AGENT_STANDALONE_AGENT_REGISTERING, false);
|
|
161
|
-
const agent = await ApiBuddy.register(true, !!options.target, !!options.tunnels, !!options.proxy, host, token, tags, (0, utils_1.getCurrentUser)(),
|
|
168
|
+
const agent = await ApiBuddy.register(true, !!options.target, !!options.tunnels, !!options.proxy, host, token, tags, (0, utils_1.getCurrentUser)(), {
|
|
169
|
+
note,
|
|
170
|
+
agentNote,
|
|
171
|
+
}, (region) => {
|
|
162
172
|
cfg_1.default.setRegionIfNotSet(region);
|
|
163
173
|
});
|
|
164
174
|
logger_1.default.info(texts_1.TXT_AGENT_STANDALONE_AGENT_REGISTERED);
|
|
@@ -220,6 +230,8 @@ commandAgentInstall.option('--proxy', texts_1.OPTION_AGENT_PROXY);
|
|
|
220
230
|
commandAgentInstall.option('--no-tunnels', texts_1.OPTION_AGENT_TUNNELING);
|
|
221
231
|
commandAgentInstall.option('--tag <tag...>', texts_1.OPTION_AGENT_TAG);
|
|
222
232
|
commandAgentInstall.option('-d, --debug', texts_1.OPTION_AGENT_DEBUG);
|
|
233
|
+
commandAgentInstall.option('--note <note>', texts_1.OPT_COMMAND_NOTE);
|
|
234
|
+
commandAgentInstall.option('--agent-note <note>', texts_1.OPT_COMMAND_AGENT_NOTE);
|
|
223
235
|
commandAgentInstall.action(async (options) => {
|
|
224
236
|
const AgentManager = require('../../agent/manager').default;
|
|
225
237
|
options.start = options.start === 'true' || options.start === true;
|
|
@@ -20,7 +20,7 @@ commandHttp.action(async (target, options) => {
|
|
|
20
20
|
const { host, token } = await Input.tunnelToken(options.token);
|
|
21
21
|
const prepared = await Cfg.prepareTunnel(tunnel_1.TUNNEL_TYPE.HTTP, target, options, true);
|
|
22
22
|
await output_1.default.spinner(texts_1.TXT_OPENING_TUNNEL);
|
|
23
|
-
const agent = await ApiBuddy.register(false, false, true, false, host, token, [], (0, utils_1.getCurrentUser)(), (region) => {
|
|
23
|
+
const agent = await ApiBuddy.register(false, false, true, false, host, token, [], (0, utils_1.getCurrentUser)(), {}, (region) => {
|
|
24
24
|
Cfg.setRegionIfNotSet(region);
|
|
25
25
|
});
|
|
26
26
|
await agent.start();
|
|
@@ -20,7 +20,7 @@ commandStart.action(async (name, options) => {
|
|
|
20
20
|
const { token, host } = await Input.tunnelToken(options.token);
|
|
21
21
|
const prepared = Cfg.getTunnel(name);
|
|
22
22
|
await output_1.default.spinner(texts_1.TXT_OPENING_TUNNEL);
|
|
23
|
-
const agent = await ApiBuddy.register(false, false, true, false, host, token, [], (0, utils_1.getCurrentUser)(), (region) => {
|
|
23
|
+
const agent = await ApiBuddy.register(false, false, true, false, host, token, [], (0, utils_1.getCurrentUser)(), {}, (region) => {
|
|
24
24
|
Cfg.setRegionIfNotSet(region);
|
|
25
25
|
});
|
|
26
26
|
await agent.start();
|
|
@@ -19,7 +19,7 @@ commandTcp.action(async (target, options) => {
|
|
|
19
19
|
const { host, token } = await Input.tunnelToken(options.token);
|
|
20
20
|
const prepared = await Cfg.prepareTunnel(tunnel_1.TUNNEL_TYPE.TCP, target, options, true);
|
|
21
21
|
await output_1.default.spinner(texts_1.TXT_OPENING_TUNNEL);
|
|
22
|
-
const agent = await ApiBuddy.register(false, false, true, false, host, token, [], (0, utils_1.getCurrentUser)(), (region) => {
|
|
22
|
+
const agent = await ApiBuddy.register(false, false, true, false, host, token, [], (0, utils_1.getCurrentUser)(), {}, (region) => {
|
|
23
23
|
Cfg.setRegionIfNotSet(region);
|
|
24
24
|
});
|
|
25
25
|
await agent.start();
|
|
@@ -19,7 +19,7 @@ commandTls.action(async (target, options) => {
|
|
|
19
19
|
const { token, host } = await Input.tunnelToken(options.token);
|
|
20
20
|
const prepared = await Cfg.prepareTunnel(tunnel_1.TUNNEL_TYPE.TLS, target, options, true);
|
|
21
21
|
await output_1.default.spinner(texts_1.TXT_OPENING_TUNNEL);
|
|
22
|
-
const agent = await ApiBuddy.register(false, false, true, false, host, token, [], (0, utils_1.getCurrentUser)(), (region) => {
|
|
22
|
+
const agent = await ApiBuddy.register(false, false, true, false, host, token, [], (0, utils_1.getCurrentUser)(), {}, (region) => {
|
|
23
23
|
Cfg.setRegionIfNotSet(region);
|
|
24
24
|
});
|
|
25
25
|
await agent.start();
|
package/distTs/src/format.js
CHANGED
|
@@ -86,6 +86,19 @@ class Format {
|
|
|
86
86
|
return 'Not set';
|
|
87
87
|
return host;
|
|
88
88
|
}
|
|
89
|
+
static note(note) {
|
|
90
|
+
if (!note)
|
|
91
|
+
return 'Not set';
|
|
92
|
+
return this.noteInline(note);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Notes are free text and may contain newlines. Every place we render one
|
|
96
|
+
* sits on a single line — a log entry or a fixed-height terminal row — so
|
|
97
|
+
* collapse whitespace runs before display.
|
|
98
|
+
*/
|
|
99
|
+
static noteInline(note) {
|
|
100
|
+
return note.replace(/\s+/g, ' ').trim();
|
|
101
|
+
}
|
|
89
102
|
static basicAuth(login, pass) {
|
|
90
103
|
if (!login || !pass)
|
|
91
104
|
return 'Not set';
|
package/distTs/src/output.js
CHANGED
|
@@ -204,7 +204,12 @@ class Output {
|
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
static async spinner(txt) {
|
|
207
|
-
|
|
207
|
+
// Both streams must be a TTY, not just stdout: terminal-kit's inline
|
|
208
|
+
// spinner awaits a cursor-position reply read from stdin, so with stdout on
|
|
209
|
+
// a terminal but stdin redirected (e.g. `bdy tunnel http 3000 < /dev/null`)
|
|
210
|
+
// that reply can never arrive. A spinner is interactive-session animation
|
|
211
|
+
// anyway, so requiring both is also the correct predicate.
|
|
212
|
+
if (!this.s && this.isTTY()) {
|
|
208
213
|
this.s = await getTerminal().spinner();
|
|
209
214
|
if (txt)
|
|
210
215
|
getTerminal()(` ${txt}`);
|
package/distTs/src/texts.js
CHANGED
|
@@ -412,7 +412,7 @@ exports.OPTION_ARTIFACT_ID = 'Human-readable ID of the artifact and optionally v
|
|
|
412
412
|
exports.OPTION_ARTIFACT_PUBLISH_CREATE = 'Create artifact if not exists';
|
|
413
413
|
exports.OPTION_ARTIFACT_VERSION_FROM = 'Version to copy content from';
|
|
414
414
|
exports.OPTION_ARTIFACT_VERSION_NOTE = 'Note of the artifact version';
|
|
415
|
-
exports.OPTION_ARTIFACT_VERSION_AGENT_NOTE = '
|
|
415
|
+
exports.OPTION_ARTIFACT_VERSION_AGENT_NOTE = 'Note of the artifact version for AI agents';
|
|
416
416
|
exports.OPTION_ARTIFACT_PUBLISH_OVERWRITE_VERSION = 'Allow overwriting existing version';
|
|
417
417
|
exports.OPTION_ARTIFACT_DOWNLOAD_MERGE = 'Merge contents of the directory with artifact';
|
|
418
418
|
exports.OPTION_ARTIFACT_DOWNLOAD_REPLACE = 'Replace contents of the directory with artifact';
|
|
@@ -634,7 +634,7 @@ exports.DESC_COMMAND_SANDBOX_APP = 'Manage sandbox apps';
|
|
|
634
634
|
exports.OPTION_SANDBOX_IDENTIFIER = 'Sandbox identifier';
|
|
635
635
|
exports.OPTION_SANDBOX_NAME = 'Sandbox display name';
|
|
636
636
|
exports.OPTION_SANDBOX_NOTE = 'Sandbox note';
|
|
637
|
-
exports.OPTION_SANDBOX_AGENT_NOTE = 'Sandbox
|
|
637
|
+
exports.OPTION_SANDBOX_AGENT_NOTE = 'Sandbox note for AI agents';
|
|
638
638
|
exports.OPTION_SANDBOX_OS = `Operating system image (ubuntu:24.04 (default), ubuntu:22.04)`;
|
|
639
639
|
exports.OPTION_SANDBOX_RESOURCES = 'Resource allocation: 1x2, 2x4, 4x8, 8x16, 12x24 (CPUxRAM)';
|
|
640
640
|
exports.OPTION_SANDBOX_INSTALL_COMMANDS = 'Setup commands to run on creation (can be used multiple times)';
|
|
@@ -954,7 +954,7 @@ exports.DESC_COMMAND_ROUTE_DELETE = 'Delete route. Required scopes: DISTRIBUTION
|
|
|
954
954
|
exports.DESC_COMMAND_ROUTE_UPDATE = 'Update route. Required scopes: DISTRIBUTION_MANAGE';
|
|
955
955
|
exports.DESC_COMMAND_ROUTE = 'Manage distribution routes';
|
|
956
956
|
exports.OPT_COMMAND_NOTE = 'Resource note';
|
|
957
|
-
exports.OPT_COMMAND_AGENT_NOTE = '
|
|
957
|
+
exports.OPT_COMMAND_AGENT_NOTE = 'Note for AI agents operating on this resource';
|
|
958
958
|
exports.OPT_COMMAND_SCOPE = 'Force scope (WORKSPACE, PROJECT). By default calculated by provided options and environmental variables (--project, BUDDY_PROJECT, linked project)';
|
|
959
959
|
exports.OPT_COMMAND_DISTRO_IDENTIFIER = 'Human-readable ID of the distribution';
|
|
960
960
|
exports.OPT_COMMAND_ROUTE_ID = 'ID of the route (find via "bdy distro route ls")';
|
|
@@ -963,7 +963,7 @@ exports.OPT_COMMAND_ROUTE_SUBDOMAIN = 'Optional sub-name prepended to --domain (
|
|
|
963
963
|
exports.OPT_COMMAND_ROUTE_DOMAIN = 'Zone for the route — pass the WHOLE string from `bdy domain ls` (e.g. "example.com" or "my-app.example.dev"). Do NOT split a multi-level zone into subdomain+domain; the entire bought/claimed string is one zone and goes here as-is. Use --subdomain only to route a sub-name within this zone';
|
|
964
964
|
exports.OPT_COMMAND_ROUTE_PATH = 'Path of the route';
|
|
965
965
|
exports.OPT_COMMAND_ROUTE_NOTE = 'Note of the route';
|
|
966
|
-
exports.OPT_COMMAND_ROUTE_AGENT_NOTE = '
|
|
966
|
+
exports.OPT_COMMAND_ROUTE_AGENT_NOTE = 'Note of the route for AI agents';
|
|
967
967
|
exports.OPT_COMMAND_ROUTE_TARGET = `Target of the route (can be used multiple times).
|
|
968
968
|
Format: "region=default,url=https://example.com,artifact=artifact:version,sandbox=sandbox:endpoint"
|
|
969
969
|
To use "," in value use \\,
|
|
@@ -974,7 +974,7 @@ Region can be Default, NorthAmerica, Europe, Asia, Oceania, SouthAmerica, Africa
|
|
|
974
974
|
If no region is specified or default is used, the target is used as the fallback for all locations. Default region is mandatory`;
|
|
975
975
|
exports.OPT_COMMAND_DISTRO_NAME = 'Name of the distribution';
|
|
976
976
|
exports.OPT_COMMAND_DISTRO_NOTE = 'Note of the distribution';
|
|
977
|
-
exports.OPT_COMMAND_DISTRO_AGENT_NOTE = '
|
|
977
|
+
exports.OPT_COMMAND_DISTRO_AGENT_NOTE = 'Note of the distribution for AI agents';
|
|
978
978
|
exports.OPT_COMMAND_DISTRO_ENABLE = 'Enable the distribution';
|
|
979
979
|
exports.OPT_COMMAND_DISTRO_DISABLE = 'Disable the distribution';
|
|
980
980
|
exports.ERR_COMMAND_SCOPE_NO_PROJECT = 'Project must be provided for PROJECT scope';
|
|
@@ -1156,7 +1156,7 @@ exports.EXAMPLE_DISTRO_UPDATE = `
|
|
|
1156
1156
|
bdy distro update distro-identifier -n "new name"
|
|
1157
1157
|
### set note (pass an empty value to clear it)
|
|
1158
1158
|
bdy distro update distro-identifier --note "owned by team web"
|
|
1159
|
-
### set the
|
|
1159
|
+
### set the note read by AI agents
|
|
1160
1160
|
bdy distro update distro-identifier --agent-note "deploy: manual-approval-required"
|
|
1161
1161
|
### disable distribution
|
|
1162
1162
|
bdy distro update distro-identifier --disable`;
|
|
@@ -49,12 +49,12 @@ const makeRequest = async (host, path, body, method = 'POST', respAsJson = true,
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
class ApiBuddyClass {
|
|
52
|
-
async register(service, target, tunneling, proxy, host, token, tags, user, onDefaultRegion) {
|
|
52
|
+
async register(service, target, tunneling, proxy, host, token, tags, user, options, onDefaultRegion) {
|
|
53
53
|
const version = (0, utils_1.getVersion)();
|
|
54
54
|
const hostname = (0, utils_1.getHostname)();
|
|
55
55
|
const platform = (0, utils_1.getPlatform)();
|
|
56
56
|
logger_1.default.info(texts_1.LOG_REGISTERING_AGENT);
|
|
57
|
-
const
|
|
57
|
+
const data = {
|
|
58
58
|
token,
|
|
59
59
|
version,
|
|
60
60
|
hostname,
|
|
@@ -64,8 +64,17 @@ class ApiBuddyClass {
|
|
|
64
64
|
user,
|
|
65
65
|
target,
|
|
66
66
|
tunneling,
|
|
67
|
-
proxy
|
|
68
|
-
|
|
67
|
+
proxy,
|
|
68
|
+
note: '',
|
|
69
|
+
agentNote: ''
|
|
70
|
+
};
|
|
71
|
+
if (options) {
|
|
72
|
+
if (options.note)
|
|
73
|
+
data.note = options.note;
|
|
74
|
+
if (options.agentNote)
|
|
75
|
+
data.agentNote = options.agentNote;
|
|
76
|
+
}
|
|
77
|
+
const r = await makeRequest(host, '/tunnel/agent/add', data);
|
|
69
78
|
logger_1.default.info((0, texts_1.LOG_AGENT_REGISTERED)(r.id));
|
|
70
79
|
logger_1.default.info((0, texts_1.LOG_REGION_DETECTED)(r.region));
|
|
71
80
|
if (onDefaultRegion)
|
package/distTs/src/tunnel/cfg.js
CHANGED
|
@@ -73,6 +73,12 @@ class Cfg {
|
|
|
73
73
|
type,
|
|
74
74
|
target: Input.target(target, type),
|
|
75
75
|
};
|
|
76
|
+
if (options.note !== undefined) {
|
|
77
|
+
tunnel.note = options.note;
|
|
78
|
+
}
|
|
79
|
+
if (options.agentNote !== undefined) {
|
|
80
|
+
tunnel.agentNote = options.agentNote;
|
|
81
|
+
}
|
|
76
82
|
if (options.region !== undefined)
|
|
77
83
|
tunnel.region = Input.region(options.region);
|
|
78
84
|
else if (useDefaults)
|
|
@@ -38,13 +38,15 @@ class TunnelConfig {
|
|
|
38
38
|
sshUser;
|
|
39
39
|
sshPassword;
|
|
40
40
|
sshForwardPort;
|
|
41
|
+
note;
|
|
42
|
+
agentNote;
|
|
41
43
|
sshClientUser;
|
|
42
44
|
sshClientPassword;
|
|
43
45
|
targetProto;
|
|
44
46
|
targetHost;
|
|
45
47
|
targetPort;
|
|
46
48
|
targetAuth;
|
|
47
|
-
constructor({ type, target, region, timeout, domain, subdomain, name, whitelist, tlsSettings, httpSettings, sshSettings, }) {
|
|
49
|
+
constructor({ type, target, region, timeout, domain, subdomain, name, whitelist, tlsSettings, httpSettings, sshSettings, resourceNote, }) {
|
|
48
50
|
this.type = type;
|
|
49
51
|
this.region = region;
|
|
50
52
|
this.target = target;
|
|
@@ -56,6 +58,8 @@ class TunnelConfig {
|
|
|
56
58
|
this.useragents = [];
|
|
57
59
|
this.headers = [];
|
|
58
60
|
this.responseHeaders = [];
|
|
61
|
+
this.note = resourceNote?.note;
|
|
62
|
+
this.agentNote = resourceNote?.agentNote;
|
|
59
63
|
if (tlsSettings) {
|
|
60
64
|
this.terminate = tlsSettings.terminate;
|
|
61
65
|
this.key = tlsSettings.key;
|
|
@@ -67,6 +67,7 @@ class OutputInteractiveTunnel {
|
|
|
67
67
|
y += this.updateSpriteDns(y);
|
|
68
68
|
y += this.updateSpriteType(y);
|
|
69
69
|
y += this.updateSpriteRegion(y);
|
|
70
|
+
y += this.updateSpriteNote(y);
|
|
70
71
|
y += this.updateSpriteTarget(y);
|
|
71
72
|
y += this.updateSpriteIdentify(y);
|
|
72
73
|
y += this.updateSpriteTerminate(y);
|
|
@@ -554,6 +555,13 @@ class OutputInteractiveTunnel {
|
|
|
554
555
|
},
|
|
555
556
|
}, fillString('Region:', ROW_LENGTH));
|
|
556
557
|
}
|
|
558
|
+
createSpriteNote() {
|
|
559
|
+
this.sprites.note = termkit_no_lazy_require_1.default.ScreenBuffer.createFromString({
|
|
560
|
+
attr: {
|
|
561
|
+
color: COLOR_LIGHT_GRAY,
|
|
562
|
+
},
|
|
563
|
+
}, fillString('Note:', ROW_LENGTH));
|
|
564
|
+
}
|
|
557
565
|
createSpriteIdentify() {
|
|
558
566
|
this.sprites.identify = termkit_no_lazy_require_1.default.ScreenBuffer.createFromString({
|
|
559
567
|
attr: {
|
|
@@ -704,6 +712,22 @@ class OutputInteractiveTunnel {
|
|
|
704
712
|
});
|
|
705
713
|
return this.sprites.region.height;
|
|
706
714
|
}
|
|
715
|
+
updateSpriteNote(y) {
|
|
716
|
+
if (!this.tunnel.note)
|
|
717
|
+
return 0;
|
|
718
|
+
this.sprites.note.put({
|
|
719
|
+
x: COLUMN_LENGTH,
|
|
720
|
+
y: 0,
|
|
721
|
+
attr: {
|
|
722
|
+
color: COLOR_WHITE,
|
|
723
|
+
},
|
|
724
|
+
}, fillString(format_1.default.noteInline(this.tunnel.note), ROW_LENGTH - COLUMN_LENGTH));
|
|
725
|
+
this.sprites.note.draw({
|
|
726
|
+
dst: this.viewPort,
|
|
727
|
+
y,
|
|
728
|
+
});
|
|
729
|
+
return this.sprites.note.height;
|
|
730
|
+
}
|
|
707
731
|
updateSpriteTerminate(y) {
|
|
708
732
|
if (this.tunnel.type === tunnel_1.TUNNEL_TYPE.TLS) {
|
|
709
733
|
this.sprites.terminate.put({
|
|
@@ -820,6 +844,7 @@ class OutputInteractiveTunnel {
|
|
|
820
844
|
this.createSpriteType();
|
|
821
845
|
this.createSpriteDns();
|
|
822
846
|
this.createSpriteRegion();
|
|
847
|
+
this.createSpriteNote();
|
|
823
848
|
this.createSpriteTarget();
|
|
824
849
|
this.createSpriteIdentify();
|
|
825
850
|
this.createSpriteTerminate();
|
|
@@ -26,6 +26,8 @@ class OutputNoninteractiveConfigTunnel {
|
|
|
26
26
|
format_1.default.target(this.tunnel.type, this.tunnel.target),
|
|
27
27
|
]);
|
|
28
28
|
}
|
|
29
|
+
data.push(['Note', format_1.default.note(this.tunnel.note)]);
|
|
30
|
+
data.push(['Agent Note', format_1.default.note(this.tunnel.agentNote)]);
|
|
29
31
|
data.push(['Region', format_1.default.tunnelRegion(this.tunnel.region)]);
|
|
30
32
|
data.push(['Timeout', format_1.default.tunnelTimeout(this.tunnel.timeout)]);
|
|
31
33
|
data.push(['Whitelist', format_1.default.tunnelWhitelist(this.tunnel.whitelist)]);
|
|
@@ -17,7 +17,11 @@ class OutputNoninteractiveTunnel {
|
|
|
17
17
|
this.terminal(`${format_1.default.date()}: Tunnel ${t.type} to ${t.serve || t.target} ${status}\n`);
|
|
18
18
|
}
|
|
19
19
|
onOpen(t) {
|
|
20
|
-
|
|
20
|
+
// Appended after the entry URL, so a consumer scraping the URL out of this
|
|
21
|
+
// line still terminates it on whitespace. Omitted entirely when unset to
|
|
22
|
+
// keep the common line unchanged.
|
|
23
|
+
const note = t.note ? ` Note: ${format_1.default.noteInline(t.note)}` : '';
|
|
24
|
+
this.status(t, `open. Entry: ${format_1.default.entry(t)}${note}`);
|
|
21
25
|
}
|
|
22
26
|
onClosed(t) {
|
|
23
27
|
this.status(t, 'closed');
|
|
@@ -57,6 +61,14 @@ class OutputNoninteractiveTunnel {
|
|
|
57
61
|
this.tunnel.on(tunnel_1.TUNNEL_EVENT.HTTP_REQUEST, (t, logRequest) => this.onHttpRequest(t, logRequest));
|
|
58
62
|
this.tunnel.on(tunnel_1.TUNNEL_EVENT.HTTP_RESPONSE, (t, logRequest) => this.onHttpResponse(t, logRequest));
|
|
59
63
|
this.tunnel.on(tunnel_1.TUNNEL_EVENT.STOPPED, () => this.onStopped());
|
|
64
|
+
// This renderer is otherwise purely event-driven, so a tunnel handed to it
|
|
65
|
+
// already open — `agent tunnel status <id>` attaches to a live one — has
|
|
66
|
+
// already missed its OPEN event and would print nothing at all. Dump the
|
|
67
|
+
// current state once, the way the interactive dashboard's first draw does.
|
|
68
|
+
// Tunnels we open ourselves are not yet OPEN at this point, so they still
|
|
69
|
+
// print exactly once, from the event.
|
|
70
|
+
if (this.tunnel.status === tunnel_1.TUNNEL_STATUS.OPEN)
|
|
71
|
+
this.onOpen(this.tunnel);
|
|
60
72
|
}
|
|
61
73
|
}
|
|
62
74
|
exports.default = OutputNoninteractiveTunnel;
|
package/distTs/src/utils.js
CHANGED
|
@@ -543,6 +543,8 @@ const getBasicCommandTcp = () => {
|
|
|
543
543
|
commandTcp.option('-w, --whitelist <cidrs...>', texts_1.OPTION_WHITELIST);
|
|
544
544
|
commandTcp.option('-n, --name <name>', texts_1.OPTION_NAME);
|
|
545
545
|
commandTcp.option('-t, --timeout <seconds>', texts_1.OPTION_TIMEOUT);
|
|
546
|
+
commandTcp.option('--note <note>', texts_1.OPT_COMMAND_NOTE);
|
|
547
|
+
commandTcp.option('--agent-note <note>', texts_1.OPT_COMMAND_AGENT_NOTE);
|
|
546
548
|
return commandTcp;
|
|
547
549
|
};
|
|
548
550
|
exports.getBasicCommandTcp = getBasicCommandTcp;
|
|
@@ -594,6 +596,8 @@ const getBasicCommandHttp = () => {
|
|
|
594
596
|
commandHttp.option('-2, --http2', texts_1.OPTION_HTTP_2);
|
|
595
597
|
commandHttp.option('-c, --compression', texts_1.OPTION_HTTP_COMPRESSION);
|
|
596
598
|
commandHttp.option('--ca <ca>', texts_1.OPTION_TLS_CA);
|
|
599
|
+
commandHttp.option('--note <note>', texts_1.OPT_COMMAND_NOTE);
|
|
600
|
+
commandHttp.option('--agent-note <note>', texts_1.OPT_COMMAND_AGENT_NOTE);
|
|
597
601
|
commandHttp.option('--circuit-breaker <threshold>', texts_1.OPTION_HTTP_CIRCUIT_BREAKER);
|
|
598
602
|
return commandHttp;
|
|
599
603
|
};
|
|
@@ -609,6 +613,8 @@ const getBasicCommandTls = () => {
|
|
|
609
613
|
commandTls.option('-c, --cert <cert>', texts_1.OPTION_TLS_CERT);
|
|
610
614
|
commandTls.option('--ca <ca>', texts_1.OPTION_TLS_CA);
|
|
611
615
|
commandTls.option('-i, --terminate <at>', texts_1.OPTION_TLS_TERMINATE);
|
|
616
|
+
commandTls.option('--note <note>', texts_1.OPT_COMMAND_NOTE);
|
|
617
|
+
commandTls.option('--agent-note <note>', texts_1.OPT_COMMAND_AGENT_NOTE);
|
|
612
618
|
return commandTls;
|
|
613
619
|
};
|
|
614
620
|
exports.getBasicCommandTls = getBasicCommandTls;
|