@prohost/cli 0.12.4 → 0.13.1

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.
@@ -206,6 +206,12 @@ export interface RuntimeStatusReporterOptions {
206
206
  accountKeys?: () => string[] | undefined;
207
207
  /** A run is executing — it will bring fresh numbers, so don't probe beside it. */
208
208
  isBusy?: () => boolean;
209
+ /**
210
+ * What this harness can do that the server needs to know before sending it
211
+ * work — today only `venue_run_token` (see `venue.ts`). Read for every
212
+ * frame, so a downgraded harness stops declaring what it no longer does.
213
+ */
214
+ capabilities?: () => string[];
209
215
  now?: () => number;
210
216
  /** Timer seam for tests. Returns a cancel function. */
211
217
  schedule?: (fn: () => void, ms: number) => () => void;
@@ -472,6 +472,10 @@ function asOf(window, nowMs) {
472
472
  return window;
473
473
  return { ...window, used_percent: 0, resets_at: null };
474
474
  }
475
+ /** Left out when there is nothing to declare, so an older server sees the frame it knows. */
476
+ function capabilitiesField(capabilities) {
477
+ return capabilities && capabilities.length > 0 ? { capabilities } : {};
478
+ }
475
479
  function defaultSchedule(fn, ms) {
476
480
  const timer = setTimeout(fn, ms);
477
481
  timer.unref?.();
@@ -595,6 +599,7 @@ export class RuntimeStatusReporter {
595
599
  plan_label: this.state.plan_label ?? null,
596
600
  quota_windows: windows,
597
601
  observed_at: new Date(nowMs).toISOString(),
602
+ ...capabilitiesField(this.options.capabilities?.()),
598
603
  // Optional additions: an older server ignores keys it doesn't know.
599
604
  ...(this.accounts?.current ? { account: this.accounts.current } : {}),
600
605
  // Never a list the registry has moved on from — the server would delete
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Runs that answer in a connected team's thread — a *venue*.
3
+ *
4
+ * Connected Teams let two ProhostAI workspaces talk in each other's team chat,
5
+ * so this agent can be addressed in a thread that belongs to the OTHER
6
+ * workspace. That thread's text is someone else's prompt, and the harness's own
7
+ * credential can write anywhere in this agent's home workspace. So a venue run
8
+ * is answered by a session that holds none of it:
9
+ *
10
+ * * **Its own credential.** The event carries no thread text at all. The
11
+ * harness opens the run's *venue session* over its own `/ws/webhooks` socket
12
+ * (there is no HTTP route to it) and gets back a token minted for this one
13
+ * run together with the thread. The token reads and posts in that one thread and heartbeats,
14
+ * streams and completes that one run — nothing else — and the server refuses
15
+ * the harness's key for all of it. Every request the run makes carries the
16
+ * token. It lives in memory only: never logged, never written to disk.
17
+ * * **No tools, no configuration.** Claude Code is started from the operator's
18
+ * binary and model only, with `--tools ''` (no built-in tools, so nothing can
19
+ * read the credentials file or the environment), `--safe-mode` and
20
+ * `--setting-sources '' --settings '{}'` (no hooks, plugins, skills,
21
+ * `CLAUDE.md`, permissions or settings from `~/.claude` or any project), an
22
+ * empty strict MCP config (never the ProhostAI server or the operator's extra
23
+ * servers), and `--no-session-persistence` (the connected team's text is not
24
+ * written to a transcript). The agent answers from the thread; the harness
25
+ * posts the reply.
26
+ * * **No home environment.** The child gets an allowlisted environment —
27
+ * what a shell and the Claude login need, nothing of ProhostAI's — and an
28
+ * empty directory of its own, removed afterwards.
29
+ *
30
+ * Only Claude Code can be held to that, and only a release that has every one
31
+ * of those flags, so only such a harness declares
32
+ * {@link VENUE_RUN_TOKEN_CAPABILITY} — and the server sends venue runs only to
33
+ * a runtime that declared it. A venue run that reaches any other harness anyway
34
+ * is refused without being run.
35
+ */
36
+ import type { ApiOptions } from './api.js';
37
+ import type { AgentRunRequest } from './contract.js';
38
+ /**
39
+ * What a harness declares in its `runtime_status` frame when it runs venue
40
+ * sessions as described above. Mirrors `VENUE_RUN_TOKEN_CAPABILITY` in the
41
+ * server's `shared/agents/runtime_status.py`.
42
+ */
43
+ export declare const VENUE_RUN_TOKEN_CAPABILITY = "venue_run_token";
44
+ /** The token prefix the server mints. Anything else is not a run token. */
45
+ export declare const VENUE_RUN_TOKEN_PREFIX = "pvr_";
46
+ /** Whether a run answers in a connected team's thread. */
47
+ export declare function isVenueRun(run: AgentRunRequest): boolean;
48
+ /**
49
+ * The API options a run's requests go out with: its own token for a venue run
50
+ * whose session is open, the harness's credential for every other.
51
+ */
52
+ export declare function apiForRun(api: ApiOptions, run: AgentRunRequest): ApiOptions;
53
+ /**
54
+ * Whether this Claude Code binary has every flag a venue session depends on.
55
+ *
56
+ * Asked of `--help` rather than inferred from a version number: the flags are
57
+ * what matters, and a build without one of them would reject the command
58
+ * outright — or, worse, a future one might accept and ignore it. Windows is
59
+ * left out because its shell quoting cannot be relied on to hand `--tools` an
60
+ * empty value.
61
+ */
62
+ export declare function claudeSupportsVenueSessions(helpText: string, platform?: NodeJS.Platform): boolean;
63
+ /**
64
+ * The Claude Code command a venue run is answered with.
65
+ *
66
+ * Built from the operator's binary and model only — never the rest of their
67
+ * `--exec` string, whose flags (`--add-dir`, `--mcp-config`, `--allowedTools`,
68
+ * `--dangerously-skip-permissions`) are exactly what a venue session must not
69
+ * get.
70
+ */
71
+ export declare function claudeVenueCommand(exec: string, model?: string, platform?: NodeJS.Platform): string;
72
+ /**
73
+ * The environment a venue session's child gets, built up rather than pared
74
+ * down: the shell basics above, the locale, and Claude Code's own login and
75
+ * configuration (`CLAUDE_*`, `ANTHROPIC_*` — the brain cannot start without
76
+ * them). Everything else is dropped — ProhostAI's variables first among them,
77
+ * but also every other credential the operator's environment happens to hold.
78
+ *
79
+ * `HOME` stays real: Claude Code finds its login through it, and a session
80
+ * with no tools cannot read anything there.
81
+ */
82
+ export declare function venueEnv(base: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
83
+ /** A fresh empty directory for one venue session, and its removal. */
84
+ export declare function venueWorkdir(): {
85
+ dir: string;
86
+ remove: () => void;
87
+ };
88
+ /**
89
+ * The `/ws/webhooks` contract for venue sessions. Mirrors `VENUE_SESSION_*` in
90
+ * the server's `shared/agents/venue.py`: the feature `auth_ok` lists, the frame
91
+ * this harness sends to open one, and the frame it gets back.
92
+ */
93
+ export declare const VENUE_SESSION_FEATURE = "venue_session";
94
+ export declare const VENUE_SESSION_OPEN_FRAME = "venue_session_open";
95
+ export declare const VENUE_SESSION_FRAME = "venue_session";
96
+ /** An opened venue session: the run as the agent will see it, token attached. */
97
+ export type VenueSessionResult = {
98
+ ok: true;
99
+ run: AgentRunRequest;
100
+ } | {
101
+ ok: false;
102
+ error: string;
103
+ };
104
+ /**
105
+ * The run as its venue session answered it, with the thread and the token.
106
+ *
107
+ * The session is opened over this harness's own socket and nowhere else — the
108
+ * server keeps no HTTP route to it, so a process that merely holds this
109
+ * machine's key (an ordinary agent session) cannot ask for one the way the
110
+ * harness does. The token is attached to the returned run and goes nowhere
111
+ * else: no error here repeats the answer.
112
+ */
113
+ export declare function venueRunFromSession(run: AgentRunRequest, data: Record<string, unknown>, answer: Record<string, unknown>, clock?: VenueClock): VenueSessionResult;
114
+ /**
115
+ * When a venue session was asked for, and the time now, on both clocks. Each
116
+ * defaults to the real clock; tests pin them.
117
+ */
118
+ export interface VenueClock {
119
+ openedAtMono?: number;
120
+ openedAtWall?: number;
121
+ nowMono?: number;
122
+ wallNow?: number;
123
+ }
124
+ /**
125
+ * How long before its deadline a venue grant already counts as over: room to
126
+ * close the run with its token while the token still works.
127
+ */
128
+ export declare const VENUE_EXPIRY_MARGIN_MS = 30000;
129
+ /**
130
+ * How often a running venue run's grant is re-checked: the longest a run can
131
+ * outlive its grant after the machine wakes from a sleep.
132
+ */
133
+ export declare const VENUE_GRANT_CHECK_MS = 15000;
134
+ /** The completion error of a venue run whose grant ran out before it started. */
135
+ export declare const VENUE_GRANT_EXPIRED_ERROR = "connected-team grant expired before the run started";
136
+ /** The completion error of a venue run stopped because its grant was ending. */
137
+ export declare const VENUE_GRANT_ENDED_ERROR = "connected-team grant expired while the run was working";
138
+ /**
139
+ * How much of a venue run's grant is left, in milliseconds — negative once it
140
+ * is over, and `-Infinity` for a run that carries no grant.
141
+ *
142
+ * The lifetime is counted on both clocks and the shorter one wins: the
143
+ * monotonic clock cannot be wound back, and the wall clock keeps counting
144
+ * while the machine sleeps (Linux's monotonic clock does not), so neither a
145
+ * changed clock nor a suspend outlasts the token. Both count elapsed time from
146
+ * the same moment, so a skewed wall clock still cancels out.
147
+ */
148
+ export declare function venueGrantRemainingMs(run: AgentRunRequest, nowMono?: number, wallNow?: number): number;
149
+ /**
150
+ * Whether a venue run's grant is still good — checked when its session opens
151
+ * and again right before the agent is started, so a run that waited in the
152
+ * queue past its grant never starts.
153
+ */
154
+ export declare function venueGrantLive(run: AgentRunRequest, nowMono?: number, wallNow?: number): boolean;
155
+ /**
156
+ * What a venue run reports about itself while it works and when it fails.
157
+ *
158
+ * The run's progress line and failure detail land on its row in this agent's
159
+ * home workspace. A venue run's would be the agent's words about the
160
+ * connected team's thread — or the thread itself, quoted — so it reports a
161
+ * fixed line instead.
162
+ */
163
+ export declare const VENUE_PROGRESS = "answering in a connected team's thread";
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Runs that answer in a connected team's thread — a *venue*.
3
+ *
4
+ * Connected Teams let two ProhostAI workspaces talk in each other's team chat,
5
+ * so this agent can be addressed in a thread that belongs to the OTHER
6
+ * workspace. That thread's text is someone else's prompt, and the harness's own
7
+ * credential can write anywhere in this agent's home workspace. So a venue run
8
+ * is answered by a session that holds none of it:
9
+ *
10
+ * * **Its own credential.** The event carries no thread text at all. The
11
+ * harness opens the run's *venue session* over its own `/ws/webhooks` socket
12
+ * (there is no HTTP route to it) and gets back a token minted for this one
13
+ * run together with the thread. The token reads and posts in that one thread and heartbeats,
14
+ * streams and completes that one run — nothing else — and the server refuses
15
+ * the harness's key for all of it. Every request the run makes carries the
16
+ * token. It lives in memory only: never logged, never written to disk.
17
+ * * **No tools, no configuration.** Claude Code is started from the operator's
18
+ * binary and model only, with `--tools ''` (no built-in tools, so nothing can
19
+ * read the credentials file or the environment), `--safe-mode` and
20
+ * `--setting-sources '' --settings '{}'` (no hooks, plugins, skills,
21
+ * `CLAUDE.md`, permissions or settings from `~/.claude` or any project), an
22
+ * empty strict MCP config (never the ProhostAI server or the operator's extra
23
+ * servers), and `--no-session-persistence` (the connected team's text is not
24
+ * written to a transcript). The agent answers from the thread; the harness
25
+ * posts the reply.
26
+ * * **No home environment.** The child gets an allowlisted environment —
27
+ * what a shell and the Claude login need, nothing of ProhostAI's — and an
28
+ * empty directory of its own, removed afterwards.
29
+ *
30
+ * Only Claude Code can be held to that, and only a release that has every one
31
+ * of those flags, so only such a harness declares
32
+ * {@link VENUE_RUN_TOKEN_CAPABILITY} — and the server sends venue runs only to
33
+ * a runtime that declared it. A venue run that reaches any other harness anyway
34
+ * is refused without being run.
35
+ */
36
+ import { mkdtempSync, rmSync } from 'node:fs';
37
+ import os from 'node:os';
38
+ import path from 'node:path';
39
+ import { parseRunRequest } from './contract.js';
40
+ import { shellQuote } from './shell.js';
41
+ /**
42
+ * What a harness declares in its `runtime_status` frame when it runs venue
43
+ * sessions as described above. Mirrors `VENUE_RUN_TOKEN_CAPABILITY` in the
44
+ * server's `shared/agents/runtime_status.py`.
45
+ */
46
+ export const VENUE_RUN_TOKEN_CAPABILITY = 'venue_run_token';
47
+ /** The token prefix the server mints. Anything else is not a run token. */
48
+ export const VENUE_RUN_TOKEN_PREFIX = 'pvr_';
49
+ /** Every flag {@link claudeVenueCommand} uses. A build missing one cannot run a venue session. */
50
+ const VENUE_FLAGS = [
51
+ '--tools',
52
+ '--safe-mode',
53
+ '--setting-sources',
54
+ '--settings',
55
+ '--strict-mcp-config',
56
+ '--mcp-config',
57
+ '--no-session-persistence',
58
+ ];
59
+ /** Whether a run answers in a connected team's thread. */
60
+ export function isVenueRun(run) {
61
+ return run.venue !== undefined;
62
+ }
63
+ /**
64
+ * The API options a run's requests go out with: its own token for a venue run
65
+ * whose session is open, the harness's credential for every other.
66
+ */
67
+ export function apiForRun(api, run) {
68
+ return isVenueRun(run) && run.venue_run_token ? { ...api, apiKey: run.venue_run_token } : api;
69
+ }
70
+ /**
71
+ * Whether this Claude Code binary has every flag a venue session depends on.
72
+ *
73
+ * Asked of `--help` rather than inferred from a version number: the flags are
74
+ * what matters, and a build without one of them would reject the command
75
+ * outright — or, worse, a future one might accept and ignore it. Windows is
76
+ * left out because its shell quoting cannot be relied on to hand `--tools` an
77
+ * empty value.
78
+ */
79
+ export function claudeSupportsVenueSessions(helpText, platform = process.platform) {
80
+ if (platform === 'win32')
81
+ return false;
82
+ return VENUE_FLAGS.every((flag) => new RegExp(`(^|\\s)${flag.replace(/-/g, '\\-')}(\\s|,|$)`, 'm').test(helpText));
83
+ }
84
+ /** An empty MCP config, inline: there is no file another run could rewrite under us. */
85
+ const EMPTY_MCP_CONFIG = '{"mcpServers":{}}';
86
+ /**
87
+ * The Claude Code command a venue run is answered with.
88
+ *
89
+ * Built from the operator's binary and model only — never the rest of their
90
+ * `--exec` string, whose flags (`--add-dir`, `--mcp-config`, `--allowedTools`,
91
+ * `--dangerously-skip-permissions`) are exactly what a venue session must not
92
+ * get.
93
+ */
94
+ export function claudeVenueCommand(exec, model, platform = process.platform) {
95
+ const quote = (value) => shellQuote(value, platform);
96
+ const binary = exec.trim().split(/\s+/)[0] ?? 'claude';
97
+ const parts = [binary, '-p'];
98
+ if (model)
99
+ parts.push('--model', quote(model));
100
+ parts.push('--output-format', 'stream-json', '--verbose', '--no-session-persistence', '--safe-mode', '--setting-sources', quote(''), '--settings', quote('{}'), '--tools', quote(''),
101
+ // Last: `--mcp-config` is variadic and would swallow anything after it
102
+ // that is not itself a flag.
103
+ '--strict-mcp-config', '--mcp-config', quote(EMPTY_MCP_CONFIG));
104
+ return parts.join(' ');
105
+ }
106
+ /** Variables a venue session keeps by name: what a shell and the TLS stack need. */
107
+ const VENUE_ENV_NAMES = new Set([
108
+ 'PATH',
109
+ 'HOME',
110
+ 'USER',
111
+ 'LOGNAME',
112
+ 'SHELL',
113
+ 'LANG',
114
+ 'TERM',
115
+ 'TMPDIR',
116
+ 'TZ',
117
+ 'NODE_EXTRA_CA_CERTS',
118
+ 'SSL_CERT_FILE',
119
+ 'SSL_CERT_DIR',
120
+ 'HTTPS_PROXY',
121
+ 'HTTP_PROXY',
122
+ 'NO_PROXY',
123
+ 'https_proxy',
124
+ 'http_proxy',
125
+ 'no_proxy',
126
+ ]);
127
+ /**
128
+ * The environment a venue session's child gets, built up rather than pared
129
+ * down: the shell basics above, the locale, and Claude Code's own login and
130
+ * configuration (`CLAUDE_*`, `ANTHROPIC_*` — the brain cannot start without
131
+ * them). Everything else is dropped — ProhostAI's variables first among them,
132
+ * but also every other credential the operator's environment happens to hold.
133
+ *
134
+ * `HOME` stays real: Claude Code finds its login through it, and a session
135
+ * with no tools cannot read anything there.
136
+ */
137
+ export function venueEnv(base) {
138
+ const env = {};
139
+ for (const [key, value] of Object.entries(base)) {
140
+ if (value === undefined || /PROHOST/i.test(key))
141
+ continue;
142
+ if (VENUE_ENV_NAMES.has(key) || key.startsWith('LC_') || /^(CLAUDE|ANTHROPIC)_/.test(key))
143
+ env[key] = value;
144
+ }
145
+ return env;
146
+ }
147
+ /** A fresh empty directory for one venue session, and its removal. */
148
+ export function venueWorkdir() {
149
+ const dir = mkdtempSync(path.join(os.tmpdir(), 'prohost-venue-'));
150
+ return {
151
+ dir,
152
+ remove: () => {
153
+ try {
154
+ rmSync(dir, { recursive: true, force: true });
155
+ }
156
+ catch {
157
+ // Best effort: an empty temp directory left behind costs nothing.
158
+ }
159
+ },
160
+ };
161
+ }
162
+ /**
163
+ * The `/ws/webhooks` contract for venue sessions. Mirrors `VENUE_SESSION_*` in
164
+ * the server's `shared/agents/venue.py`: the feature `auth_ok` lists, the frame
165
+ * this harness sends to open one, and the frame it gets back.
166
+ */
167
+ export const VENUE_SESSION_FEATURE = 'venue_session';
168
+ export const VENUE_SESSION_OPEN_FRAME = 'venue_session_open';
169
+ export const VENUE_SESSION_FRAME = 'venue_session';
170
+ /**
171
+ * The run as its venue session answered it, with the thread and the token.
172
+ *
173
+ * The session is opened over this harness's own socket and nowhere else — the
174
+ * server keeps no HTTP route to it, so a process that merely holds this
175
+ * machine's key (an ordinary agent session) cannot ask for one the way the
176
+ * harness does. The token is attached to the returned run and goes nowhere
177
+ * else: no error here repeats the answer.
178
+ */
179
+ export function venueRunFromSession(run, data, answer, clock = {}) {
180
+ if (answer.ok !== true)
181
+ return { ok: false, error: 'the server refused the venue session' };
182
+ const token = typeof answer.token === 'string' ? answer.token : '';
183
+ if (!token.startsWith(VENUE_RUN_TOKEN_PREFIX))
184
+ return { ok: false, error: 'the venue session carried no run token' };
185
+ const trigger = answer.trigger && typeof answer.trigger === 'object' ? answer.trigger : {};
186
+ const opened = parseRunRequest({
187
+ ...data,
188
+ trigger: { ...data.trigger, ...trigger },
189
+ recent_messages: Array.isArray(answer.recent_messages) ? answer.recent_messages : [],
190
+ });
191
+ if (opened === null || opened.run_id !== run.run_id) {
192
+ return { ok: false, error: 'the venue session did not match the run' };
193
+ }
194
+ const lifetime = sessionLifetimeMs(answer, clock.wallNow);
195
+ if (lifetime === undefined)
196
+ return { ok: false, error: 'the venue session carried no expiry' };
197
+ const withGrant = {
198
+ ...opened,
199
+ venue_run_token: token,
200
+ venue_deadline_ms: (clock.openedAtMono ?? performance.now()) + lifetime,
201
+ venue_wall_deadline_ms: (clock.openedAtWall ?? Date.now()) + lifetime,
202
+ };
203
+ if (!venueGrantLive(withGrant, clock.nowMono, clock.wallNow)) {
204
+ return { ok: false, error: 'the venue session had already expired' };
205
+ }
206
+ return { ok: true, run: withGrant };
207
+ }
208
+ /**
209
+ * How long the grant lasts from when the session was asked for, or
210
+ * `undefined` for an answer that states none.
211
+ *
212
+ * The server's remaining lifetime (`expires_in_seconds`) is counted from when
213
+ * the session was asked for — never later than the server started counting —
214
+ * so neither a skewed wall clock nor the round trip can lengthen the grant.
215
+ * `expires_at` is the fallback for a server that sends only that, and the one
216
+ * place the wall clock's reading is trusted.
217
+ */
218
+ function sessionLifetimeMs(answer, wallNow = Date.now()) {
219
+ const remaining = answer.expires_in_seconds;
220
+ if (typeof remaining === 'number' && Number.isFinite(remaining))
221
+ return Math.max(0, remaining) * 1000;
222
+ const expiresAt = typeof answer.expires_at === 'string' ? Date.parse(answer.expires_at) : Number.NaN;
223
+ if (!Number.isFinite(expiresAt))
224
+ return undefined;
225
+ return expiresAt - wallNow;
226
+ }
227
+ /**
228
+ * How long before its deadline a venue grant already counts as over: room to
229
+ * close the run with its token while the token still works.
230
+ */
231
+ export const VENUE_EXPIRY_MARGIN_MS = 30_000;
232
+ /**
233
+ * How often a running venue run's grant is re-checked: the longest a run can
234
+ * outlive its grant after the machine wakes from a sleep.
235
+ */
236
+ export const VENUE_GRANT_CHECK_MS = 15_000;
237
+ /** The completion error of a venue run whose grant ran out before it started. */
238
+ export const VENUE_GRANT_EXPIRED_ERROR = 'connected-team grant expired before the run started';
239
+ /** The completion error of a venue run stopped because its grant was ending. */
240
+ export const VENUE_GRANT_ENDED_ERROR = 'connected-team grant expired while the run was working';
241
+ /**
242
+ * How much of a venue run's grant is left, in milliseconds — negative once it
243
+ * is over, and `-Infinity` for a run that carries no grant.
244
+ *
245
+ * The lifetime is counted on both clocks and the shorter one wins: the
246
+ * monotonic clock cannot be wound back, and the wall clock keeps counting
247
+ * while the machine sleeps (Linux's monotonic clock does not), so neither a
248
+ * changed clock nor a suspend outlasts the token. Both count elapsed time from
249
+ * the same moment, so a skewed wall clock still cancels out.
250
+ */
251
+ export function venueGrantRemainingMs(run, nowMono = performance.now(), wallNow = Date.now()) {
252
+ if (run.venue_deadline_ms === undefined || run.venue_wall_deadline_ms === undefined)
253
+ return -Infinity;
254
+ return Math.min(run.venue_deadline_ms - nowMono, run.venue_wall_deadline_ms - wallNow);
255
+ }
256
+ /**
257
+ * Whether a venue run's grant is still good — checked when its session opens
258
+ * and again right before the agent is started, so a run that waited in the
259
+ * queue past its grant never starts.
260
+ */
261
+ export function venueGrantLive(run, nowMono = performance.now(), wallNow = Date.now()) {
262
+ return venueGrantRemainingMs(run, nowMono, wallNow) > VENUE_EXPIRY_MARGIN_MS;
263
+ }
264
+ /**
265
+ * What a venue run reports about itself while it works and when it fails.
266
+ *
267
+ * The run's progress line and failure detail land on its row in this agent's
268
+ * home workspace. A venue run's would be the agent's words about the
269
+ * connected team's thread — or the thread itself, quoted — so it reports a
270
+ * fixed line instead.
271
+ */
272
+ export const VENUE_PROGRESS = "answering in a connected team's thread";
package/dist/version.d.ts CHANGED
@@ -7,6 +7,6 @@
7
7
  * `package.json`, so a release bump that forgets this file fails the suite
8
8
  * instead of shipping a `User-Agent` that lies about which build is calling.
9
9
  */
10
- export declare const CLI_VERSION = "0.12.4";
10
+ export declare const CLI_VERSION = "0.13.1";
11
11
  /** Sent on every HTTP request the CLI makes back into ProhostAI. */
12
- export declare const USER_AGENT = "prohost-cli/0.12.4";
12
+ export declare const USER_AGENT = "prohost-cli/0.13.1";
package/dist/version.js CHANGED
@@ -7,6 +7,6 @@
7
7
  * `package.json`, so a release bump that forgets this file fails the suite
8
8
  * instead of shipping a `User-Agent` that lies about which build is calling.
9
9
  */
10
- export const CLI_VERSION = '0.12.4';
10
+ export const CLI_VERSION = '0.13.1';
11
11
  /** Sent on every HTTP request the CLI makes back into ProhostAI. */
12
12
  export const USER_AGENT = `prohost-cli/${CLI_VERSION}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prohost/cli",
3
- "version": "0.12.4",
3
+ "version": "0.13.1",
4
4
  "description": "Run your own AI agent as a ProhostAI teammate, and stream your account's webhooks to your laptop.",
5
5
  "type": "module",
6
6
  "license": "MIT",