@astrosheep/square 0.4.0 → 0.4.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.
- package/dist/artifact.d.ts +1 -3
- package/dist/artifact.js +12 -36
- package/dist/attention-presentation.d.ts +2 -22
- package/dist/attention-presentation.js +9 -12
- package/dist/boundary-presentation.d.ts +3 -14
- package/dist/boundary-presentation.js +29 -104
- package/dist/card-presentation.d.ts +1 -0
- package/dist/card-presentation.js +2 -0
- package/dist/catch-decisions.js +1 -7
- package/dist/claude-delivery.d.ts +13 -8
- package/dist/claude-delivery.js +40 -93
- package/dist/claude-mcp-context.js +2 -2
- package/dist/claude-mod.js +28 -140
- package/dist/claude-transport.d.ts +3 -3
- package/dist/claude-transport.js +20 -44
- package/dist/cli/context.js +7 -9
- package/dist/cli/observation-commands.d.ts +2 -0
- package/dist/cli/observation-commands.js +12 -2
- package/dist/cli/registry.js +3 -1
- package/dist/codex-address.d.ts +2 -2
- package/dist/codex-boundary-state.d.ts +1 -5
- package/dist/codex-boundary-state.js +0 -4
- package/dist/codex-hook.d.ts +7 -10
- package/dist/codex-hook.js +69 -33
- package/dist/codex-queue.d.ts +10 -11
- package/dist/codex-queue.js +32 -32
- package/dist/codex-watch.d.ts +2 -0
- package/dist/codex-watch.js +100 -0
- package/dist/decisions.js +2 -2
- package/dist/delivery-deferral.d.ts +8 -17
- package/dist/delivery-deferral.js +0 -28
- package/dist/delivery-frame.d.ts +7 -0
- package/dist/delivery-frame.js +11 -0
- package/dist/delivery-ledger-sqlite.d.ts +97 -0
- package/dist/delivery-ledger-sqlite.js +496 -0
- package/dist/delivery-ledger.d.ts +196 -0
- package/dist/delivery-ledger.js +268 -0
- package/dist/delivery-lifetime.d.ts +6 -0
- package/dist/delivery-lifetime.js +45 -0
- package/dist/harness-links.js +61 -7
- package/dist/harness.js +12 -17
- package/dist/help.js +2 -0
- package/dist/http-delivery.d.ts +5 -9
- package/dist/http-delivery.js +20 -77
- package/dist/inbox.d.ts +6 -49
- package/dist/inbox.js +24 -371
- package/dist/index.d.ts +6 -3
- package/dist/index.js +4 -1
- package/dist/mcp.js +1 -1
- package/dist/model.d.ts +7 -47
- package/dist/model.js +1 -7
- package/dist/notifications.d.ts +24 -20
- package/dist/notifications.js +39 -108
- package/dist/operation-control.d.ts +4 -0
- package/dist/operation-control.js +20 -0
- package/dist/packages/agent-delivery/src/claude-native.d.ts +2 -0
- package/dist/packages/agent-delivery/src/claude-native.js +5 -0
- package/dist/packages/agent-delivery/src/codex-boundary.d.ts +11 -6
- package/dist/packages/agent-delivery/src/codex-boundary.js +31 -40
- package/dist/packages/agent-delivery/src/codex-hook.d.ts +17 -12
- package/dist/packages/agent-delivery/src/codex-hook.js +26 -39
- package/dist/packages/agent-delivery/src/codex.d.ts +3 -0
- package/dist/packages/agent-delivery/src/codex.js +41 -4
- package/dist/packages/agent-delivery/src/index.d.ts +3 -1
- package/dist/packages/agent-delivery/src/index.js +1 -1
- package/dist/packages/agent-delivery/src/paseo.js +11 -2
- package/dist/packages/agent-delivery/src/types.d.ts +1 -0
- package/dist/paseo-delivery.d.ts +5 -5
- package/dist/paseo-delivery.js +19 -97
- package/dist/paseo.d.ts +1 -1
- package/dist/paseo.js +1 -1
- package/dist/plugins/opencode/index.d.ts +5 -3
- package/dist/plugins/opencode/index.js +99 -21
- package/dist/plugins/opencode-shared/delivery.d.ts +23 -0
- package/dist/plugins/opencode-shared/delivery.js +109 -0
- package/dist/plugins/opencode-v1/index.d.ts +28 -0
- package/dist/plugins/opencode-v1/index.js +41 -0
- package/dist/plugins/opencode-v1/runtime.d.ts +56 -0
- package/dist/plugins/opencode-v1/runtime.js +152 -0
- package/dist/plugins/opencode-v1/transport.d.ts +13 -0
- package/dist/plugins/opencode-v1/transport.js +50 -0
- package/dist/plugins/paseo/shared/card-presentation.d.ts +10 -0
- package/dist/plugins/paseo/shared/card-presentation.js +7 -0
- package/dist/ports.d.ts +31 -90
- package/dist/session-lifecycle.d.ts +8 -7
- package/dist/session-lifecycle.js +40 -42
- package/dist/sqlite-square.d.ts +14 -23
- package/dist/sqlite-square.js +132 -139
- package/dist/square-api.js +4 -7
- package/dist/square-core.d.ts +0 -1
- package/dist/square-domain.d.ts +5 -17
- package/dist/square-domain.js +104 -221
- package/dist/square-facade.d.ts +18 -15
- package/dist/square-post.d.ts +53 -0
- package/dist/square-post.js +4 -0
- package/dist/square-posting.d.ts +13 -0
- package/dist/square-posting.js +174 -0
- package/dist/square-producer-sqlite.d.ts +11 -0
- package/dist/square-producer-sqlite.js +210 -0
- package/dist/square-sqlite.d.ts +15 -25
- package/dist/square-sqlite.js +150 -226
- package/dist/views.d.ts +2 -2
- package/dist/views.js +0 -1
- package/dist/wake-sink.d.ts +4 -11
- package/dist/wake-sink.js +8 -32
- package/dist/wake-transports.d.ts +4 -7
- package/dist/wake-transports.js +8 -39
- package/examples/symmetric-domains.mjs +29 -249
- package/guides/change-waits.md +13 -53
- package/guides/claude-native.md +19 -175
- package/guides/codex-delivery.md +55 -80
- package/guides/delivery-primitives.md +48 -207
- package/guides/operation-cancellation.md +2 -5
- package/guides/participant-ownership.md +25 -89
- package/guides/pi-native-delivery.md +19 -56
- package/guides/pi-tools.md +6 -8
- package/guides/square-api.md +113 -615
- package/package.json +8 -8
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/hooks/hooks.json +1 -1
- package/plugins/claude/{hooks/register.js → mods/square.js} +4 -7
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/hooks/hooks.json +11 -23
- package/plugins/opencode/index.ts +91 -23
- package/plugins/opencode-shared/delivery.ts +91 -0
- package/plugins/opencode-v1/index.ts +36 -0
- package/plugins/opencode-v1/runtime.ts +134 -0
- package/plugins/opencode-v1/transport.ts +41 -0
- package/plugins/paseo/OVERVIEW.md +5 -5
- package/plugins/paseo/README.md +7 -6
- package/plugins/paseo/client/markdown.tsx +5 -5
- package/plugins/paseo/client/square-message.tsx +28 -24
- package/plugins/paseo/client/transform.ts +8 -5
- package/plugins/paseo/shared/card-presentation.ts +16 -0
- package/plugins/paseo/shared/message.ts +6 -11
- package/plugins/pi/square-pi.js +156 -417
- package/dist/channel-artifact.d.ts +0 -10
- package/dist/channel-artifact.js +0 -55
- package/dist/channel-delivery.d.ts +0 -11
- package/dist/channel-delivery.js +0 -51
- package/dist/channel-domain.d.ts +0 -3
- package/dist/channel-domain.js +0 -83
- package/dist/channel-facade.d.ts +0 -76
- package/dist/channel-facade.js +0 -1
- package/dist/channel-internal.d.ts +0 -126
- package/dist/channel-internal.js +0 -440
- package/dist/channel-metadata.d.ts +0 -11
- package/dist/channel-metadata.js +0 -1
- package/dist/channel-ports.d.ts +0 -241
- package/dist/channel-ports.js +0 -1
- package/dist/channel-presentation.d.ts +0 -17
- package/dist/channel-presentation.js +0 -22
- package/dist/channel-sqlite-schema.d.ts +0 -13
- package/dist/channel-sqlite-schema.js +0 -81
- package/dist/channel-transport.d.ts +0 -62
- package/dist/channel-transport.js +0 -1
- package/dist/channel.d.ts +0 -84
- package/dist/channel.js +0 -60
- package/dist/claude-delivery-status.d.ts +0 -13
- package/dist/claude-delivery-status.js +0 -46
- package/dist/cmd/notify-once.d.ts +0 -2
- package/dist/cmd/notify-once.js +0 -29
- package/dist/delivery-attempts.d.ts +0 -52
- package/dist/delivery-attempts.js +0 -73
- package/dist/delivery-effects.d.ts +0 -139
- package/dist/delivery-effects.js +0 -163
- package/dist/delivery-health.d.ts +0 -51
- package/dist/delivery-health.js +0 -173
- package/dist/delivery-operations.d.ts +0 -22
- package/dist/delivery-operations.js +0 -198
- package/dist/delivery-primitives.d.ts +0 -5
- package/dist/delivery-primitives.js +0 -3
- package/dist/delivery.d.ts +0 -56
- package/dist/delivery.js +0 -80
- package/dist/plugins/opencode/delivery.d.ts +0 -19
- package/dist/plugins/opencode/delivery.js +0 -223
- package/dist/presentation-operations.d.ts +0 -5
- package/dist/presentation-operations.js +0 -86
- package/dist/sqlite-channel.d.ts +0 -15
- package/dist/sqlite-channel.js +0 -600
- package/dist/square-index.d.ts +0 -16
- package/dist/square-index.js +0 -106
- package/dist/wake-preview.d.ts +0 -7
- package/dist/wake-preview.js +0 -15
- package/plugins/opencode/delivery.ts +0 -198
- /package/dist/{channel-values.d.ts → square-values.d.ts} +0 -0
- /package/dist/{channel-values.js → square-values.js} +0 -0
package/dist/paseo-delivery.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DeliveryCard, DeliveryTransport, DeliveryTransportContext, TransportOutcome } from './delivery-ledger.js';
|
|
2
2
|
import { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
|
|
3
3
|
import { sendPaseoWake } from './wake-sink.js';
|
|
4
4
|
export interface PaseoWakeTransportOptions {
|
|
5
|
-
discover?:
|
|
5
|
+
discover?: typeof discoverPaseoAgents;
|
|
6
6
|
waitForBoundary?: typeof waitForPaseoWakeBoundary;
|
|
7
7
|
sendWake?: typeof sendPaseoWake;
|
|
8
8
|
}
|
|
9
|
-
export declare class PaseoWakeTransport implements
|
|
9
|
+
export declare class PaseoWakeTransport implements DeliveryTransport {
|
|
10
10
|
private readonly opts;
|
|
11
|
+
readonly kind = "paseo";
|
|
11
12
|
private discovering?;
|
|
12
13
|
constructor(opts?: PaseoWakeTransportOptions);
|
|
13
|
-
/** Coalesce overlapping inventory reads only; a later send must rediscover current status. */
|
|
14
14
|
private discover;
|
|
15
|
-
|
|
15
|
+
send(card: DeliveryCard, address: Readonly<Record<string, string>>, context: DeliveryTransportContext): Promise<TransportOutcome>;
|
|
16
16
|
}
|
package/dist/paseo-delivery.js
CHANGED
|
@@ -1,117 +1,39 @@
|
|
|
1
|
+
import { renderDeliveryReminder } from './delivery-frame.js';
|
|
1
2
|
import { DeliveryError } from './packages/agent-delivery/src/index.js';
|
|
2
|
-
import { resolvePaseoDaemon } from './packages/agent-delivery/src/paseo-native.js';
|
|
3
3
|
import { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
|
|
4
4
|
import { sendPaseoWake } from './wake-sink.js';
|
|
5
|
-
/** Every send failure is a DeliveryError; only its code and certainty decide retry. */
|
|
6
|
-
function diagnostic(phase, address, code) {
|
|
7
|
-
return {
|
|
8
|
-
phase,
|
|
9
|
-
code,
|
|
10
|
-
// Only discovery still runs a Paseo CLI; a wake is a capability call on the shared entry.
|
|
11
|
-
...(phase === 'discovery' ? { command: 'paseo ls --global --json' } : {}),
|
|
12
|
-
endpoint: resolvePaseoDaemon(undefined)?.url ?? 'unresolved',
|
|
13
|
-
paseoAgentIds: [address.agentId].filter(Boolean),
|
|
14
|
-
passwordPresent: Boolean(process.env.PASEO_PASSWORD),
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
5
|
export class PaseoWakeTransport {
|
|
18
6
|
opts;
|
|
7
|
+
kind = 'paseo';
|
|
19
8
|
discovering;
|
|
20
9
|
constructor(opts = {}) {
|
|
21
10
|
this.opts = opts;
|
|
22
11
|
}
|
|
23
|
-
/** Coalesce overlapping inventory reads only; a later send must rediscover current status. */
|
|
24
12
|
discover(timeoutMs) {
|
|
25
13
|
return this.discovering ??= Promise.resolve().then(() => (this.opts.discover ?? discoverPaseoAgents)(timeoutMs))
|
|
26
14
|
.finally(() => { this.discovering = undefined; });
|
|
27
15
|
}
|
|
28
|
-
async
|
|
29
|
-
const address = request.route.address;
|
|
30
|
-
const deadline = Date.now() + timeoutMs;
|
|
31
|
-
const remainingMs = () => Math.max(0, deadline - Date.now());
|
|
32
|
-
const budgetUnavailable = () => ({
|
|
33
|
-
outcome: 'failed',
|
|
34
|
-
signature: 'dispatch_budget_exhausted',
|
|
35
|
-
message: 'The wake dispatch budget elapsed before Paseo accepted the wake.',
|
|
36
|
-
});
|
|
16
|
+
async send(card, address, context) {
|
|
37
17
|
const agentId = address.agentId?.trim();
|
|
38
|
-
if (!agentId)
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
diagnostic: diagnostic('selection', address, 'invalid_address'),
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
const payload = request.presentation?.payload;
|
|
47
|
-
if (payload === undefined)
|
|
48
|
-
return { outcome: 'not-capable', diagnostic: 'No pending Square activity to preview.' };
|
|
49
|
-
let remaining = remainingMs();
|
|
50
|
-
if (remaining === 0)
|
|
51
|
-
return budgetUnavailable();
|
|
52
|
-
const discovery = await this.discover(remaining);
|
|
53
|
-
if (discovery.error && discovery.agents.length === 0) {
|
|
54
|
-
return {
|
|
55
|
-
outcome: 'failed',
|
|
56
|
-
// A credential or authorization refusal is proven; anything else may be transient.
|
|
57
|
-
signature: /password|auth|unauthori[sz]ed/i.test(discovery.error) ? 'discovery_rejected'
|
|
58
|
-
: /DAEMON_NOT_RUNNING|ECONNREFUSED|ENOENT|not found.*executable|ETIMEDOUT|timed out|timeout/i.test(discovery.error)
|
|
59
|
-
? 'discovery_transient' : 'discovery_rejected',
|
|
60
|
-
message: `Paseo unavailable: ${discovery.error}`,
|
|
61
|
-
diagnostic: diagnostic('discovery', address, 'unavailable'),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
const agent = discovery.agents.find((candidate) => candidate.id === agentId);
|
|
65
|
-
if (agent === undefined || agent.status !== 'idle') {
|
|
66
|
-
return {
|
|
67
|
-
outcome: 'failed',
|
|
68
|
-
signature: agent === undefined ? 'address_not_found' : 'agent_not_idle',
|
|
69
|
-
message: agent === undefined ? 'The registered Paseo agent was not found.' : 'The registered Paseo agent is not idle.',
|
|
70
|
-
diagnostic: diagnostic('selection', address, agent === undefined ? 'not_found' : 'not_idle'),
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
remaining = remainingMs();
|
|
74
|
-
if (remaining === 0)
|
|
75
|
-
return budgetUnavailable();
|
|
76
|
-
if (!(await (this.opts.waitForBoundary ?? waitForPaseoWakeBoundary)(agent, remaining))) {
|
|
77
|
-
return {
|
|
78
|
-
outcome: 'failed',
|
|
79
|
-
signature: 'boundary_unavailable',
|
|
80
|
-
message: 'Paseo did not reach the current tool boundary before the wake timeout.',
|
|
81
|
-
diagnostic: diagnostic('boundary', address, 'unavailable'),
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
if (!(await beforeSend()))
|
|
85
|
-
return { outcome: 'not-capable' };
|
|
86
|
-
remaining = remainingMs();
|
|
87
|
-
if (remaining === 0)
|
|
88
|
-
return budgetUnavailable();
|
|
18
|
+
if (!agentId)
|
|
19
|
+
return 'not-capable';
|
|
20
|
+
const remaining = () => Math.max(0, context.deadline - Date.now());
|
|
21
|
+
if (context.signal.aborted || !remaining())
|
|
22
|
+
return 'not-capable';
|
|
89
23
|
try {
|
|
90
|
-
await
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
24
|
+
const discovery = await this.discover(remaining());
|
|
25
|
+
const agent = discovery.agents.find(candidate => candidate.id === agentId);
|
|
26
|
+
if (!agent || agent.status !== 'idle' || !remaining())
|
|
27
|
+
return 'failed';
|
|
28
|
+
if (!await (this.opts.waitForBoundary ?? waitForPaseoWakeBoundary)(agent, remaining()))
|
|
29
|
+
return 'failed';
|
|
30
|
+
if (!await context.prepare({ messageId: context.token }) || context.signal.aborted || !remaining())
|
|
31
|
+
return 'not-capable';
|
|
32
|
+
await (this.opts.sendWake ?? sendPaseoWake)({ agentId, prompt: renderDeliveryReminder([card.text], { tagged: true }), messageId: context.token }, { timeoutMs: remaining(), beforeSend: context.beforeSend, signal: context.signal });
|
|
33
|
+
return 'accepted';
|
|
99
34
|
}
|
|
100
35
|
catch (error) {
|
|
101
|
-
|
|
102
|
-
const kind = !(error instanceof DeliveryError) || error.maybeDelivered ? 'unknown'
|
|
103
|
-
: error.code === 'unavailable' ? 'transient'
|
|
104
|
-
: ['authentication_failed', 'session_not_found', 'rejected', 'invalid_arguments'].includes(error.code) ? 'rejected'
|
|
105
|
-
: 'unknown';
|
|
106
|
-
const details = { ...diagnostic('send', address, 'failed'), outcome: kind };
|
|
107
|
-
if (kind === 'unknown')
|
|
108
|
-
return { outcome: 'unknown', signature: 'send_unknown', message, diagnostic: details };
|
|
109
|
-
return {
|
|
110
|
-
outcome: 'failed',
|
|
111
|
-
signature: kind === 'transient' ? 'send_pre_accept_transient' : 'send_pre_accept_rejected',
|
|
112
|
-
message,
|
|
113
|
-
diagnostic: details,
|
|
114
|
-
};
|
|
36
|
+
return error instanceof DeliveryError && !error.maybeDelivered ? 'failed' : 'unknown';
|
|
115
37
|
}
|
|
116
38
|
}
|
|
117
39
|
}
|
package/dist/paseo.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Optional Paseo integration. Importing this entry requires the Paseo peer dependencies. */
|
|
2
2
|
export { PaseoWakeTransport } from './paseo-delivery.js';
|
|
3
|
-
export {
|
|
3
|
+
export { sendPaseoWake } from './wake-sink.js';
|
|
4
4
|
export type { PaseoWakeRequest } from './wake-sink.js';
|
|
5
5
|
export { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
|
|
6
6
|
export type { PaseoAgent } from './paseo-state.js';
|
package/dist/paseo.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** Optional Paseo integration. Importing this entry requires the Paseo peer dependencies. */
|
|
2
2
|
export { PaseoWakeTransport } from './paseo-delivery.js';
|
|
3
|
-
export {
|
|
3
|
+
export { sendPaseoWake } from './wake-sink.js';
|
|
4
4
|
export { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type
|
|
1
|
+
import type { DeliveryTransport } from '../../delivery-ledger.js';
|
|
2
|
+
import { type OpenCodeNativeSession, type OpenCodeSessionCapability } from '../../packages/agent-delivery/src/opencode-native.js';
|
|
3
|
+
import { type OpenCodeContextMessage } from '../opencode-shared/delivery.js';
|
|
4
|
+
export declare function createOpenCodeWakeTransport(target: OpenCodeNativeSession, lifetime: AbortSignal): DeliveryTransport;
|
|
3
5
|
interface OpenCodePluginContext {
|
|
4
6
|
readonly app: {
|
|
5
7
|
readonly version: string;
|
|
@@ -32,7 +34,7 @@ interface OpenCodePluginContext {
|
|
|
32
34
|
}>;
|
|
33
35
|
};
|
|
34
36
|
}
|
|
35
|
-
/**
|
|
37
|
+
/** OpenCode v2 server plugin. Harness identity belongs to ctx, never process.env. */
|
|
36
38
|
declare const _default: {
|
|
37
39
|
id: string;
|
|
38
40
|
setup(ctx: OpenCodePluginContext): Promise<() => Promise<void>>;
|
|
@@ -1,17 +1,58 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { renderDeliveryReminder } from '../../delivery-frame.js';
|
|
2
3
|
import { canonicalPath } from '../../canonical-path.js';
|
|
3
|
-
import { connectNative } from '../../packages/agent-delivery/src/opencode-native.js';
|
|
4
|
-
import { cancelOpenCodeDeliveries, endOpenCodeSession,
|
|
5
|
-
|
|
4
|
+
import { connectNative, createNativeInputId, sendNativeText } from '../../packages/agent-delivery/src/opencode-native.js';
|
|
5
|
+
import { cancelOpenCodeDeliveries, currentOpenCodeGeneration, detachOpenCodeSession, endOpenCodeSession, listOpenCodeSessions, observeOpenCodeContext, observeOpenCodeSessions, publishOpenCodeAddress, receiveOpenCodePending } from '../opencode-shared/delivery.js';
|
|
6
|
+
const routeKind = 'opencode-server';
|
|
7
|
+
export function createOpenCodeWakeTransport(target, lifetime) {
|
|
8
|
+
return {
|
|
9
|
+
kind: routeKind,
|
|
10
|
+
async send(card, address, context) {
|
|
11
|
+
const signal = AbortSignal.any([lifetime, context.signal]);
|
|
12
|
+
if (address.sessionId !== target.sessionId || signal.aborted)
|
|
13
|
+
return 'not-capable';
|
|
14
|
+
const messageId = createNativeInputId();
|
|
15
|
+
const text = renderDeliveryReminder([card.text], { tagged: true });
|
|
16
|
+
const payloadHash = createHash('sha256').update(text).digest('hex');
|
|
17
|
+
if (!await context.prepare({ token: context.token, messageId, payloadHash }) || signal.aborted
|
|
18
|
+
|| !await context.beforeSend() || signal.aborted || Date.now() >= context.deadline)
|
|
19
|
+
return 'not-capable';
|
|
20
|
+
const result = await sendNativeText(target, text, {
|
|
21
|
+
inputId: messageId, delivery: 'steer', timeoutMs: Math.max(1, context.deadline - Date.now()), signal,
|
|
22
|
+
});
|
|
23
|
+
if (result.state === 'accepted')
|
|
24
|
+
return 'accepted';
|
|
25
|
+
if (result.state === 'unavailable')
|
|
26
|
+
return 'failed';
|
|
27
|
+
return 'unknown';
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** OpenCode v2 server plugin. Harness identity belongs to ctx, never process.env. */
|
|
6
32
|
export default {
|
|
7
33
|
id: 'square',
|
|
8
34
|
async setup(ctx) {
|
|
9
|
-
|
|
35
|
+
// OpenCode publishes semantic versions; unknown version forms are not evidence of a v2 host.
|
|
36
|
+
const version = ctx?.app?.version;
|
|
37
|
+
const reason = typeof version !== 'string' || !/^2\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(version)
|
|
38
|
+
? 'expected an OpenCode 2.x semantic version'
|
|
39
|
+
: typeof ctx.location?.directory !== 'string' || !ctx.location.directory ||
|
|
40
|
+
typeof ctx.location.project?.id !== 'string' || !ctx.location.project.id ||
|
|
41
|
+
(ctx.location.workspaceID !== undefined && typeof ctx.location.workspaceID !== 'string')
|
|
42
|
+
? 'missing location directory or project identity'
|
|
43
|
+
: typeof ctx.session?.hook !== 'function' || typeof ctx.session.get !== 'function' || typeof ctx.session.prompt !== 'function'
|
|
44
|
+
? 'missing session hook, get, or prompt capability'
|
|
45
|
+
: typeof ctx.event?.subscribe !== 'function' ? 'missing event subscription capability' : undefined;
|
|
46
|
+
if (reason) {
|
|
47
|
+
console.warn(`Square OpenCode plugin inactive: ${reason}.`);
|
|
10
48
|
return async () => { };
|
|
49
|
+
}
|
|
11
50
|
const env = { ...process.env };
|
|
12
|
-
const
|
|
51
|
+
const discovery = await observeOpenCodeSessions(env);
|
|
13
52
|
const lifetime = new AbortController();
|
|
14
53
|
const receivers = new Map(); // Operational handles only; presence owns membership.
|
|
54
|
+
const interrupting = new Set();
|
|
55
|
+
const cancellationFailed = new Set();
|
|
15
56
|
const directory = await canonicalPath(ctx.location.directory);
|
|
16
57
|
let coordinating = Promise.resolve();
|
|
17
58
|
const coordinate = (operation) => {
|
|
@@ -39,26 +80,37 @@ export default {
|
|
|
39
80
|
return target;
|
|
40
81
|
};
|
|
41
82
|
const reconcile = async (activeSession) => {
|
|
42
|
-
const candidates = new Set(await
|
|
83
|
+
const candidates = new Set(await listOpenCodeSessions(env));
|
|
43
84
|
if (activeSession)
|
|
44
85
|
candidates.add(activeSession);
|
|
45
86
|
for (const sessionId of candidates) {
|
|
46
87
|
if (lifetime.signal.aborted)
|
|
47
88
|
return;
|
|
89
|
+
if (interrupting.has(sessionId) || cancellationFailed.has(sessionId))
|
|
90
|
+
continue;
|
|
48
91
|
const target = await validate(sessionId);
|
|
49
92
|
if (!target) {
|
|
93
|
+
const receiver = receivers.get(sessionId);
|
|
50
94
|
stop(sessionId);
|
|
95
|
+
if (receiver)
|
|
96
|
+
await detachOpenCodeSession(sessionId, receiver.generation, env);
|
|
51
97
|
continue;
|
|
52
98
|
}
|
|
53
|
-
|
|
99
|
+
const existing = receivers.get(sessionId);
|
|
100
|
+
if (existing?.settled === false || interrupting.has(sessionId))
|
|
101
|
+
continue;
|
|
102
|
+
const generation = existing?.generation ?? await publishOpenCodeAddress(sessionId, env, lifetime.signal);
|
|
103
|
+
if (!generation) {
|
|
54
104
|
stop(sessionId);
|
|
55
105
|
continue;
|
|
56
106
|
}
|
|
57
|
-
if (
|
|
107
|
+
if (lifetime.signal.aborted || interrupting.has(sessionId)) {
|
|
108
|
+
await detachOpenCodeSession(sessionId, generation, env);
|
|
58
109
|
continue;
|
|
110
|
+
}
|
|
59
111
|
const abort = new AbortController();
|
|
60
112
|
const signal = AbortSignal.any([lifetime.signal, abort.signal]);
|
|
61
|
-
const receiver = { abort, settled: false, running: receiveOpenCodePending(target, env, signal).catch(() => { }).finally(() => { receiver.settled = true; }) };
|
|
113
|
+
const receiver = { abort, generation, settled: false, running: receiveOpenCodePending(sessionId, generation, createOpenCodeWakeTransport(target, signal), env, signal).catch(() => { }).finally(() => { receiver.settled = true; }) };
|
|
62
114
|
receivers.set(sessionId, receiver);
|
|
63
115
|
}
|
|
64
116
|
for (const sessionId of receivers.keys())
|
|
@@ -66,16 +118,31 @@ export default {
|
|
|
66
118
|
stop(sessionId);
|
|
67
119
|
};
|
|
68
120
|
const cancel = async (sessionId) => {
|
|
69
|
-
|
|
121
|
+
const receiver = receivers.get(sessionId);
|
|
122
|
+
if (!receiver)
|
|
70
123
|
return;
|
|
71
|
-
// Stop synchronously; persist the cutoff before allowing reconciliation to start fresh work.
|
|
72
124
|
stop(sessionId);
|
|
73
|
-
await
|
|
74
|
-
|
|
125
|
+
await receiver.running;
|
|
126
|
+
try {
|
|
127
|
+
if (!await cancelOpenCodeDeliveries(sessionId, receiver.generation, env))
|
|
128
|
+
throw new Error('OpenCode cancellation fence lost');
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
cancellationFailed.add(sessionId);
|
|
132
|
+
await detachOpenCodeSession(sessionId, receiver.generation, env).catch(() => { });
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
interrupting.delete(sessionId);
|
|
137
|
+
}
|
|
138
|
+
await reconcile(sessionId);
|
|
75
139
|
};
|
|
76
140
|
const end = async (sessionId) => {
|
|
141
|
+
const receiver = receivers.get(sessionId);
|
|
77
142
|
stop(sessionId);
|
|
78
|
-
await
|
|
143
|
+
const generation = receiver?.generation ?? await currentOpenCodeGeneration(sessionId, env);
|
|
144
|
+
if (generation)
|
|
145
|
+
await endOpenCodeSession(sessionId, generation, env);
|
|
79
146
|
};
|
|
80
147
|
await ctx.session.hook('prompt', (event) => coordinate(() => reconcile(event.sessionID)));
|
|
81
148
|
await ctx.session.hook('context', async (event) => {
|
|
@@ -83,13 +150,13 @@ export default {
|
|
|
83
150
|
const receiver = receivers.get(event.sessionID);
|
|
84
151
|
if (!receiver || lifetime.signal.aborted)
|
|
85
152
|
return;
|
|
86
|
-
await observeOpenCodeContext(event.sessionID, event.messages, env, AbortSignal.any([lifetime.signal, receiver.abort.signal])).catch(() => { });
|
|
153
|
+
await observeOpenCodeContext(event.sessionID, receiver.generation, event.messages, env, AbortSignal.any([lifetime.signal, receiver.abort.signal])).catch(() => { });
|
|
87
154
|
});
|
|
88
155
|
const presenceLoop = (async () => {
|
|
89
156
|
while (!lifetime.signal.aborted) {
|
|
90
|
-
const baseline =
|
|
157
|
+
const baseline = discovery.observer.generation;
|
|
91
158
|
await coordinate(() => reconcile());
|
|
92
|
-
await
|
|
159
|
+
await discovery.observer.hinted(baseline, 2000, lifetime.signal);
|
|
93
160
|
}
|
|
94
161
|
})().catch(() => { });
|
|
95
162
|
const eventLoop = (async () => {
|
|
@@ -100,8 +167,17 @@ export default {
|
|
|
100
167
|
if (event.type === 'session.deleted')
|
|
101
168
|
await coordinate(() => end(sessionId));
|
|
102
169
|
else if (event.type === 'session.moved')
|
|
103
|
-
await coordinate(async () => {
|
|
170
|
+
await coordinate(async () => {
|
|
171
|
+
const receiver = receivers.get(sessionId);
|
|
172
|
+
stop(sessionId);
|
|
173
|
+
if (receiver)
|
|
174
|
+
await detachOpenCodeSession(sessionId, receiver.generation, env);
|
|
175
|
+
await reconcile();
|
|
176
|
+
});
|
|
104
177
|
else if (event.type === 'session.execution.interrupted' && event.data.reason === 'user') {
|
|
178
|
+
if (interrupting.has(sessionId) || !receivers.has(sessionId))
|
|
179
|
+
continue;
|
|
180
|
+
interrupting.add(sessionId);
|
|
105
181
|
receivers.get(sessionId)?.abort.abort();
|
|
106
182
|
await coordinate(() => cancel(sessionId));
|
|
107
183
|
}
|
|
@@ -110,8 +186,8 @@ export default {
|
|
|
110
186
|
// Do not await any native prompt in setup: plugin activation itself is lazy.
|
|
111
187
|
return async () => {
|
|
112
188
|
lifetime.abort();
|
|
113
|
-
|
|
114
|
-
const tasks = [presenceLoop, eventLoop, coordinating, ...
|
|
189
|
+
const captured = [...receivers.entries()];
|
|
190
|
+
const tasks = [presenceLoop, eventLoop, coordinating, ...captured.map(([id]) => stop(id))];
|
|
115
191
|
let timer;
|
|
116
192
|
try {
|
|
117
193
|
await Promise.race([Promise.allSettled(tasks), new Promise((resolve) => { timer = setTimeout(resolve, 3000); })]);
|
|
@@ -120,6 +196,8 @@ export default {
|
|
|
120
196
|
if (timer !== undefined)
|
|
121
197
|
clearTimeout(timer);
|
|
122
198
|
}
|
|
199
|
+
await Promise.allSettled(captured.map(([id, receiver]) => detachOpenCodeSession(id, receiver.generation, env)));
|
|
200
|
+
await discovery.close();
|
|
123
201
|
// Instance unload is not session deletion: retain memberships and uncertain correlations.
|
|
124
202
|
};
|
|
125
203
|
},
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DeliveryTransport } from '../../delivery-ledger.js';
|
|
2
|
+
export interface OpenCodeContextMessage {
|
|
3
|
+
readonly id?: string;
|
|
4
|
+
readonly role: string;
|
|
5
|
+
readonly content: readonly {
|
|
6
|
+
readonly type: string;
|
|
7
|
+
readonly text?: string;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
export declare function listOpenCodeSessions(env: NodeJS.ProcessEnv): Promise<readonly string[]>;
|
|
11
|
+
/** The file observer is a hint; callers must always reread the ledger after an edge. */
|
|
12
|
+
export declare function observeOpenCodeSessions(env: NodeJS.ProcessEnv): Promise<{
|
|
13
|
+
observer: import("../../file-changes.js").VersionObserver<string>;
|
|
14
|
+
close: () => Promise<void>;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function publishOpenCodeAddress(sessionId: string, env: NodeJS.ProcessEnv, signal: AbortSignal): Promise<string | undefined>;
|
|
17
|
+
export declare function currentOpenCodeGeneration(sessionId: string, env: NodeJS.ProcessEnv): Promise<string | undefined>;
|
|
18
|
+
export declare function detachOpenCodeSession(sessionId: string, generation: string, env: NodeJS.ProcessEnv): Promise<void>;
|
|
19
|
+
export declare function endOpenCodeSession(sessionId: string, generation: string, env: NodeJS.ProcessEnv): Promise<void>;
|
|
20
|
+
export declare function cancelOpenCodeDeliveries(sessionId: string, generation: string, env: NodeJS.ProcessEnv): Promise<boolean>;
|
|
21
|
+
/** Confirmation is observer-level: another host plugin may subsequently remove the message. */
|
|
22
|
+
export declare function observeOpenCodeContext(sessionId: string, generation: string, messages: readonly OpenCodeContextMessage[], env: NodeJS.ProcessEnv, signal: AbortSignal): Promise<void>;
|
|
23
|
+
export declare function receiveOpenCodePending(sessionId: string, generation: string, transport: DeliveryTransport, env: NodeJS.ProcessEnv, signal: AbortSignal): Promise<void>;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { DeliveryLedger } from '../../delivery-ledger.js';
|
|
3
|
+
import { retainDeliveryLedger } from '../../delivery-lifetime.js';
|
|
4
|
+
import { harnessOwner, decodeHarnessOwner } from '../../owner.js';
|
|
5
|
+
import { attachDeliverySessionRoutes, detachDeliverySession, markDeliverySessionDeleted } from '../../session-lifecycle.js';
|
|
6
|
+
const routeKind = 'opencode-server';
|
|
7
|
+
const ownerFor = (sessionId) => harnessOwner({ channel: 'opencode', session: sessionId });
|
|
8
|
+
const open = (env) => DeliveryLedger.open(env.SQUARE_DELIVERY ? { location: env.SQUARE_DELIVERY } : {});
|
|
9
|
+
const payloadHash = (payload) => createHash('sha256').update(payload).digest('hex');
|
|
10
|
+
export async function listOpenCodeSessions(env) {
|
|
11
|
+
const ledger = await open(env);
|
|
12
|
+
try {
|
|
13
|
+
return (await ledger.sessions()).flatMap(session => {
|
|
14
|
+
const coordinate = decodeHarnessOwner(session.owner);
|
|
15
|
+
return session.state !== 'deleted' && coordinate?.channel === 'opencode' ? [coordinate.session] : [];
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
await ledger.close();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** The file observer is a hint; callers must always reread the ledger after an edge. */
|
|
23
|
+
export async function observeOpenCodeSessions(env) {
|
|
24
|
+
const ledger = await open(env);
|
|
25
|
+
const observer = await ledger.observe(ownerFor('discovery'));
|
|
26
|
+
return { observer, close: async () => { observer.close(); await ledger.close(); } };
|
|
27
|
+
}
|
|
28
|
+
export async function publishOpenCodeAddress(sessionId, env, signal) {
|
|
29
|
+
const session = await attachDeliverySessionRoutes(ownerFor(sessionId), env, [{ kind: routeKind, address: { sessionId } }], signal);
|
|
30
|
+
return session ? session.generation : undefined;
|
|
31
|
+
}
|
|
32
|
+
export async function currentOpenCodeGeneration(sessionId, env) {
|
|
33
|
+
const ledger = await open(env);
|
|
34
|
+
try {
|
|
35
|
+
return (await ledger.session(ownerFor(sessionId)))?.generation;
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
await ledger.close();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export async function detachOpenCodeSession(sessionId, generation, env) {
|
|
42
|
+
await detachDeliverySession(ownerFor(sessionId), generation, env);
|
|
43
|
+
}
|
|
44
|
+
export async function endOpenCodeSession(sessionId, generation, env) {
|
|
45
|
+
await markDeliverySessionDeleted(ownerFor(sessionId), generation, env);
|
|
46
|
+
}
|
|
47
|
+
export async function cancelOpenCodeDeliveries(sessionId, generation, env) {
|
|
48
|
+
const ledger = await open(env);
|
|
49
|
+
try {
|
|
50
|
+
return await ledger.cancel({ owner: ownerFor(sessionId), generation });
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
await ledger.close();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function textMessage(message) {
|
|
57
|
+
if (message.role !== 'user' || message.id === undefined || !message.content.every(part => part.type === 'text' && typeof part.text === 'string'))
|
|
58
|
+
return undefined;
|
|
59
|
+
return message.content.map(part => part.text).join('');
|
|
60
|
+
}
|
|
61
|
+
/** Confirmation is observer-level: another host plugin may subsequently remove the message. */
|
|
62
|
+
export async function observeOpenCodeContext(sessionId, generation, messages, env, signal) {
|
|
63
|
+
const observed = new Map(messages.flatMap(message => {
|
|
64
|
+
const text = textMessage(message);
|
|
65
|
+
return text === undefined ? [] : [[message.id, payloadHash(text)]];
|
|
66
|
+
}));
|
|
67
|
+
if (!observed.size || signal.aborted)
|
|
68
|
+
return;
|
|
69
|
+
const ledger = await open(env);
|
|
70
|
+
try {
|
|
71
|
+
for (const attempt of await ledger.handoffs(ownerFor(sessionId), { generation })) {
|
|
72
|
+
if (signal.aborted)
|
|
73
|
+
return;
|
|
74
|
+
const { correlation } = attempt;
|
|
75
|
+
if (attempt.routeKind === routeKind && correlation.token === attempt.token && correlation.messageId !== undefined
|
|
76
|
+
&& correlation.payloadHash !== undefined && observed.get(correlation.messageId) === correlation.payloadHash)
|
|
77
|
+
await ledger.observePresentation({ token: attempt.token, owner: ownerFor(sessionId), generation, routeKind, payloadHash: correlation.payloadHash }, { requireCurrent: true });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
await ledger.close();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export async function receiveOpenCodePending(sessionId, generation, transport, env, signal) {
|
|
85
|
+
const owner = ownerFor(sessionId);
|
|
86
|
+
const ledger = await open(env);
|
|
87
|
+
const lifetime = retainDeliveryLedger(ledger);
|
|
88
|
+
const observer = await ledger.observe(owner);
|
|
89
|
+
try {
|
|
90
|
+
while (!signal.aborted) {
|
|
91
|
+
const baseline = observer.generation;
|
|
92
|
+
for (const card of await ledger.pending(owner, { generation })) {
|
|
93
|
+
if (signal.aborted)
|
|
94
|
+
return;
|
|
95
|
+
lifetime.track(await ledger.dispatchHandoff(owner, card.key, transport, { generation, timeoutMs: 5000, signal }));
|
|
96
|
+
}
|
|
97
|
+
if (!signal.aborted)
|
|
98
|
+
await observer.hinted(baseline, 2000, signal);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (!signal.aborted)
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
observer.close();
|
|
107
|
+
await lifetime.close();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface LegacyContext {
|
|
2
|
+
readonly serverUrl: string | URL;
|
|
3
|
+
readonly directory: string;
|
|
4
|
+
readonly project: {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
};
|
|
7
|
+
readonly client: {
|
|
8
|
+
readonly session: {
|
|
9
|
+
get(input: unknown): Promise<{
|
|
10
|
+
data?: unknown;
|
|
11
|
+
error?: unknown;
|
|
12
|
+
}>;
|
|
13
|
+
promptAsync(input: unknown): Promise<{
|
|
14
|
+
error?: unknown;
|
|
15
|
+
response?: Response;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Legacy loader: no storage imports until the actual host and runtime qualify. */
|
|
21
|
+
export default function squareOpenCodeV1(ctx: LegacyContext): Promise<{
|
|
22
|
+
'shell.env': (input: {
|
|
23
|
+
sessionID?: string;
|
|
24
|
+
}, output: {
|
|
25
|
+
env: Record<string, string>;
|
|
26
|
+
}) => Promise<void>;
|
|
27
|
+
}>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Legacy loader: no storage imports until the actual host and runtime qualify. */
|
|
2
|
+
export default async function squareOpenCodeV1(ctx) {
|
|
3
|
+
const shell = async (input, output) => {
|
|
4
|
+
if (typeof input.sessionID === 'string' && input.sessionID)
|
|
5
|
+
output.env.OPENCODE_SESSION_ID = input.sessionID;
|
|
6
|
+
};
|
|
7
|
+
const reduced = { 'shell.env': shell };
|
|
8
|
+
try {
|
|
9
|
+
let response;
|
|
10
|
+
try {
|
|
11
|
+
response = await fetch(new URL('/global/health', ctx.serverUrl), { signal: AbortSignal.timeout(1500) });
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
throw new Error('health endpoint unreachable (embedded TUI may not expose it)');
|
|
15
|
+
}
|
|
16
|
+
if (!response.ok)
|
|
17
|
+
throw new Error(`health endpoint returned HTTP ${response.status} (embedded TUI may not expose it)`);
|
|
18
|
+
const health = await response.json();
|
|
19
|
+
const match = typeof health.version === 'string' && /^(\d+)\.(\d+)\.(\d+)$/.exec(health.version);
|
|
20
|
+
if (!match || Number(match[1]) !== 1 || Number(match[2]) < 15 || (Number(match[2]) === 15 && Number(match[3]) < 11))
|
|
21
|
+
throw new Error('native version below resident floor or unknown');
|
|
22
|
+
if (typeof ctx.client?.session?.get !== 'function' || typeof ctx.client.session.promptAsync !== 'function')
|
|
23
|
+
throw new Error('native session API unavailable');
|
|
24
|
+
const { DatabaseSync } = await import('node:sqlite');
|
|
25
|
+
const db = new DatabaseSync(':memory:');
|
|
26
|
+
try {
|
|
27
|
+
db.exec('CREATE TABLE capability (value TEXT)');
|
|
28
|
+
db.prepare('INSERT INTO capability VALUES (?)').run('ok');
|
|
29
|
+
db.prepare('SELECT value FROM capability').get();
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
db.close();
|
|
33
|
+
}
|
|
34
|
+
const { startReceiver } = await import('./runtime.js');
|
|
35
|
+
return { ...reduced, ...await startReceiver(ctx) };
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.warn(`[square] OpenCode 1.x reduced mode (no proactive delivery): ${error instanceof Error ? error.message : String(error)}`);
|
|
39
|
+
return reduced;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
interface Context {
|
|
2
|
+
readonly directory: string;
|
|
3
|
+
readonly project: {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
};
|
|
6
|
+
readonly client: {
|
|
7
|
+
readonly session: {
|
|
8
|
+
get(input: unknown): Promise<{
|
|
9
|
+
data?: unknown;
|
|
10
|
+
error?: unknown;
|
|
11
|
+
}>;
|
|
12
|
+
promptAsync(input: unknown): Promise<{
|
|
13
|
+
error?: unknown;
|
|
14
|
+
response?: Response;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
interface NativeMessage {
|
|
20
|
+
info?: {
|
|
21
|
+
id?: string;
|
|
22
|
+
sessionID?: string;
|
|
23
|
+
role?: string;
|
|
24
|
+
};
|
|
25
|
+
parts?: {
|
|
26
|
+
type?: string;
|
|
27
|
+
text?: string;
|
|
28
|
+
sessionID?: string;
|
|
29
|
+
messageID?: string;
|
|
30
|
+
synthetic?: boolean;
|
|
31
|
+
ignored?: boolean;
|
|
32
|
+
}[];
|
|
33
|
+
}
|
|
34
|
+
export declare function startReceiver(ctx: Context): Promise<{
|
|
35
|
+
'experimental.chat.messages.transform': (_input: unknown, output: {
|
|
36
|
+
messages: NativeMessage[];
|
|
37
|
+
}) => Promise<void>;
|
|
38
|
+
event: ({ event }: {
|
|
39
|
+
event: {
|
|
40
|
+
type: string;
|
|
41
|
+
properties?: {
|
|
42
|
+
sessionID?: string;
|
|
43
|
+
error?: {
|
|
44
|
+
name?: string;
|
|
45
|
+
};
|
|
46
|
+
info?: {
|
|
47
|
+
id?: string;
|
|
48
|
+
projectID?: string;
|
|
49
|
+
directory?: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
}) => Promise<void>;
|
|
54
|
+
dispose: () => Promise<void>;
|
|
55
|
+
}>;
|
|
56
|
+
export {};
|