@astrosheep/square 0.4.6 → 0.4.8
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/card-format.d.ts +2 -0
- package/dist/card-format.js +2 -0
- package/dist/claude-mcp-context.d.ts +0 -1
- package/dist/claude-mcp-context.js +0 -10
- package/dist/claude-mod.d.ts +2 -0
- package/dist/claude-mod.js +211 -0
- package/dist/cli/context.d.ts +2 -2
- package/dist/cli/context.js +14 -16
- package/dist/cli/express-presentation.js +12 -53
- package/dist/cli/json.js +2 -2
- package/dist/cli/observation-commands.d.ts +2 -7
- package/dist/cli/observation-commands.js +31 -97
- package/dist/cli/registry.js +3 -6
- package/dist/cli/square-commands.d.ts +2 -3
- package/dist/cli/square-commands.js +12 -22
- package/dist/decisions.js +5 -4
- package/dist/harness-claude.js +3 -3
- package/dist/help.js +9 -16
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.js +7 -18
- package/dist/model.d.ts +1 -1
- package/dist/neutral.d.ts +15 -3
- package/dist/notifications.d.ts +1 -3
- package/dist/notifications.js +21 -23
- package/dist/operation-control.d.ts +0 -1
- package/dist/operation-control.js +0 -11
- package/dist/operation-presentation.d.ts +28 -21
- package/dist/operation-presentation.js +90 -87
- package/dist/packages/agent-delivery/src/index.d.ts +4 -9
- package/dist/packages/agent-delivery/src/index.js +0 -9
- package/dist/packages/agent-delivery/src/local-endpoint.d.ts +2 -12
- package/dist/packages/agent-delivery/src/local-endpoint.js +4 -48
- package/dist/packages/agent-delivery/src/pi-client.js +0 -2
- package/dist/packages/agent-delivery/src/types.d.ts +3 -37
- package/dist/participant-identity.d.ts +0 -2
- package/dist/participant-identity.js +0 -13
- package/dist/plugins/paseo/shared/card-format.d.ts +6 -0
- package/dist/plugins/paseo/shared/card-format.js +38 -0
- package/dist/plugins/paseo/shared/card-presentation.d.ts +3 -1
- package/dist/plugins/paseo/shared/card-presentation.js +3 -1
- package/dist/presentation.d.ts +5 -22
- package/dist/presentation.js +25 -58
- package/dist/runtime.d.ts +6 -6
- package/dist/runtime.js +5 -15
- package/dist/sqlite-square.d.ts +4 -5
- package/dist/sqlite-square.js +29 -32
- package/dist/square-api.d.ts +1 -1
- package/dist/square-api.js +1 -1
- package/dist/square-facade.d.ts +5 -14
- package/dist/square-location.d.ts +0 -1
- package/dist/square-posting.d.ts +4 -4
- package/dist/square-posting.js +14 -16
- package/dist/square-tools.d.ts +4 -17
- package/dist/square-tools.js +52 -119
- package/dist/square-values.d.ts +1 -1
- package/dist/square-values.js +1 -1
- package/dist/time.d.ts +1 -0
- package/dist/time.js +10 -0
- package/dist/views.d.ts +1 -1
- package/dist/views.js +2 -2
- package/dist/wake-transports.d.ts +2 -2
- package/dist/wake-transports.js +7 -9
- package/dist/wakes.js +1 -1
- package/examples/symmetric-domains.mjs +1 -2
- package/guides/catch-cold-path-optimization.md +1 -1
- package/guides/claude-native.md +37 -7
- package/guides/delivery-primitives.md +2 -1
- package/guides/mcp.md +3 -3
- package/guides/pi-native-delivery.md +10 -2
- package/guides/pi-tools.md +1 -3
- package/guides/row-storage-design.md +1 -1
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +3 -2
- package/plugins/claude/README.md +9 -0
- package/plugins/claude/hooks/hooks.json +1 -9
- package/plugins/claude/hooks/register.js +178 -0
- package/plugins/claude/skills/square/SKILL.md +2 -2
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/paseo/OVERVIEW.md +1 -1
- package/plugins/paseo/README.md +20 -23
- package/plugins/paseo/client/markdown.tsx +88 -95
- package/plugins/paseo/client/palette.ts +37 -12
- package/plugins/paseo/client/square-message.tsx +52 -76
- package/plugins/paseo/client/transform.ts +4 -6
- package/plugins/paseo/shared/card-format.ts +37 -0
- package/plugins/paseo/shared/card-presentation.ts +6 -2
- package/plugins/paseo/shared/message.ts +1 -6
- package/plugins/pi/square-pi.js +76 -60
- package/skills/square/SKILL.md +2 -2
- package/dist/claude-boundary-state.d.ts +0 -20
- package/dist/claude-boundary-state.js +0 -84
- package/dist/claude-hook.d.ts +0 -2
- package/dist/claude-hook.js +0 -232
- package/dist/packages/agent-delivery/src/claude-auth.d.ts +0 -13
- package/dist/packages/agent-delivery/src/claude-auth.js +0 -75
- package/dist/packages/agent-delivery/src/claude-native.d.ts +0 -30
- package/dist/packages/agent-delivery/src/claude-native.js +0 -75
- package/dist/packages/agent-delivery/src/claude.d.ts +0 -5
- package/dist/packages/agent-delivery/src/claude.js +0 -66
package/dist/notifications.js
CHANGED
|
@@ -1,52 +1,50 @@
|
|
|
1
1
|
import { createDefaultDeliveryTransports } from './wake-transports.js';
|
|
2
2
|
export { createDefaultDeliveryTransports } from './wake-transports.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return Number.isSafeInteger(configured) && configured > 0 ? configured : 5000;
|
|
6
|
-
}
|
|
3
|
+
const DEFAULT_DELIVERY_WAIT_MS = 5000;
|
|
4
|
+
const NATIVE_RECEIVER_ROUTES = new Set(['codex-queue', 'claude-mod', 'pi-native']);
|
|
7
5
|
/** Best-effort dispatch for currently eligible cards, including cards restored by release. */
|
|
8
6
|
export async function dispatchEligibleCards(ledger, owner, options = {}) {
|
|
9
|
-
|
|
10
|
-
const session = await ledger.session(owner,
|
|
11
|
-
if (!session || session.state !== 'attached' ||
|
|
7
|
+
const signal = options.signal ?? AbortSignal.timeout(DEFAULT_DELIVERY_WAIT_MS);
|
|
8
|
+
const session = await ledger.session(owner, signal);
|
|
9
|
+
if (!session || session.state !== 'attached' || signal.aborted)
|
|
12
10
|
return;
|
|
13
|
-
const pending = await ledger.pending(owner, { generation: session.generation },
|
|
11
|
+
const pending = await ledger.pending(owner, { generation: session.generation }, signal);
|
|
14
12
|
for (const card of pending)
|
|
15
|
-
await dispatchPostedCard(ledger, owner, card.key, options.track ?? (() => undefined),
|
|
13
|
+
await dispatchPostedCard(ledger, owner, card.key, options.track ?? (() => undefined), signal, options.transports);
|
|
16
14
|
}
|
|
17
15
|
/** Post, then best-effort dispatch without consulting producer storage. */
|
|
18
16
|
export async function postAndDispatch(ledger, input, options = {}) {
|
|
19
|
-
|
|
20
|
-
const result = await ledger.post(input,
|
|
17
|
+
const signal = options.signal ?? AbortSignal.timeout(DEFAULT_DELIVERY_WAIT_MS);
|
|
18
|
+
const result = await ledger.post(input, signal);
|
|
21
19
|
if (result.status === 'posted' || result.status === 'duplicate') {
|
|
22
20
|
try {
|
|
23
|
-
await dispatchEligibleCards(ledger, input.owner, options);
|
|
21
|
+
await dispatchEligibleCards(ledger, input.owner, { ...options, signal });
|
|
24
22
|
}
|
|
25
23
|
catch { /* Posting is already committed. */ }
|
|
26
24
|
}
|
|
27
25
|
return result;
|
|
28
26
|
}
|
|
29
27
|
/** Best-effort dispatch after a card has been posted; never inspect producer storage. */
|
|
30
|
-
export async function dispatchPostedCard(ledger, owner, key, track,
|
|
28
|
+
export async function dispatchPostedCard(ledger, owner, key, track, signal, suppliedTransports) {
|
|
31
29
|
if (signal?.aborted)
|
|
32
30
|
return;
|
|
33
|
-
|
|
34
|
-
signal ??= AbortSignal.timeout(timeoutMs);
|
|
31
|
+
signal ??= AbortSignal.timeout(DEFAULT_DELIVERY_WAIT_MS);
|
|
35
32
|
const session = await ledger.session(owner, signal);
|
|
36
33
|
if (!session || session.state !== 'attached')
|
|
37
34
|
return;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
// Native receiver custody belongs to the receiver itself, including for
|
|
36
|
+
// callers that supply transports explicitly to the producer API.
|
|
37
|
+
const routes = session.routes.filter(route => !NATIVE_RECEIVER_ROUTES.has(route.kind));
|
|
38
|
+
if (!routes.length)
|
|
39
|
+
return;
|
|
40
|
+
const transports = suppliedTransports ?? await createDefaultDeliveryTransports();
|
|
41
|
+
for (const route of routes) {
|
|
42
|
+
if (signal.aborted)
|
|
45
43
|
return;
|
|
46
44
|
const transport = transports.find(candidate => candidate.kind === route.kind);
|
|
47
45
|
if (!transport)
|
|
48
46
|
continue;
|
|
49
|
-
const result = await ledger.dispatchHandoff(owner, key, transport, { generation: session.generation, timeoutMs, signal });
|
|
47
|
+
const result = await ledger.dispatchHandoff(owner, key, transport, { generation: session.generation, timeoutMs: DEFAULT_DELIVERY_WAIT_MS, signal });
|
|
50
48
|
track(result);
|
|
51
49
|
if (result.outcome === 'accepted' || result.outcome === 'presented' || result.outcome === 'unknown')
|
|
52
50
|
return;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import type { OperationControl, OperationFailureDetail } from './neutral.js';
|
|
2
2
|
export declare function checkControl(control?: OperationControl): void;
|
|
3
|
-
export declare function squareClock(env: NodeJS.ProcessEnv, clock?: () => number): () => number;
|
|
4
3
|
export declare function failure(error: unknown, detail: OperationFailureDetail): Error;
|
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
import { SquareError } from './neutral.js';
|
|
2
1
|
export function checkControl(control) {
|
|
3
2
|
if (control?.signal?.aborted)
|
|
4
3
|
throw control.signal.reason ?? new Error('Square operation was cancelled');
|
|
5
4
|
}
|
|
6
|
-
export function squareClock(env, clock) {
|
|
7
|
-
if (clock !== undefined)
|
|
8
|
-
return clock;
|
|
9
|
-
if (env.SQUARE_NOW_MS === undefined)
|
|
10
|
-
return Date.now;
|
|
11
|
-
const value = Number.parseInt(env.SQUARE_NOW_MS, 10);
|
|
12
|
-
if (!Number.isFinite(value))
|
|
13
|
-
throw new SquareError('invalid_args', 'Invalid SQUARE_NOW_MS: expected integer milliseconds.');
|
|
14
|
-
return () => value;
|
|
15
|
-
}
|
|
16
5
|
export function failure(error, detail) {
|
|
17
6
|
const normalized = error instanceof Error ? error : new Error(String(error), { cause: error });
|
|
18
7
|
Object.assign(normalized, { operation: detail });
|
|
@@ -1,32 +1,34 @@
|
|
|
1
|
-
import type { PerceiveOptions, PerceiveResult, ExpressResult, HistoryQuery, HistoryResult, JoinResult, LifecycleResult, ListenerChangeResult,
|
|
1
|
+
import type { PerceiveOptions, PerceiveResult, ExpressResult, HistoryQuery, HistoryResult, JoinResult, LifecycleResult, ListenerChangeResult, OperationFailureDetail, SquareErrorFacts, StatusResult, DiscoveryResult } from './square-facade.js';
|
|
2
|
+
import { type PresentationSurface } from './presentation.js';
|
|
2
3
|
export declare function renderSquareList(data: DiscoveryResult, projection: {
|
|
3
4
|
now: number;
|
|
4
5
|
depth: number;
|
|
5
6
|
limit: number;
|
|
7
|
+
surface?: PresentationSurface;
|
|
6
8
|
}): string;
|
|
7
|
-
export declare const PARTICIPANTS_DEFAULT_LIMIT = 20;
|
|
8
|
-
export declare const PARTICIPANTS_MAX_LIMIT = 100;
|
|
9
9
|
/** A join receipt whose participant is already reduced to its serializable name. */
|
|
10
10
|
export type JoinPresentation = Omit<JoinResult, 'participant'> & {
|
|
11
11
|
readonly participant: {
|
|
12
12
|
readonly name: string;
|
|
13
13
|
} | string;
|
|
14
14
|
};
|
|
15
|
-
export declare function renderJoinResult(data: JoinPresentation, owner?: string): string | undefined;
|
|
16
|
-
export declare function renderExpression(squarePath: string, data: ExpressResult, owner?: string): string | undefined;
|
|
15
|
+
export declare function renderJoinResult(data: JoinPresentation, owner?: string, surface?: PresentationSurface): string | undefined;
|
|
16
|
+
export declare function renderExpression(squarePath: string, data: ExpressResult, owner?: string, surface?: PresentationSurface): string | undefined;
|
|
17
17
|
/** Render settled perceive facts; no selection, terminal decisions, receipts or wait machinery. */
|
|
18
|
-
export declare function renderPerceiveOutcome(squarePath: string, data: PerceiveResult, options?: PerceiveOptions, owner?: string): {
|
|
18
|
+
export declare function renderPerceiveOutcome(squarePath: string, data: PerceiveResult, options?: PerceiveOptions, owner?: string, surface?: PresentationSurface): {
|
|
19
19
|
stdout: string;
|
|
20
20
|
exitCode: number;
|
|
21
21
|
};
|
|
22
|
+
export declare function historyContinuationCommand(squarePath: string, args: readonly string[]): string;
|
|
22
23
|
export declare function renderHistoryResult(squarePath: string, data: HistoryResult, options?: {
|
|
23
24
|
query?: HistoryQuery;
|
|
24
|
-
|
|
25
|
+
full?: boolean;
|
|
25
26
|
continuationArgs?: readonly string[];
|
|
27
|
+
surface?: PresentationSurface;
|
|
28
|
+
}): string | undefined;
|
|
29
|
+
export declare function renderStatusResult(squarePath: string, data: StatusResult, options?: {
|
|
30
|
+
surface?: PresentationSurface;
|
|
26
31
|
}): string | undefined;
|
|
27
|
-
export declare function renderParticipantsResult(squarePath: string, data: ParticipantsResult, limit?: number): string | undefined;
|
|
28
|
-
export declare function renderStatusResult(squarePath: string, data: StatusResult): string | undefined;
|
|
29
|
-
export declare function renderListeningResult(squarePath: string, data: ListeningResult): string | undefined;
|
|
30
32
|
export type ListenerVerb = 'listen' | 'ignore' | 'unlisten';
|
|
31
33
|
export declare function renderListenerChange(squarePath: string, verb: ListenerVerb, data: ListenerChangeResult): string | undefined;
|
|
32
34
|
export declare function renderLifecycleResult(squarePath: string, data: LifecycleResult): string | undefined;
|
|
@@ -34,16 +36,21 @@ export declare function renderLifecycleResult(squarePath: string, data: Lifecycl
|
|
|
34
36
|
export interface FailureReport {
|
|
35
37
|
readonly code: string;
|
|
36
38
|
readonly message: string;
|
|
37
|
-
readonly facts?:
|
|
38
|
-
readonly reason?: 'never_joined' | 'not_standing' | 'bell_mention_conflict' | 'not_addressed' | 'invalid_reply' | 'invalid_done_body' | 'needs_seat';
|
|
39
|
-
readonly activityId?: string;
|
|
40
|
-
readonly activityExists?: boolean;
|
|
41
|
-
};
|
|
39
|
+
readonly facts?: SquareErrorFacts;
|
|
42
40
|
readonly operation?: OperationFailureDetail;
|
|
43
41
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
interface FailureOptions {
|
|
43
|
+
readonly squarePath?: string;
|
|
44
|
+
readonly name?: string;
|
|
45
|
+
readonly owner?: string;
|
|
46
|
+
readonly surface?: PresentationSurface;
|
|
47
|
+
readonly reply?: string;
|
|
48
|
+
/** CLI only: the saved draft and the full command that resends it. */
|
|
49
|
+
readonly draftPath?: string;
|
|
50
|
+
readonly retry?: string;
|
|
51
|
+
}
|
|
52
|
+
/** Express gates are physics, not mistakes: one scene for every surface, then that surface's next action. */
|
|
53
|
+
export declare function isExpressGate(code: string): boolean;
|
|
54
|
+
/** Refusal lines with surface-specific recovery actions. */
|
|
55
|
+
export declare function renderFailureLines(failure: FailureReport, options?: FailureOptions): string[];
|
|
56
|
+
export {};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
// Human-facing
|
|
2
|
-
// render through these functions, so a person sees the same square either way.
|
|
1
|
+
// Human-facing scenes for settled operations, with surface-specific next actions.
|
|
3
2
|
import { sameName } from './model.js';
|
|
4
3
|
import { formatActivityId } from './square-core.js';
|
|
5
|
-
import { commandPrefix, joinRecoveryCommand, participantCommandPrefix, participantIdentity,
|
|
6
|
-
import { formatRelativeTime, formatTimestamp } from './time.js';
|
|
4
|
+
import { displayPath, formatToolAction, commandPrefix, joinRecoveryCommand, participantCommandPrefix, participantIdentity, quoteShell, renderAmbientEvent, renderAmbientEventFacts, renderEventCli, renderGrepActivitiesView, renderPresenceAnchor, renderWatchAlreadyActive, renderWatchReplaced, renderWatchStatus, renderUnreadSummary, takeoverRecoveryLines, withPathOutput, truncateChars, } from './presentation.js';
|
|
5
|
+
import { formatDuration, formatRelativeTime, formatTimestamp } from './time.js';
|
|
7
6
|
import { style } from './tty-style.js';
|
|
8
7
|
function listDisplay(value) {
|
|
9
8
|
const truncated = truncateChars(value, 159);
|
|
@@ -37,16 +36,14 @@ export function renderSquareList(data, projection) {
|
|
|
37
36
|
if (remaining > 0) {
|
|
38
37
|
lines.push(style('dim', stopped ? ' … more squares' : ` … ${remaining} more ${remaining === 1 ? 'square' : 'squares'}`));
|
|
39
38
|
if (next !== undefined)
|
|
40
|
-
lines.push(`square list --depth ${projection.depth} --limit ${projection.limit} --after ${quoteShell(next)}`);
|
|
39
|
+
lines.push(projection.surface === 'tool' ? formatToolAction('list', { depth: projection.depth, limit: projection.limit, after: next }) : `square list --depth ${projection.depth} --limit ${projection.limit} --after ${quoteShell(next)}`);
|
|
41
40
|
}
|
|
42
41
|
if (stopped)
|
|
43
42
|
lines.push(style('dim', '○ the walk stopped early — deeper squares may still be hiding'));
|
|
44
43
|
return lines.join('\n') + '\n';
|
|
45
44
|
}
|
|
46
|
-
export const PARTICIPANTS_DEFAULT_LIMIT = 20;
|
|
47
|
-
export const PARTICIPANTS_MAX_LIMIT = 100;
|
|
48
45
|
const STATUS_PARTICIPANT_PREVIEW_LIMIT = 10;
|
|
49
|
-
export function renderJoinResult(data, owner) {
|
|
46
|
+
export function renderJoinResult(data, owner, surface = 'cli') {
|
|
50
47
|
const after = data.observation;
|
|
51
48
|
if (after === undefined)
|
|
52
49
|
return undefined;
|
|
@@ -56,7 +53,7 @@ export function renderJoinResult(data, owner) {
|
|
|
56
53
|
now: after.now, preview: 200, perception: event.perception,
|
|
57
54
|
})).filter(Boolean).join('\n\n');
|
|
58
55
|
const fallback = after.deliveryAvailable ? ['', '· when someone calls you, you’ll hear them here'] : [
|
|
59
|
-
'', `${participantCommandPrefix(after.location, name, owner)} perceive --idle 30m`,
|
|
56
|
+
'', surface === 'tool' ? formatToolAction('perceive', { location: displayPath(after.location), as: name, idle: '30m' }) : `${participantCommandPrefix(after.location, name, owner)} perceive --idle 30m`,
|
|
60
57
|
' · stay within earshot — keep this perceive open for new activity',
|
|
61
58
|
];
|
|
62
59
|
const entryLine = data.kind === 'joined' ? '● you stepped into the square'
|
|
@@ -77,7 +74,7 @@ export function renderJoinResult(data, owner) {
|
|
|
77
74
|
function isGestureOnly(body) {
|
|
78
75
|
return /\*[^*]*\*/.test(body) && body.replace(/\*[^*]*\*/g, '').trim() === '';
|
|
79
76
|
}
|
|
80
|
-
export function renderExpression(squarePath, data, owner) {
|
|
77
|
+
export function renderExpression(squarePath, data, owner, surface = 'cli') {
|
|
81
78
|
const projection = data.observation;
|
|
82
79
|
if (projection === undefined)
|
|
83
80
|
return undefined;
|
|
@@ -87,7 +84,7 @@ export function renderExpression(squarePath, data, owner) {
|
|
|
87
84
|
'Unread context · preview only, not consumed',
|
|
88
85
|
...context.activities.map(item => `· ${participantIdentity(item.actor)} · ${item.id}\n ${item.preview}${item.truncated ? '… (truncated)' : ''}`),
|
|
89
86
|
...(context.remaining === 0 ? [] : [`· ${context.remaining} more unread activities`]),
|
|
90
|
-
`${participantCommandPrefix(projection.location, name, owner)} perceive`,
|
|
87
|
+
surface === 'tool' ? formatToolAction('perceive', { location: displayPath(projection.location), as: name }) : `${participantCommandPrefix(projection.location, name, owner)} perceive`,
|
|
91
88
|
].join('\n');
|
|
92
89
|
const ownCount = projection.ownActivityCount;
|
|
93
90
|
const capCount = projection.hardCap === null ? '' : ` · ${ownCount}/${projection.hardCap}`;
|
|
@@ -104,17 +101,17 @@ export function renderExpression(squarePath, data, owner) {
|
|
|
104
101
|
return withPathOutput(projection.location ?? squarePath, confirmation + (data.hint ? `\n${style('dim', `· ${data.hint}`)}` : '') + replyNotice + unmatchedNotice + pending, { participantCount: projection.standingCount });
|
|
105
102
|
}
|
|
106
103
|
function continuationCommand(squarePath, name, options, owner) {
|
|
107
|
-
const args = [
|
|
104
|
+
const args = [];
|
|
108
105
|
if (options.from?.length)
|
|
109
106
|
args.push('--from', options.from.join(','));
|
|
110
107
|
if (options.mention)
|
|
111
108
|
args.push('--mention');
|
|
112
109
|
if (options.limit !== undefined)
|
|
113
110
|
args.push('--limit', String(options.limit));
|
|
114
|
-
return
|
|
111
|
+
return [participantCommandPrefix(squarePath, name, owner), 'perceive', ...args].join(' ');
|
|
115
112
|
}
|
|
116
113
|
/** Render settled perceive facts; no selection, terminal decisions, receipts or wait machinery. */
|
|
117
|
-
export function renderPerceiveOutcome(squarePath, data, options = {}, owner) {
|
|
114
|
+
export function renderPerceiveOutcome(squarePath, data, options = {}, owner, surface = 'cli') {
|
|
118
115
|
const projection = data.observation;
|
|
119
116
|
if (projection === undefined)
|
|
120
117
|
return { stdout: '', exitCode: 0 };
|
|
@@ -123,7 +120,7 @@ export function renderPerceiveOutcome(squarePath, data, options = {}, owner) {
|
|
|
123
120
|
const stop = data.reason === 'drained' && data.activities.length > 0 ? undefined : data.reason;
|
|
124
121
|
const header = { participantCount: projection.standingCount };
|
|
125
122
|
const statusOptions = {
|
|
126
|
-
squarePath: location, name, owner, presence: projection.presence,
|
|
123
|
+
squarePath: location, name, owner, surface, presence: projection.presence,
|
|
127
124
|
showPerceiveHint: !projection.deliveryAvailable,
|
|
128
125
|
ownActivityCount: projection.ownActivityCount, hardCap: projection.hardCap,
|
|
129
126
|
};
|
|
@@ -138,27 +135,27 @@ export function renderPerceiveOutcome(squarePath, data, options = {}, owner) {
|
|
|
138
135
|
now: projection.now, perception: activity.perception, mention: options.mention ? name : undefined,
|
|
139
136
|
})).filter(Boolean).join('\n\n');
|
|
140
137
|
const remaining = data.remaining === 0 ? ''
|
|
141
|
-
: `· ${data.remaining} matching ${data.remaining === 1 ? 'activity remains' : 'activities remain'}\n${continuationCommand(location, name, options, owner)}`;
|
|
138
|
+
: `· ${data.remaining} matching ${data.remaining === 1 ? 'activity remains' : 'activities remain'}\n${surface === 'tool' ? formatToolAction('perceive', { location: displayPath(location), as: name, ...(options.from?.length ? { from: options.from } : {}), ...(options.mention ? { mention: true } : {}), ...(options.limit !== undefined ? { limit: options.limit } : {}) }) : continuationCommand(location, name, options, owner)}`;
|
|
142
139
|
const terminal = stop === undefined ? '' : renderWatchStatus({
|
|
143
140
|
...statusOptions, status: stop,
|
|
144
141
|
...(stop === 'idle' && options.idle !== undefined ? { idleMs: options.idle } : {}),
|
|
145
142
|
});
|
|
146
143
|
const fallback = stop === undefined && !projection.deliveryAvailable && data.remaining === 0
|
|
147
|
-
? `${participantCommandPrefix(location, name, owner)} perceive --idle 30m\n stay available for new activity` : '';
|
|
144
|
+
? `${surface === 'tool' ? formatToolAction('perceive', { location: displayPath(location), as: name, idle: '30m' }) : `${participantCommandPrefix(location, name, owner)} perceive --idle 30m`}\n stay available for new activity` : '';
|
|
148
145
|
const hint = data.hint === undefined ? '' : style('dim', `· ${data.hint}`);
|
|
149
146
|
return {
|
|
150
147
|
stdout: withPathOutput(location, [terminal, rendered, hint, remaining, fallback].filter(Boolean).join('\n\n'), header),
|
|
151
148
|
exitCode: stop === 'capped' ? 1 : 0,
|
|
152
149
|
};
|
|
153
150
|
}
|
|
154
|
-
function renderHistoryProjection(projection, visible,
|
|
151
|
+
function renderHistoryProjection(projection, visible, full, squarePath, surface) {
|
|
155
152
|
const shown = visible;
|
|
156
|
-
const preview =
|
|
153
|
+
const preview = full || shown.length <= 1 ? undefined : 200;
|
|
157
154
|
const chunks = [];
|
|
158
155
|
// Presence anchors collect into one closing line instead of interrupting the page.
|
|
159
156
|
const anchored = [];
|
|
160
157
|
for (const activity of shown) {
|
|
161
|
-
const rendered = renderEventCli(activity, { preview });
|
|
158
|
+
const rendered = renderEventCli(activity, { now: projection.now, preview });
|
|
162
159
|
if (rendered !== '')
|
|
163
160
|
chunks.push(rendered);
|
|
164
161
|
for (const participant of projection.presenceAnchors[activity.index] ?? []) {
|
|
@@ -169,13 +166,14 @@ function renderHistoryProjection(projection, visible, noTruncate, squarePath) {
|
|
|
169
166
|
if (chunks.length === 0)
|
|
170
167
|
return '○ no activity matches this history query';
|
|
171
168
|
if (preview !== undefined && shown.some((activity) => activity.kind === 'say' && (activity.body?.length ?? 0) > preview)) {
|
|
172
|
-
|
|
169
|
+
const ids = shown.map((activity) => formatActivityId(activity.index));
|
|
170
|
+
chunks.push(surface === 'tool' ? formatToolAction('history', { location: displayPath(squarePath), at: ids, full: true }) : `${commandPrefix(squarePath)} history --at ${ids.join(',')} --full`);
|
|
173
171
|
}
|
|
174
172
|
if (anchored.length > 0)
|
|
175
173
|
chunks.push(renderPresenceAnchor(anchored));
|
|
176
174
|
return chunks.join('\n\n');
|
|
177
175
|
}
|
|
178
|
-
function historyContinuationCommand(squarePath, args) {
|
|
176
|
+
export function historyContinuationCommand(squarePath, args) {
|
|
179
177
|
return `${commandPrefix(squarePath)} history ${args.map((arg) => arg.startsWith('-') || /^act\/\d+$/.test(arg) || /^\d+$/.test(arg) ? arg : quoteShell(arg)).join(' ')}`;
|
|
180
178
|
}
|
|
181
179
|
/** The same query spelled as CLI arguments, for a continuation someone can actually run. */
|
|
@@ -187,14 +185,15 @@ function historyQueryArgs(query) {
|
|
|
187
185
|
args.push('--since', formatTimestamp(query.since));
|
|
188
186
|
if (query.at?.length)
|
|
189
187
|
args.push('--at', query.at.join(','));
|
|
190
|
-
if (query.
|
|
191
|
-
args.push('-
|
|
192
|
-
if (query.contextAfter !== undefined)
|
|
193
|
-
args.push('-A', String(query.contextAfter));
|
|
188
|
+
if (query.context !== undefined)
|
|
189
|
+
args.push('-C', String(query.context));
|
|
194
190
|
if (query.mention !== undefined)
|
|
195
191
|
args.push('--mention', query.mention);
|
|
196
|
-
if (query.search !== undefined)
|
|
197
|
-
args.push(
|
|
192
|
+
if (query.search !== undefined) {
|
|
193
|
+
args.push('--search', query.search.text);
|
|
194
|
+
if (query.search.mode === 'regex')
|
|
195
|
+
args.push('--regex');
|
|
196
|
+
}
|
|
198
197
|
if (query.order !== undefined)
|
|
199
198
|
args.push('--order', query.order);
|
|
200
199
|
return args;
|
|
@@ -204,44 +203,17 @@ export function renderHistoryResult(squarePath, data, options = {}) {
|
|
|
204
203
|
if (projection === undefined)
|
|
205
204
|
return undefined;
|
|
206
205
|
const query = options.query ?? {};
|
|
207
|
-
const
|
|
206
|
+
const full = options.full === true;
|
|
208
207
|
const search = query.search;
|
|
209
208
|
const output = search === undefined
|
|
210
|
-
? renderHistoryProjection(projection, projection.visibleActivities,
|
|
211
|
-
: renderGrepActivitiesView(projection.visibleActivities, projection.totalMatches,
|
|
209
|
+
? renderHistoryProjection(projection, projection.visibleActivities, full, squarePath, options.surface ?? 'cli')
|
|
210
|
+
: renderGrepActivitiesView(projection.visibleActivities, projection.totalMatches, full, squarePath, search.text, search.mode === 'literal', () => 'full', options.surface);
|
|
212
211
|
const next = projection.continuation;
|
|
213
|
-
const base = options.continuationArgs ?? historyQueryArgs(query);
|
|
214
|
-
const continuation = next === undefined ? '' : `\n\n${historyContinuationCommand(squarePath, [...base, `--${next.direction}`, next.cursor, '--limit', String(next.limit)])}`;
|
|
212
|
+
const base = options.continuationArgs ?? [...historyQueryArgs(query), ...(full ? ['--full'] : [])];
|
|
213
|
+
const continuation = next === undefined ? '' : `\n\n${options.surface === 'tool' ? formatToolAction('history', { location: displayPath(squarePath), ...(query.from?.length ? { from: query.from } : {}), ...(query.since !== undefined ? { since: formatTimestamp(query.since) } : {}), ...(query.at?.length ? { at: query.at } : {}), ...(query.context !== undefined ? { context: query.context } : {}), ...(query.mention !== undefined ? { mention: query.mention } : {}), ...(query.search !== undefined ? { search: query.search.text, ...(query.search.mode === 'regex' ? { regex: true } : {}) } : {}), ...(query.order !== undefined ? { order: query.order } : {}), ...(full ? { full: true } : {}), [next.direction]: next.cursor, limit: next.limit }) : historyContinuationCommand(squarePath, [...base, `--${next.direction}`, next.cursor, '--limit', String(next.limit)])}`;
|
|
215
214
|
return withPathOutput(squarePath, output + continuation, { participantCount: projection.standingCount });
|
|
216
215
|
}
|
|
217
|
-
function
|
|
218
|
-
return `${commandPrefix(squarePath)} participants --limit ${limit}`;
|
|
219
|
-
}
|
|
220
|
-
export function renderParticipantsResult(squarePath, data, limit = PARTICIPANTS_DEFAULT_LIMIT) {
|
|
221
|
-
const projection = data.observation;
|
|
222
|
-
if (projection === undefined)
|
|
223
|
-
return undefined;
|
|
224
|
-
const now = projection.now;
|
|
225
|
-
const participants = data.participants;
|
|
226
|
-
const lines = participants.slice(0, limit).map((participant) => {
|
|
227
|
-
const glyph = participant.presence === 'done' ? '○' : participant.presence === 'watching' ? '◎' : participant.activityCount > 0 && projection.classificationByName[participant.name] === 'here' ? '●' : '○';
|
|
228
|
-
const state = participant.presence === 'watching' ? 'perceiving' : participant.presence === 'never-joined' ? 'not joined' : participant.presence;
|
|
229
|
-
const last = participant.lastActiveAt === undefined ? '—' : formatRelativeTime(participant.lastActiveAt, now);
|
|
230
|
-
return ` ${glyph} ${participant.name}${style('dim', ` · ${state} · ${participant.activityCount} ${participant.activityCount === 1 ? 'activity' : 'activities'} · ${last}`)}`;
|
|
231
|
-
});
|
|
232
|
-
const tail = participants.length <= limit
|
|
233
|
-
? []
|
|
234
|
-
: [
|
|
235
|
-
style('dim', ` · ${lines.length} of ${participants.length} participants shown`),
|
|
236
|
-
...(participants.length <= PARTICIPANTS_MAX_LIMIT ? [
|
|
237
|
-
`${participantsLimitCommand(squarePath, participants.length)}`,
|
|
238
|
-
] : []),
|
|
239
|
-
];
|
|
240
|
-
return withPathOutput(squarePath, ['participants', ...lines, ...tail].join('\n'), {
|
|
241
|
-
participantCount: projection.standingCount,
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
export function renderStatusResult(squarePath, data) {
|
|
216
|
+
export function renderStatusResult(squarePath, data, options = {}) {
|
|
245
217
|
const presentation = data.observation;
|
|
246
218
|
if (presentation === undefined)
|
|
247
219
|
return undefined;
|
|
@@ -278,18 +250,11 @@ export function renderStatusResult(squarePath, data) {
|
|
|
278
250
|
people.push(...away.slice(0, STATUS_PARTICIPANT_PREVIEW_LIMIT).map(participant => ` ○ ${participantIdentity(participant.name)}${style('dim', ' · away')}`));
|
|
279
251
|
if (away.length > STATUS_PARTICIPANT_PREVIEW_LIMIT)
|
|
280
252
|
people.push(` ○ … ${away.length - STATUS_PARTICIPANT_PREVIEW_LIMIT} more away`);
|
|
281
|
-
const unshown = Math.max(0, orderedHere.length - STATUS_PARTICIPANT_PREVIEW_LIMIT)
|
|
282
|
-
+ Math.max(0, away.length - STATUS_PARTICIPANT_PREVIEW_LIMIT) + lingering;
|
|
283
253
|
if (orderedHere.length > STATUS_PARTICIPANT_PREVIEW_LIMIT) {
|
|
284
254
|
people.push(` ○ … ${orderedHere.length - STATUS_PARTICIPANT_PREVIEW_LIMIT} more here`);
|
|
285
255
|
}
|
|
286
256
|
if (lingering > 0)
|
|
287
257
|
people.push(` ○ … ${lingering} lingering`);
|
|
288
|
-
if (unshown > 0) {
|
|
289
|
-
people.push(`${presentation.knownParticipantCount <= PARTICIPANTS_MAX_LIMIT
|
|
290
|
-
? participantsLimitCommand(squarePath, presentation.knownParticipantCount)
|
|
291
|
-
: `${commandPrefix(squarePath)} participants`}`);
|
|
292
|
-
}
|
|
293
258
|
}
|
|
294
259
|
const cap = data.hardCap === null ? 'unlimited' : `${data.hardCap} each`;
|
|
295
260
|
const visible = data.latestActivity === undefined
|
|
@@ -312,7 +277,7 @@ export function renderStatusResult(squarePath, data) {
|
|
|
312
277
|
if (presentation.joinCount > 3)
|
|
313
278
|
latest.push(style('dim', ` → … ${presentation.joinCount - 3} more stepped in`));
|
|
314
279
|
if (visible.bodyClipped && data.latestActivity !== undefined) {
|
|
315
|
-
latest.push(`${commandPrefix(squarePath)} history --at ${data.latestActivity.id} -C 2 --
|
|
280
|
+
latest.push(options.surface === 'tool' ? formatToolAction('history', { location: displayPath(squarePath), at: [data.latestActivity.id], context: 2, full: true }) : `${commandPrefix(squarePath)} history --at ${data.latestActivity.id} -C 2 --full`);
|
|
316
281
|
}
|
|
317
282
|
const counts = [
|
|
318
283
|
`${orderedHere.length} here`,
|
|
@@ -332,15 +297,6 @@ export function renderStatusResult(squarePath, data) {
|
|
|
332
297
|
].join('\n');
|
|
333
298
|
return withPathOutput(squarePath, output, { participantCount: presentation.standingCount });
|
|
334
299
|
}
|
|
335
|
-
export function renderListeningResult(squarePath, data) {
|
|
336
|
-
const projection = data.observation;
|
|
337
|
-
if (projection?.participant === undefined)
|
|
338
|
-
return undefined;
|
|
339
|
-
const body = data.listening.length === 0
|
|
340
|
-
? `○ ${participantIdentity(projection.participant)} is not turned toward anyone`
|
|
341
|
-
: ['listening', ...data.listening.map((target) => ` · ${participantIdentity(target)}`)].join('\n');
|
|
342
|
-
return withPathOutput(squarePath, body, { participantCount: projection.standingCount });
|
|
343
|
-
}
|
|
344
300
|
export function renderListenerChange(squarePath, verb, data) {
|
|
345
301
|
const projection = data.observation;
|
|
346
302
|
if (projection?.participant === undefined)
|
|
@@ -366,34 +322,81 @@ export function renderLifecycleResult(squarePath, data) {
|
|
|
366
322
|
participantCount: projection.standingCount,
|
|
367
323
|
});
|
|
368
324
|
}
|
|
369
|
-
/**
|
|
325
|
+
/** Express gates are physics, not mistakes: one scene for every surface, then that surface's next action. */
|
|
326
|
+
export function isExpressGate(code) {
|
|
327
|
+
return code === 'behind' || code === 'capped' || code === 'throttled' || code === 'bell_quota';
|
|
328
|
+
}
|
|
329
|
+
function expressGateLines(failure, options) {
|
|
330
|
+
if (!isExpressGate(failure.code))
|
|
331
|
+
return undefined;
|
|
332
|
+
const { squarePath, name, owner } = options;
|
|
333
|
+
const facts = failure.facts;
|
|
334
|
+
const tool = options.surface === 'tool';
|
|
335
|
+
const scene = failure.code === 'behind'
|
|
336
|
+
? ['✕ your words stay unsent — someone spoke while you were away', ...renderUnreadSummary(facts?.activitySummaries ?? [])]
|
|
337
|
+
: failure.code === 'capped'
|
|
338
|
+
? [`✕ you’ve reached your speaking cap${facts?.spoken !== undefined && facts.hardCap !== undefined ? ` — ${facts.spoken}/${facts.hardCap} spoken` : ''}`]
|
|
339
|
+
: failure.code === 'throttled'
|
|
340
|
+
? ['✕ the square is packed — shoulder to shoulder', ` · a lull opens in ${formatDuration(facts?.retryAfterMs ?? 1)}`]
|
|
341
|
+
: ['✕ the bell stays quiet for now', ` · you can ring it again in ${formatDuration(facts?.retryAfterMs ?? 1)}`];
|
|
342
|
+
const lines = [...scene, ...(options.draftPath === undefined ? [] : [style('dim', `· draft kept: ${options.draftPath}`)])];
|
|
343
|
+
if (squarePath === undefined || name === undefined)
|
|
344
|
+
return lines;
|
|
345
|
+
const action = (verb) => tool
|
|
346
|
+
? formatToolAction(verb, { location: displayPath(squarePath), as: name })
|
|
347
|
+
: `${participantCommandPrefix(squarePath, name, owner)} ${verb}`;
|
|
348
|
+
if (failure.code === 'behind')
|
|
349
|
+
lines.push(...(tool ? ['Take it in, then express again:', action('perceive')] : [action('perceive'), ' · take it in, then retry:']));
|
|
350
|
+
if (failure.code === 'capped')
|
|
351
|
+
lines.push(' · your words stay unsent; done only steps out', action('done'));
|
|
352
|
+
if (failure.code === 'bell_quota' && !tool)
|
|
353
|
+
lines.push(' · retry when the bell is ready:');
|
|
354
|
+
if (failure.code !== 'capped' && options.retry !== undefined)
|
|
355
|
+
lines.push(options.retry);
|
|
356
|
+
return lines;
|
|
357
|
+
}
|
|
358
|
+
/** Refusal lines with surface-specific recovery actions. */
|
|
370
359
|
export function renderFailureLines(failure, options = {}) {
|
|
371
360
|
const { squarePath, name, owner } = options;
|
|
372
361
|
const facts = failure.facts;
|
|
373
362
|
const reason = facts?.reason;
|
|
363
|
+
const gate = expressGateLines(failure, options);
|
|
364
|
+
if (gate !== undefined)
|
|
365
|
+
return gate;
|
|
374
366
|
const marked = reason === 'never_joined' || reason === 'not_standing';
|
|
375
367
|
const lines = marked ? failure.message.split('\n').map((line) => `✕ ${line}`) : [failure.message];
|
|
376
|
-
if (reason === '
|
|
368
|
+
if (reason === 'bell_mention_conflict' || reason === 'invalid_reply') {
|
|
369
|
+
lines[0] = reason === 'bell_mention_conflict' ? '✕ a bell cannot be combined with a mention'
|
|
370
|
+
: `Invalid ${options.surface === 'tool' ? 'reply' : '--reply'}: ${facts?.activityExists === false ? `${facts.activityId ?? options.reply ?? 'that activity'} is not in this square's history` : 'expected an activity id like act/12'}`;
|
|
371
|
+
if (squarePath !== undefined)
|
|
372
|
+
lines.push(options.surface === 'tool'
|
|
373
|
+
? formatToolAction(reason === 'invalid_reply' ? 'history' : 'status', { location: displayPath(squarePath), ...(reason === 'invalid_reply' ? { limit: 10 } : {}) })
|
|
374
|
+
: reason === 'invalid_reply' ? `${commandPrefix(squarePath)} history --limit 10` : `${commandPrefix(squarePath)} status`);
|
|
375
|
+
}
|
|
376
|
+
else if (reason === 'needs_seat' && squarePath !== undefined && name !== undefined) {
|
|
377
377
|
lines.splice(0, 1, `✕ ${failure.message}`);
|
|
378
|
-
lines.push(joinRecoveryCommand(squarePath, name, owner));
|
|
378
|
+
lines.push(options.surface === 'tool' ? formatToolAction('join', { location: displayPath(squarePath), as: name }) : joinRecoveryCommand(squarePath, name, owner));
|
|
379
379
|
}
|
|
380
380
|
else if (squarePath !== undefined && name !== undefined && failure.code === 'already_joined') {
|
|
381
381
|
lines.splice(0, 1, `✕ ${participantIdentity(name)} shoos you out of the square`, ` · ${participantIdentity(name)} already stands here — another session holds the name`);
|
|
382
|
-
lines.push(...takeoverRecoveryLines(squarePath, name, owner));
|
|
382
|
+
lines.push(...(options.surface === 'tool' ? ['If this is your name to reclaim, takeover banishes the one standing here so you can step in:', formatToolAction('join', { location: displayPath(squarePath), as: name, takeover: true })] : takeoverRecoveryLines(squarePath, name, owner)));
|
|
383
|
+
}
|
|
384
|
+
else if (squarePath !== undefined && name !== undefined && (failure.code === 'unknown_participant' || failure.code === 'not_joined') && reason !== 'not_standing') {
|
|
385
|
+
lines.push(options.surface === 'tool' ? formatToolAction('join', { location: displayPath(squarePath), as: name }) : joinRecoveryCommand(squarePath, name, owner));
|
|
383
386
|
}
|
|
384
387
|
else if (squarePath !== undefined && reason === 'never_joined') {
|
|
385
|
-
lines.push(failure.operation?.subject !== 'filter' && name !== undefined
|
|
386
|
-
? joinRecoveryCommand(squarePath, name, owner) :
|
|
388
|
+
lines.push(options.surface === 'tool' ? (failure.operation?.subject !== 'filter' && name !== undefined ? formatToolAction('join', { location: displayPath(squarePath), as: name }) : formatToolAction('status', { location: displayPath(squarePath) })) : failure.operation?.subject !== 'filter' && name !== undefined
|
|
389
|
+
? joinRecoveryCommand(squarePath, name, owner) : `${commandPrefix(squarePath)} status`);
|
|
387
390
|
}
|
|
388
391
|
else if (squarePath !== undefined && reason === 'not_standing') {
|
|
389
|
-
lines.push(
|
|
392
|
+
lines.push(options.surface === 'tool' ? formatToolAction('status', { location: displayPath(squarePath) }) : `${commandPrefix(squarePath)} status`);
|
|
390
393
|
}
|
|
391
394
|
else if (squarePath !== undefined && reason === 'not_addressed' && facts?.activityId !== undefined) {
|
|
392
|
-
lines.push(facts.activityExists === true
|
|
395
|
+
lines.push(options.surface === 'tool' ? (facts.activityExists === true ? formatToolAction('history', { location: displayPath(squarePath), at: [facts.activityId], context: 2 }) : formatToolAction('history', { location: displayPath(squarePath), limit: 10 })) : facts.activityExists === true
|
|
393
396
|
? `${commandPrefix(squarePath)} history --at ${facts.activityId} -C 2`
|
|
394
397
|
: `${commandPrefix(squarePath)} history --limit 10`);
|
|
395
398
|
}
|
|
396
|
-
if (reason === 'invalid_done_body')
|
|
399
|
+
if (reason === 'invalid_done_body' && options.surface !== 'tool')
|
|
397
400
|
lines.push('square done --help');
|
|
398
401
|
return lines;
|
|
399
402
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DeliveryError } from './errors.js';
|
|
2
|
-
import type { OpenCodeConnectOptions,
|
|
3
|
-
export type { OpenCodeConnectOptions,
|
|
2
|
+
import type { OpenCodeConnectOptions, PiConnectOptions, PaseoConnectOptions, CodexConnectOptions, CodexAppServerConnectOptions, CodexCliConnectOptions } from './types.js';
|
|
3
|
+
export type { OpenCodeConnectOptions, PiConnectOptions, PaseoConnectOptions, CodexConnectOptions, CodexAppServerConnectOptions, CodexCliConnectOptions } from './types.js';
|
|
4
4
|
export interface SendOptions {
|
|
5
5
|
readonly timeoutMs?: number;
|
|
6
6
|
readonly signal?: AbortSignal;
|
|
@@ -10,7 +10,7 @@ export interface KeyedSendOptions extends SendOptions {
|
|
|
10
10
|
}
|
|
11
11
|
export interface Receipt {
|
|
12
12
|
readonly id: string;
|
|
13
|
-
readonly proof: '
|
|
13
|
+
readonly proof: 'admitted' | 'observed';
|
|
14
14
|
}
|
|
15
15
|
export interface Steerable<O = SendOptions> {
|
|
16
16
|
steer(text: string, options?: O): Promise<Receipt>;
|
|
@@ -22,10 +22,6 @@ export type OpenCodeAgent = Steerable<KeyedSendOptions> & Queueable<KeyedSendOpt
|
|
|
22
22
|
readonly harness: 'opencode';
|
|
23
23
|
readonly sessionId: string;
|
|
24
24
|
};
|
|
25
|
-
export type ClaudeAgent = Steerable & {
|
|
26
|
-
readonly harness: 'claude';
|
|
27
|
-
readonly sessionId: string;
|
|
28
|
-
};
|
|
29
25
|
export type PiAgent = Steerable & Queueable & {
|
|
30
26
|
readonly harness: 'pi';
|
|
31
27
|
readonly sessionId: string;
|
|
@@ -47,9 +43,8 @@ export type CodexCliAgent = Queueable & {
|
|
|
47
43
|
readonly sessionId: string;
|
|
48
44
|
};
|
|
49
45
|
export type CodexAgent = CodexAppServerAgent | CodexCliAgent;
|
|
50
|
-
export type Agent = OpenCodeAgent |
|
|
46
|
+
export type Agent = OpenCodeAgent | PiAgent | PaseoAgent | CodexAgent;
|
|
51
47
|
export declare function connect(options: OpenCodeConnectOptions): Promise<OpenCodeAgent>;
|
|
52
|
-
export declare function connect(options: ClaudeConnectOptions): Promise<ClaudeAgent>;
|
|
53
48
|
export declare function connect(options: PiConnectOptions): Promise<PiAgent>;
|
|
54
49
|
export declare function connect(options: PaseoConnectOptions): Promise<PaseoAgent>;
|
|
55
50
|
export declare function connect(options: CodexCliConnectOptions): Promise<CodexCliAgent>;
|
|
@@ -58,15 +58,6 @@ const harnesses = {
|
|
|
58
58
|
return { coordinate: target.sessionId, send: (text, value) => sendText(target, text, value) };
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
|
-
claude: {
|
|
62
|
-
harness: 'claude', proof: 'written', accepted: 'written', coordinate: 'sessionId', keyed: false, queue: false,
|
|
63
|
-
id: (result) => result.messageId,
|
|
64
|
-
open: async (options) => {
|
|
65
|
-
const { connectExisting, sendText } = await import('./claude.js');
|
|
66
|
-
const target = await connectExisting(options);
|
|
67
|
-
return { coordinate: target.sessionId, send: (text, value) => sendText(target, text, value) };
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
61
|
pi: {
|
|
71
62
|
harness: 'pi', proof: 'observed', accepted: 'observed', coordinate: 'sessionId', keyed: false, queue: true,
|
|
72
63
|
id: (result) => result.inputId,
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import net from 'node:net';
|
|
2
2
|
export interface LocalEndpoint {
|
|
3
|
-
readonly kind: 'unix' | 'pipe';
|
|
4
|
-
/** What the socket connects to. */
|
|
5
3
|
readonly path: string;
|
|
6
|
-
/** What the native receiver fingerprints; also the auth key file digest input. */
|
|
7
|
-
readonly canonical: string;
|
|
8
4
|
}
|
|
9
|
-
/**
|
|
10
|
-
* A local endpoint is either a Windows named pipe or an absolute Unix socket
|
|
11
|
-
* path. There is no `stat().isSocket()` check: connecting is the existence check.
|
|
12
|
-
*/
|
|
5
|
+
/** An absolute Unix socket path; connecting is the existence check. */
|
|
13
6
|
export declare function parseLocalEndpoint(raw: unknown): LocalEndpoint;
|
|
14
7
|
export declare class LocalEndpointError extends Error {
|
|
15
8
|
readonly code: 'unavailable' | 'aborted' | 'timeout' | 'transport';
|
|
16
|
-
|
|
17
|
-
constructor(code: LocalEndpointError['code'], maybeDelivered?: boolean);
|
|
9
|
+
constructor(code: LocalEndpointError['code']);
|
|
18
10
|
}
|
|
19
11
|
export interface LocalConnectScope {
|
|
20
12
|
readonly signal?: AbortSignal;
|
|
@@ -22,5 +14,3 @@ export interface LocalConnectScope {
|
|
|
22
14
|
}
|
|
23
15
|
/** Connect with bounded waiting. A connect failure is `unavailable`: nothing was written. */
|
|
24
16
|
export declare function connectLocal(endpoint: LocalEndpoint, scope?: LocalConnectScope): Promise<net.Socket>;
|
|
25
|
-
/** LF-delimited JSON frames. Any failure here is past the uncertainty boundary. */
|
|
26
|
-
export declare function writeFrames(socket: net.Socket, frames: object[]): Promise<void>;
|