@astrosheep/square 0.4.7 → 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 +1 -1
- package/dist/cli/context.js +1 -12
- package/dist/cli/express-presentation.js +6 -33
- package/dist/cli/json.js +1 -1
- package/dist/cli/observation-commands.d.ts +2 -3
- package/dist/cli/observation-commands.js +21 -59
- package/dist/cli/registry.js +3 -5
- package/dist/cli/square-commands.d.ts +1 -2
- package/dist/cli/square-commands.js +7 -17
- package/dist/decisions.js +5 -4
- package/dist/harness-claude.js +3 -3
- package/dist/help.js +6 -8
- package/dist/mcp.js +1 -1
- package/dist/neutral.d.ts +15 -1
- package/dist/notifications.js +1 -1
- package/dist/operation-presentation.d.ts +17 -15
- package/dist/operation-presentation.js +58 -32
- 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/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 +2 -20
- package/dist/presentation.js +11 -46
- package/dist/sqlite-square.js +5 -6
- package/dist/square-facade.d.ts +3 -12
- package/dist/square-posting.js +1 -1
- package/dist/square-tools.d.ts +0 -11
- package/dist/square-tools.js +33 -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 +1 -1
- package/dist/wake-transports.js +1 -1
- 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 +69 -50
- 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/harness-claude.js
CHANGED
|
@@ -71,8 +71,8 @@ export async function doctorClaudePlugin(homeDir, run = runClaude) {
|
|
|
71
71
|
return [
|
|
72
72
|
fs.existsSync(bundle) ? `✓ Square Claude plugin bundle ${root}` : `○ Square Claude plugin bundle missing ${root}`,
|
|
73
73
|
installed ? `✓ ${CLAUDE_PLUGIN_ID} installed` : `○ ${CLAUDE_PLUGIN_ID} unavailable`,
|
|
74
|
-
`Claude delivery uses
|
|
75
|
-
`
|
|
76
|
-
`
|
|
74
|
+
`Claude delivery uses a mod: busy turns append context and log it; idle main sessions submit an attributed plugin prompt.`,
|
|
75
|
+
`Stop suppresses the current delivery batch; clear, resume and module reload retire the captured helper and attachment.`,
|
|
76
|
+
`Exact native acceptance records presentation, not model comprehension. Paseo does not yet expose Claude ui_log events.`,
|
|
77
77
|
];
|
|
78
78
|
}
|
package/dist/help.js
CHANGED
|
@@ -40,11 +40,10 @@ const COMMANDS = [
|
|
|
40
40
|
{ names: ['listen'], usage: '--as <name> listen <participant>', usesSquare: true, group: 'participant', summary: 'Turn an ear toward one participant\'s future activity.' },
|
|
41
41
|
{ names: ['unlisten'], usage: '--as <name> unlisten <participant>', usesSquare: true, group: 'participant', summary: 'Stop listening without blocking that participant\'s mentions or replies.' },
|
|
42
42
|
{ names: ['ignore'], usage: '--as <name> ignore <participant>', usesSquare: true, group: 'participant', summary: 'Stop hearing one participant\'s future activity, except bells.' },
|
|
43
|
-
{ names: ['listening'], usage: '--as <name> listening', usesSquare: true, group: 'participant', summary: 'Show who you are turned toward.', details: ['Listening applies to future activity. What you could hear when an activity landed does not change afterward.'] },
|
|
44
43
|
{
|
|
45
|
-
names: ['perceive'], usage: '--as <name> perceive [--id <activity-id>] [--
|
|
44
|
+
names: ['perceive'], usage: '--as <name> perceive [--id <activity-id>] [--idle <duration>] [--from <names>] [--mention] [--limit <count>] [--takeover]', usesSquare: true, group: 'participant',
|
|
46
45
|
summary: 'Perceive directed conversation since you last looked.',
|
|
47
|
-
details: ['Modes:', ' --id <activity-id>
|
|
46
|
+
details: ['Modes:', ' --id <activity-id> Open one activity addressed to you in full; repeats work. Use it alone.', ' --idle <duration> Wait for something relevant, or for quiet to last this long.', '', 'Attention:', ' Mentions arrive when you are addressed; bells arrive for everyone; bare says require listen.', ' listen and ignore are future-only and fixed when each say lands.', '', 'Filters:', ' --from <names> Match only comma-separated participants.', ' --mention Match direct attention for your current participant (and bells).', ' --limit <count> Return one page (default 10, maximum 100).', '', 'Recovery:', ' --takeover Take over from another active perceive for this participant.'],
|
|
48
47
|
},
|
|
49
48
|
{ names: ['done'], usage: '--as <name> done', usesSquare: true, group: 'participant', summary: 'Step out of the square.', details: ['done takes no message. Use express before leaving to send one.'] },
|
|
50
49
|
{
|
|
@@ -60,12 +59,11 @@ const COMMANDS = [
|
|
|
60
59
|
{ names: ['codex-hook'], usage: '{command}', summary: 'Present pending attention at one native agent boundary.', hiddenFromIndex: true },
|
|
61
60
|
{ names: ['codex-watch'], usage: '{command}', summary: 'Observe pending attention from a native async Stop hook.', hiddenFromIndex: true },
|
|
62
61
|
{ names: ['codex-interrupt'], usage: '{command}', summary: 'Cancel pending attention at a native Interrupt boundary.', hiddenFromIndex: true },
|
|
63
|
-
{ names: ['claude-
|
|
64
|
-
{ names: ['claude-watch'], usage: '{command}', summary: 'Observe pending attention from a native async Stop hook.', hiddenFromIndex: true },
|
|
62
|
+
{ names: ['claude-mod'], usage: '{command}', summary: 'Run the Claude mod delivery helper.', hiddenFromIndex: true },
|
|
65
63
|
{
|
|
66
64
|
names: ['history'], usage: 'history [filters] [output]', usesSquare: true, group: 'participant',
|
|
67
65
|
summary: 'Read or search the archive without changing what you have perceived.',
|
|
68
|
-
details: ['
|
|
66
|
+
details: ['Filters:', ' --from <names> Match activities from participants.', ' --since <time> Match activities after a time.', ' --search <text> [--regex] Search ids, participants, and original bodies; literal by default.', ' --mention <name> Match direct attention for a participant.', ' --at <ids> Center on comma-separated activity ids; may repeat.', ' -C <N> Set symmetric context around every --at coordinate.', ' --before <id> Read the page immediately before an activity.', ' --after <id> Read the page immediately after an activity.', '', 'Results:', ' --limit <N> Page size (default 10, maximum 100).', ' --order <asc|desc> Set display order (default oldest first).', '', 'Output:', ' --full --json --format <fields>', ' One result shows its full body; multiple results use previews.', ' --full shows every original body.'],
|
|
69
67
|
},
|
|
70
68
|
{ names: ['status'], usage: '[--as <name>] status', usesSquare: true, group: 'participant', summary: 'Show who is present and what happened most recently.' },
|
|
71
69
|
{
|
|
@@ -96,7 +94,7 @@ function isHelpFlag(value) {
|
|
|
96
94
|
}
|
|
97
95
|
export function renderGlobalHelp() {
|
|
98
96
|
const groups = [
|
|
99
|
-
{ key: 'participant', title: 'In the square:', order: ['join', 'express', 'listen', 'unlisten', 'ignore', '
|
|
97
|
+
{ key: 'participant', title: 'In the square:', order: ['join', 'express', 'listen', 'unlisten', 'ignore', 'perceive', 'history', 'status', 'done'] },
|
|
100
98
|
{ key: 'host', title: 'Prepare and manage:', order: ['build', 'list'] },
|
|
101
99
|
{ key: 'maintenance', title: 'Setup:', order: ['install', 'uninstall', 'doctor'] },
|
|
102
100
|
];
|
|
@@ -112,7 +110,7 @@ export function renderGlobalHelp() {
|
|
|
112
110
|
'Usage: square [--location <square>] [--as <name>] [--owner <id>] <command> [args...]',
|
|
113
111
|
'Location: square-accessing commands require --location <square>. Use square list to find nearby squares and your joined names; use --as to select a participant.',
|
|
114
112
|
'Identity: --owner overrides SQUARE_OWNER, then a complete harness identity, then user:<OS user>@<host>. Incomplete or ambiguous harness identities refuse. Owners without wake use perceive --idle.',
|
|
115
|
-
'Output: --json on join, express, perceive, history, listen, ignore, unlisten,
|
|
113
|
+
'Output: --json on join, express, perceive, history, listen, ignore, unlisten, done, status and inbox prints the SDK result without observation; a participant handle becomes {name}.',
|
|
116
114
|
'History emits one JSON document; stream --ndjson emits one SDK record per line.',
|
|
117
115
|
'',
|
|
118
116
|
...commandLines,
|
package/dist/mcp.js
CHANGED
|
@@ -20,7 +20,7 @@ export function createSquareMcpServer(options) {
|
|
|
20
20
|
return invoke(tool, args, { signal: extra.signal }, async () => {
|
|
21
21
|
const threadId = extra._meta?.threadId;
|
|
22
22
|
const opencodeSessionId = extra._meta?.['ai.opencode/sessionID'];
|
|
23
|
-
// Claude's bundled
|
|
23
|
+
// Claude's bundled mod requires a per-call native association; startup identity is not a fallback.
|
|
24
24
|
const claude = baseEnv.SQUARE_CLAUDE_MCP_CONTEXT === '1'
|
|
25
25
|
? await readClaudeMcpCall(extra._meta?.['claudecode/toolUseId'], baseEnv)
|
|
26
26
|
: undefined;
|
package/dist/neutral.d.ts
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
export type Owner = string;
|
|
3
3
|
export type SquareErrorCode = 'invalid_name' | 'invalid_args' | 'unknown_participant' | 'not_joined' | 'already_joined' | 'already_done' | 'capped' | 'throttled' | 'bell_quota' | 'behind' | 'io' | 'unavailable';
|
|
4
4
|
export type InternalSquareErrorCode = SquareErrorCode | 'not_found' | 'cap_reached' | 'conflict' | 'pending_peer';
|
|
5
|
+
/** One speaker's unperceived activity, previewed by its latest body. */
|
|
6
|
+
export interface UnreadActivitySummary {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly count: number;
|
|
9
|
+
readonly latestActivityAgeMs: number;
|
|
10
|
+
readonly preview: {
|
|
11
|
+
readonly body?: string;
|
|
12
|
+
readonly structured: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
5
15
|
export interface SquareErrorFacts {
|
|
6
16
|
/** Express admission rejected before any activity was committed. */
|
|
7
17
|
activityUnsent?: true;
|
|
@@ -13,8 +23,12 @@ export interface SquareErrorFacts {
|
|
|
13
23
|
targets?: readonly string[];
|
|
14
24
|
/** Whether the artifact holds that activity at all; an unknown id needs an ordinary page. */
|
|
15
25
|
activityExists?: boolean;
|
|
16
|
-
|
|
26
|
+
/** Who spoke while an express was away; the refusal rests on exactly these. */
|
|
27
|
+
activitySummaries?: readonly UnreadActivitySummary[];
|
|
17
28
|
retryAfterMs?: number;
|
|
29
|
+
/** A capped speaker's spoken count against the square's cap. */
|
|
30
|
+
spoken?: number;
|
|
31
|
+
hardCap?: number;
|
|
18
32
|
}
|
|
19
33
|
export interface PerceiveWaitStart {
|
|
20
34
|
readonly idleMs: number;
|
package/dist/notifications.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createDefaultDeliveryTransports } from './wake-transports.js';
|
|
2
2
|
export { createDefaultDeliveryTransports } from './wake-transports.js';
|
|
3
3
|
const DEFAULT_DELIVERY_WAIT_MS = 5000;
|
|
4
|
-
const NATIVE_RECEIVER_ROUTES = new Set(['codex-queue', 'claude-
|
|
4
|
+
const NATIVE_RECEIVER_ROUTES = new Set(['codex-queue', 'claude-mod', 'pi-native']);
|
|
5
5
|
/** Best-effort dispatch for currently eligible cards, including cards restored by release. */
|
|
6
6
|
export async function dispatchEligibleCards(ledger, owner, options = {}) {
|
|
7
7
|
const signal = options.signal ?? AbortSignal.timeout(DEFAULT_DELIVERY_WAIT_MS);
|
|
@@ -1,4 +1,4 @@
|
|
|
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
2
|
import { type PresentationSurface } from './presentation.js';
|
|
3
3
|
export declare function renderSquareList(data: DiscoveryResult, projection: {
|
|
4
4
|
now: number;
|
|
@@ -22,14 +22,13 @@ export declare function renderPerceiveOutcome(squarePath: string, data: Perceive
|
|
|
22
22
|
export declare function historyContinuationCommand(squarePath: string, args: readonly string[]): string;
|
|
23
23
|
export declare function renderHistoryResult(squarePath: string, data: HistoryResult, options?: {
|
|
24
24
|
query?: HistoryQuery;
|
|
25
|
-
|
|
25
|
+
full?: boolean;
|
|
26
26
|
continuationArgs?: readonly string[];
|
|
27
27
|
surface?: PresentationSurface;
|
|
28
28
|
}): string | undefined;
|
|
29
29
|
export declare function renderStatusResult(squarePath: string, data: StatusResult, options?: {
|
|
30
30
|
surface?: PresentationSurface;
|
|
31
31
|
}): string | undefined;
|
|
32
|
-
export declare function renderListeningResult(squarePath: string, data: ListeningResult): string | undefined;
|
|
33
32
|
export type ListenerVerb = 'listen' | 'ignore' | 'unlisten';
|
|
34
33
|
export declare function renderListenerChange(squarePath: string, verb: ListenerVerb, data: ListenerChangeResult): string | undefined;
|
|
35
34
|
export declare function renderLifecycleResult(squarePath: string, data: LifecycleResult): string | undefined;
|
|
@@ -37,18 +36,21 @@ export declare function renderLifecycleResult(squarePath: string, data: Lifecycl
|
|
|
37
36
|
export interface FailureReport {
|
|
38
37
|
readonly code: string;
|
|
39
38
|
readonly message: string;
|
|
40
|
-
readonly facts?:
|
|
41
|
-
readonly reason?: 'never_joined' | 'not_standing' | 'bell_mention_conflict' | 'not_addressed' | 'invalid_reply' | 'invalid_done_body' | 'needs_seat';
|
|
42
|
-
readonly activityId?: string;
|
|
43
|
-
readonly activityExists?: boolean;
|
|
44
|
-
};
|
|
39
|
+
readonly facts?: SquareErrorFacts;
|
|
45
40
|
readonly operation?: OperationFailureDetail;
|
|
46
41
|
}
|
|
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;
|
|
47
54
|
/** Refusal lines with surface-specific recovery actions. */
|
|
48
|
-
export declare function renderFailureLines(failure: FailureReport, options?:
|
|
49
|
-
|
|
50
|
-
name?: string;
|
|
51
|
-
owner?: string;
|
|
52
|
-
surface?: PresentationSurface;
|
|
53
|
-
reply?: string;
|
|
54
|
-
}): string[];
|
|
55
|
+
export declare function renderFailureLines(failure: FailureReport, options?: FailureOptions): string[];
|
|
56
|
+
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Human-facing scenes for settled operations, with surface-specific next actions.
|
|
2
2
|
import { sameName } from './model.js';
|
|
3
3
|
import { formatActivityId } from './square-core.js';
|
|
4
|
-
import { displayPath, formatToolAction, commandPrefix, joinRecoveryCommand, participantCommandPrefix, participantIdentity, quoteShell, renderAmbientEvent, renderAmbientEventFacts, renderEventCli, renderGrepActivitiesView, renderPresenceAnchor, renderWatchAlreadyActive, renderWatchReplaced, renderWatchStatus, takeoverRecoveryLines, withPathOutput, truncateChars, } from './presentation.js';
|
|
5
|
-
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';
|
|
6
6
|
import { style } from './tty-style.js';
|
|
7
7
|
function listDisplay(value) {
|
|
8
8
|
const truncated = truncateChars(value, 159);
|
|
@@ -53,7 +53,7 @@ export function renderJoinResult(data, owner, surface = 'cli') {
|
|
|
53
53
|
now: after.now, preview: 200, perception: event.perception,
|
|
54
54
|
})).filter(Boolean).join('\n\n');
|
|
55
55
|
const fallback = after.deliveryAvailable ? ['', '· when someone calls you, you’ll hear them here'] : [
|
|
56
|
-
'', surface === 'tool' ? formatToolAction('perceive', { location: displayPath(after.location), as: name, idle:
|
|
56
|
+
'', surface === 'tool' ? formatToolAction('perceive', { location: displayPath(after.location), as: name, idle: '30m' }) : `${participantCommandPrefix(after.location, name, owner)} perceive --idle 30m`,
|
|
57
57
|
' · stay within earshot — keep this perceive open for new activity',
|
|
58
58
|
];
|
|
59
59
|
const entryLine = data.kind === 'joined' ? '● you stepped into the square'
|
|
@@ -101,14 +101,14 @@ export function renderExpression(squarePath, data, owner, surface = 'cli') {
|
|
|
101
101
|
return withPathOutput(projection.location ?? squarePath, confirmation + (data.hint ? `\n${style('dim', `· ${data.hint}`)}` : '') + replyNotice + unmatchedNotice + pending, { participantCount: projection.standingCount });
|
|
102
102
|
}
|
|
103
103
|
function continuationCommand(squarePath, name, options, owner) {
|
|
104
|
-
const args = [
|
|
104
|
+
const args = [];
|
|
105
105
|
if (options.from?.length)
|
|
106
106
|
args.push('--from', options.from.join(','));
|
|
107
107
|
if (options.mention)
|
|
108
108
|
args.push('--mention');
|
|
109
109
|
if (options.limit !== undefined)
|
|
110
110
|
args.push('--limit', String(options.limit));
|
|
111
|
-
return
|
|
111
|
+
return [participantCommandPrefix(squarePath, name, owner), 'perceive', ...args].join(' ');
|
|
112
112
|
}
|
|
113
113
|
/** Render settled perceive facts; no selection, terminal decisions, receipts or wait machinery. */
|
|
114
114
|
export function renderPerceiveOutcome(squarePath, data, options = {}, owner, surface = 'cli') {
|
|
@@ -141,16 +141,16 @@ export function renderPerceiveOutcome(squarePath, data, options = {}, owner, sur
|
|
|
141
141
|
...(stop === 'idle' && options.idle !== undefined ? { idleMs: options.idle } : {}),
|
|
142
142
|
});
|
|
143
143
|
const fallback = stop === undefined && !projection.deliveryAvailable && data.remaining === 0
|
|
144
|
-
? `${surface === 'tool' ? formatToolAction('perceive', { location: displayPath(location), as: name, idle:
|
|
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` : '';
|
|
145
145
|
const hint = data.hint === undefined ? '' : style('dim', `· ${data.hint}`);
|
|
146
146
|
return {
|
|
147
147
|
stdout: withPathOutput(location, [terminal, rendered, hint, remaining, fallback].filter(Boolean).join('\n\n'), header),
|
|
148
148
|
exitCode: stop === 'capped' ? 1 : 0,
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
|
-
function renderHistoryProjection(projection, visible,
|
|
151
|
+
function renderHistoryProjection(projection, visible, full, squarePath, surface) {
|
|
152
152
|
const shown = visible;
|
|
153
|
-
const preview =
|
|
153
|
+
const preview = full || shown.length <= 1 ? undefined : 200;
|
|
154
154
|
const chunks = [];
|
|
155
155
|
// Presence anchors collect into one closing line instead of interrupting the page.
|
|
156
156
|
const anchored = [];
|
|
@@ -167,7 +167,7 @@ function renderHistoryProjection(projection, visible, noTruncate, squarePath, su
|
|
|
167
167
|
return '○ no activity matches this history query';
|
|
168
168
|
if (preview !== undefined && shown.some((activity) => activity.kind === 'say' && (activity.body?.length ?? 0) > preview)) {
|
|
169
169
|
const ids = shown.map((activity) => formatActivityId(activity.index));
|
|
170
|
-
chunks.push(surface === 'tool' ? formatToolAction('history', { location: displayPath(squarePath), at: ids,
|
|
170
|
+
chunks.push(surface === 'tool' ? formatToolAction('history', { location: displayPath(squarePath), at: ids, full: true }) : `${commandPrefix(squarePath)} history --at ${ids.join(',')} --full`);
|
|
171
171
|
}
|
|
172
172
|
if (anchored.length > 0)
|
|
173
173
|
chunks.push(renderPresenceAnchor(anchored));
|
|
@@ -185,14 +185,15 @@ function historyQueryArgs(query) {
|
|
|
185
185
|
args.push('--since', formatTimestamp(query.since));
|
|
186
186
|
if (query.at?.length)
|
|
187
187
|
args.push('--at', query.at.join(','));
|
|
188
|
-
if (query.
|
|
189
|
-
args.push('-
|
|
190
|
-
if (query.contextAfter !== undefined)
|
|
191
|
-
args.push('-A', String(query.contextAfter));
|
|
188
|
+
if (query.context !== undefined)
|
|
189
|
+
args.push('-C', String(query.context));
|
|
192
190
|
if (query.mention !== undefined)
|
|
193
191
|
args.push('--mention', query.mention);
|
|
194
|
-
if (query.search !== undefined)
|
|
195
|
-
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
|
+
}
|
|
196
197
|
if (query.order !== undefined)
|
|
197
198
|
args.push('--order', query.order);
|
|
198
199
|
return args;
|
|
@@ -202,14 +203,14 @@ export function renderHistoryResult(squarePath, data, options = {}) {
|
|
|
202
203
|
if (projection === undefined)
|
|
203
204
|
return undefined;
|
|
204
205
|
const query = options.query ?? {};
|
|
205
|
-
const
|
|
206
|
+
const full = options.full === true;
|
|
206
207
|
const search = query.search;
|
|
207
208
|
const output = search === undefined
|
|
208
|
-
? renderHistoryProjection(projection, projection.visibleActivities,
|
|
209
|
-
: 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);
|
|
210
211
|
const next = projection.continuation;
|
|
211
|
-
const base = options.continuationArgs ?? historyQueryArgs(query);
|
|
212
|
-
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.
|
|
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)])}`;
|
|
213
214
|
return withPathOutput(squarePath, output + continuation, { participantCount: projection.standingCount });
|
|
214
215
|
}
|
|
215
216
|
export function renderStatusResult(squarePath, data, options = {}) {
|
|
@@ -276,7 +277,7 @@ export function renderStatusResult(squarePath, data, options = {}) {
|
|
|
276
277
|
if (presentation.joinCount > 3)
|
|
277
278
|
latest.push(style('dim', ` → … ${presentation.joinCount - 3} more stepped in`));
|
|
278
279
|
if (visible.bodyClipped && data.latestActivity !== undefined) {
|
|
279
|
-
latest.push(options.surface === 'tool' ? formatToolAction('history', { location: displayPath(squarePath), at: [data.latestActivity.id], context: 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`);
|
|
280
281
|
}
|
|
281
282
|
const counts = [
|
|
282
283
|
`${orderedHere.length} here`,
|
|
@@ -296,15 +297,6 @@ export function renderStatusResult(squarePath, data, options = {}) {
|
|
|
296
297
|
].join('\n');
|
|
297
298
|
return withPathOutput(squarePath, output, { participantCount: presentation.standingCount });
|
|
298
299
|
}
|
|
299
|
-
export function renderListeningResult(squarePath, data) {
|
|
300
|
-
const projection = data.observation;
|
|
301
|
-
if (projection?.participant === undefined)
|
|
302
|
-
return undefined;
|
|
303
|
-
const body = data.listening.length === 0
|
|
304
|
-
? `○ ${participantIdentity(projection.participant)} is not turned toward anyone`
|
|
305
|
-
: ['listening', ...data.listening.map((target) => ` · ${participantIdentity(target)}`)].join('\n');
|
|
306
|
-
return withPathOutput(squarePath, body, { participantCount: projection.standingCount });
|
|
307
|
-
}
|
|
308
300
|
export function renderListenerChange(squarePath, verb, data) {
|
|
309
301
|
const projection = data.observation;
|
|
310
302
|
if (projection?.participant === undefined)
|
|
@@ -330,15 +322,49 @@ export function renderLifecycleResult(squarePath, data) {
|
|
|
330
322
|
participantCount: projection.standingCount,
|
|
331
323
|
});
|
|
332
324
|
}
|
|
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
|
+
}
|
|
333
358
|
/** Refusal lines with surface-specific recovery actions. */
|
|
334
359
|
export function renderFailureLines(failure, options = {}) {
|
|
335
360
|
const { squarePath, name, owner } = options;
|
|
336
361
|
const facts = failure.facts;
|
|
337
362
|
const reason = facts?.reason;
|
|
363
|
+
const gate = expressGateLines(failure, options);
|
|
364
|
+
if (gate !== undefined)
|
|
365
|
+
return gate;
|
|
338
366
|
const marked = reason === 'never_joined' || reason === 'not_standing';
|
|
339
367
|
const lines = marked ? failure.message.split('\n').map((line) => `✕ ${line}`) : [failure.message];
|
|
340
|
-
if (failure.code === 'behind' && options.surface === 'tool')
|
|
341
|
-
lines[0] = `✕ your words stay unsent — ${failure.message}`;
|
|
342
368
|
if (reason === 'bell_mention_conflict' || reason === 'invalid_reply') {
|
|
343
369
|
lines[0] = reason === 'bell_mention_conflict' ? '✕ a bell cannot be combined with a mention'
|
|
344
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'}`;
|
|
@@ -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>;
|
|
@@ -1,35 +1,20 @@
|
|
|
1
1
|
import net from 'node:net';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
const PIPE = /^[\\/]{2}[.?][\\/]pipe[\\/](?:(LOCAL)[\\/])?([^\\/]+)$/i;
|
|
5
|
-
/**
|
|
6
|
-
* A local endpoint is either a Windows named pipe or an absolute Unix socket
|
|
7
|
-
* path. There is no `stat().isSocket()` check: connecting is the existence check.
|
|
8
|
-
*/
|
|
3
|
+
/** An absolute Unix socket path; connecting is the existence check. */
|
|
9
4
|
export function parseLocalEndpoint(raw) {
|
|
10
|
-
if (typeof raw !== 'string' || raw.includes('\0'))
|
|
11
|
-
throw new Error('Invalid local endpoint.');
|
|
12
|
-
const pipe = PIPE.exec(raw);
|
|
13
|
-
if (pipe) {
|
|
14
|
-
const canonical = `\\\\.\\pipe\\${pipe[2].toLowerCase()}`;
|
|
15
|
-
return { kind: 'pipe', path: canonical, canonical };
|
|
16
|
-
}
|
|
17
|
-
if (!(process.platform === 'win32' ? /^[A-Za-z]:[\\/]/.test(raw) : raw.startsWith('/')))
|
|
5
|
+
if (typeof raw !== 'string' || raw.includes('\0') || !raw.startsWith('/'))
|
|
18
6
|
throw new Error('Invalid local endpoint.');
|
|
19
7
|
const limit = process.platform === 'darwin' ? 103 : process.platform === 'linux' ? 107 : undefined;
|
|
20
8
|
if (limit !== undefined && Buffer.byteLength(raw) > limit)
|
|
21
9
|
throw new Error('Invalid local endpoint.');
|
|
22
|
-
|
|
23
|
-
return { kind: 'unix', path: canonical, canonical };
|
|
10
|
+
return { path: resolve(raw) };
|
|
24
11
|
}
|
|
25
12
|
export class LocalEndpointError extends Error {
|
|
26
13
|
code;
|
|
27
|
-
|
|
28
|
-
constructor(code, maybeDelivered = false) {
|
|
14
|
+
constructor(code) {
|
|
29
15
|
super(code);
|
|
30
16
|
this.name = 'LocalEndpointError';
|
|
31
17
|
this.code = code;
|
|
32
|
-
this.maybeDelivered = maybeDelivered;
|
|
33
18
|
}
|
|
34
19
|
}
|
|
35
20
|
function errnoCode(error) {
|
|
@@ -83,32 +68,3 @@ export function connectLocal(endpoint, scope = {}) {
|
|
|
83
68
|
}
|
|
84
69
|
});
|
|
85
70
|
}
|
|
86
|
-
/** LF-delimited JSON frames. Any failure here is past the uncertainty boundary. */
|
|
87
|
-
export function writeFrames(socket, frames) {
|
|
88
|
-
const payload = frames.map((frame) => JSON.stringify(frame)).join('\n') + '\n';
|
|
89
|
-
return new Promise((resolveWrite, reject) => {
|
|
90
|
-
let settled = false;
|
|
91
|
-
// Error/close handlers stay attached past settling, so a later I/O failure is
|
|
92
|
-
// swallowed here instead of surfacing as an unhandled socket event.
|
|
93
|
-
const finish = (error) => {
|
|
94
|
-
if (settled)
|
|
95
|
-
return;
|
|
96
|
-
settled = true;
|
|
97
|
-
if (error) {
|
|
98
|
-
reject(error);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
resolveWrite();
|
|
102
|
-
};
|
|
103
|
-
const failed = (error) => finish(new LocalEndpointError(errnoCode(error), true));
|
|
104
|
-
socket.once('error', failed);
|
|
105
|
-
socket.once('close', () => finish(new LocalEndpointError('transport', true)));
|
|
106
|
-
socket.end(payload, 'utf8', (error) => {
|
|
107
|
-
if (error) {
|
|
108
|
-
failed(error);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
finish();
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
}
|
|
@@ -55,8 +55,6 @@ export async function connectPi(options) {
|
|
|
55
55
|
}
|
|
56
56
|
if (process.platform !== 'darwin')
|
|
57
57
|
throw new ConnectionError('unsupported_platform');
|
|
58
|
-
if (endpoint.kind !== 'unix')
|
|
59
|
-
throw new ConnectionError('invalid_arguments');
|
|
60
58
|
const answer = await request(endpoint, { protocol: VERSION, harness: 'pi', op: 'hello', sessionId: options.sessionId }, options.timeoutMs, options.signal);
|
|
61
59
|
if (answer.code !== undefined)
|
|
62
60
|
throw new ConnectionError(answer.code === 'transport' ? 'service_unavailable' : answer.code);
|
|
@@ -5,11 +5,6 @@ export interface OpenCodeTarget {
|
|
|
5
5
|
readonly sessionId: string;
|
|
6
6
|
readonly [targetBrand]: true;
|
|
7
7
|
}
|
|
8
|
-
export interface ClaudeTarget {
|
|
9
|
-
readonly harness: 'claude';
|
|
10
|
-
readonly sessionId: string;
|
|
11
|
-
readonly [targetBrand]: true;
|
|
12
|
-
}
|
|
13
8
|
export interface PiTarget {
|
|
14
9
|
readonly harness: 'pi';
|
|
15
10
|
readonly sessionId: string;
|
|
@@ -25,7 +20,7 @@ export interface CodexTarget {
|
|
|
25
20
|
readonly sessionId: string;
|
|
26
21
|
readonly [targetBrand]: true;
|
|
27
22
|
}
|
|
28
|
-
export type Target = OpenCodeTarget |
|
|
23
|
+
export type Target = OpenCodeTarget | PiTarget | PaseoTarget | CodexTarget;
|
|
29
24
|
export type Delivery = 'steer' | 'queue';
|
|
30
25
|
export interface OpenCodeSendTextOptions {
|
|
31
26
|
readonly delivery?: Delivery;
|
|
@@ -33,12 +28,6 @@ export interface OpenCodeSendTextOptions {
|
|
|
33
28
|
readonly timeoutMs?: number;
|
|
34
29
|
readonly signal?: AbortSignal;
|
|
35
30
|
}
|
|
36
|
-
export interface ClaudeSendTextOptions {
|
|
37
|
-
readonly delivery?: 'steer';
|
|
38
|
-
readonly inputId?: never;
|
|
39
|
-
readonly timeoutMs?: number;
|
|
40
|
-
readonly signal?: AbortSignal;
|
|
41
|
-
}
|
|
42
31
|
export interface PiSendTextOptions {
|
|
43
32
|
readonly delivery?: Delivery;
|
|
44
33
|
readonly inputId?: never;
|
|
@@ -58,7 +47,7 @@ export interface CodexSendTextOptions {
|
|
|
58
47
|
readonly timeoutMs?: number;
|
|
59
48
|
readonly signal?: AbortSignal;
|
|
60
49
|
}
|
|
61
|
-
export type SendTextOptions = OpenCodeSendTextOptions |
|
|
50
|
+
export type SendTextOptions = OpenCodeSendTextOptions | PiSendTextOptions | PaseoSendTextOptions | CodexSendTextOptions;
|
|
62
51
|
export interface OpenCodeConnectOptions {
|
|
63
52
|
readonly harness: 'opencode';
|
|
64
53
|
readonly sessionId: string;
|
|
@@ -74,15 +63,6 @@ export interface OpenCodeConnectOptions {
|
|
|
74
63
|
readonly timeoutMs?: number;
|
|
75
64
|
readonly signal?: AbortSignal;
|
|
76
65
|
}
|
|
77
|
-
export interface ClaudeConnectOptions {
|
|
78
|
-
readonly harness: 'claude';
|
|
79
|
-
readonly sessionId: string;
|
|
80
|
-
readonly endpoint: string;
|
|
81
|
-
readonly token?: string;
|
|
82
|
-
readonly claudeHome?: string;
|
|
83
|
-
readonly timeoutMs?: number;
|
|
84
|
-
readonly signal?: AbortSignal;
|
|
85
|
-
}
|
|
86
66
|
export interface PiConnectOptions {
|
|
87
67
|
readonly harness: 'pi';
|
|
88
68
|
readonly sessionId: string;
|
|
@@ -147,20 +127,6 @@ export type OpenCodeDeliveryResult = (OpenCodeAttempt & {
|
|
|
147
127
|
readonly state: 'unavailable';
|
|
148
128
|
readonly code: 'aborted' | 'timeout';
|
|
149
129
|
});
|
|
150
|
-
interface ClaudeAttempt {
|
|
151
|
-
readonly harness: 'claude';
|
|
152
|
-
readonly sessionId: string;
|
|
153
|
-
}
|
|
154
|
-
export type ClaudeDeliveryResult = (ClaudeAttempt & {
|
|
155
|
-
readonly state: 'written';
|
|
156
|
-
readonly messageId: string;
|
|
157
|
-
}) | (ClaudeAttempt & {
|
|
158
|
-
readonly state: 'unknown';
|
|
159
|
-
readonly code: 'timeout' | 'aborted' | 'transport';
|
|
160
|
-
}) | (ClaudeAttempt & {
|
|
161
|
-
readonly state: 'unavailable';
|
|
162
|
-
readonly code: 'aborted' | 'timeout' | 'endpoint_unavailable' | 'authentication_failed';
|
|
163
|
-
});
|
|
164
130
|
interface PiAttempt {
|
|
165
131
|
readonly harness: 'pi';
|
|
166
132
|
readonly sessionId: string;
|
|
@@ -214,5 +180,5 @@ export type CodexDeliveryResult = (CodexAttempt & {
|
|
|
214
180
|
readonly state: 'rejected';
|
|
215
181
|
readonly code: 'not_found' | 'refused' | 'unsupported_version';
|
|
216
182
|
});
|
|
217
|
-
export type DeliveryResult = OpenCodeDeliveryResult |
|
|
183
|
+
export type DeliveryResult = OpenCodeDeliveryResult | PiDeliveryResult | PaseoDeliveryResult | CodexDeliveryResult;
|
|
218
184
|
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CardPresentation } from "./card-presentation.ts";
|
|
2
|
+
export declare function reachLabel(reach?: CardPresentation["reach"]): string | undefined;
|
|
3
|
+
/** Calendar days, rather than elapsed hours, keep yesterday correct across DST. */
|
|
4
|
+
export declare function timeLabel(at: number, now?: number, compact?: boolean): string;
|
|
5
|
+
/** Only adjacent references from the same origin can form a range. */
|
|
6
|
+
export declare function cardReferences(items: readonly CardPresentation[], originLabel?: (origin: string) => string): string;
|