@prohost/cli 0.8.0 → 0.8.2

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/CHANGELOG.md CHANGED
@@ -4,6 +4,41 @@ Versions follow [semver](https://semver.org/). Publishing is automated: merging
4
4
  a version bump to `main` triggers `.github/workflows/npm-publish-cli.yml`, which
5
5
  builds via `prepack`, runs the suite, publishes, and tags `cli-v<version>`.
6
6
 
7
+ ## 0.8.2
8
+
9
+ A ProhostAI back-office agent is told its cross-account reads are allowed.
10
+
11
+ - **Back-office read tools change the credential sentence.** Before each run
12
+ whose ProhostAI tools are wired, the harness asks the MCP server's own
13
+ `tools/list` (cached 10 minutes; a failure reads as "absent" and is retried
14
+ after a minute). When it lists both `backoffice_describe_readonly_schema` and
15
+ `backoffice_query_readonly` — shown only to an agent-bound key on ProhostAI's
16
+ internal account holding `backoffice:read` — and a read-only call to the
17
+ schema tool goes through (its rollout flag is enforced only at call time),
18
+ the prompt replaces "your
19
+ credential is deliberately narrow" with: read-only cross-account
20
+ investigation is pre-authorized, look before answering (schema, then a query
21
+ filtered to the customer's account), never ask a human before a read-only
22
+ query, writes and customer-facing sends still follow approval discipline,
23
+ and summarize rather than paste rows. Ungated runs are also told that
24
+ read-only tools on the machine (operator-added MCP servers, CLIs) serve the
25
+ same purpose. Every other agent's prompt is byte-for-byte unchanged.
26
+
27
+ ## 0.8.1
28
+
29
+ A long message no longer reaches a paired agent as a fragment it can't recover.
30
+
31
+ - **Clipped trigger text is called out.** When the server reports that the
32
+ message that woke the agent was clipped (`trigger.text_truncated: true`, new
33
+ in the run event), the prompt says so and, when the agent has ProhostAI tools
34
+ and a conversation, tells it to read the full message with
35
+ `get_conversation_messages` before answering. An agent without tools is told
36
+ to say the message reached it truncated instead of answering the fragment.
37
+ Keyed on the explicit flag, never on a trailing `…` a person could have typed;
38
+ a server that predates the flag reads as "not clipped". Pairs with the server raising the excerpt
39
+ cap from 500 to 16,000 characters and returning full message bodies from
40
+ `get_conversation_messages`, so this path is now rare.
41
+
7
42
  ## 0.8.0
8
43
 
9
44
  A paired agent woken as a bystander can now stay silent.
package/README.md CHANGED
@@ -172,6 +172,12 @@ reservations or listings — those tools return a permission error. The prompt
172
172
  tells the agent to say what it couldn't reach rather than answer as if it had,
173
173
  and refused tools are printed in the run log.
174
174
 
175
+ The one exception is a ProhostAI back-office agent. Before a run, the CLI asks
176
+ the MCP server's `tools/list` (cached for ten minutes). If the list includes the
177
+ back-office read tools, which only an internal key with `backoffice:read` sees,
178
+ and a read-only call to the schema tool is allowed, the prompt tells the agent that read-only cross-account investigation is
179
+ pre-authorized. Writes and customer-facing sends still go through approval.
180
+
175
181
  **It reads the reply out of JSON.** The run is invoked with
176
182
  `--output-format json`, and the `result` field is what gets posted. If that
177
183
  output isn't JSON — a login prompt, a crash banner — the run is reported failed
@@ -0,0 +1,59 @@
1
+ /**
2
+ * What the paired credential can reach, as far as the prompt needs to know.
3
+ *
4
+ * Today that is one question: does this agent hold ProhostAI's back-office
5
+ * read tools (`backoffice_describe_readonly_schema` + `backoffice_query_readonly`)?
6
+ * The answer changes what the prompt says — an agent told its credential is
7
+ * "deliberately narrow" refuses or hedges on exactly the cross-account
8
+ * investigations those tools exist for.
9
+ *
10
+ * Nothing the CLI stores can answer it. The pairing response carries no scopes,
11
+ * and the gate is not a scope alone: the server shows the tools only to an
12
+ * agent-bound key on ProhostAI's internal account, holding the literal
13
+ * `backoffice:read` scope, with a flag on — any of which can change after
14
+ * pairing. So the server is asked: `tools/list` first, and — because its
15
+ * visibility check leaves out the rollout flag, which is enforced only when a
16
+ * tool is called — then the read-only, side-effect-free
17
+ * `backoffice_describe_readonly_schema`, which runs the whole gate. Two small
18
+ * requests, cached, and every failure reads as "absent": the prompt then says
19
+ * what it has always said.
20
+ */
21
+ /** Both have to be listed — the schema call is what makes the query usable. */
22
+ export declare const BACKOFFICE_READ_TOOLS: readonly ["backoffice_describe_readonly_schema", "backoffice_query_readonly"];
23
+ export interface RunCapabilities {
24
+ /** The back-office read tools are in this credential's `tools/list`. */
25
+ backofficeRead: boolean;
26
+ }
27
+ export declare const NO_CAPABILITIES: RunCapabilities;
28
+ /** Short: a run waits on this before its agent starts. */
29
+ export declare const CAPABILITY_PROBE_TIMEOUT_MS = 5000;
30
+ /** How long an answer is reused. A grant or revoke shows up within this. */
31
+ export declare const CAPABILITY_CACHE_MS: number;
32
+ /** How long a failed probe is reused, so an outage costs one timeout a minute, not one per run. */
33
+ export declare const CAPABILITY_FAILURE_CACHE_MS = 60000;
34
+ export interface ToolListOptions {
35
+ mcpUrl: string;
36
+ apiKey: string;
37
+ fetchImpl?: typeof fetch;
38
+ timeoutMs?: number;
39
+ }
40
+ /** The tool names the server lists for this key, or `null` when it could not be asked. */
41
+ export declare function listMcpToolNames(options: ToolListOptions): Promise<string[] | null>;
42
+ /**
43
+ * Whether a back-office read actually goes through for this key: `true` when
44
+ * the schema call answers with its schema, `false` when the server refuses it
45
+ * (`backoffice_forbidden` — e.g. the rollout flag is off), `null` when it could
46
+ * not be asked.
47
+ */
48
+ export declare function backofficeReadAllowed(options: ToolListOptions): Promise<boolean | null>;
49
+ export declare function capabilitiesFromToolNames(names: readonly string[]): RunCapabilities;
50
+ /**
51
+ * A cached `tools/list` probe for one daemon's credential.
52
+ *
53
+ * A daemon is long-lived, so the answer is re-asked every
54
+ * {@link CAPABILITY_CACHE_MS} rather than fixed at start-up: a scope granted or
55
+ * revoked on the server reaches the prompt without a restart.
56
+ */
57
+ export declare function capabilityProbe(options: ToolListOptions & {
58
+ now?: () => number;
59
+ }): () => Promise<RunCapabilities>;
@@ -0,0 +1,158 @@
1
+ /**
2
+ * What the paired credential can reach, as far as the prompt needs to know.
3
+ *
4
+ * Today that is one question: does this agent hold ProhostAI's back-office
5
+ * read tools (`backoffice_describe_readonly_schema` + `backoffice_query_readonly`)?
6
+ * The answer changes what the prompt says — an agent told its credential is
7
+ * "deliberately narrow" refuses or hedges on exactly the cross-account
8
+ * investigations those tools exist for.
9
+ *
10
+ * Nothing the CLI stores can answer it. The pairing response carries no scopes,
11
+ * and the gate is not a scope alone: the server shows the tools only to an
12
+ * agent-bound key on ProhostAI's internal account, holding the literal
13
+ * `backoffice:read` scope, with a flag on — any of which can change after
14
+ * pairing. So the server is asked: `tools/list` first, and — because its
15
+ * visibility check leaves out the rollout flag, which is enforced only when a
16
+ * tool is called — then the read-only, side-effect-free
17
+ * `backoffice_describe_readonly_schema`, which runs the whole gate. Two small
18
+ * requests, cached, and every failure reads as "absent": the prompt then says
19
+ * what it has always said.
20
+ */
21
+ import { USER_AGENT } from '../version.js';
22
+ /** Both have to be listed — the schema call is what makes the query usable. */
23
+ export const BACKOFFICE_READ_TOOLS = ['backoffice_describe_readonly_schema', 'backoffice_query_readonly'];
24
+ export const NO_CAPABILITIES = { backofficeRead: false };
25
+ /** Short: a run waits on this before its agent starts. */
26
+ export const CAPABILITY_PROBE_TIMEOUT_MS = 5_000;
27
+ /** How long an answer is reused. A grant or revoke shows up within this. */
28
+ export const CAPABILITY_CACHE_MS = 10 * 60_000;
29
+ /** How long a failed probe is reused, so an outage costs one timeout a minute, not one per run. */
30
+ export const CAPABILITY_FAILURE_CACHE_MS = 60_000;
31
+ /** Cap on the body read — a full catalog is well under this. */
32
+ const MAX_BODY_CHARS = 2_000_000;
33
+ /**
34
+ * Pull the JSON-RPC result out of a response that may be plain JSON or a
35
+ * streamable-HTTP SSE stream (`data: {...}` lines). `undefined` when neither
36
+ * shape holds a result.
37
+ */
38
+ function jsonRpcResult(body) {
39
+ const candidates = body.trimStart().startsWith('{')
40
+ ? [body]
41
+ : body
42
+ .split(/\r?\n/)
43
+ .filter((line) => line.startsWith('data:'))
44
+ .map((line) => line.slice('data:'.length).trim());
45
+ for (const candidate of candidates) {
46
+ try {
47
+ const parsed = JSON.parse(candidate);
48
+ if (parsed && typeof parsed.result === 'object' && parsed.result !== null) {
49
+ return parsed.result;
50
+ }
51
+ }
52
+ catch {
53
+ // Not JSON — keep looking.
54
+ }
55
+ }
56
+ return undefined;
57
+ }
58
+ /**
59
+ * One JSON-RPC request to the ProhostAI MCP server; its `result`, or `null`
60
+ * when it could not be asked (network, timeout, non-2xx, unparseable, error).
61
+ *
62
+ * Authenticates exactly as the brain's own MCP config does (`X-API-Key`), so
63
+ * the answer is what the agent itself will see. The server runs stateless
64
+ * HTTP, so no `initialize` round-trip is needed first.
65
+ */
66
+ async function mcpRequest(options, method, params) {
67
+ const fetchImpl = options.fetchImpl ?? fetch;
68
+ const controller = new AbortController();
69
+ const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? CAPABILITY_PROBE_TIMEOUT_MS);
70
+ try {
71
+ const response = await fetchImpl(options.mcpUrl, {
72
+ method: 'POST',
73
+ headers: {
74
+ 'Content-Type': 'application/json',
75
+ Accept: 'application/json, text/event-stream',
76
+ 'X-API-Key': options.apiKey,
77
+ 'User-Agent': USER_AGENT,
78
+ },
79
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
80
+ signal: controller.signal,
81
+ });
82
+ if (response.status < 200 || response.status >= 300)
83
+ return null;
84
+ return jsonRpcResult((await response.text()).slice(0, MAX_BODY_CHARS)) ?? null;
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ finally {
90
+ clearTimeout(timer);
91
+ }
92
+ }
93
+ /** The tool names the server lists for this key, or `null` when it could not be asked. */
94
+ export async function listMcpToolNames(options) {
95
+ const tools = (await mcpRequest(options, 'tools/list', {}))?.tools;
96
+ if (!Array.isArray(tools))
97
+ return null;
98
+ return tools
99
+ .map((tool) => (tool && typeof tool === 'object' ? tool.name : undefined))
100
+ .filter((name) => typeof name === 'string');
101
+ }
102
+ /**
103
+ * Whether a back-office read actually goes through for this key: `true` when
104
+ * the schema call answers with its schema, `false` when the server refuses it
105
+ * (`backoffice_forbidden` — e.g. the rollout flag is off), `null` when it could
106
+ * not be asked.
107
+ */
108
+ export async function backofficeReadAllowed(options) {
109
+ const result = await mcpRequest(options, 'tools/call', {
110
+ name: 'backoffice_describe_readonly_schema',
111
+ arguments: {},
112
+ });
113
+ if (!result)
114
+ return null;
115
+ if (result.isError === true)
116
+ return false;
117
+ const content = Array.isArray(result.content) ? result.content : [];
118
+ const text = content
119
+ .map((part) => (part && typeof part === 'object' ? part.text : undefined))
120
+ .filter((part) => typeof part === 'string')
121
+ .join('');
122
+ try {
123
+ const parsed = JSON.parse(text);
124
+ return parsed.error === undefined && parsed.tables !== undefined;
125
+ }
126
+ catch {
127
+ return false;
128
+ }
129
+ }
130
+ export function capabilitiesFromToolNames(names) {
131
+ return { backofficeRead: BACKOFFICE_READ_TOOLS.every((tool) => names.includes(tool)) };
132
+ }
133
+ /**
134
+ * A cached `tools/list` probe for one daemon's credential.
135
+ *
136
+ * A daemon is long-lived, so the answer is re-asked every
137
+ * {@link CAPABILITY_CACHE_MS} rather than fixed at start-up: a scope granted or
138
+ * revoked on the server reaches the prompt without a restart.
139
+ */
140
+ export function capabilityProbe(options) {
141
+ const now = options.now ?? Date.now;
142
+ let cached;
143
+ return async () => {
144
+ if (cached && now() < cached.until)
145
+ return cached.value;
146
+ const names = await listMcpToolNames(options);
147
+ let value = names ? capabilitiesFromToolNames(names) : NO_CAPABILITIES;
148
+ let answered = names !== null;
149
+ if (value.backofficeRead) {
150
+ // Listed is not the same as allowed: confirm the gate end to end.
151
+ const allowed = await backofficeReadAllowed(options);
152
+ answered = allowed !== null;
153
+ value = { backofficeRead: allowed === true };
154
+ }
155
+ cached = { value, until: now() + (answered ? CAPABILITY_CACHE_MS : CAPABILITY_FAILURE_CACHE_MS) };
156
+ return value;
157
+ };
158
+ }
@@ -235,6 +235,12 @@ export interface AgentRunRequest {
235
235
  trigger_message_id?: string;
236
236
  /** Capped inline excerpt of the message that woke the agent. */
237
237
  trigger_text?: string;
238
+ /**
239
+ * The server clipped `trigger_text` (`trigger.text_truncated`). Explicit
240
+ * metadata rather than a guess from a trailing ellipsis, which a person can
241
+ * also type. Absent on servers that predate it — read as "not clipped".
242
+ */
243
+ trigger_text_truncated?: boolean;
238
244
  /**
239
245
  * Images and files on the message that woke the agent.
240
246
  *
@@ -337,6 +337,8 @@ export function parseRunRequest(data) {
337
337
  trigger_source: str(trigger.source) ?? str(data.trigger_source),
338
338
  trigger_message_id: str(trigger.message_id),
339
339
  trigger_text: str(trigger.text_excerpt),
340
+ // Only an explicit `true` counts: anything else is an unclipped message.
341
+ trigger_text_truncated: trigger.text_truncated === true,
340
342
  trigger_attachments: attachmentList(trigger.attachments ?? data.trigger_attachments),
341
343
  trigger_user_id: str(trigger.user_id),
342
344
  trigger_brief: brief(trigger.brief),
@@ -30,6 +30,17 @@ export interface PromptContext {
30
30
  * to guess at it.
31
31
  */
32
32
  mcpToolPattern?: string;
33
+ /**
34
+ * The ProhostAI tools include the back-office read pair
35
+ * (`backoffice_describe_readonly_schema` → `backoffice_query_readonly`).
36
+ *
37
+ * Taken from the server's own `tools/list` for this key (see
38
+ * `capabilities.ts`), never assumed. It changes what the prompt says about
39
+ * the credential: an agent told its access is "deliberately narrow" refused
40
+ * or asked permission for exactly the cross-account reads these tools
41
+ * pre-authorize. Unset or false, the prompt is byte-for-byte what it was.
42
+ */
43
+ backofficeRead?: boolean;
33
44
  /**
34
45
  * Tools are behind permission prompts this run (`--safe-tools`).
35
46
  *
@@ -207,6 +207,23 @@ export function buildPrompt(run, context) {
207
207
  // The server caps this excerpt, so say so rather than let an agent assume
208
208
  // it has the whole message.
209
209
  lines.push('Message that woke you (may be truncated by the server):', run.trigger_text, '');
210
+ // An agent that is only told the text "may be" truncated answers the
211
+ // fragment — or asks the sender to repost — when the whole message is one
212
+ // tool call away. Keyed on the server's explicit flag, never on a trailing
213
+ // ellipsis a person could have typed.
214
+ if (run.trigger_text_truncated) {
215
+ lines.push(...(context.mcpServerName && run.conversation_id
216
+ ? [
217
+ 'ProhostAI cut that message short. Before answering, read it in full with',
218
+ `the ProhostAI get_conversation_messages tool (conversation ${run.conversation_id})`,
219
+ 'and answer the whole message, not the excerpt above.',
220
+ ]
221
+ : [
222
+ 'ProhostAI cut that message short, and you have no tool to read the rest.',
223
+ 'Answer what you can see and say plainly that the message reached you',
224
+ 'truncated.',
225
+ ]), '');
226
+ }
210
227
  }
211
228
  else if (triggerAttachments.length > 0) {
212
229
  // Distinct from "the server didn't send the text": here the message really
@@ -311,10 +328,13 @@ export function buildPrompt(run, context) {
311
328
  context.mcpToolPattern
312
329
  ? ` (${context.mcpToolPattern})`
313
330
  : `, from the MCP server registered as "${context.mcpServerName}"`}. They are the sanctioned ` +
314
- 'way to look up workspace data, so use them rather than guessing. Your credential is ' +
315
- 'deliberately narrow and does not reach every part of the workspace: if a tool returns ' +
316
- 'a permission error, that is a real limit rather than a glitch — say what you could not ' +
317
- 'look up instead of retrying it or answering as if you had.'
331
+ 'way to look up workspace data, so use them rather than guessing. ' +
332
+ (context.backofficeRead
333
+ ? backofficeGuidance(Boolean(context.toolsGated))
334
+ : 'Your credential is ' +
335
+ 'deliberately narrow and does not reach every part of the workspace: if a tool returns ' +
336
+ 'a permission error, that is a real limit rather than a glitch — say what you could not ' +
337
+ 'look up instead of retrying it or answering as if you had.')
318
338
  : '- You have no ProhostAI tools in this run. Everything you know about this ' +
319
339
  'workspace is what is written above.', '');
320
340
  // Postability is a separate question from what the run is about: a task run
@@ -334,6 +354,29 @@ export function buildPrompt(run, context) {
334
354
  : 'stdout is recorded but not posted anywhere — act through your own tools.');
335
355
  return `${lines.join('\n')}\n`;
336
356
  }
357
+ /**
358
+ * What replaces the "deliberately narrow" sentence for a back-office agent.
359
+ *
360
+ * Field-observed 2026-10-01: an internal support agent holding these tools
361
+ * answered "I couldn't read the workflow" and asked a human before a read-only
362
+ * query, because the only thing the prompt said about its access was that it
363
+ * was narrow. The read is pre-authorized, so the prompt says so — and keeps
364
+ * writes, customer-facing sends and personal data exactly as guarded as before.
365
+ */
366
+ function backofficeGuidance(toolsGated) {
367
+ return ('You are a ProhostAI back-office agent: read-only cross-account investigation is ' +
368
+ 'pre-authorized and expected. When a support or engineering question is about a ' +
369
+ 'specific customer account, look before you answer — backoffice_describe_readonly_schema ' +
370
+ 'for the tables, then backoffice_query_readonly filtered to that customer\'s account. ' +
371
+ 'Never ask a human for permission to run a read-only query. ' +
372
+ (toolsGated
373
+ ? ''
374
+ : 'Read-only investigation tools on this machine — MCP servers your operator added, ' +
375
+ 'CLIs such as `gh` — are usable for the same purpose. ') +
376
+ 'Writes and anything sent to a customer still follow approval discipline. Keep personal ' +
377
+ 'data and secrets out of your reply: summarize what you found, do not paste rows. If a ' +
378
+ 'tool returns a permission error, that is a real limit — say what you could not look up.');
379
+ }
337
380
  /**
338
381
  * Normalize an agent's stdout into a postable message.
339
382
  *
@@ -26,6 +26,7 @@ import type { spawn } from 'node:child_process';
26
26
  import WebSocket from 'ws';
27
27
  import type { CommandRunner } from './accounts.js';
28
28
  import type { AgentCredentials } from './credentials.js';
29
+ import type { RunCapabilities } from './capabilities.js';
29
30
  import type { QuotaProvider } from './runtime_status.js';
30
31
  /**
31
32
  * Default ceiling on one agent invocation: none.
@@ -144,6 +145,12 @@ export interface AgentRunOptions {
144
145
  * `codex login status`). Tests inject a fake so no real CLI is asked.
145
146
  */
146
147
  accountCommandRunner?: CommandRunner;
148
+ /**
149
+ * Asks what the paired credential can reach (see `capabilities.ts`).
150
+ * Defaults to a cached `tools/list` against the pairing's MCP endpoint; tests
151
+ * inject a fake so no extra request lands in their recorded calls.
152
+ */
153
+ capabilityProbe?: () => Promise<RunCapabilities>;
147
154
  }
148
155
  export interface AgentRunMetrics {
149
156
  connections: number;
package/dist/agent/run.js CHANGED
@@ -38,6 +38,7 @@ import { ensureWorkspace, streamUrlFor, workspacePath } from './credentials.js';
38
38
  import { execAgent } from './exec.js';
39
39
  import { HeartbeatLoop } from './heartbeat.js';
40
40
  import { buildPrompt, replyFromStdout } from './prompt.js';
41
+ import { NO_CAPABILITIES, capabilityProbe } from './capabilities.js';
41
42
  import { RunStore } from './runstore.js';
42
43
  import { RUNTIME_STATUS_FEATURE, RuntimeStatusReporter, claudeQuotaProvider, codexConfiguredModel, codexQuotaProvider, modelFromExec, parseVersion, readCodexObservation, } from './runtime_status.js';
43
44
  import { SessionStore, sessionKeyFor } from './sessionstore.js';
@@ -255,6 +256,7 @@ function buildRuntime(options, log) {
255
256
  brain,
256
257
  skipPermissions,
257
258
  prepareMcp: () => ({ mcpWired: false }),
259
+ capabilities: async () => NO_CAPABILITIES,
258
260
  runtimeName,
259
261
  observe,
260
262
  model,
@@ -336,6 +338,10 @@ function buildRuntime(options, log) {
336
338
  sessions,
337
339
  brain,
338
340
  prepareMcp: prepareWithAccount,
341
+ capabilities: options.capabilityProbe ??
342
+ (mcpUrl
343
+ ? capabilityProbe({ mcpUrl, apiKey: options.credentials.api_key, fetchImpl: options.fetchImpl })
344
+ : async () => NO_CAPABILITIES),
339
345
  skipPermissions,
340
346
  runtimeName,
341
347
  observe,
@@ -841,6 +847,8 @@ async function handleRun(run, options, runtime, api, log, sleep, control) {
841
847
  const surface = run.conversation_id ?? run.kind ?? 'no conversation';
842
848
  log(`${timestamp()} ▶ ${label} started (${surface})`);
843
849
  const mcp = runtime.prepareMcp();
850
+ // Only worth asking when the tools it describes are wired into this run.
851
+ const capabilities = mcp.mcpWired ? await runtime.capabilities() : NO_CAPABILITIES;
844
852
  const prompt = buildPrompt(run, {
845
853
  agentName: options.credentials.agent?.name ?? 'your agent',
846
854
  // Named only when the tools are actually reachable from this invocation.
@@ -852,6 +860,7 @@ async function handleRun(run, options, runtime, api, log, sleep, control) {
852
860
  // `plain` command is still told the server name only: we have no idea what
853
861
  // it is. See PromptContext.mcpToolPattern.
854
862
  mcpToolPattern: runtime.brain !== 'plain' && mcp.mcpWired ? MCP_TOOL_PATTERN : undefined,
863
+ backofficeRead: capabilities.backofficeRead,
855
864
  toolsGated: !runtime.skipPermissions,
856
865
  // The real numbers, not a vague "there is a limit" — see PromptContext.
857
866
  timeoutMs: options.timeoutMs ?? DEFAULT_EXEC_TIMEOUT_MS,
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.8.0";
10
+ export declare const CLI_VERSION = "0.8.2";
11
11
  /** Sent on every HTTP request the CLI makes back into ProhostAI. */
12
- export declare const USER_AGENT = "prohost-cli/0.8.0";
12
+ export declare const USER_AGENT = "prohost-cli/0.8.2";
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.8.0';
10
+ export const CLI_VERSION = '0.8.2';
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.8.0",
3
+ "version": "0.8.2",
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",